adds a socket option for low latency polling.
This allows overriding the global sysctl value with a per-socket one.
Unexport sysctl_net_ll_poll since for now it's not needed in modules.
Signed-off-by: Eliezer Tamir <eliezer.tamir@linux.intel.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
 
 #define SO_SELECT_ERR_QUEUE    45
 
+#define SO_LL                  46
+
 #endif /* _UAPI_ASM_SOCKET_H */
 
 
 #define SO_SELECT_ERR_QUEUE    45
 
+#define SO_LL                  46
+
 #endif /* __ASM_AVR32_SOCKET_H */
 
 
 #define SO_SELECT_ERR_QUEUE    45
 
+#define SO_LL                  46
+
 #endif /* _ASM_SOCKET_H */
 
 
 
 
 #define SO_SELECT_ERR_QUEUE    45
 
+#define SO_LL                  46
+
 #endif /* _ASM_SOCKET_H */
 
 
 
 #define SO_SELECT_ERR_QUEUE    45
 
+#define SO_LL                  46
+
 #endif /* _ASM_SOCKET_H */
 
 
 #define SO_SELECT_ERR_QUEUE    45
 
+#define SO_LL                  46
+
 #endif /* _ASM_IA64_SOCKET_H */
 
 
 #define SO_SELECT_ERR_QUEUE    45
 
+#define SO_LL                  46
+
 #endif /* _ASM_M32R_SOCKET_H */
 
 
 #define SO_SELECT_ERR_QUEUE    45
 
+#define SO_LL                  46
+
 #endif /* _UAPI_ASM_SOCKET_H */
 
 
 #define SO_SELECT_ERR_QUEUE    45
 
+#define SO_LL                  46
+
 #endif /* _ASM_SOCKET_H */
 
 
 #define SO_SELECT_ERR_QUEUE    0x4026
 
+#define SO_LL                  0x4027
+
 /* O_NONBLOCK clashes with the bits used for socket types.  Therefore we
  * have to define SOCK_NONBLOCK to a different value here.
  */
 
 
 #define SO_SELECT_ERR_QUEUE    45
 
+#define SO_LL                  46
+
 #endif /* _ASM_POWERPC_SOCKET_H */
 
 
 #define SO_SELECT_ERR_QUEUE    45
 
+#define SO_LL                  46
+
 #endif /* _ASM_SOCKET_H */
 
 
 #define SO_SELECT_ERR_QUEUE    0x0029
 
+#define SO_LL                  0x0030
+
 /* Security levels - as per NRL IPv6 - don't actually do anything */
 #define SO_SECURITY_AUTHENTICATION             0x5001
 #define SO_SECURITY_ENCRYPTION_TRANSPORT       0x5002
 
 
 #define SO_SELECT_ERR_QUEUE    45
 
+#define SO_LL                  46
+
 #endif /* _XTENSA_SOCKET_H */
 
 /* we can use sched_clock() because we don't care much about precision
  * we only care that the average is bounded
  */
-static inline u64 ll_end_time(void)
+static inline u64 ll_end_time(struct sock *sk)
 {
-       u64 end_time = ACCESS_ONCE(sysctl_net_ll_poll);
+       u64 end_time = ACCESS_ONCE(sk->sk_ll_usec);
 
        /* we don't mind a ~2.5% imprecision
-        * sysctl_net_ll_poll is a u_int so this can't overflow
+        * sk->sk_ll_usec is a u_int so this can't overflow
         */
        end_time = (end_time << 10) + sched_clock();
 
 
 static inline bool sk_valid_ll(struct sock *sk)
 {
-       return sysctl_net_ll_poll && sk->sk_napi_id &&
+       return sk->sk_ll_usec && sk->sk_napi_id &&
               !need_resched() && !signal_pending(current);
 }
 
 static inline bool sk_poll_ll(struct sock *sk, int nonblock)
 {
        const struct net_device_ops *ops;
-       u64 end_time = ll_end_time();
+       u64 end_time = ll_end_time(sk);
        struct napi_struct *napi;
        int rc = false;
 
 
 #else /* CONFIG_NET_LL_RX_POLL */
 
-static inline u64 ll_end_time(void)
+static inline u64 ll_end_time(struct sock *sk)
 {
        return 0;
 }
 
   *    @sk_wmem_queued: persistent queue size
   *    @sk_forward_alloc: space allocated forward
   *    @sk_napi_id: id of the last napi context to receive data for sk
+  *    @sk_ll_usec: usecs to busypoll when there is no data
   *    @sk_allocation: allocation mode
   *    @sk_sndbuf: size of send buffer in bytes
   *    @sk_flags: %SO_LINGER (l_onoff), %SO_BROADCAST, %SO_KEEPALIVE,
 #endif
 #ifdef CONFIG_NET_LL_RX_POLL
        unsigned int            sk_napi_id;
+       unsigned int            sk_ll_usec;
 #endif
        atomic_t                sk_drops;
        int                     sk_rcvbuf;
 
 
 #define SO_SELECT_ERR_QUEUE    45
 
+#define SO_LL                  46
+
 #endif /* __ASM_GENERIC_SOCKET_H */
 
                sock_valbool_flag(sk, SOCK_SELECT_ERR_QUEUE, valbool);
                break;
 
+#ifdef CONFIG_NET_LL_RX_POLL
+       case SO_LL:
+               /* allow unprivileged users to decrease the value */
+               if ((val > sk->sk_ll_usec) && !capable(CAP_NET_ADMIN))
+                       ret = -EPERM;
+               else {
+                       if (val < 0)
+                               ret = -EINVAL;
+                       else
+                               sk->sk_ll_usec = val;
+               }
+               break;
+#endif
        default:
                ret = -ENOPROTOOPT;
                break;
                v.val = sock_flag(sk, SOCK_SELECT_ERR_QUEUE);
                break;
 
+#ifdef CONFIG_NET_LL_RX_POLL
+       case SO_LL:
+               v.val = sk->sk_ll_usec;
+               break;
+#endif
+
        default:
                return -ENOPROTOOPT;
        }
 
 #ifdef CONFIG_NET_LL_RX_POLL
        sk->sk_napi_id          =       0;
+       sk->sk_ll_usec          =       sysctl_net_ll_poll;
 #endif
 
        /*
 
 
 #ifdef CONFIG_NET_LL_RX_POLL
 unsigned int sysctl_net_ll_poll __read_mostly;
-EXPORT_SYMBOL_GPL(sysctl_net_ll_poll);
 #endif
 
 static int sock_no_open(struct inode *irrelevant, struct file *dontcare);