Skip to content

Commit 18fb0b4

Browse files
committed
Merge git://git.kernel.org/pub/scm/linux/kernel/git/davem/net
2 parents 39cebdb + 6d9c153 commit 18fb0b4

File tree

13 files changed

+76
-106
lines changed

13 files changed

+76
-106
lines changed

drivers/net/dsa/dsa_loop.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -352,7 +352,7 @@ static void __exit dsa_loop_exit(void)
352352

353353
mdio_driver_unregister(&dsa_loop_drv);
354354
for (i = 0; i < NUM_FIXED_PHYS; i++)
355-
if (phydevs[i])
355+
if (!IS_ERR(phydevs[i]))
356356
fixed_phy_unregister(phydevs[i]);
357357
}
358358
module_exit(dsa_loop_exit);

include/net/inet_frag.h

Lines changed: 9 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,9 @@
11
#ifndef __NET_FRAG_H__
22
#define __NET_FRAG_H__
33

4-
#include <linux/percpu_counter.h>
5-
64
struct netns_frags {
7-
/* The percpu_counter "mem" need to be cacheline aligned.
8-
* mem.count must not share cacheline with other writers
9-
*/
10-
struct percpu_counter mem ____cacheline_aligned_in_smp;
11-
5+
/* Keep atomic mem on separate cachelines in structs that include it */
6+
atomic_t mem ____cacheline_aligned_in_smp;
127
/* sysctls */
138
int timeout;
149
int high_thresh;
@@ -108,15 +103,10 @@ struct inet_frags {
108103
int inet_frags_init(struct inet_frags *);
109104
void inet_frags_fini(struct inet_frags *);
110105

111-
static inline int inet_frags_init_net(struct netns_frags *nf)
112-
{
113-
return percpu_counter_init(&nf->mem, 0, GFP_KERNEL);
114-
}
115-
static inline void inet_frags_uninit_net(struct netns_frags *nf)
106+
static inline void inet_frags_init_net(struct netns_frags *nf)
116107
{
117-
percpu_counter_destroy(&nf->mem);
108+
atomic_set(&nf->mem, 0);
118109
}
119-
120110
void inet_frags_exit_net(struct netns_frags *nf, struct inet_frags *f);
121111

122112
void inet_frag_kill(struct inet_frag_queue *q, struct inet_frags *f);
@@ -140,31 +130,24 @@ static inline bool inet_frag_evicting(struct inet_frag_queue *q)
140130

141131
/* Memory Tracking Functions. */
142132

143-
/* The default percpu_counter batch size is not big enough to scale to
144-
* fragmentation mem acct sizes.
145-
* The mem size of a 64K fragment is approx:
146-
* (44 fragments * 2944 truesize) + frag_queue struct(200) = 129736 bytes
147-
*/
148-
static unsigned int frag_percpu_counter_batch = 130000;
149-
150133
static inline int frag_mem_limit(struct netns_frags *nf)
151134
{
152-
return percpu_counter_read(&nf->mem);
135+
return atomic_read(&nf->mem);
153136
}
154137

155138
static inline void sub_frag_mem_limit(struct netns_frags *nf, int i)
156139
{
157-
percpu_counter_add_batch(&nf->mem, -i, frag_percpu_counter_batch);
140+
atomic_sub(i, &nf->mem);
158141
}
159142

160143
static inline void add_frag_mem_limit(struct netns_frags *nf, int i)
161144
{
162-
percpu_counter_add_batch(&nf->mem, i, frag_percpu_counter_batch);
145+
atomic_add(i, &nf->mem);
163146
}
164147

165-
static inline unsigned int sum_frag_mem_limit(struct netns_frags *nf)
148+
static inline int sum_frag_mem_limit(struct netns_frags *nf)
166149
{
167-
return percpu_counter_sum_positive(&nf->mem);
150+
return atomic_read(&nf->mem);
168151
}
169152

170153
/* RFC 3168 support :

include/net/route.h

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -189,10 +189,11 @@ static inline int ip_route_input(struct sk_buff *skb, __be32 dst, __be32 src,
189189

190190
rcu_read_lock();
191191
err = ip_route_input_noref(skb, dst, src, tos, devin);
192-
if (!err)
192+
if (!err) {
193193
skb_dst_force_safe(skb);
194-
if (!skb_dst(skb))
195-
err = -EINVAL;
194+
if (!skb_dst(skb))
195+
err = -EINVAL;
196+
}
196197
rcu_read_unlock();
197198

198199
return err;

net/ieee802154/6lowpan/reassembly.c

Lines changed: 3 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -580,19 +580,14 @@ static int __net_init lowpan_frags_init_net(struct net *net)
580580
{
581581
struct netns_ieee802154_lowpan *ieee802154_lowpan =
582582
net_ieee802154_lowpan(net);
583-
int res;
584583

585584
ieee802154_lowpan->frags.high_thresh = IPV6_FRAG_HIGH_THRESH;
586585
ieee802154_lowpan->frags.low_thresh = IPV6_FRAG_LOW_THRESH;
587586
ieee802154_lowpan->frags.timeout = IPV6_FRAG_TIMEOUT;
588587

589-
res = inet_frags_init_net(&ieee802154_lowpan->frags);
590-
if (res)
591-
return res;
592-
res = lowpan_frags_ns_sysctl_register(net);
593-
if (res)
594-
inet_frags_uninit_net(&ieee802154_lowpan->frags);
595-
return res;
588+
inet_frags_init_net(&ieee802154_lowpan->frags);
589+
590+
return lowpan_frags_ns_sysctl_register(net);
596591
}
597592

598593
static void __net_exit lowpan_frags_exit_net(struct net *net)

net/ipv4/inet_fragment.c

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -234,10 +234,8 @@ void inet_frags_exit_net(struct netns_frags *nf, struct inet_frags *f)
234234
cond_resched();
235235

236236
if (read_seqretry(&f->rnd_seqlock, seq) ||
237-
percpu_counter_sum(&nf->mem))
237+
sum_frag_mem_limit(nf))
238238
goto evict_again;
239-
240-
percpu_counter_destroy(&nf->mem);
241239
}
242240
EXPORT_SYMBOL(inet_frags_exit_net);
243241

net/ipv4/ip_fragment.c

Lines changed: 3 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -844,8 +844,6 @@ static void __init ip4_frags_ctl_register(void)
844844

845845
static int __net_init ipv4_frags_init_net(struct net *net)
846846
{
847-
int res;
848-
849847
/* Fragment cache limits.
850848
*
851849
* The fragment memory accounting code, (tries to) account for
@@ -871,13 +869,9 @@ static int __net_init ipv4_frags_init_net(struct net *net)
871869

872870
net->ipv4.frags.max_dist = 64;
873871

874-
res = inet_frags_init_net(&net->ipv4.frags);
875-
if (res)
876-
return res;
877-
res = ip4_frags_ns_ctl_register(net);
878-
if (res)
879-
inet_frags_uninit_net(&net->ipv4.frags);
880-
return res;
872+
inet_frags_init_net(&net->ipv4.frags);
873+
874+
return ip4_frags_ns_ctl_register(net);
881875
}
882876

883877
static void __net_exit ipv4_frags_exit_net(struct net *net)

net/ipv6/netfilter/nf_conntrack_reasm.c

Lines changed: 3 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -622,18 +622,12 @@ EXPORT_SYMBOL_GPL(nf_ct_frag6_gather);
622622

623623
static int nf_ct_net_init(struct net *net)
624624
{
625-
int res;
626-
627625
net->nf_frag.frags.high_thresh = IPV6_FRAG_HIGH_THRESH;
628626
net->nf_frag.frags.low_thresh = IPV6_FRAG_LOW_THRESH;
629627
net->nf_frag.frags.timeout = IPV6_FRAG_TIMEOUT;
630-
res = inet_frags_init_net(&net->nf_frag.frags);
631-
if (res)
632-
return res;
633-
res = nf_ct_frag6_sysctl_register(net);
634-
if (res)
635-
inet_frags_uninit_net(&net->nf_frag.frags);
636-
return res;
628+
inet_frags_init_net(&net->nf_frag.frags);
629+
630+
return nf_ct_frag6_sysctl_register(net);
637631
}
638632

639633
static void nf_ct_net_exit(struct net *net)

net/ipv6/reassembly.c

Lines changed: 3 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -714,19 +714,13 @@ static void ip6_frags_sysctl_unregister(void)
714714

715715
static int __net_init ipv6_frags_init_net(struct net *net)
716716
{
717-
int res;
718-
719717
net->ipv6.frags.high_thresh = IPV6_FRAG_HIGH_THRESH;
720718
net->ipv6.frags.low_thresh = IPV6_FRAG_LOW_THRESH;
721719
net->ipv6.frags.timeout = IPV6_FRAG_TIMEOUT;
722720

723-
res = inet_frags_init_net(&net->ipv6.frags);
724-
if (res)
725-
return res;
726-
res = ip6_frags_ns_sysctl_register(net);
727-
if (res)
728-
inet_frags_uninit_net(&net->ipv6.frags);
729-
return res;
721+
inet_frags_init_net(&net->ipv6.frags);
722+
723+
return ip6_frags_ns_sysctl_register(net);
730724
}
731725

732726
static void __net_exit ipv6_frags_exit_net(struct net *net)

net/l2tp/l2tp_core.c

Lines changed: 28 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -329,39 +329,56 @@ static int l2tp_session_add_to_tunnel(struct l2tp_tunnel *tunnel,
329329
struct hlist_head *g_head;
330330
struct hlist_head *head;
331331
struct l2tp_net *pn;
332+
int err;
332333

333334
head = l2tp_session_id_hash(tunnel, session->session_id);
334335

335336
write_lock_bh(&tunnel->hlist_lock);
337+
if (!tunnel->acpt_newsess) {
338+
err = -ENODEV;
339+
goto err_tlock;
340+
}
341+
336342
hlist_for_each_entry(session_walk, head, hlist)
337-
if (session_walk->session_id == session->session_id)
338-
goto exist;
343+
if (session_walk->session_id == session->session_id) {
344+
err = -EEXIST;
345+
goto err_tlock;
346+
}
339347

340348
if (tunnel->version == L2TP_HDR_VER_3) {
341349
pn = l2tp_pernet(tunnel->l2tp_net);
342350
g_head = l2tp_session_id_hash_2(l2tp_pernet(tunnel->l2tp_net),
343351
session->session_id);
344352

345353
spin_lock_bh(&pn->l2tp_session_hlist_lock);
354+
346355
hlist_for_each_entry(session_walk, g_head, global_hlist)
347-
if (session_walk->session_id == session->session_id)
348-
goto exist_glob;
356+
if (session_walk->session_id == session->session_id) {
357+
err = -EEXIST;
358+
goto err_tlock_pnlock;
359+
}
349360

361+
l2tp_tunnel_inc_refcount(tunnel);
362+
sock_hold(tunnel->sock);
350363
hlist_add_head_rcu(&session->global_hlist, g_head);
364+
351365
spin_unlock_bh(&pn->l2tp_session_hlist_lock);
366+
} else {
367+
l2tp_tunnel_inc_refcount(tunnel);
368+
sock_hold(tunnel->sock);
352369
}
353370

354371
hlist_add_head(&session->hlist, head);
355372
write_unlock_bh(&tunnel->hlist_lock);
356373

357374
return 0;
358375

359-
exist_glob:
376+
err_tlock_pnlock:
360377
spin_unlock_bh(&pn->l2tp_session_hlist_lock);
361-
exist:
378+
err_tlock:
362379
write_unlock_bh(&tunnel->hlist_lock);
363380

364-
return -EEXIST;
381+
return err;
365382
}
366383

367384
/* Lookup a tunnel by id
@@ -1251,7 +1268,6 @@ static void l2tp_tunnel_destruct(struct sock *sk)
12511268
/* Remove hooks into tunnel socket */
12521269
sk->sk_destruct = tunnel->old_sk_destruct;
12531270
sk->sk_user_data = NULL;
1254-
tunnel->sock = NULL;
12551271

12561272
/* Remove the tunnel struct from the tunnel list */
12571273
pn = l2tp_pernet(tunnel->l2tp_net);
@@ -1261,6 +1277,8 @@ static void l2tp_tunnel_destruct(struct sock *sk)
12611277
atomic_dec(&l2tp_tunnel_count);
12621278

12631279
l2tp_tunnel_closeall(tunnel);
1280+
1281+
tunnel->sock = NULL;
12641282
l2tp_tunnel_dec_refcount(tunnel);
12651283

12661284
/* Call the original destructor */
@@ -1285,6 +1303,7 @@ void l2tp_tunnel_closeall(struct l2tp_tunnel *tunnel)
12851303
tunnel->name);
12861304

12871305
write_lock_bh(&tunnel->hlist_lock);
1306+
tunnel->acpt_newsess = false;
12881307
for (hash = 0; hash < L2TP_HASH_SIZE; hash++) {
12891308
again:
12901309
hlist_for_each_safe(walk, tmp, &tunnel->session_hlist[hash]) {
@@ -1581,6 +1600,7 @@ int l2tp_tunnel_create(struct net *net, int fd, int version, u32 tunnel_id, u32
15811600
tunnel->magic = L2TP_TUNNEL_MAGIC;
15821601
sprintf(&tunnel->name[0], "tunl %u", tunnel_id);
15831602
rwlock_init(&tunnel->hlist_lock);
1603+
tunnel->acpt_newsess = true;
15841604

15851605
/* The net we belong to */
15861606
tunnel->l2tp_net = net;
@@ -1829,11 +1849,6 @@ struct l2tp_session *l2tp_session_create(int priv_size, struct l2tp_tunnel *tunn
18291849
return ERR_PTR(err);
18301850
}
18311851

1832-
l2tp_tunnel_inc_refcount(tunnel);
1833-
1834-
/* Ensure tunnel socket isn't deleted */
1835-
sock_hold(tunnel->sock);
1836-
18371852
/* Ignore management session in session count value */
18381853
if (session->session_id != 0)
18391854
atomic_inc(&l2tp_session_count);

net/l2tp/l2tp_core.h

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -162,6 +162,10 @@ struct l2tp_tunnel {
162162
int magic; /* Should be L2TP_TUNNEL_MAGIC */
163163
struct rcu_head rcu;
164164
rwlock_t hlist_lock; /* protect session_hlist */
165+
bool acpt_newsess; /* Indicates whether this
166+
* tunnel accepts new sessions.
167+
* Protected by hlist_lock.
168+
*/
165169
struct hlist_head session_hlist[L2TP_HASH_SIZE];
166170
/* hashed list of sessions,
167171
* hashed by id */
@@ -197,7 +201,9 @@ struct l2tp_tunnel {
197201
};
198202

199203
struct l2tp_nl_cmd_ops {
200-
int (*session_create)(struct net *net, u32 tunnel_id, u32 session_id, u32 peer_session_id, struct l2tp_session_cfg *cfg);
204+
int (*session_create)(struct net *net, struct l2tp_tunnel *tunnel,
205+
u32 session_id, u32 peer_session_id,
206+
struct l2tp_session_cfg *cfg);
201207
int (*session_delete)(struct l2tp_session *session);
202208
};
203209

net/l2tp/l2tp_eth.c

Lines changed: 3 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -262,24 +262,19 @@ static void l2tp_eth_adjust_mtu(struct l2tp_tunnel *tunnel,
262262
dev->needed_headroom += session->hdr_len;
263263
}
264264

265-
static int l2tp_eth_create(struct net *net, u32 tunnel_id, u32 session_id, u32 peer_session_id, struct l2tp_session_cfg *cfg)
265+
static int l2tp_eth_create(struct net *net, struct l2tp_tunnel *tunnel,
266+
u32 session_id, u32 peer_session_id,
267+
struct l2tp_session_cfg *cfg)
266268
{
267269
unsigned char name_assign_type;
268270
struct net_device *dev;
269271
char name[IFNAMSIZ];
270-
struct l2tp_tunnel *tunnel;
271272
struct l2tp_session *session;
272273
struct l2tp_eth *priv;
273274
struct l2tp_eth_sess *spriv;
274275
int rc;
275276
struct l2tp_eth_net *pn;
276277

277-
tunnel = l2tp_tunnel_find(net, tunnel_id);
278-
if (!tunnel) {
279-
rc = -ENODEV;
280-
goto out;
281-
}
282-
283278
if (cfg->ifname) {
284279
strlcpy(name, cfg->ifname, IFNAMSIZ);
285280
name_assign_type = NET_NAME_USER;

net/l2tp/l2tp_netlink.c

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -643,10 +643,10 @@ static int l2tp_nl_cmd_session_create(struct sk_buff *skb, struct genl_info *inf
643643
break;
644644
}
645645

646-
ret = -EPROTONOSUPPORT;
647-
if (l2tp_nl_cmd_ops[cfg.pw_type]->session_create)
648-
ret = (*l2tp_nl_cmd_ops[cfg.pw_type]->session_create)(net, tunnel_id,
649-
session_id, peer_session_id, &cfg);
646+
ret = l2tp_nl_cmd_ops[cfg.pw_type]->session_create(net, tunnel,
647+
session_id,
648+
peer_session_id,
649+
&cfg);
650650

651651
if (ret >= 0) {
652652
session = l2tp_session_get(net, tunnel, session_id, false);

0 commit comments

Comments
 (0)