diff options
author | David S. Miller <davem@davemloft.net> | 2012-07-19 14:17:30 -0400 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2012-07-19 14:17:30 -0400 |
commit | abaa72d7fd9a20a67b62e6afa0e746e27851dc33 (patch) | |
tree | ebe4134fcc93a6e205e6004b3e652d7a62281651 /net/core | |
parent | 67da22d23fa6f3324e03bcd0580b914b2e4afbf3 (diff) | |
parent | 3e4b9459fb0e149c6b74c9e89399a8fc39a92b44 (diff) |
Merge git://git.kernel.org/pub/scm/linux/kernel/git/davem/net
Conflicts:
drivers/net/ethernet/intel/ixgbevf/ixgbevf_main.c
Diffstat (limited to 'net/core')
-rw-r--r-- | net/core/dev.c | 3 | ||||
-rw-r--r-- | net/core/net_namespace.c | 4 | ||||
-rw-r--r-- | net/core/netprio_cgroup.c | 71 | ||||
-rw-r--r-- | net/core/skbuff.c | 2 |
4 files changed, 60 insertions, 20 deletions
diff --git a/net/core/dev.c b/net/core/dev.c index 73e87c7b4377..d70e4a3a49f2 100644 --- a/net/core/dev.c +++ b/net/core/dev.c | |||
@@ -6313,7 +6313,8 @@ static struct hlist_head *netdev_create_hash(void) | |||
6313 | /* Initialize per network namespace state */ | 6313 | /* Initialize per network namespace state */ |
6314 | static int __net_init netdev_init(struct net *net) | 6314 | static int __net_init netdev_init(struct net *net) |
6315 | { | 6315 | { |
6316 | INIT_LIST_HEAD(&net->dev_base_head); | 6316 | if (net != &init_net) |
6317 | INIT_LIST_HEAD(&net->dev_base_head); | ||
6317 | 6318 | ||
6318 | net->dev_name_head = netdev_create_hash(); | 6319 | net->dev_name_head = netdev_create_hash(); |
6319 | if (net->dev_name_head == NULL) | 6320 | if (net->dev_name_head == NULL) |
diff --git a/net/core/net_namespace.c b/net/core/net_namespace.c index dddbacb8f28c..42f1e1c7514f 100644 --- a/net/core/net_namespace.c +++ b/net/core/net_namespace.c | |||
@@ -27,7 +27,9 @@ static DEFINE_MUTEX(net_mutex); | |||
27 | LIST_HEAD(net_namespace_list); | 27 | LIST_HEAD(net_namespace_list); |
28 | EXPORT_SYMBOL_GPL(net_namespace_list); | 28 | EXPORT_SYMBOL_GPL(net_namespace_list); |
29 | 29 | ||
30 | struct net init_net; | 30 | struct net init_net = { |
31 | .dev_base_head = LIST_HEAD_INIT(init_net.dev_base_head), | ||
32 | }; | ||
31 | EXPORT_SYMBOL(init_net); | 33 | EXPORT_SYMBOL(init_net); |
32 | 34 | ||
33 | #define INITIAL_NET_GEN_PTRS 13 /* +1 for len +2 for rcu_head */ | 35 | #define INITIAL_NET_GEN_PTRS 13 /* +1 for len +2 for rcu_head */ |
diff --git a/net/core/netprio_cgroup.c b/net/core/netprio_cgroup.c index 3e953eaddbfc..b2e9caa1ad1a 100644 --- a/net/core/netprio_cgroup.c +++ b/net/core/netprio_cgroup.c | |||
@@ -65,7 +65,7 @@ static void put_prioidx(u32 idx) | |||
65 | spin_unlock_irqrestore(&prioidx_map_lock, flags); | 65 | spin_unlock_irqrestore(&prioidx_map_lock, flags); |
66 | } | 66 | } |
67 | 67 | ||
68 | static void extend_netdev_table(struct net_device *dev, u32 new_len) | 68 | static int extend_netdev_table(struct net_device *dev, u32 new_len) |
69 | { | 69 | { |
70 | size_t new_size = sizeof(struct netprio_map) + | 70 | size_t new_size = sizeof(struct netprio_map) + |
71 | ((sizeof(u32) * new_len)); | 71 | ((sizeof(u32) * new_len)); |
@@ -77,7 +77,7 @@ static void extend_netdev_table(struct net_device *dev, u32 new_len) | |||
77 | 77 | ||
78 | if (!new_priomap) { | 78 | if (!new_priomap) { |
79 | pr_warn("Unable to alloc new priomap!\n"); | 79 | pr_warn("Unable to alloc new priomap!\n"); |
80 | return; | 80 | return -ENOMEM; |
81 | } | 81 | } |
82 | 82 | ||
83 | for (i = 0; | 83 | for (i = 0; |
@@ -90,46 +90,79 @@ static void extend_netdev_table(struct net_device *dev, u32 new_len) | |||
90 | rcu_assign_pointer(dev->priomap, new_priomap); | 90 | rcu_assign_pointer(dev->priomap, new_priomap); |
91 | if (old_priomap) | 91 | if (old_priomap) |
92 | kfree_rcu(old_priomap, rcu); | 92 | kfree_rcu(old_priomap, rcu); |
93 | return 0; | ||
93 | } | 94 | } |
94 | 95 | ||
95 | static void update_netdev_tables(void) | 96 | static int write_update_netdev_table(struct net_device *dev) |
96 | { | 97 | { |
98 | int ret = 0; | ||
99 | u32 max_len; | ||
100 | struct netprio_map *map; | ||
101 | |||
102 | rtnl_lock(); | ||
103 | max_len = atomic_read(&max_prioidx) + 1; | ||
104 | map = rtnl_dereference(dev->priomap); | ||
105 | if (!map || map->priomap_len < max_len) | ||
106 | ret = extend_netdev_table(dev, max_len); | ||
107 | rtnl_unlock(); | ||
108 | |||
109 | return ret; | ||
110 | } | ||
111 | |||
112 | static int update_netdev_tables(void) | ||
113 | { | ||
114 | int ret = 0; | ||
97 | struct net_device *dev; | 115 | struct net_device *dev; |
98 | u32 max_len = atomic_read(&max_prioidx) + 1; | 116 | u32 max_len; |
99 | struct netprio_map *map; | 117 | struct netprio_map *map; |
100 | 118 | ||
101 | rtnl_lock(); | 119 | rtnl_lock(); |
120 | max_len = atomic_read(&max_prioidx) + 1; | ||
102 | for_each_netdev(&init_net, dev) { | 121 | for_each_netdev(&init_net, dev) { |
103 | map = rtnl_dereference(dev->priomap); | 122 | map = rtnl_dereference(dev->priomap); |
104 | if ((!map) || | 123 | /* |
105 | (map->priomap_len < max_len)) | 124 | * don't allocate priomap if we didn't |
106 | extend_netdev_table(dev, max_len); | 125 | * change net_prio.ifpriomap (map == NULL), |
126 | * this will speed up skb_update_prio. | ||
127 | */ | ||
128 | if (map && map->priomap_len < max_len) { | ||
129 | ret = extend_netdev_table(dev, max_len); | ||
130 | if (ret < 0) | ||
131 | break; | ||
132 | } | ||
107 | } | 133 | } |
108 | rtnl_unlock(); | 134 | rtnl_unlock(); |
135 | return ret; | ||
109 | } | 136 | } |
110 | 137 | ||
111 | static struct cgroup_subsys_state *cgrp_create(struct cgroup *cgrp) | 138 | static struct cgroup_subsys_state *cgrp_create(struct cgroup *cgrp) |
112 | { | 139 | { |
113 | struct cgroup_netprio_state *cs; | 140 | struct cgroup_netprio_state *cs; |
114 | int ret; | 141 | int ret = -EINVAL; |
115 | 142 | ||
116 | cs = kzalloc(sizeof(*cs), GFP_KERNEL); | 143 | cs = kzalloc(sizeof(*cs), GFP_KERNEL); |
117 | if (!cs) | 144 | if (!cs) |
118 | return ERR_PTR(-ENOMEM); | 145 | return ERR_PTR(-ENOMEM); |
119 | 146 | ||
120 | if (cgrp->parent && cgrp_netprio_state(cgrp->parent)->prioidx) { | 147 | if (cgrp->parent && cgrp_netprio_state(cgrp->parent)->prioidx) |
121 | kfree(cs); | 148 | goto out; |
122 | return ERR_PTR(-EINVAL); | ||
123 | } | ||
124 | 149 | ||
125 | ret = get_prioidx(&cs->prioidx); | 150 | ret = get_prioidx(&cs->prioidx); |
126 | if (ret != 0) { | 151 | if (ret < 0) { |
127 | pr_warn("No space in priority index array\n"); | 152 | pr_warn("No space in priority index array\n"); |
128 | kfree(cs); | 153 | goto out; |
129 | return ERR_PTR(ret); | 154 | } |
155 | |||
156 | ret = update_netdev_tables(); | ||
157 | if (ret < 0) { | ||
158 | put_prioidx(cs->prioidx); | ||
159 | goto out; | ||
130 | } | 160 | } |
131 | 161 | ||
132 | return &cs->css; | 162 | return &cs->css; |
163 | out: | ||
164 | kfree(cs); | ||
165 | return ERR_PTR(ret); | ||
133 | } | 166 | } |
134 | 167 | ||
135 | static void cgrp_destroy(struct cgroup *cgrp) | 168 | static void cgrp_destroy(struct cgroup *cgrp) |
@@ -221,13 +254,17 @@ static int write_priomap(struct cgroup *cgrp, struct cftype *cft, | |||
221 | if (!dev) | 254 | if (!dev) |
222 | goto out_free_devname; | 255 | goto out_free_devname; |
223 | 256 | ||
224 | update_netdev_tables(); | 257 | ret = write_update_netdev_table(dev); |
225 | ret = 0; | 258 | if (ret < 0) |
259 | goto out_put_dev; | ||
260 | |||
226 | rcu_read_lock(); | 261 | rcu_read_lock(); |
227 | map = rcu_dereference(dev->priomap); | 262 | map = rcu_dereference(dev->priomap); |
228 | if (map) | 263 | if (map) |
229 | map->priomap[prioidx] = priority; | 264 | map->priomap[prioidx] = priority; |
230 | rcu_read_unlock(); | 265 | rcu_read_unlock(); |
266 | |||
267 | out_put_dev: | ||
231 | dev_put(dev); | 268 | dev_put(dev); |
232 | 269 | ||
233 | out_free_devname: | 270 | out_free_devname: |
diff --git a/net/core/skbuff.c b/net/core/skbuff.c index c011d7fab62d..ccfcb7d8711e 100644 --- a/net/core/skbuff.c +++ b/net/core/skbuff.c | |||
@@ -365,7 +365,7 @@ struct sk_buff *__netdev_alloc_skb(struct net_device *dev, | |||
365 | unsigned int fragsz = SKB_DATA_ALIGN(length + NET_SKB_PAD) + | 365 | unsigned int fragsz = SKB_DATA_ALIGN(length + NET_SKB_PAD) + |
366 | SKB_DATA_ALIGN(sizeof(struct skb_shared_info)); | 366 | SKB_DATA_ALIGN(sizeof(struct skb_shared_info)); |
367 | 367 | ||
368 | if (fragsz <= PAGE_SIZE && !(gfp_mask & __GFP_WAIT)) { | 368 | if (fragsz <= PAGE_SIZE && !(gfp_mask & (__GFP_WAIT | GFP_DMA))) { |
369 | void *data = netdev_alloc_frag(fragsz); | 369 | void *data = netdev_alloc_frag(fragsz); |
370 | 370 | ||
371 | if (likely(data)) { | 371 | if (likely(data)) { |