svn commit: r204322 - user/luigi/ipfw3-head/sys/netinet/ipfw

Luigi Rizzo luigi at FreeBSD.org
Thu Feb 25 16:14:09 UTC 2010


Author: luigi
Date: Thu Feb 25 16:14:07 2010
New Revision: 204322
URL: http://svn.freebsd.org/changeset/base/204322

Log:
  support for draining idle scheduler and queues.
  On passing, merge in the conditional parts for building
  ipfw and dummynet under linux and windows.
  The differences are small and non intrusive, and it makes
  no sense to keep them out of the tree.

Modified:
  user/luigi/ipfw3-head/sys/netinet/ipfw/ip_dn_private.h
  user/luigi/ipfw3-head/sys/netinet/ipfw/ip_fw_private.h

Modified: user/luigi/ipfw3-head/sys/netinet/ipfw/ip_dn_private.h
==============================================================================
--- user/luigi/ipfw3-head/sys/netinet/ipfw/ip_dn_private.h	Thu Feb 25 16:11:51 2010	(r204321)
+++ user/luigi/ipfw3-head/sys/netinet/ipfw/ip_dn_private.h	Thu Feb 25 16:14:07 2010	(r204322)
@@ -50,7 +50,10 @@ MALLOC_DECLARE(M_DUMMYNET);
 #ifndef FREE_PKT
 #define	FREE_PKT(m)	m_freem(m)
 #endif
+
+#ifndef __linux__
 #define div64(a, b)  ((int64_t)(a) / (int64_t)(b))
+#endif
 
 #define DN_LOCK_INIT() do {				\
 	mtx_init(&dn_cfg.uh_mtx, "dn_uh", NULL, MTX_DEF);	\
@@ -135,6 +138,12 @@ struct dn_parms {
 	struct dn_fsk_head	fsu;	/* list of unlinked flowsets */
 	struct dn_alg_head	schedlist;	/* list of algorithms */
 
+	/* Store the fs/sch to scan when draining. The value is the
+	 * bucket number of the hash table 
+	 **/
+	int drain_fs;
+	int drain_sch;
+	
 	/* if the upper half is busy doing something long,
 	 * can set the busy flag and we will enqueue packets in
 	 * a queue for later processing.
@@ -152,8 +161,14 @@ struct dn_parms {
 	 * bh_mtx protects all other structures which may be
 	 * modified upon packet arrivals
 	 */
+#if defined( __linux__ ) || defined( _WIN32 )
+	spinlock_t uh_mtx;
+	spinlock_t bh_mtx;
+#else
 	struct mtx uh_mtx;
 	struct mtx bh_mtx;
+#endif
+
 #endif /* _KERNEL */
 };
 
@@ -191,6 +206,10 @@ struct dn_fsk { /* kernel side of a flow
 	struct dn_schk *sched;		/* Sched we are linked to */
 	SLIST_ENTRY(dn_fsk) sch_chain;	/* list of fsk attached to sched */
 
+	/* bucket index used by drain routine to drain queues for this
+	 * flowset
+	 */
+	int drain_bucket;
 	/* Parameter realted to RED / GRED */
 	/* original values are in dn_fs*/
 	int w_q ;		/* queue weight (scaled) */
@@ -253,6 +272,11 @@ struct dn_schk {
 	struct dn_fsk_head fsk_list;  /* all fsk linked to me */
 	struct dn_fsk *fs;	/* Flowset for !MULTIQUEUE */
 
+	/* bucket index used by the drain routine to drain the scheduler
+	 * instance for this flowset.
+	 */
+	int drain_bucket;
+
 	/* Hash table of all instances (through sch.sched_mask)
 	 * or single instance if no mask. Always valid.
 	 */
@@ -275,8 +299,41 @@ struct dn_sch_inst {
 	int64_t	credit;		/* bits I can transmit (more or less). */
 	uint64_t sched_time;	/* time link was scheduled in ready_heap */
 	uint64_t idle_time;	/* start of scheduler instance idle time */
+
+	/* q_count is the number of queues that this instance is using.
+	 * The counter is incremented or decremented when
+	 * a reference from the queue is created or deleted.
+	 * It is used to make sure that a scheduler instance can be safely
+	 * deleted by the drain routine. See notes below.
+	 */
+	int q_count;
+
 };
 
+/*
+ * NOTE about object drain.
+ * The system will automatically (XXX check when) drain queues and
+ * scheduler instances when they are idle.
+ * A queue is idle when it has no packets; an instance is idle when
+ * it is not in the evheap heap, and the corresponding delay line is empty.
+ * A queue can be safely deleted when it is idle because of the scheduler
+ * function xxx_free_queue() will remove any references to it.
+ * An instance can be only deleted when no queues reference it. To be sure
+ * of that, a counter (q_count) stores the number of queues that are pointing
+ * to the instance.
+ *
+ * XXX
+ * Order of scan:
+ * - take all flowset in a bucket for the flowset hash table
+ * - take all queues in a bucket for the flowset
+ * - increment the queue bucket
+ * - scan next flowset bucket
+ * Nothing is done if a bucket contains no entries.
+ *
+ * The same schema is used for sceduler instances
+ */
+
+
 /* kernel-side flags. Linux has DN_DELETE in fcntl.h
  */
 enum {
@@ -321,4 +378,8 @@ int copy_data_helper_compat(void *_o, vo
 int dn_compat_calc_size(struct dn_parms dn_cfg);
 int do_config(void *p, int l);
 
+/* function to drain idle object */
+void dn_drain_scheduler(void);
+void dn_drain_queue(void);
+
 #endif /* _IP_DN_PRIVATE_H */

Modified: user/luigi/ipfw3-head/sys/netinet/ipfw/ip_fw_private.h
==============================================================================
--- user/luigi/ipfw3-head/sys/netinet/ipfw/ip_fw_private.h	Thu Feb 25 16:11:51 2010	(r204321)
+++ user/luigi/ipfw3-head/sys/netinet/ipfw/ip_fw_private.h	Thu Feb 25 16:14:07 2010	(r204322)
@@ -35,6 +35,12 @@
 
 #ifdef _KERNEL
 
+#ifndef SYSBEGIN
+#define SYSBEGIN(x)
+#endif
+#ifndef SYSEND
+#define SYSEND
+#endif
 
 /* Return values from ipfw_chk() */
 enum {
@@ -201,8 +207,13 @@ struct ip_fw_chain {
 	struct ip_fw    **map;	/* array of rule ptrs to ease lookup */
 	LIST_HEAD(nat_list, cfg_nat) nat;       /* list of nat entries */
 	struct radix_node_head *tables[IPFW_TABLES_MAX];
+#if defined( __linux__ ) || defined( _WIN32 )
+	spinlock_t rwmtx;
+	spinlock_t uh_lock;
+#else
 	struct rwlock	rwmtx;
 	struct rwlock	uh_lock;	/* lock for upper half */
+#endif
 	uint32_t	id;		/* ruleset id */
 };
 


More information about the svn-src-user mailing list