[<prev] [next>] [<thread-prev] [day] [month] [year] [list]
Message-ID: <CAKgT0UfeAgS-Jh69AdRNUzG2qt_gcHrLP1DP1v-5bxpY8UwpZg@mail.gmail.com>
Date: Wed, 28 Aug 2019 11:32:14 -0700
From: Alexander Duyck <alexander.duyck@...il.com>
To: Robert Beckett <bob.beckett@...labora.com>
Cc: intel-wired-lan <intel-wired-lan@...ts.osuosl.org>,
Jeff Kirsher <jeffrey.t.kirsher@...el.com>,
"David S. Miller" <davem@...emloft.net>,
Netdev <netdev@...r.kernel.org>
Subject: Re: [PATCH] igb: add rx drop enable attribute
On Wed, Aug 28, 2019 at 10:40 AM Robert Beckett
<bob.beckett@...labora.com> wrote:
>
> To allow userland to enable or disable dropping packets when descriptor
> ring is exhausted, add an adapter rx_drop_en attribute.
>
> This can be used in conjunction with flow control to mitigate packet storms
> (e.g. due to network loop or DoS) by forcing the network adapter to send
> pause frames whenever the ring is close to exhaustion.
>
> By default this will maintain previous behaviour of enabling dropping of
> packets during ring buffer exhaustion.
> Some use cases prefer to not drop packets upon exhaustion, but instead
> use flow control to limit ingress rates and ensure no dropped packets.
> This is useful when the host CPU cannot keep up with packet delivery,
> but data delivery is more important than throughput via multiple queues.
>
> Userland can write 0 to rx_drop_en to disable packet dropping via udev.
>
> Signed-off-by: Robert Beckett <bob.beckett@...labora.com>
Instead of doing this as a sysfs file it might be better to just do
this as an ethtool private flag like what I did for "legacy-rx".
> ---
> drivers/net/ethernet/intel/igb/igb.h | 1 +
> drivers/net/ethernet/intel/igb/igb_main.c | 60 ++++++++++++++++++++++-
> 2 files changed, 60 insertions(+), 1 deletion(-)
>
> diff --git a/drivers/net/ethernet/intel/igb/igb.h b/drivers/net/ethernet/intel/igb/igb.h
> index ca54e268d157..efada57a05e1 100644
> --- a/drivers/net/ethernet/intel/igb/igb.h
> +++ b/drivers/net/ethernet/intel/igb/igb.h
> @@ -594,6 +594,7 @@ struct igb_adapter {
> struct igb_mac_addr *mac_table;
> struct vf_mac_filter vf_macs;
> struct vf_mac_filter *vf_mac_list;
> + bool rx_drop_enable; /* drop packets when descriptor ring exhausted */
> };
>
> /* flags controlling PTP/1588 function */
> diff --git a/drivers/net/ethernet/intel/igb/igb_main.c b/drivers/net/ethernet/intel/igb/igb_main.c
> index 105b0624081a..5b499130c3f5 100644
> --- a/drivers/net/ethernet/intel/igb/igb_main.c
> +++ b/drivers/net/ethernet/intel/igb/igb_main.c
> @@ -2982,6 +2982,54 @@ static s32 igb_init_i2c(struct igb_adapter *adapter)
> return status;
> }
>
> +static ssize_t rx_drop_en_show(struct device *dev,
> + struct device_attribute *attr,
> + char *buf)
> +
> +{
> + struct net_device *netdev = pci_get_drvdata(to_pci_dev(dev));
> + struct igb_adapter *adapter = netdev_priv(netdev);
> +
> + if (adapter->rx_drop_enable)
> + return sprintf(buf, "1\n");
> + else
> + return sprintf(buf, "0\n");
> +}
> +
> +static ssize_t rx_drop_en_store(struct device *dev,
> + struct device_attribute *attr,
> + const char *buf, size_t count)
> +{
> + struct net_device *netdev = pci_get_drvdata(to_pci_dev(dev));
> + struct igb_adapter *adapter = netdev_priv(netdev);
> + struct e1000_hw *hw = &adapter->hw;
> + int queue_idx, reg_idx;
> + bool val;
> + u32 srrctl;
> + int ret;
> +
> + ret = kstrtobool(buf, &val);
> + if (ret < 0)
> + return ret;
> +
> + adapter->rx_drop_enable = val;
> +
> + /* set for each currently active ring */
> + for (queue_idx = 0; queue_idx < adapter->num_rx_queues; queue_idx++) {
> + reg_idx = adapter->rx_ring[queue_idx]->reg_idx;
> + srrctl = rd32(E1000_SRRCTL(reg_idx));
> + if (val == 0)
> + srrctl &= ~E1000_SRRCTL_DROP_EN;
> + else
> + srrctl |= E1000_SRRCTL_DROP_EN;
> + wr32(E1000_SRRCTL(reg_idx), srrctl);
> + }
> +
> + return count;
> +}
> +
> +static DEVICE_ATTR_RW(rx_drop_en);
> +
> /**
> * igb_probe - Device Initialization Routine
> * @pdev: PCI device information struct
> @@ -3329,6 +3377,9 @@ static int igb_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
> goto err_eeprom;
> }
>
> + /* Add adapter attributes */
> + device_create_file(&pdev->dev, &dev_attr_rx_drop_en);
> +
> /* let the f/w know that the h/w is now under the control of the
> * driver.
> */
> @@ -3655,6 +3706,9 @@ static void igb_remove(struct pci_dev *pdev)
> */
> igb_release_hw_control(adapter);
>
> + /* Remove addapter attributes */
> + device_remove_file(&pdev->dev, &dev_attr_rx_drop_en);
> +
> #ifdef CONFIG_PCI_IOV
> igb_disable_sriov(pdev);
> #endif
> @@ -3753,6 +3807,9 @@ static void igb_init_queue_configuration(struct igb_adapter *adapter)
> max_rss_queues = igb_get_max_rss_queues(adapter);
> adapter->rss_queues = min_t(u32, max_rss_queues, num_online_cpus());
>
> + if (adapter->vfs_allocated_count || adapter->rss_queues > 1)
> + adapter->rx_drop_enable = true;
> +
> igb_set_flag_queue_pairs(adapter, max_rss_queues);
> }
>
> @@ -4504,7 +4561,8 @@ void igb_configure_rx_ring(struct igb_adapter *adapter,
> if (hw->mac.type >= e1000_82580)
> srrctl |= E1000_SRRCTL_TIMESTAMP;
> /* Only set Drop Enable if we are supporting multiple queues */
> - if (adapter->vfs_allocated_count || adapter->num_rx_queues > 1)
> + if (adapter->rx_drop_enable &&
> + (adapter->vfs_allocated_count || adapter->num_rx_queues > 1))
Isn't this redundant due to the code above where you were overriding
the value and setting it to true based on the vfs_allocated_count and
num_rx_queues? You could probably just use rx_drop_enable by itself.
> srrctl |= E1000_SRRCTL_DROP_EN;
>
> wr32(E1000_SRRCTL(reg_idx), srrctl);
> --
> 2.18.0
>
Powered by blists - more mailing lists