[qca-nss-clients] Enable qdisc on 4.4 kernel
This uses qdisc_replace() API which is originally introduced in kernel
version 4.6, however this has been back ported to the 4.4 kernal
used in QSDK and therefore we are able to use it.
Change-Id: I2523e1ab41585690f63f56d69d919fe3a1df9f12
Signed-off-by: Sakthi Vignesh Radhakrishnan <sradhakr@codeaurora.org>
diff --git a/nss_qdisc/nss_bf.c b/nss_qdisc/nss_bf.c
index 43e4ac3..aab7587 100644
--- a/nss_qdisc/nss_bf.c
+++ b/nss_qdisc/nss_bf.c
@@ -380,11 +380,9 @@
}
/*
- * Attach qdisc once it is done in the NSS
+ * Replaced in NSS, now replace in Linux.
*/
- sch_tree_lock(sch);
- cl->qdisc = new;
- sch_tree_unlock(sch);
+ nss_qdisc_replace(sch, new, &cl->qdisc);
nss_qdisc_info("Nssbf grafted");
diff --git a/nss_qdisc/nss_htb.c b/nss_qdisc/nss_htb.c
index fead0fc..ddc7615 100644
--- a/nss_qdisc/nss_htb.c
+++ b/nss_qdisc/nss_htb.c
@@ -503,11 +503,10 @@
}
/*
- * Attach qdisc once it is done in the NSS
+ * Replaced in NSS, now replace in Linux.
*/
- sch_tree_lock(sch);
- cl->qdisc = new;
- sch_tree_unlock(sch);
+ nss_qdisc_replace(sch, new, &cl->qdisc);
+
return 0;
}
diff --git a/nss_qdisc/nss_prio.c b/nss_qdisc/nss_prio.c
index d12baa8..d2fe8c3 100644
--- a/nss_qdisc/nss_prio.c
+++ b/nss_qdisc/nss_prio.c
@@ -267,8 +267,6 @@
sch_tree_lock(sch);
*old = q->queues[band];
- q->queues[band] = new;
- qdisc_reset(*old);
sch_tree_unlock(sch);
nss_qdisc_info("%s:Grafting old: %p with new: %p\n", __func__, *old, new);
@@ -294,6 +292,12 @@
return -EINVAL;
}
}
+
+ /*
+ * Replaced in NSS, now replace in Linux.
+ */
+ nss_qdisc_replace(sch, new, &q->queues[band]);
+
nss_qdisc_info("Nssprio grafted");
return 0;
diff --git a/nss_qdisc/nss_qdisc.c b/nss_qdisc/nss_qdisc.c
index 2482f65..87b1333 100644
--- a/nss_qdisc/nss_qdisc.c
+++ b/nss_qdisc/nss_qdisc.c
@@ -921,6 +921,35 @@
}
/*
+ * nss_qdisc_replace()
+ * Used to replace old qdisc with a new qdisc.
+ */
+struct Qdisc *nss_qdisc_replace(struct Qdisc *sch, struct Qdisc *new,
+ struct Qdisc **pold)
+{
+ /*
+ * The qdisc_replace() API is originally introduced in kernel version 4.6,
+ * however this has been back ported to the 4.4. kernal used in QSDK.
+ */
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 4, 0))
+ return qdisc_replace(sch, new, pold);
+#else
+ struct Qdisc *old;
+
+ sch_tree_lock(sch);
+ old = *pold;
+ *pold = new;
+ if (old != NULL) {
+ qdisc_tree_decrease_qlen(old, old->q.qlen);
+ qdisc_reset(old);
+ }
+ sch_tree_unlock(sch);
+
+ return old;
+#endif
+}
+
+/*
* nss_qdisc_peek()
* Called to peek at the head of an nss qdisc
*/
@@ -1654,7 +1683,7 @@
* Determine if dev is a bridge or not as this determines if we
* interract with an I or B shaper.
*/
- if (dev->priv_flags == IFF_EBRIDGE) {
+ if (dev->priv_flags & IFF_EBRIDGE) {
nss_qdisc_info("%s: Qdisc %p (type %d) init qdisc: %p, is bridge\n",
__func__, nq->qdisc, nq->type, nq->qdisc);
nq->is_bridge = true;
@@ -2180,7 +2209,7 @@
br = nss_qdisc_get_dev_master(dev);
if_num = nss_cmn_get_interface_number(nss_qdisc_ctx, dev);
- if (br == NULL || br->priv_flags != IFF_EBRIDGE) {
+ if (br == NULL || !(br->priv_flags & IFF_EBRIDGE)) {
nss_qdisc_error("Sensed bridge activity on interface %s "
"that is not on any bridge\n", dev->name);
break;
diff --git a/nss_qdisc/nss_qdisc.h b/nss_qdisc/nss_qdisc.h
index eea266e..8689245 100644
--- a/nss_qdisc/nss_qdisc.h
+++ b/nss_qdisc/nss_qdisc.h
@@ -276,3 +276,9 @@
extern int nss_qdisc_gnet_stats_copy_queue(struct gnet_dump *d,
struct gnet_stats_queue *q);
+/*
+ * nss_qdisc_replace()
+ * Used to replace old qdisc with a new one
+ */
+extern struct Qdisc *nss_qdisc_replace(struct Qdisc *sch, struct Qdisc *new,
+ struct Qdisc **pold);
diff --git a/nss_qdisc/nss_tbl.c b/nss_qdisc/nss_tbl.c
index dd2c444..c936682 100644
--- a/nss_qdisc/nss_tbl.c
+++ b/nss_qdisc/nss_tbl.c
@@ -1,6 +1,6 @@
/*
**************************************************************************
- * Copyright (c) 2014, 2015 The Linux Foundation. All rights reserved.
+ * Copyright (c) 2014-2016 The Linux Foundation. All rights reserved.
* Permission to use, copy, modify, and/or distribute this software for
* any purpose with or without fee is hereby granted, provided that the
* above copyright notice and this permission notice appear in all copies.
@@ -241,9 +241,6 @@
sch_tree_lock(sch);
*old = q->qdisc;
- q->qdisc = new;
- qdisc_tree_decrease_qlen(*old, (*old)->q.qlen);
- qdisc_reset(*old);
sch_tree_unlock(sch);
nss_qdisc_info("%s:Grafting old: %p with new: %p\n", __func__, *old, new);
@@ -267,6 +264,11 @@
}
}
+ /*
+ * Replaced in NSS, now replace in Linux.
+ */
+ nss_qdisc_replace(sch, new, &q->qdisc);
+
nss_qdisc_info("Nsstbl grafted");
return 0;
diff --git a/nss_qdisc/nss_wrr.c b/nss_qdisc/nss_wrr.c
index f663701..52c0486 100644
--- a/nss_qdisc/nss_wrr.c
+++ b/nss_qdisc/nss_wrr.c
@@ -360,11 +360,9 @@
}
/*
- * Attach qdisc once it is done in the NSS
+ * Replaced in NSS, now replace in Linux.
*/
- sch_tree_lock(sch);
- cl->qdisc = new;
- sch_tree_unlock(sch);
+ nss_qdisc_replace(sch, new, &cl->qdisc);
nss_qdisc_info("Nsswrr grafted");