Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 5b4d7208 authored by David Woodhouse's avatar David Woodhouse
Browse files

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: default avatarDavid Woodhouse <David.Woodhouse@intel.com>
Acked-by: default avatarKrzysztof Mazur <krzysiek@podlesie.net>
parent 9eba2526
Loading
Loading
Loading
Loading
+19 −2
Original line number Diff line number Diff line
@@ -113,6 +113,16 @@ static void pppoatm_release_cb(struct atm_vcc *atmvcc)
{
	struct pppoatm_vcc *pvcc = atmvcc_to_pvcc(atmvcc);

	/*
	 * As in pppoatm_pop(), it's safe to clear the BLOCKED bit here because
	 * the wakeup *can't* race with pppoatm_send(). They both hold the PPP
	 * channel's ->downl lock. And the potential race with *setting* it,
	 * which leads to the double-check dance in pppoatm_may_send(), doesn't
	 * exist here. In the sock_owned_by_user() case in pppoatm_send(), we
	 * set the BLOCKED bit while the socket is still locked. We know that
	 * ->release_cb() can't be called until that's done.
	 */
	if (test_and_clear_bit(BLOCKED, &pvcc->blocked))
		tasklet_schedule(&pvcc->wakeup_tasklet);
	if (pvcc->old_release_cb)
		pvcc->old_release_cb(atmvcc);
@@ -292,8 +302,15 @@ static int pppoatm_send(struct ppp_channel *chan, struct sk_buff *skb)

	vcc = ATM_SKB(skb)->vcc;
	bh_lock_sock(sk_atm(vcc));
	if (sock_owned_by_user(sk_atm(vcc)))
	if (sock_owned_by_user(sk_atm(vcc))) {
		/*
		 * Needs to happen (and be flushed, hence test_and_) before we unlock
		 * the socket. It needs to be seen by the time our ->release_cb gets
		 * called.
		 */
		test_and_set_bit(BLOCKED, &pvcc->blocked);
		goto nospace;
	}
	if (test_bit(ATM_VF_RELEASED, &vcc->flags) ||
	    test_bit(ATM_VF_CLOSE, &vcc->flags) ||
	    !test_bit(ATM_VF_READY, &vcc->flags)) {