aboutsummaryrefslogtreecommitdiffstats
path: root/net/sched/sch_cbq.c
diff options
context:
space:
mode:
Diffstat (limited to 'net/sched/sch_cbq.c')
-rw-r--r--net/sched/sch_cbq.c76
1 files changed, 29 insertions, 47 deletions
diff --git a/net/sched/sch_cbq.c b/net/sched/sch_cbq.c
index 03e389e8d945..9e43ed949167 100644
--- a/net/sched/sch_cbq.c
+++ b/net/sched/sch_cbq.c
@@ -405,40 +405,6 @@ cbq_enqueue(struct sk_buff *skb, struct Qdisc *sch)
405 return ret; 405 return ret;
406} 406}
407 407
408static int
409cbq_requeue(struct sk_buff *skb, struct Qdisc *sch)
410{
411 struct cbq_sched_data *q = qdisc_priv(sch);
412 struct cbq_class *cl;
413 int ret;
414
415 if ((cl = q->tx_class) == NULL) {
416 kfree_skb(skb);
417 sch->qstats.drops++;
418 return NET_XMIT_CN;
419 }
420 q->tx_class = NULL;
421
422 cbq_mark_toplevel(q, cl);
423
424#ifdef CONFIG_NET_CLS_ACT
425 q->rx_class = cl;
426 cl->q->__parent = sch;
427#endif
428 if ((ret = cl->q->ops->requeue(skb, cl->q)) == 0) {
429 sch->q.qlen++;
430 sch->qstats.requeues++;
431 if (!cl->next_alive)
432 cbq_activate_class(cl);
433 return 0;
434 }
435 if (net_xmit_drop_count(ret)) {
436 sch->qstats.drops++;
437 cl->qstats.drops++;
438 }
439 return ret;
440}
441
442/* Overlimit actions */ 408/* Overlimit actions */
443 409
444/* TC_CBQ_OVL_CLASSIC: (default) penalize leaf class by adding offtime */ 410/* TC_CBQ_OVL_CLASSIC: (default) penalize leaf class by adding offtime */
@@ -1669,7 +1635,8 @@ static int cbq_graft(struct Qdisc *sch, unsigned long arg, struct Qdisc *new,
1669#endif 1635#endif
1670 } 1636 }
1671 sch_tree_lock(sch); 1637 sch_tree_lock(sch);
1672 *old = xchg(&cl->q, new); 1638 *old = cl->q;
1639 cl->q = new;
1673 qdisc_tree_decrease_qlen(*old, (*old)->q.qlen); 1640 qdisc_tree_decrease_qlen(*old, (*old)->q.qlen);
1674 qdisc_reset(*old); 1641 qdisc_reset(*old);
1675 sch_tree_unlock(sch); 1642 sch_tree_unlock(sch);
@@ -1798,11 +1765,23 @@ cbq_change_class(struct Qdisc *sch, u32 classid, u32 parentid, struct nlattr **t
1798 } 1765 }
1799 1766
1800 if (tb[TCA_CBQ_RATE]) { 1767 if (tb[TCA_CBQ_RATE]) {
1801 rtab = qdisc_get_rtab(nla_data(tb[TCA_CBQ_RATE]), tb[TCA_CBQ_RTAB]); 1768 rtab = qdisc_get_rtab(nla_data(tb[TCA_CBQ_RATE]),
1769 tb[TCA_CBQ_RTAB]);
1802 if (rtab == NULL) 1770 if (rtab == NULL)
1803 return -EINVAL; 1771 return -EINVAL;
1804 } 1772 }
1805 1773
1774 if (tca[TCA_RATE]) {
1775 err = gen_replace_estimator(&cl->bstats, &cl->rate_est,
1776 qdisc_root_sleeping_lock(sch),
1777 tca[TCA_RATE]);
1778 if (err) {
1779 if (rtab)
1780 qdisc_put_rtab(rtab);
1781 return err;
1782 }
1783 }
1784
1806 /* Change class parameters */ 1785 /* Change class parameters */
1807 sch_tree_lock(sch); 1786 sch_tree_lock(sch);
1808 1787
@@ -1810,8 +1789,8 @@ cbq_change_class(struct Qdisc *sch, u32 classid, u32 parentid, struct nlattr **t
1810 cbq_deactivate_class(cl); 1789 cbq_deactivate_class(cl);
1811 1790
1812 if (rtab) { 1791 if (rtab) {
1813 rtab = xchg(&cl->R_tab, rtab); 1792 qdisc_put_rtab(cl->R_tab);
1814 qdisc_put_rtab(rtab); 1793 cl->R_tab = rtab;
1815 } 1794 }
1816 1795
1817 if (tb[TCA_CBQ_LSSOPT]) 1796 if (tb[TCA_CBQ_LSSOPT])
@@ -1838,10 +1817,6 @@ cbq_change_class(struct Qdisc *sch, u32 classid, u32 parentid, struct nlattr **t
1838 1817
1839 sch_tree_unlock(sch); 1818 sch_tree_unlock(sch);
1840 1819
1841 if (tca[TCA_RATE])
1842 gen_replace_estimator(&cl->bstats, &cl->rate_est,
1843 qdisc_root_sleeping_lock(sch),
1844 tca[TCA_RATE]);
1845 return 0; 1820 return 0;
1846 } 1821 }
1847 1822
@@ -1888,6 +1863,17 @@ cbq_change_class(struct Qdisc *sch, u32 classid, u32 parentid, struct nlattr **t
1888 cl = kzalloc(sizeof(*cl), GFP_KERNEL); 1863 cl = kzalloc(sizeof(*cl), GFP_KERNEL);
1889 if (cl == NULL) 1864 if (cl == NULL)
1890 goto failure; 1865 goto failure;
1866
1867 if (tca[TCA_RATE]) {
1868 err = gen_new_estimator(&cl->bstats, &cl->rate_est,
1869 qdisc_root_sleeping_lock(sch),
1870 tca[TCA_RATE]);
1871 if (err) {
1872 kfree(cl);
1873 goto failure;
1874 }
1875 }
1876
1891 cl->R_tab = rtab; 1877 cl->R_tab = rtab;
1892 rtab = NULL; 1878 rtab = NULL;
1893 cl->refcnt = 1; 1879 cl->refcnt = 1;
@@ -1929,10 +1915,6 @@ cbq_change_class(struct Qdisc *sch, u32 classid, u32 parentid, struct nlattr **t
1929 1915
1930 qdisc_class_hash_grow(sch, &q->clhash); 1916 qdisc_class_hash_grow(sch, &q->clhash);
1931 1917
1932 if (tca[TCA_RATE])
1933 gen_new_estimator(&cl->bstats, &cl->rate_est,
1934 qdisc_root_sleeping_lock(sch), tca[TCA_RATE]);
1935
1936 *arg = (unsigned long)cl; 1918 *arg = (unsigned long)cl;
1937 return 0; 1919 return 0;
1938 1920
@@ -2066,7 +2048,7 @@ static struct Qdisc_ops cbq_qdisc_ops __read_mostly = {
2066 .priv_size = sizeof(struct cbq_sched_data), 2048 .priv_size = sizeof(struct cbq_sched_data),
2067 .enqueue = cbq_enqueue, 2049 .enqueue = cbq_enqueue,
2068 .dequeue = cbq_dequeue, 2050 .dequeue = cbq_dequeue,
2069 .requeue = cbq_requeue, 2051 .peek = qdisc_peek_dequeued,
2070 .drop = cbq_drop, 2052 .drop = cbq_drop,
2071 .init = cbq_init, 2053 .init = cbq_init,
2072 .reset = cbq_reset, 2054 .reset = cbq_reset,