patch-2.1.68 linux/include/net/pkt_sched.h

Next file: linux/include/net/protocol.h
Previous file: linux/include/net/netlink.h
Back to the patch index
Back to the overall index

diff -u --recursive --new-file v2.1.67/linux/include/net/pkt_sched.h linux/include/net/pkt_sched.h
@@ -0,0 +1,164 @@
+#ifndef __NET_PKT_SCHED_H
+#define __NET_PKT_SCHED_H
+
+#include <linux/pkt_sched.h>
+
+struct Qdisc_ops
+{
+	struct Qdisc_ops	*next;
+	char			id[IFNAMSIZ];
+	int			refcnt;
+	int			priv_size;
+	int 			(*enqueue)(struct sk_buff *skb, struct Qdisc *);
+	struct sk_buff *	(*dequeue)(struct Qdisc *);
+	void			(*reset)(struct Qdisc *);
+	void			(*destroy)(struct Qdisc *);
+	int			(*init)(struct Qdisc *, void *arg);
+	int			(*control)(struct Qdisc *, void *);
+};
+
+struct Qdisc_head
+{
+	struct Qdisc_head *forw;
+};
+
+extern struct Qdisc_head qdisc_head;
+
+struct Qdisc
+{
+	struct Qdisc_head	h;
+	int 			(*enqueue)(struct sk_buff *skb, struct Qdisc *dev);
+	struct sk_buff *	(*dequeue)(struct Qdisc *dev);
+	struct Qdisc_ops	*ops;
+	int			handle;
+	struct Qdisc		*parent;
+	struct sk_buff_head	q;
+	struct device 		*dev;
+	struct sk_buff_head	failure_q;
+	unsigned long		dropped;
+	unsigned long		tx_last;
+	unsigned long		tx_timeo;
+
+	char			data[0];
+};
+
+
+/* Yes, it is slow for [34]86, but we have no choice.
+   10 msec resolution is appropriate only for bandwidth < 32Kbit/sec.
+
+   RULE:
+   Timer resolution MUST BE < 10% of min_schedulable_packet_size/bandwidth
+   
+   Normal IP packet size ~ 512byte, hence:
+
+   0.5Kbyte/1Mbyte/sec = 0.5msec, so that we need 50usec timer for
+   10Mbit ethernet.
+
+   10msec resolution -> <50Kbit/sec.
+   
+   The result: [34]86 is not good choice for QoS router :-(
+ */
+
+
+typedef struct timeval psched_time_t;
+
+/* On 64bit architecures it would be clever to define:
+typedef u64 psched_time_t;
+   and make all this boring arithmetics directly
+ */
+
+#ifndef SCHEDULE_ONLY_LOW_BANDWIDTH
+#define PSCHED_GET_TIME(stamp) do_gettimeofday(&(stamp))
+#else
+#define PSCHED_GET_TIME(stamp) ((stamp) = xtime)
+#endif
+
+#define PSCHED_TDIFF(tv1, tv2) \
+({ \
+	   int __delta_sec = (tv1).tv_sec - (tv2).tv_sec; \
+	   int __delta = (tv1).tv_usec - (tv2).tv_usec; \
+	   if (__delta_sec) { \
+	           switch (__delta_sec) { \
+		   default: \
+			   __delta = 0; \
+		   case 2: \
+			   __delta += 1000000; \
+		   case 1: \
+			   __delta += 1000000; \
+	           } \
+	   } \
+	   __delta; \
+})
+
+#define PSCHED_TDIFF_SAFE(tv1, tv2, bound, guard) \
+({ \
+	   int __delta_sec = (tv1).tv_sec - (tv2).tv_sec; \
+	   int __delta = (tv1).tv_usec - (tv2).tv_usec; \
+	   switch (__delta_sec) { \
+	   default: \
+		   __delta = (bound); guard; break; \
+	   case 2: \
+		   __delta += 1000000; \
+	   case 1: \
+		   __delta += 1000000; \
+	   case 0: ; \
+	   } \
+	   __delta; \
+})
+
+#define PSCHED_US2JIFFIE(usecs) (((usecs)+(1000000/HZ-1))/(1000000/HZ))
+
+#define PSCHED_TLESS(tv1, tv2) (((tv1).tv_usec < (tv2).tv_usec && \
+				(tv1).tv_sec < (tv2).tv_sec) || \
+				 (tv1).tv_sec < (tv2).tv_sec)
+
+#define PSCHED_TADD2(tv, delta, tv_res) \
+({ \
+	   int __delta = (tv).tv_usec + (delta); \
+	   (tv_res).tv_sec = (tv).tv_sec; \
+	   if (__delta > 1000000) { (tv_res).tv_sec++; __delta -= 1000000; } \
+	   (tv_res).tv_sec = __delta; \
+})
+
+#define PSCHED_TADD(tv, delta) \
+({ \
+	   (tv).tv_usec += (delta); \
+	   if ((tv).tv_usec > 1000000) { (tv).tv_sec++; \
+		 (tv).tv_usec -= 1000000; } \
+})
+
+/* Set/check that undertime is in the "past perfect";
+   it depends on concrete representation of system time
+ */
+
+#define PSCHED_SET_PASTPERFECT(t)	((t).tv_sec = 0)
+#define PSCHED_IS_PASTPERFECT(t)	((t).tv_sec == 0)
+
+
+extern struct Qdisc noop_qdisc;
+
+int register_qdisc(struct Qdisc_ops *qops);
+int unregister_qdisc(struct Qdisc_ops *qops);
+void dev_init_scheduler(struct device *dev);
+void dev_shutdown(struct device *dev);
+void dev_activate(struct device *dev);
+void dev_deactivate(struct device *dev);
+void qdisc_reset(struct Qdisc *qdisc);
+void qdisc_destroy(struct Qdisc *qdisc);
+int pktsched_init(void);
+
+void qdisc_run_queues(void);
+int qdisc_restart(struct device *dev);
+
+extern __inline__ void qdisc_wakeup(struct device *dev)
+{
+	if (!dev->tbusy) {
+		struct Qdisc *q = dev->qdisc;
+		if (qdisc_restart(dev) && q->h.forw == NULL) {
+			q->h.forw = qdisc_head.forw;
+			qdisc_head.forw = &q->h;
+		}
+	}
+}
+
+#endif

FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen, slshen@lbl.gov