aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEric Dumazet <eric.dumazet@gmail.com>2012-01-02 05:47:57 +0000
committerDavid S. Miller <davem@davemloft.net>2012-01-03 12:58:23 -0500
commit6bafcac3238758203703bdd4abe9c1f38d259584 (patch)
treeb5413ecd31f0fa3229b04bd415c870041fe30d95
parent115e8e705e4be071b9e06ff72578e3b603f2ba65 (diff)
downloadlinux-linaro-6bafcac3238758203703bdd4abe9c1f38d259584.tar.gz
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>
-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 10334340859..7b0325459e7 100644
--- a/net/sched/sch_qfq.c
+++ b/net/sched/sch_qfq.c
@@ -817,11 +817,11 @@ skip_unblock:
static void qfq_update_start(struct qfq_sched *q, struct qfq_class *cl)
{
unsigned long mask;
- uint32_t limit, roundedF;
+ u64 limit, roundedF;
int slot_shift = cl->grp->slot_shift;
roundedF = qfq_round_down(cl->F, slot_shift);
- limit = qfq_round_down(q->V, slot_shift) + (1UL << slot_shift);
+ limit = qfq_round_down(q->V, slot_shift) + (1ULL << slot_shift);
if (!qfq_gt(cl->F, q->V) || qfq_gt(roundedF, limit)) {
/* timestamp was stale */