mirror of https://gitee.com/openkylin/linux.git
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: Jarek Poplawski <jarkao2@gmail.com> Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
parent
a9312ae893
commit
def82a1db1
|
@ -1339,19 +1339,23 @@ static void dev_queue_xmit_nit(struct sk_buff *skb, struct net_device *dev)
|
|||
}
|
||||
|
||||
|
||||
static inline void __netif_reschedule(struct Qdisc *q)
|
||||
{
|
||||
struct softnet_data *sd;
|
||||
unsigned long flags;
|
||||
|
||||
local_irq_save(flags);
|
||||
sd = &__get_cpu_var(softnet_data);
|
||||
q->next_sched = sd->output_queue;
|
||||
sd->output_queue = 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)) {
|
||||
struct softnet_data *sd;
|
||||
unsigned long flags;
|
||||
|
||||
local_irq_save(flags);
|
||||
sd = &__get_cpu_var(softnet_data);
|
||||
q->next_sched = sd->output_queue;
|
||||
sd->output_queue = q;
|
||||
raise_softirq_irqoff(NET_TX_SOFTIRQ);
|
||||
local_irq_restore(flags);
|
||||
}
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue