Changeset View
Changeset View
Standalone View
Standalone View
head/sys/netpfil/ipfw/dn_aqm_pie.c
Show First 20 Lines • Show All 201 Lines • ▼ Show 20 Lines | * status variables as an argument | ||||
*/ | */ | ||||
static void | static void | ||||
calculate_drop_prob(void *x) | calculate_drop_prob(void *x) | ||||
{ | { | ||||
int64_t p, prob, oldprob; | int64_t p, prob, oldprob; | ||||
struct dn_aqm_pie_parms *pprms; | struct dn_aqm_pie_parms *pprms; | ||||
struct pie_status *pst = (struct pie_status *) x; | struct pie_status *pst = (struct pie_status *) x; | ||||
/* dealing with race condition */ | |||||
if (callout_pending(&pst->aqm_pie_callout)) { | |||||
/* callout was reset */ | |||||
mtx_unlock(&pst->lock_mtx); | |||||
return; | |||||
} | |||||
if (!callout_active(&pst->aqm_pie_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; | |||||
} | |||||
callout_deactivate(&pst->aqm_pie_callout); | |||||
pprms = pst->parms; | pprms = pst->parms; | ||||
prob = pst->drop_prob; | prob = pst->drop_prob; | ||||
/* calculate current qdelay */ | /* calculate current qdelay */ | ||||
if (pprms->flags & PIE_DEPRATEEST_ENABLED) { | if (pprms->flags & PIE_DEPRATEEST_ENABLED) { | ||||
pst->current_qdelay = ((uint64_t)pst->pq->ni.len_bytes * | pst->current_qdelay = ((uint64_t)pst->pq->ni.len_bytes * | ||||
pst->avg_dq_time) >> PIE_DQ_THRESHOLD_BITS; | pst->avg_dq_time) >> PIE_DQ_THRESHOLD_BITS; | ||||
} | } | ||||
▲ Show 20 Lines • Show All 335 Lines • ▼ Show 20 Lines | aqm_pie_init(struct dn_queue *q) | ||||
struct pie_status *pst; | struct pie_status *pst; | ||||
struct dn_aqm_pie_parms *pprms; | struct dn_aqm_pie_parms *pprms; | ||||
int err = 0; | int err = 0; | ||||
pprms = q->fs->aqmcfg; | pprms = q->fs->aqmcfg; | ||||
do { /* exit with break when error occurs*/ | do { /* exit with break when error occurs*/ | ||||
if (!pprms){ | if (!pprms){ | ||||
D("AQM_PIE is not configured"); | DX(2, "AQM_PIE is not configured"); | ||||
err = EINVAL; | err = EINVAL; | ||||
break; | break; | ||||
} | } | ||||
q->aqm_status = malloc(sizeof(struct pie_status), | q->aqm_status = malloc(sizeof(struct pie_status), | ||||
M_DUMMYNET, M_NOWAIT | M_ZERO); | M_DUMMYNET, M_NOWAIT | M_ZERO); | ||||
if (q->aqm_status == NULL) { | if (q->aqm_status == NULL) { | ||||
D("cannot allocate PIE private data"); | D("cannot allocate PIE private data"); | ||||
Show All 22 Lines | do { /* exit with break when error occurs*/ | ||||
//DX(2, "aqm_PIE_init"); | //DX(2, "aqm_PIE_init"); | ||||
} while(0); | } while(0); | ||||
return err; | return err; | ||||
} | } | ||||
/* | /* | ||||
* Callout function to destroy pie mtx and free PIE status memory | |||||
*/ | |||||
static void | |||||
pie_callout_cleanup(void *x) | |||||
{ | |||||
struct pie_status *pst = (struct pie_status *) x; | |||||
mtx_unlock(&pst->lock_mtx); | |||||
mtx_destroy(&pst->lock_mtx); | |||||
free(x, M_DUMMYNET); | |||||
DN_BH_WLOCK(); | |||||
pie_desc.ref_count--; | |||||
DN_BH_WUNLOCK(); | |||||
} | |||||
/* | |||||
* Clean up PIE status for queue 'q' | * Clean up PIE status for queue 'q' | ||||
* Destroy memory allocated for PIE status. | * Destroy memory allocated for PIE status. | ||||
*/ | */ | ||||
static int | static int | ||||
aqm_pie_cleanup(struct dn_queue *q) | aqm_pie_cleanup(struct dn_queue *q) | ||||
{ | { | ||||
if(!q) { | if(!q) { | ||||
Show All 9 Lines | if(!q->fs || !q->fs->aqmcfg) { | ||||
D("fs is null or no cfg"); | D("fs is null or no cfg"); | ||||
return 1; | return 1; | ||||
} | } | ||||
if (q->fs->aqmfp && q->fs->aqmfp->type !=DN_AQM_PIE) { | if (q->fs->aqmfp && q->fs->aqmfp->type !=DN_AQM_PIE) { | ||||
D("Not PIE fs (%d)", q->fs->fs.fs_nr); | D("Not PIE fs (%d)", q->fs->fs.fs_nr); | ||||
return 1; | return 1; | ||||
} | } | ||||
/* | |||||
* Free PIE status allocated memory using pie_callout_cleanup() callout | |||||
* function to avoid any potential race. | |||||
* We reset aqm_pie_callout to call pie_callout_cleanup() in next 1um. This | |||||
* stops the scheduled calculate_drop_prob() callout and call pie_callout_cleanup() | |||||
* which does memory freeing. | |||||
*/ | |||||
mtx_lock(&pst->lock_mtx); | mtx_lock(&pst->lock_mtx); | ||||
callout_reset_sbt(&pst->aqm_pie_callout, | |||||
/* stop callout timer */ | SBT_1US, 0, pie_callout_cleanup, pst, 0); | ||||
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; | q->aqm_status = NULL; | ||||
pie_desc.ref_count--; | |||||
return 0; | |||||
} else { | |||||
q->aqm_status = NULL; | |||||
mtx_unlock(&pst->lock_mtx); | mtx_unlock(&pst->lock_mtx); | ||||
DX(2, "PIE callout has not been stoped from cleanup!"); | |||||
return EBUSY; | |||||
} | |||||
return 0; | return 0; | ||||
} | } | ||||
/* | /* | ||||
* Config PIE parameters | * Config PIE parameters | ||||
* also allocate memory for PIE configurations | * also allocate memory for PIE configurations | ||||
*/ | */ | ||||
static int | static int | ||||
▲ Show 20 Lines • Show All 127 Lines • Show Last 20 Lines |