diff options
| author | Linus Torvalds <torvalds@woody.linux-foundation.org> | 2007-11-09 18:07:57 -0500 |
|---|---|---|
| committer | Linus Torvalds <torvalds@woody.linux-foundation.org> | 2007-11-09 18:07:57 -0500 |
| commit | c5b875e354a54e2b5ba24eecae69bf94e025edd5 (patch) | |
| tree | 0446a68d99ad50305ab78835456d9faa62be5948 /net/core | |
| parent | eae1920a21b4f87e89cea802e7df39442b119617 (diff) | |
| parent | c3d8d1e30cace31fed6186a4b8c6b1401836d89c (diff) | |
Merge branch 'master' of master.kernel.org:/pub/scm/linux/kernel/git/davem/net-2.6
* 'master' of master.kernel.org:/pub/scm/linux/kernel/git/davem/net-2.6: (44 commits)
[NETLINK]: Fix unicast timeouts
[INET]: Remove per bucket rwlock in tcp/dccp ehash table.
[IPVS]: Synchronize closing of Connections
[IPVS]: Bind connections on stanby if the destination exists
[NET]: Remove Documentation/networking/pt.txt
[NET]: Remove Documentation/networking/routing.txt
[NET]: Remove Documentation/networking/ncsa-telnet
[NET]: Remove comx driver docs.
[NET]: Remove Documentation/networking/Configurable
[NET]: Clean proto_(un)register from in-code ifdefs
[IPSEC]: Fix crypto_alloc_comp error checking
[VLAN]: Fix SET_VLAN_INGRESS_PRIORITY_CMD ioctl
[NETNS]: Fix compiler error in net_namespace.c
[TTY]: Use tty_mode_ioctl() in network drivers.
[TTY]: Fix network driver interactions with TCGET/SET calls.
[PKT_SCHED] CLS_U32: Fix endianness problem with u32 classifier hash masks.
[NET]: Removing duplicit #includes
[NET]: Let USB_USBNET always select MII.
[RRUNNER]: Do not muck with sysctl_{r,w}mem_max
[DLM] lowcomms: Do not muck with sysctl_rmem_max.
...
Diffstat (limited to 'net/core')
| -rw-r--r-- | net/core/dst.c | 1 | ||||
| -rw-r--r-- | net/core/neighbour.c | 2 | ||||
| -rw-r--r-- | net/core/net_namespace.c | 28 | ||||
| -rw-r--r-- | net/core/sock.c | 69 |
4 files changed, 79 insertions, 21 deletions
diff --git a/net/core/dst.c b/net/core/dst.c index 16958e64e577..03daead3592a 100644 --- a/net/core/dst.c +++ b/net/core/dst.c | |||
| @@ -18,7 +18,6 @@ | |||
| 18 | #include <linux/types.h> | 18 | #include <linux/types.h> |
| 19 | #include <net/net_namespace.h> | 19 | #include <net/net_namespace.h> |
| 20 | 20 | ||
| 21 | #include <net/net_namespace.h> | ||
| 22 | #include <net/dst.h> | 21 | #include <net/dst.h> |
| 23 | 22 | ||
| 24 | /* | 23 | /* |
diff --git a/net/core/neighbour.c b/net/core/neighbour.c index 05979e356963..29b8ee4e35d6 100644 --- a/net/core/neighbour.c +++ b/net/core/neighbour.c | |||
| @@ -1435,6 +1435,8 @@ int neigh_table_clear(struct neigh_table *tbl) | |||
| 1435 | kfree(tbl->phash_buckets); | 1435 | kfree(tbl->phash_buckets); |
| 1436 | tbl->phash_buckets = NULL; | 1436 | tbl->phash_buckets = NULL; |
| 1437 | 1437 | ||
| 1438 | remove_proc_entry(tbl->id, init_net.proc_net_stat); | ||
| 1439 | |||
| 1438 | free_percpu(tbl->stats); | 1440 | free_percpu(tbl->stats); |
| 1439 | tbl->stats = NULL; | 1441 | tbl->stats = NULL; |
| 1440 | 1442 | ||
diff --git a/net/core/net_namespace.c b/net/core/net_namespace.c index e9f0964ce70b..3f6d37deac45 100644 --- a/net/core/net_namespace.c +++ b/net/core/net_namespace.c | |||
| @@ -64,6 +64,20 @@ static struct net *net_alloc(void) | |||
| 64 | return kmem_cache_zalloc(net_cachep, GFP_KERNEL); | 64 | return kmem_cache_zalloc(net_cachep, GFP_KERNEL); |
| 65 | } | 65 | } |
| 66 | 66 | ||
| 67 | static void net_free(struct net *net) | ||
| 68 | { | ||
| 69 | if (!net) | ||
| 70 | return; | ||
| 71 | |||
| 72 | if (unlikely(atomic_read(&net->use_count) != 0)) { | ||
| 73 | printk(KERN_EMERG "network namespace not free! Usage: %d\n", | ||
| 74 | atomic_read(&net->use_count)); | ||
| 75 | return; | ||
| 76 | } | ||
| 77 | |||
| 78 | kmem_cache_free(net_cachep, net); | ||
| 79 | } | ||
| 80 | |||
| 67 | struct net *copy_net_ns(unsigned long flags, struct net *old_net) | 81 | struct net *copy_net_ns(unsigned long flags, struct net *old_net) |
| 68 | { | 82 | { |
| 69 | struct net *new_net = NULL; | 83 | struct net *new_net = NULL; |
| @@ -100,20 +114,6 @@ out: | |||
| 100 | return new_net; | 114 | return new_net; |
| 101 | } | 115 | } |
| 102 | 116 | ||
| 103 | static void net_free(struct net *net) | ||
| 104 | { | ||
| 105 | if (!net) | ||
| 106 | return; | ||
| 107 | |||
| 108 | if (unlikely(atomic_read(&net->use_count) != 0)) { | ||
| 109 | printk(KERN_EMERG "network namespace not free! Usage: %d\n", | ||
| 110 | atomic_read(&net->use_count)); | ||
| 111 | return; | ||
| 112 | } | ||
| 113 | |||
| 114 | kmem_cache_free(net_cachep, net); | ||
| 115 | } | ||
| 116 | |||
| 117 | static void cleanup_net(struct work_struct *work) | 117 | static void cleanup_net(struct work_struct *work) |
| 118 | { | 118 | { |
| 119 | struct pernet_operations *ops; | 119 | struct pernet_operations *ops; |
diff --git a/net/core/sock.c b/net/core/sock.c index 12ad2067a988..8fc2f84209e4 100644 --- a/net/core/sock.c +++ b/net/core/sock.c | |||
| @@ -1801,11 +1801,65 @@ EXPORT_SYMBOL(sk_common_release); | |||
| 1801 | static DEFINE_RWLOCK(proto_list_lock); | 1801 | static DEFINE_RWLOCK(proto_list_lock); |
| 1802 | static LIST_HEAD(proto_list); | 1802 | static LIST_HEAD(proto_list); |
| 1803 | 1803 | ||
| 1804 | #ifdef CONFIG_SMP | ||
| 1805 | /* | ||
| 1806 | * Define default functions to keep track of inuse sockets per protocol | ||
| 1807 | * Note that often used protocols use dedicated functions to get a speed increase. | ||
| 1808 | * (see DEFINE_PROTO_INUSE/REF_PROTO_INUSE) | ||
| 1809 | */ | ||
| 1810 | static void inuse_add(struct proto *prot, int inc) | ||
| 1811 | { | ||
| 1812 | per_cpu_ptr(prot->inuse_ptr, smp_processor_id())[0] += inc; | ||
| 1813 | } | ||
| 1814 | |||
| 1815 | static int inuse_get(const struct proto *prot) | ||
| 1816 | { | ||
| 1817 | int res = 0, cpu; | ||
| 1818 | for_each_possible_cpu(cpu) | ||
| 1819 | res += per_cpu_ptr(prot->inuse_ptr, cpu)[0]; | ||
| 1820 | return res; | ||
| 1821 | } | ||
| 1822 | |||
| 1823 | static int inuse_init(struct proto *prot) | ||
| 1824 | { | ||
| 1825 | if (!prot->inuse_getval || !prot->inuse_add) { | ||
| 1826 | prot->inuse_ptr = alloc_percpu(int); | ||
| 1827 | if (prot->inuse_ptr == NULL) | ||
| 1828 | return -ENOBUFS; | ||
| 1829 | |||
| 1830 | prot->inuse_getval = inuse_get; | ||
| 1831 | prot->inuse_add = inuse_add; | ||
| 1832 | } | ||
| 1833 | return 0; | ||
| 1834 | } | ||
| 1835 | |||
| 1836 | static void inuse_fini(struct proto *prot) | ||
| 1837 | { | ||
| 1838 | if (prot->inuse_ptr != NULL) { | ||
| 1839 | free_percpu(prot->inuse_ptr); | ||
| 1840 | prot->inuse_ptr = NULL; | ||
| 1841 | prot->inuse_getval = NULL; | ||
| 1842 | prot->inuse_add = NULL; | ||
| 1843 | } | ||
| 1844 | } | ||
| 1845 | #else | ||
| 1846 | static inline int inuse_init(struct proto *prot) | ||
| 1847 | { | ||
| 1848 | return 0; | ||
| 1849 | } | ||
| 1850 | |||
| 1851 | static inline void inuse_fini(struct proto *prot) | ||
| 1852 | { | ||
| 1853 | } | ||
| 1854 | #endif | ||
| 1855 | |||
| 1804 | int proto_register(struct proto *prot, int alloc_slab) | 1856 | int proto_register(struct proto *prot, int alloc_slab) |
| 1805 | { | 1857 | { |
| 1806 | char *request_sock_slab_name = NULL; | 1858 | char *request_sock_slab_name = NULL; |
| 1807 | char *timewait_sock_slab_name; | 1859 | char *timewait_sock_slab_name; |
| 1808 | int rc = -ENOBUFS; | 1860 | |
| 1861 | if (inuse_init(prot)) | ||
| 1862 | goto out; | ||
| 1809 | 1863 | ||
| 1810 | if (alloc_slab) { | 1864 | if (alloc_slab) { |
| 1811 | prot->slab = kmem_cache_create(prot->name, prot->obj_size, 0, | 1865 | prot->slab = kmem_cache_create(prot->name, prot->obj_size, 0, |
| @@ -1814,7 +1868,7 @@ int proto_register(struct proto *prot, int alloc_slab) | |||
| 1814 | if (prot->slab == NULL) { | 1868 | if (prot->slab == NULL) { |
| 1815 | printk(KERN_CRIT "%s: Can't create sock SLAB cache!\n", | 1869 | printk(KERN_CRIT "%s: Can't create sock SLAB cache!\n", |
| 1816 | prot->name); | 1870 | prot->name); |
| 1817 | goto out; | 1871 | goto out_free_inuse; |
| 1818 | } | 1872 | } |
| 1819 | 1873 | ||
| 1820 | if (prot->rsk_prot != NULL) { | 1874 | if (prot->rsk_prot != NULL) { |
| @@ -1858,9 +1912,8 @@ int proto_register(struct proto *prot, int alloc_slab) | |||
| 1858 | write_lock(&proto_list_lock); | 1912 | write_lock(&proto_list_lock); |
| 1859 | list_add(&prot->node, &proto_list); | 1913 | list_add(&prot->node, &proto_list); |
| 1860 | write_unlock(&proto_list_lock); | 1914 | write_unlock(&proto_list_lock); |
| 1861 | rc = 0; | 1915 | return 0; |
| 1862 | out: | 1916 | |
| 1863 | return rc; | ||
| 1864 | out_free_timewait_sock_slab_name: | 1917 | out_free_timewait_sock_slab_name: |
| 1865 | kfree(timewait_sock_slab_name); | 1918 | kfree(timewait_sock_slab_name); |
| 1866 | out_free_request_sock_slab: | 1919 | out_free_request_sock_slab: |
| @@ -1873,7 +1926,10 @@ out_free_request_sock_slab_name: | |||
| 1873 | out_free_sock_slab: | 1926 | out_free_sock_slab: |
| 1874 | kmem_cache_destroy(prot->slab); | 1927 | kmem_cache_destroy(prot->slab); |
| 1875 | prot->slab = NULL; | 1928 | prot->slab = NULL; |
| 1876 | goto out; | 1929 | out_free_inuse: |
| 1930 | inuse_fini(prot); | ||
| 1931 | out: | ||
| 1932 | return -ENOBUFS; | ||
| 1877 | } | 1933 | } |
| 1878 | 1934 | ||
| 1879 | EXPORT_SYMBOL(proto_register); | 1935 | EXPORT_SYMBOL(proto_register); |
| @@ -1884,6 +1940,7 @@ void proto_unregister(struct proto *prot) | |||
| 1884 | list_del(&prot->node); | 1940 | list_del(&prot->node); |
| 1885 | write_unlock(&proto_list_lock); | 1941 | write_unlock(&proto_list_lock); |
| 1886 | 1942 | ||
| 1943 | inuse_fini(prot); | ||
| 1887 | if (prot->slab != NULL) { | 1944 | if (prot->slab != NULL) { |
| 1888 | kmem_cache_destroy(prot->slab); | 1945 | kmem_cache_destroy(prot->slab); |
| 1889 | prot->slab = NULL; | 1946 | prot->slab = NULL; |
