aboutsummaryrefslogtreecommitdiffstats
path: root/net/atm
diff options
context:
space:
mode:
authorDavid Woodhouse <David.Woodhouse@intel.com>2012-11-28 05:15:05 -0500
committerDavid Woodhouse <David.Woodhouse@intel.com>2012-12-01 19:05:20 -0500
commit5b4d72080f49498d2390563aa90f5bc31785406c (patch)
tree62da5867de0ff07672d07687adee6ce7bb9388af /net/atm
parent9eba25268e5862571d53122065616c456fe1142a (diff)
pppoatm: optimise PPP channel wakeups after sock_owned_by_user()
We don't need to schedule the wakeup tasklet on *every* unlock; only if we actually blocked the channel in the first place. Signed-off-by: David Woodhouse <David.Woodhouse@intel.com> Acked-by: Krzysztof Mazur <krzysiek@podlesie.net>
Diffstat (limited to 'net/atm')
-rw-r--r--net/atm/pppoatm.c21
1 files changed, 19 insertions, 2 deletions
diff --git a/net/atm/pppoatm.c b/net/atm/pppoatm.c
index 9fcda8c85e9a..8c93267ce969 100644
--- a/net/atm/pppoatm.c
+++ b/net/atm/pppoatm.c
@@ -113,7 +113,17 @@ static void pppoatm_release_cb(struct atm_vcc *atmvcc)
113{ 113{
114 struct pppoatm_vcc *pvcc = atmvcc_to_pvcc(atmvcc); 114 struct pppoatm_vcc *pvcc = atmvcc_to_pvcc(atmvcc);
115 115
116 tasklet_schedule(&pvcc->wakeup_tasklet); 116 /*
117 * As in pppoatm_pop(), it's safe to clear the BLOCKED bit here because
118 * the wakeup *can't* race with pppoatm_send(). They both hold the PPP
119 * channel's ->downl lock. And the potential race with *setting* it,
120 * which leads to the double-check dance in pppoatm_may_send(), doesn't
121 * exist here. In the sock_owned_by_user() case in pppoatm_send(), we
122 * set the BLOCKED bit while the socket is still locked. We know that
123 * ->release_cb() can't be called until that's done.
124 */
125 if (test_and_clear_bit(BLOCKED, &pvcc->blocked))
126 tasklet_schedule(&pvcc->wakeup_tasklet);
117 if (pvcc->old_release_cb) 127 if (pvcc->old_release_cb)
118 pvcc->old_release_cb(atmvcc); 128 pvcc->old_release_cb(atmvcc);
119} 129}
@@ -292,8 +302,15 @@ static int pppoatm_send(struct ppp_channel *chan, struct sk_buff *skb)
292 302
293 vcc = ATM_SKB(skb)->vcc; 303 vcc = ATM_SKB(skb)->vcc;
294 bh_lock_sock(sk_atm(vcc)); 304 bh_lock_sock(sk_atm(vcc));
295 if (sock_owned_by_user(sk_atm(vcc))) 305 if (sock_owned_by_user(sk_atm(vcc))) {
306 /*
307 * Needs to happen (and be flushed, hence test_and_) before we unlock
308 * the socket. It needs to be seen by the time our ->release_cb gets
309 * called.
310 */
311 test_and_set_bit(BLOCKED, &pvcc->blocked);
296 goto nospace; 312 goto nospace;
313 }
297 if (test_bit(ATM_VF_RELEASED, &vcc->flags) || 314 if (test_bit(ATM_VF_RELEASED, &vcc->flags) ||
298 test_bit(ATM_VF_CLOSE, &vcc->flags) || 315 test_bit(ATM_VF_CLOSE, &vcc->flags) ||
299 !test_bit(ATM_VF_READY, &vcc->flags)) { 316 !test_bit(ATM_VF_READY, &vcc->flags)) {