svn commit: r203517 - projects/tcp_cc_head/sys/netinet
Lawrence Stewart
lstewart at FreeBSD.org
Fri Feb 5 10:00:18 UTC 2010
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;
};
/*
More information about the svn-src-projects
mailing list