[lustre-devel] [PATCH 09/34] lnet: add list of cpts to lnet_net.

James Simmons jsimmons at infradead.org
Mon Sep 10 18:02:58 PDT 2018


> struct lnet_net now has a list of cpts, which is the union
> of the cpts for each lnet_ni.

Reviewed-by: James Simmons <jsimmons at infradead.org>
The below needs fixing based on response to cover letter.
 
> This is part of
>     8cbb8cd3e771e7f7e0f99cafc19fad32770dc015
>        LU-7734 lnet: Multi-Rail local NI split
>
> Signed-off-by: NeilBrown <neilb at suse.com>
> ---
>  .../staging/lustre/include/linux/lnet/lib-types.h  |    6 +
>  drivers/staging/lustre/lnet/lnet/config.c          |  164 ++++++++++++++++++++
>  2 files changed, 170 insertions(+)
> 
> diff --git a/drivers/staging/lustre/include/linux/lnet/lib-types.h b/drivers/staging/lustre/include/linux/lnet/lib-types.h
> index 2d2c066a11ba..22957d142cc0 100644
> --- a/drivers/staging/lustre/include/linux/lnet/lib-types.h
> +++ b/drivers/staging/lustre/include/linux/lnet/lib-types.h
> @@ -266,6 +266,12 @@ struct lnet_net {
>  	 * lnet/include/lnet/nidstr.h */
>  	__u32			net_id;
>  
> +	/* total number of CPTs in the array */
> +	__u32			net_ncpts;
> +
> +	/* cumulative CPTs of all NIs in this net */
> +	__u32			*net_cpts;
> +
>  	/* network tunables */
>  	struct lnet_ioctl_config_lnd_cmn_tunables net_tunables;
>  
> diff --git a/drivers/staging/lustre/lnet/lnet/config.c b/drivers/staging/lustre/lnet/lnet/config.c
> index e83bdbec11e3..380a3fb1caba 100644
> --- a/drivers/staging/lustre/lnet/lnet/config.c
> +++ b/drivers/staging/lustre/lnet/lnet/config.c
> @@ -91,11 +91,169 @@ lnet_net_unique(__u32 net, struct list_head *netlist)
>  	return true;
>  }
>  
> +static bool
> +in_array(__u32 *array, __u32 size, __u32 value)
> +{
> +	int i;
> +
> +	for (i = 0; i < size; i++) {
> +		if (array[i] == value)
> +			return false;
> +	}
> +
> +	return true;
> +}
> +
> +static int
> +lnet_net_append_cpts(__u32 *cpts, __u32 ncpts, struct lnet_net *net)
> +{
> +	__u32 *added_cpts = NULL;
> +	int i, j = 0, rc = 0;
> +
> +	/*
> +	 * no need to go futher since a subset of the NIs already exist on
> +	 * all CPTs
> +	 */
> +	if (net->net_ncpts == LNET_CPT_NUMBER)
> +		return 0;
> +
> +	if (cpts == NULL) {
> +		/* there is an NI which will exist on all CPTs */
> +		if (net->net_cpts != NULL)
> +			kvfree(net->net_cpts);
> +		net->net_cpts = NULL;
> +		net->net_ncpts = LNET_CPT_NUMBER;
> +		return 0;
> +	}
> +
> +	if (net->net_cpts == NULL) {
> +		net->net_cpts = kmalloc_array(ncpts, sizeof(net->net_cpts),
> +					      GFP_KERNEL);
> +		if (net->net_cpts == NULL)
> +			return -ENOMEM;
> +		memcpy(net->net_cpts, cpts, ncpts);
> +		return 0;
> +	}
> +
> +	added_cpts = kmalloc_array(LNET_CPT_NUMBER, sizeof(*added_cpts),
> +				   GFP_KERNEL);
> +	if (added_cpts == NULL)
> +		return -ENOMEM;
> +
> +	for (i = 0; i < ncpts; i++) {
> +		if (!in_array(net->net_cpts, net->net_ncpts, cpts[i])) {
> +			added_cpts[j] = cpts[i];
> +			j++;
> +		}
> +	}
> +
> +	/* append the new cpts if any to the list of cpts in the net */
> +	if (j > 0) {
> +		__u32 *array = NULL, *loc;
> +		__u32 total_entries = j + net->net_ncpts;
> +
> +		array = kmalloc_array(total_entries, sizeof(*net->net_cpts),
> +				      GFP_KERNEL);
> +		if (array == NULL) {
> +			rc = -ENOMEM;
> +			goto failed;
> +		}
> +
> +		memcpy(array, net->net_cpts,
> +		       net->net_ncpts * sizeof(*net->net_cpts));
> +		loc = array + net->net_ncpts;
> +		memcpy(loc, added_cpts, j * sizeof(*net->net_cpts));
> +
> +		kfree(net->net_cpts);
> +		net->net_ncpts = total_entries;
> +		net->net_cpts = array;
> +	}
> +
> +failed:
> +	kfree(added_cpts);
> +
> +	return rc;
> +}
> +
> +static void
> +lnet_net_remove_cpts(__u32 *cpts, __u32 ncpts, struct lnet_net *net)
> +{
> +	struct lnet_ni *ni;
> +	int rc;
> +
> +	/*
> +	 * Operation Assumption:
> +	 *	This function is called after an NI has been removed from
> +	 *	its parent net.
> +	 *
> +	 * if we're removing an NI which exists on all CPTs then
> +	 * we have to check if any of the other NIs on this net also
> +	 * exists on all CPTs. If none, then we need to build our Net CPT
> +	 * list based on the remaining NIs.
> +	 *
> +	 * If the NI being removed exist on a subset of the CPTs then we
> +	 * alo rebuild the Net CPT list based on the remaining NIs, which
> +	 * should resutl in the expected Net CPT list.
> +	 */
> +
> +	/*
> +	 * sometimes this function can be called due to some failure
> +	 * creating an NI, before any of the cpts are allocated, so check
> +	 * for that case and don't do anything
> +	 */
> +	if (ncpts == 0)
> +		return;
> +
> +	if (ncpts == LNET_CPT_NUMBER) {
> +		/*
> +		 * first iteration through the NI list in the net to see
> +		 * if any of the NIs exist on all the CPTs. If one is
> +		 * found then our job is done.
> +		 */
> +		list_for_each_entry(ni, &net->net_ni_list, ni_netlist) {
> +			if (ni->ni_ncpts == LNET_CPT_NUMBER)
> +				return;
> +		}
> +	}
> +
> +	/*
> +	 * Rebuild the Net CPT list again, thereby only including only the
> +	 * CPTs which the remaining NIs are associated with.
> +	 */
> +	if (net->net_cpts != NULL) {
> +		kfree(net->net_cpts);
> +		net->net_cpts = NULL;
> +	}
> +
> +	list_for_each_entry(ni, &net->net_ni_list, ni_netlist) {
> +		rc = lnet_net_append_cpts(ni->ni_cpts, ni->ni_ncpts,
> +					  net);
> +		if (rc != 0) {
> +			CERROR("Out of Memory\n");
> +			/*
> +			 * do our best to keep on going. Delete
> +			 * the net cpts and set it to NULL. This
> +			 * way we can keep on going but less
> +			 * efficiently, since memory accesses might be
> +			 * accross CPT lines.
> +			 */
> +			if (net->net_cpts != NULL) {
> +				kfree(net->net_cpts);
> +				net->net_cpts = NULL;
> +				net->net_ncpts = LNET_CPT_NUMBER;
> +			}
> +			return;
> +		}
> +	}
> +}
> +
>  void
>  lnet_ni_free(struct lnet_ni *ni)
>  {
>  	int i;
>  
> +	lnet_net_remove_cpts(ni->ni_cpts, ni->ni_ncpts, ni->ni_net);
> +
>  	if (ni->ni_refs)
>  		cfs_percpt_free(ni->ni_refs);
>  
> @@ -128,6 +286,9 @@ lnet_net_free(struct lnet_net *net)
>  		lnet_ni_free(ni);
>  	}
>  
> +	if (net->net_cpts != NULL)
> +		kfree(net->net_cpts);
> +
>  	kfree(net);
>  }
>  
> @@ -229,6 +390,9 @@ lnet_ni_alloc(struct lnet_net *net, struct cfs_expr_list *el, char *iface)
>  		ni->ni_net_ns = NULL;
>  
>  	ni->ni_last_alive = ktime_get_real_seconds();
> +	rc = lnet_net_append_cpts(ni->ni_cpts, ni->ni_ncpts, net);
> +	if (rc != 0)
> +		goto failed;
>  	list_add_tail(&ni->ni_netlist, &net->net_ni_list);
>  
>  	return ni;
> 
> 
> 


More information about the lustre-devel mailing list