aboutsummaryrefslogtreecommitdiffstats
path: root/net
diff options
context:
space:
mode:
authorEric Dumazet <eric.dumazet@gmail.com>2012-01-02 00:47:57 -0500
committerDavid S. Miller <davem@davemloft.net>2012-01-03 12:58:23 -0500
commit6bafcac3238758203703bdd4abe9c1f38d259584 (patch)
treeb5413ecd31f0fa3229b04bd415c870041fe30d95 /net
parent115e8e705e4be071b9e06ff72578e3b603f2ba65 (diff)
sch_qfq: fix overflow in qfq_update_start()
grp->slot_shift is between 22 and 41, so using 32bit wide variables is probably a typo. This could explain QFQ hangs Dave reported to me, after 2^23 packets ? (23 = 64 - 41) Reported-by: Dave Taht <dave.taht@gmail.com> Signed-off-by: Eric Dumazet <eric.dumazet@gmail.com> CC: Stephen Hemminger <shemminger@vyatta.com> CC: Dave Taht <dave.taht@gmail.com> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net')
-rw-r--r--net/sched/sch_qfq.c4
1 files changed, 2 insertions, 2 deletions
diff --git a/net/sched/sch_qfq.c b/net/sched/sch_qfq.c
index 103343408593..7b0325459e71 100644
--- a/net/sched/sch_qfq.c
+++ b/net/sched/sch_qfq.c
@@ -817,11 +817,11 @@ skip_unblock:
817static void qfq_update_start(struct qfq_sched *q, struct qfq_class *cl) 817static void qfq_update_start(struct qfq_sched *q, struct qfq_class *cl)
818{ 818{
819 unsigned long mask; 819 unsigned long mask;
820 uint32_t limit, roundedF; 820 u64 limit, roundedF;
821 int slot_shift = cl->grp->slot_shift; 821 int slot_shift = cl->grp->slot_shift;
822 822
823 roundedF = qfq_round_down(cl->F, slot_shift); 823 roundedF = qfq_round_down(cl->F, slot_shift);
824 limit = qfq_round_down(q->V, slot_shift) + (1UL << slot_shift); 824 limit = qfq_round_down(q->V, slot_shift) + (1ULL << slot_shift);
825 825
826 if (!qfq_gt(cl->F, q->V) || qfq_gt(roundedF, limit)) { 826 if (!qfq_gt(cl->F, q->V) || qfq_gt(roundedF, limit)) {
827 /* timestamp was stale */ 827 /* timestamp was stale */