From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from mails.dpdk.org (mails.dpdk.org [217.70.189.124]) by inbox.dpdk.org (Postfix) with ESMTP id 25C4F41D63; Mon, 27 Feb 2023 17:28:18 +0100 (CET) Received: from mails.dpdk.org (localhost [127.0.0.1]) by mails.dpdk.org (Postfix) with ESMTP id 082C140A84; Mon, 27 Feb 2023 17:28:18 +0100 (CET) Received: from us-smtp-delivery-124.mimecast.com (us-smtp-delivery-124.mimecast.com [170.10.133.124]) by mails.dpdk.org (Postfix) with ESMTP id 3E51040A7D for ; Mon, 27 Feb 2023 17:28:16 +0100 (CET) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1677515295; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=dyIpkY8U234s+G3br1mR4DtJI0rzu7n65z7BUdSbcN0=; b=axuuW2Cd0iJbV3tXmSZqCX/AgbuOlE1so8Gjsf5/kOOl5fVMpSFBGzMs6vPCc1ga+4g9mU 7pPgzXaJMEBSS3sAXw/toMZFjnVHfNJf8NsDKMS+RYaB/TrdYZ2jnWjenlcI7lRpoQC/9X 0q7B2ErIyg8VOd2ZDxEtZGlpxHneDpU= Received: from mimecast-mx02.redhat.com (mx3-rdu2.redhat.com [66.187.233.73]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id us-mta-532-EqOnX13oMcqNkMDz9yae3A-1; Mon, 27 Feb 2023 11:28:12 -0500 X-MC-Unique: EqOnX13oMcqNkMDz9yae3A-1 Received: from smtp.corp.redhat.com (int-mx06.intmail.prod.int.rdu2.redhat.com [10.11.54.6]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mimecast-mx02.redhat.com (Postfix) with ESMTPS id 49A2C3801F56; Mon, 27 Feb 2023 16:28:12 +0000 (UTC) Received: from [10.45.242.42] (unknown [10.45.242.42]) by smtp.corp.redhat.com (Postfix) with ESMTPS id DF4652166B2B; Mon, 27 Feb 2023 16:28:10 +0000 (UTC) Message-ID: Date: Mon, 27 Feb 2023 17:28:09 +0100 MIME-Version: 1.0 User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:102.0) Gecko/20100101 Thunderbird/102.8.0 To: David Marchand , "Xia, Chenbo" Cc: "dev@dpdk.org" , "thomas@monjalon.net" References: <20230224081642.2566619-1-david.marchand@redhat.com> <20230224151143.3274897-1-david.marchand@redhat.com> <20230224151143.3274897-12-david.marchand@redhat.com> From: Maxime Coquelin Subject: Re: [PATCH v2 11/20] net/virtio: annotate lock for guest announce In-Reply-To: X-Scanned-By: MIMEDefang 3.1 on 10.11.54.6 X-Mimecast-Spam-Score: 0 X-Mimecast-Originator: redhat.com Content-Language: en-US Content-Type: text/plain; charset=UTF-8; format=flowed Content-Transfer-Encoding: 7bit X-BeenThere: dev@dpdk.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: DPDK patches and discussions List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: dev-bounces@dpdk.org Hi, On 2/27/23 09:24, David Marchand wrote: > Hello Chenbo, > > Adding Maxime too. > > On Mon, Feb 27, 2023 at 3:05 AM Xia, Chenbo wrote: >>> @@ -1217,7 +1217,7 @@ virtio_notify_peers(struct rte_eth_dev *dev) >>> } >>> >>> /* If virtio port just stopped, no need to send RARP */ >>> - if (virtio_dev_pause(dev) < 0) { >>> + if (virtio_dev_pause(dev) != 0) { >>> rte_pktmbuf_free(rarp_mbuf); >>> return; >>> } >>> diff --git a/drivers/net/virtio/virtio_ethdev.h >>> b/drivers/net/virtio/virtio_ethdev.h >>> index c08f382791..ece0130603 100644 >>> --- a/drivers/net/virtio/virtio_ethdev.h >>> +++ b/drivers/net/virtio/virtio_ethdev.h >>> @@ -112,8 +112,11 @@ int eth_virtio_dev_init(struct rte_eth_dev *eth_dev); >>> >>> void virtio_interrupt_handler(void *param); >>> >>> -int virtio_dev_pause(struct rte_eth_dev *dev); >>> -void virtio_dev_resume(struct rte_eth_dev *dev); >>> +#define VIRTIO_DEV_TO_HW(dev) ((struct virtio_hw *)(dev)->data- >>>> dev_private) >>> +int virtio_dev_pause(struct rte_eth_dev *dev) >>> + __rte_exclusive_trylock_function(0, &VIRTIO_DEV_TO_HW(dev)- >>>> state_lock); >> >> Just curious, why this is trylock instead of lock? > > I wrote this patch some time ago. > At the time, I must say that I preferred removing those helpers (the > only caller is virtio_notify_peers()). > It seems those helpers were added as a kind of api for future > usecases, it seemed a reason for keeping them. > So I changed my mind and just annotated them. > > > For your question, annotating with "lock" would tell clang that the > function always takes the lock, regardless of the function return > value. > > One alternative to this patch could be to always take the lock > (+annotate dev_pause as "lock"), and have the caller release the lock > if != 0 return value. > But it seems counterintuitive to me. > > WDYT? > > As discussed with David off-list, I think we could simplify and inline virtio_dev_pause()/virtio_dev_resume() into virtio_notify_peers() since there are no other users of these functions (see below). Any objection? diff --git a/drivers/net/virtio/virtio_ethdev.c b/drivers/net/virtio/virtio_ethdev.c index 0103d95920..dbd84e25ea 100644 --- a/drivers/net/virtio/virtio_ethdev.c +++ b/drivers/net/virtio/virtio_ethdev.c @@ -1144,43 +1144,10 @@ virtio_ethdev_negotiate_features(struct virtio_hw *hw, uint64_t req_features) return 0; } -int -virtio_dev_pause(struct rte_eth_dev *dev) -{ - struct virtio_hw *hw = dev->data->dev_private; - - rte_spinlock_lock(&hw->state_lock); - - if (hw->started == 0) { - /* Device is just stopped. */ - rte_spinlock_unlock(&hw->state_lock); - return -1; - } - hw->started = 0; - /* - * Prevent the worker threads from touching queues to avoid contention, - * 1 ms should be enough for the ongoing Tx function to finish. - */ - rte_delay_ms(1); - return 0; -} - -/* - * Recover hw state to let the worker threads continue. - */ -void -virtio_dev_resume(struct rte_eth_dev *dev) -{ - struct virtio_hw *hw = dev->data->dev_private; - - hw->started = 1; - rte_spinlock_unlock(&hw->state_lock); -} - /* * Should be called only after device is paused. */ -int +static int virtio_inject_pkts(struct rte_eth_dev *dev, struct rte_mbuf **tx_pkts, int nb_pkts) { @@ -1216,14 +1183,25 @@ virtio_notify_peers(struct rte_eth_dev *dev) return; } - /* If virtio port just stopped, no need to send RARP */ - if (virtio_dev_pause(dev) < 0) { + rte_spinlock_lock(&hw->state_lock); + + if (hw->started == 0) { + /* If virtio port just stopped, no need to send RARP */ rte_pktmbuf_free(rarp_mbuf); - return; + goto out_unlock; } + /* + * Prevent the worker threads from touching queues to avoid contention, + * 1 ms should be enough for the ongoing Tx function to finish. + */ + rte_delay_ms(1); + virtio_inject_pkts(dev, &rarp_mbuf, 1); - virtio_dev_resume(dev); + hw->started = 1; + +out_unlock: + rte_spinlock_unlock(&hw->state_lock); } static void diff --git a/drivers/net/virtio/virtio_ethdev.h b/drivers/net/virtio/virtio_ethdev.h index c08f382791..7be1c9acd0 100644 --- a/drivers/net/virtio/virtio_ethdev.h +++ b/drivers/net/virtio/virtio_ethdev.h @@ -112,12 +112,8 @@ int eth_virtio_dev_init(struct rte_eth_dev *eth_dev); void virtio_interrupt_handler(void *param); -int virtio_dev_pause(struct rte_eth_dev *dev); -void virtio_dev_resume(struct rte_eth_dev *dev); int virtio_dev_stop(struct rte_eth_dev *dev); int virtio_dev_close(struct rte_eth_dev *dev); -int virtio_inject_pkts(struct rte_eth_dev *dev, struct rte_mbuf **tx_pkts, - int nb_pkts); bool virtio_rx_check_scatter(uint16_t max_rx_pkt_len, uint16_t rx_buf_size, bool rx_scatter_enabled, const char **error);