summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMichal Soltys <soltys@ziu.info>2016-06-29 20:26:44 -0400
committerDavid S. Miller <davem@davemloft.net>2016-07-01 05:03:43 -0400
commit12d0ad3be9c3854e52ec74bb83bb6f43612827c7 (patch)
treeabdffc0beb64f19e9535603f30ed21a67a8f46d4
parent19689e38eca5d7b32755182d4e62efd7a5376c45 (diff)
net/sched/sch_hfsc.c: handle corner cases where head may change invalidating calculated deadline
Realtime scheduling implemented in HFSC uses head of the queue to make the decision about which packet to schedule next. But in case of any head drop, the deadline calculated for the previous head is not necessarily correct for the next head (unless both packets have the same length). Thanks to peek() function used during dequeue - which internally is a dequeue operation - hfsc is almost safe from this issue, as peek() dequeues and isolates the head storing it temporarily until the real dequeue happens. But there is one exception: if after the class activation a drop happens before the first dequeue operation, there's never a chance to do the peek(). Adding peek() call in enqueue - if this is the first packet in a new backlog period AND the scheduler has realtime curve defined - fixes that one corner case. The 1st hfsc_dequeue() will use that peeked packet, similarly as every subsequent hfsc_dequeue() call uses packet peeked by the previous call. Signed-off-by: Michal Soltys <soltys@ziu.info> Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r--net/sched/sch_hfsc.c11
1 files changed, 10 insertions, 1 deletions
diff --git a/net/sched/sch_hfsc.c b/net/sched/sch_hfsc.c
index 8cb5eff7b79c..6d6df6b2d38f 100644
--- a/net/sched/sch_hfsc.c
+++ b/net/sched/sch_hfsc.c
@@ -1594,8 +1594,17 @@ hfsc_enqueue(struct sk_buff *skb, struct Qdisc *sch, struct sk_buff **to_free)
1594 return err; 1594 return err;
1595 } 1595 }
1596 1596
1597 if (cl->qdisc->q.qlen == 1) 1597 if (cl->qdisc->q.qlen == 1) {
1598 set_active(cl, qdisc_pkt_len(skb)); 1598 set_active(cl, qdisc_pkt_len(skb));
1599 /*
1600 * If this is the first packet, isolate the head so an eventual
1601 * head drop before the first dequeue operation has no chance
1602 * to invalidate the deadline.
1603 */
1604 if (cl->cl_flags & HFSC_RSC)
1605 cl->qdisc->ops->peek(cl->qdisc);
1606
1607 }
1599 1608
1600 qdisc_qstats_backlog_inc(sch, skb); 1609 qdisc_qstats_backlog_inc(sch, skb);
1601 sch->q.qlen++; 1610 sch->q.qlen++;