Index: sys/netpfil/ipfw/dn_aqm_pie.h =================================================================== --- sys/netpfil/ipfw/dn_aqm_pie.h +++ sys/netpfil/ipfw/dn_aqm_pie.h @@ -97,7 +97,8 @@ /* PIE current state */ enum { PIE_ACTIVE = 1, - PIE_INMEASUREMENT = 2 + PIE_INMEASUREMENT = 2, + PIE_STOP_CALLOUT = 4 }; /* Index: sys/netpfil/ipfw/dn_aqm_pie.c =================================================================== --- sys/netpfil/ipfw/dn_aqm_pie.c +++ sys/netpfil/ipfw/dn_aqm_pie.c @@ -214,15 +212,20 @@ return; } - if (!callout_active(&pst->aqm_pie_callout)) { + if (pst->sflags & PIE_STOP_CALLOUT) { /* callout was stopped */ mtx_unlock(&pst->lock_mtx); mtx_destroy(&pst->lock_mtx); free(x, M_DUMMYNET); - //pst->pq->aqm_status = NULL; pie_desc.ref_count--; return; } + + if (!callout_active(&pst->aqm_pie_callout)) { + mtx_unlock(&pst->lock_mtx); + return; + } + callout_deactivate(&pst->aqm_pie_callout); pprms = pst->parms; @@ -576,7 +579,7 @@ do { /* exit with break when error occurs*/ if (!pprms){ - D("AQM_PIE is not configured"); + DX(2, "AQM_PIE is not configured"); err = EINVAL; break; } @@ -640,22 +643,19 @@ return 1; } + /* Signal callout function (calculate_drop_prob) to stop and free the + * allocated memory. + * We set sflag to PIE_STOP_CALLOUT and resetting callout to be executed + * in the next microsecond. When the time is elapsed, calculate_drop_prob + * will free the allocated memory and will not reschedule the callout. + */ mtx_lock(&pst->lock_mtx); + pst->sflags |= PIE_STOP_CALLOUT; + callout_reset_sbt(&pst->aqm_pie_callout, + SBT_1US, 0, calculate_drop_prob, pst, 0); + q->aqm_status = NULL; + mtx_unlock(&pst->lock_mtx); - /* stop callout timer */ - if (callout_stop(&pst->aqm_pie_callout) || !(pst->sflags & PIE_ACTIVE)) { - mtx_unlock(&pst->lock_mtx); - mtx_destroy(&pst->lock_mtx); - free(q->aqm_status, M_DUMMYNET); - q->aqm_status = NULL; - pie_desc.ref_count--; - return 0; - } else { - q->aqm_status = NULL; - mtx_unlock(&pst->lock_mtx); - DX(2, "PIE callout has not been stoped from cleanup!"); - return EBUSY; - } return 0; }