net: ena: fix issues in setting interrupt moderation params in ethtool
authorArthur Kiyanovski <akiyano@amazon.com>
Thu, 19 Dec 2019 15:40:56 +0000 (17:40 +0200)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Tue, 31 Dec 2019 15:41:41 +0000 (16:41 +0100)
[ Upstream commit 41c53caa5a61ebc9221b71cc37f4a90549f1121d ]

Issue 1:
--------
Reproduction steps:
1. sudo ethtool -C eth0 rx-usecs 128
2. sudo ethtool -C eth0 adaptive-rx on
3. sudo ethtool -C eth0 adaptive-rx off
4. ethtool -c eth0

expected output: rx-usecs 128
actual output: rx-usecs 0

Reason for issue:
In stage 3, ethtool userspace calls first the ena_get_coalesce() handler
to get the current value of all properties, and then the ena_set_coalesce()
handler. When ena_get_coalesce() is called the adaptive interrupt
moderation is still on. There is an if in the code that returns the
rx_coalesce_usecs only if the adaptive interrupt moderation is off.
And since it is still on, rx_coalesce_usecs is not set, meaning it
stays 0.

Solution to issue:
Remove this if static interrupt moderation intervals have nothing to do
with dynamic ones.

Issue 2:
--------
Reproduction steps:
1. sudo ethtool -C eth0 adaptive-rx on
2. sudo ethtool -C eth0 rx-usecs 128
3. ethtool -c eth0

expected output: rx-usecs 128
actual output: rx-usecs 0

Reason for issue:
In stage 2, when ena_set_coalesce() is called, the handler tests if
rx adaptive interrupt moderation is on, and if it is, it returns before
getting to the part in the function that sets the rx non-adaptive
interrupt moderation interval.

Solution to issue:
Remove the return from the function when rx adaptive interrupt moderation
is on.

Also cleaned up the fixed code in ena_set_coalesce by grouping together
adaptive interrupt moderation toggling, and using && instead of nested
ifs.

Fixes: b3db86dc4b82 ("net: ena: reimplement set/get_coalesce()")
Fixes: 0eda847953d8 ("net: ena: fix retrieval of nonadaptive interrupt moderation intervals")
Fixes: 1738cd3ed342 ("net: ena: Add a driver for Amazon Elastic Network Adapters (ENA)")
Signed-off-by: Arthur Kiyanovski <akiyano@amazon.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
drivers/net/ethernet/amazon/ena/ena_ethtool.c

index 16553d9..8c1c73b 100644 (file)
@@ -315,10 +315,9 @@ static int ena_get_coalesce(struct net_device *net_dev,
                ena_com_get_nonadaptive_moderation_interval_tx(ena_dev) *
                        ena_dev->intr_delay_resolution;
 
-       if (!ena_com_get_adaptive_moderation_enabled(ena_dev))
-               coalesce->rx_coalesce_usecs =
-                       ena_com_get_nonadaptive_moderation_interval_rx(ena_dev)
-                       * ena_dev->intr_delay_resolution;
+       coalesce->rx_coalesce_usecs =
+               ena_com_get_nonadaptive_moderation_interval_rx(ena_dev)
+               * ena_dev->intr_delay_resolution;
 
        coalesce->use_adaptive_rx_coalesce =
                ena_com_get_adaptive_moderation_enabled(ena_dev);
@@ -367,12 +366,6 @@ static int ena_set_coalesce(struct net_device *net_dev,
 
        ena_update_tx_rings_intr_moderation(adapter);
 
-       if (coalesce->use_adaptive_rx_coalesce) {
-               if (!ena_com_get_adaptive_moderation_enabled(ena_dev))
-                       ena_com_enable_adaptive_moderation(ena_dev);
-               return 0;
-       }
-
        rc = ena_com_update_nonadaptive_moderation_interval_rx(ena_dev,
                                                               coalesce->rx_coalesce_usecs);
        if (rc)
@@ -380,10 +373,13 @@ static int ena_set_coalesce(struct net_device *net_dev,
 
        ena_update_rx_rings_intr_moderation(adapter);
 
-       if (!coalesce->use_adaptive_rx_coalesce) {
-               if (ena_com_get_adaptive_moderation_enabled(ena_dev))
-                       ena_com_disable_adaptive_moderation(ena_dev);
-       }
+       if (coalesce->use_adaptive_rx_coalesce &&
+           !ena_com_get_adaptive_moderation_enabled(ena_dev))
+               ena_com_enable_adaptive_moderation(ena_dev);
+
+       if (!coalesce->use_adaptive_rx_coalesce &&
+           ena_com_get_adaptive_moderation_enabled(ena_dev))
+               ena_com_disable_adaptive_moderation(ena_dev);
 
        return 0;
 }