diff options
Diffstat (limited to 'net/socket.c')
| -rw-r--r-- | net/socket.c | 28 |
1 files changed, 17 insertions, 11 deletions
diff --git a/net/socket.c b/net/socket.c index 792f0313ea91..e6945e318f02 100644 --- a/net/socket.c +++ b/net/socket.c | |||
| @@ -252,7 +252,7 @@ static struct inode *sock_alloc_inode(struct super_block *sb) | |||
| 252 | init_waitqueue_head(&wq->wait); | 252 | init_waitqueue_head(&wq->wait); |
| 253 | wq->fasync_list = NULL; | 253 | wq->fasync_list = NULL; |
| 254 | wq->flags = 0; | 254 | wq->flags = 0; |
| 255 | RCU_INIT_POINTER(ei->socket.wq, wq); | 255 | ei->socket.wq = wq; |
| 256 | 256 | ||
| 257 | ei->socket.state = SS_UNCONNECTED; | 257 | ei->socket.state = SS_UNCONNECTED; |
| 258 | ei->socket.flags = 0; | 258 | ei->socket.flags = 0; |
| @@ -266,11 +266,9 @@ static struct inode *sock_alloc_inode(struct super_block *sb) | |||
| 266 | static void sock_destroy_inode(struct inode *inode) | 266 | static void sock_destroy_inode(struct inode *inode) |
| 267 | { | 267 | { |
| 268 | struct socket_alloc *ei; | 268 | struct socket_alloc *ei; |
| 269 | struct socket_wq *wq; | ||
| 270 | 269 | ||
| 271 | ei = container_of(inode, struct socket_alloc, vfs_inode); | 270 | ei = container_of(inode, struct socket_alloc, vfs_inode); |
| 272 | wq = rcu_dereference_protected(ei->socket.wq, 1); | 271 | kfree_rcu(ei->socket.wq, rcu); |
| 273 | kfree_rcu(wq, rcu); | ||
| 274 | kmem_cache_free(sock_inode_cachep, ei); | 272 | kmem_cache_free(sock_inode_cachep, ei); |
| 275 | } | 273 | } |
| 276 | 274 | ||
| @@ -585,7 +583,7 @@ static void __sock_release(struct socket *sock, struct inode *inode) | |||
| 585 | module_put(owner); | 583 | module_put(owner); |
| 586 | } | 584 | } |
| 587 | 585 | ||
| 588 | if (rcu_dereference_protected(sock->wq, 1)->fasync_list) | 586 | if (sock->wq->fasync_list) |
| 589 | pr_err("%s: fasync list not empty!\n", __func__); | 587 | pr_err("%s: fasync list not empty!\n", __func__); |
| 590 | 588 | ||
| 591 | if (!sock->file) { | 589 | if (!sock->file) { |
| @@ -1112,12 +1110,21 @@ EXPORT_SYMBOL(sock_create_lite); | |||
| 1112 | static __poll_t sock_poll(struct file *file, poll_table *wait) | 1110 | static __poll_t sock_poll(struct file *file, poll_table *wait) |
| 1113 | { | 1111 | { |
| 1114 | struct socket *sock = file->private_data; | 1112 | struct socket *sock = file->private_data; |
| 1115 | __poll_t events = poll_requested_events(wait); | 1113 | __poll_t events = poll_requested_events(wait), flag = 0; |
| 1116 | 1114 | ||
| 1117 | sock_poll_busy_loop(sock, events); | ||
| 1118 | if (!sock->ops->poll) | 1115 | if (!sock->ops->poll) |
| 1119 | return 0; | 1116 | return 0; |
| 1120 | return sock->ops->poll(file, sock, wait) | sock_poll_busy_flag(sock); | 1117 | |
| 1118 | if (sk_can_busy_loop(sock->sk)) { | ||
| 1119 | /* poll once if requested by the syscall */ | ||
| 1120 | if (events & POLL_BUSY_LOOP) | ||
| 1121 | sk_busy_loop(sock->sk, 1); | ||
| 1122 | |||
| 1123 | /* if this socket can poll_ll, tell the system call */ | ||
| 1124 | flag = POLL_BUSY_LOOP; | ||
| 1125 | } | ||
| 1126 | |||
| 1127 | return sock->ops->poll(file, sock, wait) | flag; | ||
| 1121 | } | 1128 | } |
| 1122 | 1129 | ||
| 1123 | static int sock_mmap(struct file *file, struct vm_area_struct *vma) | 1130 | static int sock_mmap(struct file *file, struct vm_area_struct *vma) |
| @@ -1154,7 +1161,7 @@ static int sock_fasync(int fd, struct file *filp, int on) | |||
| 1154 | return -EINVAL; | 1161 | return -EINVAL; |
| 1155 | 1162 | ||
| 1156 | lock_sock(sk); | 1163 | lock_sock(sk); |
| 1157 | wq = rcu_dereference_protected(sock->wq, lockdep_sock_is_held(sk)); | 1164 | wq = sock->wq; |
| 1158 | fasync_helper(fd, filp, on, &wq->fasync_list); | 1165 | fasync_helper(fd, filp, on, &wq->fasync_list); |
| 1159 | 1166 | ||
| 1160 | if (!wq->fasync_list) | 1167 | if (!wq->fasync_list) |
| @@ -2671,8 +2678,7 @@ EXPORT_SYMBOL(sock_unregister); | |||
| 2671 | 2678 | ||
| 2672 | bool sock_is_registered(int family) | 2679 | bool sock_is_registered(int family) |
| 2673 | { | 2680 | { |
| 2674 | return family < NPROTO && | 2681 | return family < NPROTO && rcu_access_pointer(net_families[family]); |
| 2675 | rcu_access_pointer(net_families[array_index_nospec(family, NPROTO)]); | ||
| 2676 | } | 2682 | } |
| 2677 | 2683 | ||
| 2678 | static int __init sock_init(void) | 2684 | static int __init sock_init(void) |
