]> Pileus Git - ~andy/linux/blobdiff - net/core/sock.c
Merge branch 'for-3.5' of git://git.kernel.org/pub/scm/linux/kernel/git/tj/cgroup
[~andy/linux] / net / core / sock.c
index 878f7447cf61b5adb267bbeb3c96d23b4357a828..f372d9bf497675a436aa2cbc7cba00b5464faf9b 100644 (file)
@@ -89,6 +89,8 @@
  *             2 of the License, or (at your option) any later version.
  */
 
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
+
 #include <linux/capability.h>
 #include <linux/errno.h>
 #include <linux/types.h>
 #include <linux/user_namespace.h>
 #include <linux/static_key.h>
 #include <linux/memcontrol.h>
+#include <linux/prefetch.h>
 
 #include <asm/uaccess.h>
 
@@ -258,7 +261,9 @@ static struct lock_class_key af_callback_keys[AF_MAX];
 
 /* Run time adjustable parameters. */
 __u32 sysctl_wmem_max __read_mostly = SK_WMEM_MAX;
+EXPORT_SYMBOL(sysctl_wmem_max);
 __u32 sysctl_rmem_max __read_mostly = SK_RMEM_MAX;
+EXPORT_SYMBOL(sysctl_rmem_max);
 __u32 sysctl_wmem_default __read_mostly = SK_WMEM_MAX;
 __u32 sysctl_rmem_default __read_mostly = SK_RMEM_MAX;
 
@@ -294,9 +299,8 @@ static int sock_set_timeout(long *timeo_p, char __user *optval, int optlen)
                *timeo_p = 0;
                if (warned < 10 && net_ratelimit()) {
                        warned++;
-                       printk(KERN_INFO "sock_set_timeout: `%s' (pid %d) "
-                              "tries to set negative timeout\n",
-                               current->comm, task_pid_nr(current));
+                       pr_info("%s: `%s' (pid %d) tries to set negative timeout\n",
+                               __func__, current->comm, task_pid_nr(current));
                }
                return 0;
        }
@@ -314,8 +318,8 @@ static void sock_warn_obsolete_bsdism(const char *name)
        static char warncomm[TASK_COMM_LEN];
        if (strcmp(warncomm, current->comm) && warned < 5) {
                strcpy(warncomm,  current->comm);
-               printk(KERN_WARNING "process `%s' is using obsolete "
-                      "%s SO_BSDCOMPAT\n", warncomm, name);
+               pr_warn("process `%s' is using obsolete %s SO_BSDCOMPAT\n",
+                       warncomm, name);
                warned++;
        }
 }
@@ -389,7 +393,7 @@ int sk_receive_skb(struct sock *sk, struct sk_buff *skb, const int nested)
 
        skb->dev = NULL;
 
-       if (sk_rcvqueues_full(sk, skb)) {
+       if (sk_rcvqueues_full(sk, skb, sk->sk_rcvbuf)) {
                atomic_inc(&sk->sk_drops);
                goto discard_and_relse;
        }
@@ -406,7 +410,7 @@ int sk_receive_skb(struct sock *sk, struct sk_buff *skb, const int nested)
                rc = sk_backlog_rcv(sk, skb);
 
                mutex_release(&sk->sk_lock.dep_map, 1, _RET_IP_);
-       } else if (sk_add_backlog(sk, skb)) {
+       } else if (sk_add_backlog(sk, skb, sk->sk_rcvbuf)) {
                bh_unlock_sock(sk);
                atomic_inc(&sk->sk_drops);
                goto discard_and_relse;
@@ -561,7 +565,7 @@ int sock_setsockopt(struct socket *sock, int level, int optname,
                        sock_valbool_flag(sk, SOCK_DBG, valbool);
                break;
        case SO_REUSEADDR:
-               sk->sk_reuse = valbool;
+               sk->sk_reuse = (valbool ? SK_CAN_REUSE : SK_NO_REUSE);
                break;
        case SO_TYPE:
        case SO_PROTOCOL:
@@ -577,23 +581,15 @@ int sock_setsockopt(struct socket *sock, int level, int optname,
                break;
        case SO_SNDBUF:
                /* Don't error on this BSD doesn't and if you think
-                  about it this is right. Otherwise apps have to
-                  play 'guess the biggest size' games. RCVBUF/SNDBUF
-                  are treated in BSD as hints */
-
-               if (val > sysctl_wmem_max)
-                       val = sysctl_wmem_max;
+                * about it this is right. Otherwise apps have to
+                * play 'guess the biggest size' games. RCVBUF/SNDBUF
+                * are treated in BSD as hints
+                */
+               val = min_t(u32, val, sysctl_wmem_max);
 set_sndbuf:
                sk->sk_userlocks |= SOCK_SNDBUF_LOCK;
-               if ((val * 2) < SOCK_MIN_SNDBUF)
-                       sk->sk_sndbuf = SOCK_MIN_SNDBUF;
-               else
-                       sk->sk_sndbuf = val * 2;
-
-               /*
-                *      Wake up sending tasks if we
-                *      upped the value.
-                */
+               sk->sk_sndbuf = max_t(u32, val * 2, SOCK_MIN_SNDBUF);
+               /* Wake up sending tasks if we upped the value. */
                sk->sk_write_space(sk);
                break;
 
@@ -606,12 +602,11 @@ set_sndbuf:
 
        case SO_RCVBUF:
                /* Don't error on this BSD doesn't and if you think
-                  about it this is right. Otherwise apps have to
-                  play 'guess the biggest size' games. RCVBUF/SNDBUF
-                  are treated in BSD as hints */
-
-               if (val > sysctl_rmem_max)
-                       val = sysctl_rmem_max;
+                * about it this is right. Otherwise apps have to
+                * play 'guess the biggest size' games. RCVBUF/SNDBUF
+                * are treated in BSD as hints
+                */
+               val = min_t(u32, val, sysctl_rmem_max);
 set_rcvbuf:
                sk->sk_userlocks |= SOCK_RCVBUF_LOCK;
                /*
@@ -629,10 +624,7 @@ set_rcvbuf:
                 * returning the value we actually used in getsockopt
                 * is the most desirable behavior.
                 */
-               if ((val * 2) < SOCK_MIN_RCVBUF)
-                       sk->sk_rcvbuf = SOCK_MIN_RCVBUF;
-               else
-                       sk->sk_rcvbuf = val * 2;
+               sk->sk_rcvbuf = max_t(u32, val * 2, SOCK_MIN_RCVBUF);
                break;
 
        case SO_RCVBUFFORCE:
@@ -858,7 +850,7 @@ int sock_getsockopt(struct socket *sock, int level, int optname,
                break;
 
        case SO_BROADCAST:
-               v.val = !!sock_flag(sk, SOCK_BROADCAST);
+               v.val = sock_flag(sk, SOCK_BROADCAST);
                break;
 
        case SO_SNDBUF:
@@ -874,7 +866,7 @@ int sock_getsockopt(struct socket *sock, int level, int optname,
                break;
 
        case SO_KEEPALIVE:
-               v.val = !!sock_flag(sk, SOCK_KEEPOPEN);
+               v.val = sock_flag(sk, SOCK_KEEPOPEN);
                break;
 
        case SO_TYPE:
@@ -896,7 +888,7 @@ int sock_getsockopt(struct socket *sock, int level, int optname,
                break;
 
        case SO_OOBINLINE:
-               v.val = !!sock_flag(sk, SOCK_URGINLINE);
+               v.val = sock_flag(sk, SOCK_URGINLINE);
                break;
 
        case SO_NO_CHECK:
@@ -909,7 +901,7 @@ int sock_getsockopt(struct socket *sock, int level, int optname,
 
        case SO_LINGER:
                lv              = sizeof(v.ling);
-               v.ling.l_onoff  = !!sock_flag(sk, SOCK_LINGER);
+               v.ling.l_onoff  = sock_flag(sk, SOCK_LINGER);
                v.ling.l_linger = sk->sk_lingertime / HZ;
                break;
 
@@ -975,7 +967,7 @@ int sock_getsockopt(struct socket *sock, int level, int optname,
                break;
 
        case SO_PASSCRED:
-               v.val = test_bit(SOCK_PASSCRED, &sock->flags) ? 1 : 0;
+               v.val = !!test_bit(SOCK_PASSCRED, &sock->flags);
                break;
 
        case SO_PEERCRED:
@@ -1010,7 +1002,7 @@ int sock_getsockopt(struct socket *sock, int level, int optname,
                break;
 
        case SO_PASSSEC:
-               v.val = test_bit(SOCK_PASSSEC, &sock->flags) ? 1 : 0;
+               v.val = !!test_bit(SOCK_PASSSEC, &sock->flags);
                break;
 
        case SO_PEERSEC:
@@ -1021,11 +1013,11 @@ int sock_getsockopt(struct socket *sock, int level, int optname,
                break;
 
        case SO_RXQ_OVFL:
-               v.val = !!sock_flag(sk, SOCK_RXQ_OVFL);
+               v.val = sock_flag(sk, SOCK_RXQ_OVFL);
                break;
 
        case SO_WIFI_STATUS:
-               v.val = !!sock_flag(sk, SOCK_WIFI_STATUS);
+               v.val = sock_flag(sk, SOCK_WIFI_STATUS);
                break;
 
        case SO_PEEK_OFF:
@@ -1035,7 +1027,7 @@ int sock_getsockopt(struct socket *sock, int level, int optname,
                v.val = sk->sk_peek_off;
                break;
        case SO_NOFCS:
-               v.val = !!sock_flag(sk, SOCK_NOFCS);
+               v.val = sock_flag(sk, SOCK_NOFCS);
                break;
        default:
                return -ENOPROTOOPT;
@@ -1247,8 +1239,8 @@ static void __sk_free(struct sock *sk)
        sock_disable_timestamp(sk, SK_FLAGS_TIMESTAMP);
 
        if (atomic_read(&sk->sk_omem_alloc))
-               printk(KERN_DEBUG "%s: optmem leakage (%d bytes) detected.\n",
-                      __func__, atomic_read(&sk->sk_omem_alloc));
+               pr_debug("%s: optmem leakage (%d bytes) detected\n",
+                        __func__, atomic_read(&sk->sk_omem_alloc));
 
        if (sk->sk_peer_cred)
                put_cred(sk->sk_peer_cred);
@@ -1534,7 +1526,7 @@ struct sk_buff *sock_rmalloc(struct sock *sk, unsigned long size, int force,
  */
 void *sock_kmalloc(struct sock *sk, int size, gfp_t priority)
 {
-       if ((unsigned)size <= sysctl_optmem_max &&
+       if ((unsigned int)size <= sysctl_optmem_max &&
            atomic_read(&sk->sk_omem_alloc) + size < sysctl_optmem_max) {
                void *mem;
                /* First do the add, to avoid the race if kmalloc
@@ -1712,6 +1704,7 @@ static void __release_sock(struct sock *sk)
                do {
                        struct sk_buff *next = skb->next;
 
+                       prefetch(next);
                        WARN_ON_ONCE(skb_dst_is_noref(skb));
                        skb->next = NULL;
                        sk_backlog_rcv(sk, skb);
@@ -2432,7 +2425,7 @@ static void assign_proto_idx(struct proto *prot)
        prot->inuse_idx = find_first_zero_bit(proto_inuse_idx, PROTO_INUSE_NR);
 
        if (unlikely(prot->inuse_idx == PROTO_INUSE_NR - 1)) {
-               printk(KERN_ERR "PROTO_INUSE_NR exhausted\n");
+               pr_err("PROTO_INUSE_NR exhausted\n");
                return;
        }
 
@@ -2462,8 +2455,8 @@ int proto_register(struct proto *prot, int alloc_slab)
                                        NULL);
 
                if (prot->slab == NULL) {
-                       printk(KERN_CRIT "%s: Can't create sock SLAB cache!\n",
-                              prot->name);
+                       pr_crit("%s: Can't create sock SLAB cache!\n",
+                               prot->name);
                        goto out;
                }
 
@@ -2477,8 +2470,8 @@ int proto_register(struct proto *prot, int alloc_slab)
                                                                 SLAB_HWCACHE_ALIGN, NULL);
 
                        if (prot->rsk_prot->slab == NULL) {
-                               printk(KERN_CRIT "%s: Can't create request sock SLAB cache!\n",
-                                      prot->name);
+                               pr_crit("%s: Can't create request sock SLAB cache!\n",
+                                       prot->name);
                                goto out_free_request_sock_slab_name;
                        }
                }
@@ -2576,7 +2569,7 @@ static char proto_method_implemented(const void *method)
 }
 static long sock_prot_memory_allocated(struct proto *proto)
 {
-       return proto->memory_allocated != NULL ? proto_memory_allocated(proto): -1L;
+       return proto->memory_allocated != NULL ? proto_memory_allocated(proto) : -1L;
 }
 
 static char *sock_prot_memory_pressure(struct proto *proto)