Skip site navigation (1)Skip section navigation (2)
Date:      Fri, 5 Feb 2010 10:00:18 +0000 (UTC)
From:      Lawrence Stewart <lstewart@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-projects@freebsd.org
Subject:   svn commit: r203517 - projects/tcp_cc_head/sys/netinet
Message-ID:  <201002051000.o15A0Iw5001923@svn.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: lstewart
Date: Fri Feb  5 10:00:18 2010
New Revision: 203517
URL: http://svn.freebsd.org/changeset/base/203517

Log:
  Checkpoint commit. Helper's data block is now passed to it's hook.

Modified:
  projects/tcp_cc_head/sys/netinet/ertt.c
  projects/tcp_cc_head/sys/netinet/helper.c
  projects/tcp_cc_head/sys/netinet/helper.h
  projects/tcp_cc_head/sys/netinet/hhooks.c
  projects/tcp_cc_head/sys/netinet/hhooks.h
  projects/tcp_cc_head/sys/netinet/tcp_input.c
  projects/tcp_cc_head/sys/netinet/tcp_subr.c
  projects/tcp_cc_head/sys/netinet/tcp_var.h

Modified: projects/tcp_cc_head/sys/netinet/ertt.c
==============================================================================
--- projects/tcp_cc_head/sys/netinet/ertt.c	Fri Feb  5 08:56:10 2010	(r203516)
+++ projects/tcp_cc_head/sys/netinet/ertt.c	Fri Feb  5 10:00:18 2010	(r203517)
@@ -52,23 +52,32 @@ __FBSDID("$FreeBSD$");
 #include <netinet/in_var.h>
 #include <netinet/tcp_var.h>
 
+void ertt_tcpest_hook(void *udata, void *ctx_data, void *dblock);
+int ertt_mod_init(void);
+int ertt_mod_destroy(void);
+int ertt_block_init(void **block);
+int ertt_block_destroy(void *block);
+
 struct ertt {
 	int test;
 };
 
-void ertt_tcpest_hook(void *udata, void *ctx_data);
-int ertt_mod_init(void);
-int ertt_mod_destroy(void);
-int ertt_block_init(uintptr_t *block);
-int ertt_block_destroy(uintptr_t *block);
+struct helper ertt_helper = {
+	.mod_init = ertt_mod_init,
+	.mod_destroy = ertt_mod_destroy,
+	.block_init = ertt_block_init,
+	.block_destroy = ertt_block_destroy,
+	.flags = HELPER_NEEDS_DBLOCK
+};
+
 
 void
-ertt_tcpest_hook(void *udata, void *ctx_data)
+ertt_tcpest_hook(void *udata, void *ctx_data, void *dblock)
 {
 	//struct ertt *e = (struct ertt *)(((struct tcpcb *)inp->inp_ppcb)->helper_data[0]);
-	//struct ertt *e = (struct ertt *)arg;
-	printf("In the hook with ctx_data: %p, curack = %d\n", ctx_data,
-	((struct tcp_hhook_data *)ctx_data)->curack);
+	struct ertt *e = (struct ertt *)dblock;
+	printf("In the hook with errt->test: %d, ctx_data: %p, curack = %u\n",
+	e->test, ctx_data, ((struct tcp_hhook_data *)ctx_data)->curack);
 }
 
 
@@ -76,7 +85,7 @@ int
 ertt_mod_init(void)
 {
 	return register_hhook(HHOOK_TYPE_TCP, HHOOK_TCP_ESTABLISHED,
-	&ertt_tcpest_hook, NULL, HHOOK_WAITOK);
+	    &ertt_helper, &ertt_tcpest_hook, NULL, HHOOK_WAITOK);
 }
 
 int
@@ -87,9 +96,9 @@ ertt_mod_destroy(void)
 }
 
 int
-ertt_block_init(uintptr_t *block)
+ertt_block_init(void **block)
 {
-	*block = (uintptr_t)malloc(sizeof(struct ertt), M_HELPER, M_NOWAIT);
+	*block = malloc(sizeof(struct ertt), M_HELPER, M_NOWAIT);
 
 	((struct ertt *)*block)->test = 5;
 
@@ -100,20 +109,12 @@ ertt_block_init(uintptr_t *block)
 }
 
 int
-ertt_block_destroy(uintptr_t *block)
+ertt_block_destroy(void *block)
 {
 	KASSERT(block != NULL, ("Block is NULL!"));
-	free((void *)*block, M_HELPER);
+	free(block, M_HELPER);
 
 	return (0);
 }
 
-struct helper ertt_helper = {
-	.mod_init = ertt_mod_init,
-	.mod_destroy = ertt_mod_destroy,
-	.block_init = ertt_block_init,
-	.block_destroy = ertt_block_destroy,
-	.flags = HLPR_NEEDS_DATABLOCK
-};
-
 DECLARE_HELPER(ertt, &ertt_helper);

Modified: projects/tcp_cc_head/sys/netinet/helper.c
==============================================================================
--- projects/tcp_cc_head/sys/netinet/helper.c	Fri Feb  5 08:56:10 2010	(r203516)
+++ projects/tcp_cc_head/sys/netinet/helper.c	Fri Feb  5 10:00:18 2010	(r203517)
@@ -33,82 +33,100 @@ __FBSDID("$FreeBSD$");
 
 #include <sys/param.h>
 #include <sys/kernel.h>
+#include <sys/lock.h>
 #include <sys/malloc.h>
 #include <sys/module.h>
 #include <sys/queue.h>
+#include <sys/rwlock.h>
 #include <sys/systm.h>
 
 #include <netinet/helper.h>
 #include <netinet/helper_module.h>
 
+static struct rwlock helper_list_lock;
+RW_SYSINIT(helperlistlock, &helper_list_lock, "helper list lock");
 
-struct hlpr_head helpers = STAILQ_HEAD_INITIALIZER(helpers);
-static int num_datablocks = 0;
+static STAILQ_HEAD(hlpr_head, helper) helpers = STAILQ_HEAD_INITIALIZER(helpers);
 
+static int num_dblocks = 0;
 
+/* Monotonically increasing ID assigned to helpers on registration. */
+static int helper_id = 0;
+
+static struct helper * get_helper(int id);
+
+/*
+ * Public KPI functions.
+ */
 int
-init_datablocks(uintptr_t **array_head, int *nblocks)
+init_helper_dblocks(struct helper_dblock **dblocks, int *nblocks)
 {
 	struct helper *h;
-	int i = 0;
+	struct helper_dblock *dblock;
+	int i = 0, error = 0;
 
-	if(num_datablocks <= 0)
-		return (0);
+	HELPER_LIST_RLOCK();
 
+	if (num_dblocks == 0) {
+		HELPER_LIST_RUNLOCK();
+		return (0);
+	}
 
-	*array_head = malloc(num_datablocks * sizeof(uintptr_t), M_HELPER, M_NOWAIT
-	| M_ZERO);
+	*dblocks = malloc(num_dblocks * sizeof(struct helper_dblock), M_HELPER,
+	    M_NOWAIT | M_ZERO);
 
-	printf("Malloced ptr %p for %d data blocks\n", *array_head, num_datablocks);
-	STAILQ_FOREACH(h, &helpers, entries) {
-		KASSERT(i < num_datablocks, ("Badness!\n"));
-		if (h->block_init != NULL) {
-			printf("Calling block_init(%p) for helper: %p\n",
-			(*array_head)+i, h);
-			h->block_init((*array_head)+i);
+	if (*dblocks != NULL) {
+		printf("Malloced ptr %p for %d data blocks\n", *dblocks, num_dblocks);
+		STAILQ_FOREACH(h, &helpers, h_next) {
+			if (h->block_init != NULL) {
+				dblock = dblocks[i];
+				h->block_init(&dblock->block);
+				dblock->id = h->id;
+				printf("dblock[%d]: id=%d, block=%p\n", i,
+				dblock->id, dblock->block);
+			}
+			i++;
 		}
-		i++;
-	}
-
-	*nblocks = num_datablocks;
+		*nblocks = num_dblocks;
+	} else
+		error = ENOMEM;
 
-	return (0);
+	HELPER_LIST_RUNLOCK();
+	return (error);
 }
 
 int
-destroy_datablocks(uintptr_t **array_head, int nblocks)
+destroy_helper_dblocks(struct helper_dblock *array_head, int nblocks)
 {
 	struct helper *h;
-	int i = 0;
-	//for (; nblocks >= 0; nblocks--)
-	//	h->block_destroy();
-
-	STAILQ_FOREACH(h, &helpers, entries) {
-		if (h->block_destroy != NULL) {
-			printf("Calling block_destroy(%p) for helper: %p\n",
-			array_head[i], h);
-			h->block_destroy(array_head[i++]);
-		}
+
+	HELPER_LIST_WLOCK();
+
+	for (nblocks--; nblocks >= 0; nblocks--) {
+		h = get_helper(array_head[nblocks].id);
+		if (h->block_destroy != NULL)
+			h->block_destroy(array_head[nblocks].block);
 	}
 
+	HELPER_LIST_WUNLOCK();
 	return (0);
 }
 
 int
 register_helper(struct helper *h)
 {
-	/*for hooks in hlpr
-		register hlpr_callback for hook
-
-	if !errorgt
-		h->dynamic_id = X
-	*/
 	printf("Register helper 0x%p\n", h);
 
-	if (h->flags | HLPR_NEEDS_DATABLOCK)
-		num_datablocks++;
+	HELPER_LIST_WLOCK();
+
+	if (h->flags | HELPER_NEEDS_DBLOCK)
+		num_dblocks++;
+
+	h->id = helper_id++;
+
+	STAILQ_INSERT_TAIL(&helpers, h, h_next);
 
-	STAILQ_INSERT_TAIL(&helpers, h, entries);
+	HELPER_LIST_WUNLOCK();
 
 	return (0);
 }
@@ -118,12 +136,32 @@ deregister_helper(struct helper *h)
 {
 	printf("Deregister helper 0x%p\n", h);
 
-	STAILQ_REMOVE(&helpers, h, helper, entries);
-	num_datablocks--;
+	HELPER_LIST_WLOCK();
+	STAILQ_REMOVE(&helpers, h, helper, h_next);
+	num_dblocks--;
+	HELPER_LIST_WUNLOCK();
+
+	/* Block unload if there are still consumers to avoid mem leak*/
+
 	return (0);
 }
 
+/*
+ * Private KPI functions.
+ */
+static struct helper *
+get_helper(int id)
+{
+	struct helper *h;
 
+	HELPER_LIST_LOCK_ASSERT();
+
+	STAILQ_FOREACH(h, &helpers, h_next) {
+		if (h->id == id)
+			return (h);
+	}
+	return (NULL);
+}
 
 /*
  * Handles kld related events. Returns 0 on success, non-zero on failure.

Modified: projects/tcp_cc_head/sys/netinet/helper.h
==============================================================================
--- projects/tcp_cc_head/sys/netinet/helper.h	Fri Feb  5 08:56:10 2010	(r203516)
+++ projects/tcp_cc_head/sys/netinet/helper.h	Fri Feb  5 10:00:18 2010	(r203517)
@@ -34,6 +34,13 @@
 #define	_NETINET_HELPER_H_
 
 
+struct helper_dblock {
+	/* ID of the helper this data block is associated with */
+	int id;
+
+	void *block;
+};
+
 struct helper {
 	/* Init global module state on kldload. */
 	int (*mod_init) (void);
@@ -41,28 +48,34 @@ struct helper {
 	/* Cleanup global module state on kldunload. */
 	int (*mod_destroy) (void);
 
-	int (*block_init) (uintptr_t *data);
-	int (*block_destroy) (uintptr_t *data);
+	int (*block_init) (void **data);
+	int (*block_destroy) (void *data);
 
 	uint16_t	flags;
 
 	//STAILQ hooks; /* which hooks does this helper want to be called from */
-	//STAILQ struct helper_data;
-	int dynamic_id; /* ID assigned by system to this hlpr's data in the
+	unsigned int id; /* ID assigned by system to this hlpr's data in the
 	dynamic array */
 
 
-	STAILQ_ENTRY(helper) entries;
+	STAILQ_ENTRY(helper) h_next;
 };
 
 /* Helper flags */
-#define HLPR_NEEDS_DATABLOCK	0x0001
+#define HELPER_NEEDS_DBLOCK	0x0001
 
-extern	STAILQ_HEAD(hlpr_head, helper) helpers;
 
-int	init_datablocks(uintptr_t **array_head, int *nblocks);
-int	destroy_datablocks(uintptr_t **array_head, int nblocks);
+int	init_helper_dblocks(struct helper_dblock **dblocks, int *nblocks);
+int	destroy_helper_dblocks(struct helper_dblock *array_head, int nblocks);
 int	register_helper(struct helper *h);
 int	deregister_helper(struct helper *h);
+/*struct helper_dblock * get_helper_dblock(struct helper_dblock *array_head, int
+id);*/
+
+#define	HELPER_LIST_WLOCK() rw_wlock(&helper_list_lock)
+#define	HELPER_LIST_WUNLOCK() rw_wunlock(&helper_list_lock)
+#define	HELPER_LIST_RLOCK() rw_rlock(&helper_list_lock)
+#define	HELPER_LIST_RUNLOCK() rw_runlock(&helper_list_lock)
+#define	HELPER_LIST_LOCK_ASSERT() rw_assert(&helper_list_lock, RA_LOCKED)
 
 #endif /* _NETINET_HELPER_H_ */

Modified: projects/tcp_cc_head/sys/netinet/hhooks.c
==============================================================================
--- projects/tcp_cc_head/sys/netinet/hhooks.c	Fri Feb  5 08:56:10 2010	(r203516)
+++ projects/tcp_cc_head/sys/netinet/hhooks.c	Fri Feb  5 10:00:18 2010	(r203517)
@@ -53,6 +53,7 @@ MALLOC_DEFINE(M_HHOOK, "helper hook rela
 struct hhook {
 	hhook_func_t h_func;
 	void	*h_udata;
+	struct helper *h_helper;
         STAILQ_ENTRY(hhook) h_next;
 };
 
@@ -138,31 +139,24 @@ deregister_hhook_head(int hhook_type, in
 	}
 
 	HHOOK_HEAD_LIST_UNLOCK();
-
-	/*
-	TAILQ_FOREACH_SAFE(pfh, &ph->ph_in, pfil_link, pfnext)
-		free(pfh, M_IFADDR);
-	TAILQ_FOREACH_SAFE(pfh, &ph->ph_out, pfil_link, pfnext)
-		free(pfh, M_IFADDR);
-	*/
-
 	return (error);
 }
 
 int
-register_hhook(int hhook_type, int hhook_id, hhook_func_t hook, void *udata,
-    int flags)
+register_hhook(int hhook_type, int hhook_id, struct helper *helper,
+    hhook_func_t hook, void *udata, int flags)
 {
 	struct hhook *h, *tmp;
 	struct hhook_head *hh;
 	int error = 0;
 
-	h = malloc(sizeof(struct hhook), M_HHOOK, (flags & HHOOK_WAITOK) ?
-	    M_WAITOK : M_NOWAIT);
+	h = malloc(sizeof(struct hhook), M_HHOOK,
+	    M_ZERO | ((flags & HHOOK_WAITOK) ? M_WAITOK : M_NOWAIT));
 
 	if (h == NULL)
 		return (ENOMEM);
 
+	h->h_helper = helper;
 	h->h_func = hook;
 	h->h_udata = udata;
 
@@ -181,7 +175,7 @@ register_hhook(int hhook_type, int hhook
 	}
 
 	if (!error) {
-		STAILQ_INSERT_HEAD(&hh->hh_hooks, h, h_next);
+		STAILQ_INSERT_TAIL(&hh->hh_hooks, h, h_next);
 		hh->hh_nhooks++;
 	}
 	else
@@ -218,19 +212,34 @@ deregister_hhook(int hhook_type, int hho
 }
 
 void
-run_hhooks(int hhook_type, int hhook_id, void *ctx_data)
+run_hhooks(int hhook_type, int hhook_id, void *ctx_data,
+    struct helper_dblock *dblocks, int n_dblocks)
 {
 	struct hhook_head *hh;
 	struct hhook *tmp;
 	struct rm_priotracker rmpt;
+	int i = 0;
+	void *dblock = NULL;
 
 	hh = get_hhook_head(hhook_type, hhook_id, &rmpt, RLOCK_HHOOK_HEAD);
 
 	if (hh == NULL)
 		return;
 
-	STAILQ_FOREACH(tmp, &hh->hh_hooks, h_next)
-		tmp->h_func(tmp->h_udata, ctx_data);
+	STAILQ_FOREACH(tmp, &hh->hh_hooks, h_next) {
+		printf("Running hook %p for helper %d\n", tmp,
+		tmp->h_helper->id);
+		if (tmp->h_helper->flags & HELPER_NEEDS_DBLOCK) {
+			if (n_dblocks == 0
+			    || i >= n_dblocks
+			    || tmp->h_helper->id != dblocks[i].id)
+				continue;
+			dblock = dblocks[i].block;
+			i++;
+		}
+		tmp->h_func(tmp->h_udata, ctx_data, dblock);
+		dblock = NULL;
+	}
 
 	HHOOK_HEAD_RUNLOCK(hh, &rmpt);
 }

Modified: projects/tcp_cc_head/sys/netinet/hhooks.h
==============================================================================
--- projects/tcp_cc_head/sys/netinet/hhooks.h	Fri Feb  5 08:56:10 2010	(r203516)
+++ projects/tcp_cc_head/sys/netinet/hhooks.h	Fri Feb  5 10:00:18 2010	(r203517)
@@ -38,20 +38,20 @@
 
 #define	HHOOK_TYPE_TCP		1
 
-typedef void (*hhook_func_t)(void *udata, void *ctx_data);
+typedef void (*hhook_func_t)(void *udata, void *ctx_data, void *helper_dblock);
 
+struct helper;
+struct helper_dblock;
 struct hhook_head;
 
 int	register_hhook_head(int hhook_type, int hhook_id, int flags);
 int	deregister_hhook_head(int hhook_type, int hhook_id);
-int	register_hhook(int hhook_type, int hhook_id, hhook_func_t hook,
-    void *udata, int flags);
+int	register_hhook(int hhook_type, int hhook_id, struct helper *helper,
+    hhook_func_t hook, void *udata, int flags);
 int	deregister_hhook(int hhook_type, int hhook_id, hhook_func_t hook,
     void *udata, int flags);
-void	run_hhooks(int hhook_type, int hhook_id, void *ctx_data);
-
-
-#define	HHOOKED(hh) ((hh)->hh_nhooks > 0)
+void	run_hhooks(int hhook_type, int hhook_id, void *ctx_data,
+    struct helper_dblock *dblocks, int n_dblocks);
 
 #define	HHOOK_HEAD_LIST_LOCK() mtx_lock(&hhook_head_list_lock)
 #define	HHOOK_HEAD_LIST_UNLOCK() mtx_unlock(&hhook_head_list_lock)

Modified: projects/tcp_cc_head/sys/netinet/tcp_input.c
==============================================================================
--- projects/tcp_cc_head/sys/netinet/tcp_input.c	Fri Feb  5 08:56:10 2010	(r203516)
+++ projects/tcp_cc_head/sys/netinet/tcp_input.c	Fri Feb  5 10:00:18 2010	(r203517)
@@ -2125,7 +2125,8 @@ tcp_do_segment(struct mbuf *m, struct tc
 			tcp_sack_doack(tp, &to, th->th_ack);
 
 		hhook_data.curack = th->th_ack;
-		run_hhooks(HHOOK_TYPE_TCP, HHOOK_TCP_ESTABLISHED, &hhook_data);
+		run_hhooks(HHOOK_TYPE_TCP, HHOOK_TCP_ESTABLISHED, &hhook_data,
+		tp->dblocks, tp->n_dblocks);
 
 		if (SEQ_LEQ(th->th_ack, tp->snd_una)) {
 			if (tlen == 0 && tiwin == tp->snd_wnd) {

Modified: projects/tcp_cc_head/sys/netinet/tcp_subr.c
==============================================================================
--- projects/tcp_cc_head/sys/netinet/tcp_subr.c	Fri Feb  5 08:56:10 2010	(r203516)
+++ projects/tcp_cc_head/sys/netinet/tcp_subr.c	Fri Feb  5 10:00:18 2010	(r203517)
@@ -774,10 +774,9 @@ tcp_newtcpcb(struct inpcb *inp)
 			return NULL;
 		}
 
-	KASSERT(tp->helper_data == NULL, ("tp->hlpr_data NOT NULL!"));
-	init_datablocks(&tp->helper_data, &tp->nhelpers);
-	printf("tp->helper_data = %p, tp->nhelpers = %d\n", tp->helper_data,
-	tp->nhelpers);
+	KASSERT(tp->dblocks == NULL, ("tp->dblocks NOT NULL!"));
+	init_helper_dblocks(&tp->dblocks, &tp->n_dblocks);
+	printf("tp->dblocks = %p, tp->n_dblocks = %d\n", tp->dblocks, tp->n_dblocks);
 
 #ifdef VIMAGE
 	tp->t_vnet = inp->inp_vnet;
@@ -948,7 +947,7 @@ tcp_discardcb(struct tcpcb *tp)
 	if (CC_ALGO(tp)->cb_destroy != NULL)
 		CC_ALGO(tp)->cb_destroy(tp);
 
-	destroy_datablocks(&tp->helper_data, tp->nhelpers);
+	destroy_helper_dblocks(tp->dblocks, tp->n_dblocks);
 
 	CC_ALGO(tp) = NULL;
 	inp->inp_ppcb = NULL;

Modified: projects/tcp_cc_head/sys/netinet/tcp_var.h
==============================================================================
--- projects/tcp_cc_head/sys/netinet/tcp_var.h	Fri Feb  5 08:56:10 2010	(r203516)
+++ projects/tcp_cc_head/sys/netinet/tcp_var.h	Fri Feb  5 10:00:18 2010	(r203517)
@@ -206,8 +206,8 @@ struct tcpcb {
 	uint64_t _pad[12];		/* 7 UTO, 5 TBD (1-2 CC/RTT?) */
 	struct cc_algo	*cc_algo;	/* the algorithm that will manage congestion control*/
 	void	*cc_data;		/* pointer to a struct containing data required for the cc algorithm in use */
-	uintptr_t	*helper_data;		/* */
-	int		nhelpers;
+	struct helper_dblock	*dblocks;	/* */
+	int		n_dblocks;
 };
 
 /*



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201002051000.o15A0Iw5001923>