nss-packages-LiBwrt/qca-nss-clients/patches-11.4/0026-qdisc-backport-12.4.patch
2025-11-04 13:19:44 +08:00

331 lines
10 KiB
Diff

--- a/nss_qdisc/nss_bf.c
+++ b/nss_qdisc/nss_bf.c
@@ -331,10 +331,19 @@ static int nss_bf_delete_class(struct Qd
qdisc_class_hash_remove(&q->clhash, &cl->cl_common);
refcnt = nss_qdisc_atomic_sub_return(&cl->nq);
sch_tree_unlock(sch);
+
+ /*
+ * For 5.4 and above kernels, calling nss_htb_destroy_class
+ * explicitly as there is no put_class which would have called
+ * nss_bf_destroy_class when refcnt becomes zero.
+ */
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 14, 0))
+ nss_bf_destroy_class(sch, cl);
+#else
if (!refcnt) {
nss_qdisc_error("Reference count should not be zero for class %px\n", cl);
}
-
+#endif
return 0;
}
@@ -634,6 +643,11 @@ static int nss_bf_change_qdisc(struct Qd
*/
static void nss_bf_reset_class(struct nss_bf_class_data *cl)
{
+ if (cl->qdisc == &noop_qdisc) {
+ nss_qdisc_trace("Class %x has no child qdisc to reset\n", cl->nq.qos_tag);
+ return;
+ }
+
nss_qdisc_reset(cl->qdisc);
nss_qdisc_info("Nssbf class resetted %px\n", cl->qdisc);
}
--- a/nss_qdisc/nss_htb.c
+++ b/nss_qdisc/nss_htb.c
@@ -1,6 +1,6 @@
/*
**************************************************************************
- * Copyright (c) 2014-2017, 2019-2020, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2014-2017, 2019-2021, 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.
@@ -574,10 +574,16 @@ static int nss_htb_delete_class(struct Q
/*
* If we are root class, we dont have to update our parent.
* We simply deduct refcnt and return.
+ * For 5.4 and above kernels, calling nss_htb_destroy_class
+ * explicitly as there is no put_class which would have called
+ * nss_htb_destroy_class when refcnt becomes zero.
*/
if (!cl->parent) {
refcnt = nss_qdisc_atomic_sub_return(&cl->nq);
sch_tree_unlock(sch);
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 14, 0))
+ nss_htb_destroy_class(sch, cl);
+#endif
return 0;
}
@@ -596,6 +602,14 @@ static int nss_htb_delete_class(struct Q
refcnt = nss_qdisc_atomic_sub_return(&cl->nq);
sch_tree_unlock(sch);
+ /*
+ * For 5.4 and above kernels, calling nss_htb_destroy_class
+ * explicitly as there is no put_class which would have called
+ * nss_htb_destroy_class when refcnt becomes zero.
+ */
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 14, 0))
+ nss_htb_destroy_class(sch, cl);
+#endif
return 0;
}
@@ -898,6 +912,11 @@ static int nss_htb_change_qdisc(struct Q
*/
static void nss_htb_reset_class(struct nss_htb_class_data *cl)
{
+ if (cl->qdisc == &noop_qdisc) {
+ nss_qdisc_trace("Class %x has no child qdisc to reset\n", cl->nq.qos_tag);
+ return;
+ }
+
nss_qdisc_reset(cl->qdisc);
nss_qdisc_trace("htb class %x reset\n", cl->nq.qos_tag);
}
--- a/nss_qdisc/nss_qdisc.c
+++ b/nss_qdisc/nss_qdisc.c
@@ -30,9 +30,6 @@
void *nss_qdisc_ctx; /* Shaping context for nss_qdisc */
-#define NSS_QDISC_COMMAND_TIMEOUT (10*HZ) /* We set 10sec to be the command */
- /* timeout value for messages */
-
/*
* Defines related to root hash maintenance
*/
@@ -40,6 +37,53 @@ void *nss_qdisc_ctx; /* Shaping contex
#define NSS_QDISC_ROOT_HASH_MASK (NSS_QDISC_ROOT_HASH_SIZE - 1)
/*
+ * nss_qdisc_get_interface_msg()
+ * Returns the correct message that needs to be sent down to the NSS interface.
+ */
+int nss_qdisc_get_interface_msg(bool is_bridge, uint32_t msg_type)
+{
+ /*
+ * We re-assign the message based on whether this is for the I shaper
+ * or the B shaper. The is_bridge flag tells if we are on a bridge interface.
+ */
+ if (is_bridge) {
+ switch (msg_type) {
+ case NSS_QDISC_IF_SHAPER_ASSIGN:
+ return NSS_IF_BSHAPER_ASSIGN;
+ case NSS_QDISC_IF_SHAPER_UNASSIGN:
+ return NSS_IF_BSHAPER_UNASSIGN;
+ case NSS_QDISC_IF_SHAPER_CONFIG:
+ return NSS_IF_BSHAPER_CONFIG;
+ default:
+ nss_qdisc_info("Unknown message type for a bridge - type %d", msg_type);
+ return -1;
+ }
+ } else {
+ switch (msg_type) {
+ case NSS_QDISC_IF_SHAPER_ASSIGN:
+ return NSS_IF_ISHAPER_ASSIGN;
+ case NSS_QDISC_IF_SHAPER_UNASSIGN:
+ return NSS_IF_ISHAPER_UNASSIGN;
+ case NSS_QDISC_IF_SHAPER_CONFIG:
+ return NSS_IF_ISHAPER_CONFIG;
+ default:
+ nss_qdisc_info("Unknown message type for an interface - type %d", msg_type);
+ return -1;
+ }
+ }
+}
+
+/*
+ * nss_qdisc_msg_init()
+ * Initialize the qdisc specific message
+ */
+void nss_qdisc_msg_init(struct nss_if_msg *nim, uint16_t if_num, uint32_t msg_type, uint32_t len,
+ nss_if_msg_callback_t cb, void *app_data)
+{
+ nss_cmn_msg_init(&nim->cm, if_num, msg_type, len, (void *)cb, app_data);
+}
+
+/*
* nss_qdisc_interface_is_virtual()
* Return true if it is redirect or bridge interface.
*/
@@ -122,53 +166,6 @@ static int nss_qdisc_ppe_init(struct Qdi
#endif
/*
- * nss_qdisc_msg_init()
- * Initialize the qdisc specific message
- */
-static void nss_qdisc_msg_init(struct nss_if_msg *nim, uint16_t if_num, uint32_t msg_type, uint32_t len,
- nss_if_msg_callback_t cb, void *app_data)
-{
- nss_cmn_msg_init(&nim->cm, if_num, msg_type, len, (void*)cb, app_data);
-}
-
-/*
- * nss_qdisc_get_interface_msg()
- * Returns the correct message that needs to be sent down to the NSS interface.
- */
-static inline int nss_qdisc_get_interface_msg(bool is_bridge, uint32_t msg_type)
-{
- /*
- * We re-assign the message based on whether this is for the I shaper
- * or the B shaper. The is_bridge flag tells if we are on a bridge interface.
- */
- if (is_bridge) {
- switch(msg_type) {
- case NSS_QDISC_IF_SHAPER_ASSIGN:
- return NSS_IF_BSHAPER_ASSIGN;
- case NSS_QDISC_IF_SHAPER_UNASSIGN:
- return NSS_IF_BSHAPER_UNASSIGN;
- case NSS_QDISC_IF_SHAPER_CONFIG:
- return NSS_IF_BSHAPER_CONFIG;
- default:
- nss_qdisc_info("Unknown message type for a bridge - type %d", msg_type);
- return -1;
- }
- } else {
- switch(msg_type) {
- case NSS_QDISC_IF_SHAPER_ASSIGN:
- return NSS_IF_ISHAPER_ASSIGN;
- case NSS_QDISC_IF_SHAPER_UNASSIGN:
- return NSS_IF_ISHAPER_UNASSIGN;
- case NSS_QDISC_IF_SHAPER_CONFIG:
- return NSS_IF_ISHAPER_CONFIG;
- default:
- nss_qdisc_info("Unknown message type for an interface - type %d", msg_type);
- return -1;
- }
- }
-}
-
-/*
* nss_qdisc_attach_bshaper_callback()
* Call back funtion for bridge shaper attach to an interface.
*/
@@ -613,7 +610,6 @@ static void nss_qdisc_root_cleanup_free_
nss_qdisc_info("Root qdisc %px (type %d) free SUCCESS - response "
"type: %d\n", nq->qdisc, nq->type,
nim->msg.shaper_configure.config.response_type);
-
nss_qdisc_root_cleanup_shaper_unassign(nq);
}
@@ -1168,8 +1164,15 @@ unsigned int nss_qdisc_drop(struct Qdisc
*/
void nss_qdisc_reset(struct Qdisc *sch)
{
- struct nss_qdisc *nq = qdisc_priv(sch);
+ struct nss_qdisc *nq;
+ if(!(sch->flags & TCQ_F_NSS)) {
+ qdisc_reset_queue(sch);
+ nss_qdisc_info("Qdisc %px resetting non NSS qdisc\n", sch);
+ return;
+ }
+
+ nq = qdisc_priv(sch);
nss_qdisc_info("Qdisc %px (type %d) resetting\n",
sch, nq->type);
@@ -1891,6 +1894,7 @@ int nss_qdisc_configure(struct nss_qdisc
return 0;
}
+
/*
* nss_qdisc_register_configure_callback()
* Register shaper configure callback, which gets invoked on receiving a response.
@@ -2117,6 +2121,8 @@ int __nss_qdisc_init(struct Qdisc *sch,
*/
if ((sch->parent == TC_H_ROOT) && (!nq->is_class)) {
nss_qdisc_info("Qdisc %px (type %d) is root\n", nq->qdisc, nq->type);
+ nss_qdisc_info("Qdisc %px dev-name %s qdisc_dev(sch)->qdisc %px, qdisc_dev(sch)->qdisc->handle %x\n", qdisc_dev(sch), qdisc_dev(sch)->name, qdisc_dev(sch)->qdisc, qdisc_dev(sch)->qdisc->handle);
+ nss_qdisc_info("Qdisc %px (sch %px) is root, sch->handle %x\n", nq->qdisc, sch, sch->handle);
nq->is_root = true;
root = sch;
} else {
--- a/nss_qdisc/nss_qdisc.h
+++ b/nss_qdisc/nss_qdisc.h
@@ -1,6 +1,6 @@
/*
**************************************************************************
- * Copyright (c) 2014-2018, 2020 The Linux Foundation. All rights reserved.
+ * Copyright (c) 2014-2018, 2020-2021 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.
@@ -41,6 +41,9 @@
#define NSS_QDISC_DEBUG_LEVEL_INFO 3
#define NSS_QDISC_DEBUG_LEVEL_TRACE 4
+#define NSS_QDISC_COMMAND_TIMEOUT (10*HZ) /* We set 10sec to be the command */
+ /* timeout value for messages */
+
/*
* Debug message for module init and exit
*/
@@ -486,3 +489,15 @@ extern unsigned long nss_qdisc_tcf_bind(
* Unbind the filter from the qdisc.
*/
extern void nss_qdisc_tcf_unbind(struct Qdisc *sch, unsigned long arg);
+
+/*
+ * nss_qdisc_get_interface_msg()
+ * Returns the correct message that needs to be sent down to the NSS interface.
+ */
+extern int nss_qdisc_get_interface_msg(bool is_bridge, uint32_t msg_type);
+
+/*
+ * nss_qdisc_msg_init()
+ * Initialize the qdisc specific message
+ */
+extern void nss_qdisc_msg_init(struct nss_if_msg *nim, uint16_t if_num, uint32_t msg_type, uint32_t len, nss_if_msg_callback_t cb, void *app_data);
--- a/nss_qdisc/nss_wrr.c
+++ b/nss_qdisc/nss_wrr.c
@@ -1,6 +1,6 @@
/*
**************************************************************************
- * Copyright (c) 2014-2017, 2019-2020, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2014-2017, 2019-2021, 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.
@@ -442,10 +442,19 @@ static int nss_wrr_delete_class(struct Q
refcnt = nss_qdisc_atomic_sub_return(&cl->nq);
sch_tree_unlock(sch);
+
+ /*
+ * For 5.4 and above kernels, calling nss_htb_destroy_class
+ * explicitly as there is no put_class which would have called
+ * nss_wrr_destroy_class when refcnt becomes zero.
+ */
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 14, 0))
+ nss_wrr_destroy_class(sch, cl);
+#else
if (!refcnt) {
nss_qdisc_error("Reference count should not be zero for class %px\n", cl);
}
-
+#endif
return 0;
}
@@ -764,6 +773,11 @@ static int nss_wrr_change_qdisc(struct Q
static void nss_wrr_reset_class(struct nss_wrr_class_data *cl)
{
+ if (cl->qdisc == &noop_qdisc) {
+ nss_qdisc_trace("Class %x has no child qdisc to reset\n", cl->nq.qos_tag);
+ return;
+ }
+
nss_qdisc_reset(cl->qdisc);
nss_qdisc_info("Nsswrr class resetted %px\n", cl->qdisc);
}