Le jeudi 24 juin 2010 à 13:02 +1000, npiggin@xxxxxxx a écrit : > pièce jointe document texte brut (list-bitlock.patch) > Introduce a type of hlist that can support the use of the lowest bit in the > hlist_head. This will be subsequently used to implement per-bucket bit spinlock > for inode and dentry hashes. > > Signed-off-by: Nick Piggin <npiggin@xxxxxxx> > > --- > include/linux/list_bl.h | 99 +++++++++++++++++++++++++++++++++++++ > include/linux/rculist_bl.h | 120 +++++++++++++++++++++++++++++++++++++++++++++ > 2 files changed, 219 insertions(+) > > Index: linux-2.6/include/linux/list_bl.h > =================================================================== > --- /dev/null > +++ linux-2.6/include/linux/list_bl.h > @@ -0,0 +1,99 @@ > +#ifndef _LINUX_LIST_BL_H > +#define _LINUX_LIST_BL_H > + > +#include <linux/list.h> > + > +/* > + * Special version of lists, where head of the list has a bit spinlock > + * in the lowest bit. This is useful for scalable hash tables without > + * increasing memory footprint overhead. > + */ > + > +struct hlist_bl_head { > + struct hlist_bl_node *first; > +}; > + > +struct hlist_bl_node { > + struct hlist_bl_node *next, **pprev; > +}; > +#define INIT_HLIST_BL_HEAD(ptr) \ > + ((ptr)->first = NULL) > + > +static inline void INIT_HLIST_BL_NODE(struct hlist_bl_node *h) > +{ > + h->next = NULL; > + h->pprev = NULL; > +} > + > +#define hlist_bl_entry(ptr, type, member) container_of(ptr,type,member) > + > +static inline int hlist_bl_unhashed(const struct hlist_bl_node *h) > +{ > + return !h->pprev; > +} > + > +static inline struct hlist_bl_node *hlist_bl_first(struct hlist_bl_head *h) > +{ > + return (struct hlist_bl_node *)((unsigned long)h->first & ~1UL); > +} > + > +static inline void hlist_bl_set_first(struct hlist_bl_head *h, struct hlist_bl_node *n) > +{ > + h->first = (struct hlist_bl_node *)((unsigned long)n | ((unsigned long)h->first & 1UL)); Hmm, shouldnt hlist_bl_set_first() be used only with bit lock held ? h->first = (struct hlist_bl_node *)((unsigned long)n | 1UL); > +} > + > + > +static inline void hlist_bl_set_first_rcu(struct hlist_bl_head *h, struct hlist_bl_node *n) > +{ > + rcu_assign_pointer(h->first, (struct hlist_bl_node *)((unsigned long)n | ((unsigned long)h->first & 1UL))); Same question here. > +} > + > +static inline struct hlist_bl_node *hlist_bl_first_rcu(struct hlist_bl_head *h) > +{ > + return (struct hlist_bl_node *)((unsigned long)rcu_dereference(h->first) & ~1UL); > +} Looks really nice Nick, maybe we should push this so that other subsystem can start using it. Thanks -- To unsubscribe from this list: send the line "unsubscribe linux-fsdevel" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html