Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

sfc: Use netdev refcount tracking in struct efx_async_filter_insertion

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>

authored by

YiFei Zhu and committed by
Jakub Kicinski
85101bda a6ac6674

+10 -4
+2
drivers/net/ethernet/sfc/net_driver.h
··· 831 831 /** 832 832 * struct efx_async_filter_insertion - Request to asynchronously insert a filter 833 833 * @net_dev: Reference to the netdevice 834 + * @net_dev_tracker: reference tracker entry for @net_dev 834 835 * @spec: The filter to insert 835 836 * @work: Workitem for this request 836 837 * @rxq_index: Identifies the channel for which this request was made ··· 839 838 */ 840 839 struct efx_async_filter_insertion { 841 840 struct net_device *net_dev; 841 + netdevice_tracker net_dev_tracker; 842 842 struct efx_filter_spec spec; 843 843 struct work_struct work; 844 844 u16 rxq_index;
+3 -2
drivers/net/ethernet/sfc/rx_common.c
··· 897 897 898 898 /* Release references */ 899 899 clear_bit(slot_idx, &efx->rps_slot_map); 900 - dev_put(req->net_dev); 900 + netdev_put(req->net_dev, &req->net_dev_tracker); 901 901 } 902 902 903 903 int efx_filter_rfs(struct net_device *net_dev, const struct sk_buff *skb, ··· 989 989 } 990 990 991 991 /* Queue the request */ 992 - dev_hold(req->net_dev = net_dev); 992 + req->net_dev = net_dev; 993 + netdev_hold(req->net_dev, &req->net_dev_tracker, GFP_ATOMIC); 993 994 INIT_WORK(&req->work, efx_filter_rfs_work); 994 995 req->rxq_index = rxq_index; 995 996 req->flow_id = flow_id;
+2
drivers/net/ethernet/sfc/siena/net_driver.h
··· 753 753 /** 754 754 * struct efx_async_filter_insertion - Request to asynchronously insert a filter 755 755 * @net_dev: Reference to the netdevice 756 + * @net_dev_tracker: reference tracker entry for @net_dev 756 757 * @spec: The filter to insert 757 758 * @work: Workitem for this request 758 759 * @rxq_index: Identifies the channel for which this request was made ··· 761 760 */ 762 761 struct efx_async_filter_insertion { 763 762 struct net_device *net_dev; 763 + netdevice_tracker net_dev_tracker; 764 764 struct efx_filter_spec spec; 765 765 struct work_struct work; 766 766 u16 rxq_index;
+3 -2
drivers/net/ethernet/sfc/siena/rx_common.c
··· 888 888 889 889 /* Release references */ 890 890 clear_bit(slot_idx, &efx->rps_slot_map); 891 - dev_put(req->net_dev); 891 + netdev_put(req->net_dev, &req->net_dev_tracker); 892 892 } 893 893 894 894 int efx_siena_filter_rfs(struct net_device *net_dev, const struct sk_buff *skb, ··· 980 980 } 981 981 982 982 /* Queue the request */ 983 - dev_hold(req->net_dev = net_dev); 983 + req->net_dev = net_dev; 984 + netdev_hold(req->net_dev, &req->net_dev_tracker, GFP_ATOMIC); 984 985 INIT_WORK(&req->work, efx_filter_rfs_work); 985 986 req->rxq_index = rxq_index; 986 987 req->flow_id = flow_id;