aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKeller, Jacob E <jacob.e.keller@intel.com>2013-03-28 07:19:25 -0400
committerDavid S. Miller <davem@davemloft.net>2013-03-31 19:44:20 -0400
commit7d4c04fc170087119727119074e72445f2bb192b (patch)
treed76759bfe44399949f70cc344f3be76b8448cac2
parent4eb06148250f92e1e58bf069c309dac173e8b5f7 (diff)
net: add option to enable error queue packets waking select
Currently, when a socket receives something on the error queue it only wakes up the socket on select if it is in the "read" list, that is the socket has something to read. It is useful also to wake the socket if it is in the error list, which would enable software to wait on error queue packets without waking up for regular data on the socket. The main use case is for receiving timestamped transmit packets which return the timestamp to the socket via the error queue. This enables an application to select on the socket for the error queue only instead of for the regular traffic. -v2- * Added the SO_SELECT_ERR_QUEUE socket option to every architechture specific file * Modified every socket poll function that checks error queue Signed-off-by: Jacob Keller <jacob.e.keller@intel.com> Cc: Jeffrey Kirsher <jeffrey.t.kirsher@intel.com> Cc: Richard Cochran <richardcochran@gmail.com> Cc: Matthew Vick <matthew.vick@intel.com> Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r--arch/alpha/include/uapi/asm/socket.h2
-rw-r--r--arch/avr32/include/uapi/asm/socket.h2
-rw-r--r--arch/cris/include/uapi/asm/socket.h2
-rw-r--r--arch/frv/include/uapi/asm/socket.h2
-rw-r--r--arch/h8300/include/uapi/asm/socket.h2
-rw-r--r--arch/ia64/include/uapi/asm/socket.h2
-rw-r--r--arch/m32r/include/uapi/asm/socket.h2
-rw-r--r--arch/mips/include/uapi/asm/socket.h2
-rw-r--r--arch/mn10300/include/uapi/asm/socket.h2
-rw-r--r--arch/parisc/include/uapi/asm/socket.h2
-rw-r--r--arch/powerpc/include/uapi/asm/socket.h2
-rw-r--r--arch/s390/include/uapi/asm/socket.h2
-rw-r--r--arch/sparc/include/uapi/asm/socket.h2
-rw-r--r--arch/xtensa/include/uapi/asm/socket.h2
-rw-r--r--include/net/sock.h1
-rw-r--r--include/uapi/asm-generic/socket.h2
-rw-r--r--net/bluetooth/af_bluetooth.c3
-rw-r--r--net/core/datagram.c4
-rw-r--r--net/core/sock.c8
-rw-r--r--net/iucv/af_iucv.c3
-rw-r--r--net/nfc/llcp/sock.c3
-rw-r--r--net/sctp/socket.c3
-rw-r--r--net/unix/af_unix.c4
23 files changed, 53 insertions, 6 deletions
diff --git a/arch/alpha/include/uapi/asm/socket.h b/arch/alpha/include/uapi/asm/socket.h
index c5195524d1ef..eee6ea76bdaf 100644
--- a/arch/alpha/include/uapi/asm/socket.h
+++ b/arch/alpha/include/uapi/asm/socket.h
@@ -79,4 +79,6 @@
79 79
80#define SO_LOCK_FILTER 44 80#define SO_LOCK_FILTER 44
81 81
82#define SO_SELECT_ERR_QUEUE 45
83
82#endif /* _UAPI_ASM_SOCKET_H */ 84#endif /* _UAPI_ASM_SOCKET_H */
diff --git a/arch/avr32/include/uapi/asm/socket.h b/arch/avr32/include/uapi/asm/socket.h
index 51c6401582ea..37401f535126 100644
--- a/arch/avr32/include/uapi/asm/socket.h
+++ b/arch/avr32/include/uapi/asm/socket.h
@@ -72,4 +72,6 @@
72 72
73#define SO_LOCK_FILTER 44 73#define SO_LOCK_FILTER 44
74 74
75#define SO_SELECT_ERR_QUEUE 45
76
75#endif /* __ASM_AVR32_SOCKET_H */ 77#endif /* __ASM_AVR32_SOCKET_H */
diff --git a/arch/cris/include/uapi/asm/socket.h b/arch/cris/include/uapi/asm/socket.h
index 50692b738c75..ba409c9947bc 100644
--- a/arch/cris/include/uapi/asm/socket.h
+++ b/arch/cris/include/uapi/asm/socket.h
@@ -74,6 +74,8 @@
74 74
75#define SO_LOCK_FILTER 44 75#define SO_LOCK_FILTER 44
76 76
77#define SO_SELECT_ERR_QUEUE 45
78
77#endif /* _ASM_SOCKET_H */ 79#endif /* _ASM_SOCKET_H */
78 80
79 81
diff --git a/arch/frv/include/uapi/asm/socket.h b/arch/frv/include/uapi/asm/socket.h
index 595391f0f98c..31dbb5d8e13d 100644
--- a/arch/frv/include/uapi/asm/socket.h
+++ b/arch/frv/include/uapi/asm/socket.h
@@ -72,5 +72,7 @@
72 72
73#define SO_LOCK_FILTER 44 73#define SO_LOCK_FILTER 44
74 74
75#define SO_SELECT_ERR_QUEUE 45
76
75#endif /* _ASM_SOCKET_H */ 77#endif /* _ASM_SOCKET_H */
76 78
diff --git a/arch/h8300/include/uapi/asm/socket.h b/arch/h8300/include/uapi/asm/socket.h
index 43e32621da7d..5d1c6d0870e6 100644
--- a/arch/h8300/include/uapi/asm/socket.h
+++ b/arch/h8300/include/uapi/asm/socket.h
@@ -72,4 +72,6 @@
72 72
73#define SO_LOCK_FILTER 44 73#define SO_LOCK_FILTER 44
74 74
75#define SO_SELECT_ERR_QUEUE 45
76
75#endif /* _ASM_SOCKET_H */ 77#endif /* _ASM_SOCKET_H */
diff --git a/arch/ia64/include/uapi/asm/socket.h b/arch/ia64/include/uapi/asm/socket.h
index c567adc8bea5..6b4329f18b29 100644
--- a/arch/ia64/include/uapi/asm/socket.h
+++ b/arch/ia64/include/uapi/asm/socket.h
@@ -81,4 +81,6 @@
81 81
82#define SO_LOCK_FILTER 44 82#define SO_LOCK_FILTER 44
83 83
84#define SO_SELECT_ERR_QUEUE 45
85
84#endif /* _ASM_IA64_SOCKET_H */ 86#endif /* _ASM_IA64_SOCKET_H */
diff --git a/arch/m32r/include/uapi/asm/socket.h b/arch/m32r/include/uapi/asm/socket.h
index 519afa2755db..2a3b59e0e171 100644
--- a/arch/m32r/include/uapi/asm/socket.h
+++ b/arch/m32r/include/uapi/asm/socket.h
@@ -72,4 +72,6 @@
72 72
73#define SO_LOCK_FILTER 44 73#define SO_LOCK_FILTER 44
74 74
75#define SO_SELECT_ERR_QUEUE 45
76
75#endif /* _ASM_M32R_SOCKET_H */ 77#endif /* _ASM_M32R_SOCKET_H */
diff --git a/arch/mips/include/uapi/asm/socket.h b/arch/mips/include/uapi/asm/socket.h
index 47132f44c955..3b211507be7f 100644
--- a/arch/mips/include/uapi/asm/socket.h
+++ b/arch/mips/include/uapi/asm/socket.h
@@ -90,4 +90,6 @@
90 90
91#define SO_LOCK_FILTER 44 91#define SO_LOCK_FILTER 44
92 92
93#define SO_SELECT_ERR_QUEUE 45
94
93#endif /* _UAPI_ASM_SOCKET_H */ 95#endif /* _UAPI_ASM_SOCKET_H */
diff --git a/arch/mn10300/include/uapi/asm/socket.h b/arch/mn10300/include/uapi/asm/socket.h
index 5c7c7c988544..b4ce844c9391 100644
--- a/arch/mn10300/include/uapi/asm/socket.h
+++ b/arch/mn10300/include/uapi/asm/socket.h
@@ -72,4 +72,6 @@
72 72
73#define SO_LOCK_FILTER 44 73#define SO_LOCK_FILTER 44
74 74
75#define SO_SELECT_ERR_QUEUE 45
76
75#endif /* _ASM_SOCKET_H */ 77#endif /* _ASM_SOCKET_H */
diff --git a/arch/parisc/include/uapi/asm/socket.h b/arch/parisc/include/uapi/asm/socket.h
index 526e4b9aece0..70c512a386f7 100644
--- a/arch/parisc/include/uapi/asm/socket.h
+++ b/arch/parisc/include/uapi/asm/socket.h
@@ -71,6 +71,8 @@
71 71
72#define SO_LOCK_FILTER 0x4025 72#define SO_LOCK_FILTER 0x4025
73 73
74#define SO_SELECT_ERR_QUEUE 0x4026
75
74/* O_NONBLOCK clashes with the bits used for socket types. Therefore we 76/* O_NONBLOCK clashes with the bits used for socket types. Therefore we
75 * have to define SOCK_NONBLOCK to a different value here. 77 * have to define SOCK_NONBLOCK to a different value here.
76 */ 78 */
diff --git a/arch/powerpc/include/uapi/asm/socket.h b/arch/powerpc/include/uapi/asm/socket.h
index a26dcaece509..a36daf3c6f9a 100644
--- a/arch/powerpc/include/uapi/asm/socket.h
+++ b/arch/powerpc/include/uapi/asm/socket.h
@@ -79,4 +79,6 @@
79 79
80#define SO_LOCK_FILTER 44 80#define SO_LOCK_FILTER 44
81 81
82#define SO_SELECT_ERR_QUEUE 45
83
82#endif /* _ASM_POWERPC_SOCKET_H */ 84#endif /* _ASM_POWERPC_SOCKET_H */
diff --git a/arch/s390/include/uapi/asm/socket.h b/arch/s390/include/uapi/asm/socket.h
index f99eea7fff0f..2dacb306835c 100644
--- a/arch/s390/include/uapi/asm/socket.h
+++ b/arch/s390/include/uapi/asm/socket.h
@@ -78,4 +78,6 @@
78 78
79#define SO_LOCK_FILTER 44 79#define SO_LOCK_FILTER 44
80 80
81#define SO_SELECT_ERR_QUEUE 45
82
81#endif /* _ASM_SOCKET_H */ 83#endif /* _ASM_SOCKET_H */
diff --git a/arch/sparc/include/uapi/asm/socket.h b/arch/sparc/include/uapi/asm/socket.h
index cbbad74b2e06..89f49b68a21c 100644
--- a/arch/sparc/include/uapi/asm/socket.h
+++ b/arch/sparc/include/uapi/asm/socket.h
@@ -68,6 +68,8 @@
68 68
69#define SO_LOCK_FILTER 0x0028 69#define SO_LOCK_FILTER 0x0028
70 70
71#define SO_SELECT_ERR_QUEUE 0x0029
72
71/* Security levels - as per NRL IPv6 - don't actually do anything */ 73/* Security levels - as per NRL IPv6 - don't actually do anything */
72#define SO_SECURITY_AUTHENTICATION 0x5001 74#define SO_SECURITY_AUTHENTICATION 0x5001
73#define SO_SECURITY_ENCRYPTION_TRANSPORT 0x5002 75#define SO_SECURITY_ENCRYPTION_TRANSPORT 0x5002
diff --git a/arch/xtensa/include/uapi/asm/socket.h b/arch/xtensa/include/uapi/asm/socket.h
index 35905cb6e419..a8f44f50e651 100644
--- a/arch/xtensa/include/uapi/asm/socket.h
+++ b/arch/xtensa/include/uapi/asm/socket.h
@@ -83,4 +83,6 @@
83 83
84#define SO_LOCK_FILTER 44 84#define SO_LOCK_FILTER 44
85 85
86#define SO_SELECT_ERR_QUEUE 45
87
86#endif /* _XTENSA_SOCKET_H */ 88#endif /* _XTENSA_SOCKET_H */
diff --git a/include/net/sock.h b/include/net/sock.h
index 14f6e9d19dc7..08f05f964737 100644
--- a/include/net/sock.h
+++ b/include/net/sock.h
@@ -667,6 +667,7 @@ enum sock_flags {
667 * user-space instead. 667 * user-space instead.
668 */ 668 */
669 SOCK_FILTER_LOCKED, /* Filter cannot be changed anymore */ 669 SOCK_FILTER_LOCKED, /* Filter cannot be changed anymore */
670 SOCK_SELECT_ERR_QUEUE, /* Wake select on error queue */
670}; 671};
671 672
672static inline void sock_copy_flags(struct sock *nsk, struct sock *osk) 673static inline void sock_copy_flags(struct sock *nsk, struct sock *osk)
diff --git a/include/uapi/asm-generic/socket.h b/include/uapi/asm-generic/socket.h
index 4ef3acbba5da..c5d2e3a1cf68 100644
--- a/include/uapi/asm-generic/socket.h
+++ b/include/uapi/asm-generic/socket.h
@@ -74,4 +74,6 @@
74 74
75#define SO_LOCK_FILTER 44 75#define SO_LOCK_FILTER 44
76 76
77#define SO_SELECT_ERR_QUEUE 45
78
77#endif /* __ASM_GENERIC_SOCKET_H */ 79#endif /* __ASM_GENERIC_SOCKET_H */
diff --git a/net/bluetooth/af_bluetooth.c b/net/bluetooth/af_bluetooth.c
index d3ee69b35a78..409902f892ff 100644
--- a/net/bluetooth/af_bluetooth.c
+++ b/net/bluetooth/af_bluetooth.c
@@ -422,7 +422,8 @@ unsigned int bt_sock_poll(struct file *file, struct socket *sock,
422 return bt_accept_poll(sk); 422 return bt_accept_poll(sk);
423 423
424 if (sk->sk_err || !skb_queue_empty(&sk->sk_error_queue)) 424 if (sk->sk_err || !skb_queue_empty(&sk->sk_error_queue))
425 mask |= POLLERR; 425 mask |= POLLERR |
426 sock_flag(sk, SOCK_SELECT_ERR_QUEUE) ? POLLPRI : 0;
426 427
427 if (sk->sk_shutdown & RCV_SHUTDOWN) 428 if (sk->sk_shutdown & RCV_SHUTDOWN)
428 mask |= POLLRDHUP | POLLIN | POLLRDNORM; 429 mask |= POLLRDHUP | POLLIN | POLLRDNORM;
diff --git a/net/core/datagram.c b/net/core/datagram.c
index 368f9c3f9dc6..36da5b663514 100644
--- a/net/core/datagram.c
+++ b/net/core/datagram.c
@@ -749,7 +749,9 @@ unsigned int datagram_poll(struct file *file, struct socket *sock,
749 749
750 /* exceptional events? */ 750 /* exceptional events? */
751 if (sk->sk_err || !skb_queue_empty(&sk->sk_error_queue)) 751 if (sk->sk_err || !skb_queue_empty(&sk->sk_error_queue))
752 mask |= POLLERR; 752 mask |= POLLERR |
753 sock_flag(sk, SOCK_SELECT_ERR_QUEUE) ? POLLPRI : 0;
754
753 if (sk->sk_shutdown & RCV_SHUTDOWN) 755 if (sk->sk_shutdown & RCV_SHUTDOWN)
754 mask |= POLLRDHUP | POLLIN | POLLRDNORM; 756 mask |= POLLRDHUP | POLLIN | POLLRDNORM;
755 if (sk->sk_shutdown == SHUTDOWN_MASK) 757 if (sk->sk_shutdown == SHUTDOWN_MASK)
diff --git a/net/core/sock.c b/net/core/sock.c
index a19e728d5fb6..2ff5f3619a8d 100644
--- a/net/core/sock.c
+++ b/net/core/sock.c
@@ -907,6 +907,10 @@ set_rcvbuf:
907 sock_valbool_flag(sk, SOCK_NOFCS, valbool); 907 sock_valbool_flag(sk, SOCK_NOFCS, valbool);
908 break; 908 break;
909 909
910 case SO_SELECT_ERR_QUEUE:
911 sock_valbool_flag(sk, SOCK_SELECT_ERR_QUEUE, valbool);
912 break;
913
910 default: 914 default:
911 ret = -ENOPROTOOPT; 915 ret = -ENOPROTOOPT;
912 break; 916 break;
@@ -1160,6 +1164,10 @@ int sock_getsockopt(struct socket *sock, int level, int optname,
1160 v.val = sock_flag(sk, SOCK_FILTER_LOCKED); 1164 v.val = sock_flag(sk, SOCK_FILTER_LOCKED);
1161 break; 1165 break;
1162 1166
1167 case SO_SELECT_ERR_QUEUE:
1168 v.val = sock_flag(sk, SOCK_SELECT_ERR_QUEUE);
1169 break;
1170
1163 default: 1171 default:
1164 return -ENOPROTOOPT; 1172 return -ENOPROTOOPT;
1165 } 1173 }
diff --git a/net/iucv/af_iucv.c b/net/iucv/af_iucv.c
index a7d11ffe4284..f0550a38f295 100644
--- a/net/iucv/af_iucv.c
+++ b/net/iucv/af_iucv.c
@@ -1461,7 +1461,8 @@ unsigned int iucv_sock_poll(struct file *file, struct socket *sock,
1461 return iucv_accept_poll(sk); 1461 return iucv_accept_poll(sk);
1462 1462
1463 if (sk->sk_err || !skb_queue_empty(&sk->sk_error_queue)) 1463 if (sk->sk_err || !skb_queue_empty(&sk->sk_error_queue))
1464 mask |= POLLERR; 1464 mask |= POLLERR |
1465 sock_flag(sk, SOCK_SELECT_ERR_QUEUE) ? POLLPRI : 0;
1465 1466
1466 if (sk->sk_shutdown & RCV_SHUTDOWN) 1467 if (sk->sk_shutdown & RCV_SHUTDOWN)
1467 mask |= POLLRDHUP; 1468 mask |= POLLRDHUP;
diff --git a/net/nfc/llcp/sock.c b/net/nfc/llcp/sock.c
index f1b377e247fe..2d55e8a45958 100644
--- a/net/nfc/llcp/sock.c
+++ b/net/nfc/llcp/sock.c
@@ -521,7 +521,8 @@ static unsigned int llcp_sock_poll(struct file *file, struct socket *sock,
521 return llcp_accept_poll(sk); 521 return llcp_accept_poll(sk);
522 522
523 if (sk->sk_err || !skb_queue_empty(&sk->sk_error_queue)) 523 if (sk->sk_err || !skb_queue_empty(&sk->sk_error_queue))
524 mask |= POLLERR; 524 mask |= POLLERR |
525 sock_flag(sk, SOCK_SELECT_ERR_QUEUE) ? POLLPRI : 0;
525 526
526 if (!skb_queue_empty(&sk->sk_receive_queue)) 527 if (!skb_queue_empty(&sk->sk_receive_queue))
527 mask |= POLLIN | POLLRDNORM; 528 mask |= POLLIN | POLLRDNORM;
diff --git a/net/sctp/socket.c b/net/sctp/socket.c
index b9070736b8d9..dd21ae3013d8 100644
--- a/net/sctp/socket.c
+++ b/net/sctp/socket.c
@@ -6185,7 +6185,8 @@ unsigned int sctp_poll(struct file *file, struct socket *sock, poll_table *wait)
6185 6185
6186 /* Is there any exceptional events? */ 6186 /* Is there any exceptional events? */
6187 if (sk->sk_err || !skb_queue_empty(&sk->sk_error_queue)) 6187 if (sk->sk_err || !skb_queue_empty(&sk->sk_error_queue))
6188 mask |= POLLERR; 6188 mask |= POLLERR |
6189 sock_flag(sk, SOCK_SELECT_ERR_QUEUE) ? POLLPRI : 0;
6189 if (sk->sk_shutdown & RCV_SHUTDOWN) 6190 if (sk->sk_shutdown & RCV_SHUTDOWN)
6190 mask |= POLLRDHUP | POLLIN | POLLRDNORM; 6191 mask |= POLLRDHUP | POLLIN | POLLRDNORM;
6191 if (sk->sk_shutdown == SHUTDOWN_MASK) 6192 if (sk->sk_shutdown == SHUTDOWN_MASK)
diff --git a/net/unix/af_unix.c b/net/unix/af_unix.c
index 971282b6f6a3..fb7a63ff71a5 100644
--- a/net/unix/af_unix.c
+++ b/net/unix/af_unix.c
@@ -2196,7 +2196,9 @@ static unsigned int unix_dgram_poll(struct file *file, struct socket *sock,
2196 2196
2197 /* exceptional events? */ 2197 /* exceptional events? */
2198 if (sk->sk_err || !skb_queue_empty(&sk->sk_error_queue)) 2198 if (sk->sk_err || !skb_queue_empty(&sk->sk_error_queue))
2199 mask |= POLLERR; 2199 mask |= POLLERR |
2200 sock_flag(sk, SOCK_SELECT_ERR_QUEUE) ? POLLPRI : 0;
2201
2200 if (sk->sk_shutdown & RCV_SHUTDOWN) 2202 if (sk->sk_shutdown & RCV_SHUTDOWN)
2201 mask |= POLLRDHUP | POLLIN | POLLRDNORM; 2203 mask |= POLLRDHUP | POLLIN | POLLRDNORM;
2202 if (sk->sk_shutdown == SHUTDOWN_MASK) 2204 if (sk->sk_shutdown == SHUTDOWN_MASK)