From: Heng Qi <hengqi@linux.alibaba.com>
To: Daniel Jurgens <danielj@nvidia.com>
Cc: mst@redhat.com, jasowang@redhat.com, xuanzhuo@linux.alibaba.com,
virtualization@lists.linux.dev, davem@davemloft.net,
edumazet@google.com, kuba@kernel.org, pabeni@redhat.com,
jiri@nvidia.com,
"open list:NETWORKING DRIVERS" <netdev@vger.kernel.org>
Subject: Re: [PATCH net-next 2/4] virtio_net: Remove command data from control_buf
Date: Tue, 26 Mar 2024 15:06:39 +0800 [thread overview]
Message-ID: <413cc507-4cd0-431a-8efb-fab09cb2d490@linux.alibaba.com> (raw)
In-Reply-To: <20240325214912.323749-3-danielj@nvidia.com>
在 2024/3/26 上午5:49, Daniel Jurgens 写道:
> Allocate memory for the data when it's used. Ideally the could be on the
> stack, but we can't DMA stack memory. With this change only the header
> and status memory are shared between commands, which will allow using a
> tighter lock than RTNL.
>
> Signed-off-by: Daniel Jurgens <danielj@nvidia.com>
> Reviewed-by: Jiri Pirko <jiri@nvidia.com>
> ---
> drivers/net/virtio_net.c | 110 ++++++++++++++++++++++++++-------------
> 1 file changed, 74 insertions(+), 36 deletions(-)
>
> diff --git a/drivers/net/virtio_net.c b/drivers/net/virtio_net.c
> index 7419a68cf6e2..6780479a1e6c 100644
> --- a/drivers/net/virtio_net.c
> +++ b/drivers/net/virtio_net.c
> @@ -235,14 +235,6 @@ struct virtio_net_ctrl_rss {
> struct control_buf {
> struct virtio_net_ctrl_hdr hdr;
> virtio_net_ctrl_ack status;
> - struct virtio_net_ctrl_mq mq;
> - u8 promisc;
> - u8 allmulti;
> - __virtio16 vid;
> - __virtio64 offloads;
> - struct virtio_net_ctrl_coal_tx coal_tx;
> - struct virtio_net_ctrl_coal_rx coal_rx;
> - struct virtio_net_ctrl_coal_vq coal_vq;
> };
>
> struct virtnet_info {
> @@ -2654,14 +2646,19 @@ static void virtnet_ack_link_announce(struct virtnet_info *vi)
>
> static int _virtnet_set_queues(struct virtnet_info *vi, u16 queue_pairs)
> {
> + struct virtio_net_ctrl_mq *mq __free(kfree) = NULL;
> struct scatterlist sg;
> struct net_device *dev = vi->dev;
>
> if (!vi->has_cvq || !virtio_has_feature(vi->vdev, VIRTIO_NET_F_MQ))
> return 0;
>
> - vi->ctrl->mq.virtqueue_pairs = cpu_to_virtio16(vi->vdev, queue_pairs);
> - sg_init_one(&sg, &vi->ctrl->mq, sizeof(vi->ctrl->mq));
> + mq = kzalloc(sizeof(*mq), GFP_KERNEL);
> + if (!mq)
> + return -ENOMEM;
> +
> + mq->virtqueue_pairs = cpu_to_virtio16(vi->vdev, queue_pairs);
> + sg_init_one(&sg, mq, sizeof(*mq));
>
> if (!virtnet_send_command(vi, VIRTIO_NET_CTRL_MQ,
> VIRTIO_NET_CTRL_MQ_VQ_PAIRS_SET, &sg)) {
> @@ -2708,6 +2705,7 @@ static int virtnet_close(struct net_device *dev)
>
> static void virtnet_set_rx_mode(struct net_device *dev)
You need to rebase next branch in the next version,
.ndo_set_rx_mode has been completed using workqueue in that.
Regards,
Heng
> {
> + u8 *promisc_allmulti __free(kfree) = NULL;
> struct virtnet_info *vi = netdev_priv(dev);
> struct scatterlist sg[2];
> struct virtio_net_ctrl_mac *mac_data;
> @@ -2721,22 +2719,27 @@ static void virtnet_set_rx_mode(struct net_device *dev)
> if (!virtio_has_feature(vi->vdev, VIRTIO_NET_F_CTRL_RX))
> return;
>
> - vi->ctrl->promisc = ((dev->flags & IFF_PROMISC) != 0);
> - vi->ctrl->allmulti = ((dev->flags & IFF_ALLMULTI) != 0);
> + promisc_allmulti = kzalloc(sizeof(*promisc_allmulti), GFP_ATOMIC);
> + if (!promisc_allmulti) {
> + dev_warn(&dev->dev, "Failed to set RX mode, no memory.\n");
> + return;
> + }
>
> - sg_init_one(sg, &vi->ctrl->promisc, sizeof(vi->ctrl->promisc));
> + *promisc_allmulti = !!(dev->flags & IFF_PROMISC);
> + sg_init_one(sg, promisc_allmulti, sizeof(*promisc_allmulti));
>
> if (!virtnet_send_command(vi, VIRTIO_NET_CTRL_RX,
> VIRTIO_NET_CTRL_RX_PROMISC, sg))
> dev_warn(&dev->dev, "Failed to %sable promisc mode.\n",
> - vi->ctrl->promisc ? "en" : "dis");
> + *promisc_allmulti ? "en" : "dis");
>
> - sg_init_one(sg, &vi->ctrl->allmulti, sizeof(vi->ctrl->allmulti));
> + *promisc_allmulti = !!(dev->flags & IFF_ALLMULTI);
> + sg_init_one(sg, promisc_allmulti, sizeof(*promisc_allmulti));
>
> if (!virtnet_send_command(vi, VIRTIO_NET_CTRL_RX,
> VIRTIO_NET_CTRL_RX_ALLMULTI, sg))
> dev_warn(&dev->dev, "Failed to %sable allmulti mode.\n",
> - vi->ctrl->allmulti ? "en" : "dis");
> + *promisc_allmulti ? "en" : "dis");
>
> uc_count = netdev_uc_count(dev);
> mc_count = netdev_mc_count(dev);
> @@ -2780,10 +2783,15 @@ static int virtnet_vlan_rx_add_vid(struct net_device *dev,
> __be16 proto, u16 vid)
> {
> struct virtnet_info *vi = netdev_priv(dev);
> + __virtio16 *_vid __free(kfree) = NULL;
> struct scatterlist sg;
>
> - vi->ctrl->vid = cpu_to_virtio16(vi->vdev, vid);
> - sg_init_one(&sg, &vi->ctrl->vid, sizeof(vi->ctrl->vid));
> + _vid = kzalloc(sizeof(*_vid), GFP_KERNEL);
> + if (!_vid)
> + return -ENOMEM;
> +
> + *_vid = cpu_to_virtio16(vi->vdev, vid);
> + sg_init_one(&sg, _vid, sizeof(*_vid));
>
> if (!virtnet_send_command(vi, VIRTIO_NET_CTRL_VLAN,
> VIRTIO_NET_CTRL_VLAN_ADD, &sg))
> @@ -2795,10 +2803,15 @@ static int virtnet_vlan_rx_kill_vid(struct net_device *dev,
> __be16 proto, u16 vid)
> {
> struct virtnet_info *vi = netdev_priv(dev);
> + __virtio16 *_vid __free(kfree) = NULL;
> struct scatterlist sg;
>
> - vi->ctrl->vid = cpu_to_virtio16(vi->vdev, vid);
> - sg_init_one(&sg, &vi->ctrl->vid, sizeof(vi->ctrl->vid));
> + _vid = kzalloc(sizeof(*_vid), GFP_KERNEL);
> + if (!_vid)
> + return -ENOMEM;
> +
> + *_vid = cpu_to_virtio16(vi->vdev, vid);
> + sg_init_one(&sg, _vid, sizeof(*_vid));
>
> if (!virtnet_send_command(vi, VIRTIO_NET_CTRL_VLAN,
> VIRTIO_NET_CTRL_VLAN_DEL, &sg))
> @@ -2911,12 +2924,17 @@ static void virtnet_cpu_notif_remove(struct virtnet_info *vi)
> static int virtnet_send_ctrl_coal_vq_cmd(struct virtnet_info *vi,
> u16 vqn, u32 max_usecs, u32 max_packets)
> {
> + struct virtio_net_ctrl_coal_vq *coal_vq __free(kfree) = NULL;
> struct scatterlist sgs;
>
> - vi->ctrl->coal_vq.vqn = cpu_to_le16(vqn);
> - vi->ctrl->coal_vq.coal.max_usecs = cpu_to_le32(max_usecs);
> - vi->ctrl->coal_vq.coal.max_packets = cpu_to_le32(max_packets);
> - sg_init_one(&sgs, &vi->ctrl->coal_vq, sizeof(vi->ctrl->coal_vq));
> + coal_vq = kzalloc(sizeof(*coal_vq), GFP_KERNEL);
> + if (!coal_vq)
> + return -ENOMEM;
> +
> + coal_vq->vqn = cpu_to_le16(vqn);
> + coal_vq->coal.max_usecs = cpu_to_le32(max_usecs);
> + coal_vq->coal.max_packets = cpu_to_le32(max_packets);
> + sg_init_one(&sgs, coal_vq, sizeof(*coal_vq));
>
> if (!virtnet_send_command(vi, VIRTIO_NET_CTRL_NOTF_COAL,
> VIRTIO_NET_CTRL_NOTF_COAL_VQ_SET,
> @@ -3062,11 +3080,15 @@ static bool virtnet_commit_rss_command(struct virtnet_info *vi)
>
> if (!virtnet_send_command(vi, VIRTIO_NET_CTRL_MQ,
> vi->has_rss ? VIRTIO_NET_CTRL_MQ_RSS_CONFIG
> - : VIRTIO_NET_CTRL_MQ_HASH_CONFIG, sgs)) {
> - dev_warn(&dev->dev, "VIRTIONET issue with committing RSS sgs\n");
> - return false;
> - }
> + : VIRTIO_NET_CTRL_MQ_HASH_CONFIG, sgs))
> + goto err;
> +
> return true;
> +
> +err:
> + dev_warn(&dev->dev, "VIRTIONET issue with committing RSS sgs\n");
> + return false;
> +
> }
>
> static void virtnet_init_default_rss(struct virtnet_info *vi)
> @@ -3371,12 +3393,17 @@ static int virtnet_get_link_ksettings(struct net_device *dev,
> static int virtnet_send_tx_notf_coal_cmds(struct virtnet_info *vi,
> struct ethtool_coalesce *ec)
> {
> + struct virtio_net_ctrl_coal_tx *coal_tx __free(kfree) = NULL;
> struct scatterlist sgs_tx;
> int i;
>
> - vi->ctrl->coal_tx.tx_usecs = cpu_to_le32(ec->tx_coalesce_usecs);
> - vi->ctrl->coal_tx.tx_max_packets = cpu_to_le32(ec->tx_max_coalesced_frames);
> - sg_init_one(&sgs_tx, &vi->ctrl->coal_tx, sizeof(vi->ctrl->coal_tx));
> + coal_tx = kzalloc(sizeof(*coal_tx), GFP_KERNEL);
> + if (!coal_tx)
> + return -ENOMEM;
> +
> + coal_tx->tx_usecs = cpu_to_le32(ec->tx_coalesce_usecs);
> + coal_tx->tx_max_packets = cpu_to_le32(ec->tx_max_coalesced_frames);
> + sg_init_one(&sgs_tx, coal_tx, sizeof(*coal_tx));
>
> if (!virtnet_send_command(vi, VIRTIO_NET_CTRL_NOTF_COAL,
> VIRTIO_NET_CTRL_NOTF_COAL_TX_SET,
> @@ -3396,6 +3423,7 @@ static int virtnet_send_tx_notf_coal_cmds(struct virtnet_info *vi,
> static int virtnet_send_rx_notf_coal_cmds(struct virtnet_info *vi,
> struct ethtool_coalesce *ec)
> {
> + struct virtio_net_ctrl_coal_rx *coal_rx __free(kfree) = NULL;
> bool rx_ctrl_dim_on = !!ec->use_adaptive_rx_coalesce;
> struct scatterlist sgs_rx;
> int i;
> @@ -3414,6 +3442,10 @@ static int virtnet_send_rx_notf_coal_cmds(struct virtnet_info *vi,
> return 0;
> }
>
> + coal_rx = kzalloc(sizeof(*coal_rx), GFP_KERNEL);
> + if (!coal_rx)
> + return -ENOMEM;
> +
> if (!rx_ctrl_dim_on && vi->rx_dim_enabled) {
> vi->rx_dim_enabled = false;
> for (i = 0; i < vi->max_queue_pairs; i++)
> @@ -3424,9 +3456,9 @@ static int virtnet_send_rx_notf_coal_cmds(struct virtnet_info *vi,
> * we need apply the global new params even if they
> * are not updated.
> */
> - vi->ctrl->coal_rx.rx_usecs = cpu_to_le32(ec->rx_coalesce_usecs);
> - vi->ctrl->coal_rx.rx_max_packets = cpu_to_le32(ec->rx_max_coalesced_frames);
> - sg_init_one(&sgs_rx, &vi->ctrl->coal_rx, sizeof(vi->ctrl->coal_rx));
> + coal_rx->rx_usecs = cpu_to_le32(ec->rx_coalesce_usecs);
> + coal_rx->rx_max_packets = cpu_to_le32(ec->rx_max_coalesced_frames);
> + sg_init_one(&sgs_rx, coal_rx, sizeof(*coal_rx));
>
> if (!virtnet_send_command(vi, VIRTIO_NET_CTRL_NOTF_COAL,
> VIRTIO_NET_CTRL_NOTF_COAL_RX_SET,
> @@ -3893,10 +3925,16 @@ static int virtnet_restore_up(struct virtio_device *vdev)
>
> static int virtnet_set_guest_offloads(struct virtnet_info *vi, u64 offloads)
> {
> + u64 *_offloads __free(kfree) = NULL;
> struct scatterlist sg;
> - vi->ctrl->offloads = cpu_to_virtio64(vi->vdev, offloads);
>
> - sg_init_one(&sg, &vi->ctrl->offloads, sizeof(vi->ctrl->offloads));
> + _offloads = kzalloc(sizeof(*_offloads), GFP_KERNEL);
> + if (!_offloads)
> + return -ENOMEM;
> +
> + *_offloads = cpu_to_virtio64(vi->vdev, offloads);
> +
> + sg_init_one(&sg, _offloads, sizeof(*_offloads));
>
> if (!virtnet_send_command(vi, VIRTIO_NET_CTRL_GUEST_OFFLOADS,
> VIRTIO_NET_CTRL_GUEST_OFFLOADS_SET, &sg)) {
next prev parent reply other threads:[~2024-03-26 7:06 UTC|newest]
Thread overview: 16+ messages / expand[flat|nested] mbox.gz Atom feed top
2024-03-25 21:49 [PATCH net-next 0/4] Remove RTNL lock protection of CVQ Daniel Jurgens
2024-03-25 21:49 ` [PATCH net-next 1/4] virtio_net: Store RSS setting in virtnet_info Daniel Jurgens
2024-03-25 21:49 ` [PATCH net-next 2/4] virtio_net: Remove command data from control_buf Daniel Jurgens
2024-03-26 7:06 ` Heng Qi [this message]
2024-03-28 13:35 ` Simon Horman
2024-03-28 15:29 ` Michael S. Tsirkin
2024-03-25 21:49 ` [PATCH net-next 3/4] virtio_net: Add a lock for the command VQ Daniel Jurgens
2024-03-25 21:49 ` [PATCH net-next 4/4] virtio_net: Remove rtnl lock protection of command buffers Daniel Jurgens
2024-03-26 8:54 ` Heng Qi
2024-03-26 15:18 ` Dan Jurgens
2024-03-27 2:10 ` Heng Qi
2024-03-27 12:00 ` Heng Qi
2024-03-26 1:33 ` [PATCH net-next 0/4] Remove RTNL lock protection of CVQ Xuan Zhuo
2024-03-26 2:54 ` Heng Qi
2024-03-26 4:11 ` Dan Jurgens
2024-03-26 6:05 ` Heng Qi
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=413cc507-4cd0-431a-8efb-fab09cb2d490@linux.alibaba.com \
--to=hengqi@linux.alibaba.com \
--cc=danielj@nvidia.com \
--cc=davem@davemloft.net \
--cc=edumazet@google.com \
--cc=jasowang@redhat.com \
--cc=jiri@nvidia.com \
--cc=kuba@kernel.org \
--cc=mst@redhat.com \
--cc=netdev@vger.kernel.org \
--cc=pabeni@redhat.com \
--cc=virtualization@lists.linux.dev \
--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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).