aboutsummaryrefslogtreecommitdiffstats
path: root/net/core/sock.c
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@woody.linux-foundation.org>2007-11-09 18:07:57 -0500
committerLinus Torvalds <torvalds@woody.linux-foundation.org>2007-11-09 18:07:57 -0500
commitc5b875e354a54e2b5ba24eecae69bf94e025edd5 (patch)
tree0446a68d99ad50305ab78835456d9faa62be5948 /net/core/sock.c
parenteae1920a21b4f87e89cea802e7df39442b119617 (diff)
parentc3d8d1e30cace31fed6186a4b8c6b1401836d89c (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.c69
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);
1801static DEFINE_RWLOCK(proto_list_lock); 1801static DEFINE_RWLOCK(proto_list_lock);
1802static LIST_HEAD(proto_list); 1802static 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 */
1810static void inuse_add(struct proto *prot, int inc)
1811{
1812 per_cpu_ptr(prot->inuse_ptr, smp_processor_id())[0] += inc;
1813}
1814
1815static 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
1823static 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
1836static 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
1846static inline int inuse_init(struct proto *prot)
1847{
1848 return 0;
1849}
1850
1851static inline void inuse_fini(struct proto *prot)
1852{
1853}
1854#endif
1855
1804int proto_register(struct proto *prot, int alloc_slab) 1856int 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;
1862out: 1916
1863 return rc;
1864out_free_timewait_sock_slab_name: 1917out_free_timewait_sock_slab_name:
1865 kfree(timewait_sock_slab_name); 1918 kfree(timewait_sock_slab_name);
1866out_free_request_sock_slab: 1919out_free_request_sock_slab:
@@ -1873,7 +1926,10 @@ out_free_request_sock_slab_name:
1873out_free_sock_slab: 1926out_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; 1929out_free_inuse:
1930 inuse_fini(prot);
1931out:
1932 return -ENOBUFS;
1877} 1933}
1878 1934
1879EXPORT_SYMBOL(proto_register); 1935EXPORT_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;