]> git.ipfire.org Git - thirdparty/kernel/linux.git/commitdiff
sfc: Use netdev refcount tracking in struct efx_async_filter_insertion
authorYiFei Zhu <zhuyifei@google.com>
Thu, 19 Dec 2024 17:30:04 +0000 (17:30 +0000)
committerJakub Kicinski <kuba@kernel.org>
Mon, 23 Dec 2024 18:11:49 +0000 (10:11 -0800)
I was debugging some netdev refcount issues in OpenOnload, and one
of the places I was looking at was in the sfc driver. Only
struct efx_async_filter_insertion was not using netdev refcount tracker,
so add it here. GFP_ATOMIC because this code path is called by
ndo_rx_flow_steer which holds RCU.

This patch should be a no-op if !CONFIG_NET_DEV_REFCNT_TRACKER

Signed-off-by: YiFei Zhu <zhuyifei@google.com>
Reviewed-by: Eric Dumazet <edumazet@google.com>
Link: https://patch.msgid.link/20241219173004.2615655-1-zhuyifei@google.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
drivers/net/ethernet/sfc/net_driver.h
drivers/net/ethernet/sfc/rx_common.c
drivers/net/ethernet/sfc/siena/net_driver.h
drivers/net/ethernet/sfc/siena/rx_common.c

index 620ba6ef3514bd5eb9abc38e3ea6171b65d61aa2..f70a7b7d6345c554b864f4bad78d380e3782e974 100644 (file)
@@ -831,6 +831,7 @@ struct efx_arfs_rule {
 /**
  * struct efx_async_filter_insertion - Request to asynchronously insert a filter
  * @net_dev: Reference to the netdevice
+ * @net_dev_tracker: reference tracker entry for @net_dev
  * @spec: The filter to insert
  * @work: Workitem for this request
  * @rxq_index: Identifies the channel for which this request was made
@@ -838,6 +839,7 @@ struct efx_arfs_rule {
  */
 struct efx_async_filter_insertion {
        struct net_device *net_dev;
+       netdevice_tracker net_dev_tracker;
        struct efx_filter_spec spec;
        struct work_struct work;
        u16 rxq_index;
index ab358fe13e1df037e02f9076a10c70cdb2363686..4cc83203e18800d5424e9332263b766dd64587d4 100644 (file)
@@ -897,7 +897,7 @@ static void efx_filter_rfs_work(struct work_struct *data)
 
        /* Release references */
        clear_bit(slot_idx, &efx->rps_slot_map);
-       dev_put(req->net_dev);
+       netdev_put(req->net_dev, &req->net_dev_tracker);
 }
 
 int efx_filter_rfs(struct net_device *net_dev, const struct sk_buff *skb,
@@ -989,7 +989,8 @@ int efx_filter_rfs(struct net_device *net_dev, const struct sk_buff *skb,
        }
 
        /* Queue the request */
-       dev_hold(req->net_dev = net_dev);
+       req->net_dev = net_dev;
+       netdev_hold(req->net_dev, &req->net_dev_tracker, GFP_ATOMIC);
        INIT_WORK(&req->work, efx_filter_rfs_work);
        req->rxq_index = rxq_index;
        req->flow_id = flow_id;
index 9785eff10607beb585891abf96e98fba14742bf5..2be3bad3c993356b3f06394728007d700982bae4 100644 (file)
@@ -753,6 +753,7 @@ struct efx_arfs_rule {
 /**
  * struct efx_async_filter_insertion - Request to asynchronously insert a filter
  * @net_dev: Reference to the netdevice
+ * @net_dev_tracker: reference tracker entry for @net_dev
  * @spec: The filter to insert
  * @work: Workitem for this request
  * @rxq_index: Identifies the channel for which this request was made
@@ -760,6 +761,7 @@ struct efx_arfs_rule {
  */
 struct efx_async_filter_insertion {
        struct net_device *net_dev;
+       netdevice_tracker net_dev_tracker;
        struct efx_filter_spec spec;
        struct work_struct work;
        u16 rxq_index;
index 082e35c6caaaed0a0f78db03ddd055c0764e197d..2839d0e0a9c16a5fd8f9ff81bc2cc44b54d978cb 100644 (file)
@@ -888,7 +888,7 @@ static void efx_filter_rfs_work(struct work_struct *data)
 
        /* Release references */
        clear_bit(slot_idx, &efx->rps_slot_map);
-       dev_put(req->net_dev);
+       netdev_put(req->net_dev, &req->net_dev_tracker);
 }
 
 int efx_siena_filter_rfs(struct net_device *net_dev, const struct sk_buff *skb,
@@ -980,7 +980,8 @@ int efx_siena_filter_rfs(struct net_device *net_dev, const struct sk_buff *skb,
        }
 
        /* Queue the request */
-       dev_hold(req->net_dev = net_dev);
+       req->net_dev = net_dev;
+       netdev_hold(req->net_dev, &req->net_dev_tracker, GFP_ATOMIC);
        INIT_WORK(&req->work, efx_filter_rfs_work);
        req->rxq_index = rxq_index;
        req->flow_id = flow_id;