[qca-nss-clients] Make qdisc module take a reference on IGS module.
The code change causes nss qdisc module to take a reference on the IGS
module when a qdisc is configured on an IFB interface. This ensure the
IGS module will not go away when shapers are configured on it.
Change-Id: Ib7748af0b0f41fb52afc77badc988626c4b8ec5a
Signed-off-by: Manish Verma <maniverm@codeaurora.org>
diff --git a/nss_qdisc/igs/nss_ifb.c b/nss_qdisc/igs/nss_ifb.c
index 746524c..e53781e 100644
--- a/nss_qdisc/igs/nss_ifb.c
+++ b/nss_qdisc/igs/nss_ifb.c
@@ -318,7 +318,7 @@
spin_lock_bh(&nss_ifb_list_lock);
if (!(ifb_info->is_mapped)) {
- nss_igs_info("%s IFB device mapped flag is not set\n", ifb_info->map_dev->name);
+ nss_igs_info("%s IFB device mapped flag is not set\n", ifb_info->ifb_dev->name);
spin_unlock_bh(&nss_ifb_list_lock);
return true;
}
@@ -418,7 +418,7 @@
spin_lock_bh(&nss_ifb_list_lock);
if (!(ifb_info->is_mapped)) {
- nss_igs_info("%s IFB device mapped flag is not set\n", ifb_info->map_dev->name);
+ nss_igs_info("%s IFB device mapped flag is not set\n", ifb_info->ifb_dev->name);
spin_unlock_bh(&nss_ifb_list_lock);
return true;
}
diff --git a/nss_qdisc/igs/nss_mirred.c b/nss_qdisc/igs/nss_mirred.c
index 5fca4e0..5ca5914 100644
--- a/nss_qdisc/igs/nss_mirred.c
+++ b/nss_qdisc/igs/nss_mirred.c
@@ -539,6 +539,11 @@
return err;
}
+ /*
+ * Set the IGS module reference variable.
+ */
+ nss_igs_module_save(&nss_mirred_act_ops, THIS_MODULE);
+
nss_ifb_init();
return 0;
}
@@ -549,6 +554,11 @@
*/
static void __exit nss_mirred_cleanup_module(void)
{
+ /*
+ * Reset the IGS module reference variable.
+ */
+ nss_igs_module_save(&nss_mirred_act_ops, NULL);
+
nf_unregister_hooks(nss_mirred_igs_nf_ops, ARRAY_SIZE(nss_mirred_igs_nf_ops));
/*
diff --git a/nss_qdisc/nss_qdisc.c b/nss_qdisc/nss_qdisc.c
index b5fb2e3..83a5886 100644
--- a/nss_qdisc/nss_qdisc.c
+++ b/nss_qdisc/nss_qdisc.c
@@ -14,6 +14,7 @@
**************************************************************************
*/
+#include <nss_api_if.h>
#include "nss_qdisc.h"
#include "nss_fifo.h"
#include "nss_codel.h"
@@ -1880,7 +1881,9 @@
* How we begin to tidy up depends on whether we are root or child
*/
nq->pending_final_state = NSS_QDISC_STATE_IDLE;
- if (nq->is_root) {
+ if (!nq->is_root) {
+ nss_qdisc_child_cleanup_free_node(nq);
+ } else {
/*
* If this is root on a bridge interface, then unassign
@@ -1897,8 +1900,12 @@
*/
nss_qdisc_root_cleanup_free_node(nq);
- } else {
- nss_qdisc_child_cleanup_free_node(nq);
+ /*
+ * In case of IGS interface, release the reference of the IGS module.
+ */
+ if (nss_igs_verify_if_num(nq->nss_interface_number)) {
+ nss_igs_module_put();
+ }
}
/*
@@ -1951,6 +1958,7 @@
#if defined(NSS_QDISC_PPE_SUPPORT)
bool mode_ppe = false;
#endif
+ bool igs_put = false;
if (accel_mode >= TCA_NSS_ACCEL_MODE_MAX) {
nss_qdisc_warning("Qdisc %p (type %d) accel_mode:%u should be < %u\n",
@@ -2238,15 +2246,15 @@
* register for bridge bouncing as it will be responsible for
* bouncing packets to the NSS for bridge shaping.
*/
- if (nss_igs_verify_if_num(nq->nss_interface_number)) {
+ if (!nss_igs_verify_if_num(nq->nss_interface_number)) {
+ nq->bounce_context = nss_shaper_register_shaper_bounce_bridge(nq->nss_interface_number,
+ nss_qdisc_bounce_callback, nq->qdisc, THIS_MODULE);
+ } else {
nss_qdisc_error("Since %d is an IFB device, it cannot"
" register for bridge bouncing\n", nq->nss_interface_number);
nss_shaper_unregister_shaping(nq->nss_shaping_ctx);
atomic_set(&nq->state, NSS_QDISC_STATE_INIT_FAILED);
goto init_fail;
- } else {
- nq->bounce_context = nss_shaper_register_shaper_bounce_bridge(nq->nss_interface_number,
- nss_qdisc_bounce_callback, nq->qdisc, THIS_MODULE);
}
if (!nq->bounce_context) {
@@ -2290,12 +2298,31 @@
/*
* Register for interface bounce shaping.
*/
- if (nss_igs_verify_if_num(nq->nss_interface_number)) {
- nq->bounce_context = nss_shaper_register_shaper_bounce_interface(nq->nss_interface_number,
- nss_qdisc_mark_and_schedule, nq->qdisc, THIS_MODULE);
- } else {
+ if (!nss_igs_verify_if_num(nq->nss_interface_number)) {
nq->bounce_context = nss_shaper_register_shaper_bounce_interface(nq->nss_interface_number,
nss_qdisc_bounce_callback, nq->qdisc, THIS_MODULE);
+ } else {
+
+ /*
+ * In case of IGS interface, take the reference of IGS module.
+ */
+ if (!nss_igs_module_get()) {
+ nss_qdisc_error("Module reference failed for IGS interface %d"
+ " , Qdisc %p (type %d)\n", nq->nss_interface_number,
+ nq->qdisc, nq->type);
+ nss_shaper_unregister_shaping(nq->nss_shaping_ctx);
+ atomic_set(&nq->state, NSS_QDISC_STATE_INIT_FAILED);
+ goto init_fail;
+ }
+
+ /*
+ * Set the flag to indicate the IGS module reference get is successful.
+ * This flag will be used to decrement the IGS module reference in case
+ * of any error conditions.
+ */
+ igs_put = true;
+ nq->bounce_context = nss_shaper_register_shaper_bounce_interface(nq->nss_interface_number,
+ nss_qdisc_mark_and_schedule, nq->qdisc, THIS_MODULE);
}
if (!nq->bounce_context) {
@@ -2342,6 +2369,12 @@
*/
if (!wait_event_timeout(nq->wait_queue, atomic_read(&nq->state) != NSS_QDISC_STATE_IDLE,
NSS_QDISC_COMMAND_TIMEOUT)) {
+ /*
+ * Decrement the IGS module reference.
+ */
+ if (igs_put) {
+ nss_igs_module_put();
+ }
nss_qdisc_error("init for qdisc %x timedout!\n", nq->qos_tag);
return -1;
}
@@ -2380,6 +2413,13 @@
init_fail:
+ /*
+ * Decrement the IGS module reference.
+ */
+ if (igs_put) {
+ nss_igs_module_put();
+ }
+
#if defined(NSS_QDISC_PPE_SUPPORT)
if (nq->mode == NSS_QDISC_MODE_PPE) {
nss_ppe_destroy(nq);