FreeBSD/sys/netpfil/ipfw/dn_sched_fq_pie.c
/*
 * Callout function for drop probability calculation 
 * This function is called over tupdate ms and takes pointer of FQ-PIE
 * flow as an argument
  */
Callout function for drop probability calculation
This function is called over tupdate ms and takes pointer of FQ-PIE
flow as an argument
Callout function for drop probability calculation This function is called over tupdate ms and takes pointer of FQ - PIE flow as an argument
static void
fq_calculate_drop_prob(void *x)
{
	struct fq_pie_flow *q = (struct fq_pie_flow *) x;
	struct pie_status *pst = &q->pst;
	struct dn_aqm_pie_parms *pprms; 
	int64_t p, prob, oldprob;
	aqm_time_t now;
	now = AQM_UNOW;
	pprms = pst->parms;
	prob = pst->drop_prob;
	if (pprms->flags & PIE_DEPRATEEST_ENABLED) {
		pst->current_qdelay = ((uint64_t)q->stats.len_bytes  * pst->avg_dq_time)
			>> PIE_DQ_THRESHOLD_BITS;
	}
	p = (int64_t)pprms->alpha * 
		((int64_t)pst->current_qdelay - (int64_t)pprms->qdelay_ref); 
	p +=(int64_t) pprms->beta * 
		((int64_t)pst->current_qdelay - (int64_t)pst->qdelay_old); 
	p *= (PIE_MAX_PROB << 12) / AQM_TIME_1S;
	if (prob < (PIE_MAX_PROB / 1000000)) 
		p >>= 11 + PIE_FIX_POINT_BITS + 12;
	else if (prob < (PIE_MAX_PROB / 100000)) 
		p >>= 9 + PIE_FIX_POINT_BITS + 12;
	else if (prob < (PIE_MAX_PROB / 10000)) 
		p >>= 7 + PIE_FIX_POINT_BITS + 12;
	else if (prob < (PIE_MAX_PROB / 1000)) 
		p >>= 5 + PIE_FIX_POINT_BITS + 12;
	else if (prob < (PIE_MAX_PROB / 100)) 
		p >>= 3 + PIE_FIX_POINT_BITS + 12;
	else if (prob < (PIE_MAX_PROB / 10)) 
		p >>= 1 + PIE_FIX_POINT_BITS + 12;
	else
		p >>= PIE_FIX_POINT_BITS + 12;
	oldprob = prob;
	if ((pprms->flags & PIE_CAPDROP_ENABLED) && prob >= PIE_MAX_PROB / 10
		&& p > PIE_MAX_PROB / 50 ) 
			p = PIE_MAX_PROB / 50;
	prob = prob + p;
	if (pst->current_qdelay == 0 && pst->qdelay_old == 0)
		prob = prob - (prob >> 6); 
	if (p>0) {
		if (prob<oldprob) {
			D("overflow");
			prob= PIE_MAX_PROB;
		}
	}
	else
		if (prob>oldprob) {
			prob= 0;
			D("underflow");
		}
	if (prob < 0)
		prob = 0;
	else if (prob > PIE_MAX_PROB)
		prob = PIE_MAX_PROB;
	pst->drop_prob = prob;
	pst->qdelay_old = pst->current_qdelay;
	if ((pst->sflags & PIE_ACTIVE) && pst->burst_allowance) {
		if (pst->burst_allowance > pprms->tupdate)
			pst->burst_allowance -= pprms->tupdate;
		else 
			pst->burst_allowance = 0;
	}
	if (pst->sflags & PIE_ACTIVE)
	callout_reset_sbt(&pst->aqm_pie_callout,
		(uint64_t)pprms->tupdate * SBT_1US,
		0, fq_calculate_drop_prob, q, 0);
	mtx_unlock(&pst->lock_mtx);
}
static void fq_calculate_drop_prob ( void * x ) { struct fq_pie_flow * q = ( struct fq_pie_flow * ) x ; struct pie_status * pst = & q -> pst ; struct dn_aqm_pie_parms * pprms ; int64_t p , prob , oldprob ; aqm_time_t now ; now = AQM_UNOW ; pprms = pst -> parms ; prob = pst -> drop_prob ; if ( pprms -> flags & PIE_DEPRATEEST_ENABLED ) { pst -> current_qdelay = ( ( uint64_t ) q -> stats . len_bytes * pst -> avg_dq_time ) >> PIE_DQ_THRESHOLD_BITS ; } p = ( int64_t ) pprms -> alpha * ( ( int64_t ) pst -> current_qdelay - ( int64_t ) pprms -> qdelay_ref ) ; p += ( int64_t ) pprms -> beta * ( ( int64_t ) pst -> current_qdelay - ( int64_t ) pst -> qdelay_old ) ; p *= ( PIE_MAX_PROB << 12 ) / AQM_TIME_1S ; if ( prob < ( PIE_MAX_PROB / 1000000 ) ) p >>= 11 + PIE_FIX_POINT_BITS + 12 ; else if ( prob < ( PIE_MAX_PROB / 100000 ) ) p >>= 9 + PIE_FIX_POINT_BITS + 12 ; else if ( prob < ( PIE_MAX_PROB / 10000 ) ) p >>= 7 + PIE_FIX_POINT_BITS + 12 ; else if ( prob < ( PIE_MAX_PROB / 1000 ) ) p >>= 5 + PIE_FIX_POINT_BITS + 12 ; else if ( prob < ( PIE_MAX_PROB / 100 ) ) p >>= 3 + PIE_FIX_POINT_BITS + 12 ; else if ( prob < ( PIE_MAX_PROB / 10 ) ) p >>= 1 + PIE_FIX_POINT_BITS + 12 ; else p >>= PIE_FIX_POINT_BITS + 12 ; oldprob = prob ; if ( ( pprms -> flags & PIE_CAPDROP_ENABLED ) && prob >= PIE_MAX_PROB / 10 && p > PIE_MAX_PROB / 50 ) p = PIE_MAX_PROB / 50 ; prob = prob + p ; if ( pst -> current_qdelay == 0 && pst -> qdelay_old == 0 ) prob = prob - ( prob >> 6 ) ; if ( p > 0 ) { if ( prob < oldprob ) { D ( " " ) ; prob = PIE_MAX_PROB ; } } else if ( prob > oldprob ) { prob = 0 ; D ( " " ) ; } if ( prob < 0 ) prob = 0 ; else if ( prob > PIE_MAX_PROB ) prob = PIE_MAX_PROB ; pst -> drop_prob = prob ; pst -> qdelay_old = pst -> current_qdelay ; if ( ( pst -> sflags & PIE_ACTIVE ) && pst -> burst_allowance ) { if ( pst -> burst_allowance > pprms -> tupdate ) pst -> burst_allowance -= pprms -> tupdate ; else pst -> burst_allowance = 0 ; } if ( pst -> sflags & PIE_ACTIVE ) callout_reset_sbt ( & pst -> aqm_pie_callout , ( uint64_t ) pprms -> tupdate * SBT_1US , 0 , fq_calculate_drop_prob , q , 0 ) ; mtx_unlock ( & pst -> lock_mtx ) ; }
Callout function for drop probability calculation
 This function is called over tupdate ms and takes pointer of FQ-PIE
 flow as an argument
Callout function for drop probability calculation This function is called over tupdate ms and takes pointer of FQ - PIE flow as an argument
/* calculate current qdelay */ /* calculate drop probability */ /* We PIE_MAX_PROB shift by 12-bits to increase the division precision  */ /* auto-tune drop probability */ /* 0.000001 */ /* 0.00001 */ /* 0.0001 */ /* 0.001 */ /* 0.01 */ /* 0.1 */ /* Cap Drop adjustment */ /* decay the drop probability exponentially */ /* 0.98 ~= 1- 1/64 */ /* check for multiplication over/under flow */ /* make drop probability between 0 and PIE_MAX_PROB*/ /* store current delay value */ /* update burst allowance */