aboutsummaryrefslogtreecommitdiffstats
path: root/net/core/net-sysfs.c
diff options
context:
space:
mode:
Diffstat (limited to 'net/core/net-sysfs.c')
-rw-r--r--net/core/net-sysfs.c83
1 files changed, 26 insertions, 57 deletions
diff --git a/net/core/net-sysfs.c b/net/core/net-sysfs.c
index 5ceb257e860c..33d2a1fba131 100644
--- a/net/core/net-sysfs.c
+++ b/net/core/net-sysfs.c
@@ -28,6 +28,7 @@
28static const char fmt_hex[] = "%#x\n"; 28static const char fmt_hex[] = "%#x\n";
29static const char fmt_long_hex[] = "%#lx\n"; 29static const char fmt_long_hex[] = "%#lx\n";
30static const char fmt_dec[] = "%d\n"; 30static const char fmt_dec[] = "%d\n";
31static const char fmt_udec[] = "%u\n";
31static const char fmt_ulong[] = "%lu\n"; 32static const char fmt_ulong[] = "%lu\n";
32static const char fmt_u64[] = "%llu\n"; 33static const char fmt_u64[] = "%llu\n";
33 34
@@ -145,13 +146,10 @@ static ssize_t show_speed(struct device *dev,
145 if (!rtnl_trylock()) 146 if (!rtnl_trylock())
146 return restart_syscall(); 147 return restart_syscall();
147 148
148 if (netif_running(netdev) && 149 if (netif_running(netdev)) {
149 netdev->ethtool_ops && 150 struct ethtool_cmd cmd;
150 netdev->ethtool_ops->get_settings) { 151 if (!dev_ethtool_get_settings(netdev, &cmd))
151 struct ethtool_cmd cmd = { ETHTOOL_GSET }; 152 ret = sprintf(buf, fmt_udec, ethtool_cmd_speed(&cmd));
152
153 if (!netdev->ethtool_ops->get_settings(netdev, &cmd))
154 ret = sprintf(buf, fmt_dec, ethtool_cmd_speed(&cmd));
155 } 153 }
156 rtnl_unlock(); 154 rtnl_unlock();
157 return ret; 155 return ret;
@@ -166,13 +164,11 @@ static ssize_t show_duplex(struct device *dev,
166 if (!rtnl_trylock()) 164 if (!rtnl_trylock())
167 return restart_syscall(); 165 return restart_syscall();
168 166
169 if (netif_running(netdev) && 167 if (netif_running(netdev)) {
170 netdev->ethtool_ops && 168 struct ethtool_cmd cmd;
171 netdev->ethtool_ops->get_settings) { 169 if (!dev_ethtool_get_settings(netdev, &cmd))
172 struct ethtool_cmd cmd = { ETHTOOL_GSET }; 170 ret = sprintf(buf, "%s\n",
173 171 cmd.duplex ? "full" : "half");
174 if (!netdev->ethtool_ops->get_settings(netdev, &cmd))
175 ret = sprintf(buf, "%s\n", cmd.duplex ? "full" : "half");
176 } 172 }
177 rtnl_unlock(); 173 rtnl_unlock();
178 return ret; 174 return ret;
@@ -565,13 +561,6 @@ static ssize_t show_rps_map(struct netdev_rx_queue *queue,
565 return len; 561 return len;
566} 562}
567 563
568static void rps_map_release(struct rcu_head *rcu)
569{
570 struct rps_map *map = container_of(rcu, struct rps_map, rcu);
571
572 kfree(map);
573}
574
575static ssize_t store_rps_map(struct netdev_rx_queue *queue, 564static ssize_t store_rps_map(struct netdev_rx_queue *queue,
576 struct rx_queue_attribute *attribute, 565 struct rx_queue_attribute *attribute,
577 const char *buf, size_t len) 566 const char *buf, size_t len)
@@ -619,7 +608,7 @@ static ssize_t store_rps_map(struct netdev_rx_queue *queue,
619 spin_unlock(&rps_map_lock); 608 spin_unlock(&rps_map_lock);
620 609
621 if (old_map) 610 if (old_map)
622 call_rcu(&old_map->rcu, rps_map_release); 611 kfree_rcu(old_map, rcu);
623 612
624 free_cpumask_var(mask); 613 free_cpumask_var(mask);
625 return len; 614 return len;
@@ -728,7 +717,7 @@ static void rx_queue_release(struct kobject *kobj)
728 map = rcu_dereference_raw(queue->rps_map); 717 map = rcu_dereference_raw(queue->rps_map);
729 if (map) { 718 if (map) {
730 RCU_INIT_POINTER(queue->rps_map, NULL); 719 RCU_INIT_POINTER(queue->rps_map, NULL);
731 call_rcu(&map->rcu, rps_map_release); 720 kfree_rcu(map, rcu);
732 } 721 }
733 722
734 flow_table = rcu_dereference_raw(queue->rps_flow_table); 723 flow_table = rcu_dereference_raw(queue->rps_flow_table);
@@ -898,21 +887,6 @@ static ssize_t show_xps_map(struct netdev_queue *queue,
898 return len; 887 return len;
899} 888}
900 889
901static void xps_map_release(struct rcu_head *rcu)
902{
903 struct xps_map *map = container_of(rcu, struct xps_map, rcu);
904
905 kfree(map);
906}
907
908static void xps_dev_maps_release(struct rcu_head *rcu)
909{
910 struct xps_dev_maps *dev_maps =
911 container_of(rcu, struct xps_dev_maps, rcu);
912
913 kfree(dev_maps);
914}
915
916static DEFINE_MUTEX(xps_map_mutex); 890static DEFINE_MUTEX(xps_map_mutex);
917#define xmap_dereference(P) \ 891#define xmap_dereference(P) \
918 rcu_dereference_protected((P), lockdep_is_held(&xps_map_mutex)) 892 rcu_dereference_protected((P), lockdep_is_held(&xps_map_mutex))
@@ -968,7 +942,7 @@ static ssize_t store_xps_map(struct netdev_queue *queue,
968 } else 942 } else
969 pos = map_len = alloc_len = 0; 943 pos = map_len = alloc_len = 0;
970 944
971 need_set = cpu_isset(cpu, *mask) && cpu_online(cpu); 945 need_set = cpumask_test_cpu(cpu, mask) && cpu_online(cpu);
972#ifdef CONFIG_NUMA 946#ifdef CONFIG_NUMA
973 if (need_set) { 947 if (need_set) {
974 if (numa_node == -2) 948 if (numa_node == -2)
@@ -1009,7 +983,7 @@ static ssize_t store_xps_map(struct netdev_queue *queue,
1009 map = dev_maps ? 983 map = dev_maps ?
1010 xmap_dereference(dev_maps->cpu_map[cpu]) : NULL; 984 xmap_dereference(dev_maps->cpu_map[cpu]) : NULL;
1011 if (map && xmap_dereference(new_dev_maps->cpu_map[cpu]) != map) 985 if (map && xmap_dereference(new_dev_maps->cpu_map[cpu]) != map)
1012 call_rcu(&map->rcu, xps_map_release); 986 kfree_rcu(map, rcu);
1013 if (new_dev_maps->cpu_map[cpu]) 987 if (new_dev_maps->cpu_map[cpu])
1014 nonempty = 1; 988 nonempty = 1;
1015 } 989 }
@@ -1022,7 +996,7 @@ static ssize_t store_xps_map(struct netdev_queue *queue,
1022 } 996 }
1023 997
1024 if (dev_maps) 998 if (dev_maps)
1025 call_rcu(&dev_maps->rcu, xps_dev_maps_release); 999 kfree_rcu(dev_maps, rcu);
1026 1000
1027 netdev_queue_numa_node_write(queue, (numa_node >= 0) ? numa_node : 1001 netdev_queue_numa_node_write(queue, (numa_node >= 0) ? numa_node :
1028 NUMA_NO_NODE); 1002 NUMA_NO_NODE);
@@ -1084,7 +1058,7 @@ static void netdev_queue_release(struct kobject *kobj)
1084 else { 1058 else {
1085 RCU_INIT_POINTER(dev_maps->cpu_map[i], 1059 RCU_INIT_POINTER(dev_maps->cpu_map[i],
1086 NULL); 1060 NULL);
1087 call_rcu(&map->rcu, xps_map_release); 1061 kfree_rcu(map, rcu);
1088 map = NULL; 1062 map = NULL;
1089 } 1063 }
1090 } 1064 }
@@ -1094,7 +1068,7 @@ static void netdev_queue_release(struct kobject *kobj)
1094 1068
1095 if (!nonempty) { 1069 if (!nonempty) {
1096 RCU_INIT_POINTER(dev->xps_maps, NULL); 1070 RCU_INIT_POINTER(dev->xps_maps, NULL);
1097 call_rcu(&dev_maps->rcu, xps_dev_maps_release); 1071 kfree_rcu(dev_maps, rcu);
1098 } 1072 }
1099 } 1073 }
1100 1074
@@ -1205,9 +1179,14 @@ static void remove_queue_kobjects(struct net_device *net)
1205#endif 1179#endif
1206} 1180}
1207 1181
1208static const void *net_current_ns(void) 1182static void *net_grab_current_ns(void)
1209{ 1183{
1210 return current->nsproxy->net_ns; 1184 struct net *ns = current->nsproxy->net_ns;
1185#ifdef CONFIG_NET_NS
1186 if (ns)
1187 atomic_inc(&ns->passive);
1188#endif
1189 return ns;
1211} 1190}
1212 1191
1213static const void *net_initial_ns(void) 1192static const void *net_initial_ns(void)
@@ -1222,22 +1201,13 @@ static const void *net_netlink_ns(struct sock *sk)
1222 1201
1223struct kobj_ns_type_operations net_ns_type_operations = { 1202struct kobj_ns_type_operations net_ns_type_operations = {
1224 .type = KOBJ_NS_TYPE_NET, 1203 .type = KOBJ_NS_TYPE_NET,
1225 .current_ns = net_current_ns, 1204 .grab_current_ns = net_grab_current_ns,
1226 .netlink_ns = net_netlink_ns, 1205 .netlink_ns = net_netlink_ns,
1227 .initial_ns = net_initial_ns, 1206 .initial_ns = net_initial_ns,
1207 .drop_ns = net_drop_ns,
1228}; 1208};
1229EXPORT_SYMBOL_GPL(net_ns_type_operations); 1209EXPORT_SYMBOL_GPL(net_ns_type_operations);
1230 1210
1231static void net_kobj_ns_exit(struct net *net)
1232{
1233 kobj_ns_exit(KOBJ_NS_TYPE_NET, net);
1234}
1235
1236static struct pernet_operations kobj_net_ops = {
1237 .exit = net_kobj_ns_exit,
1238};
1239
1240
1241#ifdef CONFIG_HOTPLUG 1211#ifdef CONFIG_HOTPLUG
1242static int netdev_uevent(struct device *d, struct kobj_uevent_env *env) 1212static int netdev_uevent(struct device *d, struct kobj_uevent_env *env)
1243{ 1213{
@@ -1365,6 +1335,5 @@ EXPORT_SYMBOL(netdev_class_remove_file);
1365int netdev_kobject_init(void) 1335int netdev_kobject_init(void)
1366{ 1336{
1367 kobj_ns_type_register(&net_ns_type_operations); 1337 kobj_ns_type_register(&net_ns_type_operations);
1368 register_pernet_subsys(&kobj_net_ops);
1369 return class_register(&net_class); 1338 return class_register(&net_class);
1370} 1339}