« Return to Thread: [patch 0/3] net: Sanitizing hrtimer usage in net/sched/sch_cbq.c

[patch 1/3] net: serialize hrtimer callback in sched_cbq

by Thomas Gleixner :: Rate this Message:

Reply to Author | View in Thread

The hrtimer callback cbq_undelay() is not serialized against
cbq_ovl_delay(). That affects at least q->pmask and q->delay_timer.

Lock it proper.

Signed-off-by: Thomas Gleixner <tglx@...>
---
 net/sched/sch_cbq.c |    8 ++++++++
 1 file changed, 8 insertions(+)

Index: linux-2.6/net/sched/sch_cbq.c
===================================================================
--- linux-2.6.orig/net/sched/sch_cbq.c
+++ linux-2.6/net/sched/sch_cbq.c
@@ -163,6 +163,7 @@ struct cbq_sched_data
  psched_time_t now_rt; /* Cached real time */
  unsigned pmask;
 
+ spinlock_t lock;
  struct hrtimer delay_timer;
  struct qdisc_watchdog watchdog; /* Watchdog timer,
    started when CBQ has
@@ -503,6 +504,9 @@ static void cbq_ovl_delay(struct cbq_cla
  cl->undertime = q->now + delay;
 
  if (delay > 0) {
+ unsigned long flags;
+
+ spin_lock_irqsave(&q->lock, flags);
  sched += delay + cl->penalty;
  cl->penalized = sched;
  cl->cpriority = TC_CBQ_MAXPRIO;
@@ -518,6 +522,7 @@ static void cbq_ovl_delay(struct cbq_cla
  hrtimer_restart(&q->delay_timer);
  cl->delayed = 1;
  cl->xstats.overactions++;
+ spin_unlock_irqrestore(&q->lock, flags);
  return;
  }
  delay = 1;
@@ -599,6 +604,7 @@ static enum hrtimer_restart cbq_undelay(
 
  now = psched_get_time();
 
+ spin_lock(&q->lock);
  pmask = q->pmask;
  q->pmask = 0;
 
@@ -623,6 +629,7 @@ static enum hrtimer_restart cbq_undelay(
  time = ktime_add_ns(time, PSCHED_TICKS2NS(now + delay));
  hrtimer_start(&q->delay_timer, time, HRTIMER_MODE_ABS);
  }
+ spin_unlock(&q->lock);
 
  sch->flags &= ~TCQ_F_THROTTLED;
  __netif_schedule(qdisc_root(sch));
@@ -1396,6 +1403,7 @@ static int cbq_init(struct Qdisc *sch, s
  q->link.avpkt = q->link.allot/2;
  q->link.minidle = -0x7FFFFFFF;
 
+ spin_lock_init(&q->lock);
  qdisc_watchdog_init(&q->watchdog, sch);
  hrtimer_init(&q->delay_timer, CLOCK_MONOTONIC, HRTIMER_MODE_ABS);
  q->delay_timer.function = cbq_undelay;


--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@...
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/

 « Return to Thread: [patch 0/3] net: Sanitizing hrtimer usage in net/sched/sch_cbq.c