From: Heng Qi <hengqi@linux.alibaba.com>
To: Willem de Bruijn <willemdebruijn.kernel@gmail.com>,
netdev@vger.kernel.org,
virtualization@lists.linux-foundation.org
Cc: Jason Wang <jasowang@redhat.com>,
"Michael S. Tsirkin" <mst@redhat.com>,
"David S. Miller" <davem@davemloft.net>,
Eric Dumazet <edumazet@google.com>,
Jakub Kicinski <kuba@kernel.org>, Paolo Abeni <pabeni@redhat.com>,
Alexei Starovoitov <ast@kernel.org>,
Xuan Zhuo <xuanzhuo@linux.alibaba.com>
Subject: Re: [PATCH net-next] virtio-net: switch napi_tx without downing nic
Date: Thu, 21 Dec 2023 13:18:20 +0800 [thread overview]
Message-ID: <084142b9-7e0d-4eae-82d2-0736494953cd@linux.alibaba.com> (raw)
In-Reply-To: <6582fe057cb9_1a34a429435@willemb.c.googlers.com.notmuch>
在 2023/12/20 下午10:45, Willem de Bruijn 写道:
> Heng Qi wrote:
>> virtio-net has two ways to switch napi_tx: one is through the
>> module parameter, and the other is through coalescing parameter
>> settings (provided that the nic status is down).
>>
>> Sometimes we face performance regression caused by napi_tx,
>> then we need to switch napi_tx when debugging. However, the
>> existing methods are a bit troublesome, such as needing to
>> reload the driver or turn off the network card. So try to make
>> this update.
>>
>> Signed-off-by: Heng Qi <hengqi@linux.alibaba.com>
>> Reviewed-by: Xuan Zhuo <xuanzhuo@linux.alibaba.com>
> The commit does not explain why it is safe to do so.
virtnet_napi_tx_disable ensures that already scheduled tx napi ends and
no new tx napi will be scheduled.
Afterwards, if the __netif_tx_lock_bh lock is held, the stack cannot
send the packet.
Then we can safely toggle the weight to indicate where to clear the buffers.
>
> The tx-napi weights are not really weights: it is a boolean whether
> napi is used for transmit cleaning, or whether packets are cleaned
> in ndo_start_xmit.
Right.
>
> There certainly are some subtle issues with regard to pausing/waking
> queues when switching between modes.
What are "subtle issues" and if there are any, we find them.
So far my test results show it's working fine.
>
> Calling napi_enable/napi_disable without bringing down the device is
> allowed. The actually napi.weight field is only updated when neither
> napi nor ndo_start_xmit is running.
YES.
> So I don't see an immediate issue.
Switching napi_tx requires reloading the driver or downing the nic,
which is troublesome.
I think it would be better if we could find a better way.
Thanks!
>
>
>> ---
>> drivers/net/virtio_net.c | 81 ++++++++++++++++++----------------------
>> 1 file changed, 37 insertions(+), 44 deletions(-)
>>
>> diff --git a/drivers/net/virtio_net.c b/drivers/net/virtio_net.c
>> index 10614e9f7cad..12f8e1f9971c 100644
>> --- a/drivers/net/virtio_net.c
>> +++ b/drivers/net/virtio_net.c
>> @@ -3559,16 +3559,37 @@ static int virtnet_coal_params_supported(struct ethtool_coalesce *ec)
>> return 0;
>> }
>>
>> -static int virtnet_should_update_vq_weight(int dev_flags, int weight,
>> - int vq_weight, bool *should_update)
>> +static void virtnet_switch_napi_tx(struct virtnet_info *vi, u32 qstart,
>> + u32 qend, u32 tx_frames)
>> {
>> - if (weight ^ vq_weight) {
>> - if (dev_flags & IFF_UP)
>> - return -EBUSY;
>> - *should_update = true;
>> - }
>> + struct net_device *dev = vi->dev;
>> + int new_weight, cur_weight;
>> + struct netdev_queue *txq;
>> + struct send_queue *sq;
>>
>> - return 0;
>> + new_weight = tx_frames ? NAPI_POLL_WEIGHT : 0;
>> + for (; qstart < qend; qstart++) {
>> + sq = &vi->sq[qstart];
>> + cur_weight = sq->napi.weight;
>> + if (!(new_weight ^ cur_weight))
>> + continue;
>> +
>> + if (!(dev->flags & IFF_UP)) {
>> + sq->napi.weight = new_weight;
>> + continue;
>> + }
>> +
>> + if (cur_weight)
>> + virtnet_napi_tx_disable(&sq->napi);
>> +
>> + txq = netdev_get_tx_queue(dev, qstart);
>> + __netif_tx_lock_bh(txq);
>> + sq->napi.weight = new_weight;
>> + __netif_tx_unlock_bh(txq);
>> +
>> + if (!cur_weight)
>> + virtnet_napi_tx_enable(vi, sq->vq, &sq->napi);
>> + }
>> }
>>
>> static int virtnet_set_coalesce(struct net_device *dev,
>> @@ -3577,25 +3598,11 @@ static int virtnet_set_coalesce(struct net_device *dev,
>> struct netlink_ext_ack *extack)
>> {
>> struct virtnet_info *vi = netdev_priv(dev);
>> - int ret, queue_number, napi_weight;
>> - bool update_napi = false;
>> -
>> - /* Can't change NAPI weight if the link is up */
>> - napi_weight = ec->tx_max_coalesced_frames ? NAPI_POLL_WEIGHT : 0;
>> - for (queue_number = 0; queue_number < vi->max_queue_pairs; queue_number++) {
>> - ret = virtnet_should_update_vq_weight(dev->flags, napi_weight,
>> - vi->sq[queue_number].napi.weight,
>> - &update_napi);
>> - if (ret)
>> - return ret;
>> -
>> - if (update_napi) {
>> - /* All queues that belong to [queue_number, vi->max_queue_pairs] will be
>> - * updated for the sake of simplicity, which might not be necessary
>> - */
>> - break;
>> - }
>> - }
>> + int ret;
>> +
>> + /* Param tx_frames can be used to switch napi_tx */
>> + virtnet_switch_napi_tx(vi, 0, vi->max_queue_pairs,
>> + ec->tx_max_coalesced_frames);
>>
>> if (virtio_has_feature(vi->vdev, VIRTIO_NET_F_NOTF_COAL))
>> ret = virtnet_send_notf_coal_cmds(vi, ec);
>> @@ -3605,11 +3612,6 @@ static int virtnet_set_coalesce(struct net_device *dev,
>> if (ret)
>> return ret;
>>
>> - if (update_napi) {
>> - for (; queue_number < vi->max_queue_pairs; queue_number++)
>> - vi->sq[queue_number].napi.weight = napi_weight;
>> - }
>> -
>> return ret;
>> }
>>
>> @@ -3641,19 +3643,13 @@ static int virtnet_set_per_queue_coalesce(struct net_device *dev,
>> struct ethtool_coalesce *ec)
>> {
>> struct virtnet_info *vi = netdev_priv(dev);
>> - int ret, napi_weight;
>> - bool update_napi = false;
>> + int ret;
>>
>> if (queue >= vi->max_queue_pairs)
>> return -EINVAL;
>>
>> - /* Can't change NAPI weight if the link is up */
>> - napi_weight = ec->tx_max_coalesced_frames ? NAPI_POLL_WEIGHT : 0;
>> - ret = virtnet_should_update_vq_weight(dev->flags, napi_weight,
>> - vi->sq[queue].napi.weight,
>> - &update_napi);
>> - if (ret)
>> - return ret;
>> + /* Param tx_frames can be used to switch napi_tx */
>> + virtnet_switch_napi_tx(vi, queue, queue, ec->tx_max_coalesced_frames);
>>
>> if (virtio_has_feature(vi->vdev, VIRTIO_NET_F_VQ_NOTF_COAL))
>> ret = virtnet_send_notf_coal_vq_cmds(vi, ec, queue);
>> @@ -3663,9 +3659,6 @@ static int virtnet_set_per_queue_coalesce(struct net_device *dev,
>> if (ret)
>> return ret;
>>
>> - if (update_napi)
>> - vi->sq[queue].napi.weight = napi_weight;
>> -
>> return 0;
>> }
>>
>> --
>> 2.19.1.6.gb485710b
>>
next prev parent reply other threads:[~2023-12-21 5:18 UTC|newest]
Thread overview: 18+ messages / expand[flat|nested] mbox.gz Atom feed top
2023-12-20 8:07 [PATCH net-next] virtio-net: switch napi_tx without downing nic Heng Qi
2023-12-20 14:45 ` Willem de Bruijn
2023-12-21 5:18 ` Heng Qi [this message]
2023-12-21 15:05 ` Willem de Bruijn
2023-12-22 2:35 ` Jason Wang
2023-12-22 8:14 ` Michael S. Tsirkin
2023-12-25 4:12 ` Jason Wang
2023-12-25 8:03 ` Michael S. Tsirkin
2023-12-26 3:32 ` Jason Wang
2023-12-25 2:24 ` Jason Xing
2023-12-25 4:14 ` Jason Wang
2023-12-25 6:33 ` Jason Xing
2023-12-25 6:44 ` Jason Wang
2023-12-25 6:47 ` Jason Wang
2023-12-25 7:52 ` Jason Xing
2023-12-21 3:02 ` Zhu Yanjun
2023-12-21 5:20 ` Heng Qi
2023-12-21 14:34 ` Zhu Yanjun
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=084142b9-7e0d-4eae-82d2-0736494953cd@linux.alibaba.com \
--to=hengqi@linux.alibaba.com \
--cc=ast@kernel.org \
--cc=davem@davemloft.net \
--cc=edumazet@google.com \
--cc=jasowang@redhat.com \
--cc=kuba@kernel.org \
--cc=mst@redhat.com \
--cc=netdev@vger.kernel.org \
--cc=pabeni@redhat.com \
--cc=virtualization@lists.linux-foundation.org \
--cc=willemdebruijn.kernel@gmail.com \
--cc=xuanzhuo@linux.alibaba.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.