Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit 4ab93d8

Browse files
Use netdev refcount tracking in a couple places
Netdev refcounting was added a couple years back in 5.17 [1], but onload only uses the untracked versions. This patch adds support to the ones that are low-hanging fruit. For sfc, kernel compatibility for netdevice_tracker is already provided by its kernel_compat.h. Tracking in tc_encap_actions.c is already upstream [2] so this is backporting from there. For rx_common.c I just sent a patch upstream [3] and backported it here. Outside sfc I added the same support to ci/driver/kernel_compat.h. [1] https://lore.kernel.org/netdev/20211205042217.982127-4-eric.dumazet@gmail.com/ [2] torvalds/linux@7e5e7d800011ad#diff-9ffb1b01a8a11d0d7b6976a10eede3bebdcfaf256ef26d0d95714fe8aa03c89fR156 [3] https://lore.kernel.org/netdev/20241217224717.1711626-1-zhuyifei@google.com/T/ Signed-off-by: YiFei Zhu <zhuyifei@google.com>
1 parent 97b8c0a commit 4ab93d8

File tree

10 files changed

+53
-13
lines changed

10 files changed

+53
-13
lines changed

‎src/driver/linux_net/drivers/net/ethernet/sfc/net_driver.h‎

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1291,13 +1291,15 @@ struct efx_arfs_rule {
12911291
/**
12921292
* struct efx_async_filter_insertion - Request to asynchronously insert a filter
12931293
* @net_dev: Reference to the netdevice
1294+
* @net_dev_tracker: reference tracker entry for @net_dev
12941295
* @spec: The filter to insert
12951296
* @work: Workitem for this request
12961297
* @rxq_index: Identifies the channel for which this request was made
12971298
* @flow_id: Identifies the kernel-side flow for which this request was made
12981299
*/
12991300
struct efx_async_filter_insertion {
13001301
struct net_device *net_dev;
1302+
netdevice_tracker net_dev_tracker;
13011303
struct efx_filter_spec spec;
13021304
struct work_struct work;
13031305
u16 rxq_index;

‎src/driver/linux_net/drivers/net/ethernet/sfc/rx_common.c‎

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1845,7 +1845,7 @@ static void efx_filter_rfs_work(struct work_struct *data)
18451845

18461846
/* Release references */
18471847
clear_bit(slot_idx, &efx->rps_slot_map);
1848-
dev_put(req->net_dev);
1848+
netdev_put(req->net_dev, &req->net_dev_tracker);
18491849

18501850
return;
18511851
}
@@ -1908,7 +1908,8 @@ int efx_filter_rfs(struct net_device *net_dev, const struct sk_buff *skb,
19081908
}
19091909

19101910
/* Queue the request */
1911-
dev_hold(req->net_dev = net_dev);
1911+
req->net_dev = net_dev;
1912+
netdev_hold(req->net_dev, &req->net_dev_tracker, GFP_ATOMIC);
19121913
INIT_WORK(&req->work, efx_filter_rfs_work);
19131914
req->rxq_index = rxq_index;
19141915
req->flow_id = flow_id;
@@ -1965,4 +1966,3 @@ bool __efx_filter_rfs_expire(struct efx_channel *channel, unsigned int quota)
19651966
}
19661967

19671968
#endif /* CONFIG_RFS_ACCEL */
1968-

‎src/driver/linux_net/drivers/net/ethernet/sfc/tc_encap_actions.c‎

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -209,7 +209,8 @@ static int efx_bind_neigh(struct efx_nic *efx,
209209
EFX_TC_ERR_MSG(efx, extack, "Failed to lookup route for encap");
210210
goto out_free;
211211
}
212-
dev_hold(neigh->egdev = dst->dev);
212+
netdev_hold(neigh->egdev = dst->dev, &neigh->dev_tracker,
213+
GFP_KERNEL_ACCOUNT);
213214
neigh->ttl = ip6_dst_hoplimit(dst);
214215
n = dst_neigh_lookup(dst, &flow6.daddr);
215216
dst_release(dst);
@@ -223,7 +224,8 @@ static int efx_bind_neigh(struct efx_nic *efx,
223224
EFX_TC_ERR_MSG(efx, extack, "Failed to lookup route for encap");
224225
goto out_free;
225226
}
226-
dev_hold(neigh->egdev = rt->dst.dev);
227+
netdev_hold(neigh->egdev = rt->dst.dev, &neigh->dev_tracker,
228+
GFP_KERNEL_ACCOUNT);
227229
neigh->ttl = ip4_dst_hoplimit(&rt->dst);
228230
n = dst_neigh_lookup(&rt->dst, &flow4.daddr);
229231
ip_rt_put(rt);
@@ -233,7 +235,7 @@ static int efx_bind_neigh(struct efx_nic *efx,
233235
if (!n) {
234236
rc = -ENETUNREACH;
235237
EFX_TC_ERR_MSG(efx, extack, "Failed to lookup neighbour for encap");
236-
dev_put(neigh->egdev);
238+
netdev_put(neigh->egdev, &neigh->dev_tracker);
237239
goto out_free;
238240
}
239241
refcount_set(&neigh->ref, 1);
@@ -273,7 +275,7 @@ static void efx_free_neigh(struct efx_neigh_binder *neigh)
273275
rhashtable_remove_fast(&efx->tc->neigh_ht, &neigh->linkage,
274276
efx_neigh_ht_params);
275277
synchronize_rcu();
276-
dev_put(neigh->egdev);
278+
netdev_put(neigh->egdev, &neigh->dev_tracker);
277279
put_net(neigh->net);
278280
kfree(neigh);
279281
}

‎src/driver/linux_net/drivers/net/ethernet/sfc/tc_encap_actions.h‎

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@
2626
* @ttl: Time To Live associated with the route used
2727
* @dying: set when egdev is going away, to skip further updates
2828
* @egdev: egress device from the route lookup. Holds a reference
29+
* @dev_tracker: reference tracker entry for @egdev
2930
* @ref: counts encap actions referencing this entry
3031
* @used: jiffies of last time traffic hit any encap action using this.
3132
* When counter reads update this, a new neighbour event is sent to
@@ -53,6 +54,7 @@ struct efx_neigh_binder {
5354
u8 ttl;
5455
bool dying;
5556
struct net_device *egdev;
57+
netdevice_tracker dev_tracker;
5658
refcount_t ref;
5759
unsigned long used;
5860
struct list_head users;

‎src/driver/linux_resource/kernel_compat.sh‎

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -178,6 +178,9 @@ EFRM_HAVE_FOLLOW_PTE_VMA symtype follow_pte include/linux/mm.h int(struct vm_are
178178
179179
EFRM_HAVE_LINUX_TPH_H file include/linux/pci-tph.h
180180
181+
EFX_NEED_NETDEV_HOLD nsymbol netdev_hold include/linux/netdevice.h
182+
EFX_HAVE_DEV_HOLD_TRACK symbol dev_hold_track include/linux/netdevice.h
183+
181184
# TODO move onload-related stuff from net kernel_compat
182185
" | grep -E -v -e '^#' -e '^$' | sed 's/[ \t][ \t]*/:/g'
183186
}

‎src/driver/linux_resource/nondl_resource.c‎

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
#include <ci/efrm/efrm_client.h>
99
#include <ci/efrm/nondl.h>
1010
#include <linux/rtnetlink.h>
11+
#include <linux/netdevice.h>
1112

1213
/* Maximum number of VIs we will try to create for each device. */
1314
#define MAX_VIS 128
@@ -132,7 +133,7 @@ int efrm_nondl_register_netdev(struct net_device *netdev,
132133

133134
INIT_LIST_HEAD(&device->node);
134135

135-
dev_hold(netdev);
136+
netdev_hold(netdev, &device->netdev_tracker, GFP_KERNEL);
136137
device->netdev = netdev;
137138
device->n_vis = n_vis;
138139
device->is_up = 1;
@@ -153,7 +154,7 @@ static void efrm_nondl_cleanup_netdev(struct efrm_nondl_device *device)
153154
BUG_ON(device->driver);
154155

155156
list_del(&device->node);
156-
dev_put(device->netdev);
157+
netdev_put(device->netdev, &device->netdev_tracker);
157158

158159
kfree(device);
159160
}

‎src/driver/linux_resource/resource_driver.c‎

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -206,7 +206,7 @@ linux_efrm_nic_ctor(struct linux_efhw_nic *lnic, struct device *dev,
206206
/* Tie the lifetime of the kernel's state to that of our own. */
207207
if( dev )
208208
get_device(dev);
209-
dev_hold(net_dev);
209+
netdev_hold(net_dev, &nic->net_dev_tracker, GFP_KERNEL);
210210

211211
rc = efhw_nic_ctor(nic, res_dim, dev_type, net_dev, dev);
212212
if (rc < 0)
@@ -236,7 +236,7 @@ linux_efrm_nic_ctor(struct linux_efhw_nic *lnic, struct device *dev,
236236
fail1:
237237
if( dev )
238238
put_device(dev);
239-
dev_put(net_dev);
239+
netdev_put(net_dev, &nic->net_dev_tracker);
240240
return rc;
241241
}
242242

@@ -259,7 +259,7 @@ linux_efrm_nic_reclaim(struct linux_efhw_nic *lnic,
259259

260260
/* Replace the net & pci devs */
261261
get_device(dev);
262-
dev_hold(net_dev);
262+
netdev_hold(net_dev, &nic->net_dev_tracker, GFP_KERNEL);
263263
spin_lock_bh(&nic->pci_dev_lock);
264264
old_dev = nic->dev;
265265
nic->dev = dev;
@@ -506,7 +506,7 @@ efrm_nic_do_unplug(struct efhw_nic* nic, bool hard)
506506
spin_unlock_bh(&nic->pci_dev_lock);
507507

508508
EFRM_ASSERT(net_dev != NULL);
509-
dev_put(net_dev);
509+
netdev_put(net_dev, &nic->net_dev_tracker);
510510
put_device(dev);
511511

512512
return 0;

‎src/include/ci/driver/kernel_compat.h‎

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -546,4 +546,30 @@ static inline int efrm_follow_pfn(struct vm_area_struct *vma,
546546
}
547547
#endif
548548

549+
#ifdef EFX_NEED_NETDEV_HOLD
550+
#ifdef EFX_HAVE_DEV_HOLD_TRACK
551+
/* Commit d62607c3fe45 ("net: rename reference+tracking helpers")
552+
* renamed these.
553+
*/
554+
#define netdev_hold(_n, _t, _g) dev_hold_track(_n, _t, _g)
555+
#define netdev_put(_n, _t) dev_put_track(_n, _t)
556+
#else
557+
/* This was introduced in the same commit that adds dev_hold_track */
558+
typedef struct {} netdevice_tracker;
559+
560+
static inline void netdev_hold(struct net_device *dev,
561+
netdevice_tracker *tracker __always_unused,
562+
gfp_t gfp __always_unused)
563+
{
564+
dev_hold(dev);
565+
}
566+
567+
static inline void netdev_put(struct net_device *dev,
568+
netdevice_tracker *tracker __always_unused)
569+
{
570+
dev_put(dev);
571+
}
572+
#endif
573+
#endif
574+
549575
#endif /* DRIVER_LINUX_RESOURCE_KERNEL_COMPAT_H */

‎src/include/ci/efhw/efhw_types.h‎

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@
4040
#ifndef __CI_EFHW_EFAB_TYPES_H__
4141
#define __CI_EFHW_EFAB_TYPES_H__
4242

43+
#include <ci/driver/kernel_compat.h>
4344
#include <ci/efhw/efhw_config.h>
4445
#include <ci/efhw/hardware_sysdep.h>
4546
#include <ci/efhw/iopage_types.h>
@@ -569,6 +570,7 @@ struct efhw_nic {
569570
int index;
570571

571572
struct net_device *net_dev; /*!< Network device */
573+
netdevice_tracker net_dev_tracker;
572574
struct device *dev; /*!< HW device */
573575
struct pci_dev *pci_dev; /*!< PCI device */
574576
spinlock_t pci_dev_lock; /*!< Protects access to dev & net_dev */

‎src/include/ci/efrm/nondl.h‎

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
#define __EFRM_NONDL_H__
99

1010
#include <linux/types.h>
11+
#include <ci/driver/kernel_compat.h>
1112

1213

1314
/* Non-driverlink network device.
@@ -43,6 +44,7 @@ struct efrm_nondl_device {
4344
/* Network device currently associated with this non-driverlink
4445
* device. */
4546
struct net_device *netdev;
47+
netdevice_tracker netdev_tracker;
4648

4749
/* Number of VIs we would like to create on this device. */
4850
unsigned int n_vis;

0 commit comments

Comments
(0)

AltStyle によって変換されたページ (->オリジナル) /