On Nov. 10, 2008, 22:21 +0200, Benny Halevy <bhalevy@xxxxxxxxxxx> wrote: > Free a slot in the slot table. > > Mark the slot as free in the bitmap-based allocation table > by clearing a bit corresponding to the slotid. > > Update lowest_free_slotid if freed slotid is lower than that. > Update highest_used_slotid. In the case the freed slotid > equals the highest_used_slotid, scan downwards for the next > highest used slotid using the optimized fls* functions. > > Finally, wake up thread waiting on slot_tbl_waitq for a free slot > to become available. > > Signed-off-by: Benny Halevy <bhalevy@xxxxxxxxxxx> > --- > fs/nfs/nfs4proc.c | 54 +++++++++++++++++++++++++++++++++++++++++++++++++++++ > 1 files changed, 54 insertions(+), 0 deletions(-) > > diff --git a/fs/nfs/nfs4proc.c b/fs/nfs/nfs4proc.c > index 4ded3a5..d26f61d 100644 > --- a/fs/nfs/nfs4proc.c > +++ b/fs/nfs/nfs4proc.c > @@ -243,6 +243,60 @@ static inline int bmp2idx(unsigned long *base, unsigned long *bmp, > } > > /* > + * nfs4_find_slot - free a slot and efficiently update slot table. > + * > + * freeing a slot is trivially done by clearing its respective bit > + * in the bitmap. > + * The lowest_free_slotid is updated if the freed slotid is lower than that. > + * If the freed slotid equals highest_used_slotid we want to update it > + * so that the server would be able to size down the slot table if needed, > + * otherwise we know that the highest_used_slotid is still in use. > + * When updating highest_used_slotid there may be "holes" in the bitmap > + * so we need to scan down from highest_used_slotid to 0 looking for the now > + * highest slotid in use. > + * We use the fls cpu-optimized function to look for the last set bit in each > + * word in the bitmap. > + * If none found, highest_used_slotid is set to -1. > + */ > +static void > +nfs41_free_slot(struct nfs4_slot_table *tbl, struct nfs4_slot *slot) > +{ > + int slotid = slot_idx(tbl, slot); > + unsigned long *used, u; > + int bit; > + > + spin_lock(&tbl->slot_tbl_lock); > + /* clear used bit in bitmap */ > + used = idx2bmp(tbl->used_slots, slotid, &bit); > + *used &= ~(1 << bit); > + > + if (slotid < tbl->lowest_free_slotid) > + tbl->lowest_free_slotid = slotid; > + > + /* update highest_used_slotid when it is freed */ > + if (slotid == tbl->highest_used_slotid) { > + tbl->highest_used_slotid = -1; > + slotid--; > + /* scan down for the highest used slotid */ > + while (slotid >= 0) { > + used = idx2bmp(tbl->used_slots, slotid, NULL); review 11-14: look into using a bitmap_ function, add one if needed > + u = *used; > + if (!u) { > + /* all slots marked free in this word */ > + slotid -= BITS_PER_LONG; > + continue; > + } > + bit = __fls(u); > + tbl->highest_used_slotid = bmp2idx(tbl->used_slots, > + used, bit); > + break; > + } > + } > + spin_unlock(&tbl->slot_tbl_lock); > + rpc_wake_up_next(&tbl->slot_tbl_waitq); > +} > + > +/* > * nfs4_find_slot - efficiently look for a free slot > * > * nfs4_find_slot uses the ffz cpu-optimized function to look for an unset -- 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