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

Commit def82a1d authored by Jarek Poplawski's avatar Jarek Poplawski Committed by David S. Miller
Browse files

net: Change handling of the __QDISC_STATE_SCHED flag in net_tx_action().



Change handling of the __QDISC_STATE_SCHED flag in net_tx_action() to
enable proper control in dev_deactivate(). Now, if this flag is seen
as unset under root_lock means a qdisc can't be netif_scheduled.

Signed-off-by: default avatarJarek Poplawski <jarkao2@gmail.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent a9312ae8
Loading
Loading
Loading
Loading
+19 −15
Original line number Diff line number Diff line
@@ -1339,9 +1339,8 @@ static void dev_queue_xmit_nit(struct sk_buff *skb, struct net_device *dev)
}


void __netif_schedule(struct Qdisc *q)
static inline void __netif_reschedule(struct Qdisc *q)
{
	if (!test_and_set_bit(__QDISC_STATE_SCHED, &q->state)) {
	struct softnet_data *sd;
	unsigned long flags;

@@ -1352,6 +1351,11 @@ void __netif_schedule(struct Qdisc *q)
	raise_softirq_irqoff(NET_TX_SOFTIRQ);
	local_irq_restore(flags);
}

void __netif_schedule(struct Qdisc *q)
{
	if (!test_and_set_bit(__QDISC_STATE_SCHED, &q->state))
		__netif_reschedule(q);
}
EXPORT_SYMBOL(__netif_schedule);

@@ -1980,15 +1984,15 @@ static void net_tx_action(struct softirq_action *h)

			head = head->next_sched;

			smp_mb__before_clear_bit();
			clear_bit(__QDISC_STATE_SCHED, &q->state);

			root_lock = qdisc_lock(q);
			if (spin_trylock(root_lock)) {
				smp_mb__before_clear_bit();
				clear_bit(__QDISC_STATE_SCHED,
					  &q->state);
				qdisc_run(q);
				spin_unlock(root_lock);
			} else {
				__netif_schedule(q);
				__netif_reschedule(q);
			}
		}
	}