Index: /branches/rel_apv_10_4_0_112_gail/usr/src/sys/click/app/qos/qos_classifier.c
===================================================================
--- /branches/rel_apv_10_4_0_112_gail/usr/src/sys/click/app/qos/qos_classifier.c	(revision 38158)
+++ /branches/rel_apv_10_4_0_112_gail/usr/src/sys/click/app/qos/qos_classifier.c	(working copy)
@@ -141,6 +141,7 @@
 extern uint32_t repeat_segment_num;
 extern uint32_t q_del_step_size;
 extern struct mtx qos_session_lock;
+extern struct mtx qos_filter_lock;
 /******************************************************************************
  * Return the current valid class poniter.
  *
@@ -223,12 +224,14 @@
         return;
     }
 
-/* On reaching MAX session queues, we start to flush the filters and start to delete the queues. Till we delete all queues, we will not be creating any new filter and queue for the sessions and all packets will use 'default' queue */
+/* On reaching MAX session queues, we flush the filters and start to delete the queues. Till we delete all queues, we will not be creating any new filter and queue for the sessions and all packets will use 'default' queue */
     if (current_dyn_q_count >= MAX_DYN_QUEUE) {
 	fastlog_syslog(LOG_DEBUG, "QoS sessions reached maximum limit : %u. Recycling old sessions\n", MAX_DYN_QUEUE);
         if (qos_session_cleanup == 0) {
             qos_session_cleanup = 1;
+            mtx_lock (&qos_filter_lock);
             qos_filter_clear_all_dyn (NULL);
+            mtx_unlock (&qos_filter_lock);
         }
         mtx_unlock (&qos_session_lock);
         return;
@@ -1068,12 +1071,15 @@
 		goto ADD_FLTR_ERROR;
 	}
 
+	mtx_lock (&qos_filter_lock);
+
 	qs = &qos_filter_share;
 
 	/*
 	 * Check existing filters.
 	 */
-	for(i=0; i < QOS_MAX_FLTR_NUM; i++) {
+        if (qos_session_status != SESSION_ENABLE) {
+	    for(i=0; i < QOS_MAX_FLTR_NUM; i++) {
 		pfltr = &qs->a_fltrs[i];
 
 		if(!pfltr->used) {
@@ -1083,6 +1089,7 @@
 		if(!strcmp(qos_filter->fltr_name, pfltr->fltr_name)) {
 			app_printf(pcb, "ERROR: the QoS L4 filter name has aready existed\n");
 			fastlog_syslog (LOG_DEBUG,  "ERROR: the QoS L4 filter name - %s has aready existed\n", pfltr->fltr_name);
+			mtx_unlock (&qos_filter_lock);
 			goto ADD_FLTR_ERROR;
 		}
 
@@ -1091,13 +1098,15 @@
 				!bcmp(&qos_filter->tp, &pfltr->tp, sizeof(clickrule_5tuple_t))){
 			app_printf(pcb, "ERROR: found a duplicate QoS L4 filter name: \"%s\"\n", pfltr->fltr_name);
 			fastlog_syslog (LOG_DEBUG, "ERROR: found a duplicate QoS L4 filter name: \"%s\"\n", pfltr->fltr_name);
+			mtx_unlock (&qos_filter_lock);
 			goto ADD_FLTR_ERROR;
 		}
-	}
+	    }
+        }
 
-	/*
-	 * Find an empty one.
-	 */
+        /*
+        * Find an empty one.
+	*/
 	for(i=0; i < QOS_MAX_FLTR_NUM; i++) {
 		pfltr = &qs->a_fltrs[i];
 
@@ -1108,24 +1117,27 @@
 	if (i == QOS_MAX_FLTR_NUM) {
 		app_printf(pcb, "ERROR: maximum number of QoS L4 filters reached. maximum %u\n", QOS_MAX_FLTR_NUM);
 		fastlog_syslog (LOG_DEBUG, "ERROR: maximum number of QoS L4 filters reached maximum %u\n", QOS_MAX_FLTR_NUM);
+		mtx_unlock (&qos_filter_lock);
 		goto ADD_FLTR_ERROR;
 	}
 
 	/*
-	 * Add the qos filter to qos filter array.
-	 */
+	* Add the qos filter to qos filter array.
+	*/
 	bcopy(qos_filter, pfltr, sizeof(qos_filter_t));
 
 	ret = qos_filter_add_table(qs, pfltr);
 	if(QOS_FAILURE == ret) {
-		bzero(pfltr, sizeof(qos_filter_t));
-		qos_filter_share.fltr_g_stats.count_add_table_fail++;
-		fastlog_syslog(LOG_DEBUG, "ERROR: failed to add the filter to the table\n");
-		goto ADD_FLTR_ERROR;
+	    bzero(pfltr, sizeof(qos_filter_t));
+	    qos_filter_share.fltr_g_stats.count_add_table_fail++;
+	    fastlog_syslog(LOG_DEBUG, "ERROR: failed to add the filter to the table\n");
+	    mtx_unlock (&qos_filter_lock);
+	    goto ADD_FLTR_ERROR;
 	}
 
 	pfltr->used = 1;
 
+	mtx_unlock (&qos_filter_lock);
 	return QOS_SUCCESS;
 
 ADD_FLTR_ERROR:
Index: /branches/rel_apv_10_4_0_112_gail/usr/src/sys/click/app/qos/qos_dynamic.h
===================================================================
--- /branches/rel_apv_10_4_0_112_gail/usr/src/sys/click/app/qos/qos_dynamic.h	(revision 38158)
+++ /branches/rel_apv_10_4_0_112_gail/usr/src/sys/click/app/qos/qos_dynamic.h	(working copy)
@@ -28,6 +28,7 @@
 extern uint32_t repeat_segment_num;
 extern uint32_t q_del_step_size;
 extern struct mtx qos_session_lock;
+extern struct mtx qos_filter_lock;
 
 typedef struct dyn_qos_session_lookup {
     struct dyn_qos_session_lookup *dyn_qos_session_lookup_node[N_CHILDREN];
Index: /branches/rel_apv_10_4_0_112_gail/usr/src/sys/click/app/qos/qos_dynamic.c
===================================================================
--- /branches/rel_apv_10_4_0_112_gail/usr/src/sys/click/app/qos/qos_dynamic.c	(revision 38158)
+++ /branches/rel_apv_10_4_0_112_gail/usr/src/sys/click/app/qos/qos_dynamic.c	(working copy)
@@ -29,6 +29,7 @@
 #define TUPLE_LEN 12 /* src ip + src port + dest ip + dst port */
 
 struct mtx qos_session_lock;
+struct mtx qos_filter_lock;
 
 int qos_session_status = SESSION_DISABLE;
 
@@ -432,5 +433,6 @@
 
 int qos_session_init (void) {
     mtx_init(&qos_session_lock, "qos session lock", NULL, MTX_DEF | MTX_NOWITNESS);
+    mtx_init(&qos_filter_lock, "qos filter lock", NULL, MTX_DEF | MTX_NOWITNESS);
     return QOS_SUCCESS;
 }
