[PATCH v2 11/20] net/virtio: annotate lock for guest announce
Maxime Coquelin
maxime.coquelin at redhat.com
Mon Feb 27 17:28:09 CET 2023
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 <chenbo.xia at intel.com> 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);
More information about the dev
mailing list