diff options
Diffstat (limited to 'net')
-rw-r--r-- | net/core/dev.c | 4 | ||||
-rw-r--r-- | net/sched/sch_api.c | 57 | ||||
-rw-r--r-- | net/sched/sch_generic.c | 8 |
3 files changed, 23 insertions, 46 deletions
diff --git a/net/core/dev.c b/net/core/dev.c index 8d13a9b9f1df..63d6bcddbf46 100644 --- a/net/core/dev.c +++ b/net/core/dev.c | |||
@@ -2100,7 +2100,7 @@ static int ing_filter(struct sk_buff *skb) | |||
2100 | rxq = &dev->rx_queue; | 2100 | rxq = &dev->rx_queue; |
2101 | 2101 | ||
2102 | q = rxq->qdisc; | 2102 | q = rxq->qdisc; |
2103 | if (q) { | 2103 | if (q != &noop_qdisc) { |
2104 | spin_lock(qdisc_lock(q)); | 2104 | spin_lock(qdisc_lock(q)); |
2105 | result = qdisc_enqueue_root(skb, q); | 2105 | result = qdisc_enqueue_root(skb, q); |
2106 | spin_unlock(qdisc_lock(q)); | 2106 | spin_unlock(qdisc_lock(q)); |
@@ -2113,7 +2113,7 @@ static inline struct sk_buff *handle_ing(struct sk_buff *skb, | |||
2113 | struct packet_type **pt_prev, | 2113 | struct packet_type **pt_prev, |
2114 | int *ret, struct net_device *orig_dev) | 2114 | int *ret, struct net_device *orig_dev) |
2115 | { | 2115 | { |
2116 | if (!skb->dev->rx_queue.qdisc) | 2116 | if (skb->dev->rx_queue.qdisc == &noop_qdisc) |
2117 | goto out; | 2117 | goto out; |
2118 | 2118 | ||
2119 | if (*pt_prev) { | 2119 | if (*pt_prev) { |
diff --git a/net/sched/sch_api.c b/net/sched/sch_api.c index b0601642e227..4840aff47256 100644 --- a/net/sched/sch_api.c +++ b/net/sched/sch_api.c | |||
@@ -572,44 +572,21 @@ static u32 qdisc_alloc_handle(struct net_device *dev) | |||
572 | static struct Qdisc *dev_graft_qdisc(struct netdev_queue *dev_queue, | 572 | static struct Qdisc *dev_graft_qdisc(struct netdev_queue *dev_queue, |
573 | struct Qdisc *qdisc) | 573 | struct Qdisc *qdisc) |
574 | { | 574 | { |
575 | struct Qdisc *oqdisc = dev_queue->qdisc_sleeping; | ||
575 | spinlock_t *root_lock; | 576 | spinlock_t *root_lock; |
576 | struct Qdisc *oqdisc; | ||
577 | int ingress; | ||
578 | |||
579 | ingress = 0; | ||
580 | if (qdisc && qdisc->flags&TCQ_F_INGRESS) | ||
581 | ingress = 1; | ||
582 | |||
583 | if (ingress) { | ||
584 | oqdisc = dev_queue->qdisc; | ||
585 | } else { | ||
586 | oqdisc = dev_queue->qdisc_sleeping; | ||
587 | } | ||
588 | 577 | ||
589 | root_lock = qdisc_root_lock(oqdisc); | 578 | root_lock = qdisc_root_lock(oqdisc); |
590 | spin_lock_bh(root_lock); | 579 | spin_lock_bh(root_lock); |
591 | 580 | ||
592 | if (ingress) { | 581 | /* Prune old scheduler */ |
593 | /* Prune old scheduler */ | 582 | if (oqdisc && atomic_read(&oqdisc->refcnt) <= 1) |
594 | if (oqdisc && atomic_read(&oqdisc->refcnt) <= 1) { | 583 | qdisc_reset(oqdisc); |
595 | /* delete */ | ||
596 | qdisc_reset(oqdisc); | ||
597 | dev_queue->qdisc = NULL; | ||
598 | } else { /* new */ | ||
599 | dev_queue->qdisc = qdisc; | ||
600 | } | ||
601 | 584 | ||
602 | } else { | 585 | /* ... and graft new one */ |
603 | /* Prune old scheduler */ | 586 | if (qdisc == NULL) |
604 | if (oqdisc && atomic_read(&oqdisc->refcnt) <= 1) | 587 | qdisc = &noop_qdisc; |
605 | qdisc_reset(oqdisc); | 588 | dev_queue->qdisc_sleeping = qdisc; |
606 | 589 | dev_queue->qdisc = &noop_qdisc; | |
607 | /* ... and graft new one */ | ||
608 | if (qdisc == NULL) | ||
609 | qdisc = &noop_qdisc; | ||
610 | dev_queue->qdisc_sleeping = qdisc; | ||
611 | dev_queue->qdisc = &noop_qdisc; | ||
612 | } | ||
613 | 590 | ||
614 | spin_unlock_bh(root_lock); | 591 | spin_unlock_bh(root_lock); |
615 | 592 | ||
@@ -678,7 +655,8 @@ static int qdisc_graft(struct net_device *dev, struct Qdisc *parent, | |||
678 | 655 | ||
679 | ingress = 0; | 656 | ingress = 0; |
680 | num_q = dev->num_tx_queues; | 657 | num_q = dev->num_tx_queues; |
681 | if (q && q->flags & TCQ_F_INGRESS) { | 658 | if ((q && q->flags & TCQ_F_INGRESS) || |
659 | (new && new->flags & TCQ_F_INGRESS)) { | ||
682 | num_q = 1; | 660 | num_q = 1; |
683 | ingress = 1; | 661 | ingress = 1; |
684 | } | 662 | } |
@@ -692,13 +670,10 @@ static int qdisc_graft(struct net_device *dev, struct Qdisc *parent, | |||
692 | if (!ingress) | 670 | if (!ingress) |
693 | dev_queue = netdev_get_tx_queue(dev, i); | 671 | dev_queue = netdev_get_tx_queue(dev, i); |
694 | 672 | ||
695 | if (ingress) { | 673 | old = dev_graft_qdisc(dev_queue, new); |
696 | old = dev_graft_qdisc(dev_queue, q); | 674 | if (new && i > 0) |
697 | } else { | 675 | atomic_inc(&new->refcnt); |
698 | old = dev_graft_qdisc(dev_queue, new); | 676 | |
699 | if (new && i > 0) | ||
700 | atomic_inc(&new->refcnt); | ||
701 | } | ||
702 | notify_and_destroy(skb, n, classid, old, new); | 677 | notify_and_destroy(skb, n, classid, old, new); |
703 | } | 678 | } |
704 | 679 | ||
@@ -817,7 +792,7 @@ qdisc_create(struct net_device *dev, struct netdev_queue *dev_queue, | |||
817 | goto err_out3; | 792 | goto err_out3; |
818 | } | 793 | } |
819 | } | 794 | } |
820 | if (parent) | 795 | if (parent && !(sch->flags & TCQ_F_INGRESS)) |
821 | list_add_tail(&sch->list, &dev_queue->qdisc->list); | 796 | list_add_tail(&sch->list, &dev_queue->qdisc->list); |
822 | 797 | ||
823 | return sch; | 798 | return sch; |
diff --git a/net/sched/sch_generic.c b/net/sched/sch_generic.c index fd2a6cadb115..345838a2e369 100644 --- a/net/sched/sch_generic.c +++ b/net/sched/sch_generic.c | |||
@@ -596,7 +596,7 @@ static void transition_one_qdisc(struct net_device *dev, | |||
596 | int *need_watchdog_p = _need_watchdog; | 596 | int *need_watchdog_p = _need_watchdog; |
597 | 597 | ||
598 | rcu_assign_pointer(dev_queue->qdisc, new_qdisc); | 598 | rcu_assign_pointer(dev_queue->qdisc, new_qdisc); |
599 | if (new_qdisc != &noqueue_qdisc) | 599 | if (need_watchdog_p && new_qdisc != &noqueue_qdisc) |
600 | *need_watchdog_p = 1; | 600 | *need_watchdog_p = 1; |
601 | } | 601 | } |
602 | 602 | ||
@@ -619,6 +619,7 @@ void dev_activate(struct net_device *dev) | |||
619 | 619 | ||
620 | need_watchdog = 0; | 620 | need_watchdog = 0; |
621 | netdev_for_each_tx_queue(dev, transition_one_qdisc, &need_watchdog); | 621 | netdev_for_each_tx_queue(dev, transition_one_qdisc, &need_watchdog); |
622 | transition_one_qdisc(dev, &dev->rx_queue, NULL); | ||
622 | 623 | ||
623 | if (need_watchdog) { | 624 | if (need_watchdog) { |
624 | dev->trans_start = jiffies; | 625 | dev->trans_start = jiffies; |
@@ -677,6 +678,7 @@ void dev_deactivate(struct net_device *dev) | |||
677 | bool running; | 678 | bool running; |
678 | 679 | ||
679 | netdev_for_each_tx_queue(dev, dev_deactivate_queue, &noop_qdisc); | 680 | netdev_for_each_tx_queue(dev, dev_deactivate_queue, &noop_qdisc); |
681 | dev_deactivate_queue(dev, &dev->rx_queue, &noop_qdisc); | ||
680 | 682 | ||
681 | dev_watchdog_down(dev); | 683 | dev_watchdog_down(dev); |
682 | 684 | ||
@@ -718,7 +720,7 @@ static void dev_init_scheduler_queue(struct net_device *dev, | |||
718 | void dev_init_scheduler(struct net_device *dev) | 720 | void dev_init_scheduler(struct net_device *dev) |
719 | { | 721 | { |
720 | netdev_for_each_tx_queue(dev, dev_init_scheduler_queue, &noop_qdisc); | 722 | netdev_for_each_tx_queue(dev, dev_init_scheduler_queue, &noop_qdisc); |
721 | dev_init_scheduler_queue(dev, &dev->rx_queue, NULL); | 723 | dev_init_scheduler_queue(dev, &dev->rx_queue, &noop_qdisc); |
722 | 724 | ||
723 | setup_timer(&dev->watchdog_timer, dev_watchdog, (unsigned long)dev); | 725 | setup_timer(&dev->watchdog_timer, dev_watchdog, (unsigned long)dev); |
724 | } | 726 | } |
@@ -745,6 +747,6 @@ static void shutdown_scheduler_queue(struct net_device *dev, | |||
745 | void dev_shutdown(struct net_device *dev) | 747 | void dev_shutdown(struct net_device *dev) |
746 | { | 748 | { |
747 | netdev_for_each_tx_queue(dev, shutdown_scheduler_queue, &noop_qdisc); | 749 | netdev_for_each_tx_queue(dev, shutdown_scheduler_queue, &noop_qdisc); |
748 | shutdown_scheduler_queue(dev, &dev->rx_queue, NULL); | 750 | shutdown_scheduler_queue(dev, &dev->rx_queue, &noop_qdisc); |
749 | WARN_ON(timer_pending(&dev->watchdog_timer)); | 751 | WARN_ON(timer_pending(&dev->watchdog_timer)); |
750 | } | 752 | } |