diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2009-06-18 17:07:15 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2009-06-18 17:07:15 -0400 |
commit | d2aa4550379f92e929af7ed1dd4f55e6a1e331f8 (patch) | |
tree | 5ef0fc69a507f0d701fd157b6652427eabd5efdd /net | |
parent | 9e3e4b1d2d13bead8d52703c82a02b55f108b491 (diff) | |
parent | cb2107be43d2fc5eadec58b92b54bf32c00bfff3 (diff) |
Merge git://git.kernel.org/pub/scm/linux/kernel/git/davem/net-next-2.6
* git://git.kernel.org/pub/scm/linux/kernel/git/davem/net-next-2.6: (55 commits)
netxen: fix tx ring accounting
netxen: fix detection of cut-thru firmware mode
forcedeth: fix dma api mismatches
atm: sk_wmem_alloc initial value is one
net: correct off-by-one write allocations reports
via-velocity : fix no link detection on boot
Net / e100: Fix suspend of devices that cannot be power managed
TI DaVinci EMAC : Fix rmmod error
net: group address list and its count
ipv4: Fix fib_trie rebalancing, part 2
pkt_sched: Update drops stats in act_police
sky2: version 1.23
sky2: add GRO support
sky2: skb recycling
sky2: reduce default transmit ring
sky2: receive counter update
sky2: fix shutdown synchronization
sky2: PCI irq issues
sky2: more receive shutdown
sky2: turn off pause during shutdown
...
Manually fix trivial conflict in net/core/skbuff.c due to kmemcheck
Diffstat (limited to 'net')
40 files changed, 260 insertions, 211 deletions
diff --git a/net/appletalk/atalk_proc.c b/net/appletalk/atalk_proc.c index fd8e0847b254..80caad1a31a5 100644 --- a/net/appletalk/atalk_proc.c +++ b/net/appletalk/atalk_proc.c | |||
@@ -204,8 +204,8 @@ static int atalk_seq_socket_show(struct seq_file *seq, void *v) | |||
204 | "%02X %d\n", | 204 | "%02X %d\n", |
205 | s->sk_type, ntohs(at->src_net), at->src_node, at->src_port, | 205 | s->sk_type, ntohs(at->src_net), at->src_node, at->src_port, |
206 | ntohs(at->dest_net), at->dest_node, at->dest_port, | 206 | ntohs(at->dest_net), at->dest_node, at->dest_port, |
207 | atomic_read(&s->sk_wmem_alloc), | 207 | sk_wmem_alloc_get(s), |
208 | atomic_read(&s->sk_rmem_alloc), | 208 | sk_rmem_alloc_get(s), |
209 | s->sk_state, SOCK_INODE(s->sk_socket)->i_uid); | 209 | s->sk_state, SOCK_INODE(s->sk_socket)->i_uid); |
210 | out: | 210 | out: |
211 | return 0; | 211 | return 0; |
diff --git a/net/appletalk/ddp.c b/net/appletalk/ddp.c index b603cbacdc58..590b83963622 100644 --- a/net/appletalk/ddp.c +++ b/net/appletalk/ddp.c | |||
@@ -162,8 +162,7 @@ static void atalk_destroy_timer(unsigned long data) | |||
162 | { | 162 | { |
163 | struct sock *sk = (struct sock *)data; | 163 | struct sock *sk = (struct sock *)data; |
164 | 164 | ||
165 | if (atomic_read(&sk->sk_wmem_alloc) || | 165 | if (sk_has_allocations(sk)) { |
166 | atomic_read(&sk->sk_rmem_alloc)) { | ||
167 | sk->sk_timer.expires = jiffies + SOCK_DESTROY_TIME; | 166 | sk->sk_timer.expires = jiffies + SOCK_DESTROY_TIME; |
168 | add_timer(&sk->sk_timer); | 167 | add_timer(&sk->sk_timer); |
169 | } else | 168 | } else |
@@ -175,8 +174,7 @@ static inline void atalk_destroy_socket(struct sock *sk) | |||
175 | atalk_remove_socket(sk); | 174 | atalk_remove_socket(sk); |
176 | skb_queue_purge(&sk->sk_receive_queue); | 175 | skb_queue_purge(&sk->sk_receive_queue); |
177 | 176 | ||
178 | if (atomic_read(&sk->sk_wmem_alloc) || | 177 | if (sk_has_allocations(sk)) { |
179 | atomic_read(&sk->sk_rmem_alloc)) { | ||
180 | setup_timer(&sk->sk_timer, atalk_destroy_timer, | 178 | setup_timer(&sk->sk_timer, atalk_destroy_timer, |
181 | (unsigned long)sk); | 179 | (unsigned long)sk); |
182 | sk->sk_timer.expires = jiffies + SOCK_DESTROY_TIME; | 180 | sk->sk_timer.expires = jiffies + SOCK_DESTROY_TIME; |
@@ -1750,8 +1748,7 @@ static int atalk_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg) | |||
1750 | switch (cmd) { | 1748 | switch (cmd) { |
1751 | /* Protocol layer */ | 1749 | /* Protocol layer */ |
1752 | case TIOCOUTQ: { | 1750 | case TIOCOUTQ: { |
1753 | long amount = sk->sk_sndbuf - | 1751 | long amount = sk->sk_sndbuf - sk_wmem_alloc_get(sk); |
1754 | atomic_read(&sk->sk_wmem_alloc); | ||
1755 | 1752 | ||
1756 | if (amount < 0) | 1753 | if (amount < 0) |
1757 | amount = 0; | 1754 | amount = 0; |
diff --git a/net/atm/common.c b/net/atm/common.c index d34edbe754c8..c1c97936192c 100644 --- a/net/atm/common.c +++ b/net/atm/common.c | |||
@@ -62,15 +62,15 @@ static struct sk_buff *alloc_tx(struct atm_vcc *vcc,unsigned int size) | |||
62 | struct sk_buff *skb; | 62 | struct sk_buff *skb; |
63 | struct sock *sk = sk_atm(vcc); | 63 | struct sock *sk = sk_atm(vcc); |
64 | 64 | ||
65 | if (atomic_read(&sk->sk_wmem_alloc) && !atm_may_send(vcc, size)) { | 65 | if (sk_wmem_alloc_get(sk) && !atm_may_send(vcc, size)) { |
66 | pr_debug("Sorry: wmem_alloc = %d, size = %d, sndbuf = %d\n", | 66 | pr_debug("Sorry: wmem_alloc = %d, size = %d, sndbuf = %d\n", |
67 | atomic_read(&sk->sk_wmem_alloc), size, | 67 | sk_wmem_alloc_get(sk), size, |
68 | sk->sk_sndbuf); | 68 | sk->sk_sndbuf); |
69 | return NULL; | 69 | return NULL; |
70 | } | 70 | } |
71 | while (!(skb = alloc_skb(size,GFP_KERNEL))) schedule(); | 71 | while (!(skb = alloc_skb(size, GFP_KERNEL))) |
72 | pr_debug("AlTx %d += %d\n", atomic_read(&sk->sk_wmem_alloc), | 72 | schedule(); |
73 | skb->truesize); | 73 | pr_debug("AlTx %d += %d\n", sk_wmem_alloc_get(sk), skb->truesize); |
74 | atomic_add(skb->truesize, &sk->sk_wmem_alloc); | 74 | atomic_add(skb->truesize, &sk->sk_wmem_alloc); |
75 | return skb; | 75 | return skb; |
76 | } | 76 | } |
@@ -145,7 +145,7 @@ int vcc_create(struct net *net, struct socket *sock, int protocol, int family) | |||
145 | memset(&vcc->local,0,sizeof(struct sockaddr_atmsvc)); | 145 | memset(&vcc->local,0,sizeof(struct sockaddr_atmsvc)); |
146 | memset(&vcc->remote,0,sizeof(struct sockaddr_atmsvc)); | 146 | memset(&vcc->remote,0,sizeof(struct sockaddr_atmsvc)); |
147 | vcc->qos.txtp.max_sdu = 1 << 16; /* for meta VCs */ | 147 | vcc->qos.txtp.max_sdu = 1 << 16; /* for meta VCs */ |
148 | atomic_set(&sk->sk_wmem_alloc, 0); | 148 | atomic_set(&sk->sk_wmem_alloc, 1); |
149 | atomic_set(&sk->sk_rmem_alloc, 0); | 149 | atomic_set(&sk->sk_rmem_alloc, 0); |
150 | vcc->push = NULL; | 150 | vcc->push = NULL; |
151 | vcc->pop = NULL; | 151 | vcc->pop = NULL; |
diff --git a/net/atm/ioctl.c b/net/atm/ioctl.c index 76ed3c8d26e6..4da8892ced5f 100644 --- a/net/atm/ioctl.c +++ b/net/atm/ioctl.c | |||
@@ -63,8 +63,7 @@ static int do_vcc_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg | |||
63 | error = -EINVAL; | 63 | error = -EINVAL; |
64 | goto done; | 64 | goto done; |
65 | } | 65 | } |
66 | error = put_user(sk->sk_sndbuf - | 66 | error = put_user(sk->sk_sndbuf - sk_wmem_alloc_get(sk), |
67 | atomic_read(&sk->sk_wmem_alloc), | ||
68 | (int __user *) argp) ? -EFAULT : 0; | 67 | (int __user *) argp) ? -EFAULT : 0; |
69 | goto done; | 68 | goto done; |
70 | case SIOCINQ: | 69 | case SIOCINQ: |
diff --git a/net/atm/proc.c b/net/atm/proc.c index e7b3b273907d..38de5ff61ecd 100644 --- a/net/atm/proc.c +++ b/net/atm/proc.c | |||
@@ -204,8 +204,8 @@ static void vcc_info(struct seq_file *seq, struct atm_vcc *vcc) | |||
204 | seq_printf(seq, "%3d", sk->sk_family); | 204 | seq_printf(seq, "%3d", sk->sk_family); |
205 | } | 205 | } |
206 | seq_printf(seq, " %04lx %5d %7d/%7d %7d/%7d [%d]\n", vcc->flags, sk->sk_err, | 206 | seq_printf(seq, " %04lx %5d %7d/%7d %7d/%7d [%d]\n", vcc->flags, sk->sk_err, |
207 | atomic_read(&sk->sk_wmem_alloc), sk->sk_sndbuf, | 207 | sk_wmem_alloc_get(sk), sk->sk_sndbuf, |
208 | atomic_read(&sk->sk_rmem_alloc), sk->sk_rcvbuf, | 208 | sk_rmem_alloc_get(sk), sk->sk_rcvbuf, |
209 | atomic_read(&sk->sk_refcnt)); | 209 | atomic_read(&sk->sk_refcnt)); |
210 | } | 210 | } |
211 | 211 | ||
diff --git a/net/atm/raw.c b/net/atm/raw.c index b0a2d8cb6744..cbfcc71a17b1 100644 --- a/net/atm/raw.c +++ b/net/atm/raw.c | |||
@@ -33,7 +33,7 @@ static void atm_pop_raw(struct atm_vcc *vcc,struct sk_buff *skb) | |||
33 | struct sock *sk = sk_atm(vcc); | 33 | struct sock *sk = sk_atm(vcc); |
34 | 34 | ||
35 | pr_debug("APopR (%d) %d -= %d\n", vcc->vci, | 35 | pr_debug("APopR (%d) %d -= %d\n", vcc->vci, |
36 | atomic_read(&sk->sk_wmem_alloc), skb->truesize); | 36 | sk_wmem_alloc_get(sk), skb->truesize); |
37 | atomic_sub(skb->truesize, &sk->sk_wmem_alloc); | 37 | atomic_sub(skb->truesize, &sk->sk_wmem_alloc); |
38 | dev_kfree_skb_any(skb); | 38 | dev_kfree_skb_any(skb); |
39 | sk->sk_write_space(sk); | 39 | sk->sk_write_space(sk); |
diff --git a/net/ax25/af_ax25.c b/net/ax25/af_ax25.c index fd9d06f291dc..da0f64f82b57 100644 --- a/net/ax25/af_ax25.c +++ b/net/ax25/af_ax25.c | |||
@@ -330,8 +330,7 @@ void ax25_destroy_socket(ax25_cb *ax25) | |||
330 | } | 330 | } |
331 | 331 | ||
332 | if (ax25->sk != NULL) { | 332 | if (ax25->sk != NULL) { |
333 | if (atomic_read(&ax25->sk->sk_wmem_alloc) || | 333 | if (sk_has_allocations(ax25->sk)) { |
334 | atomic_read(&ax25->sk->sk_rmem_alloc)) { | ||
335 | /* Defer: outstanding buffers */ | 334 | /* Defer: outstanding buffers */ |
336 | setup_timer(&ax25->dtimer, ax25_destroy_timer, | 335 | setup_timer(&ax25->dtimer, ax25_destroy_timer, |
337 | (unsigned long)ax25); | 336 | (unsigned long)ax25); |
@@ -1691,7 +1690,8 @@ static int ax25_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg) | |||
1691 | switch (cmd) { | 1690 | switch (cmd) { |
1692 | case TIOCOUTQ: { | 1691 | case TIOCOUTQ: { |
1693 | long amount; | 1692 | long amount; |
1694 | amount = sk->sk_sndbuf - atomic_read(&sk->sk_wmem_alloc); | 1693 | |
1694 | amount = sk->sk_sndbuf - sk_wmem_alloc_get(sk); | ||
1695 | if (amount < 0) | 1695 | if (amount < 0) |
1696 | amount = 0; | 1696 | amount = 0; |
1697 | res = put_user(amount, (int __user *)argp); | 1697 | res = put_user(amount, (int __user *)argp); |
@@ -1781,8 +1781,8 @@ static int ax25_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg) | |||
1781 | ax25_info.idletimer = ax25_display_timer(&ax25->idletimer) / (60 * HZ); | 1781 | ax25_info.idletimer = ax25_display_timer(&ax25->idletimer) / (60 * HZ); |
1782 | ax25_info.n2count = ax25->n2count; | 1782 | ax25_info.n2count = ax25->n2count; |
1783 | ax25_info.state = ax25->state; | 1783 | ax25_info.state = ax25->state; |
1784 | ax25_info.rcv_q = atomic_read(&sk->sk_rmem_alloc); | 1784 | ax25_info.rcv_q = sk_wmem_alloc_get(sk); |
1785 | ax25_info.snd_q = atomic_read(&sk->sk_wmem_alloc); | 1785 | ax25_info.snd_q = sk_rmem_alloc_get(sk); |
1786 | ax25_info.vs = ax25->vs; | 1786 | ax25_info.vs = ax25->vs; |
1787 | ax25_info.vr = ax25->vr; | 1787 | ax25_info.vr = ax25->vr; |
1788 | ax25_info.va = ax25->va; | 1788 | ax25_info.va = ax25->va; |
@@ -1922,8 +1922,8 @@ static int ax25_info_show(struct seq_file *seq, void *v) | |||
1922 | 1922 | ||
1923 | if (ax25->sk != NULL) { | 1923 | if (ax25->sk != NULL) { |
1924 | seq_printf(seq, " %d %d %lu\n", | 1924 | seq_printf(seq, " %d %d %lu\n", |
1925 | atomic_read(&ax25->sk->sk_wmem_alloc), | 1925 | sk_wmem_alloc_get(ax25->sk), |
1926 | atomic_read(&ax25->sk->sk_rmem_alloc), | 1926 | sk_rmem_alloc_get(ax25->sk), |
1927 | sock_i_ino(ax25->sk)); | 1927 | sock_i_ino(ax25->sk)); |
1928 | } else { | 1928 | } else { |
1929 | seq_puts(seq, " * * *\n"); | 1929 | seq_puts(seq, " * * *\n"); |
diff --git a/net/bluetooth/af_bluetooth.c b/net/bluetooth/af_bluetooth.c index 02b9baa1930b..0250e0600150 100644 --- a/net/bluetooth/af_bluetooth.c +++ b/net/bluetooth/af_bluetooth.c | |||
@@ -337,7 +337,7 @@ int bt_sock_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg) | |||
337 | if (sk->sk_state == BT_LISTEN) | 337 | if (sk->sk_state == BT_LISTEN) |
338 | return -EINVAL; | 338 | return -EINVAL; |
339 | 339 | ||
340 | amount = sk->sk_sndbuf - atomic_read(&sk->sk_wmem_alloc); | 340 | amount = sk->sk_sndbuf - sk_wmem_alloc_get(sk); |
341 | if (amount < 0) | 341 | if (amount < 0) |
342 | amount = 0; | 342 | amount = 0; |
343 | err = put_user(amount, (int __user *) arg); | 343 | err = put_user(amount, (int __user *) arg); |
diff --git a/net/core/dev.c b/net/core/dev.c index 576a61574a93..baf2dc13a34a 100644 --- a/net/core/dev.c +++ b/net/core/dev.c | |||
@@ -3461,10 +3461,10 @@ void __dev_set_rx_mode(struct net_device *dev) | |||
3461 | /* Unicast addresses changes may only happen under the rtnl, | 3461 | /* Unicast addresses changes may only happen under the rtnl, |
3462 | * therefore calling __dev_set_promiscuity here is safe. | 3462 | * therefore calling __dev_set_promiscuity here is safe. |
3463 | */ | 3463 | */ |
3464 | if (dev->uc_count > 0 && !dev->uc_promisc) { | 3464 | if (dev->uc.count > 0 && !dev->uc_promisc) { |
3465 | __dev_set_promiscuity(dev, 1); | 3465 | __dev_set_promiscuity(dev, 1); |
3466 | dev->uc_promisc = 1; | 3466 | dev->uc_promisc = 1; |
3467 | } else if (dev->uc_count == 0 && dev->uc_promisc) { | 3467 | } else if (dev->uc.count == 0 && dev->uc_promisc) { |
3468 | __dev_set_promiscuity(dev, -1); | 3468 | __dev_set_promiscuity(dev, -1); |
3469 | dev->uc_promisc = 0; | 3469 | dev->uc_promisc = 0; |
3470 | } | 3470 | } |
@@ -3483,9 +3483,8 @@ void dev_set_rx_mode(struct net_device *dev) | |||
3483 | 3483 | ||
3484 | /* hw addresses list handling functions */ | 3484 | /* hw addresses list handling functions */ |
3485 | 3485 | ||
3486 | static int __hw_addr_add(struct list_head *list, int *delta, | 3486 | static int __hw_addr_add(struct netdev_hw_addr_list *list, unsigned char *addr, |
3487 | unsigned char *addr, int addr_len, | 3487 | int addr_len, unsigned char addr_type) |
3488 | unsigned char addr_type) | ||
3489 | { | 3488 | { |
3490 | struct netdev_hw_addr *ha; | 3489 | struct netdev_hw_addr *ha; |
3491 | int alloc_size; | 3490 | int alloc_size; |
@@ -3493,7 +3492,7 @@ static int __hw_addr_add(struct list_head *list, int *delta, | |||
3493 | if (addr_len > MAX_ADDR_LEN) | 3492 | if (addr_len > MAX_ADDR_LEN) |
3494 | return -EINVAL; | 3493 | return -EINVAL; |
3495 | 3494 | ||
3496 | list_for_each_entry(ha, list, list) { | 3495 | list_for_each_entry(ha, &list->list, list) { |
3497 | if (!memcmp(ha->addr, addr, addr_len) && | 3496 | if (!memcmp(ha->addr, addr, addr_len) && |
3498 | ha->type == addr_type) { | 3497 | ha->type == addr_type) { |
3499 | ha->refcount++; | 3498 | ha->refcount++; |
@@ -3512,9 +3511,8 @@ static int __hw_addr_add(struct list_head *list, int *delta, | |||
3512 | ha->type = addr_type; | 3511 | ha->type = addr_type; |
3513 | ha->refcount = 1; | 3512 | ha->refcount = 1; |
3514 | ha->synced = false; | 3513 | ha->synced = false; |
3515 | list_add_tail_rcu(&ha->list, list); | 3514 | list_add_tail_rcu(&ha->list, &list->list); |
3516 | if (delta) | 3515 | list->count++; |
3517 | (*delta)++; | ||
3518 | return 0; | 3516 | return 0; |
3519 | } | 3517 | } |
3520 | 3518 | ||
@@ -3526,120 +3524,121 @@ static void ha_rcu_free(struct rcu_head *head) | |||
3526 | kfree(ha); | 3524 | kfree(ha); |
3527 | } | 3525 | } |
3528 | 3526 | ||
3529 | static int __hw_addr_del(struct list_head *list, int *delta, | 3527 | static int __hw_addr_del(struct netdev_hw_addr_list *list, unsigned char *addr, |
3530 | unsigned char *addr, int addr_len, | 3528 | int addr_len, unsigned char addr_type) |
3531 | unsigned char addr_type) | ||
3532 | { | 3529 | { |
3533 | struct netdev_hw_addr *ha; | 3530 | struct netdev_hw_addr *ha; |
3534 | 3531 | ||
3535 | list_for_each_entry(ha, list, list) { | 3532 | list_for_each_entry(ha, &list->list, list) { |
3536 | if (!memcmp(ha->addr, addr, addr_len) && | 3533 | if (!memcmp(ha->addr, addr, addr_len) && |
3537 | (ha->type == addr_type || !addr_type)) { | 3534 | (ha->type == addr_type || !addr_type)) { |
3538 | if (--ha->refcount) | 3535 | if (--ha->refcount) |
3539 | return 0; | 3536 | return 0; |
3540 | list_del_rcu(&ha->list); | 3537 | list_del_rcu(&ha->list); |
3541 | call_rcu(&ha->rcu_head, ha_rcu_free); | 3538 | call_rcu(&ha->rcu_head, ha_rcu_free); |
3542 | if (delta) | 3539 | list->count--; |
3543 | (*delta)--; | ||
3544 | return 0; | 3540 | return 0; |
3545 | } | 3541 | } |
3546 | } | 3542 | } |
3547 | return -ENOENT; | 3543 | return -ENOENT; |
3548 | } | 3544 | } |
3549 | 3545 | ||
3550 | static int __hw_addr_add_multiple(struct list_head *to_list, int *to_delta, | 3546 | static int __hw_addr_add_multiple(struct netdev_hw_addr_list *to_list, |
3551 | struct list_head *from_list, int addr_len, | 3547 | struct netdev_hw_addr_list *from_list, |
3548 | int addr_len, | ||
3552 | unsigned char addr_type) | 3549 | unsigned char addr_type) |
3553 | { | 3550 | { |
3554 | int err; | 3551 | int err; |
3555 | struct netdev_hw_addr *ha, *ha2; | 3552 | struct netdev_hw_addr *ha, *ha2; |
3556 | unsigned char type; | 3553 | unsigned char type; |
3557 | 3554 | ||
3558 | list_for_each_entry(ha, from_list, list) { | 3555 | list_for_each_entry(ha, &from_list->list, list) { |
3559 | type = addr_type ? addr_type : ha->type; | 3556 | type = addr_type ? addr_type : ha->type; |
3560 | err = __hw_addr_add(to_list, to_delta, ha->addr, | 3557 | err = __hw_addr_add(to_list, ha->addr, addr_len, type); |
3561 | addr_len, type); | ||
3562 | if (err) | 3558 | if (err) |
3563 | goto unroll; | 3559 | goto unroll; |
3564 | } | 3560 | } |
3565 | return 0; | 3561 | return 0; |
3566 | 3562 | ||
3567 | unroll: | 3563 | unroll: |
3568 | list_for_each_entry(ha2, from_list, list) { | 3564 | list_for_each_entry(ha2, &from_list->list, list) { |
3569 | if (ha2 == ha) | 3565 | if (ha2 == ha) |
3570 | break; | 3566 | break; |
3571 | type = addr_type ? addr_type : ha2->type; | 3567 | type = addr_type ? addr_type : ha2->type; |
3572 | __hw_addr_del(to_list, to_delta, ha2->addr, | 3568 | __hw_addr_del(to_list, ha2->addr, addr_len, type); |
3573 | addr_len, type); | ||
3574 | } | 3569 | } |
3575 | return err; | 3570 | return err; |
3576 | } | 3571 | } |
3577 | 3572 | ||
3578 | static void __hw_addr_del_multiple(struct list_head *to_list, int *to_delta, | 3573 | static void __hw_addr_del_multiple(struct netdev_hw_addr_list *to_list, |
3579 | struct list_head *from_list, int addr_len, | 3574 | struct netdev_hw_addr_list *from_list, |
3575 | int addr_len, | ||
3580 | unsigned char addr_type) | 3576 | unsigned char addr_type) |
3581 | { | 3577 | { |
3582 | struct netdev_hw_addr *ha; | 3578 | struct netdev_hw_addr *ha; |
3583 | unsigned char type; | 3579 | unsigned char type; |
3584 | 3580 | ||
3585 | list_for_each_entry(ha, from_list, list) { | 3581 | list_for_each_entry(ha, &from_list->list, list) { |
3586 | type = addr_type ? addr_type : ha->type; | 3582 | type = addr_type ? addr_type : ha->type; |
3587 | __hw_addr_del(to_list, to_delta, ha->addr, | 3583 | __hw_addr_del(to_list, ha->addr, addr_len, addr_type); |
3588 | addr_len, addr_type); | ||
3589 | } | 3584 | } |
3590 | } | 3585 | } |
3591 | 3586 | ||
3592 | static int __hw_addr_sync(struct list_head *to_list, int *to_delta, | 3587 | static int __hw_addr_sync(struct netdev_hw_addr_list *to_list, |
3593 | struct list_head *from_list, int *from_delta, | 3588 | struct netdev_hw_addr_list *from_list, |
3594 | int addr_len) | 3589 | int addr_len) |
3595 | { | 3590 | { |
3596 | int err = 0; | 3591 | int err = 0; |
3597 | struct netdev_hw_addr *ha, *tmp; | 3592 | struct netdev_hw_addr *ha, *tmp; |
3598 | 3593 | ||
3599 | list_for_each_entry_safe(ha, tmp, from_list, list) { | 3594 | list_for_each_entry_safe(ha, tmp, &from_list->list, list) { |
3600 | if (!ha->synced) { | 3595 | if (!ha->synced) { |
3601 | err = __hw_addr_add(to_list, to_delta, ha->addr, | 3596 | err = __hw_addr_add(to_list, ha->addr, |
3602 | addr_len, ha->type); | 3597 | addr_len, ha->type); |
3603 | if (err) | 3598 | if (err) |
3604 | break; | 3599 | break; |
3605 | ha->synced = true; | 3600 | ha->synced = true; |
3606 | ha->refcount++; | 3601 | ha->refcount++; |
3607 | } else if (ha->refcount == 1) { | 3602 | } else if (ha->refcount == 1) { |
3608 | __hw_addr_del(to_list, to_delta, ha->addr, | 3603 | __hw_addr_del(to_list, ha->addr, addr_len, ha->type); |
3609 | addr_len, ha->type); | 3604 | __hw_addr_del(from_list, ha->addr, addr_len, ha->type); |
3610 | __hw_addr_del(from_list, from_delta, ha->addr, | ||
3611 | addr_len, ha->type); | ||
3612 | } | 3605 | } |
3613 | } | 3606 | } |
3614 | return err; | 3607 | return err; |
3615 | } | 3608 | } |
3616 | 3609 | ||
3617 | static void __hw_addr_unsync(struct list_head *to_list, int *to_delta, | 3610 | static void __hw_addr_unsync(struct netdev_hw_addr_list *to_list, |
3618 | struct list_head *from_list, int *from_delta, | 3611 | struct netdev_hw_addr_list *from_list, |
3619 | int addr_len) | 3612 | int addr_len) |
3620 | { | 3613 | { |
3621 | struct netdev_hw_addr *ha, *tmp; | 3614 | struct netdev_hw_addr *ha, *tmp; |
3622 | 3615 | ||
3623 | list_for_each_entry_safe(ha, tmp, from_list, list) { | 3616 | list_for_each_entry_safe(ha, tmp, &from_list->list, list) { |
3624 | if (ha->synced) { | 3617 | if (ha->synced) { |
3625 | __hw_addr_del(to_list, to_delta, ha->addr, | 3618 | __hw_addr_del(to_list, ha->addr, |
3626 | addr_len, ha->type); | 3619 | addr_len, ha->type); |
3627 | ha->synced = false; | 3620 | ha->synced = false; |
3628 | __hw_addr_del(from_list, from_delta, ha->addr, | 3621 | __hw_addr_del(from_list, ha->addr, |
3629 | addr_len, ha->type); | 3622 | addr_len, ha->type); |
3630 | } | 3623 | } |
3631 | } | 3624 | } |
3632 | } | 3625 | } |
3633 | 3626 | ||
3634 | 3627 | static void __hw_addr_flush(struct netdev_hw_addr_list *list) | |
3635 | static void __hw_addr_flush(struct list_head *list) | ||
3636 | { | 3628 | { |
3637 | struct netdev_hw_addr *ha, *tmp; | 3629 | struct netdev_hw_addr *ha, *tmp; |
3638 | 3630 | ||
3639 | list_for_each_entry_safe(ha, tmp, list, list) { | 3631 | list_for_each_entry_safe(ha, tmp, &list->list, list) { |
3640 | list_del_rcu(&ha->list); | 3632 | list_del_rcu(&ha->list); |
3641 | call_rcu(&ha->rcu_head, ha_rcu_free); | 3633 | call_rcu(&ha->rcu_head, ha_rcu_free); |
3642 | } | 3634 | } |
3635 | list->count = 0; | ||
3636 | } | ||
3637 | |||
3638 | static void __hw_addr_init(struct netdev_hw_addr_list *list) | ||
3639 | { | ||
3640 | INIT_LIST_HEAD(&list->list); | ||
3641 | list->count = 0; | ||
3643 | } | 3642 | } |
3644 | 3643 | ||
3645 | /* Device addresses handling functions */ | 3644 | /* Device addresses handling functions */ |
@@ -3648,7 +3647,7 @@ static void dev_addr_flush(struct net_device *dev) | |||
3648 | { | 3647 | { |
3649 | /* rtnl_mutex must be held here */ | 3648 | /* rtnl_mutex must be held here */ |
3650 | 3649 | ||
3651 | __hw_addr_flush(&dev->dev_addr_list); | 3650 | __hw_addr_flush(&dev->dev_addrs); |
3652 | dev->dev_addr = NULL; | 3651 | dev->dev_addr = NULL; |
3653 | } | 3652 | } |
3654 | 3653 | ||
@@ -3660,16 +3659,16 @@ static int dev_addr_init(struct net_device *dev) | |||
3660 | 3659 | ||
3661 | /* rtnl_mutex must be held here */ | 3660 | /* rtnl_mutex must be held here */ |
3662 | 3661 | ||
3663 | INIT_LIST_HEAD(&dev->dev_addr_list); | 3662 | __hw_addr_init(&dev->dev_addrs); |
3664 | memset(addr, 0, sizeof(addr)); | 3663 | memset(addr, 0, sizeof(addr)); |
3665 | err = __hw_addr_add(&dev->dev_addr_list, NULL, addr, sizeof(addr), | 3664 | err = __hw_addr_add(&dev->dev_addrs, addr, sizeof(addr), |
3666 | NETDEV_HW_ADDR_T_LAN); | 3665 | NETDEV_HW_ADDR_T_LAN); |
3667 | if (!err) { | 3666 | if (!err) { |
3668 | /* | 3667 | /* |
3669 | * Get the first (previously created) address from the list | 3668 | * Get the first (previously created) address from the list |
3670 | * and set dev_addr pointer to this location. | 3669 | * and set dev_addr pointer to this location. |
3671 | */ | 3670 | */ |
3672 | ha = list_first_entry(&dev->dev_addr_list, | 3671 | ha = list_first_entry(&dev->dev_addrs.list, |
3673 | struct netdev_hw_addr, list); | 3672 | struct netdev_hw_addr, list); |
3674 | dev->dev_addr = ha->addr; | 3673 | dev->dev_addr = ha->addr; |
3675 | } | 3674 | } |
@@ -3694,8 +3693,7 @@ int dev_addr_add(struct net_device *dev, unsigned char *addr, | |||
3694 | 3693 | ||
3695 | ASSERT_RTNL(); | 3694 | ASSERT_RTNL(); |
3696 | 3695 | ||
3697 | err = __hw_addr_add(&dev->dev_addr_list, NULL, addr, dev->addr_len, | 3696 | err = __hw_addr_add(&dev->dev_addrs, addr, dev->addr_len, addr_type); |
3698 | addr_type); | ||
3699 | if (!err) | 3697 | if (!err) |
3700 | call_netdevice_notifiers(NETDEV_CHANGEADDR, dev); | 3698 | call_netdevice_notifiers(NETDEV_CHANGEADDR, dev); |
3701 | return err; | 3699 | return err; |
@@ -3725,11 +3723,12 @@ int dev_addr_del(struct net_device *dev, unsigned char *addr, | |||
3725 | * We can not remove the first address from the list because | 3723 | * We can not remove the first address from the list because |
3726 | * dev->dev_addr points to that. | 3724 | * dev->dev_addr points to that. |
3727 | */ | 3725 | */ |
3728 | ha = list_first_entry(&dev->dev_addr_list, struct netdev_hw_addr, list); | 3726 | ha = list_first_entry(&dev->dev_addrs.list, |
3727 | struct netdev_hw_addr, list); | ||
3729 | if (ha->addr == dev->dev_addr && ha->refcount == 1) | 3728 | if (ha->addr == dev->dev_addr && ha->refcount == 1) |
3730 | return -ENOENT; | 3729 | return -ENOENT; |
3731 | 3730 | ||
3732 | err = __hw_addr_del(&dev->dev_addr_list, NULL, addr, dev->addr_len, | 3731 | err = __hw_addr_del(&dev->dev_addrs, addr, dev->addr_len, |
3733 | addr_type); | 3732 | addr_type); |
3734 | if (!err) | 3733 | if (!err) |
3735 | call_netdevice_notifiers(NETDEV_CHANGEADDR, dev); | 3734 | call_netdevice_notifiers(NETDEV_CHANGEADDR, dev); |
@@ -3757,8 +3756,7 @@ int dev_addr_add_multiple(struct net_device *to_dev, | |||
3757 | 3756 | ||
3758 | if (from_dev->addr_len != to_dev->addr_len) | 3757 | if (from_dev->addr_len != to_dev->addr_len) |
3759 | return -EINVAL; | 3758 | return -EINVAL; |
3760 | err = __hw_addr_add_multiple(&to_dev->dev_addr_list, NULL, | 3759 | err = __hw_addr_add_multiple(&to_dev->dev_addrs, &from_dev->dev_addrs, |
3761 | &from_dev->dev_addr_list, | ||
3762 | to_dev->addr_len, addr_type); | 3760 | to_dev->addr_len, addr_type); |
3763 | if (!err) | 3761 | if (!err) |
3764 | call_netdevice_notifiers(NETDEV_CHANGEADDR, to_dev); | 3762 | call_netdevice_notifiers(NETDEV_CHANGEADDR, to_dev); |
@@ -3784,15 +3782,14 @@ int dev_addr_del_multiple(struct net_device *to_dev, | |||
3784 | 3782 | ||
3785 | if (from_dev->addr_len != to_dev->addr_len) | 3783 | if (from_dev->addr_len != to_dev->addr_len) |
3786 | return -EINVAL; | 3784 | return -EINVAL; |
3787 | __hw_addr_del_multiple(&to_dev->dev_addr_list, NULL, | 3785 | __hw_addr_del_multiple(&to_dev->dev_addrs, &from_dev->dev_addrs, |
3788 | &from_dev->dev_addr_list, | ||
3789 | to_dev->addr_len, addr_type); | 3786 | to_dev->addr_len, addr_type); |
3790 | call_netdevice_notifiers(NETDEV_CHANGEADDR, to_dev); | 3787 | call_netdevice_notifiers(NETDEV_CHANGEADDR, to_dev); |
3791 | return 0; | 3788 | return 0; |
3792 | } | 3789 | } |
3793 | EXPORT_SYMBOL(dev_addr_del_multiple); | 3790 | EXPORT_SYMBOL(dev_addr_del_multiple); |
3794 | 3791 | ||
3795 | /* unicast and multicast addresses handling functions */ | 3792 | /* multicast addresses handling functions */ |
3796 | 3793 | ||
3797 | int __dev_addr_delete(struct dev_addr_list **list, int *count, | 3794 | int __dev_addr_delete(struct dev_addr_list **list, int *count, |
3798 | void *addr, int alen, int glbl) | 3795 | void *addr, int alen, int glbl) |
@@ -3868,8 +3865,8 @@ int dev_unicast_delete(struct net_device *dev, void *addr) | |||
3868 | 3865 | ||
3869 | ASSERT_RTNL(); | 3866 | ASSERT_RTNL(); |
3870 | 3867 | ||
3871 | err = __hw_addr_del(&dev->uc_list, &dev->uc_count, addr, | 3868 | err = __hw_addr_del(&dev->uc, addr, dev->addr_len, |
3872 | dev->addr_len, NETDEV_HW_ADDR_T_UNICAST); | 3869 | NETDEV_HW_ADDR_T_UNICAST); |
3873 | if (!err) | 3870 | if (!err) |
3874 | __dev_set_rx_mode(dev); | 3871 | __dev_set_rx_mode(dev); |
3875 | return err; | 3872 | return err; |
@@ -3892,8 +3889,8 @@ int dev_unicast_add(struct net_device *dev, void *addr) | |||
3892 | 3889 | ||
3893 | ASSERT_RTNL(); | 3890 | ASSERT_RTNL(); |
3894 | 3891 | ||
3895 | err = __hw_addr_add(&dev->uc_list, &dev->uc_count, addr, | 3892 | err = __hw_addr_add(&dev->uc, addr, dev->addr_len, |
3896 | dev->addr_len, NETDEV_HW_ADDR_T_UNICAST); | 3893 | NETDEV_HW_ADDR_T_UNICAST); |
3897 | if (!err) | 3894 | if (!err) |
3898 | __dev_set_rx_mode(dev); | 3895 | __dev_set_rx_mode(dev); |
3899 | return err; | 3896 | return err; |
@@ -3966,8 +3963,7 @@ int dev_unicast_sync(struct net_device *to, struct net_device *from) | |||
3966 | if (to->addr_len != from->addr_len) | 3963 | if (to->addr_len != from->addr_len) |
3967 | return -EINVAL; | 3964 | return -EINVAL; |
3968 | 3965 | ||
3969 | err = __hw_addr_sync(&to->uc_list, &to->uc_count, | 3966 | err = __hw_addr_sync(&to->uc, &from->uc, to->addr_len); |
3970 | &from->uc_list, &from->uc_count, to->addr_len); | ||
3971 | if (!err) | 3967 | if (!err) |
3972 | __dev_set_rx_mode(to); | 3968 | __dev_set_rx_mode(to); |
3973 | return err; | 3969 | return err; |
@@ -3990,8 +3986,7 @@ void dev_unicast_unsync(struct net_device *to, struct net_device *from) | |||
3990 | if (to->addr_len != from->addr_len) | 3986 | if (to->addr_len != from->addr_len) |
3991 | return; | 3987 | return; |
3992 | 3988 | ||
3993 | __hw_addr_unsync(&to->uc_list, &to->uc_count, | 3989 | __hw_addr_unsync(&to->uc, &from->uc, to->addr_len); |
3994 | &from->uc_list, &from->uc_count, to->addr_len); | ||
3995 | __dev_set_rx_mode(to); | 3990 | __dev_set_rx_mode(to); |
3996 | } | 3991 | } |
3997 | EXPORT_SYMBOL(dev_unicast_unsync); | 3992 | EXPORT_SYMBOL(dev_unicast_unsync); |
@@ -4000,15 +3995,14 @@ static void dev_unicast_flush(struct net_device *dev) | |||
4000 | { | 3995 | { |
4001 | /* rtnl_mutex must be held here */ | 3996 | /* rtnl_mutex must be held here */ |
4002 | 3997 | ||
4003 | __hw_addr_flush(&dev->uc_list); | 3998 | __hw_addr_flush(&dev->uc); |
4004 | dev->uc_count = 0; | ||
4005 | } | 3999 | } |
4006 | 4000 | ||
4007 | static void dev_unicast_init(struct net_device *dev) | 4001 | static void dev_unicast_init(struct net_device *dev) |
4008 | { | 4002 | { |
4009 | /* rtnl_mutex must be held here */ | 4003 | /* rtnl_mutex must be held here */ |
4010 | 4004 | ||
4011 | INIT_LIST_HEAD(&dev->uc_list); | 4005 | __hw_addr_init(&dev->uc); |
4012 | } | 4006 | } |
4013 | 4007 | ||
4014 | 4008 | ||
diff --git a/net/core/skbuff.c b/net/core/skbuff.c index 5c93435b0347..9e0597d189b0 100644 --- a/net/core/skbuff.c +++ b/net/core/skbuff.c | |||
@@ -204,6 +204,10 @@ struct sk_buff *__alloc_skb(unsigned int size, gfp_t gfp_mask, | |||
204 | skb->end = skb->tail + size; | 204 | skb->end = skb->tail + size; |
205 | kmemcheck_annotate_bitfield(skb, flags1); | 205 | kmemcheck_annotate_bitfield(skb, flags1); |
206 | kmemcheck_annotate_bitfield(skb, flags2); | 206 | kmemcheck_annotate_bitfield(skb, flags2); |
207 | #ifdef NET_SKBUFF_DATA_USES_OFFSET | ||
208 | skb->mac_header = ~0U; | ||
209 | #endif | ||
210 | |||
207 | /* make sure we initialize shinfo sequentially */ | 211 | /* make sure we initialize shinfo sequentially */ |
208 | shinfo = skb_shinfo(skb); | 212 | shinfo = skb_shinfo(skb); |
209 | atomic_set(&shinfo->dataref, 1); | 213 | atomic_set(&shinfo->dataref, 1); |
@@ -665,7 +669,8 @@ static void copy_skb_header(struct sk_buff *new, const struct sk_buff *old) | |||
665 | /* {transport,network,mac}_header are relative to skb->head */ | 669 | /* {transport,network,mac}_header are relative to skb->head */ |
666 | new->transport_header += offset; | 670 | new->transport_header += offset; |
667 | new->network_header += offset; | 671 | new->network_header += offset; |
668 | new->mac_header += offset; | 672 | if (skb_mac_header_was_set(new)) |
673 | new->mac_header += offset; | ||
669 | #endif | 674 | #endif |
670 | skb_shinfo(new)->gso_size = skb_shinfo(old)->gso_size; | 675 | skb_shinfo(new)->gso_size = skb_shinfo(old)->gso_size; |
671 | skb_shinfo(new)->gso_segs = skb_shinfo(old)->gso_segs; | 676 | skb_shinfo(new)->gso_segs = skb_shinfo(old)->gso_segs; |
@@ -847,7 +852,8 @@ int pskb_expand_head(struct sk_buff *skb, int nhead, int ntail, | |||
847 | skb->tail += off; | 852 | skb->tail += off; |
848 | skb->transport_header += off; | 853 | skb->transport_header += off; |
849 | skb->network_header += off; | 854 | skb->network_header += off; |
850 | skb->mac_header += off; | 855 | if (skb_mac_header_was_set(skb)) |
856 | skb->mac_header += off; | ||
851 | skb->csum_start += nhead; | 857 | skb->csum_start += nhead; |
852 | skb->cloned = 0; | 858 | skb->cloned = 0; |
853 | skb->hdr_len = 0; | 859 | skb->hdr_len = 0; |
@@ -939,7 +945,8 @@ struct sk_buff *skb_copy_expand(const struct sk_buff *skb, | |||
939 | #ifdef NET_SKBUFF_DATA_USES_OFFSET | 945 | #ifdef NET_SKBUFF_DATA_USES_OFFSET |
940 | n->transport_header += off; | 946 | n->transport_header += off; |
941 | n->network_header += off; | 947 | n->network_header += off; |
942 | n->mac_header += off; | 948 | if (skb_mac_header_was_set(skb)) |
949 | n->mac_header += off; | ||
943 | #endif | 950 | #endif |
944 | 951 | ||
945 | return n; | 952 | return n; |
diff --git a/net/decnet/af_decnet.c b/net/decnet/af_decnet.c index a5e3a593e472..d351b8db0df5 100644 --- a/net/decnet/af_decnet.c +++ b/net/decnet/af_decnet.c | |||
@@ -1240,7 +1240,7 @@ static int dn_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg) | |||
1240 | return val; | 1240 | return val; |
1241 | 1241 | ||
1242 | case TIOCOUTQ: | 1242 | case TIOCOUTQ: |
1243 | amount = sk->sk_sndbuf - atomic_read(&sk->sk_wmem_alloc); | 1243 | amount = sk->sk_sndbuf - sk_wmem_alloc_get(sk); |
1244 | if (amount < 0) | 1244 | if (amount < 0) |
1245 | amount = 0; | 1245 | amount = 0; |
1246 | err = put_user(amount, (int __user *)arg); | 1246 | err = put_user(amount, (int __user *)arg); |
diff --git a/net/econet/af_econet.c b/net/econet/af_econet.c index 8121bf0029e3..2e1f836d4240 100644 --- a/net/econet/af_econet.c +++ b/net/econet/af_econet.c | |||
@@ -540,8 +540,7 @@ static void econet_destroy_timer(unsigned long data) | |||
540 | { | 540 | { |
541 | struct sock *sk=(struct sock *)data; | 541 | struct sock *sk=(struct sock *)data; |
542 | 542 | ||
543 | if (!atomic_read(&sk->sk_wmem_alloc) && | 543 | if (!sk_has_allocations(sk)) { |
544 | !atomic_read(&sk->sk_rmem_alloc)) { | ||
545 | sk_free(sk); | 544 | sk_free(sk); |
546 | return; | 545 | return; |
547 | } | 546 | } |
@@ -579,8 +578,7 @@ static int econet_release(struct socket *sock) | |||
579 | 578 | ||
580 | skb_queue_purge(&sk->sk_receive_queue); | 579 | skb_queue_purge(&sk->sk_receive_queue); |
581 | 580 | ||
582 | if (atomic_read(&sk->sk_rmem_alloc) || | 581 | if (sk_has_allocations(sk)) { |
583 | atomic_read(&sk->sk_wmem_alloc)) { | ||
584 | sk->sk_timer.data = (unsigned long)sk; | 582 | sk->sk_timer.data = (unsigned long)sk; |
585 | sk->sk_timer.expires = jiffies + HZ; | 583 | sk->sk_timer.expires = jiffies + HZ; |
586 | sk->sk_timer.function = econet_destroy_timer; | 584 | sk->sk_timer.function = econet_destroy_timer; |
diff --git a/net/ieee802154/dgram.c b/net/ieee802154/dgram.c index 1779677aed46..14d39840dd62 100644 --- a/net/ieee802154/dgram.c +++ b/net/ieee802154/dgram.c | |||
@@ -126,7 +126,8 @@ static int dgram_ioctl(struct sock *sk, int cmd, unsigned long arg) | |||
126 | switch (cmd) { | 126 | switch (cmd) { |
127 | case SIOCOUTQ: | 127 | case SIOCOUTQ: |
128 | { | 128 | { |
129 | int amount = atomic_read(&sk->sk_wmem_alloc); | 129 | int amount = sk_wmem_alloc_get(sk); |
130 | |||
130 | return put_user(amount, (int __user *)arg); | 131 | return put_user(amount, (int __user *)arg); |
131 | } | 132 | } |
132 | 133 | ||
diff --git a/net/ipv4/fib_trie.c b/net/ipv4/fib_trie.c index d1a39b1277d6..012cf5a68581 100644 --- a/net/ipv4/fib_trie.c +++ b/net/ipv4/fib_trie.c | |||
@@ -391,13 +391,8 @@ static inline void tnode_free(struct tnode *tn) | |||
391 | static void tnode_free_safe(struct tnode *tn) | 391 | static void tnode_free_safe(struct tnode *tn) |
392 | { | 392 | { |
393 | BUG_ON(IS_LEAF(tn)); | 393 | BUG_ON(IS_LEAF(tn)); |
394 | 394 | tn->tnode_free = tnode_free_head; | |
395 | if (node_parent((struct node *) tn)) { | 395 | tnode_free_head = tn; |
396 | tn->tnode_free = tnode_free_head; | ||
397 | tnode_free_head = tn; | ||
398 | } else { | ||
399 | tnode_free(tn); | ||
400 | } | ||
401 | } | 396 | } |
402 | 397 | ||
403 | static void tnode_free_flush(void) | 398 | static void tnode_free_flush(void) |
@@ -1009,7 +1004,7 @@ fib_find_node(struct trie *t, u32 key) | |||
1009 | return NULL; | 1004 | return NULL; |
1010 | } | 1005 | } |
1011 | 1006 | ||
1012 | static struct node *trie_rebalance(struct trie *t, struct tnode *tn) | 1007 | static void trie_rebalance(struct trie *t, struct tnode *tn) |
1013 | { | 1008 | { |
1014 | int wasfull; | 1009 | int wasfull; |
1015 | t_key cindex, key; | 1010 | t_key cindex, key; |
@@ -1033,12 +1028,13 @@ static struct node *trie_rebalance(struct trie *t, struct tnode *tn) | |||
1033 | } | 1028 | } |
1034 | 1029 | ||
1035 | /* Handle last (top) tnode */ | 1030 | /* Handle last (top) tnode */ |
1036 | if (IS_TNODE(tn)) { | 1031 | if (IS_TNODE(tn)) |
1037 | tn = (struct tnode *)resize(t, (struct tnode *)tn); | 1032 | tn = (struct tnode *)resize(t, (struct tnode *)tn); |
1038 | tnode_free_flush(); | ||
1039 | } | ||
1040 | 1033 | ||
1041 | return (struct node *)tn; | 1034 | rcu_assign_pointer(t->trie, (struct node *)tn); |
1035 | tnode_free_flush(); | ||
1036 | |||
1037 | return; | ||
1042 | } | 1038 | } |
1043 | 1039 | ||
1044 | /* only used from updater-side */ | 1040 | /* only used from updater-side */ |
@@ -1186,7 +1182,7 @@ static struct list_head *fib_insert_node(struct trie *t, u32 key, int plen) | |||
1186 | 1182 | ||
1187 | /* Rebalance the trie */ | 1183 | /* Rebalance the trie */ |
1188 | 1184 | ||
1189 | rcu_assign_pointer(t->trie, trie_rebalance(t, tp)); | 1185 | trie_rebalance(t, tp); |
1190 | done: | 1186 | done: |
1191 | return fa_head; | 1187 | return fa_head; |
1192 | } | 1188 | } |
@@ -1605,7 +1601,7 @@ static void trie_leaf_remove(struct trie *t, struct leaf *l) | |||
1605 | if (tp) { | 1601 | if (tp) { |
1606 | t_key cindex = tkey_extract_bits(l->key, tp->pos, tp->bits); | 1602 | t_key cindex = tkey_extract_bits(l->key, tp->pos, tp->bits); |
1607 | put_child(t, (struct tnode *)tp, cindex, NULL); | 1603 | put_child(t, (struct tnode *)tp, cindex, NULL); |
1608 | rcu_assign_pointer(t->trie, trie_rebalance(t, tp)); | 1604 | trie_rebalance(t, tp); |
1609 | } else | 1605 | } else |
1610 | rcu_assign_pointer(t->trie, NULL); | 1606 | rcu_assign_pointer(t->trie, NULL); |
1611 | 1607 | ||
diff --git a/net/ipv4/inet_diag.c b/net/ipv4/inet_diag.c index b0b273503e2a..a706a47f4dbb 100644 --- a/net/ipv4/inet_diag.c +++ b/net/ipv4/inet_diag.c | |||
@@ -156,10 +156,10 @@ static int inet_csk_diag_fill(struct sock *sk, | |||
156 | r->idiag_inode = sock_i_ino(sk); | 156 | r->idiag_inode = sock_i_ino(sk); |
157 | 157 | ||
158 | if (minfo) { | 158 | if (minfo) { |
159 | minfo->idiag_rmem = atomic_read(&sk->sk_rmem_alloc); | 159 | minfo->idiag_rmem = sk_rmem_alloc_get(sk); |
160 | minfo->idiag_wmem = sk->sk_wmem_queued; | 160 | minfo->idiag_wmem = sk->sk_wmem_queued; |
161 | minfo->idiag_fmem = sk->sk_forward_alloc; | 161 | minfo->idiag_fmem = sk->sk_forward_alloc; |
162 | minfo->idiag_tmem = atomic_read(&sk->sk_wmem_alloc); | 162 | minfo->idiag_tmem = sk_wmem_alloc_get(sk); |
163 | } | 163 | } |
164 | 164 | ||
165 | handler->idiag_get_info(sk, r, info); | 165 | handler->idiag_get_info(sk, r, info); |
diff --git a/net/ipv4/raw.c b/net/ipv4/raw.c index 3dc9171a272f..2979f14bb188 100644 --- a/net/ipv4/raw.c +++ b/net/ipv4/raw.c | |||
@@ -799,7 +799,8 @@ static int raw_ioctl(struct sock *sk, int cmd, unsigned long arg) | |||
799 | { | 799 | { |
800 | switch (cmd) { | 800 | switch (cmd) { |
801 | case SIOCOUTQ: { | 801 | case SIOCOUTQ: { |
802 | int amount = atomic_read(&sk->sk_wmem_alloc); | 802 | int amount = sk_wmem_alloc_get(sk); |
803 | |||
803 | return put_user(amount, (int __user *)arg); | 804 | return put_user(amount, (int __user *)arg); |
804 | } | 805 | } |
805 | case SIOCINQ: { | 806 | case SIOCINQ: { |
@@ -935,8 +936,8 @@ static void raw_sock_seq_show(struct seq_file *seq, struct sock *sp, int i) | |||
935 | seq_printf(seq, "%4d: %08X:%04X %08X:%04X" | 936 | seq_printf(seq, "%4d: %08X:%04X %08X:%04X" |
936 | " %02X %08X:%08X %02X:%08lX %08X %5d %8d %lu %d %p %d\n", | 937 | " %02X %08X:%08X %02X:%08lX %08X %5d %8d %lu %d %p %d\n", |
937 | i, src, srcp, dest, destp, sp->sk_state, | 938 | i, src, srcp, dest, destp, sp->sk_state, |
938 | atomic_read(&sp->sk_wmem_alloc), | 939 | sk_wmem_alloc_get(sp), |
939 | atomic_read(&sp->sk_rmem_alloc), | 940 | sk_rmem_alloc_get(sp), |
940 | 0, 0L, 0, sock_i_uid(sp), 0, sock_i_ino(sp), | 941 | 0, 0L, 0, sock_i_uid(sp), 0, sock_i_ino(sp), |
941 | atomic_read(&sp->sk_refcnt), sp, atomic_read(&sp->sk_drops)); | 942 | atomic_read(&sp->sk_refcnt), sp, atomic_read(&sp->sk_drops)); |
942 | } | 943 | } |
diff --git a/net/ipv4/udp.c b/net/ipv4/udp.c index 8f4158d7c9a6..80e3812837ad 100644 --- a/net/ipv4/udp.c +++ b/net/ipv4/udp.c | |||
@@ -840,7 +840,8 @@ int udp_ioctl(struct sock *sk, int cmd, unsigned long arg) | |||
840 | switch (cmd) { | 840 | switch (cmd) { |
841 | case SIOCOUTQ: | 841 | case SIOCOUTQ: |
842 | { | 842 | { |
843 | int amount = atomic_read(&sk->sk_wmem_alloc); | 843 | int amount = sk_wmem_alloc_get(sk); |
844 | |||
844 | return put_user(amount, (int __user *)arg); | 845 | return put_user(amount, (int __user *)arg); |
845 | } | 846 | } |
846 | 847 | ||
@@ -1721,8 +1722,8 @@ static void udp4_format_sock(struct sock *sp, struct seq_file *f, | |||
1721 | seq_printf(f, "%4d: %08X:%04X %08X:%04X" | 1722 | seq_printf(f, "%4d: %08X:%04X %08X:%04X" |
1722 | " %02X %08X:%08X %02X:%08lX %08X %5d %8d %lu %d %p %d%n", | 1723 | " %02X %08X:%08X %02X:%08lX %08X %5d %8d %lu %d %p %d%n", |
1723 | bucket, src, srcp, dest, destp, sp->sk_state, | 1724 | bucket, src, srcp, dest, destp, sp->sk_state, |
1724 | atomic_read(&sp->sk_wmem_alloc), | 1725 | sk_wmem_alloc_get(sp), |
1725 | atomic_read(&sp->sk_rmem_alloc), | 1726 | sk_rmem_alloc_get(sp), |
1726 | 0, 0L, 0, sock_i_uid(sp), 0, sock_i_ino(sp), | 1727 | 0, 0L, 0, sock_i_uid(sp), 0, sock_i_ino(sp), |
1727 | atomic_read(&sp->sk_refcnt), sp, | 1728 | atomic_read(&sp->sk_refcnt), sp, |
1728 | atomic_read(&sp->sk_drops), len); | 1729 | atomic_read(&sp->sk_drops), len); |
diff --git a/net/ipv6/raw.c b/net/ipv6/raw.c index 36a090d87a3d..8b0b6f948063 100644 --- a/net/ipv6/raw.c +++ b/net/ipv6/raw.c | |||
@@ -1130,7 +1130,8 @@ static int rawv6_ioctl(struct sock *sk, int cmd, unsigned long arg) | |||
1130 | switch(cmd) { | 1130 | switch(cmd) { |
1131 | case SIOCOUTQ: | 1131 | case SIOCOUTQ: |
1132 | { | 1132 | { |
1133 | int amount = atomic_read(&sk->sk_wmem_alloc); | 1133 | int amount = sk_wmem_alloc_get(sk); |
1134 | |||
1134 | return put_user(amount, (int __user *)arg); | 1135 | return put_user(amount, (int __user *)arg); |
1135 | } | 1136 | } |
1136 | case SIOCINQ: | 1137 | case SIOCINQ: |
@@ -1236,8 +1237,8 @@ static void raw6_sock_seq_show(struct seq_file *seq, struct sock *sp, int i) | |||
1236 | dest->s6_addr32[0], dest->s6_addr32[1], | 1237 | dest->s6_addr32[0], dest->s6_addr32[1], |
1237 | dest->s6_addr32[2], dest->s6_addr32[3], destp, | 1238 | dest->s6_addr32[2], dest->s6_addr32[3], destp, |
1238 | sp->sk_state, | 1239 | sp->sk_state, |
1239 | atomic_read(&sp->sk_wmem_alloc), | 1240 | sk_wmem_alloc_get(sp), |
1240 | atomic_read(&sp->sk_rmem_alloc), | 1241 | sk_rmem_alloc_get(sp), |
1241 | 0, 0L, 0, | 1242 | 0, 0L, 0, |
1242 | sock_i_uid(sp), 0, | 1243 | sock_i_uid(sp), 0, |
1243 | sock_i_ino(sp), | 1244 | sock_i_ino(sp), |
diff --git a/net/ipv6/udp.c b/net/ipv6/udp.c index fc333d854728..023beda6b224 100644 --- a/net/ipv6/udp.c +++ b/net/ipv6/udp.c | |||
@@ -1061,8 +1061,8 @@ static void udp6_sock_seq_show(struct seq_file *seq, struct sock *sp, int bucket | |||
1061 | dest->s6_addr32[0], dest->s6_addr32[1], | 1061 | dest->s6_addr32[0], dest->s6_addr32[1], |
1062 | dest->s6_addr32[2], dest->s6_addr32[3], destp, | 1062 | dest->s6_addr32[2], dest->s6_addr32[3], destp, |
1063 | sp->sk_state, | 1063 | sp->sk_state, |
1064 | atomic_read(&sp->sk_wmem_alloc), | 1064 | sk_wmem_alloc_get(sp), |
1065 | atomic_read(&sp->sk_rmem_alloc), | 1065 | sk_rmem_alloc_get(sp), |
1066 | 0, 0L, 0, | 1066 | 0, 0L, 0, |
1067 | sock_i_uid(sp), 0, | 1067 | sock_i_uid(sp), 0, |
1068 | sock_i_ino(sp), | 1068 | sock_i_ino(sp), |
diff --git a/net/ipx/af_ipx.c b/net/ipx/af_ipx.c index 1627050e29fd..417b0e309495 100644 --- a/net/ipx/af_ipx.c +++ b/net/ipx/af_ipx.c | |||
@@ -1835,7 +1835,7 @@ static int ipx_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg) | |||
1835 | 1835 | ||
1836 | switch (cmd) { | 1836 | switch (cmd) { |
1837 | case TIOCOUTQ: | 1837 | case TIOCOUTQ: |
1838 | amount = sk->sk_sndbuf - atomic_read(&sk->sk_wmem_alloc); | 1838 | amount = sk->sk_sndbuf - sk_wmem_alloc_get(sk); |
1839 | if (amount < 0) | 1839 | if (amount < 0) |
1840 | amount = 0; | 1840 | amount = 0; |
1841 | rc = put_user(amount, (int __user *)argp); | 1841 | rc = put_user(amount, (int __user *)argp); |
diff --git a/net/ipx/ipx_proc.c b/net/ipx/ipx_proc.c index 5ed97ad0e2e3..576178482f89 100644 --- a/net/ipx/ipx_proc.c +++ b/net/ipx/ipx_proc.c | |||
@@ -280,8 +280,8 @@ static int ipx_seq_socket_show(struct seq_file *seq, void *v) | |||
280 | } | 280 | } |
281 | 281 | ||
282 | seq_printf(seq, "%08X %08X %02X %03d\n", | 282 | seq_printf(seq, "%08X %08X %02X %03d\n", |
283 | atomic_read(&s->sk_wmem_alloc), | 283 | sk_wmem_alloc_get(s), |
284 | atomic_read(&s->sk_rmem_alloc), | 284 | sk_rmem_alloc_get(s), |
285 | s->sk_state, SOCK_INODE(s->sk_socket)->i_uid); | 285 | s->sk_state, SOCK_INODE(s->sk_socket)->i_uid); |
286 | out: | 286 | out: |
287 | return 0; | 287 | return 0; |
diff --git a/net/irda/af_irda.c b/net/irda/af_irda.c index 3eb5bcc75f99..5922febe25c4 100644 --- a/net/irda/af_irda.c +++ b/net/irda/af_irda.c | |||
@@ -1762,7 +1762,8 @@ static int irda_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg) | |||
1762 | switch (cmd) { | 1762 | switch (cmd) { |
1763 | case TIOCOUTQ: { | 1763 | case TIOCOUTQ: { |
1764 | long amount; | 1764 | long amount; |
1765 | amount = sk->sk_sndbuf - atomic_read(&sk->sk_wmem_alloc); | 1765 | |
1766 | amount = sk->sk_sndbuf - sk_wmem_alloc_get(sk); | ||
1766 | if (amount < 0) | 1767 | if (amount < 0) |
1767 | amount = 0; | 1768 | amount = 0; |
1768 | if (put_user(amount, (unsigned int __user *)arg)) | 1769 | if (put_user(amount, (unsigned int __user *)arg)) |
diff --git a/net/key/af_key.c b/net/key/af_key.c index 643c1be2d02e..dba9abd27f90 100644 --- a/net/key/af_key.c +++ b/net/key/af_key.c | |||
@@ -3662,8 +3662,8 @@ static int pfkey_seq_show(struct seq_file *f, void *v) | |||
3662 | seq_printf(f ,"%p %-6d %-6u %-6u %-6u %-6lu\n", | 3662 | seq_printf(f ,"%p %-6d %-6u %-6u %-6u %-6lu\n", |
3663 | s, | 3663 | s, |
3664 | atomic_read(&s->sk_refcnt), | 3664 | atomic_read(&s->sk_refcnt), |
3665 | atomic_read(&s->sk_rmem_alloc), | 3665 | sk_rmem_alloc_get(s), |
3666 | atomic_read(&s->sk_wmem_alloc), | 3666 | sk_wmem_alloc_get(s), |
3667 | sock_i_uid(s), | 3667 | sock_i_uid(s), |
3668 | sock_i_ino(s) | 3668 | sock_i_ino(s) |
3669 | ); | 3669 | ); |
diff --git a/net/llc/llc_proc.c b/net/llc/llc_proc.c index d208b3396d94..f97be471fe2e 100644 --- a/net/llc/llc_proc.c +++ b/net/llc/llc_proc.c | |||
@@ -134,8 +134,8 @@ static int llc_seq_socket_show(struct seq_file *seq, void *v) | |||
134 | seq_printf(seq, "@%02X ", llc->sap->laddr.lsap); | 134 | seq_printf(seq, "@%02X ", llc->sap->laddr.lsap); |
135 | llc_ui_format_mac(seq, llc->daddr.mac); | 135 | llc_ui_format_mac(seq, llc->daddr.mac); |
136 | seq_printf(seq, "@%02X %8d %8d %2d %3d %4d\n", llc->daddr.lsap, | 136 | seq_printf(seq, "@%02X %8d %8d %2d %3d %4d\n", llc->daddr.lsap, |
137 | atomic_read(&sk->sk_wmem_alloc), | 137 | sk_wmem_alloc_get(sk), |
138 | atomic_read(&sk->sk_rmem_alloc) - llc->copied_seq, | 138 | sk_rmem_alloc_get(sk) - llc->copied_seq, |
139 | sk->sk_state, | 139 | sk->sk_state, |
140 | sk->sk_socket ? SOCK_INODE(sk->sk_socket)->i_uid : -1, | 140 | sk->sk_socket ? SOCK_INODE(sk->sk_socket)->i_uid : -1, |
141 | llc->link); | 141 | llc->link); |
diff --git a/net/mac80211/debugfs.c b/net/mac80211/debugfs.c index 11c72311f35b..6c439cd5ccea 100644 --- a/net/mac80211/debugfs.c +++ b/net/mac80211/debugfs.c | |||
@@ -163,6 +163,29 @@ static const struct file_operations noack_ops = { | |||
163 | .open = mac80211_open_file_generic | 163 | .open = mac80211_open_file_generic |
164 | }; | 164 | }; |
165 | 165 | ||
166 | static ssize_t queues_read(struct file *file, char __user *user_buf, | ||
167 | size_t count, loff_t *ppos) | ||
168 | { | ||
169 | struct ieee80211_local *local = file->private_data; | ||
170 | unsigned long flags; | ||
171 | char buf[IEEE80211_MAX_QUEUES * 20]; | ||
172 | int q, res = 0; | ||
173 | |||
174 | spin_lock_irqsave(&local->queue_stop_reason_lock, flags); | ||
175 | for (q = 0; q < local->hw.queues; q++) | ||
176 | res += sprintf(buf + res, "%02d: %#.8lx/%d\n", q, | ||
177 | local->queue_stop_reasons[q], | ||
178 | __netif_subqueue_stopped(local->mdev, q)); | ||
179 | spin_unlock_irqrestore(&local->queue_stop_reason_lock, flags); | ||
180 | |||
181 | return simple_read_from_buffer(user_buf, count, ppos, buf, res); | ||
182 | } | ||
183 | |||
184 | static const struct file_operations queues_ops = { | ||
185 | .read = queues_read, | ||
186 | .open = mac80211_open_file_generic | ||
187 | }; | ||
188 | |||
166 | /* statistics stuff */ | 189 | /* statistics stuff */ |
167 | 190 | ||
168 | #define DEBUGFS_STATS_FILE(name, buflen, fmt, value...) \ | 191 | #define DEBUGFS_STATS_FILE(name, buflen, fmt, value...) \ |
@@ -298,6 +321,7 @@ void debugfs_hw_add(struct ieee80211_local *local) | |||
298 | DEBUGFS_ADD(total_ps_buffered); | 321 | DEBUGFS_ADD(total_ps_buffered); |
299 | DEBUGFS_ADD(wep_iv); | 322 | DEBUGFS_ADD(wep_iv); |
300 | DEBUGFS_ADD(tsf); | 323 | DEBUGFS_ADD(tsf); |
324 | DEBUGFS_ADD(queues); | ||
301 | DEBUGFS_ADD_MODE(reset, 0200); | 325 | DEBUGFS_ADD_MODE(reset, 0200); |
302 | DEBUGFS_ADD(noack); | 326 | DEBUGFS_ADD(noack); |
303 | 327 | ||
@@ -350,6 +374,7 @@ void debugfs_hw_del(struct ieee80211_local *local) | |||
350 | DEBUGFS_DEL(total_ps_buffered); | 374 | DEBUGFS_DEL(total_ps_buffered); |
351 | DEBUGFS_DEL(wep_iv); | 375 | DEBUGFS_DEL(wep_iv); |
352 | DEBUGFS_DEL(tsf); | 376 | DEBUGFS_DEL(tsf); |
377 | DEBUGFS_DEL(queues); | ||
353 | DEBUGFS_DEL(reset); | 378 | DEBUGFS_DEL(reset); |
354 | DEBUGFS_DEL(noack); | 379 | DEBUGFS_DEL(noack); |
355 | 380 | ||
diff --git a/net/mac80211/ieee80211_i.h b/net/mac80211/ieee80211_i.h index 4dbc28964196..68eb5052179a 100644 --- a/net/mac80211/ieee80211_i.h +++ b/net/mac80211/ieee80211_i.h | |||
@@ -783,6 +783,7 @@ struct ieee80211_local { | |||
783 | struct dentry *total_ps_buffered; | 783 | struct dentry *total_ps_buffered; |
784 | struct dentry *wep_iv; | 784 | struct dentry *wep_iv; |
785 | struct dentry *tsf; | 785 | struct dentry *tsf; |
786 | struct dentry *queues; | ||
786 | struct dentry *reset; | 787 | struct dentry *reset; |
787 | struct dentry *noack; | 788 | struct dentry *noack; |
788 | struct dentry *statistics; | 789 | struct dentry *statistics; |
@@ -1100,7 +1101,6 @@ void ieee802_11_parse_elems(u8 *start, size_t len, | |||
1100 | u32 ieee802_11_parse_elems_crc(u8 *start, size_t len, | 1101 | u32 ieee802_11_parse_elems_crc(u8 *start, size_t len, |
1101 | struct ieee802_11_elems *elems, | 1102 | struct ieee802_11_elems *elems, |
1102 | u64 filter, u32 crc); | 1103 | u64 filter, u32 crc); |
1103 | int ieee80211_set_freq(struct ieee80211_sub_if_data *sdata, int freq); | ||
1104 | u32 ieee80211_mandatory_rates(struct ieee80211_local *local, | 1104 | u32 ieee80211_mandatory_rates(struct ieee80211_local *local, |
1105 | enum ieee80211_band band); | 1105 | enum ieee80211_band band); |
1106 | 1106 | ||
diff --git a/net/mac80211/mlme.c b/net/mac80211/mlme.c index d779c57a8220..aca22b00b6a3 100644 --- a/net/mac80211/mlme.c +++ b/net/mac80211/mlme.c | |||
@@ -1102,14 +1102,6 @@ static void ieee80211_set_disassoc(struct ieee80211_sub_if_data *sdata, | |||
1102 | struct sta_info *sta; | 1102 | struct sta_info *sta; |
1103 | u32 changed = 0, config_changed = 0; | 1103 | u32 changed = 0, config_changed = 0; |
1104 | 1104 | ||
1105 | rcu_read_lock(); | ||
1106 | |||
1107 | sta = sta_info_get(local, ifmgd->bssid); | ||
1108 | if (!sta) { | ||
1109 | rcu_read_unlock(); | ||
1110 | return; | ||
1111 | } | ||
1112 | |||
1113 | if (deauth) { | 1105 | if (deauth) { |
1114 | ifmgd->direct_probe_tries = 0; | 1106 | ifmgd->direct_probe_tries = 0; |
1115 | ifmgd->auth_tries = 0; | 1107 | ifmgd->auth_tries = 0; |
@@ -1120,7 +1112,11 @@ static void ieee80211_set_disassoc(struct ieee80211_sub_if_data *sdata, | |||
1120 | netif_tx_stop_all_queues(sdata->dev); | 1112 | netif_tx_stop_all_queues(sdata->dev); |
1121 | netif_carrier_off(sdata->dev); | 1113 | netif_carrier_off(sdata->dev); |
1122 | 1114 | ||
1123 | ieee80211_sta_tear_down_BA_sessions(sta); | 1115 | rcu_read_lock(); |
1116 | sta = sta_info_get(local, ifmgd->bssid); | ||
1117 | if (sta) | ||
1118 | ieee80211_sta_tear_down_BA_sessions(sta); | ||
1119 | rcu_read_unlock(); | ||
1124 | 1120 | ||
1125 | bss = ieee80211_rx_bss_get(local, ifmgd->bssid, | 1121 | bss = ieee80211_rx_bss_get(local, ifmgd->bssid, |
1126 | conf->channel->center_freq, | 1122 | conf->channel->center_freq, |
@@ -1156,8 +1152,6 @@ static void ieee80211_set_disassoc(struct ieee80211_sub_if_data *sdata, | |||
1156 | ifmgd->ssid, ifmgd->ssid_len); | 1152 | ifmgd->ssid, ifmgd->ssid_len); |
1157 | } | 1153 | } |
1158 | 1154 | ||
1159 | rcu_read_unlock(); | ||
1160 | |||
1161 | ieee80211_set_wmm_default(sdata); | 1155 | ieee80211_set_wmm_default(sdata); |
1162 | 1156 | ||
1163 | ieee80211_recalc_idle(local); | 1157 | ieee80211_recalc_idle(local); |
@@ -2223,7 +2217,10 @@ static int ieee80211_sta_config_auth(struct ieee80211_sub_if_data *sdata) | |||
2223 | capa_mask, capa_val); | 2217 | capa_mask, capa_val); |
2224 | 2218 | ||
2225 | if (bss) { | 2219 | if (bss) { |
2226 | ieee80211_set_freq(sdata, bss->cbss.channel->center_freq); | 2220 | local->oper_channel = bss->cbss.channel; |
2221 | local->oper_channel_type = NL80211_CHAN_NO_HT; | ||
2222 | ieee80211_hw_config(local, 0); | ||
2223 | |||
2227 | if (!(ifmgd->flags & IEEE80211_STA_SSID_SET)) | 2224 | if (!(ifmgd->flags & IEEE80211_STA_SSID_SET)) |
2228 | ieee80211_sta_set_ssid(sdata, bss->ssid, | 2225 | ieee80211_sta_set_ssid(sdata, bss->ssid, |
2229 | bss->ssid_len); | 2226 | bss->ssid_len); |
@@ -2445,6 +2442,14 @@ void ieee80211_sta_req_auth(struct ieee80211_sub_if_data *sdata) | |||
2445 | ieee80211_set_disassoc(sdata, true, true, | 2442 | ieee80211_set_disassoc(sdata, true, true, |
2446 | WLAN_REASON_DEAUTH_LEAVING); | 2443 | WLAN_REASON_DEAUTH_LEAVING); |
2447 | 2444 | ||
2445 | if (ifmgd->ssid_len == 0) { | ||
2446 | /* | ||
2447 | * Only allow association to be started if a valid SSID | ||
2448 | * is configured. | ||
2449 | */ | ||
2450 | return; | ||
2451 | } | ||
2452 | |||
2448 | if (!(ifmgd->flags & IEEE80211_STA_EXT_SME) || | 2453 | if (!(ifmgd->flags & IEEE80211_STA_EXT_SME) || |
2449 | ifmgd->state != IEEE80211_STA_MLME_ASSOCIATE) | 2454 | ifmgd->state != IEEE80211_STA_MLME_ASSOCIATE) |
2450 | set_bit(IEEE80211_STA_REQ_AUTH, &ifmgd->request); | 2455 | set_bit(IEEE80211_STA_REQ_AUTH, &ifmgd->request); |
@@ -2476,6 +2481,10 @@ int ieee80211_sta_set_ssid(struct ieee80211_sub_if_data *sdata, char *ssid, size | |||
2476 | ifmgd = &sdata->u.mgd; | 2481 | ifmgd = &sdata->u.mgd; |
2477 | 2482 | ||
2478 | if (ifmgd->ssid_len != len || memcmp(ifmgd->ssid, ssid, len) != 0) { | 2483 | if (ifmgd->ssid_len != len || memcmp(ifmgd->ssid, ssid, len) != 0) { |
2484 | if (ifmgd->state == IEEE80211_STA_MLME_ASSOCIATED) | ||
2485 | ieee80211_set_disassoc(sdata, true, true, | ||
2486 | WLAN_REASON_DEAUTH_LEAVING); | ||
2487 | |||
2479 | /* | 2488 | /* |
2480 | * Do not use reassociation if SSID is changed (different ESS). | 2489 | * Do not use reassociation if SSID is changed (different ESS). |
2481 | */ | 2490 | */ |
@@ -2500,6 +2509,11 @@ int ieee80211_sta_set_bssid(struct ieee80211_sub_if_data *sdata, u8 *bssid) | |||
2500 | { | 2509 | { |
2501 | struct ieee80211_if_managed *ifmgd = &sdata->u.mgd; | 2510 | struct ieee80211_if_managed *ifmgd = &sdata->u.mgd; |
2502 | 2511 | ||
2512 | if (compare_ether_addr(bssid, ifmgd->bssid) != 0 && | ||
2513 | ifmgd->state == IEEE80211_STA_MLME_ASSOCIATED) | ||
2514 | ieee80211_set_disassoc(sdata, true, true, | ||
2515 | WLAN_REASON_DEAUTH_LEAVING); | ||
2516 | |||
2503 | if (is_valid_ether_addr(bssid)) { | 2517 | if (is_valid_ether_addr(bssid)) { |
2504 | memcpy(ifmgd->bssid, bssid, ETH_ALEN); | 2518 | memcpy(ifmgd->bssid, bssid, ETH_ALEN); |
2505 | ifmgd->flags |= IEEE80211_STA_BSSID_SET; | 2519 | ifmgd->flags |= IEEE80211_STA_BSSID_SET; |
diff --git a/net/mac80211/util.c b/net/mac80211/util.c index 66ce96a69f31..915e77769312 100644 --- a/net/mac80211/util.c +++ b/net/mac80211/util.c | |||
@@ -774,31 +774,6 @@ void ieee80211_tx_skb(struct ieee80211_sub_if_data *sdata, struct sk_buff *skb, | |||
774 | dev_queue_xmit(skb); | 774 | dev_queue_xmit(skb); |
775 | } | 775 | } |
776 | 776 | ||
777 | int ieee80211_set_freq(struct ieee80211_sub_if_data *sdata, int freqMHz) | ||
778 | { | ||
779 | int ret = -EINVAL; | ||
780 | struct ieee80211_channel *chan; | ||
781 | struct ieee80211_local *local = sdata->local; | ||
782 | |||
783 | chan = ieee80211_get_channel(local->hw.wiphy, freqMHz); | ||
784 | |||
785 | if (chan && !(chan->flags & IEEE80211_CHAN_DISABLED)) { | ||
786 | if (sdata->vif.type == NL80211_IFTYPE_ADHOC && | ||
787 | chan->flags & IEEE80211_CHAN_NO_IBSS) | ||
788 | return ret; | ||
789 | local->oper_channel = chan; | ||
790 | local->oper_channel_type = NL80211_CHAN_NO_HT; | ||
791 | |||
792 | if (local->sw_scanning || local->hw_scanning) | ||
793 | ret = 0; | ||
794 | else | ||
795 | ret = ieee80211_hw_config( | ||
796 | local, IEEE80211_CONF_CHANGE_CHANNEL); | ||
797 | } | ||
798 | |||
799 | return ret; | ||
800 | } | ||
801 | |||
802 | u32 ieee80211_mandatory_rates(struct ieee80211_local *local, | 777 | u32 ieee80211_mandatory_rates(struct ieee80211_local *local, |
803 | enum ieee80211_band band) | 778 | enum ieee80211_band band) |
804 | { | 779 | { |
diff --git a/net/mac80211/wext.c b/net/mac80211/wext.c index d2d81b103341..1da81f456744 100644 --- a/net/mac80211/wext.c +++ b/net/mac80211/wext.c | |||
@@ -55,6 +55,8 @@ static int ieee80211_ioctl_siwfreq(struct net_device *dev, | |||
55 | struct iw_freq *freq, char *extra) | 55 | struct iw_freq *freq, char *extra) |
56 | { | 56 | { |
57 | struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev); | 57 | struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev); |
58 | struct ieee80211_local *local = sdata->local; | ||
59 | struct ieee80211_channel *chan; | ||
58 | 60 | ||
59 | if (sdata->vif.type == NL80211_IFTYPE_ADHOC) | 61 | if (sdata->vif.type == NL80211_IFTYPE_ADHOC) |
60 | return cfg80211_ibss_wext_siwfreq(dev, info, freq, extra); | 62 | return cfg80211_ibss_wext_siwfreq(dev, info, freq, extra); |
@@ -69,17 +71,38 @@ static int ieee80211_ioctl_siwfreq(struct net_device *dev, | |||
69 | IEEE80211_STA_AUTO_CHANNEL_SEL; | 71 | IEEE80211_STA_AUTO_CHANNEL_SEL; |
70 | return 0; | 72 | return 0; |
71 | } else | 73 | } else |
72 | return ieee80211_set_freq(sdata, | 74 | chan = ieee80211_get_channel(local->hw.wiphy, |
73 | ieee80211_channel_to_frequency(freq->m)); | 75 | ieee80211_channel_to_frequency(freq->m)); |
74 | } else { | 76 | } else { |
75 | int i, div = 1000000; | 77 | int i, div = 1000000; |
76 | for (i = 0; i < freq->e; i++) | 78 | for (i = 0; i < freq->e; i++) |
77 | div /= 10; | 79 | div /= 10; |
78 | if (div > 0) | 80 | if (div <= 0) |
79 | return ieee80211_set_freq(sdata, freq->m / div); | ||
80 | else | ||
81 | return -EINVAL; | 81 | return -EINVAL; |
82 | chan = ieee80211_get_channel(local->hw.wiphy, freq->m / div); | ||
82 | } | 83 | } |
84 | |||
85 | if (!chan) | ||
86 | return -EINVAL; | ||
87 | |||
88 | if (chan->flags & IEEE80211_CHAN_DISABLED) | ||
89 | return -EINVAL; | ||
90 | |||
91 | /* | ||
92 | * no change except maybe auto -> fixed, ignore the HT | ||
93 | * setting so you can fix a channel you're on already | ||
94 | */ | ||
95 | if (local->oper_channel == chan) | ||
96 | return 0; | ||
97 | |||
98 | if (sdata->vif.type == NL80211_IFTYPE_STATION) | ||
99 | ieee80211_sta_req_auth(sdata); | ||
100 | |||
101 | local->oper_channel = chan; | ||
102 | local->oper_channel_type = NL80211_CHAN_NO_HT; | ||
103 | ieee80211_hw_config(local, 0); | ||
104 | |||
105 | return 0; | ||
83 | } | 106 | } |
84 | 107 | ||
85 | 108 | ||
diff --git a/net/netlink/af_netlink.c b/net/netlink/af_netlink.c index 8b6bbb3032b0..2936fa3b6dc8 100644 --- a/net/netlink/af_netlink.c +++ b/net/netlink/af_netlink.c | |||
@@ -1914,8 +1914,8 @@ static int netlink_seq_show(struct seq_file *seq, void *v) | |||
1914 | s->sk_protocol, | 1914 | s->sk_protocol, |
1915 | nlk->pid, | 1915 | nlk->pid, |
1916 | nlk->groups ? (u32)nlk->groups[0] : 0, | 1916 | nlk->groups ? (u32)nlk->groups[0] : 0, |
1917 | atomic_read(&s->sk_rmem_alloc), | 1917 | sk_rmem_alloc_get(s), |
1918 | atomic_read(&s->sk_wmem_alloc), | 1918 | sk_wmem_alloc_get(s), |
1919 | nlk->cb, | 1919 | nlk->cb, |
1920 | atomic_read(&s->sk_refcnt), | 1920 | atomic_read(&s->sk_refcnt), |
1921 | atomic_read(&s->sk_drops) | 1921 | atomic_read(&s->sk_drops) |
diff --git a/net/netrom/af_netrom.c b/net/netrom/af_netrom.c index 3be0e016ab7d..ce51ce012cda 100644 --- a/net/netrom/af_netrom.c +++ b/net/netrom/af_netrom.c | |||
@@ -286,8 +286,7 @@ void nr_destroy_socket(struct sock *sk) | |||
286 | kfree_skb(skb); | 286 | kfree_skb(skb); |
287 | } | 287 | } |
288 | 288 | ||
289 | if (atomic_read(&sk->sk_wmem_alloc) || | 289 | if (sk_has_allocations(sk)) { |
290 | atomic_read(&sk->sk_rmem_alloc)) { | ||
291 | /* Defer: outstanding buffers */ | 290 | /* Defer: outstanding buffers */ |
292 | sk->sk_timer.function = nr_destroy_timer; | 291 | sk->sk_timer.function = nr_destroy_timer; |
293 | sk->sk_timer.expires = jiffies + 2 * HZ; | 292 | sk->sk_timer.expires = jiffies + 2 * HZ; |
@@ -1206,7 +1205,7 @@ static int nr_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg) | |||
1206 | long amount; | 1205 | long amount; |
1207 | 1206 | ||
1208 | lock_sock(sk); | 1207 | lock_sock(sk); |
1209 | amount = sk->sk_sndbuf - atomic_read(&sk->sk_wmem_alloc); | 1208 | amount = sk->sk_sndbuf - sk_wmem_alloc_get(sk); |
1210 | if (amount < 0) | 1209 | if (amount < 0) |
1211 | amount = 0; | 1210 | amount = 0; |
1212 | release_sock(sk); | 1211 | release_sock(sk); |
@@ -1342,8 +1341,8 @@ static int nr_info_show(struct seq_file *seq, void *v) | |||
1342 | nr->n2count, | 1341 | nr->n2count, |
1343 | nr->n2, | 1342 | nr->n2, |
1344 | nr->window, | 1343 | nr->window, |
1345 | atomic_read(&s->sk_wmem_alloc), | 1344 | sk_wmem_alloc_get(s), |
1346 | atomic_read(&s->sk_rmem_alloc), | 1345 | sk_rmem_alloc_get(s), |
1347 | s->sk_socket ? SOCK_INODE(s->sk_socket)->i_ino : 0L); | 1346 | s->sk_socket ? SOCK_INODE(s->sk_socket)->i_ino : 0L); |
1348 | 1347 | ||
1349 | bh_unlock_sock(s); | 1348 | bh_unlock_sock(s); |
diff --git a/net/packet/af_packet.c b/net/packet/af_packet.c index 4f76e5552d8e..ebe5718baa31 100644 --- a/net/packet/af_packet.c +++ b/net/packet/af_packet.c | |||
@@ -1987,7 +1987,8 @@ static int packet_ioctl(struct socket *sock, unsigned int cmd, | |||
1987 | switch (cmd) { | 1987 | switch (cmd) { |
1988 | case SIOCOUTQ: | 1988 | case SIOCOUTQ: |
1989 | { | 1989 | { |
1990 | int amount = atomic_read(&sk->sk_wmem_alloc); | 1990 | int amount = sk_wmem_alloc_get(sk); |
1991 | |||
1991 | return put_user(amount, (int __user *)arg); | 1992 | return put_user(amount, (int __user *)arg); |
1992 | } | 1993 | } |
1993 | case SIOCINQ: | 1994 | case SIOCINQ: |
diff --git a/net/rose/af_rose.c b/net/rose/af_rose.c index 877a7f65f707..6bd8e93869ed 100644 --- a/net/rose/af_rose.c +++ b/net/rose/af_rose.c | |||
@@ -356,8 +356,7 @@ void rose_destroy_socket(struct sock *sk) | |||
356 | kfree_skb(skb); | 356 | kfree_skb(skb); |
357 | } | 357 | } |
358 | 358 | ||
359 | if (atomic_read(&sk->sk_wmem_alloc) || | 359 | if (sk_has_allocations(sk)) { |
360 | atomic_read(&sk->sk_rmem_alloc)) { | ||
361 | /* Defer: outstanding buffers */ | 360 | /* Defer: outstanding buffers */ |
362 | setup_timer(&sk->sk_timer, rose_destroy_timer, | 361 | setup_timer(&sk->sk_timer, rose_destroy_timer, |
363 | (unsigned long)sk); | 362 | (unsigned long)sk); |
@@ -1310,7 +1309,8 @@ static int rose_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg) | |||
1310 | switch (cmd) { | 1309 | switch (cmd) { |
1311 | case TIOCOUTQ: { | 1310 | case TIOCOUTQ: { |
1312 | long amount; | 1311 | long amount; |
1313 | amount = sk->sk_sndbuf - atomic_read(&sk->sk_wmem_alloc); | 1312 | |
1313 | amount = sk->sk_sndbuf - sk_wmem_alloc_get(sk); | ||
1314 | if (amount < 0) | 1314 | if (amount < 0) |
1315 | amount = 0; | 1315 | amount = 0; |
1316 | return put_user(amount, (unsigned int __user *) argp); | 1316 | return put_user(amount, (unsigned int __user *) argp); |
@@ -1481,8 +1481,8 @@ static int rose_info_show(struct seq_file *seq, void *v) | |||
1481 | rose->hb / HZ, | 1481 | rose->hb / HZ, |
1482 | ax25_display_timer(&rose->idletimer) / (60 * HZ), | 1482 | ax25_display_timer(&rose->idletimer) / (60 * HZ), |
1483 | rose->idle / (60 * HZ), | 1483 | rose->idle / (60 * HZ), |
1484 | atomic_read(&s->sk_wmem_alloc), | 1484 | sk_wmem_alloc_get(s), |
1485 | atomic_read(&s->sk_rmem_alloc), | 1485 | sk_rmem_alloc_get(s), |
1486 | s->sk_socket ? SOCK_INODE(s->sk_socket)->i_ino : 0L); | 1486 | s->sk_socket ? SOCK_INODE(s->sk_socket)->i_ino : 0L); |
1487 | } | 1487 | } |
1488 | 1488 | ||
diff --git a/net/sched/act_police.c b/net/sched/act_police.c index f8f047b61245..723964c3ee4f 100644 --- a/net/sched/act_police.c +++ b/net/sched/act_police.c | |||
@@ -294,6 +294,8 @@ static int tcf_act_police(struct sk_buff *skb, struct tc_action *a, | |||
294 | if (police->tcfp_ewma_rate && | 294 | if (police->tcfp_ewma_rate && |
295 | police->tcf_rate_est.bps >= police->tcfp_ewma_rate) { | 295 | police->tcf_rate_est.bps >= police->tcfp_ewma_rate) { |
296 | police->tcf_qstats.overlimits++; | 296 | police->tcf_qstats.overlimits++; |
297 | if (police->tcf_action == TC_ACT_SHOT) | ||
298 | police->tcf_qstats.drops++; | ||
297 | spin_unlock(&police->tcf_lock); | 299 | spin_unlock(&police->tcf_lock); |
298 | return police->tcf_action; | 300 | return police->tcf_action; |
299 | } | 301 | } |
@@ -327,6 +329,8 @@ static int tcf_act_police(struct sk_buff *skb, struct tc_action *a, | |||
327 | } | 329 | } |
328 | 330 | ||
329 | police->tcf_qstats.overlimits++; | 331 | police->tcf_qstats.overlimits++; |
332 | if (police->tcf_action == TC_ACT_SHOT) | ||
333 | police->tcf_qstats.drops++; | ||
330 | spin_unlock(&police->tcf_lock); | 334 | spin_unlock(&police->tcf_lock); |
331 | return police->tcf_action; | 335 | return police->tcf_action; |
332 | } | 336 | } |
diff --git a/net/sched/em_meta.c b/net/sched/em_meta.c index 266151ae85a3..18d85d259104 100644 --- a/net/sched/em_meta.c +++ b/net/sched/em_meta.c | |||
@@ -349,13 +349,13 @@ META_COLLECTOR(int_sk_type) | |||
349 | META_COLLECTOR(int_sk_rmem_alloc) | 349 | META_COLLECTOR(int_sk_rmem_alloc) |
350 | { | 350 | { |
351 | SKIP_NONLOCAL(skb); | 351 | SKIP_NONLOCAL(skb); |
352 | dst->value = atomic_read(&skb->sk->sk_rmem_alloc); | 352 | dst->value = sk_rmem_alloc_get(skb->sk); |
353 | } | 353 | } |
354 | 354 | ||
355 | META_COLLECTOR(int_sk_wmem_alloc) | 355 | META_COLLECTOR(int_sk_wmem_alloc) |
356 | { | 356 | { |
357 | SKIP_NONLOCAL(skb); | 357 | SKIP_NONLOCAL(skb); |
358 | dst->value = atomic_read(&skb->sk->sk_wmem_alloc); | 358 | dst->value = sk_wmem_alloc_get(skb->sk); |
359 | } | 359 | } |
360 | 360 | ||
361 | META_COLLECTOR(int_sk_omem_alloc) | 361 | META_COLLECTOR(int_sk_omem_alloc) |
diff --git a/net/sctp/socket.c b/net/sctp/socket.c index 0f01e5d8a24f..35ba035970a2 100644 --- a/net/sctp/socket.c +++ b/net/sctp/socket.c | |||
@@ -130,7 +130,7 @@ static inline int sctp_wspace(struct sctp_association *asoc) | |||
130 | if (asoc->ep->sndbuf_policy) | 130 | if (asoc->ep->sndbuf_policy) |
131 | amt = asoc->sndbuf_used; | 131 | amt = asoc->sndbuf_used; |
132 | else | 132 | else |
133 | amt = atomic_read(&asoc->base.sk->sk_wmem_alloc); | 133 | amt = sk_wmem_alloc_get(asoc->base.sk); |
134 | 134 | ||
135 | if (amt >= asoc->base.sk->sk_sndbuf) { | 135 | if (amt >= asoc->base.sk->sk_sndbuf) { |
136 | if (asoc->base.sk->sk_userlocks & SOCK_SNDBUF_LOCK) | 136 | if (asoc->base.sk->sk_userlocks & SOCK_SNDBUF_LOCK) |
@@ -6523,7 +6523,7 @@ static int sctp_writeable(struct sock *sk) | |||
6523 | { | 6523 | { |
6524 | int amt = 0; | 6524 | int amt = 0; |
6525 | 6525 | ||
6526 | amt = sk->sk_sndbuf - atomic_read(&sk->sk_wmem_alloc); | 6526 | amt = sk->sk_sndbuf - sk_wmem_alloc_get(sk); |
6527 | if (amt < 0) | 6527 | if (amt < 0) |
6528 | amt = 0; | 6528 | amt = 0; |
6529 | return amt; | 6529 | return amt; |
diff --git a/net/unix/af_unix.c b/net/unix/af_unix.c index 9dcc6e7f96ec..36d4e44d6233 100644 --- a/net/unix/af_unix.c +++ b/net/unix/af_unix.c | |||
@@ -1946,7 +1946,7 @@ static int unix_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg) | |||
1946 | 1946 | ||
1947 | switch (cmd) { | 1947 | switch (cmd) { |
1948 | case SIOCOUTQ: | 1948 | case SIOCOUTQ: |
1949 | amount = atomic_read(&sk->sk_wmem_alloc); | 1949 | amount = sk_wmem_alloc_get(sk); |
1950 | err = put_user(amount, (int __user *)arg); | 1950 | err = put_user(amount, (int __user *)arg); |
1951 | break; | 1951 | break; |
1952 | case SIOCINQ: | 1952 | case SIOCINQ: |
diff --git a/net/x25/af_x25.c b/net/x25/af_x25.c index ed80af8ca5fb..21cdc872004e 100644 --- a/net/x25/af_x25.c +++ b/net/x25/af_x25.c | |||
@@ -332,14 +332,14 @@ static unsigned int x25_new_lci(struct x25_neigh *nb) | |||
332 | /* | 332 | /* |
333 | * Deferred destroy. | 333 | * Deferred destroy. |
334 | */ | 334 | */ |
335 | void x25_destroy_socket(struct sock *); | 335 | static void __x25_destroy_socket(struct sock *); |
336 | 336 | ||
337 | /* | 337 | /* |
338 | * handler for deferred kills. | 338 | * handler for deferred kills. |
339 | */ | 339 | */ |
340 | static void x25_destroy_timer(unsigned long data) | 340 | static void x25_destroy_timer(unsigned long data) |
341 | { | 341 | { |
342 | x25_destroy_socket((struct sock *)data); | 342 | x25_destroy_socket_from_timer((struct sock *)data); |
343 | } | 343 | } |
344 | 344 | ||
345 | /* | 345 | /* |
@@ -349,12 +349,10 @@ static void x25_destroy_timer(unsigned long data) | |||
349 | * will touch it and we are (fairly 8-) ) safe. | 349 | * will touch it and we are (fairly 8-) ) safe. |
350 | * Not static as it's used by the timer | 350 | * Not static as it's used by the timer |
351 | */ | 351 | */ |
352 | void x25_destroy_socket(struct sock *sk) | 352 | static void __x25_destroy_socket(struct sock *sk) |
353 | { | 353 | { |
354 | struct sk_buff *skb; | 354 | struct sk_buff *skb; |
355 | 355 | ||
356 | sock_hold(sk); | ||
357 | lock_sock(sk); | ||
358 | x25_stop_heartbeat(sk); | 356 | x25_stop_heartbeat(sk); |
359 | x25_stop_timer(sk); | 357 | x25_stop_timer(sk); |
360 | 358 | ||
@@ -374,8 +372,7 @@ void x25_destroy_socket(struct sock *sk) | |||
374 | kfree_skb(skb); | 372 | kfree_skb(skb); |
375 | } | 373 | } |
376 | 374 | ||
377 | if (atomic_read(&sk->sk_wmem_alloc) || | 375 | if (sk_has_allocations(sk)) { |
378 | atomic_read(&sk->sk_rmem_alloc)) { | ||
379 | /* Defer: outstanding buffers */ | 376 | /* Defer: outstanding buffers */ |
380 | sk->sk_timer.expires = jiffies + 10 * HZ; | 377 | sk->sk_timer.expires = jiffies + 10 * HZ; |
381 | sk->sk_timer.function = x25_destroy_timer; | 378 | sk->sk_timer.function = x25_destroy_timer; |
@@ -385,7 +382,22 @@ void x25_destroy_socket(struct sock *sk) | |||
385 | /* drop last reference so sock_put will free */ | 382 | /* drop last reference so sock_put will free */ |
386 | __sock_put(sk); | 383 | __sock_put(sk); |
387 | } | 384 | } |
385 | } | ||
386 | |||
387 | void x25_destroy_socket_from_timer(struct sock *sk) | ||
388 | { | ||
389 | sock_hold(sk); | ||
390 | bh_lock_sock(sk); | ||
391 | __x25_destroy_socket(sk); | ||
392 | bh_unlock_sock(sk); | ||
393 | sock_put(sk); | ||
394 | } | ||
388 | 395 | ||
396 | static void x25_destroy_socket(struct sock *sk) | ||
397 | { | ||
398 | sock_hold(sk); | ||
399 | lock_sock(sk); | ||
400 | __x25_destroy_socket(sk); | ||
389 | release_sock(sk); | 401 | release_sock(sk); |
390 | sock_put(sk); | 402 | sock_put(sk); |
391 | } | 403 | } |
@@ -1259,8 +1271,8 @@ static int x25_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg) | |||
1259 | 1271 | ||
1260 | switch (cmd) { | 1272 | switch (cmd) { |
1261 | case TIOCOUTQ: { | 1273 | case TIOCOUTQ: { |
1262 | int amount = sk->sk_sndbuf - | 1274 | int amount = sk->sk_sndbuf - sk_wmem_alloc_get(sk); |
1263 | atomic_read(&sk->sk_wmem_alloc); | 1275 | |
1264 | if (amount < 0) | 1276 | if (amount < 0) |
1265 | amount = 0; | 1277 | amount = 0; |
1266 | rc = put_user(amount, (unsigned int __user *)argp); | 1278 | rc = put_user(amount, (unsigned int __user *)argp); |
diff --git a/net/x25/x25_proc.c b/net/x25/x25_proc.c index 1afa44d25beb..0a04e62e0e18 100644 --- a/net/x25/x25_proc.c +++ b/net/x25/x25_proc.c | |||
@@ -163,8 +163,8 @@ static int x25_seq_socket_show(struct seq_file *seq, void *v) | |||
163 | devname, x25->lci & 0x0FFF, x25->state, x25->vs, x25->vr, | 163 | devname, x25->lci & 0x0FFF, x25->state, x25->vs, x25->vr, |
164 | x25->va, x25_display_timer(s) / HZ, x25->t2 / HZ, | 164 | x25->va, x25_display_timer(s) / HZ, x25->t2 / HZ, |
165 | x25->t21 / HZ, x25->t22 / HZ, x25->t23 / HZ, | 165 | x25->t21 / HZ, x25->t22 / HZ, x25->t23 / HZ, |
166 | atomic_read(&s->sk_wmem_alloc), | 166 | sk_wmem_alloc_get(s), |
167 | atomic_read(&s->sk_rmem_alloc), | 167 | sk_rmem_alloc_get(s), |
168 | s->sk_socket ? SOCK_INODE(s->sk_socket)->i_ino : 0L); | 168 | s->sk_socket ? SOCK_INODE(s->sk_socket)->i_ino : 0L); |
169 | out: | 169 | out: |
170 | return 0; | 170 | return 0; |
diff --git a/net/x25/x25_timer.c b/net/x25/x25_timer.c index d3e3e54db936..5c5db1a36399 100644 --- a/net/x25/x25_timer.c +++ b/net/x25/x25_timer.c | |||
@@ -113,7 +113,7 @@ static void x25_heartbeat_expiry(unsigned long param) | |||
113 | (sk->sk_state == TCP_LISTEN && | 113 | (sk->sk_state == TCP_LISTEN && |
114 | sock_flag(sk, SOCK_DEAD))) { | 114 | sock_flag(sk, SOCK_DEAD))) { |
115 | bh_unlock_sock(sk); | 115 | bh_unlock_sock(sk); |
116 | x25_destroy_socket(sk); | 116 | x25_destroy_socket_from_timer(sk); |
117 | return; | 117 | return; |
118 | } | 118 | } |
119 | break; | 119 | break; |