pkt_sched: sch_qfq: remove forward declaration of qfq_update_agg_ts
This patch removes the forward declaration of qfq_update_agg_ts, by moving the definition of the function above its first call. This patch also removes a useless forward declaration of qfq_schedule_agg. Reported-by: David S. Miller <davem@davemloft.net> Signed-off-by: Paolo Valente <paolo.valente@unimore.it> Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
Родитель
87f1369d6e
Коммит
88d4f419a4
|
@ -1010,9 +1010,61 @@ static inline void charge_actual_service(struct qfq_aggregate *agg)
|
|||
agg->F = agg->S + (u64)service_received * agg->inv_w;
|
||||
}
|
||||
|
||||
static inline void qfq_update_agg_ts(struct qfq_sched *q,
|
||||
struct qfq_aggregate *agg,
|
||||
enum update_reason reason);
|
||||
/* Assign a reasonable start time for a new aggregate in group i.
|
||||
* Admissible values for \hat(F) are multiples of \sigma_i
|
||||
* no greater than V+\sigma_i . Larger values mean that
|
||||
* we had a wraparound so we consider the timestamp to be stale.
|
||||
*
|
||||
* If F is not stale and F >= V then we set S = F.
|
||||
* Otherwise we should assign S = V, but this may violate
|
||||
* the ordering in EB (see [2]). So, if we have groups in ER,
|
||||
* set S to the F_j of the first group j which would be blocking us.
|
||||
* We are guaranteed not to move S backward because
|
||||
* otherwise our group i would still be blocked.
|
||||
*/
|
||||
static void qfq_update_start(struct qfq_sched *q, struct qfq_aggregate *agg)
|
||||
{
|
||||
unsigned long mask;
|
||||
u64 limit, roundedF;
|
||||
int slot_shift = agg->grp->slot_shift;
|
||||
|
||||
roundedF = qfq_round_down(agg->F, slot_shift);
|
||||
limit = qfq_round_down(q->V, slot_shift) + (1ULL << slot_shift);
|
||||
|
||||
if (!qfq_gt(agg->F, q->V) || qfq_gt(roundedF, limit)) {
|
||||
/* timestamp was stale */
|
||||
mask = mask_from(q->bitmaps[ER], agg->grp->index);
|
||||
if (mask) {
|
||||
struct qfq_group *next = qfq_ffs(q, mask);
|
||||
if (qfq_gt(roundedF, next->F)) {
|
||||
if (qfq_gt(limit, next->F))
|
||||
agg->S = next->F;
|
||||
else /* preserve timestamp correctness */
|
||||
agg->S = limit;
|
||||
return;
|
||||
}
|
||||
}
|
||||
agg->S = q->V;
|
||||
} else /* timestamp is not stale */
|
||||
agg->S = agg->F;
|
||||
}
|
||||
|
||||
/* Update the timestamps of agg before scheduling/rescheduling it for
|
||||
* service. In particular, assign to agg->F its maximum possible
|
||||
* value, i.e., the virtual finish time with which the aggregate
|
||||
* should be labeled if it used all its budget once in service.
|
||||
*/
|
||||
static inline void
|
||||
qfq_update_agg_ts(struct qfq_sched *q,
|
||||
struct qfq_aggregate *agg, enum update_reason reason)
|
||||
{
|
||||
if (reason != requeue)
|
||||
qfq_update_start(q, agg);
|
||||
else /* just charge agg for the service received */
|
||||
agg->S = agg->F;
|
||||
|
||||
agg->F = agg->S + (u64)agg->budgetmax * agg->inv_w;
|
||||
}
|
||||
|
||||
static void qfq_schedule_agg(struct qfq_sched *q, struct qfq_aggregate *agg);
|
||||
|
||||
|
@ -1135,66 +1187,6 @@ static struct qfq_aggregate *qfq_choose_next_agg(struct qfq_sched *q)
|
|||
return agg;
|
||||
}
|
||||
|
||||
/*
|
||||
* Assign a reasonable start time for a new aggregate in group i.
|
||||
* Admissible values for \hat(F) are multiples of \sigma_i
|
||||
* no greater than V+\sigma_i . Larger values mean that
|
||||
* we had a wraparound so we consider the timestamp to be stale.
|
||||
*
|
||||
* If F is not stale and F >= V then we set S = F.
|
||||
* Otherwise we should assign S = V, but this may violate
|
||||
* the ordering in EB (see [2]). So, if we have groups in ER,
|
||||
* set S to the F_j of the first group j which would be blocking us.
|
||||
* We are guaranteed not to move S backward because
|
||||
* otherwise our group i would still be blocked.
|
||||
*/
|
||||
static void qfq_update_start(struct qfq_sched *q, struct qfq_aggregate *agg)
|
||||
{
|
||||
unsigned long mask;
|
||||
u64 limit, roundedF;
|
||||
int slot_shift = agg->grp->slot_shift;
|
||||
|
||||
roundedF = qfq_round_down(agg->F, slot_shift);
|
||||
limit = qfq_round_down(q->V, slot_shift) + (1ULL << slot_shift);
|
||||
|
||||
if (!qfq_gt(agg->F, q->V) || qfq_gt(roundedF, limit)) {
|
||||
/* timestamp was stale */
|
||||
mask = mask_from(q->bitmaps[ER], agg->grp->index);
|
||||
if (mask) {
|
||||
struct qfq_group *next = qfq_ffs(q, mask);
|
||||
if (qfq_gt(roundedF, next->F)) {
|
||||
if (qfq_gt(limit, next->F))
|
||||
agg->S = next->F;
|
||||
else /* preserve timestamp correctness */
|
||||
agg->S = limit;
|
||||
return;
|
||||
}
|
||||
}
|
||||
agg->S = q->V;
|
||||
} else /* timestamp is not stale */
|
||||
agg->S = agg->F;
|
||||
}
|
||||
|
||||
/*
|
||||
* Update the timestamps of agg before scheduling/rescheduling it for
|
||||
* service. In particular, assign to agg->F its maximum possible
|
||||
* value, i.e., the virtual finish time with which the aggregate
|
||||
* should be labeled if it used all its budget once in service.
|
||||
*/
|
||||
static inline void
|
||||
qfq_update_agg_ts(struct qfq_sched *q,
|
||||
struct qfq_aggregate *agg, enum update_reason reason)
|
||||
{
|
||||
if (reason != requeue)
|
||||
qfq_update_start(q, agg);
|
||||
else /* just charge agg for the service received */
|
||||
agg->S = agg->F;
|
||||
|
||||
agg->F = agg->S + (u64)agg->budgetmax * agg->inv_w;
|
||||
}
|
||||
|
||||
static void qfq_schedule_agg(struct qfq_sched *, struct qfq_aggregate *);
|
||||
|
||||
static int qfq_enqueue(struct sk_buff *skb, struct Qdisc *sch)
|
||||
{
|
||||
struct qfq_sched *q = qdisc_priv(sch);
|
||||
|
|
Загрузка…
Ссылка в новой задаче