svn commit: r228071 - head/sys/net

Bjoern A. Zeeb bz at FreeBSD.org
Mon Nov 28 19:47:28 UTC 2011


On 28. Nov 2011, at 14:44 , Gleb Smirnoff wrote:

> Author: glebius
> Date: Mon Nov 28 14:44:59 2011
> New Revision: 228071
> URL: http://svn.freebsd.org/changeset/base/228071
> 
> Log:
>  - Use generic alloc_unr(9) allocator for if_clone, instead
>    of hand-made.
>  - When registering new cloner, check whether a cloner with
>    same name already exist.
>  - When allocating unit, also check with help of ifunit()
>    whether such interface already exist or not. [1]

This forces packages to be recompiled;  they might like to have a __FreeBSD_version for that?
It's not MFCable, at least I think - don't see a MFC after, just want to be sure.

See one more comment inline?

> 
>  PR:		kern/162789 [1]
> 
> Modified:
>  head/sys/net/if_clone.c
>  head/sys/net/if_clone.h
> 
> Modified: head/sys/net/if_clone.c
> ==============================================================================
> --- head/sys/net/if_clone.c	Mon Nov 28 14:39:56 2011	(r228070)
> +++ head/sys/net/if_clone.c	Mon Nov 28 14:44:59 2011	(r228071)
> @@ -282,33 +282,34 @@ if_clone_destroyif(struct if_clone *ifc,
> /*
>  * Register a network interface cloner.
>  */
> -void
> +int
> if_clone_attach(struct if_clone *ifc)
> {
> -	int len, maxclone;
> +	struct if_clone *ifc1;
> +
> +	KASSERT(ifc->ifc_name != NULL, ("%s: no name\n", __func__));
> 
> -	/*
> -	 * Compute bitmap size and allocate it.
> -	 */
> -	maxclone = ifc->ifc_maxunit + 1;
> -	len = maxclone >> 3;
> -	if ((len << 3) < maxclone)
> -		len++;
> -	ifc->ifc_units = malloc(len, M_CLONE, M_WAITOK | M_ZERO);
> -	ifc->ifc_bmlen = len;
> 	IF_CLONE_LOCK_INIT(ifc);
> 	IF_CLONE_ADDREF(ifc);
> +	ifc->ifc_unrhdr = new_unrhdr(0, ifc->ifc_maxunit, &ifc->ifc_mtx);
> +	LIST_INIT(&ifc->ifc_iflist);
> 
> 	IF_CLONERS_LOCK();
> +	LIST_FOREACH(ifc1, &V_if_cloners, ifc_list)
> +		if (strcmp(ifc->ifc_name, ifc1->ifc_name) == 0) {
> +			IF_CLONERS_UNLOCK();
> +			IF_CLONE_REMREF(ifc);
> +			return (EEXIST);

At this point you may have a problem not freeing the unr?


> +		}
> 	LIST_INSERT_HEAD(&V_if_cloners, ifc, ifc_list);
> 	V_if_cloners_count++;
> 	IF_CLONERS_UNLOCK();
> 
> -	LIST_INIT(&ifc->ifc_iflist);
> -
> 	if (ifc->ifc_attach != NULL)
> 		(*ifc->ifc_attach)(ifc);
> 	EVENTHANDLER_INVOKE(if_clone_event, ifc);
> +
> +	return (0);
> }
> 
> /*
> @@ -338,16 +339,12 @@ if_clone_detach(struct if_clone *ifc)
> static void
> if_clone_free(struct if_clone *ifc)
> {
> -	for (int bytoff = 0; bytoff < ifc->ifc_bmlen; bytoff++) {
> -		KASSERT(ifc->ifc_units[bytoff] == 0x00,
> -		    ("ifc_units[%d] is not empty", bytoff));
> -	}
> 
> 	KASSERT(LIST_EMPTY(&ifc->ifc_iflist),
> 	    ("%s: ifc_iflist not empty", __func__));
> 
> 	IF_CLONE_LOCK_DESTROY(ifc);
> -	free(ifc->ifc_units, M_CLONE);
> +	delete_unrhdr(ifc->ifc_unrhdr);
> }
> 
> /*
> @@ -441,73 +438,40 @@ ifc_name2unit(const char *name, int *uni
> int
> ifc_alloc_unit(struct if_clone *ifc, int *unit)
> {
> -	int wildcard, bytoff, bitoff;
> -	int err = 0;
> -
> -	IF_CLONE_LOCK(ifc);
> +	char name[IFNAMSIZ];
> +	int wildcard;
> 
> -	bytoff = bitoff = 0;
> 	wildcard = (*unit < 0);
> -	/*
> -	 * Find a free unit if none was given.
> -	 */
> +retry:
> 	if (wildcard) {
> -		while ((bytoff < ifc->ifc_bmlen)
> -		    && (ifc->ifc_units[bytoff] == 0xff))
> -			bytoff++;
> -		if (bytoff >= ifc->ifc_bmlen) {
> -			err = ENOSPC;
> -			goto done;
> -		}
> -		while ((ifc->ifc_units[bytoff] & (1 << bitoff)) != 0)
> -			bitoff++;
> -		*unit = (bytoff << 3) + bitoff;
> -	}
> -
> -	if (*unit > ifc->ifc_maxunit) {
> -		err = ENOSPC;
> -		goto done;
> +		*unit = alloc_unr(ifc->ifc_unrhdr);
> +		if (*unit == -1)
> +			return (ENOSPC);
> +	} else {
> +		*unit = alloc_unr_specific(ifc->ifc_unrhdr, *unit);
> +		if (*unit == -1)
> +			return (EEXIST);
> 	}
> 
> -	if (!wildcard) {
> -		bytoff = *unit >> 3;
> -		bitoff = *unit - (bytoff << 3);
> +	snprintf(name, IFNAMSIZ, "%s%d", ifc->ifc_name, *unit);
> +	if (ifunit(name) != NULL) {
> +		if (wildcard)
> +			goto retry;	/* XXXGL: yep, it's a unit leak */
> +		else
> +			return (EEXIST);
> 	}
> 
> -	if((ifc->ifc_units[bytoff] & (1 << bitoff)) != 0) {
> -		err = EEXIST;
> -		goto done;
> -	}
> -	/*
> -	 * Allocate the unit in the bitmap.
> -	 */
> -	KASSERT((ifc->ifc_units[bytoff] & (1 << bitoff)) == 0,
> -	    ("%s: bit is already set", __func__));
> -	ifc->ifc_units[bytoff] |= (1 << bitoff);
> -	IF_CLONE_ADDREF_LOCKED(ifc);
> +	IF_CLONE_ADDREF(ifc);
> 
> -done:
> -	IF_CLONE_UNLOCK(ifc);
> -	return (err);
> +	return (0);
> }
> 
> void
> ifc_free_unit(struct if_clone *ifc, int unit)
> {
> -	int bytoff, bitoff;
> -
> 
> -	/*
> -	 * Compute offset in the bitmap and deallocate the unit.
> -	 */
> -	bytoff = unit >> 3;
> -	bitoff = unit - (bytoff << 3);
> -
> -	IF_CLONE_LOCK(ifc);
> -	KASSERT((ifc->ifc_units[bytoff] & (1 << bitoff)) != 0,
> -	    ("%s: bit is already cleared", __func__));
> -	ifc->ifc_units[bytoff] &= ~(1 << bitoff);
> -	IF_CLONE_REMREF_LOCKED(ifc);	/* releases lock */
> +	free_unr(ifc->ifc_unrhdr, unit);
> +	IF_CLONE_REMREF(ifc);
> }
> 
> void
> 
> Modified: head/sys/net/if_clone.h
> ==============================================================================
> --- head/sys/net/if_clone.h	Mon Nov 28 14:39:56 2011	(r228070)
> +++ head/sys/net/if_clone.h	Mon Nov 28 14:44:59 2011	(r228071)
> @@ -37,7 +37,15 @@
> 
> #define IFC_CLONE_INITIALIZER(name, data, maxunit,			\
>     attach, match, create, destroy)					\
> -    { { 0 }, name, maxunit, NULL, 0, data, attach, match, create, destroy }
> +    {									\
> +	.ifc_name = name,						\
> +	.ifc_maxunit = maxunit,						\
> +	.ifc_data = data,						\
> +	.ifc_attach = attach,						\
> +	.ifc_match = match,						\
> +	.ifc_create = create,						\
> +	.ifc_destroy = destroy,						\
> +    }
> 
> /*
>  * Structure describing a `cloning' interface.
> @@ -52,10 +60,7 @@ struct if_clone {
> 	LIST_ENTRY(if_clone) ifc_list;	/* (e) On list of cloners */
> 	const char *ifc_name;		/* (c) Name of device, e.g. `gif' */
> 	int ifc_maxunit;		/* (c) Maximum unit number */
> -	unsigned char *ifc_units;	/* (i) Bitmap to handle units. */
> -					/*     Considered private, access */
> -					/*     via ifc_(alloc|free)_unit(). */
> -	int ifc_bmlen;			/* (c) Bitmap length. */
> +	struct unrhdr *ifc_unrhdr;	/* (c) alloc_unr(9) header */
> 	void *ifc_data;			/* (*) Data for ifc_* functions. */
> 
> 	/* (c) Driver specific cloning functions.  Called with no locks held. */
> @@ -65,12 +70,12 @@ struct if_clone {
> 	int	(*ifc_destroy)(struct if_clone *, struct ifnet *);
> 
> 	long ifc_refcnt;		/* (i) Refrence count. */
> -	struct mtx ifc_mtx;		/* Muted to protect members. */
> +	struct mtx ifc_mtx;		/* Mutex to protect members. */
> 	LIST_HEAD(, ifnet) ifc_iflist;	/* (i) List of cloned interfaces */
> };
> 
> void	if_clone_init(void);
> -void	if_clone_attach(struct if_clone *);
> +int	if_clone_attach(struct if_clone *);
> void	if_clone_detach(struct if_clone *);
> void	vnet_if_clone_init(void);
> 

-- 
Bjoern A. Zeeb                                 You have to have visions!
         Stop bit received. Insert coin for new address family.



More information about the svn-src-all mailing list