aboutsummaryrefslogtreecommitdiffstats
path: root/net/socket.c
diff options
context:
space:
mode:
Diffstat (limited to 'net/socket.c')
-rw-r--r--net/socket.c28
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)
266static void sock_destroy_inode(struct inode *inode) 266static 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);
1112static __poll_t sock_poll(struct file *file, poll_table *wait) 1110static __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
1123static int sock_mmap(struct file *file, struct vm_area_struct *vma) 1130static 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
2672bool sock_is_registered(int family) 2679bool 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
2678static int __init sock_init(void) 2684static int __init sock_init(void)