Re: [PATCH 03/37] dccp: List management for new feature negotiation

Previous message: [thread] [date] [author]
Next message: [thread] [date] [author]
From: Gerrit Renker
Date: Thursday, August 28, 2008 - 10:22 pm

| > +/*
| > + *	List management functions
| > + */
| > +
| > +/**
| > + * dccp_feat_entry_new  -  Central list update routine (called by all others)
| > + * @fn: list to add to
| > + * @feat: feature number
| > + * @is_local: whether the local (1) or remote feature with number @feat is meant
| > + * The function maintains and relies on the following invariants:
| > + *  - each feat_num in the list is known, ie. we know its type and default value
| > + *  - each feat_num/is_local combination is unique (old entries are overwritten)
| > + *  - SP values are always freshly allocated
| > + *  - list is sorted in increasing order of feature number (faster lookup)
| > + */
| > +static struct dccp_feat_entry *
| > +	      dccp_feat_entry_new(struct list_head *fn, u8 feat, u8 is_local)
| > +{
| > +	struct dccp_feat_entry *entry;
| > +	struct list_head *pos_head = fn;
| > +
| > +	list_for_each(pos_head, fn) {
| > +		entry = list_entry(pos_head, struct dccp_feat_entry, node);
| 
| Why not use list_for_each_entry()?
As I recall (and that is now over a year ago), there were reasons for doing
it this way, but at the moment I can not figure out which. It is too
long ago, one of the disadvantages of keeping patches out for so long.


| > +		if (feat < entry->feat_num)
| > +			break;
| > +		if (entry->feat_num == feat && entry->is_local == is_local) {
| > +			dccp_feat_val_destructor(entry->feat_num, &entry->val);
| 
| <first reaction>
| You call dccp_feat_val_destructor on entry->val, that kfrees a field and
| then return it? I havent checked, but would it be safer to set the field
| kfree'ed in dccp_feat_val_destructor to NULL since
| dccp_feat_val_destructor is not a destructor (i.e. its not the last
| function in the life of dccp_feat_val)?
| 
| Humm, and shouldn't this entry be removed from the list?
| </>
Please refer to the comments above the function: 
 | > + *  - each feat_num/is_local combination is unique (old entries are overwritten)
A user is free to call setsocktopt as many times as s/he wants. To avoid
ending up with different values for the same feature in the same list,
there is one a single entry for each {feature, remote|local}
combination. Hence the list is searched first:
	 * if an entry already exists, its entry->val is deallocated
	 * and later filled in new
This is necessary since a user may first allocate {3,2} for a CCID and
then decide to overwrite later with {3}.

If there is no entry yet, a new list entry is kmalloced. Each {feature,	local|remote}
combination is allocated at most once, due to the uniqueness requirement.

| I got confused with a _new routine that ends up not being a constructor
| and _destructor being called on an object, then not setting what it
| frees to NULL and then reusing it somehow
|
It seems that the web server (www.erg.abdn.ac.uk/users/gerrit) is still
down, but this discussion would be much easier with the documentation at
hand. But the purpose of the function should be clear from the comments
above it - it is not a "standard" _new routine, due to the specific
requirements of performing feature negotiation safely.


| > +static struct dccp_feat_entry *dccp_feat_list_lookup(struct list_head *fn_list,
| > +						     u8 feat_num, u8 is_local)
| > +{
| > +	struct dccp_feat_entry *entry;
| > +
| > +	list_for_each_entry(entry, fn_list, node)
| 
| cool, here you use list_for_each_entry :-)
| 
What is "cool" about it?

| > +		if (entry->feat_num == feat_num && entry->is_local == is_local)
| > +			return entry;
| > +		else if (entry->feat_num > feat_num)
| > +			break;
| > +	return NULL;
| > +}
| 
| Humm, wouldn't it be better to make the users of dccp_feat_entry_new
| call dccp_feat_list_lookup and if it returns NULL call
| dccp_feat_entry_new that now would just be what its name implies, i.e. a
| constructor, doing just the kmalloc + member init?
| 
This conflicts with the other requirement
 | > + *  - list is sorted in increasing order of feature number (faster lookup)
I agree, the code may look similar, but in feat_entry_new, the purpose
of the list search is to advance to the position within the sorted list
where to put a new feature. When returning NULL, feat_entry_new would
need to start the same search again.

| > +/**
| > + * dccp_feat_push_change  -  Add/overwrite a Change option in the list
| > + * @fn_list: feature-negotiation list to update
| > + * @feat: one of %dccp_feature_numbers
| > + * @local: whether local (1) or remote (0) @feat_num is meant
| > + * @needs_mandatory: whether to use Mandatory feature negotiation options
| > + * @fval: pointer to NN/SP value to be inserted (will be copied)
| > + */
| > +static int dccp_feat_push_change(struct list_head *fn_list, u8 feat, u8 local,
| > +				 u8 mandatory, dccp_feat_val *fval)
| > +{
| > +	struct dccp_feat_entry *new = dccp_feat_entry_new(fn_list, feat, local);
| > +
| > +	if (new == NULL)
| > +		return -ENOMEM;
| > +
| > +	new->feat_num	     = feat;
| > +	new->is_local	     = local;
| > +	new->state	     = FEAT_INITIALISING;
| > +	new->needs_confirm   = 0;
| > +	new->empty_confirm   = 0;
| > +	new->val	     = *fval;
| > +	new->needs_mandatory = mandatory;
| > +
| > +	return 0;
| > +}
| > +
| > +/**
| > + * dccp_feat_push_confirm  -  Add a Confirm entry to the FN list
| > + * @fn_list: feature-negotiation list to add to
| > + * @feat: one of %dccp_feature_numbers
| > + * @local: whether local (1) or remote (0) @feat_num is being confirmed
| > + * @fval: pointer to NN/SP value to be inserted or NULL
| > + * Returns 0 on success, a Reset code for further processing otherwise.
| > + */
| > +static int dccp_feat_push_confirm(struct list_head *fn_list, u8 feat, u8 local,
| > +				  dccp_feat_val *fval)
| > +{
| > +	struct dccp_feat_entry *new = dccp_feat_entry_new(fn_list, feat, local);
| > +
| > +	if (new == NULL)
| > +		return DCCP_RESET_CODE_TOO_BUSY;
| > +
| > +	new->feat_num	     = feat;
| > +	new->is_local	     = local;
| > +	new->state	     = FEAT_STABLE;	/* transition in 6.6.2 */
| > +	new->needs_confirm   = 1;
| > +	new->empty_confirm   = (fval == NULL);
| > +	new->val.nn	     = 0;		/* zeroes the whole structure */
| > +	if (!new->empty_confirm)
| > +		new->val     = *fval;
| > +	new->needs_mandatory = 0;
| > +
| > +	return 0;
| > +}
| > +
| > +static int dccp_push_empty_confirm(struct list_head *fn_list, u8 feat, u8 local)
| > +{
| > +	return dccp_feat_push_confirm(fn_list, feat, local, NULL);
| > +}
| > +
| > +static inline void dccp_feat_list_pop(struct dccp_feat_entry *entry)
| > +{
| > +	list_del(&entry->node);
| > +	dccp_feat_entry_destructor(entry);
| > +}
| 
| So dccp_feat_entry will always be embedded on other structs? i.e.
| dccp_feat_entry_destructor doesn't frees its space, only fields that
| points to memory allocated elsewhere
| 
Please note that there is a "val destructor" and an "entry destructor",
whose definition is (from the other patch) below:       

static void dccp_feat_entry_destructor(struct dccp_feat_entry *entry)
{
        if (entry != NULL) {
                dccp_feat_val_destructor(entry->feat_num, &entry->val);
                kfree(entry);
        }
}

So this takes care of freeing the value first and then de-allocating the
list entry.

| > +void dccp_feat_list_purge(struct list_head *fn_list)
| > +{
| > +	struct dccp_feat_entry *entry, *next;
| > +
| > +	list_for_each_entry_safe(entry, next, fn_list, node)
| > +		dccp_feat_entry_destructor(entry);
| > +	INIT_LIST_HEAD(fn_list);
| > +}
| 
| Ditto, who frees the struct dccp_feat_entry instances?
| 
Please see above.
--
To unsubscribe from this list: send the line "unsubscribe netdev" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Previous message: [thread] [date] [author]
Next message: [thread] [date] [author]

Messages in current thread:
[PATCH 08/37] dccp: Query supported CCIDs, Gerrit Renker, (Thu Aug 28, 10:44 am)
[PATCH 10/37] dccp: Mechanism to resolve CCID dependencies, Gerrit Renker, (Thu Aug 28, 10:44 am)
[PATCH 11/37] dccp: Deprecate old setsockopt framework, Gerrit Renker, (Thu Aug 28, 10:44 am)
[PATCH 13/37] dccp: Deprecate Ack Ratio sysctl, Gerrit Renker, (Thu Aug 28, 10:44 am)
[PATCH 14/37] dccp: Tidy up setsockopt calls, Gerrit Renker, (Thu Aug 28, 10:44 am)
[PATCH 16/37] dccp: API to query the current TX/RX CCID, Gerrit Renker, (Thu Aug 28, 10:44 am)
[PATCH 18/37] dccp: Support for Mandatory options, Gerrit Renker, (Thu Aug 28, 10:44 am)
[PATCH 22/37] dccp: Preference list reconciliation, Gerrit Renker, (Thu Aug 28, 10:44 am)
[PATCH 24/37] dccp: Processing Confirm options, Gerrit Renker, (Thu Aug 28, 10:44 am)
[PATCH 25/37] dccp: Feature activation handlers, Gerrit Renker, (Thu Aug 28, 10:45 am)
Re: [PATCH 03/37] dccp: List management for new feature ne ..., Arnaldo Carvalho de Melo, (Thu Aug 28, 12:43 pm)
Re: [PATCH 04/37] dccp: Per-socket initialisation of featu ..., Arnaldo Carvalho de Melo, (Thu Aug 28, 12:53 pm)
Re: [PATCH 06/37] dccp: Limit feature negotiation to conne ..., Arnaldo Carvalho de Melo, (Thu Aug 28, 1:50 pm)
Re: [PATCH 07/37] dccp: Registration routines for changing ..., Arnaldo Carvalho de Melo, (Thu Aug 28, 1:54 pm)
Re: [PATCH 08/37] dccp: Query supported CCIDs, Arnaldo Carvalho de Melo, (Thu Aug 28, 2:00 pm)
Re: [PATCH 09/37] dccp: Resolve dependencies of features o ..., Arnaldo Carvalho de Melo, (Thu Aug 28, 2:07 pm)
Re: [PATCH 12/37] dccp: Feature negotiation for minimum-ch ..., Arnaldo Carvalho de Melo, (Thu Aug 28, 2:25 pm)
Re: [PATCH 13/37] dccp: Deprecate Ack Ratio sysctl, Arnaldo Carvalho de Melo, (Thu Aug 28, 2:26 pm)
Re: [PATCH 14/37] dccp: Tidy up setsockopt calls, Arnaldo Carvalho de Melo, (Thu Aug 28, 2:35 pm)
Re: [PATCH 15/37] dccp: Set per-connection CCIDs via socke ..., Arnaldo Carvalho de Melo, (Thu Aug 28, 2:45 pm)
Re: [PATCH 16/37] dccp: API to query the current TX/RX CCID, Arnaldo Carvalho de Melo, (Thu Aug 28, 2:47 pm)
Re: [PATCH 17/37] dccp: Increase the scope of variable-len ..., Arnaldo Carvalho de Melo, (Thu Aug 28, 2:48 pm)
Re: [PATCH 18/37] dccp: Support for Mandatory options, Arnaldo Carvalho de Melo, (Thu Aug 28, 2:50 pm)
Re: [PATCH 03/37] dccp: List management for new feature ne ..., Gerrit Renker, (Thu Aug 28, 10:22 pm)
Re: [PATCH 08/37] dccp: Query supported CCIDs, Gerrit Renker, (Thu Aug 28, 11:17 pm)
Re: [PATCH 14/37] dccp: Tidy up setsockopt calls, Gerrit Renker, (Thu Aug 28, 11:57 pm)
Re: [PATCH 14/37] dccp: Tidy up setsockopt calls, Eugene Teo, (Fri Aug 29, 2:25 am)
Re: [PATCH 08/37] dccp: Query supported CCIDs, Gerrit Renker, (Sat Aug 30, 6:52 am)
Re: [PATCH 14/37] dccp: Tidy up setsockopt calls, Gerrit Renker, (Sat Aug 30, 6:52 am)
Re: [PATCH 0/37] --- Summary of revision changes so far, Gerrit Renker, (Sat Aug 30, 10:25 am)
Re: [PATCH 25/37] dccp: Feature activation handlers, Wei Yongjun, (Mon Sep 1, 11:34 pm)
Re: net-next-2.6 [pull-request] [PATCH 0/37] dccp: Revised ..., Arnaldo Carvalho de Melo, (Tue Sep 2, 6:50 am)
Re: [PATCH 25/37] dccp: Feature activation handlers, Gerrit Renker, (Tue Sep 2, 9:38 pm)
Re: [PATCH 25/37] dccp: Feature activation handlers, Wei Yongjun, (Tue Sep 2, 10:42 pm)
Re: [PATCH 09/37] dccp: Resolve dependencies of features o ..., Arnaldo Carvalho de Melo, (Wed Sep 3, 5:59 pm)
Re: [PATCH 25/37] dccp: Feature activation handlers, Gerrit Renker, (Wed Sep 3, 10:12 pm)
Re: What to do with DCCP, David Miller, (Wed Sep 10, 10:53 pm)
Re: net-next-2.6 [pull-request] [PATCH 0/37] dccp: Revised ..., Arnaldo Carvalho de Melo, (Thu Sep 11, 7:02 am)
Re: What to do with DCCP, Gerrit Renker, (Thu Sep 11, 10:16 pm)
[PATCH 5/5] dccp: Cleanup routines for feature negotiation, Gerrit Renker, (Mon Sep 22, 12:21 am)
Re: [PATCH 1/5] dccp: Basic data structure for feature neg ..., Arnaldo Carvalho de Melo, (Mon Sep 22, 7:10 am)
Re: [PATCH 2/5] dccp: Implement lookup table for feature-n ..., Arnaldo Carvalho de Melo, (Mon Sep 22, 7:21 am)
Re: [PATCH 2/5] dccp: Implement lookup table for feature-n ..., Arnaldo Carvalho de Melo, (Mon Sep 22, 9:49 am)
Re: [PATCH 2/5] dccp: Implement lookup table for feature-n ..., Arnaldo Carvalho de Melo, (Mon Sep 22, 10:00 am)
Re: [PATCH 2/5] dccp: Implement lookup table for feature-n ..., Arnaldo Carvalho de Melo, (Wed Sep 24, 6:58 am)
Re: v2 [PATCH 1/5] dccp: Basic data structure for feature ..., Arnaldo Carvalho de Melo, (Wed Sep 24, 6:59 am)
Re: v2 [PATCH 2/5] dccp: Implement lookup table for featur ..., Arnaldo Carvalho de Melo, (Wed Sep 24, 7:01 am)
[PATCH 3/4] dccp: Query supported CCIDs, Gerrit Renker, (Wed Nov 5, 10:40 pm)
Re: [PATCH 3/4] dccp: Query supported CCIDs, David Miller, (Mon Nov 10, 2:16 pm)
v2 [PATCH 3/4] dccp: Query supported CCIDs, Gerrit Renker, (Tue Nov 11, 11:37 pm)
Re: v2 [PATCH 3/4] dccp: Query supported CCIDs, David Miller, (Wed Nov 12, 1:49 am)
[PATCH 1/5] dccp: Mechanism to resolve CCID dependencies, Gerrit Renker, (Sat Nov 15, 5:11 am)
[PATCH 2/5] dccp: Deprecate old setsockopt framework, Gerrit Renker, (Sat Nov 15, 5:11 am)
[PATCH 4/5] dccp: Deprecate Ack Ratio sysctl, Gerrit Renker, (Sat Nov 15, 5:11 am)
[PATCH 5/5] dccp: Tidy up setsockopt calls, Gerrit Renker, (Sat Nov 15, 5:11 am)
Re: [PATCH 2/5] dccp: Deprecate old setsockopt framework, David Miller, (Sun Nov 16, 11:53 pm)
Re: [PATCH 4/5] dccp: Deprecate Ack Ratio sysctl, David Miller, (Sun Nov 16, 11:56 pm)
Re: [PATCH 5/5] dccp: Tidy up setsockopt calls, David Miller, (Sun Nov 16, 11:57 pm)
Re: [PATCH 2/5] dccp: Deprecate old setsockopt framework, Gerrit Renker, (Mon Nov 17, 8:31 am)
[PATCH 2/5] dccp: API to query the current TX/RX CCID, Gerrit Renker, (Sat Nov 22, 3:30 am)
[PATCH 4/5] dccp: Support for Mandatory options, Gerrit Renker, (Sat Nov 22, 3:30 am)
Re: [PATCH 4/5] dccp: Support for Mandatory options, David Miller, (Sun Nov 23, 5:09 pm)
[PATCH 3/6] dccp: Preference list reconciliation, Gerrit Renker, (Sun Nov 30, 6:22 am)
[PATCH 5/6] dccp: Processing Confirm options, Gerrit Renker, (Sun Nov 30, 6:22 am)
[PATCH 6/6] dccp: Feature activation handlers, Gerrit Renker, (Sun Nov 30, 6:22 am)
Re: [PATCH 2/5] dccp: Auto-load (when supported) CCID plug ..., Michał Mirosław, (Sat Dec 13, 6:55 am)
Re: [PATCH 2/5] dccp: Auto-load (when supported) CCID plug ..., Michał Mirosław, (Sun Dec 14, 7:50 am)
Re: [PATCH 2/5] dccp: Auto-load (when supported) CCID plug ..., Arnaldo Carvalho de Melo, (Mon Dec 15, 6:48 am)
Re: [PATCH 4/5] dccp: Initialisation and type-checking of ..., Arnaldo Carvalho de Melo, (Mon Dec 15, 7:15 am)
Re: [PATCH 2/5] dccp: Auto-load (when supported) CCID plug ..., Arnaldo Carvalho de Melo, (Tue Dec 16, 4:19 am)
Re: [PATCH 2/5] dccp: Auto-load (when supported) CCID plug ..., Michał Mirosław, (Tue Dec 16, 4:31 am)
Re: [PATCH 2/5] dccp: Auto-load (when supported) CCID plug ..., Arnaldo Carvalho de Melo, (Tue Dec 16, 3:25 pm)
Re: [PATCH 2/5] dccp: Auto-load (when supported) CCID plug ..., Arnaldo Carvalho de Melo, (Wed Dec 17, 6:13 am)
Re: [PATCH 2/5] dccp: Auto-load (when supported) CCID plug ..., Arnaldo Carvalho de Melo, (Thu Dec 18, 7:01 am)