mirror of
https://github.com/BobTheBlinker/android_kernel_motorola_sm6375.git
synced 2026-10-30 11:41:38 -04:00
net: sock_def_readable() and friends RCU conversion
sk_callback_lock rwlock actually protects sk->sk_sleep pointer, so we need two atomic operations (and associated dirtying) per incoming packet. RCU conversion is pretty much needed : 1) Add a new structure, called "struct socket_wq" to hold all fields that will need rcu_read_lock() protection (currently: a wait_queue_head_t and a struct fasync_struct pointer). [Future patch will add a list anchor for wakeup coalescing] 2) Attach one of such structure to each "struct socket" created in sock_alloc_inode(). 3) Respect RCU grace period when freeing a "struct socket_wq" 4) Change sk_sleep pointer in "struct sock" by sk_wq, pointer to "struct socket_wq" 5) Change sk_sleep() function to use new sk->sk_wq instead of sk->sk_sleep 6) Change sk_has_sleeper() to wq_has_sleeper() that must be used inside a rcu_read_lock() section. 7) Change all sk_has_sleeper() callers to : - Use rcu_read_lock() instead of read_lock(&sk->sk_callback_lock) - Use wq_has_sleeper() to eventually wakeup tasks. - Use rcu_read_unlock() instead of read_unlock(&sk->sk_callback_lock) 8) sock_wake_async() is modified to use rcu protection as well. 9) Exceptions : macvtap, drivers/net/tun.c, af_unix use integrated "struct socket_wq" instead of dynamically allocated ones. They dont need rcu freeing. Some cleanups or followups are probably needed, (possible sk_callback_lock conversion to a spinlock for example...). Signed-off-by: Eric Dumazet <[email protected]> Signed-off-by: David S. Miller <[email protected]>
This commit is contained in:
parent
83d7eb2979
commit
4381548237
16 changed files with 181 additions and 114 deletions
|
|
@ -664,12 +664,12 @@ static int pep_wait_connreq(struct sock *sk, int noblock)
|
|||
if (signal_pending(tsk))
|
||||
return sock_intr_errno(timeo);
|
||||
|
||||
prepare_to_wait_exclusive(&sk->sk_socket->wait, &wait,
|
||||
prepare_to_wait_exclusive(sk_sleep(sk), &wait,
|
||||
TASK_INTERRUPTIBLE);
|
||||
release_sock(sk);
|
||||
timeo = schedule_timeout(timeo);
|
||||
lock_sock(sk);
|
||||
finish_wait(&sk->sk_socket->wait, &wait);
|
||||
finish_wait(sk_sleep(sk), &wait);
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
|
@ -910,10 +910,10 @@ disabled:
|
|||
goto out;
|
||||
}
|
||||
|
||||
prepare_to_wait(&sk->sk_socket->wait, &wait,
|
||||
prepare_to_wait(sk_sleep(sk), &wait,
|
||||
TASK_INTERRUPTIBLE);
|
||||
done = sk_wait_event(sk, &timeo, atomic_read(&pn->tx_credits));
|
||||
finish_wait(&sk->sk_socket->wait, &wait);
|
||||
finish_wait(sk_sleep(sk), &wait);
|
||||
|
||||
if (sk->sk_state != TCP_ESTABLISHED)
|
||||
goto disabled;
|
||||
|
|
|
|||
|
|
@ -265,7 +265,7 @@ static unsigned int pn_socket_poll(struct file *file, struct socket *sock,
|
|||
struct pep_sock *pn = pep_sk(sk);
|
||||
unsigned int mask = 0;
|
||||
|
||||
poll_wait(file, &sock->wait, wait);
|
||||
poll_wait(file, sk_sleep(sk), wait);
|
||||
|
||||
switch (sk->sk_state) {
|
||||
case TCP_LISTEN:
|
||||
|
|
|
|||
Loading…
Reference in a new issue