Blame view
net/core/net-sysfs.c
37.7 KB
1da177e4c Linux-2.6.12-rc2 |
1 2 3 4 |
/* * net-sysfs.c - network device class and attributes * * Copyright (c) 2003 Stephen Hemminger <shemminger@osdl.org> |
4ec93edb1 [NET] CORE: Fix w... |
5 |
* |
1da177e4c Linux-2.6.12-rc2 |
6 7 8 9 10 |
* This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version * 2 of the License, or (at your option) any later version. */ |
4fc268d24 [PATCH] capable/c... |
11 |
#include <linux/capability.h> |
1da177e4c Linux-2.6.12-rc2 |
12 13 |
#include <linux/kernel.h> #include <linux/netdevice.h> |
aecbe01e7 net-sysfs: expose... |
14 |
#include <net/switchdev.h> |
1da177e4c Linux-2.6.12-rc2 |
15 |
#include <linux/if_arp.h> |
5a0e3ad6a include cleanup: ... |
16 |
#include <linux/slab.h> |
174cd4b1e sched/headers: Pr... |
17 |
#include <linux/sched/signal.h> |
608b4b954 netns: Teach netw... |
18 |
#include <linux/nsproxy.h> |
1da177e4c Linux-2.6.12-rc2 |
19 |
#include <net/sock.h> |
608b4b954 netns: Teach netw... |
20 |
#include <net/net_namespace.h> |
1da177e4c Linux-2.6.12-rc2 |
21 |
#include <linux/rtnetlink.h> |
fec5e652e rfs: Receive Flow... |
22 |
#include <linux/vmalloc.h> |
bc3b2d7fb net: Add export.h... |
23 |
#include <linux/export.h> |
114cf5802 bql: Byte queue l... |
24 |
#include <linux/jiffies.h> |
9802c8e22 net/core: apply p... |
25 |
#include <linux/pm_runtime.h> |
aa836df95 net: core: add of... |
26 |
#include <linux/of.h> |
88832a22d net-sysfs: fix mi... |
27 |
#include <linux/of_net.h> |
1da177e4c Linux-2.6.12-rc2 |
28 |
|
342709efc [NET]: Remove in-... |
29 |
#include "net-sysfs.h" |
8b41d1887 [NET]: Fix runnin... |
30 |
#ifdef CONFIG_SYSFS |
1da177e4c Linux-2.6.12-rc2 |
31 32 33 34 35 36 |
static const char fmt_hex[] = "%#x "; static const char fmt_dec[] = "%d "; static const char fmt_ulong[] = "%lu "; |
be1f3c2c0 net: Enable 64-bi... |
37 38 |
static const char fmt_u64[] = "%llu "; |
1da177e4c Linux-2.6.12-rc2 |
39 |
|
4ec93edb1 [NET] CORE: Fix w... |
40 |
static inline int dev_isalive(const struct net_device *dev) |
1da177e4c Linux-2.6.12-rc2 |
41 |
{ |
fe9925b55 [NET]: Create net... |
42 |
return dev->reg_state <= NETREG_REGISTERED; |
1da177e4c Linux-2.6.12-rc2 |
43 44 45 |
} /* use same locking rules as GIF* ioctl's */ |
43cb76d91 Network: convert ... |
46 47 |
static ssize_t netdev_show(const struct device *dev, struct device_attribute *attr, char *buf, |
1da177e4c Linux-2.6.12-rc2 |
48 49 |
ssize_t (*format)(const struct net_device *, char *)) { |
6b53dafe2 net: do not name ... |
50 |
struct net_device *ndev = to_net_dev(dev); |
1da177e4c Linux-2.6.12-rc2 |
51 52 53 |
ssize_t ret = -EINVAL; read_lock(&dev_base_lock); |
6b53dafe2 net: do not name ... |
54 55 |
if (dev_isalive(ndev)) ret = (*format)(ndev, buf); |
1da177e4c Linux-2.6.12-rc2 |
56 57 58 59 60 61 62 |
read_unlock(&dev_base_lock); return ret; } /* generate a show function for simple field */ #define NETDEVICE_SHOW(field, format_string) \ |
6b53dafe2 net: do not name ... |
63 |
static ssize_t format_##field(const struct net_device *dev, char *buf) \ |
1da177e4c Linux-2.6.12-rc2 |
64 |
{ \ |
6b53dafe2 net: do not name ... |
65 |
return sprintf(buf, format_string, dev->field); \ |
1da177e4c Linux-2.6.12-rc2 |
66 |
} \ |
6be8aeef3 net: core: conver... |
67 |
static ssize_t field##_show(struct device *dev, \ |
43cb76d91 Network: convert ... |
68 |
struct device_attribute *attr, char *buf) \ |
1da177e4c Linux-2.6.12-rc2 |
69 |
{ \ |
43cb76d91 Network: convert ... |
70 |
return netdev_show(dev, attr, buf, format_##field); \ |
6be8aeef3 net: core: conver... |
71 72 73 74 75 |
} \ #define NETDEVICE_SHOW_RO(field, format_string) \ NETDEVICE_SHOW(field, format_string); \ static DEVICE_ATTR_RO(field) |
1da177e4c Linux-2.6.12-rc2 |
76 |
|
6be8aeef3 net: core: conver... |
77 78 79 |
#define NETDEVICE_SHOW_RW(field, format_string) \ NETDEVICE_SHOW(field, format_string); \ static DEVICE_ATTR_RW(field) |
1da177e4c Linux-2.6.12-rc2 |
80 81 |
/* use same locking and permission rules as SIF* ioctl's */ |
43cb76d91 Network: convert ... |
82 |
static ssize_t netdev_store(struct device *dev, struct device_attribute *attr, |
1da177e4c Linux-2.6.12-rc2 |
83 84 85 |
const char *buf, size_t len, int (*set)(struct net_device *, unsigned long)) { |
5e1fccc0b net: Allow userns... |
86 87 |
struct net_device *netdev = to_net_dev(dev); struct net *net = dev_net(netdev); |
1da177e4c Linux-2.6.12-rc2 |
88 89 |
unsigned long new; int ret = -EINVAL; |
5e1fccc0b net: Allow userns... |
90 |
if (!ns_capable(net->user_ns, CAP_NET_ADMIN)) |
1da177e4c Linux-2.6.12-rc2 |
91 |
return -EPERM; |
e1e420c71 net/core: simple_... |
92 93 |
ret = kstrtoul(buf, 0, &new); if (ret) |
1da177e4c Linux-2.6.12-rc2 |
94 |
goto err; |
5a5990d30 net: Avoid race b... |
95 |
if (!rtnl_trylock()) |
336ca57c3 net-sysfs: Use rt... |
96 |
return restart_syscall(); |
5a5990d30 net: Avoid race b... |
97 |
|
5e1fccc0b net: Allow userns... |
98 |
if (dev_isalive(netdev)) { |
6648c65e7 net: style cleanups |
99 100 |
ret = (*set)(netdev, new); if (ret == 0) |
1da177e4c Linux-2.6.12-rc2 |
101 102 103 104 105 106 |
ret = len; } rtnl_unlock(); err: return ret; } |
6be8aeef3 net: core: conver... |
107 |
NETDEVICE_SHOW_RO(dev_id, fmt_hex); |
3f85944fe net: Add sysfs fi... |
108 |
NETDEVICE_SHOW_RO(dev_port, fmt_dec); |
6be8aeef3 net: core: conver... |
109 110 |
NETDEVICE_SHOW_RO(addr_assign_type, fmt_dec); NETDEVICE_SHOW_RO(addr_len, fmt_dec); |
6be8aeef3 net: core: conver... |
111 112 113 |
NETDEVICE_SHOW_RO(ifindex, fmt_dec); NETDEVICE_SHOW_RO(type, fmt_dec); NETDEVICE_SHOW_RO(link_mode, fmt_dec); |
1da177e4c Linux-2.6.12-rc2 |
114 |
|
a54acb3a6 dev: introduce de... |
115 116 117 118 119 120 121 122 |
static ssize_t iflink_show(struct device *dev, struct device_attribute *attr, char *buf) { struct net_device *ndev = to_net_dev(dev); return sprintf(buf, fmt_dec, dev_get_iflink(ndev)); } static DEVICE_ATTR_RO(iflink); |
6b53dafe2 net: do not name ... |
123 |
static ssize_t format_name_assign_type(const struct net_device *dev, char *buf) |
685343fc3 net: add name_ass... |
124 |
{ |
6b53dafe2 net: do not name ... |
125 |
return sprintf(buf, fmt_dec, dev->name_assign_type); |
685343fc3 net: add name_ass... |
126 127 128 129 130 131 |
} static ssize_t name_assign_type_show(struct device *dev, struct device_attribute *attr, char *buf) { |
6b53dafe2 net: do not name ... |
132 |
struct net_device *ndev = to_net_dev(dev); |
685343fc3 net: add name_ass... |
133 |
ssize_t ret = -EINVAL; |
6b53dafe2 net: do not name ... |
134 |
if (ndev->name_assign_type != NET_NAME_UNKNOWN) |
685343fc3 net: add name_ass... |
135 136 137 138 139 |
ret = netdev_show(dev, attr, buf, format_name_assign_type); return ret; } static DEVICE_ATTR_RO(name_assign_type); |
1da177e4c Linux-2.6.12-rc2 |
140 |
/* use same locking rules as GIFHWADDR ioctl's */ |
6be8aeef3 net: core: conver... |
141 |
static ssize_t address_show(struct device *dev, struct device_attribute *attr, |
43cb76d91 Network: convert ... |
142 |
char *buf) |
1da177e4c Linux-2.6.12-rc2 |
143 |
{ |
6b53dafe2 net: do not name ... |
144 |
struct net_device *ndev = to_net_dev(dev); |
1da177e4c Linux-2.6.12-rc2 |
145 146 147 |
ssize_t ret = -EINVAL; read_lock(&dev_base_lock); |
6b53dafe2 net: do not name ... |
148 149 |
if (dev_isalive(ndev)) ret = sysfs_format_mac(buf, ndev->dev_addr, ndev->addr_len); |
1da177e4c Linux-2.6.12-rc2 |
150 151 152 |
read_unlock(&dev_base_lock); return ret; } |
6be8aeef3 net: core: conver... |
153 |
static DEVICE_ATTR_RO(address); |
1da177e4c Linux-2.6.12-rc2 |
154 |
|
6be8aeef3 net: core: conver... |
155 156 |
static ssize_t broadcast_show(struct device *dev, struct device_attribute *attr, char *buf) |
1da177e4c Linux-2.6.12-rc2 |
157 |
{ |
6b53dafe2 net: do not name ... |
158 |
struct net_device *ndev = to_net_dev(dev); |
6648c65e7 net: style cleanups |
159 |
|
6b53dafe2 net: do not name ... |
160 161 |
if (dev_isalive(ndev)) return sysfs_format_mac(buf, ndev->broadcast, ndev->addr_len); |
1da177e4c Linux-2.6.12-rc2 |
162 163 |
return -EINVAL; } |
6be8aeef3 net: core: conver... |
164 |
static DEVICE_ATTR_RO(broadcast); |
1da177e4c Linux-2.6.12-rc2 |
165 |
|
6b53dafe2 net: do not name ... |
166 |
static int change_carrier(struct net_device *dev, unsigned long new_carrier) |
fdae0fde5 net: allow to cha... |
167 |
{ |
6b53dafe2 net: do not name ... |
168 |
if (!netif_running(dev)) |
fdae0fde5 net: allow to cha... |
169 |
return -EINVAL; |
6648c65e7 net: style cleanups |
170 |
return dev_change_carrier(dev, (bool)new_carrier); |
fdae0fde5 net: allow to cha... |
171 |
} |
6be8aeef3 net: core: conver... |
172 173 |
static ssize_t carrier_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t len) |
fdae0fde5 net: allow to cha... |
174 175 176 |
{ return netdev_store(dev, attr, buf, len, change_carrier); } |
6be8aeef3 net: core: conver... |
177 |
static ssize_t carrier_show(struct device *dev, |
43cb76d91 Network: convert ... |
178 |
struct device_attribute *attr, char *buf) |
1da177e4c Linux-2.6.12-rc2 |
179 180 |
{ struct net_device *netdev = to_net_dev(dev); |
6648c65e7 net: style cleanups |
181 182 |
if (netif_running(netdev)) |
1da177e4c Linux-2.6.12-rc2 |
183 |
return sprintf(buf, fmt_dec, !!netif_carrier_ok(netdev)); |
6648c65e7 net: style cleanups |
184 |
|
1da177e4c Linux-2.6.12-rc2 |
185 186 |
return -EINVAL; } |
6be8aeef3 net: core: conver... |
187 |
static DEVICE_ATTR_RW(carrier); |
1da177e4c Linux-2.6.12-rc2 |
188 |
|
6be8aeef3 net: core: conver... |
189 |
static ssize_t speed_show(struct device *dev, |
d519e17e2 net: export devic... |
190 191 192 193 194 195 196 |
struct device_attribute *attr, char *buf) { struct net_device *netdev = to_net_dev(dev); int ret = -EINVAL; if (!rtnl_trylock()) return restart_syscall(); |
8ae6daca8 ethtool: Call eth... |
197 |
if (netif_running(netdev)) { |
7cad1bac9 net: core: use __... |
198 199 200 201 |
struct ethtool_link_ksettings cmd; if (!__ethtool_get_link_ksettings(netdev, &cmd)) ret = sprintf(buf, fmt_dec, cmd.base.speed); |
d519e17e2 net: export devic... |
202 203 204 205 |
} rtnl_unlock(); return ret; } |
6be8aeef3 net: core: conver... |
206 |
static DEVICE_ATTR_RO(speed); |
d519e17e2 net: export devic... |
207 |
|
6be8aeef3 net: core: conver... |
208 |
static ssize_t duplex_show(struct device *dev, |
d519e17e2 net: export devic... |
209 210 211 212 213 214 215 |
struct device_attribute *attr, char *buf) { struct net_device *netdev = to_net_dev(dev); int ret = -EINVAL; if (!rtnl_trylock()) return restart_syscall(); |
8ae6daca8 ethtool: Call eth... |
216 |
if (netif_running(netdev)) { |
7cad1bac9 net: core: use __... |
217 218 219 |
struct ethtool_link_ksettings cmd; if (!__ethtool_get_link_ksettings(netdev, &cmd)) { |
c6c13965f net: add unknown ... |
220 |
const char *duplex; |
7cad1bac9 net: core: use __... |
221 222 |
switch (cmd.base.duplex) { |
c6c13965f net: add unknown ... |
223 224 225 226 227 228 229 230 231 232 233 234 235 |
case DUPLEX_HALF: duplex = "half"; break; case DUPLEX_FULL: duplex = "full"; break; default: duplex = "unknown"; break; } ret = sprintf(buf, "%s ", duplex); } |
d519e17e2 net: export devic... |
236 237 238 239 |
} rtnl_unlock(); return ret; } |
6be8aeef3 net: core: conver... |
240 |
static DEVICE_ATTR_RO(duplex); |
d519e17e2 net: export devic... |
241 |
|
6be8aeef3 net: core: conver... |
242 |
static ssize_t dormant_show(struct device *dev, |
43cb76d91 Network: convert ... |
243 |
struct device_attribute *attr, char *buf) |
b00055aac [NET] core: add R... |
244 245 246 247 248 249 250 251 |
{ struct net_device *netdev = to_net_dev(dev); if (netif_running(netdev)) return sprintf(buf, fmt_dec, !!netif_dormant(netdev)); return -EINVAL; } |
6be8aeef3 net: core: conver... |
252 |
static DEVICE_ATTR_RO(dormant); |
b00055aac [NET] core: add R... |
253 |
|
36cbd3dcc net: mark read-on... |
254 |
static const char *const operstates[] = { |
b00055aac [NET] core: add R... |
255 256 257 258 259 260 261 262 |
"unknown", "notpresent", /* currently unused */ "down", "lowerlayerdown", "testing", /* currently unused */ "dormant", "up" }; |
6be8aeef3 net: core: conver... |
263 |
static ssize_t operstate_show(struct device *dev, |
43cb76d91 Network: convert ... |
264 |
struct device_attribute *attr, char *buf) |
b00055aac [NET] core: add R... |
265 266 267 268 269 270 271 272 273 |
{ const struct net_device *netdev = to_net_dev(dev); unsigned char operstate; read_lock(&dev_base_lock); operstate = netdev->operstate; if (!netif_running(netdev)) operstate = IF_OPER_DOWN; read_unlock(&dev_base_lock); |
e3a5cd9ed [NET]: Fix an off... |
274 |
if (operstate >= ARRAY_SIZE(operstates)) |
b00055aac [NET] core: add R... |
275 276 277 278 279 |
return -EINVAL; /* should not happen */ return sprintf(buf, "%s ", operstates[operstate]); } |
6be8aeef3 net: core: conver... |
280 |
static DEVICE_ATTR_RO(operstate); |
b00055aac [NET] core: add R... |
281 |
|
2d3b479df net-sysfs: expose... |
282 283 284 285 286 |
static ssize_t carrier_changes_show(struct device *dev, struct device_attribute *attr, char *buf) { struct net_device *netdev = to_net_dev(dev); |
6648c65e7 net: style cleanups |
287 |
|
2d3b479df net-sysfs: expose... |
288 289 290 291 |
return sprintf(buf, fmt_dec, atomic_read(&netdev->carrier_changes)); } static DEVICE_ATTR_RO(carrier_changes); |
1da177e4c Linux-2.6.12-rc2 |
292 |
/* read-write attributes */ |
1da177e4c Linux-2.6.12-rc2 |
293 |
|
6b53dafe2 net: do not name ... |
294 |
static int change_mtu(struct net_device *dev, unsigned long new_mtu) |
1da177e4c Linux-2.6.12-rc2 |
295 |
{ |
6648c65e7 net: style cleanups |
296 |
return dev_set_mtu(dev, (int)new_mtu); |
1da177e4c Linux-2.6.12-rc2 |
297 |
} |
6be8aeef3 net: core: conver... |
298 |
static ssize_t mtu_store(struct device *dev, struct device_attribute *attr, |
43cb76d91 Network: convert ... |
299 |
const char *buf, size_t len) |
1da177e4c Linux-2.6.12-rc2 |
300 |
{ |
43cb76d91 Network: convert ... |
301 |
return netdev_store(dev, attr, buf, len, change_mtu); |
1da177e4c Linux-2.6.12-rc2 |
302 |
} |
6be8aeef3 net: core: conver... |
303 |
NETDEVICE_SHOW_RW(mtu, fmt_dec); |
1da177e4c Linux-2.6.12-rc2 |
304 |
|
6b53dafe2 net: do not name ... |
305 |
static int change_flags(struct net_device *dev, unsigned long new_flags) |
1da177e4c Linux-2.6.12-rc2 |
306 |
{ |
6648c65e7 net: style cleanups |
307 |
return dev_change_flags(dev, (unsigned int)new_flags); |
1da177e4c Linux-2.6.12-rc2 |
308 |
} |
6be8aeef3 net: core: conver... |
309 |
static ssize_t flags_store(struct device *dev, struct device_attribute *attr, |
43cb76d91 Network: convert ... |
310 |
const char *buf, size_t len) |
1da177e4c Linux-2.6.12-rc2 |
311 |
{ |
43cb76d91 Network: convert ... |
312 |
return netdev_store(dev, attr, buf, len, change_flags); |
1da177e4c Linux-2.6.12-rc2 |
313 |
} |
6be8aeef3 net: core: conver... |
314 |
NETDEVICE_SHOW_RW(flags, fmt_hex); |
1da177e4c Linux-2.6.12-rc2 |
315 |
|
6b53dafe2 net: do not name ... |
316 |
static int change_tx_queue_len(struct net_device *dev, unsigned long new_len) |
1da177e4c Linux-2.6.12-rc2 |
317 |
{ |
0cd295035 net: make struct ... |
318 319 320 321 322 |
unsigned int orig_len = dev->tx_queue_len; int res; if (new_len != (unsigned int)new_len) return -ERANGE; |
08294a26e net: introduce NE... |
323 324 325 326 327 328 329 330 331 332 333 334 335 |
if (new_len != orig_len) { dev->tx_queue_len = new_len; res = call_netdevice_notifiers(NETDEV_CHANGE_TX_QUEUE_LEN, dev); res = notifier_to_errno(res); if (res) { netdev_err(dev, "refused to change device tx_queue_len "); dev->tx_queue_len = orig_len; return -EFAULT; } } |
1da177e4c Linux-2.6.12-rc2 |
336 337 |
return 0; } |
6be8aeef3 net: core: conver... |
338 |
static ssize_t tx_queue_len_store(struct device *dev, |
43cb76d91 Network: convert ... |
339 340 |
struct device_attribute *attr, const char *buf, size_t len) |
1da177e4c Linux-2.6.12-rc2 |
341 |
{ |
5e1fccc0b net: Allow userns... |
342 343 |
if (!capable(CAP_NET_ADMIN)) return -EPERM; |
43cb76d91 Network: convert ... |
344 |
return netdev_store(dev, attr, buf, len, change_tx_queue_len); |
1da177e4c Linux-2.6.12-rc2 |
345 |
} |
0cd295035 net: make struct ... |
346 |
NETDEVICE_SHOW_RW(tx_queue_len, fmt_dec); |
1da177e4c Linux-2.6.12-rc2 |
347 |
|
3b47d3039 net: gro: add a p... |
348 349 350 351 352 353 354 |
static int change_gro_flush_timeout(struct net_device *dev, unsigned long val) { dev->gro_flush_timeout = val; return 0; } static ssize_t gro_flush_timeout_store(struct device *dev, |
6648c65e7 net: style cleanups |
355 356 |
struct device_attribute *attr, const char *buf, size_t len) |
3b47d3039 net: gro: add a p... |
357 358 359 360 361 362 363 |
{ if (!capable(CAP_NET_ADMIN)) return -EPERM; return netdev_store(dev, attr, buf, len, change_gro_flush_timeout); } NETDEVICE_SHOW_RW(gro_flush_timeout, fmt_ulong); |
6be8aeef3 net: core: conver... |
364 |
static ssize_t ifalias_store(struct device *dev, struct device_attribute *attr, |
0b815a1a6 net: network devi... |
365 366 367 |
const char *buf, size_t len) { struct net_device *netdev = to_net_dev(dev); |
5e1fccc0b net: Allow userns... |
368 |
struct net *net = dev_net(netdev); |
0b815a1a6 net: network devi... |
369 370 |
size_t count = len; ssize_t ret; |
5e1fccc0b net: Allow userns... |
371 |
if (!ns_capable(net->user_ns, CAP_NET_ADMIN)) |
0b815a1a6 net: network devi... |
372 373 374 375 376 377 |
return -EPERM; /* ignore trailing newline */ if (len > 0 && buf[len - 1] == ' ') --count; |
336ca57c3 net-sysfs: Use rt... |
378 379 |
if (!rtnl_trylock()) return restart_syscall(); |
0b815a1a6 net: network devi... |
380 381 382 383 384 |
ret = dev_set_alias(netdev, buf, count); rtnl_unlock(); return ret < 0 ? ret : len; } |
6be8aeef3 net: core: conver... |
385 |
static ssize_t ifalias_show(struct device *dev, |
0b815a1a6 net: network devi... |
386 387 388 389 |
struct device_attribute *attr, char *buf) { const struct net_device *netdev = to_net_dev(dev); ssize_t ret = 0; |
336ca57c3 net-sysfs: Use rt... |
390 391 |
if (!rtnl_trylock()) return restart_syscall(); |
0b815a1a6 net: network devi... |
392 393 394 395 396 397 |
if (netdev->ifalias) ret = sprintf(buf, "%s ", netdev->ifalias); rtnl_unlock(); return ret; } |
6be8aeef3 net: core: conver... |
398 |
static DEVICE_ATTR_RW(ifalias); |
a512b92b3 net: add sysfs en... |
399 |
|
6b53dafe2 net: do not name ... |
400 |
static int change_group(struct net_device *dev, unsigned long new_group) |
a512b92b3 net: add sysfs en... |
401 |
{ |
6648c65e7 net: style cleanups |
402 |
dev_set_group(dev, (int)new_group); |
a512b92b3 net: add sysfs en... |
403 404 |
return 0; } |
6be8aeef3 net: core: conver... |
405 406 |
static ssize_t group_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t len) |
a512b92b3 net: add sysfs en... |
407 408 409 |
{ return netdev_store(dev, attr, buf, len, change_group); } |
6be8aeef3 net: core: conver... |
410 411 |
NETDEVICE_SHOW(group, fmt_dec); static DEVICE_ATTR(netdev_group, S_IRUGO | S_IWUSR, group_show, group_store); |
d746d707a net core: Add pro... |
412 413 |
static int change_proto_down(struct net_device *dev, unsigned long proto_down) { |
6648c65e7 net: style cleanups |
414 |
return dev_change_proto_down(dev, (bool)proto_down); |
d746d707a net core: Add pro... |
415 416 417 418 419 420 421 422 423 |
} static ssize_t proto_down_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t len) { return netdev_store(dev, attr, buf, len, change_proto_down); } NETDEVICE_SHOW_RW(proto_down, fmt_dec); |
cc998ff88 Merge git://git.k... |
424 |
static ssize_t phys_port_id_show(struct device *dev, |
ff80e519a net: export physi... |
425 426 427 428 429 430 431 432 433 |
struct device_attribute *attr, char *buf) { struct net_device *netdev = to_net_dev(dev); ssize_t ret = -EINVAL; if (!rtnl_trylock()) return restart_syscall(); if (dev_isalive(netdev)) { |
02637fce3 net: rename netde... |
434 |
struct netdev_phys_item_id ppid; |
ff80e519a net: export physi... |
435 436 437 438 439 440 441 442 443 444 |
ret = dev_get_phys_port_id(netdev, &ppid); if (!ret) ret = sprintf(buf, "%*phN ", ppid.id_len, ppid.id); } rtnl_unlock(); return ret; } |
cc998ff88 Merge git://git.k... |
445 |
static DEVICE_ATTR_RO(phys_port_id); |
db24a9044 net: add support ... |
446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 |
static ssize_t phys_port_name_show(struct device *dev, struct device_attribute *attr, char *buf) { struct net_device *netdev = to_net_dev(dev); ssize_t ret = -EINVAL; if (!rtnl_trylock()) return restart_syscall(); if (dev_isalive(netdev)) { char name[IFNAMSIZ]; ret = dev_get_phys_port_name(netdev, name, sizeof(name)); if (!ret) ret = sprintf(buf, "%s ", name); } rtnl_unlock(); return ret; } static DEVICE_ATTR_RO(phys_port_name); |
aecbe01e7 net-sysfs: expose... |
468 469 470 471 472 473 474 475 476 477 |
static ssize_t phys_switch_id_show(struct device *dev, struct device_attribute *attr, char *buf) { struct net_device *netdev = to_net_dev(dev); ssize_t ret = -EINVAL; if (!rtnl_trylock()) return restart_syscall(); if (dev_isalive(netdev)) { |
f8e20a9f8 switchdev: conver... |
478 |
struct switchdev_attr attr = { |
6ff64f6f9 switchdev: Pass o... |
479 |
.orig_dev = netdev, |
1f8683987 switchdev: rename... |
480 |
.id = SWITCHDEV_ATTR_ID_PORT_PARENT_ID, |
f8e20a9f8 switchdev: conver... |
481 482 |
.flags = SWITCHDEV_F_NO_RECURSE, }; |
aecbe01e7 net-sysfs: expose... |
483 |
|
f8e20a9f8 switchdev: conver... |
484 |
ret = switchdev_port_attr_get(netdev, &attr); |
aecbe01e7 net-sysfs: expose... |
485 |
if (!ret) |
42275bd8f switchdev: don't ... |
486 487 488 |
ret = sprintf(buf, "%*phN ", attr.u.ppid.id_len, attr.u.ppid.id); |
aecbe01e7 net-sysfs: expose... |
489 490 491 492 493 494 |
} rtnl_unlock(); return ret; } static DEVICE_ATTR_RO(phys_switch_id); |
ec6cc5993 net: make net sys... |
495 |
static struct attribute *net_class_attrs[] __ro_after_init = { |
6be8aeef3 net: core: conver... |
496 497 498 |
&dev_attr_netdev_group.attr, &dev_attr_type.attr, &dev_attr_dev_id.attr, |
3f85944fe net: Add sysfs fi... |
499 |
&dev_attr_dev_port.attr, |
6be8aeef3 net: core: conver... |
500 501 |
&dev_attr_iflink.attr, &dev_attr_ifindex.attr, |
685343fc3 net: add name_ass... |
502 |
&dev_attr_name_assign_type.attr, |
6be8aeef3 net: core: conver... |
503 504 505 506 507 508 509 510 511 |
&dev_attr_addr_assign_type.attr, &dev_attr_addr_len.attr, &dev_attr_link_mode.attr, &dev_attr_address.attr, &dev_attr_broadcast.attr, &dev_attr_speed.attr, &dev_attr_duplex.attr, &dev_attr_dormant.attr, &dev_attr_operstate.attr, |
2d3b479df net-sysfs: expose... |
512 |
&dev_attr_carrier_changes.attr, |
6be8aeef3 net: core: conver... |
513 514 515 516 517 |
&dev_attr_ifalias.attr, &dev_attr_carrier.attr, &dev_attr_mtu.attr, &dev_attr_flags.attr, &dev_attr_tx_queue_len.attr, |
3b47d3039 net: gro: add a p... |
518 |
&dev_attr_gro_flush_timeout.attr, |
cc998ff88 Merge git://git.k... |
519 |
&dev_attr_phys_port_id.attr, |
db24a9044 net: add support ... |
520 |
&dev_attr_phys_port_name.attr, |
aecbe01e7 net-sysfs: expose... |
521 |
&dev_attr_phys_switch_id.attr, |
d746d707a net core: Add pro... |
522 |
&dev_attr_proto_down.attr, |
6be8aeef3 net: core: conver... |
523 |
NULL, |
1da177e4c Linux-2.6.12-rc2 |
524 |
}; |
6be8aeef3 net: core: conver... |
525 |
ATTRIBUTE_GROUPS(net_class); |
1da177e4c Linux-2.6.12-rc2 |
526 527 |
/* Show a given an attribute in the statistics group */ |
43cb76d91 Network: convert ... |
528 529 |
static ssize_t netstat_show(const struct device *d, struct device_attribute *attr, char *buf, |
1da177e4c Linux-2.6.12-rc2 |
530 531 |
unsigned long offset) { |
43cb76d91 Network: convert ... |
532 |
struct net_device *dev = to_net_dev(d); |
1da177e4c Linux-2.6.12-rc2 |
533 |
ssize_t ret = -EINVAL; |
be1f3c2c0 net: Enable 64-bi... |
534 |
WARN_ON(offset > sizeof(struct rtnl_link_stats64) || |
6648c65e7 net: style cleanups |
535 |
offset % sizeof(u64) != 0); |
1da177e4c Linux-2.6.12-rc2 |
536 537 |
read_lock(&dev_base_lock); |
96e74088f net: The dev->get... |
538 |
if (dev_isalive(dev)) { |
28172739f net: fix 64 bit c... |
539 540 |
struct rtnl_link_stats64 temp; const struct rtnl_link_stats64 *stats = dev_get_stats(dev, &temp); |
6648c65e7 net: style cleanups |
541 |
ret = sprintf(buf, fmt_u64, *(u64 *)(((u8 *)stats) + offset)); |
96e74088f net: The dev->get... |
542 |
} |
1da177e4c Linux-2.6.12-rc2 |
543 544 545 546 547 548 |
read_unlock(&dev_base_lock); return ret; } /* generate a read-only statistics attribute */ #define NETSTAT_ENTRY(name) \ |
6be8aeef3 net: core: conver... |
549 |
static ssize_t name##_show(struct device *d, \ |
6648c65e7 net: style cleanups |
550 |
struct device_attribute *attr, char *buf) \ |
1da177e4c Linux-2.6.12-rc2 |
551 |
{ \ |
43cb76d91 Network: convert ... |
552 |
return netstat_show(d, attr, buf, \ |
be1f3c2c0 net: Enable 64-bi... |
553 |
offsetof(struct rtnl_link_stats64, name)); \ |
1da177e4c Linux-2.6.12-rc2 |
554 |
} \ |
6be8aeef3 net: core: conver... |
555 |
static DEVICE_ATTR_RO(name) |
1da177e4c Linux-2.6.12-rc2 |
556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 |
NETSTAT_ENTRY(rx_packets); NETSTAT_ENTRY(tx_packets); NETSTAT_ENTRY(rx_bytes); NETSTAT_ENTRY(tx_bytes); NETSTAT_ENTRY(rx_errors); NETSTAT_ENTRY(tx_errors); NETSTAT_ENTRY(rx_dropped); NETSTAT_ENTRY(tx_dropped); NETSTAT_ENTRY(multicast); NETSTAT_ENTRY(collisions); NETSTAT_ENTRY(rx_length_errors); NETSTAT_ENTRY(rx_over_errors); NETSTAT_ENTRY(rx_crc_errors); NETSTAT_ENTRY(rx_frame_errors); NETSTAT_ENTRY(rx_fifo_errors); NETSTAT_ENTRY(rx_missed_errors); NETSTAT_ENTRY(tx_aborted_errors); NETSTAT_ENTRY(tx_carrier_errors); NETSTAT_ENTRY(tx_fifo_errors); NETSTAT_ENTRY(tx_heartbeat_errors); NETSTAT_ENTRY(tx_window_errors); NETSTAT_ENTRY(rx_compressed); NETSTAT_ENTRY(tx_compressed); |
6e7333d31 net: add rx_nohan... |
580 |
NETSTAT_ENTRY(rx_nohandler); |
1da177e4c Linux-2.6.12-rc2 |
581 |
|
ec6cc5993 net: make net sys... |
582 |
static struct attribute *netstat_attrs[] __ro_after_init = { |
43cb76d91 Network: convert ... |
583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 |
&dev_attr_rx_packets.attr, &dev_attr_tx_packets.attr, &dev_attr_rx_bytes.attr, &dev_attr_tx_bytes.attr, &dev_attr_rx_errors.attr, &dev_attr_tx_errors.attr, &dev_attr_rx_dropped.attr, &dev_attr_tx_dropped.attr, &dev_attr_multicast.attr, &dev_attr_collisions.attr, &dev_attr_rx_length_errors.attr, &dev_attr_rx_over_errors.attr, &dev_attr_rx_crc_errors.attr, &dev_attr_rx_frame_errors.attr, &dev_attr_rx_fifo_errors.attr, &dev_attr_rx_missed_errors.attr, &dev_attr_tx_aborted_errors.attr, &dev_attr_tx_carrier_errors.attr, &dev_attr_tx_fifo_errors.attr, &dev_attr_tx_heartbeat_errors.attr, &dev_attr_tx_window_errors.attr, &dev_attr_rx_compressed.attr, &dev_attr_tx_compressed.attr, |
6e7333d31 net: add rx_nohan... |
606 |
&dev_attr_rx_nohandler.attr, |
1da177e4c Linux-2.6.12-rc2 |
607 608 |
NULL }; |
38ef00cc3 net: constify att... |
609 |
static const struct attribute_group netstat_group = { |
1da177e4c Linux-2.6.12-rc2 |
610 611 612 |
.name = "statistics", .attrs = netstat_attrs, }; |
38c1a01cf wireless: add bac... |
613 614 615 616 617 |
#if IS_ENABLED(CONFIG_WIRELESS_EXT) || IS_ENABLED(CONFIG_CFG80211) static struct attribute *wireless_attrs[] = { NULL }; |
38ef00cc3 net: constify att... |
618 |
static const struct attribute_group wireless_group = { |
38c1a01cf wireless: add bac... |
619 620 621 622 |
.name = "wireless", .attrs = wireless_attrs, }; #endif |
6be8aeef3 net: core: conver... |
623 624 625 |
#else /* CONFIG_SYSFS */ #define net_class_groups NULL |
d6523ddf2 net/sysfs: Fix th... |
626 |
#endif /* CONFIG_SYSFS */ |
1da177e4c Linux-2.6.12-rc2 |
627 |
|
a953be53c net-sysfs: add su... |
628 |
#ifdef CONFIG_SYSFS |
6648c65e7 net: style cleanups |
629 630 |
#define to_rx_queue_attr(_attr) \ container_of(_attr, struct rx_queue_attribute, attr) |
0a9627f26 rps: Receive Pack... |
631 632 633 634 635 636 |
#define to_rx_queue(obj) container_of(obj, struct netdev_rx_queue, kobj) static ssize_t rx_queue_attr_show(struct kobject *kobj, struct attribute *attr, char *buf) { |
667e427bc net: mark receive... |
637 |
const struct rx_queue_attribute *attribute = to_rx_queue_attr(attr); |
0a9627f26 rps: Receive Pack... |
638 639 640 641 |
struct netdev_rx_queue *queue = to_rx_queue(kobj); if (!attribute->show) return -EIO; |
718ad681e net: drop unused ... |
642 |
return attribute->show(queue, buf); |
0a9627f26 rps: Receive Pack... |
643 644 645 646 647 |
} static ssize_t rx_queue_attr_store(struct kobject *kobj, struct attribute *attr, const char *buf, size_t count) { |
667e427bc net: mark receive... |
648 |
const struct rx_queue_attribute *attribute = to_rx_queue_attr(attr); |
0a9627f26 rps: Receive Pack... |
649 650 651 652 |
struct netdev_rx_queue *queue = to_rx_queue(kobj); if (!attribute->store) return -EIO; |
718ad681e net: drop unused ... |
653 |
return attribute->store(queue, buf, count); |
0a9627f26 rps: Receive Pack... |
654 |
} |
fa50d6457 net: make rx_queu... |
655 |
static const struct sysfs_ops rx_queue_sysfs_ops = { |
0a9627f26 rps: Receive Pack... |
656 657 658 |
.show = rx_queue_attr_show, .store = rx_queue_attr_store, }; |
a953be53c net-sysfs: add su... |
659 |
#ifdef CONFIG_RPS |
718ad681e net: drop unused ... |
660 |
static ssize_t show_rps_map(struct netdev_rx_queue *queue, char *buf) |
0a9627f26 rps: Receive Pack... |
661 662 663 |
{ struct rps_map *map; cpumask_var_t mask; |
f09068276 net: use %*pb[l] ... |
664 |
int i, len; |
0a9627f26 rps: Receive Pack... |
665 666 667 668 669 670 671 672 673 |
if (!zalloc_cpumask_var(&mask, GFP_KERNEL)) return -ENOMEM; rcu_read_lock(); map = rcu_dereference(queue->rps_map); if (map) for (i = 0; i < map->len; i++) cpumask_set_cpu(map->cpus[i], mask); |
f09068276 net: use %*pb[l] ... |
674 675 |
len = snprintf(buf, PAGE_SIZE, "%*pb ", cpumask_pr_args(mask)); |
0a9627f26 rps: Receive Pack... |
676 |
rcu_read_unlock(); |
0a9627f26 rps: Receive Pack... |
677 |
free_cpumask_var(mask); |
f09068276 net: use %*pb[l] ... |
678 679 |
return len < PAGE_SIZE ? len : -EINVAL; |
0a9627f26 rps: Receive Pack... |
680 |
} |
f5acb907d rps: static funct... |
681 |
static ssize_t store_rps_map(struct netdev_rx_queue *queue, |
718ad681e net: drop unused ... |
682 |
const char *buf, size_t len) |
0a9627f26 rps: Receive Pack... |
683 684 685 686 |
{ struct rps_map *old_map, *map; cpumask_var_t mask; int err, cpu, i; |
da65ad1fe net: allow sleepi... |
687 |
static DEFINE_MUTEX(rps_map_mutex); |
0a9627f26 rps: Receive Pack... |
688 689 690 691 692 693 694 695 696 697 698 699 |
if (!capable(CAP_NET_ADMIN)) return -EPERM; if (!alloc_cpumask_var(&mask, GFP_KERNEL)) return -ENOMEM; err = bitmap_parse(buf, len, cpumask_bits(mask), nr_cpumask_bits); if (err) { free_cpumask_var(mask); return err; } |
95c961747 net: cleanup unsi... |
700 |
map = kzalloc(max_t(unsigned int, |
6648c65e7 net: style cleanups |
701 702 |
RPS_MAP_SIZE(cpumask_weight(mask)), L1_CACHE_BYTES), GFP_KERNEL); |
0a9627f26 rps: Receive Pack... |
703 704 705 706 707 708 709 710 |
if (!map) { free_cpumask_var(mask); return -ENOMEM; } i = 0; for_each_cpu_and(cpu, mask, cpu_online_mask) map->cpus[i++] = cpu; |
6648c65e7 net: style cleanups |
711 |
if (i) { |
0a9627f26 rps: Receive Pack... |
712 |
map->len = i; |
6648c65e7 net: style cleanups |
713 |
} else { |
0a9627f26 rps: Receive Pack... |
714 715 716 |
kfree(map); map = NULL; } |
da65ad1fe net: allow sleepi... |
717 |
mutex_lock(&rps_map_mutex); |
6e3f7faf3 rps: add __rcu an... |
718 |
old_map = rcu_dereference_protected(queue->rps_map, |
da65ad1fe net: allow sleepi... |
719 |
mutex_is_locked(&rps_map_mutex)); |
0a9627f26 rps: Receive Pack... |
720 |
rcu_assign_pointer(queue->rps_map, map); |
0a9627f26 rps: Receive Pack... |
721 |
|
adc9300e7 net: use jump_lab... |
722 |
if (map) |
c5905afb0 static keys: Intr... |
723 |
static_key_slow_inc(&rps_needed); |
10e4ea751 net: Fix race con... |
724 |
if (old_map) |
c5905afb0 static keys: Intr... |
725 |
static_key_slow_dec(&rps_needed); |
10e4ea751 net: Fix race con... |
726 |
|
da65ad1fe net: allow sleepi... |
727 |
mutex_unlock(&rps_map_mutex); |
10e4ea751 net: Fix race con... |
728 729 730 |
if (old_map) kfree_rcu(old_map, rcu); |
0a9627f26 rps: Receive Pack... |
731 732 733 |
free_cpumask_var(mask); return len; } |
fec5e652e rfs: Receive Flow... |
734 |
static ssize_t show_rps_dev_flow_table_cnt(struct netdev_rx_queue *queue, |
fec5e652e rfs: Receive Flow... |
735 736 737 |
char *buf) { struct rps_dev_flow_table *flow_table; |
60b778ce5 rfs: better sizin... |
738 |
unsigned long val = 0; |
fec5e652e rfs: Receive Flow... |
739 740 741 742 |
rcu_read_lock(); flow_table = rcu_dereference(queue->rps_flow_table); if (flow_table) |
60b778ce5 rfs: better sizin... |
743 |
val = (unsigned long)flow_table->mask + 1; |
fec5e652e rfs: Receive Flow... |
744 |
rcu_read_unlock(); |
60b778ce5 rfs: better sizin... |
745 746 |
return sprintf(buf, "%lu ", val); |
fec5e652e rfs: Receive Flow... |
747 |
} |
fec5e652e rfs: Receive Flow... |
748 749 750 751 |
static void rps_dev_flow_table_release(struct rcu_head *rcu) { struct rps_dev_flow_table *table = container_of(rcu, struct rps_dev_flow_table, rcu); |
243198d09 rps_dev_flow_tabl... |
752 |
vfree(table); |
fec5e652e rfs: Receive Flow... |
753 |
} |
f5acb907d rps: static funct... |
754 |
static ssize_t store_rps_dev_flow_table_cnt(struct netdev_rx_queue *queue, |
718ad681e net: drop unused ... |
755 |
const char *buf, size_t len) |
fec5e652e rfs: Receive Flow... |
756 |
{ |
60b778ce5 rfs: better sizin... |
757 |
unsigned long mask, count; |
fec5e652e rfs: Receive Flow... |
758 759 |
struct rps_dev_flow_table *table, *old_table; static DEFINE_SPINLOCK(rps_dev_flow_lock); |
60b778ce5 rfs: better sizin... |
760 |
int rc; |
fec5e652e rfs: Receive Flow... |
761 762 763 |
if (!capable(CAP_NET_ADMIN)) return -EPERM; |
60b778ce5 rfs: better sizin... |
764 765 766 |
rc = kstrtoul(buf, 0, &count); if (rc < 0) return rc; |
fec5e652e rfs: Receive Flow... |
767 768 |
if (count) { |
60b778ce5 rfs: better sizin... |
769 770 771 772 773 774 775 |
mask = count - 1; /* mask = roundup_pow_of_two(count) - 1; * without overflows... */ while ((mask | (mask >> 1)) != mask) mask |= (mask >> 1); /* On 64 bit arches, must check mask fits in table->mask (u32), |
8e3bff96a net: more spellin... |
776 777 |
* and on 32bit arches, must check * RPS_DEV_FLOW_TABLE_SIZE(mask + 1) doesn't overflow. |
60b778ce5 rfs: better sizin... |
778 779 780 |
*/ #if BITS_PER_LONG > 32 if (mask > (unsigned long)(u32)mask) |
a0a129f8b rps: fix insuffic... |
781 |
return -EINVAL; |
60b778ce5 rfs: better sizin... |
782 783 |
#else if (mask > (ULONG_MAX - RPS_DEV_FLOW_TABLE_SIZE(1)) |
a0a129f8b rps: fix insuffic... |
784 |
/ sizeof(struct rps_dev_flow)) { |
fec5e652e rfs: Receive Flow... |
785 786 787 |
/* Enforce a limit to prevent overflow */ return -EINVAL; } |
60b778ce5 rfs: better sizin... |
788 789 |
#endif table = vmalloc(RPS_DEV_FLOW_TABLE_SIZE(mask + 1)); |
fec5e652e rfs: Receive Flow... |
790 791 |
if (!table) return -ENOMEM; |
60b778ce5 rfs: better sizin... |
792 793 794 |
table->mask = mask; for (count = 0; count <= mask; count++) table->flows[count].cpu = RPS_NO_CPU; |
6648c65e7 net: style cleanups |
795 |
} else { |
fec5e652e rfs: Receive Flow... |
796 |
table = NULL; |
6648c65e7 net: style cleanups |
797 |
} |
fec5e652e rfs: Receive Flow... |
798 799 |
spin_lock(&rps_dev_flow_lock); |
6e3f7faf3 rps: add __rcu an... |
800 801 |
old_table = rcu_dereference_protected(queue->rps_flow_table, lockdep_is_held(&rps_dev_flow_lock)); |
fec5e652e rfs: Receive Flow... |
802 803 804 805 806 807 808 809 |
rcu_assign_pointer(queue->rps_flow_table, table); spin_unlock(&rps_dev_flow_lock); if (old_table) call_rcu(&old_table->rcu, rps_dev_flow_table_release); return len; } |
667e427bc net: mark receive... |
810 811 |
static struct rx_queue_attribute rps_cpus_attribute __ro_after_init = __ATTR(rps_cpus, S_IRUGO | S_IWUSR, show_rps_map, store_rps_map); |
0a9627f26 rps: Receive Pack... |
812 |
|
667e427bc net: mark receive... |
813 814 815 |
static struct rx_queue_attribute rps_dev_flow_table_cnt_attribute __ro_after_init = __ATTR(rps_flow_cnt, S_IRUGO | S_IWUSR, show_rps_dev_flow_table_cnt, store_rps_dev_flow_table_cnt); |
a953be53c net-sysfs: add su... |
816 |
#endif /* CONFIG_RPS */ |
fec5e652e rfs: Receive Flow... |
817 |
|
667e427bc net: mark receive... |
818 |
static struct attribute *rx_queue_default_attrs[] __ro_after_init = { |
a953be53c net-sysfs: add su... |
819 |
#ifdef CONFIG_RPS |
0a9627f26 rps: Receive Pack... |
820 |
&rps_cpus_attribute.attr, |
fec5e652e rfs: Receive Flow... |
821 |
&rps_dev_flow_table_cnt_attribute.attr, |
a953be53c net-sysfs: add su... |
822 |
#endif |
0a9627f26 rps: Receive Pack... |
823 824 825 826 827 828 |
NULL }; static void rx_queue_release(struct kobject *kobj) { struct netdev_rx_queue *queue = to_rx_queue(kobj); |
a953be53c net-sysfs: add su... |
829 |
#ifdef CONFIG_RPS |
6e3f7faf3 rps: add __rcu an... |
830 831 |
struct rps_map *map; struct rps_dev_flow_table *flow_table; |
0a9627f26 rps: Receive Pack... |
832 |
|
33d480ce6 net: cleanup some... |
833 |
map = rcu_dereference_protected(queue->rps_map, 1); |
9ea19481d net: zero kobject... |
834 835 |
if (map) { RCU_INIT_POINTER(queue->rps_map, NULL); |
f6f80238f net,rcu: convert ... |
836 |
kfree_rcu(map, rcu); |
9ea19481d net: zero kobject... |
837 |
} |
6e3f7faf3 rps: add __rcu an... |
838 |
|
33d480ce6 net: cleanup some... |
839 |
flow_table = rcu_dereference_protected(queue->rps_flow_table, 1); |
9ea19481d net: zero kobject... |
840 841 |
if (flow_table) { RCU_INIT_POINTER(queue->rps_flow_table, NULL); |
6e3f7faf3 rps: add __rcu an... |
842 |
call_rcu(&flow_table->rcu, rps_dev_flow_table_release); |
9ea19481d net: zero kobject... |
843 |
} |
a953be53c net-sysfs: add su... |
844 |
#endif |
0a9627f26 rps: Receive Pack... |
845 |
|
9ea19481d net: zero kobject... |
846 |
memset(kobj, 0, sizeof(*kobj)); |
fe8222406 net: Simplify RX ... |
847 |
dev_put(queue->dev); |
0a9627f26 rps: Receive Pack... |
848 |
} |
82ef3d5d5 net: fix "queues"... |
849 850 851 852 853 854 855 856 857 858 859 |
static const void *rx_queue_namespace(struct kobject *kobj) { struct netdev_rx_queue *queue = to_rx_queue(kobj); struct device *dev = &queue->dev->dev; const void *ns = NULL; if (dev->class && dev->class->ns_type) ns = dev->class->namespace(dev); return ns; } |
667e427bc net: mark receive... |
860 |
static struct kobj_type rx_queue_ktype __ro_after_init = { |
0a9627f26 rps: Receive Pack... |
861 862 863 |
.sysfs_ops = &rx_queue_sysfs_ops, .release = rx_queue_release, .default_attrs = rx_queue_default_attrs, |
82ef3d5d5 net: fix "queues"... |
864 |
.namespace = rx_queue_namespace |
0a9627f26 rps: Receive Pack... |
865 |
}; |
6b53dafe2 net: do not name ... |
866 |
static int rx_queue_add_kobject(struct net_device *dev, int index) |
0a9627f26 rps: Receive Pack... |
867 |
{ |
6b53dafe2 net: do not name ... |
868 |
struct netdev_rx_queue *queue = dev->_rx + index; |
0a9627f26 rps: Receive Pack... |
869 870 |
struct kobject *kobj = &queue->kobj; int error = 0; |
6b53dafe2 net: do not name ... |
871 |
kobj->kset = dev->queues_kset; |
0a9627f26 rps: Receive Pack... |
872 |
error = kobject_init_and_add(kobj, &rx_queue_ktype, NULL, |
6648c65e7 net: style cleanups |
873 |
"rx-%u", index); |
a953be53c net-sysfs: add su... |
874 |
if (error) |
d0d668371 net: don't decrem... |
875 |
return error; |
a953be53c net-sysfs: add su... |
876 |
|
6b53dafe2 net: do not name ... |
877 878 |
if (dev->sysfs_rx_queue_group) { error = sysfs_create_group(kobj, dev->sysfs_rx_queue_group); |
d0d668371 net: don't decrem... |
879 880 881 882 |
if (error) { kobject_put(kobj); return error; } |
0a9627f26 rps: Receive Pack... |
883 884 885 |
} kobject_uevent(kobj, KOBJ_ADD); |
fe8222406 net: Simplify RX ... |
886 |
dev_hold(queue->dev); |
0a9627f26 rps: Receive Pack... |
887 888 889 |
return error; } |
80dd6eac0 net-sysfs: fix co... |
890 |
#endif /* CONFIG_SYSFS */ |
0a9627f26 rps: Receive Pack... |
891 |
|
62fe0b40a net: Allow changi... |
892 |
int |
6b53dafe2 net: do not name ... |
893 |
net_rx_queue_update_kobjects(struct net_device *dev, int old_num, int new_num) |
0a9627f26 rps: Receive Pack... |
894 |
{ |
a953be53c net-sysfs: add su... |
895 |
#ifdef CONFIG_SYSFS |
0a9627f26 rps: Receive Pack... |
896 897 |
int i; int error = 0; |
a953be53c net-sysfs: add su... |
898 |
#ifndef CONFIG_RPS |
6b53dafe2 net: do not name ... |
899 |
if (!dev->sysfs_rx_queue_group) |
a953be53c net-sysfs: add su... |
900 901 |
return 0; #endif |
62fe0b40a net: Allow changi... |
902 |
for (i = old_num; i < new_num; i++) { |
6b53dafe2 net: do not name ... |
903 |
error = rx_queue_add_kobject(dev, i); |
62fe0b40a net: Allow changi... |
904 905 |
if (error) { new_num = old_num; |
0a9627f26 rps: Receive Pack... |
906 |
break; |
62fe0b40a net: Allow changi... |
907 |
} |
0a9627f26 rps: Receive Pack... |
908 |
} |
a953be53c net-sysfs: add su... |
909 |
while (--i >= new_num) { |
002d8a1a6 net: skip genener... |
910 |
struct kobject *kobj = &dev->_rx[i].kobj; |
91864f585 net: use net->cou... |
911 |
if (!atomic_read(&dev_net(dev)->count)) |
002d8a1a6 net: skip genener... |
912 |
kobj->uevent_suppress = 1; |
6b53dafe2 net: do not name ... |
913 |
if (dev->sysfs_rx_queue_group) |
002d8a1a6 net: skip genener... |
914 915 |
sysfs_remove_group(kobj, dev->sysfs_rx_queue_group); kobject_put(kobj); |
a953be53c net-sysfs: add su... |
916 |
} |
0a9627f26 rps: Receive Pack... |
917 918 |
return error; |
bf2641451 xps: Add CONFIG_XPS |
919 920 921 |
#else return 0; #endif |
0a9627f26 rps: Receive Pack... |
922 |
} |
ccf5ff69f net: new counter ... |
923 |
#ifdef CONFIG_SYSFS |
1d24eb481 xps: Transmit Pac... |
924 925 926 927 928 |
/* * netdev_queue sysfs structures and functions. */ struct netdev_queue_attribute { struct attribute attr; |
718ad681e net: drop unused ... |
929 |
ssize_t (*show)(struct netdev_queue *queue, char *buf); |
1d24eb481 xps: Transmit Pac... |
930 |
ssize_t (*store)(struct netdev_queue *queue, |
718ad681e net: drop unused ... |
931 |
const char *buf, size_t len); |
1d24eb481 xps: Transmit Pac... |
932 |
}; |
6648c65e7 net: style cleanups |
933 934 |
#define to_netdev_queue_attr(_attr) \ container_of(_attr, struct netdev_queue_attribute, attr) |
1d24eb481 xps: Transmit Pac... |
935 936 937 938 939 940 |
#define to_netdev_queue(obj) container_of(obj, struct netdev_queue, kobj) static ssize_t netdev_queue_attr_show(struct kobject *kobj, struct attribute *attr, char *buf) { |
667e427bc net: mark receive... |
941 942 |
const struct netdev_queue_attribute *attribute = to_netdev_queue_attr(attr); |
1d24eb481 xps: Transmit Pac... |
943 944 945 946 |
struct netdev_queue *queue = to_netdev_queue(kobj); if (!attribute->show) return -EIO; |
718ad681e net: drop unused ... |
947 |
return attribute->show(queue, buf); |
1d24eb481 xps: Transmit Pac... |
948 949 950 951 952 953 |
} static ssize_t netdev_queue_attr_store(struct kobject *kobj, struct attribute *attr, const char *buf, size_t count) { |
667e427bc net: mark receive... |
954 955 |
const struct netdev_queue_attribute *attribute = to_netdev_queue_attr(attr); |
1d24eb481 xps: Transmit Pac... |
956 957 958 959 |
struct netdev_queue *queue = to_netdev_queue(kobj); if (!attribute->store) return -EIO; |
718ad681e net: drop unused ... |
960 |
return attribute->store(queue, buf, count); |
1d24eb481 xps: Transmit Pac... |
961 962 963 964 965 966 |
} static const struct sysfs_ops netdev_queue_sysfs_ops = { .show = netdev_queue_attr_show, .store = netdev_queue_attr_store, }; |
2b9c75812 net: make queue a... |
967 |
static ssize_t tx_timeout_show(struct netdev_queue *queue, char *buf) |
ccf5ff69f net: new counter ... |
968 969 970 971 972 973 974 975 976 |
{ unsigned long trans_timeout; spin_lock_irq(&queue->_xmit_lock); trans_timeout = queue->trans_timeout; spin_unlock_irq(&queue->_xmit_lock); return sprintf(buf, "%lu", trans_timeout); } |
c4047f533 net-sysfs: get_ne... |
977 |
static unsigned int get_netdev_queue_index(struct netdev_queue *queue) |
822b3b2eb net: Add max rate... |
978 979 |
{ struct net_device *dev = queue->dev; |
c4047f533 net-sysfs: get_ne... |
980 |
unsigned int i; |
822b3b2eb net: Add max rate... |
981 |
|
c4047f533 net-sysfs: get_ne... |
982 |
i = queue - dev->_tx; |
822b3b2eb net: Add max rate... |
983 984 985 986 |
BUG_ON(i >= dev->num_tx_queues); return i; } |
2b9c75812 net: make queue a... |
987 |
static ssize_t traffic_class_show(struct netdev_queue *queue, |
8d059b0f6 net: Add sysfs va... |
988 989 990 991 992 993 994 995 996 997 998 999 1000 1001 |
char *buf) { struct net_device *dev = queue->dev; int index = get_netdev_queue_index(queue); int tc = netdev_txq_to_tc(dev, index); if (tc < 0) return -EINVAL; return sprintf(buf, "%u ", tc); } #ifdef CONFIG_XPS |
2b9c75812 net: make queue a... |
1002 |
static ssize_t tx_maxrate_show(struct netdev_queue *queue, |
822b3b2eb net: Add max rate... |
1003 1004 1005 1006 1007 |
char *buf) { return sprintf(buf, "%lu ", queue->tx_maxrate); } |
2b9c75812 net: make queue a... |
1008 1009 |
static ssize_t tx_maxrate_store(struct netdev_queue *queue, const char *buf, size_t len) |
822b3b2eb net: Add max rate... |
1010 1011 1012 1013 1014 1015 1016 1017 1018 1019 1020 1021 1022 1023 1024 1025 1026 1027 1028 1029 1030 1031 1032 |
{ struct net_device *dev = queue->dev; int err, index = get_netdev_queue_index(queue); u32 rate = 0; err = kstrtou32(buf, 10, &rate); if (err < 0) return err; if (!rtnl_trylock()) return restart_syscall(); err = -EOPNOTSUPP; if (dev->netdev_ops->ndo_set_tx_maxrate) err = dev->netdev_ops->ndo_set_tx_maxrate(dev, index, rate); rtnl_unlock(); if (!err) { queue->tx_maxrate = rate; return len; } return err; } |
2b9c75812 net: make queue a... |
1033 1034 |
static struct netdev_queue_attribute queue_tx_maxrate __ro_after_init = __ATTR_RW(tx_maxrate); |
822b3b2eb net: Add max rate... |
1035 |
#endif |
2b9c75812 net: make queue a... |
1036 1037 |
static struct netdev_queue_attribute queue_trans_timeout __ro_after_init = __ATTR_RO(tx_timeout); |
ccf5ff69f net: new counter ... |
1038 |
|
2b9c75812 net: make queue a... |
1039 1040 |
static struct netdev_queue_attribute queue_traffic_class __ro_after_init = __ATTR_RO(traffic_class); |
8d059b0f6 net: Add sysfs va... |
1041 |
|
114cf5802 bql: Byte queue l... |
1042 1043 1044 1045 1046 1047 1048 1049 1050 1051 1052 1053 1054 1055 1056 |
#ifdef CONFIG_BQL /* * Byte queue limits sysfs structures and functions. */ static ssize_t bql_show(char *buf, unsigned int value) { return sprintf(buf, "%u ", value); } static ssize_t bql_set(const char *buf, const size_t count, unsigned int *pvalue) { unsigned int value; int err; |
6648c65e7 net: style cleanups |
1057 1058 |
if (!strcmp(buf, "max") || !strcmp(buf, "max ")) { |
114cf5802 bql: Byte queue l... |
1059 |
value = DQL_MAX_LIMIT; |
6648c65e7 net: style cleanups |
1060 |
} else { |
114cf5802 bql: Byte queue l... |
1061 1062 1063 1064 1065 1066 1067 1068 1069 1070 1071 1072 1073 |
err = kstrtouint(buf, 10, &value); if (err < 0) return err; if (value > DQL_MAX_LIMIT) return -EINVAL; } *pvalue = value; return count; } static ssize_t bql_show_hold_time(struct netdev_queue *queue, |
114cf5802 bql: Byte queue l... |
1074 1075 1076 1077 1078 1079 1080 1081 1082 |
char *buf) { struct dql *dql = &queue->dql; return sprintf(buf, "%u ", jiffies_to_msecs(dql->slack_hold_time)); } static ssize_t bql_set_hold_time(struct netdev_queue *queue, |
114cf5802 bql: Byte queue l... |
1083 1084 1085 |
const char *buf, size_t len) { struct dql *dql = &queue->dql; |
95c961747 net: cleanup unsi... |
1086 |
unsigned int value; |
114cf5802 bql: Byte queue l... |
1087 1088 1089 1090 1091 1092 1093 1094 1095 1096 |
int err; err = kstrtouint(buf, 10, &value); if (err < 0) return err; dql->slack_hold_time = msecs_to_jiffies(value); return len; } |
170c658af net: make BQL sys... |
1097 1098 1099 |
static struct netdev_queue_attribute bql_hold_time_attribute __ro_after_init = __ATTR(hold_time, S_IRUGO | S_IWUSR, bql_show_hold_time, bql_set_hold_time); |
114cf5802 bql: Byte queue l... |
1100 1101 |
static ssize_t bql_show_inflight(struct netdev_queue *queue, |
114cf5802 bql: Byte queue l... |
1102 1103 1104 1105 1106 1107 1108 |
char *buf) { struct dql *dql = &queue->dql; return sprintf(buf, "%u ", dql->num_queued - dql->num_completed); } |
170c658af net: make BQL sys... |
1109 |
static struct netdev_queue_attribute bql_inflight_attribute __ro_after_init = |
795d9a253 bql: Fix inconsis... |
1110 |
__ATTR(inflight, S_IRUGO, bql_show_inflight, NULL); |
114cf5802 bql: Byte queue l... |
1111 1112 1113 |
#define BQL_ATTR(NAME, FIELD) \ static ssize_t bql_show_ ## NAME(struct netdev_queue *queue, \ |
114cf5802 bql: Byte queue l... |
1114 1115 1116 1117 1118 1119 |
char *buf) \ { \ return bql_show(buf, queue->dql.FIELD); \ } \ \ static ssize_t bql_set_ ## NAME(struct netdev_queue *queue, \ |
114cf5802 bql: Byte queue l... |
1120 1121 1122 1123 1124 |
const char *buf, size_t len) \ { \ return bql_set(buf, len, &queue->dql.FIELD); \ } \ \ |
170c658af net: make BQL sys... |
1125 1126 1127 |
static struct netdev_queue_attribute bql_ ## NAME ## _attribute __ro_after_init \ = __ATTR(NAME, S_IRUGO | S_IWUSR, \ bql_show_ ## NAME, bql_set_ ## NAME) |
114cf5802 bql: Byte queue l... |
1128 |
|
170c658af net: make BQL sys... |
1129 1130 1131 |
BQL_ATTR(limit, limit); BQL_ATTR(limit_max, max_limit); BQL_ATTR(limit_min, min_limit); |
114cf5802 bql: Byte queue l... |
1132 |
|
170c658af net: make BQL sys... |
1133 |
static struct attribute *dql_attrs[] __ro_after_init = { |
114cf5802 bql: Byte queue l... |
1134 1135 1136 1137 1138 1139 1140 |
&bql_limit_attribute.attr, &bql_limit_max_attribute.attr, &bql_limit_min_attribute.attr, &bql_hold_time_attribute.attr, &bql_inflight_attribute.attr, NULL }; |
38ef00cc3 net: constify att... |
1141 |
static const struct attribute_group dql_group = { |
114cf5802 bql: Byte queue l... |
1142 1143 1144 1145 |
.name = "byte_queue_limits", .attrs = dql_attrs, }; #endif /* CONFIG_BQL */ |
ccf5ff69f net: new counter ... |
1146 |
#ifdef CONFIG_XPS |
2b9c75812 net: make queue a... |
1147 1148 |
static ssize_t xps_cpus_show(struct netdev_queue *queue, char *buf) |
1d24eb481 xps: Transmit Pac... |
1149 1150 |
{ struct net_device *dev = queue->dev; |
184c449f9 net: Add support ... |
1151 |
int cpu, len, num_tc = 1, tc = 0; |
1d24eb481 xps: Transmit Pac... |
1152 1153 1154 |
struct xps_dev_maps *dev_maps; cpumask_var_t mask; unsigned long index; |
1d24eb481 xps: Transmit Pac... |
1155 |
|
1d24eb481 xps: Transmit Pac... |
1156 |
index = get_netdev_queue_index(queue); |
184c449f9 net: Add support ... |
1157 1158 1159 1160 1161 1162 |
if (dev->num_tc) { num_tc = dev->num_tc; tc = netdev_txq_to_tc(dev, index); if (tc < 0) return -EINVAL; } |
0dbd822f6 net-sysfs: Fix me... |
1163 1164 |
if (!zalloc_cpumask_var(&mask, GFP_KERNEL)) return -ENOMEM; |
1d24eb481 xps: Transmit Pac... |
1165 1166 1167 |
rcu_read_lock(); dev_maps = rcu_dereference(dev->xps_maps); if (dev_maps) { |
184c449f9 net: Add support ... |
1168 1169 1170 1171 1172 1173 1174 1175 1176 1177 1178 1179 |
for_each_possible_cpu(cpu) { int i, tci = cpu * num_tc + tc; struct xps_map *map; map = rcu_dereference(dev_maps->cpu_map[tci]); if (!map) continue; for (i = map->len; i--;) { if (map->queues[i] == index) { cpumask_set_cpu(cpu, mask); break; |
1d24eb481 xps: Transmit Pac... |
1180 1181 1182 1183 1184 |
} } } } rcu_read_unlock(); |
f09068276 net: use %*pb[l] ... |
1185 1186 |
len = snprintf(buf, PAGE_SIZE, "%*pb ", cpumask_pr_args(mask)); |
1d24eb481 xps: Transmit Pac... |
1187 |
free_cpumask_var(mask); |
f09068276 net: use %*pb[l] ... |
1188 |
return len < PAGE_SIZE ? len : -EINVAL; |
1d24eb481 xps: Transmit Pac... |
1189 |
} |
2b9c75812 net: make queue a... |
1190 1191 |
static ssize_t xps_cpus_store(struct netdev_queue *queue, const char *buf, size_t len) |
1d24eb481 xps: Transmit Pac... |
1192 1193 |
{ struct net_device *dev = queue->dev; |
1d24eb481 xps: Transmit Pac... |
1194 |
unsigned long index; |
537c00de1 net: Add function... |
1195 1196 |
cpumask_var_t mask; int err; |
1d24eb481 xps: Transmit Pac... |
1197 1198 1199 1200 1201 1202 1203 1204 1205 1206 1207 1208 1209 1210 |
if (!capable(CAP_NET_ADMIN)) return -EPERM; if (!alloc_cpumask_var(&mask, GFP_KERNEL)) return -ENOMEM; index = get_netdev_queue_index(queue); err = bitmap_parse(buf, len, cpumask_bits(mask), nr_cpumask_bits); if (err) { free_cpumask_var(mask); return err; } |
537c00de1 net: Add function... |
1211 |
err = netif_set_xps_queue(dev, mask, index); |
1d24eb481 xps: Transmit Pac... |
1212 1213 |
free_cpumask_var(mask); |
1d24eb481 xps: Transmit Pac... |
1214 |
|
537c00de1 net: Add function... |
1215 |
return err ? : len; |
1d24eb481 xps: Transmit Pac... |
1216 |
} |
2b9c75812 net: make queue a... |
1217 1218 |
static struct netdev_queue_attribute xps_cpus_attribute __ro_after_init = __ATTR_RW(xps_cpus); |
ccf5ff69f net: new counter ... |
1219 |
#endif /* CONFIG_XPS */ |
1d24eb481 xps: Transmit Pac... |
1220 |
|
2b9c75812 net: make queue a... |
1221 |
static struct attribute *netdev_queue_default_attrs[] __ro_after_init = { |
ccf5ff69f net: new counter ... |
1222 |
&queue_trans_timeout.attr, |
8d059b0f6 net: Add sysfs va... |
1223 |
&queue_traffic_class.attr, |
ccf5ff69f net: new counter ... |
1224 |
#ifdef CONFIG_XPS |
1d24eb481 xps: Transmit Pac... |
1225 |
&xps_cpus_attribute.attr, |
822b3b2eb net: Add max rate... |
1226 |
&queue_tx_maxrate.attr, |
ccf5ff69f net: new counter ... |
1227 |
#endif |
1d24eb481 xps: Transmit Pac... |
1228 1229 1230 1231 1232 1233 |
NULL }; static void netdev_queue_release(struct kobject *kobj) { struct netdev_queue *queue = to_netdev_queue(kobj); |
1d24eb481 xps: Transmit Pac... |
1234 |
|
1d24eb481 xps: Transmit Pac... |
1235 1236 1237 |
memset(kobj, 0, sizeof(*kobj)); dev_put(queue->dev); } |
82ef3d5d5 net: fix "queues"... |
1238 1239 1240 1241 1242 1243 1244 1245 1246 1247 1248 |
static const void *netdev_queue_namespace(struct kobject *kobj) { struct netdev_queue *queue = to_netdev_queue(kobj); struct device *dev = &queue->dev->dev; const void *ns = NULL; if (dev->class && dev->class->ns_type) ns = dev->class->namespace(dev); return ns; } |
2b9c75812 net: make queue a... |
1249 |
static struct kobj_type netdev_queue_ktype __ro_after_init = { |
1d24eb481 xps: Transmit Pac... |
1250 1251 1252 |
.sysfs_ops = &netdev_queue_sysfs_ops, .release = netdev_queue_release, .default_attrs = netdev_queue_default_attrs, |
82ef3d5d5 net: fix "queues"... |
1253 |
.namespace = netdev_queue_namespace, |
1d24eb481 xps: Transmit Pac... |
1254 |
}; |
6b53dafe2 net: do not name ... |
1255 |
static int netdev_queue_add_kobject(struct net_device *dev, int index) |
1d24eb481 xps: Transmit Pac... |
1256 |
{ |
6b53dafe2 net: do not name ... |
1257 |
struct netdev_queue *queue = dev->_tx + index; |
1d24eb481 xps: Transmit Pac... |
1258 1259 |
struct kobject *kobj = &queue->kobj; int error = 0; |
6b53dafe2 net: do not name ... |
1260 |
kobj->kset = dev->queues_kset; |
1d24eb481 xps: Transmit Pac... |
1261 |
error = kobject_init_and_add(kobj, &netdev_queue_ktype, NULL, |
6648c65e7 net: style cleanups |
1262 |
"tx-%u", index); |
114cf5802 bql: Byte queue l... |
1263 |
if (error) |
d0d668371 net: don't decrem... |
1264 |
return error; |
114cf5802 bql: Byte queue l... |
1265 1266 1267 |
#ifdef CONFIG_BQL error = sysfs_create_group(kobj, &dql_group); |
d0d668371 net: don't decrem... |
1268 1269 1270 1271 |
if (error) { kobject_put(kobj); return error; } |
114cf5802 bql: Byte queue l... |
1272 |
#endif |
1d24eb481 xps: Transmit Pac... |
1273 1274 1275 |
kobject_uevent(kobj, KOBJ_ADD); dev_hold(queue->dev); |
114cf5802 bql: Byte queue l... |
1276 |
return 0; |
1d24eb481 xps: Transmit Pac... |
1277 |
} |
ccf5ff69f net: new counter ... |
1278 |
#endif /* CONFIG_SYSFS */ |
1d24eb481 xps: Transmit Pac... |
1279 1280 |
int |
6b53dafe2 net: do not name ... |
1281 |
netdev_queue_update_kobjects(struct net_device *dev, int old_num, int new_num) |
1d24eb481 xps: Transmit Pac... |
1282 |
{ |
ccf5ff69f net: new counter ... |
1283 |
#ifdef CONFIG_SYSFS |
1d24eb481 xps: Transmit Pac... |
1284 1285 1286 1287 |
int i; int error = 0; for (i = old_num; i < new_num; i++) { |
6b53dafe2 net: do not name ... |
1288 |
error = netdev_queue_add_kobject(dev, i); |
1d24eb481 xps: Transmit Pac... |
1289 1290 1291 1292 1293 |
if (error) { new_num = old_num; break; } } |
114cf5802 bql: Byte queue l... |
1294 |
while (--i >= new_num) { |
6b53dafe2 net: do not name ... |
1295 |
struct netdev_queue *queue = dev->_tx + i; |
114cf5802 bql: Byte queue l... |
1296 |
|
91864f585 net: use net->cou... |
1297 |
if (!atomic_read(&dev_net(dev)->count)) |
002d8a1a6 net: skip genener... |
1298 |
queue->kobj.uevent_suppress = 1; |
114cf5802 bql: Byte queue l... |
1299 1300 1301 1302 1303 |
#ifdef CONFIG_BQL sysfs_remove_group(&queue->kobj, &dql_group); #endif kobject_put(&queue->kobj); } |
1d24eb481 xps: Transmit Pac... |
1304 1305 |
return error; |
bf2641451 xps: Add CONFIG_XPS |
1306 1307 |
#else return 0; |
ccf5ff69f net: new counter ... |
1308 |
#endif /* CONFIG_SYSFS */ |
1d24eb481 xps: Transmit Pac... |
1309 |
} |
6b53dafe2 net: do not name ... |
1310 |
static int register_queue_kobjects(struct net_device *dev) |
1d24eb481 xps: Transmit Pac... |
1311 |
{ |
bf2641451 xps: Add CONFIG_XPS |
1312 |
int error = 0, txq = 0, rxq = 0, real_rx = 0, real_tx = 0; |
1d24eb481 xps: Transmit Pac... |
1313 |
|
ccf5ff69f net: new counter ... |
1314 |
#ifdef CONFIG_SYSFS |
6b53dafe2 net: do not name ... |
1315 |
dev->queues_kset = kset_create_and_add("queues", |
6648c65e7 net: style cleanups |
1316 |
NULL, &dev->dev.kobj); |
6b53dafe2 net: do not name ... |
1317 |
if (!dev->queues_kset) |
62fe0b40a net: Allow changi... |
1318 |
return -ENOMEM; |
6b53dafe2 net: do not name ... |
1319 |
real_rx = dev->real_num_rx_queues; |
bf2641451 xps: Add CONFIG_XPS |
1320 |
#endif |
6b53dafe2 net: do not name ... |
1321 |
real_tx = dev->real_num_tx_queues; |
1d24eb481 xps: Transmit Pac... |
1322 |
|
6b53dafe2 net: do not name ... |
1323 |
error = net_rx_queue_update_kobjects(dev, 0, real_rx); |
1d24eb481 xps: Transmit Pac... |
1324 1325 |
if (error) goto error; |
bf2641451 xps: Add CONFIG_XPS |
1326 |
rxq = real_rx; |
1d24eb481 xps: Transmit Pac... |
1327 |
|
6b53dafe2 net: do not name ... |
1328 |
error = netdev_queue_update_kobjects(dev, 0, real_tx); |
1d24eb481 xps: Transmit Pac... |
1329 1330 |
if (error) goto error; |
bf2641451 xps: Add CONFIG_XPS |
1331 |
txq = real_tx; |
1d24eb481 xps: Transmit Pac... |
1332 1333 1334 1335 |
return 0; error: |
6b53dafe2 net: do not name ... |
1336 1337 |
netdev_queue_update_kobjects(dev, txq, 0); net_rx_queue_update_kobjects(dev, rxq, 0); |
1d24eb481 xps: Transmit Pac... |
1338 |
return error; |
62fe0b40a net: Allow changi... |
1339 |
} |
0a9627f26 rps: Receive Pack... |
1340 |
|
6b53dafe2 net: do not name ... |
1341 |
static void remove_queue_kobjects(struct net_device *dev) |
62fe0b40a net: Allow changi... |
1342 |
{ |
bf2641451 xps: Add CONFIG_XPS |
1343 |
int real_rx = 0, real_tx = 0; |
a953be53c net-sysfs: add su... |
1344 |
#ifdef CONFIG_SYSFS |
6b53dafe2 net: do not name ... |
1345 |
real_rx = dev->real_num_rx_queues; |
bf2641451 xps: Add CONFIG_XPS |
1346 |
#endif |
6b53dafe2 net: do not name ... |
1347 |
real_tx = dev->real_num_tx_queues; |
bf2641451 xps: Add CONFIG_XPS |
1348 |
|
6b53dafe2 net: do not name ... |
1349 1350 |
net_rx_queue_update_kobjects(dev, real_rx, 0); netdev_queue_update_kobjects(dev, real_tx, 0); |
ccf5ff69f net: new counter ... |
1351 |
#ifdef CONFIG_SYSFS |
6b53dafe2 net: do not name ... |
1352 |
kset_unregister(dev->queues_kset); |
bf2641451 xps: Add CONFIG_XPS |
1353 |
#endif |
0a9627f26 rps: Receive Pack... |
1354 |
} |
608b4b954 netns: Teach netw... |
1355 |
|
7dc5dbc87 sysfs: Restrict m... |
1356 1357 1358 1359 1360 1361 |
static bool net_current_may_mount(void) { struct net *net = current->nsproxy->net_ns; return ns_capable(net->user_ns, CAP_SYS_ADMIN); } |
a685e0898 Delay struct net ... |
1362 |
static void *net_grab_current_ns(void) |
608b4b954 netns: Teach netw... |
1363 |
{ |
a685e0898 Delay struct net ... |
1364 1365 1366 |
struct net *ns = current->nsproxy->net_ns; #ifdef CONFIG_NET_NS if (ns) |
c122e14df net: convert net.... |
1367 |
refcount_inc(&ns->passive); |
a685e0898 Delay struct net ... |
1368 1369 |
#endif return ns; |
608b4b954 netns: Teach netw... |
1370 1371 1372 1373 1374 1375 1376 1377 1378 1379 1380 |
} static const void *net_initial_ns(void) { return &init_net; } static const void *net_netlink_ns(struct sock *sk) { return sock_net(sk); } |
737aec57c net: constify net... |
1381 |
const struct kobj_ns_type_operations net_ns_type_operations = { |
608b4b954 netns: Teach netw... |
1382 |
.type = KOBJ_NS_TYPE_NET, |
7dc5dbc87 sysfs: Restrict m... |
1383 |
.current_may_mount = net_current_may_mount, |
a685e0898 Delay struct net ... |
1384 |
.grab_current_ns = net_grab_current_ns, |
608b4b954 netns: Teach netw... |
1385 1386 |
.netlink_ns = net_netlink_ns, .initial_ns = net_initial_ns, |
a685e0898 Delay struct net ... |
1387 |
.drop_ns = net_drop_ns, |
608b4b954 netns: Teach netw... |
1388 |
}; |
046007949 cfg80211: support... |
1389 |
EXPORT_SYMBOL_GPL(net_ns_type_operations); |
608b4b954 netns: Teach netw... |
1390 |
|
7eff2e7a8 Driver core: chan... |
1391 |
static int netdev_uevent(struct device *d, struct kobj_uevent_env *env) |
1da177e4c Linux-2.6.12-rc2 |
1392 |
{ |
43cb76d91 Network: convert ... |
1393 |
struct net_device *dev = to_net_dev(d); |
7eff2e7a8 Driver core: chan... |
1394 |
int retval; |
1da177e4c Linux-2.6.12-rc2 |
1395 |
|
312c004d3 [PATCH] driver co... |
1396 |
/* pass interface to uevent. */ |
7eff2e7a8 Driver core: chan... |
1397 |
retval = add_uevent_var(env, "INTERFACE=%s", dev->name); |
bf62456eb uevent: use add_u... |
1398 1399 |
if (retval) goto exit; |
1da177e4c Linux-2.6.12-rc2 |
1400 |
|
ca2f37dbc Driver core: noti... |
1401 1402 |
/* pass ifindex to uevent. * ifindex is useful as it won't change (interface name may change) |
6648c65e7 net: style cleanups |
1403 1404 |
* and is what RtNetlink uses natively. */ |
7eff2e7a8 Driver core: chan... |
1405 |
retval = add_uevent_var(env, "IFINDEX=%d", dev->ifindex); |
ca2f37dbc Driver core: noti... |
1406 |
|
bf62456eb uevent: use add_u... |
1407 |
exit: |
bf62456eb uevent: use add_u... |
1408 |
return retval; |
1da177e4c Linux-2.6.12-rc2 |
1409 |
} |
1da177e4c Linux-2.6.12-rc2 |
1410 1411 |
/* |
4ec93edb1 [NET] CORE: Fix w... |
1412 |
* netdev_release -- destroy and free a dead device. |
43cb76d91 Network: convert ... |
1413 |
* Called when last reference to device kobject is gone. |
1da177e4c Linux-2.6.12-rc2 |
1414 |
*/ |
43cb76d91 Network: convert ... |
1415 |
static void netdev_release(struct device *d) |
1da177e4c Linux-2.6.12-rc2 |
1416 |
{ |
43cb76d91 Network: convert ... |
1417 |
struct net_device *dev = to_net_dev(d); |
1da177e4c Linux-2.6.12-rc2 |
1418 1419 |
BUG_ON(dev->reg_state != NETREG_RELEASED); |
0b815a1a6 net: network devi... |
1420 |
kfree(dev->ifalias); |
74d332c13 net: extend net_d... |
1421 |
netdev_freemem(dev); |
1da177e4c Linux-2.6.12-rc2 |
1422 |
} |
608b4b954 netns: Teach netw... |
1423 1424 |
static const void *net_namespace(struct device *d) { |
5c29482dd net-sysfs: use to... |
1425 |
struct net_device *dev = to_net_dev(d); |
608b4b954 netns: Teach netw... |
1426 1427 |
return dev_net(dev); } |
e6d473e63 net: make net_cla... |
1428 |
static struct class net_class __ro_after_init = { |
1da177e4c Linux-2.6.12-rc2 |
1429 |
.name = "net", |
43cb76d91 Network: convert ... |
1430 |
.dev_release = netdev_release, |
6be8aeef3 net: core: conver... |
1431 |
.dev_groups = net_class_groups, |
43cb76d91 Network: convert ... |
1432 |
.dev_uevent = netdev_uevent, |
608b4b954 netns: Teach netw... |
1433 1434 |
.ns_type = &net_ns_type_operations, .namespace = net_namespace, |
1da177e4c Linux-2.6.12-rc2 |
1435 |
}; |
aa836df95 net: core: add of... |
1436 1437 1438 1439 1440 1441 1442 1443 1444 1445 |
#ifdef CONFIG_OF_NET static int of_dev_node_match(struct device *dev, const void *data) { int ret = 0; if (dev->parent) ret = dev->parent->of_node == data; return ret == 0 ? dev->of_node == data : ret; } |
9861f7207 net: fix net_devi... |
1446 1447 1448 1449 1450 1451 1452 1453 1454 |
/* * of_find_net_device_by_node - lookup the net device for the device node * @np: OF device node * * Looks up the net_device structure corresponding with the device node. * If successful, returns a pointer to the net_device with the embedded * struct device refcount incremented by one, or NULL on failure. The * refcount must be dropped when done with the net_device. */ |
aa836df95 net: core: add of... |
1455 1456 1457 1458 1459 1460 1461 1462 1463 1464 1465 1466 |
struct net_device *of_find_net_device_by_node(struct device_node *np) { struct device *dev; dev = class_find_device(&net_class, NULL, np, of_dev_node_match); if (!dev) return NULL; return to_net_dev(dev); } EXPORT_SYMBOL(of_find_net_device_by_node); #endif |
9093bbb2d [NET]: Fix race c... |
1467 1468 1469 |
/* Delete sysfs entries but hold kobject reference until after all * netdev references are gone. */ |
6b53dafe2 net: do not name ... |
1470 |
void netdev_unregister_kobject(struct net_device *ndev) |
1da177e4c Linux-2.6.12-rc2 |
1471 |
{ |
6648c65e7 net: style cleanups |
1472 |
struct device *dev = &ndev->dev; |
9093bbb2d [NET]: Fix race c... |
1473 |
|
91864f585 net: use net->cou... |
1474 |
if (!atomic_read(&dev_net(ndev)->count)) |
002d8a1a6 net: skip genener... |
1475 |
dev_set_uevent_suppress(dev, 1); |
9093bbb2d [NET]: Fix race c... |
1476 |
kobject_get(&dev->kobj); |
3891845e1 netns: Coexist wi... |
1477 |
|
6b53dafe2 net: do not name ... |
1478 |
remove_queue_kobjects(ndev); |
0a9627f26 rps: Receive Pack... |
1479 |
|
9802c8e22 net/core: apply p... |
1480 |
pm_runtime_set_memalloc_noio(dev, false); |
9093bbb2d [NET]: Fix race c... |
1481 |
device_del(dev); |
1da177e4c Linux-2.6.12-rc2 |
1482 1483 1484 |
} /* Create sysfs entries for network device. */ |
6b53dafe2 net: do not name ... |
1485 |
int netdev_register_kobject(struct net_device *ndev) |
1da177e4c Linux-2.6.12-rc2 |
1486 |
{ |
6648c65e7 net: style cleanups |
1487 |
struct device *dev = &ndev->dev; |
6b53dafe2 net: do not name ... |
1488 |
const struct attribute_group **groups = ndev->sysfs_groups; |
0a9627f26 rps: Receive Pack... |
1489 |
int error = 0; |
1da177e4c Linux-2.6.12-rc2 |
1490 |
|
a1b3f594d net: Expose all n... |
1491 |
device_initialize(dev); |
43cb76d91 Network: convert ... |
1492 |
dev->class = &net_class; |
6b53dafe2 net: do not name ... |
1493 |
dev->platform_data = ndev; |
43cb76d91 Network: convert ... |
1494 |
dev->groups = groups; |
1da177e4c Linux-2.6.12-rc2 |
1495 |
|
6b53dafe2 net: do not name ... |
1496 |
dev_set_name(dev, "%s", ndev->name); |
1da177e4c Linux-2.6.12-rc2 |
1497 |
|
8b41d1887 [NET]: Fix runnin... |
1498 |
#ifdef CONFIG_SYSFS |
0c509a6c9 net: Allow device... |
1499 1500 1501 |
/* Allow for a device specific group */ if (*groups) groups++; |
1da177e4c Linux-2.6.12-rc2 |
1502 |
|
0c509a6c9 net: Allow device... |
1503 |
*groups++ = &netstat_group; |
38c1a01cf wireless: add bac... |
1504 1505 |
#if IS_ENABLED(CONFIG_WIRELESS_EXT) || IS_ENABLED(CONFIG_CFG80211) |
6b53dafe2 net: do not name ... |
1506 |
if (ndev->ieee80211_ptr) |
38c1a01cf wireless: add bac... |
1507 1508 |
*groups++ = &wireless_group; #if IS_ENABLED(CONFIG_WIRELESS_EXT) |
6b53dafe2 net: do not name ... |
1509 |
else if (ndev->wireless_handlers) |
38c1a01cf wireless: add bac... |
1510 1511 1512 |
*groups++ = &wireless_group; #endif #endif |
8b41d1887 [NET]: Fix runnin... |
1513 |
#endif /* CONFIG_SYSFS */ |
1da177e4c Linux-2.6.12-rc2 |
1514 |
|
0a9627f26 rps: Receive Pack... |
1515 1516 1517 |
error = device_add(dev); if (error) return error; |
6b53dafe2 net: do not name ... |
1518 |
error = register_queue_kobjects(ndev); |
0a9627f26 rps: Receive Pack... |
1519 1520 1521 1522 |
if (error) { device_del(dev); return error; } |
9802c8e22 net/core: apply p... |
1523 |
pm_runtime_set_memalloc_noio(dev, true); |
0a9627f26 rps: Receive Pack... |
1524 |
return error; |
1da177e4c Linux-2.6.12-rc2 |
1525 |
} |
b793dc5c6 net: constify net... |
1526 |
int netdev_class_create_file_ns(const struct class_attribute *class_attr, |
58292cbe6 sysfs: make attr ... |
1527 |
const void *ns) |
b8a9787ed bonding: Allow se... |
1528 |
{ |
58292cbe6 sysfs: make attr ... |
1529 |
return class_create_file_ns(&net_class, class_attr, ns); |
b8a9787ed bonding: Allow se... |
1530 |
} |
58292cbe6 sysfs: make attr ... |
1531 |
EXPORT_SYMBOL(netdev_class_create_file_ns); |
b8a9787ed bonding: Allow se... |
1532 |
|
b793dc5c6 net: constify net... |
1533 |
void netdev_class_remove_file_ns(const struct class_attribute *class_attr, |
58292cbe6 sysfs: make attr ... |
1534 |
const void *ns) |
b8a9787ed bonding: Allow se... |
1535 |
{ |
58292cbe6 sysfs: make attr ... |
1536 |
class_remove_file_ns(&net_class, class_attr, ns); |
b8a9787ed bonding: Allow se... |
1537 |
} |
58292cbe6 sysfs: make attr ... |
1538 |
EXPORT_SYMBOL(netdev_class_remove_file_ns); |
b8a9787ed bonding: Allow se... |
1539 |
|
a48d4bb0b net: netdev_kobje... |
1540 |
int __init netdev_kobject_init(void) |
1da177e4c Linux-2.6.12-rc2 |
1541 |
{ |
608b4b954 netns: Teach netw... |
1542 |
kobj_ns_type_register(&net_ns_type_operations); |
1da177e4c Linux-2.6.12-rc2 |
1543 1544 |
return class_register(&net_class); } |