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/sock.c | |
| 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/sock.c')
| -rw-r--r-- | net/core/sock.c | 69 |
1 files changed, 63 insertions, 6 deletions
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; |
