Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 4179477f authored by Patrick McHardy's avatar Patrick McHardy Committed by David S. Miller
Browse files

[NET_SCHED]: Add hrtimer based qdisc watchdog

parent 641b9e0e
Loading
Loading
Loading
Loading
+10 −0
Original line number Diff line number Diff line
@@ -64,6 +64,16 @@ typedef long psched_tdiff_t;
#define PSCHED_IS_PASTPERFECT(t)	((t) == 0)
#define	PSCHED_AUDIT_TDIFF(t)

struct qdisc_watchdog {
	struct hrtimer	timer;
	struct Qdisc	*qdisc;
};

extern void qdisc_watchdog_init(struct qdisc_watchdog *wd, struct Qdisc *qdisc);
extern void qdisc_watchdog_schedule(struct qdisc_watchdog *wd,
				    psched_time_t expires);
extern void qdisc_watchdog_cancel(struct qdisc_watchdog *wd);

extern struct Qdisc_ops pfifo_qdisc_ops;
extern struct Qdisc_ops bfifo_qdisc_ops;

+36 −0
Original line number Diff line number Diff line
@@ -34,6 +34,7 @@
#include <linux/kmod.h>
#include <linux/list.h>
#include <linux/bitops.h>
#include <linux/hrtimer.h>

#include <net/sock.h>
#include <net/pkt_sched.h>
@@ -291,6 +292,41 @@ void qdisc_put_rtab(struct qdisc_rate_table *tab)
	}
}

static enum hrtimer_restart qdisc_watchdog(struct hrtimer *timer)
{
	struct qdisc_watchdog *wd = container_of(timer, struct qdisc_watchdog,
						 timer);

	wd->qdisc->flags &= ~TCQ_F_THROTTLED;
	netif_schedule(wd->qdisc->dev);
	return HRTIMER_NORESTART;
}

void qdisc_watchdog_init(struct qdisc_watchdog *wd, struct Qdisc *qdisc)
{
	hrtimer_init(&wd->timer, CLOCK_MONOTONIC, HRTIMER_MODE_ABS);
	wd->timer.function = qdisc_watchdog;
	wd->qdisc = qdisc;
}
EXPORT_SYMBOL(qdisc_watchdog_init);

void qdisc_watchdog_schedule(struct qdisc_watchdog *wd, psched_time_t expires)
{
	ktime_t time;

	wd->qdisc->flags |= TCQ_F_THROTTLED;
	time = ktime_set(0, 0);
	time = ktime_add_ns(time, PSCHED_US2NS(expires));
	hrtimer_start(&wd->timer, time, HRTIMER_MODE_ABS);
}
EXPORT_SYMBOL(qdisc_watchdog_schedule);

void qdisc_watchdog_cancel(struct qdisc_watchdog *wd)
{
	hrtimer_cancel(&wd->timer);
	wd->qdisc->flags &= ~TCQ_F_THROTTLED;
}
EXPORT_SYMBOL(qdisc_watchdog_cancel);

/* Allocate an unique handle from space managed by kernel */