Changeset View
Standalone View
sys/netinet/cc/cc.h
Show First 20 Lines • Show All 47 Lines • ▼ Show 20 Lines | |||||
* http://caia.swin.edu.au/urp/newtcp/ | * http://caia.swin.edu.au/urp/newtcp/ | ||||
*/ | */ | ||||
#ifndef _NETINET_CC_CC_H_ | #ifndef _NETINET_CC_CC_H_ | ||||
#define _NETINET_CC_CC_H_ | #define _NETINET_CC_CC_H_ | ||||
#ifdef _KERNEL | #ifdef _KERNEL | ||||
MALLOC_DECLARE(M_CC_MEM); | |||||
/* Global CC vars. */ | /* Global CC vars. */ | ||||
extern STAILQ_HEAD(cc_head, cc_algo) cc_list; | extern STAILQ_HEAD(cc_head, cc_algo) cc_list; | ||||
extern const int tcprexmtthresh; | extern const int tcprexmtthresh; | ||||
extern struct cc_algo newreno_cc_algo; | |||||
/* Per-netstack bits. */ | /* Per-netstack bits. */ | ||||
VNET_DECLARE(struct cc_algo *, default_cc_ptr); | VNET_DECLARE(struct cc_algo *, default_cc_ptr); | ||||
#define V_default_cc_ptr VNET(default_cc_ptr) | #define V_default_cc_ptr VNET(default_cc_ptr) | ||||
VNET_DECLARE(int, cc_do_abe); | VNET_DECLARE(int, cc_do_abe); | ||||
#define V_cc_do_abe VNET(cc_do_abe) | #define V_cc_do_abe VNET(cc_do_abe) | ||||
▲ Show 20 Lines • Show All 66 Lines • ▼ Show 20 Lines | struct cc_algo { | ||||
char name[TCP_CA_NAME_MAX]; | char name[TCP_CA_NAME_MAX]; | ||||
/* Init global module state on kldload. */ | /* Init global module state on kldload. */ | ||||
int (*mod_init)(void); | int (*mod_init)(void); | ||||
/* Cleanup global module state on kldunload. */ | /* Cleanup global module state on kldunload. */ | ||||
int (*mod_destroy)(void); | int (*mod_destroy)(void); | ||||
/* Init CC state for a new control block. */ | /* Return the size of the void pointer the CC needs for state */ | ||||
int (*cb_init)(struct cc_var *ccv); | size_t (*cc_data_sz)(void); | ||||
/* | |||||
* Init CC state for a new control block. The CC | |||||
* module may be passed a NULL ptr indicating that | |||||
* it must allocate the memory. If it is passed a | |||||
* non-null pointer it is pre-allocated memory by | |||||
* the caller and the cb_init is expected to use that memory. | |||||
* It is not expected to fail if memory is passed in and | |||||
* all currently defined modules do not. | |||||
*/ | |||||
int (*cb_init)(struct cc_var *ccv, void *ptr); | |||||
lstewart: Changing this hook's signature should be avoided if at all possible because it's a documented… | |||||
Not Done Inline ActionsHmm first KPI's do change! We are working in head not in stable... so it is completely allowed to change a KPI. And I don't see any CC module that has variable mallocs anywhere by the way and it seems very unlikely to As to your proposal I am fine with it if you can explain in a bit more detail how the cb_init() is going to be able to get a M_WAITOK? The premise right now is I am calling in tcp_usrreq.c malloc before getting a lock, once you call into the cb_init() the Looking through the cb_inits of the CC algorithms that are public I don't see a case where anything is done but As to having a global CC memory type I don't see that as a problem, if there is a leak your going to pretty well rrs: Hmm first KPI's do change! We are working in head not in stable... so it is completely allowed… | |||||
Done Inline ActionsOne other thing if you can provide more details on your M_WAITOK scheme.. I would like you to rrs: One other thing if you can provide more details on your M_WAITOK scheme.. I would like you to… | |||||
/* Cleanup CC state for a terminating control block. */ | /* Cleanup CC state for a terminating control block. */ | ||||
void (*cb_destroy)(struct cc_var *ccv); | void (*cb_destroy)(struct cc_var *ccv); | ||||
/* Init variables for a newly established connection. */ | /* Init variables for a newly established connection. */ | ||||
void (*conn_init)(struct cc_var *ccv); | void (*conn_init)(struct cc_var *ccv); | ||||
/* Called on receipt of an ack. */ | /* Called on receipt of an ack. */ | ||||
void (*ack_received)(struct cc_var *ccv, uint16_t type); | void (*ack_received)(struct cc_var *ccv, uint16_t type); | ||||
Show All 18 Lines | struct cc_algo { | ||||
* send the cwnd in). | * send the cwnd in). | ||||
*/ | */ | ||||
void (*rttsample)(struct cc_var *ccv, uint32_t usec_rtt, uint32_t rxtcnt, uint32_t fas); | void (*rttsample)(struct cc_var *ccv, uint32_t usec_rtt, uint32_t rxtcnt, uint32_t fas); | ||||
/* Called for {get|set}sockopt() on a TCP socket with TCP_CCALGOOPT. */ | /* Called for {get|set}sockopt() on a TCP socket with TCP_CCALGOOPT. */ | ||||
int (*ctl_output)(struct cc_var *, struct sockopt *, void *); | int (*ctl_output)(struct cc_var *, struct sockopt *, void *); | ||||
STAILQ_ENTRY (cc_algo) entries; | STAILQ_ENTRY (cc_algo) entries; | ||||
uint8_t flags; | |||||
}; | }; | ||||
#define CC_MODULE_BEING_REMOVED 0x01 /* The module is being removed */ | |||||
/* Macro to obtain the CC algo's struct ptr. */ | /* Macro to obtain the CC algo's struct ptr. */ | ||||
#define CC_ALGO(tp) ((tp)->cc_algo) | #define CC_ALGO(tp) ((tp)->cc_algo) | ||||
/* Macro to obtain the CC algo's data ptr. */ | /* Macro to obtain the CC algo's data ptr. */ | ||||
#define CC_DATA(tp) ((tp)->ccv->cc_data) | #define CC_DATA(tp) ((tp)->ccv->cc_data) | ||||
/* Macro to obtain the system default CC algo's struct ptr. */ | /* Macro to obtain the system default CC algo's struct ptr. */ | ||||
#define CC_DEFAULT() V_default_cc_ptr | #define CC_DEFAULT_ALGO() V_default_cc_ptr | ||||
extern struct rwlock cc_list_lock; | extern struct rwlock cc_list_lock; | ||||
#define CC_LIST_LOCK_INIT() rw_init(&cc_list_lock, "cc_list") | #define CC_LIST_LOCK_INIT() rw_init(&cc_list_lock, "cc_list") | ||||
#define CC_LIST_LOCK_DESTROY() rw_destroy(&cc_list_lock) | #define CC_LIST_LOCK_DESTROY() rw_destroy(&cc_list_lock) | ||||
#define CC_LIST_RLOCK() rw_rlock(&cc_list_lock) | #define CC_LIST_RLOCK() rw_rlock(&cc_list_lock) | ||||
#define CC_LIST_RUNLOCK() rw_runlock(&cc_list_lock) | #define CC_LIST_RUNLOCK() rw_runlock(&cc_list_lock) | ||||
#define CC_LIST_WLOCK() rw_wlock(&cc_list_lock) | #define CC_LIST_WLOCK() rw_wlock(&cc_list_lock) | ||||
#define CC_LIST_WUNLOCK() rw_wunlock(&cc_list_lock) | #define CC_LIST_WUNLOCK() rw_wunlock(&cc_list_lock) | ||||
#define CC_LIST_LOCK_ASSERT() rw_assert(&cc_list_lock, RA_LOCKED) | #define CC_LIST_LOCK_ASSERT() rw_assert(&cc_list_lock, RA_LOCKED) | ||||
#define CC_ALGOOPT_LIMIT 2048 | #define CC_ALGOOPT_LIMIT 2048 | ||||
/* | |||||
* These routines give NewReno behavior to the caller | |||||
* they require no state and can be used by any other CC | |||||
* module that wishes to use NewReno type behaviour (along | |||||
* with anything else they may add on, pre or post call). | |||||
*/ | |||||
void newreno_common_cc_post_recovery(struct cc_var *); | |||||
void newreno_common_cc_after_idle(struct cc_var *); | |||||
void newreno_common_cc_cong_signal(struct cc_var *, uint32_t ); | |||||
void newreno_common_cc_ack_received(struct cc_var *, uint16_t); | |||||
Not Done Inline ActionsI'm not a fan of this approach. Routines which provide newreno like behaviour belong in the newreno module, or at the very least should retain their newreno naming rather than "common" which is ambiguous and too generic. The approach I'd prefer to see taken is for the newreno CC module to revert to being a stateless CC algo implementation which other modules can continue to call into to execute newreno baseline functionality, and which provides the FreeBSD default algorithm in a minimal footprint way. The ABE + Hystart components which require state would then be excised into a shim module which provides a thin wrapper around cc_newreno with the extra optional functionality included. That gets us the best of both worlds to my mind. lstewart: I'm not a fan of this approach. Routines which provide newreno like behaviour belong in the… | |||||
Done Inline ActionsI strongly disagree with this approach. It makes "newreno" special and it should not be special and it should not I have no problem with naming the generic functions common_newreno_cc_<blah>() but I have great difficulty with any CC module reaching in and running some other CC modules methods. This rrs: I strongly disagree with this approach. It makes "newreno" special and it should not be special… | |||||
#endif /* _KERNEL */ | #endif /* _KERNEL */ | ||||
#endif /* _NETINET_CC_CC_H_ */ | #endif /* _NETINET_CC_CC_H_ */ |
Changing this hook's signature should be avoided if at all possible because it's a documented KPI and present across multiple stable releases i.e. better to extend struct cc_var if there's a need to pass in extra things, or create a new hook.
I'm also not a fan of:
I'd like to propose some tweaks that I think would address my concerns: