Re: [pnfs] [RFC 20/85] nfs41: slot table init and destroy

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



On Nov. 10, 2008, 22:21 +0200, Benny Halevy <bhalevy@xxxxxxxxxxx> wrote:
> Code to initialize and destroy the slot table.
> Uses bitmap-based allocation.
> 
> Signed-off-by: Andy Adamson<andros@xxxxxxxxxx>
> Signed-off-by: Benny Halevy <bhalevy@xxxxxxxxxxx>
> ---
>  fs/nfs/nfs4proc.c            |   88 ++++++++++++++++++++++++++++++++++++++++++
>  include/linux/nfs4_session.h |   17 ++++++++
>  2 files changed, 105 insertions(+), 0 deletions(-)
> 
> diff --git a/fs/nfs/nfs4proc.c b/fs/nfs/nfs4proc.c
> index d0b6ca1..08e7129 100644
> --- a/fs/nfs/nfs4proc.c
> +++ b/fs/nfs/nfs4proc.c
> @@ -3683,6 +3683,92 @@ int nfs4_proc_fs_locations(struct inode *dir, const struct qstr *name,
>  }
>  
>  #ifdef CONFIG_NFS_V4_1
> +/*
> + * Initialize slot table
> + *
> + * Note: the "used" bitmap points to _used_slots id max_slots <= BITS_PER_LONG.
> + * Otherwise, we dynamically allocate enough ulongs to hold max_slots bits.
> + */
> +static int nfs4_init_slot_table(struct nfs4_channel *channel)
> +{
> +	struct nfs4_slot_table *tbl = &channel->slot_table;
> +	int i, max_slots = channel->chan_attrs.max_reqs;
> +	struct nfs4_slot *slot;
> +	unsigned long *used;
> +	int ret = -ENOMEM;
> +
> +	dprintk("--> %s: max_reqs=%u\n", __func__,
> +		channel->chan_attrs.max_reqs);
> +	slot = kzalloc(max_slots * sizeof(struct nfs4_slot), GFP_ATOMIC);
> +	if (!slot)
> +		goto out;
> +	for (i = 0; i < max_slots; ++i)
> +		slot[i].seq_nr = 1;
> +
> +	if (max_slots <= BITS_PER_LONG)
> +		used = &tbl->_used_slots;	/* use word in tbl */
> +	else {
> +		/* allocate enough unsigned longs for max_slots bits */
> +		used = kzalloc(sizeof(unsigned long) *
> +				DIV_ROUND_UP(max_slots, BITS_PER_LONG),
> +			       GFP_ATOMIC);
> +		if (!used)
> +			goto out_free;
> +	}
> +	ret = 0;
> +
> +	spin_lock(&tbl->slot_tbl_lock);
> +	if (tbl->slots != NULL) {
> +		spin_unlock(&tbl->slot_tbl_lock);
> +		dprintk("%s: slot table already initialized. tbl=%p slots=%p\n",
> +			__func__, tbl, tbl->slots);
> +		WARN_ON(1);
> +		goto out_free;
> +	}
> +	tbl->max_slots = max_slots;
> +	tbl->slots = slot;
> +	tbl->used_slots = used;
> +	tbl->lowest_free_slotid = 0;	/* first slot is free */
> +	tbl->highest_used_slotid = -1;	/* no slot is currently used */
> +	spin_unlock(&tbl->slot_tbl_lock);
> +	dprintk("%s: tbl=%p slots=%p max_slots=%d\n", __func__,
> +		tbl, tbl->slots, tbl->max_slots);
> +out:
> +	dprintk("<-- %s: return %d\n", __func__, ret);
> +	return ret;
> +out_free:
> +	kfree(slot);
> +	if (used != &tbl->_used_slots)
> +		kfree(used);
> +	goto out;
> +}
> +
> +/* Destroy the slot table */
> +static void nfs4_destroy_slot_table(struct nfs4_channel *channel)
> +{
> +	if (channel->slot_table.slots == NULL)
> +		return;
> +	kfree(channel->slot_table.slots);
> +	channel->slot_table.slots = NULL;
> +	/* Was the "used" bitmap dynamically allocated? */
> +	if (channel->slot_table.used_slots != &channel->slot_table._used_slots)
> +		kfree(channel->slot_table.used_slots);
> +
> +	return;
> +}
> +
> +static int nfs4_init_channel(struct nfs4_channel *channel)
> +{
> +	struct nfs4_slot_table *tbl;
> +
> +	tbl = &channel->slot_table;
> +
> +	spin_lock_init(&tbl->slot_tbl_lock);
> +	rpc_init_wait_queue(&tbl->slot_tbl_waitq, "Slot table");
> +
> +	return 0;
> +}
> +
>  struct nfs4_session *nfs4_alloc_session(void)
>  {
>  	struct nfs4_session *session;
> @@ -3693,6 +3779,7 @@ struct nfs4_session *nfs4_alloc_session(void)
>  
>  	atomic_set(&session->ref_count, 1);
>  
> +	nfs4_init_channel(&session->fore_channel);
>  	return session;
>  }
>  
> @@ -3706,6 +3793,7 @@ void nfs4_put_session(struct nfs4_session **session)
>  {
>  	dprintk("--> nfs4_put_session()\n");
>  	if (atomic_dec_and_test(&((*session)->ref_count))) {
> +		nfs4_destroy_slot_table(&((*session)->fore_channel));
>  		nfs4_free_session(*session);
>  		*session = NULL;
>  	}
> diff --git a/include/linux/nfs4_session.h b/include/linux/nfs4_session.h
> index 36c0f94..d534269 100644
> --- a/include/linux/nfs4_session.h
> +++ b/include/linux/nfs4_session.h
> @@ -17,9 +17,26 @@ struct nfs4_channel_attrs {
>  	u32			rdma_attrs;
>  };
>  
> +struct nfs4_slot {
> +	u32		 	seq_nr;
> +};
> +
> +struct nfs4_slot_table {
> +	struct nfs4_slot *slots;		/* seqid per slot */
> +	unsigned long	*used_slots;		/* used/unused bitmap */
> +	unsigned long	_used_slots;		/* used when max_slots fits */

review 11-14: just limit to 128 bits, no dynamic allocation

> +	spinlock_t	slot_tbl_lock;
> +	struct rpc_wait_queue	slot_tbl_waitq;	/* allocators may wait here */
> +	int		max_slots;		/* # slots in table */
> +	int		lowest_free_slotid;	/* lower bound hint */
> +	int		highest_used_slotid;	/* sent to server on each SEQ.
> +						 * op for dynamic resizing */
> +};
> +
>  struct nfs4_channel {
>  	struct nfs4_channel_attrs 	chan_attrs;
>  	struct rpc_clnt 		*rpc_client;
> +	struct nfs4_slot_table		slot_table;
>  };
>  
>  /*
--
To unsubscribe from this list: send the line "unsubscribe linux-nfs" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html

[Index of Archives]     [Linux Filesystem Development]     [Linux USB Development]     [Linux Media Development]     [Video for Linux]     [Linux NILFS]     [Linux Audio Users]     [Yosemite Info]     [Linux SCSI]

  Powered by Linux