* [PATCH net v2 1/2] virtio_net: Do not set rss_indir if RSS is not supported @ 2024-03-26 15:19 Breno Leitao 2024-03-26 15:19 ` [PATCH net v2 2/2] virtio_net: Do not send RSS key if it " Breno Leitao 2024-03-27 1:37 ` [PATCH net v2 1/2] virtio_net: Do not set rss_indir if RSS " Xuan Zhuo 0 siblings, 2 replies; 9+ messages in thread From: Breno Leitao @ 2024-03-26 15:19 UTC (permalink / raw) To: hengqi, xuanzhuo, Michael S. Tsirkin, Jason Wang, David S. Miller, Eric Dumazet, Jakub Kicinski, Paolo Abeni Cc: rbc, riel, open list:VIRTIO CORE AND NET DRIVERS, open list:NETWORKING DRIVERS, open list Do not set virtnet_info->rss_indir_table_size if RSS is not available for the device. Currently, rss_indir_table_size is set if either has_rss or has_rss_hash_report is available, but, it should only be set if has_rss is set. On the virtnet_set_rxfh(), return an invalid command if the request has indirection table set, but virtnet does not support RSS. Suggested-by: Heng Qi <hengqi@linux.alibaba.com> Signed-off-by: Breno Leitao <leitao@debian.org> --- drivers/net/virtio_net.c | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/drivers/net/virtio_net.c b/drivers/net/virtio_net.c index c22d1118a133..c640fdf28fc5 100644 --- a/drivers/net/virtio_net.c +++ b/drivers/net/virtio_net.c @@ -3813,6 +3813,9 @@ static int virtnet_set_rxfh(struct net_device *dev, rxfh->hfunc != ETH_RSS_HASH_TOP) return -EOPNOTSUPP; + if (rxfh->indir && !vi->has_rss) + return -EINVAL; + if (rxfh->indir) { for (i = 0; i < vi->rss_indir_table_size; ++i) vi->ctrl->rss.indirection_table[i] = rxfh->indir[i]; @@ -4729,13 +4732,15 @@ static int virtnet_probe(struct virtio_device *vdev) if (virtio_has_feature(vdev, VIRTIO_NET_F_HASH_REPORT)) vi->has_rss_hash_report = true; - if (virtio_has_feature(vdev, VIRTIO_NET_F_RSS)) + if (virtio_has_feature(vdev, VIRTIO_NET_F_RSS)) { vi->has_rss = true; - if (vi->has_rss || vi->has_rss_hash_report) { vi->rss_indir_table_size = virtio_cread16(vdev, offsetof(struct virtio_net_config, rss_max_indirection_table_length)); + } + + if (vi->has_rss || vi->has_rss_hash_report) { vi->rss_key_size = virtio_cread8(vdev, offsetof(struct virtio_net_config, rss_max_key_size)); -- 2.43.0 ^ permalink raw reply related [flat|nested] 9+ messages in thread
* [PATCH net v2 2/2] virtio_net: Do not send RSS key if it is not supported 2024-03-26 15:19 [PATCH net v2 1/2] virtio_net: Do not set rss_indir if RSS is not supported Breno Leitao @ 2024-03-26 15:19 ` Breno Leitao 2024-03-27 2:27 ` Heng Qi 2024-03-27 1:37 ` [PATCH net v2 1/2] virtio_net: Do not set rss_indir if RSS " Xuan Zhuo 1 sibling, 1 reply; 9+ messages in thread From: Breno Leitao @ 2024-03-26 15:19 UTC (permalink / raw) To: hengqi, xuanzhuo, Michael S. Tsirkin, Jason Wang, David S. Miller, Eric Dumazet, Jakub Kicinski, Paolo Abeni, Andrew Melnychenko Cc: rbc, riel, stable, qemu-devel, open list:VIRTIO CORE AND NET DRIVERS, open list:NETWORKING DRIVERS, open list There is a bug when setting the RSS options in virtio_net that can break the whole machine, getting the kernel into an infinite loop. Running the following command in any QEMU virtual machine with virtionet will reproduce this problem: # ethtool -X eth0 hfunc toeplitz This is how the problem happens: 1) ethtool_set_rxfh() calls virtnet_set_rxfh() 2) virtnet_set_rxfh() calls virtnet_commit_rss_command() 3) virtnet_commit_rss_command() populates 4 entries for the rss scatter-gather 4) Since the command above does not have a key, then the last scatter-gatter entry will be zeroed, since rss_key_size == 0. sg_buf_size = vi->rss_key_size; 5) This buffer is passed to qemu, but qemu is not happy with a buffer with zero length, and do the following in virtqueue_map_desc() (QEMU function): if (!sz) { virtio_error(vdev, "virtio: zero sized buffers are not allowed"); 6) virtio_error() (also QEMU function) set the device as broken vdev->broken = true; 7) Qemu bails out, and do not repond this crazy kernel. 8) The kernel is waiting for the response to come back (function virtnet_send_command()) 9) The kernel is waiting doing the following : while (!virtqueue_get_buf(vi->cvq, &tmp) && !virtqueue_is_broken(vi->cvq)) cpu_relax(); 10) None of the following functions above is true, thus, the kernel loops here forever. Keeping in mind that virtqueue_is_broken() does not look at the qemu `vdev->broken`, so, it never realizes that the vitio is broken at QEMU side. Fix it by not sending RSS commands if the feature is not available in the device. Fixes: c7114b1249fa ("drivers/net/virtio_net: Added basic RSS support.") Cc: stable@vger.kernel.org Cc: qemu-devel@nongnu.org Signed-off-by: Breno Leitao <leitao@debian.org> --- drivers/net/virtio_net.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/drivers/net/virtio_net.c b/drivers/net/virtio_net.c index c640fdf28fc5..e6b0eaf08ac2 100644 --- a/drivers/net/virtio_net.c +++ b/drivers/net/virtio_net.c @@ -3809,6 +3809,9 @@ static int virtnet_set_rxfh(struct net_device *dev, struct virtnet_info *vi = netdev_priv(dev); int i; + if (!vi->has_rss && !vi->has_rss_hash_report) + return -EOPNOTSUPP; + if (rxfh->hfunc != ETH_RSS_HASH_NO_CHANGE && rxfh->hfunc != ETH_RSS_HASH_TOP) return -EOPNOTSUPP; -- 2.43.0 ^ permalink raw reply related [flat|nested] 9+ messages in thread
* Re: [PATCH net v2 2/2] virtio_net: Do not send RSS key if it is not supported 2024-03-26 15:19 ` [PATCH net v2 2/2] virtio_net: Do not send RSS key if it " Breno Leitao @ 2024-03-27 2:27 ` Heng Qi 2024-03-27 13:44 ` Breno Leitao 0 siblings, 1 reply; 9+ messages in thread From: Heng Qi @ 2024-03-27 2:27 UTC (permalink / raw) To: Breno Leitao, xuanzhuo, Michael S. Tsirkin, Jason Wang, David S. Miller, Eric Dumazet, Jakub Kicinski, Paolo Abeni, Andrew Melnychenko Cc: rbc, riel, stable, qemu-devel, open list:VIRTIO CORE AND NET DRIVERS, open list:NETWORKING DRIVERS, open list 在 2024/3/26 下午11:19, Breno Leitao 写道: > There is a bug when setting the RSS options in virtio_net that can break > the whole machine, getting the kernel into an infinite loop. > > Running the following command in any QEMU virtual machine with virtionet > will reproduce this problem: > > # ethtool -X eth0 hfunc toeplitz > > This is how the problem happens: > > 1) ethtool_set_rxfh() calls virtnet_set_rxfh() > > 2) virtnet_set_rxfh() calls virtnet_commit_rss_command() > > 3) virtnet_commit_rss_command() populates 4 entries for the rss > scatter-gather > > 4) Since the command above does not have a key, then the last > scatter-gatter entry will be zeroed, since rss_key_size == 0. > sg_buf_size = vi->rss_key_size; > > 5) This buffer is passed to qemu, but qemu is not happy with a buffer > with zero length, and do the following in virtqueue_map_desc() (QEMU > function): > > if (!sz) { > virtio_error(vdev, "virtio: zero sized buffers are not allowed"); > > 6) virtio_error() (also QEMU function) set the device as broken > > vdev->broken = true; > > 7) Qemu bails out, and do not repond this crazy kernel. > > 8) The kernel is waiting for the response to come back (function > virtnet_send_command()) > > 9) The kernel is waiting doing the following : > > while (!virtqueue_get_buf(vi->cvq, &tmp) && > !virtqueue_is_broken(vi->cvq)) > cpu_relax(); > > 10) None of the following functions above is true, thus, the kernel > loops here forever. Keeping in mind that virtqueue_is_broken() does > not look at the qemu `vdev->broken`, so, it never realizes that the > vitio is broken at QEMU side. > > Fix it by not sending RSS commands if the feature is not available in > the device. > > Fixes: c7114b1249fa ("drivers/net/virtio_net: Added basic RSS support.") > Cc: stable@vger.kernel.org > Cc: qemu-devel@nongnu.org > Signed-off-by: Breno Leitao <leitao@debian.org> > --- > drivers/net/virtio_net.c | 3 +++ > 1 file changed, 3 insertions(+) > > diff --git a/drivers/net/virtio_net.c b/drivers/net/virtio_net.c > index c640fdf28fc5..e6b0eaf08ac2 100644 > --- a/drivers/net/virtio_net.c > +++ b/drivers/net/virtio_net.c > @@ -3809,6 +3809,9 @@ static int virtnet_set_rxfh(struct net_device *dev, > struct virtnet_info *vi = netdev_priv(dev); > int i; > > + if (!vi->has_rss && !vi->has_rss_hash_report) > + return -EOPNOTSUPP; > + Why not make the second patch as the first, this seems to work better. Or squash them into one patch. Apart from these and Xuan's comments. For series: Reviewed-by: Heng Qi <hengqi@linux.alibaba.com> Regards, Heng > if (rxfh->hfunc != ETH_RSS_HASH_NO_CHANGE && > rxfh->hfunc != ETH_RSS_HASH_TOP) > return -EOPNOTSUPP; ^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [PATCH net v2 2/2] virtio_net: Do not send RSS key if it is not supported 2024-03-27 2:27 ` Heng Qi @ 2024-03-27 13:44 ` Breno Leitao 0 siblings, 0 replies; 9+ messages in thread From: Breno Leitao @ 2024-03-27 13:44 UTC (permalink / raw) To: Heng Qi Cc: xuanzhuo, Michael S. Tsirkin, Jason Wang, David S. Miller, Eric Dumazet, Jakub Kicinski, Paolo Abeni, Andrew Melnychenko, rbc, riel, stable, qemu-devel, open list:VIRTIO CORE AND NET DRIVERS, open list:NETWORKING DRIVERS, open list On Wed, Mar 27, 2024 at 10:27:58AM +0800, Heng Qi wrote: > > > 在 2024/3/26 下午11:19, Breno Leitao 写道: > > There is a bug when setting the RSS options in virtio_net that can break > > the whole machine, getting the kernel into an infinite loop. > > > > Running the following command in any QEMU virtual machine with virtionet > > will reproduce this problem: > > > > # ethtool -X eth0 hfunc toeplitz > > > > This is how the problem happens: > > > > 1) ethtool_set_rxfh() calls virtnet_set_rxfh() > > > > 2) virtnet_set_rxfh() calls virtnet_commit_rss_command() > > > > 3) virtnet_commit_rss_command() populates 4 entries for the rss > > scatter-gather > > > > 4) Since the command above does not have a key, then the last > > scatter-gatter entry will be zeroed, since rss_key_size == 0. > > sg_buf_size = vi->rss_key_size; > > > > 5) This buffer is passed to qemu, but qemu is not happy with a buffer > > with zero length, and do the following in virtqueue_map_desc() (QEMU > > function): > > > > if (!sz) { > > virtio_error(vdev, "virtio: zero sized buffers are not allowed"); > > > > 6) virtio_error() (also QEMU function) set the device as broken > > > > vdev->broken = true; > > > > 7) Qemu bails out, and do not repond this crazy kernel. > > > > 8) The kernel is waiting for the response to come back (function > > virtnet_send_command()) > > > > 9) The kernel is waiting doing the following : > > > > while (!virtqueue_get_buf(vi->cvq, &tmp) && > > !virtqueue_is_broken(vi->cvq)) > > cpu_relax(); > > > > 10) None of the following functions above is true, thus, the kernel > > loops here forever. Keeping in mind that virtqueue_is_broken() does > > not look at the qemu `vdev->broken`, so, it never realizes that the > > vitio is broken at QEMU side. > > > > Fix it by not sending RSS commands if the feature is not available in > > the device. > > > > Fixes: c7114b1249fa ("drivers/net/virtio_net: Added basic RSS support.") > > Cc: stable@vger.kernel.org > > Cc: qemu-devel@nongnu.org > > Signed-off-by: Breno Leitao <leitao@debian.org> > > --- > > drivers/net/virtio_net.c | 3 +++ > > 1 file changed, 3 insertions(+) > > > > diff --git a/drivers/net/virtio_net.c b/drivers/net/virtio_net.c > > index c640fdf28fc5..e6b0eaf08ac2 100644 > > --- a/drivers/net/virtio_net.c > > +++ b/drivers/net/virtio_net.c > > @@ -3809,6 +3809,9 @@ static int virtnet_set_rxfh(struct net_device *dev, > > struct virtnet_info *vi = netdev_priv(dev); > > int i; > > + if (!vi->has_rss && !vi->has_rss_hash_report) > > + return -EOPNOTSUPP; > > + > > Why not make the second patch as the first, this seems to work better. Sure, that works for me. Let me update it in v2. ^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [PATCH net v2 1/2] virtio_net: Do not set rss_indir if RSS is not supported 2024-03-26 15:19 [PATCH net v2 1/2] virtio_net: Do not set rss_indir if RSS is not supported Breno Leitao 2024-03-26 15:19 ` [PATCH net v2 2/2] virtio_net: Do not send RSS key if it " Breno Leitao @ 2024-03-27 1:37 ` Xuan Zhuo 2024-03-27 13:51 ` Breno Leitao 1 sibling, 1 reply; 9+ messages in thread From: Xuan Zhuo @ 2024-03-27 1:37 UTC (permalink / raw) To: Breno Leitao Cc: rbc, riel, open list:VIRTIO CORE AND NET DRIVERS, open list:NETWORKING DRIVERS, open list, hengqi, Michael S. Tsirkin, Jason Wang, David S. Miller, Eric Dumazet, Jakub Kicinski, Paolo Abeni On Tue, 26 Mar 2024 08:19:08 -0700, Breno Leitao <leitao@debian.org> wrote: > Do not set virtnet_info->rss_indir_table_size if RSS is not available > for the device. > > Currently, rss_indir_table_size is set if either has_rss or > has_rss_hash_report is available, but, it should only be set if has_rss > is set. > > On the virtnet_set_rxfh(), return an invalid command if the request has > indirection table set, but virtnet does not support RSS. > > Suggested-by: Heng Qi <hengqi@linux.alibaba.com> > Signed-off-by: Breno Leitao <leitao@debian.org> > --- > drivers/net/virtio_net.c | 9 +++++++-- > 1 file changed, 7 insertions(+), 2 deletions(-) > > diff --git a/drivers/net/virtio_net.c b/drivers/net/virtio_net.c > index c22d1118a133..c640fdf28fc5 100644 > --- a/drivers/net/virtio_net.c > +++ b/drivers/net/virtio_net.c > @@ -3813,6 +3813,9 @@ static int virtnet_set_rxfh(struct net_device *dev, > rxfh->hfunc != ETH_RSS_HASH_TOP) > return -EOPNOTSUPP; > > + if (rxfh->indir && !vi->has_rss) > + return -EINVAL; > + > if (rxfh->indir) { Put !vi->has_rss here? Thanks. > for (i = 0; i < vi->rss_indir_table_size; ++i) > vi->ctrl->rss.indirection_table[i] = rxfh->indir[i]; > @@ -4729,13 +4732,15 @@ static int virtnet_probe(struct virtio_device *vdev) > if (virtio_has_feature(vdev, VIRTIO_NET_F_HASH_REPORT)) > vi->has_rss_hash_report = true; > > - if (virtio_has_feature(vdev, VIRTIO_NET_F_RSS)) > + if (virtio_has_feature(vdev, VIRTIO_NET_F_RSS)) { > vi->has_rss = true; > > - if (vi->has_rss || vi->has_rss_hash_report) { > vi->rss_indir_table_size = > virtio_cread16(vdev, offsetof(struct virtio_net_config, > rss_max_indirection_table_length)); > + } > + > + if (vi->has_rss || vi->has_rss_hash_report) { > vi->rss_key_size = > virtio_cread8(vdev, offsetof(struct virtio_net_config, rss_max_key_size)); > > -- > 2.43.0 > ^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [PATCH net v2 1/2] virtio_net: Do not set rss_indir if RSS is not supported 2024-03-27 1:37 ` [PATCH net v2 1/2] virtio_net: Do not set rss_indir if RSS " Xuan Zhuo @ 2024-03-27 13:51 ` Breno Leitao 2024-03-28 1:28 ` Xuan Zhuo 0 siblings, 1 reply; 9+ messages in thread From: Breno Leitao @ 2024-03-27 13:51 UTC (permalink / raw) To: Xuan Zhuo Cc: rbc, riel, open list:VIRTIO CORE AND NET DRIVERS, open list:NETWORKING DRIVERS, open list, hengqi, Michael S. Tsirkin, Jason Wang, David S. Miller, Eric Dumazet, Jakub Kicinski, Paolo Abeni Hello Xuan, On Wed, Mar 27, 2024 at 09:37:43AM +0800, Xuan Zhuo wrote: > On Tue, 26 Mar 2024 08:19:08 -0700, Breno Leitao <leitao@debian.org> wrote: > > Do not set virtnet_info->rss_indir_table_size if RSS is not available > > for the device. > > > > Currently, rss_indir_table_size is set if either has_rss or > > has_rss_hash_report is available, but, it should only be set if has_rss > > is set. > > > > On the virtnet_set_rxfh(), return an invalid command if the request has > > indirection table set, but virtnet does not support RSS. > > > > Suggested-by: Heng Qi <hengqi@linux.alibaba.com> > > Signed-off-by: Breno Leitao <leitao@debian.org> > > --- > > drivers/net/virtio_net.c | 9 +++++++-- > > 1 file changed, 7 insertions(+), 2 deletions(-) > > > > diff --git a/drivers/net/virtio_net.c b/drivers/net/virtio_net.c > > index c22d1118a133..c640fdf28fc5 100644 > > --- a/drivers/net/virtio_net.c > > +++ b/drivers/net/virtio_net.c > > @@ -3813,6 +3813,9 @@ static int virtnet_set_rxfh(struct net_device *dev, > > rxfh->hfunc != ETH_RSS_HASH_TOP) > > return -EOPNOTSUPP; > > > > + if (rxfh->indir && !vi->has_rss) > > + return -EINVAL; > > + > > if (rxfh->indir) { > > Put !vi->has_rss here? I am not sure I understand the suggestion. Where do you suggest we have !vi->has_rss? If we got this far, we either have: a) rxfh->indir set and vi->has_rss is also set b) rxfh->indir not set. (vi->has_rss could be set or not). Thanks for the review, Breno ^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [PATCH net v2 1/2] virtio_net: Do not set rss_indir if RSS is not supported 2024-03-27 13:51 ` Breno Leitao @ 2024-03-28 1:28 ` Xuan Zhuo 2024-03-28 14:37 ` Breno Leitao 0 siblings, 1 reply; 9+ messages in thread From: Xuan Zhuo @ 2024-03-28 1:28 UTC (permalink / raw) To: Breno Leitao Cc: rbc, riel, open list:VIRTIO CORE AND NET DRIVERS, open list:NETWORKING DRIVERS, open list, hengqi, Michael S. Tsirkin, Jason Wang, David S. Miller, Eric Dumazet, Jakub Kicinski, Paolo Abeni On Wed, 27 Mar 2024 06:51:25 -0700, Breno Leitao <leitao@debian.org> wrote: > Hello Xuan, > > On Wed, Mar 27, 2024 at 09:37:43AM +0800, Xuan Zhuo wrote: > > On Tue, 26 Mar 2024 08:19:08 -0700, Breno Leitao <leitao@debian.org> wrote: > > > Do not set virtnet_info->rss_indir_table_size if RSS is not available > > > for the device. > > > > > > Currently, rss_indir_table_size is set if either has_rss or > > > has_rss_hash_report is available, but, it should only be set if has_rss > > > is set. > > > > > > On the virtnet_set_rxfh(), return an invalid command if the request has > > > indirection table set, but virtnet does not support RSS. > > > > > > Suggested-by: Heng Qi <hengqi@linux.alibaba.com> > > > Signed-off-by: Breno Leitao <leitao@debian.org> > > > --- > > > drivers/net/virtio_net.c | 9 +++++++-- > > > 1 file changed, 7 insertions(+), 2 deletions(-) > > > > > > diff --git a/drivers/net/virtio_net.c b/drivers/net/virtio_net.c > > > index c22d1118a133..c640fdf28fc5 100644 > > > --- a/drivers/net/virtio_net.c > > > +++ b/drivers/net/virtio_net.c > > > @@ -3813,6 +3813,9 @@ static int virtnet_set_rxfh(struct net_device *dev, > > > rxfh->hfunc != ETH_RSS_HASH_TOP) > > > return -EOPNOTSUPP; > > > > > > + if (rxfh->indir && !vi->has_rss) > > > + return -EINVAL; > > > + > > > if (rxfh->indir) { > > > > Put !vi->has_rss here? > > I am not sure I understand the suggestion. Where do you suggest we have > !vi->has_rss? > > If we got this far, we either have: > > a) rxfh->indir set and vi->has_rss is also set > b) rxfh->indir not set. (vi->has_rss could be set or not). This function does two tasks. 1. update indir table 2. update rss key #1 only for has_rss #2 for has_rss or has_rss_hash_report So I would code: bool update = false if (rxfh->indir) { if (!vi->has_rss) return -EINVAL; for (i = 0; i < vi->rss_indir_table_size; ++i) vi->ctrl->rss.indirection_table[i] = rxfh->indir[i]; update = true } if (rxfh->key) { if (!vi->has_rss && !vi->has_rss_hash_report) return -EINVAL; memcpy(vi->ctrl->rss.key, rxfh->key, vi->rss_key_size); update = true } if (update) virtnet_commit_rss_command(vi); Thanks. > > Thanks for the review, > Breno ^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [PATCH net v2 1/2] virtio_net: Do not set rss_indir if RSS is not supported 2024-03-28 1:28 ` Xuan Zhuo @ 2024-03-28 14:37 ` Breno Leitao 2024-03-29 2:10 ` Heng Qi 0 siblings, 1 reply; 9+ messages in thread From: Breno Leitao @ 2024-03-28 14:37 UTC (permalink / raw) To: Xuan Zhuo Cc: rbc, riel, open list:VIRTIO CORE AND NET DRIVERS, open list:NETWORKING DRIVERS, open list, hengqi, Michael S. Tsirkin, Jason Wang, David S. Miller, Eric Dumazet, Jakub Kicinski, Paolo Abeni > > On Wed, Mar 27, 2024 at 09:37:43AM +0800, Xuan Zhuo wrote: > > > On Tue, 26 Mar 2024 08:19:08 -0700, Breno Leitao <leitao@debian.org> wrote: > > > > Do not set virtnet_info->rss_indir_table_size if RSS is not available > > > > for the device. > > > > > > > > Currently, rss_indir_table_size is set if either has_rss or > > > > has_rss_hash_report is available, but, it should only be set if has_rss > > > > is set. > > > > > > > > On the virtnet_set_rxfh(), return an invalid command if the request has > > > > indirection table set, but virtnet does not support RSS. > > > > > > > > Suggested-by: Heng Qi <hengqi@linux.alibaba.com> > > > > Signed-off-by: Breno Leitao <leitao@debian.org> > > > > --- > > > > drivers/net/virtio_net.c | 9 +++++++-- > > > > 1 file changed, 7 insertions(+), 2 deletions(-) > > > > > > > > diff --git a/drivers/net/virtio_net.c b/drivers/net/virtio_net.c > > > > index c22d1118a133..c640fdf28fc5 100644 > > > > --- a/drivers/net/virtio_net.c > > > > +++ b/drivers/net/virtio_net.c > > > > @@ -3813,6 +3813,9 @@ static int virtnet_set_rxfh(struct net_device *dev, > > > > rxfh->hfunc != ETH_RSS_HASH_TOP) > > > > return -EOPNOTSUPP; > > > > > > > > + if (rxfh->indir && !vi->has_rss) > > > > + return -EINVAL; > > > > + > > > > if (rxfh->indir) { > > > > > > Put !vi->has_rss here? > > > > I am not sure I understand the suggestion. Where do you suggest we have > > !vi->has_rss? > > > > If we got this far, we either have: > > > > a) rxfh->indir set and vi->has_rss is also set > > b) rxfh->indir not set. (vi->has_rss could be set or not). > > > This function does two tasks. > 1. update indir table > 2. update rss key > > #1 only for has_rss > #2 for has_rss or has_rss_hash_report > > > So I would code: > > bool update = false > > if (rxfh->indir) { > if (!vi->has_rss) > return -EINVAL; > > for (i = 0; i < vi->rss_indir_table_size; ++i) > vi->ctrl->rss.indirection_table[i] = rxfh->indir[i]; > > update = true > } > > if (rxfh->key) { > if (!vi->has_rss && !vi->has_rss_hash_report) > return -EINVAL; > > memcpy(vi->ctrl->rss.key, rxfh->key, vi->rss_key_size); > update = true > } > > > if (update) > virtnet_commit_rss_command(vi); > > Thanks. This is a bit different from the previous proposal, but, I like this one approach better. It makes the code easier to read. How does the full patch looks like? diff --git a/drivers/net/virtio_net.c b/drivers/net/virtio_net.c index c22d1118a133..180f342f1898 100644 --- a/drivers/net/virtio_net.c +++ b/drivers/net/virtio_net.c @@ -3807,20 +3807,35 @@ static int virtnet_set_rxfh(struct net_device *dev, struct netlink_ext_ack *extack) { struct virtnet_info *vi = netdev_priv(dev); + bool update = false; int i; + if (!vi->has_rss && !vi->has_rss_hash_report) + return -EOPNOTSUPP; + if (rxfh->hfunc != ETH_RSS_HASH_NO_CHANGE && rxfh->hfunc != ETH_RSS_HASH_TOP) return -EOPNOTSUPP; if (rxfh->indir) { + if (!vi->has_rss) + return -EINVAL; + for (i = 0; i < vi->rss_indir_table_size; ++i) vi->ctrl->rss.indirection_table[i] = rxfh->indir[i]; + update = true; } - if (rxfh->key) + + if (rxfh->key) { + if (!vi->has_rss && !vi->has_rss_hash_report) + return -EINVAL; + memcpy(vi->ctrl->rss.key, rxfh->key, vi->rss_key_size); + update = true; + } - virtnet_commit_rss_command(vi); + if (update) + virtnet_commit_rss_command(vi); return 0; } @@ -4729,13 +4744,15 @@ static int virtnet_probe(struct virtio_device *vdev) if (virtio_has_feature(vdev, VIRTIO_NET_F_HASH_REPORT)) vi->has_rss_hash_report = true; - if (virtio_has_feature(vdev, VIRTIO_NET_F_RSS)) + if (virtio_has_feature(vdev, VIRTIO_NET_F_RSS)) { vi->has_rss = true; - if (vi->has_rss || vi->has_rss_hash_report) { vi->rss_indir_table_size = virtio_cread16(vdev, offsetof(struct virtio_net_config, rss_max_indirection_table_length)); + } + + if (vi->has_rss || vi->has_rss_hash_report) { vi->rss_key_size = virtio_cread8(vdev, offsetof(struct virtio_net_config, rss_max_key_size)); ^ permalink raw reply related [flat|nested] 9+ messages in thread
* Re: [PATCH net v2 1/2] virtio_net: Do not set rss_indir if RSS is not supported 2024-03-28 14:37 ` Breno Leitao @ 2024-03-29 2:10 ` Heng Qi 0 siblings, 0 replies; 9+ messages in thread From: Heng Qi @ 2024-03-29 2:10 UTC (permalink / raw) To: Breno Leitao Cc: rbc, riel, open list:VIRTIO CORE AND NET DRIVERS, open list:NETWORKING DRIVERS, open list, Michael S. Tsirkin, Jason Wang, David S. Miller, Eric Dumazet, Jakub Kicinski, Paolo Abeni, Xuan Zhuo 在 2024/3/28 下午10:37, Breno Leitao 写道: >>> On Wed, Mar 27, 2024 at 09:37:43AM +0800, Xuan Zhuo wrote: >>>> On Tue, 26 Mar 2024 08:19:08 -0700, Breno Leitao <leitao@debian.org> wrote: >>>>> Do not set virtnet_info->rss_indir_table_size if RSS is not available >>>>> for the device. >>>>> >>>>> Currently, rss_indir_table_size is set if either has_rss or >>>>> has_rss_hash_report is available, but, it should only be set if has_rss >>>>> is set. >>>>> >>>>> On the virtnet_set_rxfh(), return an invalid command if the request has >>>>> indirection table set, but virtnet does not support RSS. >>>>> >>>>> Suggested-by: Heng Qi <hengqi@linux.alibaba.com> >>>>> Signed-off-by: Breno Leitao <leitao@debian.org> >>>>> --- >>>>> drivers/net/virtio_net.c | 9 +++++++-- >>>>> 1 file changed, 7 insertions(+), 2 deletions(-) >>>>> >>>>> diff --git a/drivers/net/virtio_net.c b/drivers/net/virtio_net.c >>>>> index c22d1118a133..c640fdf28fc5 100644 >>>>> --- a/drivers/net/virtio_net.c >>>>> +++ b/drivers/net/virtio_net.c >>>>> @@ -3813,6 +3813,9 @@ static int virtnet_set_rxfh(struct net_device *dev, >>>>> rxfh->hfunc != ETH_RSS_HASH_TOP) >>>>> return -EOPNOTSUPP; >>>>> >>>>> + if (rxfh->indir && !vi->has_rss) >>>>> + return -EINVAL; >>>>> + >>>>> if (rxfh->indir) { >>>> Put !vi->has_rss here? >>> I am not sure I understand the suggestion. Where do you suggest we have >>> !vi->has_rss? >>> >>> If we got this far, we either have: >>> >>> a) rxfh->indir set and vi->has_rss is also set >>> b) rxfh->indir not set. (vi->has_rss could be set or not). >> >> This function does two tasks. >> 1. update indir table >> 2. update rss key >> >> #1 only for has_rss >> #2 for has_rss or has_rss_hash_report >> >> >> So I would code: >> >> bool update = false >> >> if (rxfh->indir) { >> if (!vi->has_rss) >> return -EINVAL; >> >> for (i = 0; i < vi->rss_indir_table_size; ++i) >> vi->ctrl->rss.indirection_table[i] = rxfh->indir[i]; >> >> update = true >> } >> >> if (rxfh->key) { >> if (!vi->has_rss && !vi->has_rss_hash_report) >> return -EINVAL; >> >> memcpy(vi->ctrl->rss.key, rxfh->key, vi->rss_key_size); >> update = true >> } >> >> >> if (update) >> virtnet_commit_rss_command(vi); >> >> Thanks. > This is a bit different from the previous proposal, but, I like this one > approach better. It makes the code easier to read. > > How does the full patch looks like? > > > diff --git a/drivers/net/virtio_net.c b/drivers/net/virtio_net.c > index c22d1118a133..180f342f1898 100644 > --- a/drivers/net/virtio_net.c > +++ b/drivers/net/virtio_net.c > @@ -3807,20 +3807,35 @@ static int virtnet_set_rxfh(struct net_device *dev, > struct netlink_ext_ack *extack) > { > struct virtnet_info *vi = netdev_priv(dev); > + bool update = false; > int i; > > + if (!vi->has_rss && !vi->has_rss_hash_report) > + return -EOPNOTSUPP; > + I think this two modifications are no longer needed as they have been embedded below. > if (rxfh->hfunc != ETH_RSS_HASH_NO_CHANGE && > rxfh->hfunc != ETH_RSS_HASH_TOP) > return -EOPNOTSUPP; > > if (rxfh->indir) { > + if (!vi->has_rss) > + return -EINVAL; -EOPNOTSUPP seems better. > + > for (i = 0; i < vi->rss_indir_table_size; ++i) > vi->ctrl->rss.indirection_table[i] = rxfh->indir[i]; > + update = true; > } > - if (rxfh->key) > + > + if (rxfh->key) { > + if (!vi->has_rss && !vi->has_rss_hash_report) > + return -EINVAL; Same as above. return -EOPNOTSUPP. Others look good. Thanks. > + > memcpy(vi->ctrl->rss.key, rxfh->key, vi->rss_key_size); > + update = true; > + } > > - virtnet_commit_rss_command(vi); > + if (update) > + virtnet_commit_rss_command(vi); > > return 0; > } > @@ -4729,13 +4744,15 @@ static int virtnet_probe(struct virtio_device *vdev) > if (virtio_has_feature(vdev, VIRTIO_NET_F_HASH_REPORT)) > vi->has_rss_hash_report = true; > > - if (virtio_has_feature(vdev, VIRTIO_NET_F_RSS)) > + if (virtio_has_feature(vdev, VIRTIO_NET_F_RSS)) { > vi->has_rss = true; > > - if (vi->has_rss || vi->has_rss_hash_report) { > vi->rss_indir_table_size = > virtio_cread16(vdev, offsetof(struct virtio_net_config, > rss_max_indirection_table_length)); > + } > + > + if (vi->has_rss || vi->has_rss_hash_report) { > vi->rss_key_size = > virtio_cread8(vdev, offsetof(struct virtio_net_config, rss_max_key_size)); > ^ permalink raw reply [flat|nested] 9+ messages in thread
end of thread, other threads:[~2024-03-29 2:10 UTC | newest] Thread overview: 9+ messages (download: mbox.gz / follow: Atom feed) -- links below jump to the message on this page -- 2024-03-26 15:19 [PATCH net v2 1/2] virtio_net: Do not set rss_indir if RSS is not supported Breno Leitao 2024-03-26 15:19 ` [PATCH net v2 2/2] virtio_net: Do not send RSS key if it " Breno Leitao 2024-03-27 2:27 ` Heng Qi 2024-03-27 13:44 ` Breno Leitao 2024-03-27 1:37 ` [PATCH net v2 1/2] virtio_net: Do not set rss_indir if RSS " Xuan Zhuo 2024-03-27 13:51 ` Breno Leitao 2024-03-28 1:28 ` Xuan Zhuo 2024-03-28 14:37 ` Breno Leitao 2024-03-29 2:10 ` Heng Qi
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.