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);
+
+static void qfq_schedule_agg(struct qfq_sched *q, struct qfq_aggregate *agg);
+
 static struct sk_buff *qfq_dequeue(struct Qdisc *sch)
 {
        struct qfq_sched *q = qdisc_priv(sch);
                in_serv_agg->initial_budget = in_serv_agg->budget =
                        in_serv_agg->budgetmax;
 
-               if (!list_empty(&in_serv_agg->active))
+               if (!list_empty(&in_serv_agg->active)) {
                        /*
                         * Still active: reschedule for
                         * service. Possible optimization: if no other
                         * handle it, we would need to maintain an
                         * extra num_active_aggs field.
                        */
-                       qfq_activate_agg(q, in_serv_agg, requeue);
-               else if (sch->q.qlen == 0) { /* no aggregate to serve */
+                       qfq_update_agg_ts(q, in_serv_agg, requeue);
+                       qfq_schedule_agg(q, in_serv_agg);
+               } else if (sch->q.qlen == 0) { /* no aggregate to serve */
                        q->in_serv_agg = NULL;
                        return NULL;
                }
        cl->deficit = agg->lmax;
        list_add_tail(&cl->alist, &agg->active);
 
-       if (list_first_entry(&agg->active, struct qfq_class, alist) != cl)
-               return err; /* aggregate was not empty, nothing else to do */
-
-       /* recharge budget */
-       agg->initial_budget = agg->budget = agg->budgetmax;
+       if (list_first_entry(&agg->active, struct qfq_class, alist) != cl ||
+           q->in_serv_agg == agg)
+               return err; /* non-empty or in service, nothing else to do */
 
-       qfq_update_agg_ts(q, agg, enqueue);
-       if (q->in_serv_agg == NULL)
-               q->in_serv_agg = agg;
-       else if (agg != q->in_serv_agg)
-               qfq_schedule_agg(q, agg);
+       qfq_activate_agg(q, agg, enqueue);
 
        return err;
 }
 static void qfq_activate_agg(struct qfq_sched *q, struct qfq_aggregate *agg,
                             enum update_reason reason)
 {
+       agg->initial_budget = agg->budget = agg->budgetmax; /* recharge budg. */
+
        qfq_update_agg_ts(q, agg, reason);
-       qfq_schedule_agg(q, agg);
+       if (q->in_serv_agg == NULL) { /* no aggr. in service or scheduled */
+               q->in_serv_agg = agg; /* start serving this aggregate */
+                /* update V: to be in service, agg must be eligible */
+               q->oldV = q->V = agg->S;
+       } else if (agg != q->in_serv_agg)
+               qfq_schedule_agg(q, agg);
 }
 
 static void qfq_slot_remove(struct qfq_sched *q, struct qfq_group *grp,