public inbox for linux-xfs@vger.kernel.org
 help / color / mirror / Atom feed
From: Russell Cattelan <cattelan@thebarn.com>
To: Andi Kleen <ak@suse.de>
Cc: xfs@oss.sgi.com
Subject: Re: [PATCH] Replace XFS bit functions with Linux functions
Date: Tue, 02 Oct 2007 11:37:21 -0500	[thread overview]
Message-ID: <470273C1.60300@thebarn.com> (raw)
In-Reply-To: <200710021010.58284.ak@suse.de>

[-- Attachment #1: Type: text/plain, Size: 12750 bytes --]

Andi Kleen wrote:
> XFS had some own functions to find high and low bits.
>
> This patch replaces them with a call to the respective Linux functions.
> The semantics of the Linux functions differ a little, but i checked
> all call sites that they can deal with that. I think all callers 
> are ok; but i added a few more asserts for the 0 case (where Linux
> and old XFS differ) just to make it easy to detect mistakes.
>
> The resulting xfs.ko is about 500 bytes smaller on x86-64
>
> This is similar to the patch Eric sent some days ago, but does
> it more efficiently imho. It replaces his patch.
>
> I wasn't able to do a full XFS QA run over this unfortunately; but did careful
> review.
>
>   
I would like to keep thing abstracted enough such that it is won't be to
difficult keep to map to the FreeBSD bit functions.

I have not looked closely at the freebsd functions to see how close they
are semantically.
> Signed-off-by: Andi Kleen <ak@suse.de>
>
> Index: linux-2.6.23-rc8-misc/fs/xfs/xfs_bit.c
> ===================================================================
> --- linux-2.6.23-rc8-misc.orig/fs/xfs/xfs_bit.c
> +++ linux-2.6.23-rc8-misc/fs/xfs/xfs_bit.c
> @@ -22,112 +22,9 @@
>  #include "xfs_buf_item.h"
>  
>  /*
> - * XFS bit manipulation routines, used in non-realtime code.
> + * XFS bit manipulation routines
>   */
>  
> -#ifndef HAVE_ARCH_HIGHBIT
> -/*
> - * Index of high bit number in byte, -1 for none set, 0..7 otherwise.
> - */
> -static const char xfs_highbit[256] = {
> -       -1, 0, 1, 1, 2, 2, 2, 2,			/* 00 .. 07 */
> -	3, 3, 3, 3, 3, 3, 3, 3,			/* 08 .. 0f */
> -	4, 4, 4, 4, 4, 4, 4, 4,			/* 10 .. 17 */
> -	4, 4, 4, 4, 4, 4, 4, 4,			/* 18 .. 1f */
> -	5, 5, 5, 5, 5, 5, 5, 5,			/* 20 .. 27 */
> -	5, 5, 5, 5, 5, 5, 5, 5,			/* 28 .. 2f */
> -	5, 5, 5, 5, 5, 5, 5, 5,			/* 30 .. 37 */
> -	5, 5, 5, 5, 5, 5, 5, 5,			/* 38 .. 3f */
> -	6, 6, 6, 6, 6, 6, 6, 6,			/* 40 .. 47 */
> -	6, 6, 6, 6, 6, 6, 6, 6,			/* 48 .. 4f */
> -	6, 6, 6, 6, 6, 6, 6, 6,			/* 50 .. 57 */
> -	6, 6, 6, 6, 6, 6, 6, 6,			/* 58 .. 5f */
> -	6, 6, 6, 6, 6, 6, 6, 6,			/* 60 .. 67 */
> -	6, 6, 6, 6, 6, 6, 6, 6,			/* 68 .. 6f */
> -	6, 6, 6, 6, 6, 6, 6, 6,			/* 70 .. 77 */
> -	6, 6, 6, 6, 6, 6, 6, 6,			/* 78 .. 7f */
> -	7, 7, 7, 7, 7, 7, 7, 7,			/* 80 .. 87 */
> -	7, 7, 7, 7, 7, 7, 7, 7,			/* 88 .. 8f */
> -	7, 7, 7, 7, 7, 7, 7, 7,			/* 90 .. 97 */
> -	7, 7, 7, 7, 7, 7, 7, 7,			/* 98 .. 9f */
> -	7, 7, 7, 7, 7, 7, 7, 7,			/* a0 .. a7 */
> -	7, 7, 7, 7, 7, 7, 7, 7,			/* a8 .. af */
> -	7, 7, 7, 7, 7, 7, 7, 7,			/* b0 .. b7 */
> -	7, 7, 7, 7, 7, 7, 7, 7,			/* b8 .. bf */
> -	7, 7, 7, 7, 7, 7, 7, 7,			/* c0 .. c7 */
> -	7, 7, 7, 7, 7, 7, 7, 7,			/* c8 .. cf */
> -	7, 7, 7, 7, 7, 7, 7, 7,			/* d0 .. d7 */
> -	7, 7, 7, 7, 7, 7, 7, 7,			/* d8 .. df */
> -	7, 7, 7, 7, 7, 7, 7, 7,			/* e0 .. e7 */
> -	7, 7, 7, 7, 7, 7, 7, 7,			/* e8 .. ef */
> -	7, 7, 7, 7, 7, 7, 7, 7,			/* f0 .. f7 */
> -	7, 7, 7, 7, 7, 7, 7, 7,			/* f8 .. ff */
> -};
> -#endif
> -
> -/*
> - * xfs_highbit32: get high bit set out of 32-bit argument, -1 if none set.
> - */
> -inline int
> -xfs_highbit32(
> -	__uint32_t	v)
> -{
> -#ifdef HAVE_ARCH_HIGHBIT
> -	return highbit32(v);
> -#else
> -	int		i;
> -
> -	if (v & 0xffff0000)
> -		if (v & 0xff000000)
> -			i = 24;
> -		else
> -			i = 16;
> -	else if (v & 0x0000ffff)
> -		if (v & 0x0000ff00)
> -			i = 8;
> -		else
> -			i = 0;
> -	else
> -		return -1;
> -	return i + xfs_highbit[(v >> i) & 0xff];
> -#endif
> -}
> -
> -/*
> - * xfs_lowbit64: get low bit set out of 64-bit argument, -1 if none set.
> - */
> -int
> -xfs_lowbit64(
> -	__uint64_t	v)
> -{
> -	__uint32_t	w = (__uint32_t)v;
> -	int		n = 0;
> -
> -	if (w) {	/* lower bits */
> -		n = ffs(w);
> -	} else {	/* upper bits */
> -		w = (__uint32_t)(v >> 32);
> -		if (w && (n = ffs(w)))
> -			n += 32;
> -	}
> -	return n - 1;
> -}
> -
> -/*
> - * xfs_highbit64: get high bit set out of 64-bit argument, -1 if none set.
> - */
> -int
> -xfs_highbit64(
> -	__uint64_t	v)
> -{
> -	__uint32_t	h = (__uint32_t)(v >> 32);
> -
> -	if (h)
> -		return xfs_highbit32(h) + 32;
> -	return xfs_highbit32((__uint32_t)v);
> -}
> -
> -
>  /*
>   * Return whether bitmap is empty.
>   * Size is number of words in the bitmap, which is padded to word boundary
> Index: linux-2.6.23-rc8-misc/fs/xfs/xfs_bit.h
> ===================================================================
> --- linux-2.6.23-rc8-misc.orig/fs/xfs/xfs_bit.h
> +++ linux-2.6.23-rc8-misc/fs/xfs/xfs_bit.h
> @@ -46,15 +46,6 @@ static inline __uint64_t xfs_mask64lo(in
>  	return ((__uint64_t)1 << (n)) - 1;
>  }
>  
> -/* Get high bit set out of 32-bit argument, -1 if none set */
> -extern int xfs_highbit32(__uint32_t v);
> -
> -/* Get low bit set out of 64-bit argument, -1 if none set */
> -extern int xfs_lowbit64(__uint64_t v);
> -
> -/* Get high bit set out of 64-bit argument, -1 if none set */
> -extern int xfs_highbit64(__uint64_t);
> -
>  /* Return whether bitmap is empty (1 == empty) */
>  extern int xfs_bitmap_empty(uint *map, uint size);
>  
> Index: linux-2.6.23-rc8-misc/fs/xfs/xfs_iget.c
> ===================================================================
> --- linux-2.6.23-rc8-misc.orig/fs/xfs/xfs_iget.c
> +++ linux-2.6.23-rc8-misc/fs/xfs/xfs_iget.c
> @@ -55,8 +55,7 @@ xfs_ihash_init(xfs_mount_t *mp)
>  	if (!mp->m_ihsize) {
>  		icount = mp->m_maxicount ? mp->m_maxicount :
>  			 (mp->m_sb.sb_dblocks << mp->m_sb.sb_inopblog);
> -		mp->m_ihsize = 1 << max_t(uint, 8,
> -					(xfs_highbit64(icount) + 1) / 2);
> +		mp->m_ihsize = 1 << max_t(uint, 8, fls64(icount) / 2);
>  		mp->m_ihsize = min_t(uint, mp->m_ihsize,
>  					(64 * NBPP) / sizeof(xfs_ihash_t));
>  	}
> Index: linux-2.6.23-rc8-misc/fs/xfs/xfs_mount.c
> ===================================================================
> --- linux-2.6.23-rc8-misc.orig/fs/xfs/xfs_mount.c
> +++ linux-2.6.23-rc8-misc/fs/xfs/xfs_mount.c
> @@ -439,7 +439,7 @@ xfs_xlatesb(
>  	mem_ptr = (xfs_caddr_t)sb;
>  
>  	while (fields) {
> -		f = (xfs_sb_field_t)xfs_lowbit64((__uint64_t)fields);
> +		f = (xfs_sb_field_t)find_first_bit((unsigned long *)&fields,64);
>  		first = xfs_sb_info[f].offset;
>  		size = xfs_sb_info[f + 1].offset - first;
>  
> @@ -589,7 +589,7 @@ xfs_mount_common(xfs_mount_t *mp, xfs_sb
>  	mp->m_blkbit_log = sbp->sb_blocklog + XFS_NBBYLOG;
>  	mp->m_blkbb_log = sbp->sb_blocklog - BBSHIFT;
>  	mp->m_sectbb_log = sbp->sb_sectlog - BBSHIFT;
> -	mp->m_agno_log = xfs_highbit32(sbp->sb_agcount - 1) + 1;
> +	mp->m_agno_log = fls(sbp->sb_agcount - 1);
>  	mp->m_agino_log = sbp->sb_inopblog + sbp->sb_agblklog;
>  	mp->m_litino = sbp->sb_inodesize -
>  		((uint)sizeof(xfs_dinode_core_t) + (uint)sizeof(xfs_agino_t));
> @@ -1428,11 +1428,11 @@ xfs_mod_sb(xfs_trans_t *tp, __int64_t fi
>  
>  	/* find modified range */
>  
> -	f = (xfs_sb_field_t)xfs_lowbit64((__uint64_t)fields);
> +	f = (xfs_sb_field_t)find_first_bit((unsigned long *)&fields, 64);
>  	ASSERT((1LL << f) & XFS_SB_MOD_BITS);
>  	first = xfs_sb_info[f].offset;
>  
> -	f = (xfs_sb_field_t)xfs_highbit64((__uint64_t)fields);
> +	f = (xfs_sb_field_t)fls64((__uint64_t)fields) - 1;
>  	ASSERT((1LL << f) & XFS_SB_MOD_BITS);
>  	last = xfs_sb_info[f + 1].offset - 1;
>  
> Index: linux-2.6.23-rc8-misc/fs/xfs/xfs_rtalloc.h
> ===================================================================
> --- linux-2.6.23-rc8-misc.orig/fs/xfs/xfs_rtalloc.h
> +++ linux-2.6.23-rc8-misc/fs/xfs/xfs_rtalloc.h
> @@ -60,13 +60,19 @@ struct xfs_trans;
>  #define	XFS_RTMIN(a,b)	((a) < (b) ? (a) : (b))
>  #define	XFS_RTMAX(a,b)	((a) > (b) ? (a) : (b))
>  
> -#define	XFS_RTLOBIT(w)	xfs_lowbit32(w)
> -#define	XFS_RTHIBIT(w)	xfs_highbit32(w)
> +/* All callers check for 0 arguments already; so no -1 handling */
> +static inline int xfs_rtlobit(unsigned long v)
> +{
> +	return find_first_bit(&v, 32);
> +}
> +
> +#define	XFS_RTLOBIT(w)  xfs_rtlobit(w)
> +#define	XFS_RTHIBIT(w)  (fls(w) - 1)
>  
>  #if XFS_BIG_BLKNOS
> -#define	XFS_RTBLOCKLOG(b)	xfs_highbit64(b)
> +#define	XFS_RTBLOCKLOG(b)	(fls64(b) - 1)
>  #else
> -#define	XFS_RTBLOCKLOG(b)	xfs_highbit32(b)
> +#define	XFS_RTBLOCKLOG(b)	(fls(b) - 1)
>  #endif
>  
>  
> Index: linux-2.6.23-rc8-misc/fs/xfs/xfs_rtalloc.c
> ===================================================================
> --- linux-2.6.23-rc8-misc.orig/fs/xfs/xfs_rtalloc.c
> +++ linux-2.6.23-rc8-misc/fs/xfs/xfs_rtalloc.c
> @@ -73,18 +73,6 @@ STATIC int xfs_rtmodify_summary(xfs_moun
>   */
>  
>  /*
> - * xfs_lowbit32: get low bit set out of 32-bit argument, -1 if none set.
> - */
> -STATIC int
> -xfs_lowbit32(
> -	__uint32_t	v)
> -{
> -	if (v)
> -		return ffs(v) - 1;
> -	return -1;
> -}
> -
> -/*
>   * Allocate space to the bitmap or summary file, and zero it, for growfs.
>   */
>  STATIC int				/* error */
> @@ -444,7 +432,8 @@ xfs_rtallocate_extent_near(
>  	}
>  	bbno = XFS_BITTOBLOCK(mp, bno);
>  	i = 0;
> -	log2len = xfs_highbit32(minlen);
> +	ASSERT(minlen != 0);
> +	log2len = fls(minlen) - 1;
>  	/*
>  	 * Loop over all bitmap blocks (bbno + i is current block).
>  	 */
> @@ -607,11 +596,13 @@ xfs_rtallocate_extent_size(
>  	int		error;		/* error value */
>  	int		i;		/* bitmap block number */
>  	int		l;		/* level number (loop control) */
> +	int 		end;
>  	xfs_rtblock_t	n;		/* next block to be tried */
>  	xfs_rtblock_t	r;		/* result block number */
>  	xfs_suminfo_t	sum;		/* summary information for extents */
>  
>  	ASSERT(minlen % prod == 0 && maxlen % prod == 0);
> +	ASSERT(maxlen != 0);
>  	/*
>  	 * Loop over all the levels starting with maxlen.
>  	 * At each level, look at all the bitmap blocks, to see if there
> @@ -619,7 +610,7 @@ xfs_rtallocate_extent_size(
>  	 * Note, only on the initial level can the allocation fail if
>  	 * the summary says there's an extent.
>  	 */
> -	for (l = xfs_highbit32(maxlen); l < mp->m_rsumlevels; l++) {
> +	for (l = fls(maxlen) - 1; l < mp->m_rsumlevels; l++) {
>  		/*
>  		 * Loop over all the bitmap blocks.
>  		 */
> @@ -669,12 +660,15 @@ xfs_rtallocate_extent_size(
>  		*rtblock = NULLRTBLOCK;
>  		return 0;
>  	}
> +	ASSERT(maxlen != 0);
> +	ASSERT(minlen != 0);
>  	/*
>  	 * Loop over sizes, from maxlen down to minlen.
>  	 * This time, when we do the allocations, allow smaller ones
>  	 * to succeed.
>  	 */
> -	for (l = xfs_highbit32(maxlen); l >= xfs_highbit32(minlen); l--) {
> +	end = fls(minlen) - 1;
> +	for (l = fls(maxlen) - 1; l >= end; l--) {
>  		/*
>  		 * Loop over all the bitmap blocks, try an allocation
>  		 * starting in that block.
> @@ -1863,7 +1857,6 @@ xfs_growfs_rt(
>  	xfs_drfsbno_t	nrblocks;	/* new number of realtime blocks */
>  	xfs_extlen_t	nrbmblocks;	/* new number of rt bitmap blocks */
>  	xfs_drtbno_t	nrextents;	/* new number of realtime extents */
> -	uint8_t		nrextslog;	/* new log2 of sb_rextents */
>  	xfs_extlen_t	nrsumblocks;	/* new number of summary blocks */
>  	uint		nrsumlevels;	/* new rt summary levels */
>  	uint		nrsumsize;	/* new size of rt summary, bytes */
> @@ -1900,8 +1893,7 @@ xfs_growfs_rt(
>  	nrextents = nrblocks;
>  	do_div(nrextents, in->extsize);
>  	nrbmblocks = howmany_64(nrextents, NBBY * sbp->sb_blocksize);
> -	nrextslog = xfs_highbit32(nrextents);
> -	nrsumlevels = nrextslog + 1;
> +	nrsumlevels = fls(nrextents);
>  	nrsumsize = (uint)sizeof(xfs_suminfo_t) * nrsumlevels * nrbmblocks;
>  	nrsumblocks = XFS_B_TO_FSB(mp, nrsumsize);
>  	nrsumsize = XFS_FSB_TO_B(mp, nrsumblocks);
> @@ -1954,7 +1946,8 @@ xfs_growfs_rt(
>  				  nsbp->sb_blocksize * nsbp->sb_rextsize);
>  		nsbp->sb_rextents = nsbp->sb_rblocks;
>  		do_div(nsbp->sb_rextents, nsbp->sb_rextsize);
> -		nsbp->sb_rextslog = xfs_highbit32(nsbp->sb_rextents);
> +		ASSERT(nsbp->sb_rextents != 0);
> +		nsbp->sb_rextslog = fls(nsbp->sb_rextents) - 1;
>  		nrsumlevels = nmp->m_rsumlevels = nsbp->sb_rextslog + 1;
>  		nrsumsize =
>  			(uint)sizeof(xfs_suminfo_t) * nrsumlevels *
> @@ -2317,9 +2310,10 @@ xfs_rtpick_extent(
>  		*seqp = 0;
>  	}
>  	seq = *seqp;
> -	if ((log2 = xfs_highbit64(seq)) == -1)
> +	if ((log2 = fls64(seq)) == 0)
>  		b = 0;
>  	else {
> +		log2--;
>  		resid = seq - (1ULL << log2);
>  		b = (mp->m_sb.sb_rextents * ((resid << 1) + 1ULL)) >>
>  		    (log2 + 1);
> Index: linux-2.6.23-rc8-misc/fs/xfs/xfs_ialloc.h
> ===================================================================
> --- linux-2.6.23-rc8-misc.orig/fs/xfs/xfs_ialloc.h
> +++ linux-2.6.23-rc8-misc/fs/xfs/xfs_ialloc.h
> @@ -57,10 +57,10 @@ xfs_make_iptr(struct xfs_mount *mp, stru
>  #define	XFS_IALLOC_FIND_FREE(fp)	xfs_ialloc_find_free(fp)
>  static inline int xfs_ialloc_find_free(xfs_inofree_t *fp)
>  {
> -	return xfs_lowbit64(*fp);
> +	unsigned long v = *fp; /* Guarantee alignment */
> +	return find_first_bit(&v, 64);
>  }
>  
> -
>  #ifdef __KERNEL__
>  /*
>   * Allocate an inode on disk.
>
>   


[-- Attachment #2: cattelan.vcf --]
[-- Type: text/x-vcard, Size: 131 bytes --]

begin:vcard
fn:Russell Cattelan
n:Cattelan;Russell
email;internet:cattelan@thebarn.com
x-mozilla-html:FALSE
version:2.1
end:vcard


  parent reply	other threads:[~2007-10-02 16:37 UTC|newest]

Thread overview: 8+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2007-10-02  8:10 [PATCH] Replace XFS bit functions with Linux functions Andi Kleen
2007-10-02  9:55 ` Christoph Hellwig
2007-10-02 10:11   ` Andi Kleen
2007-10-02 12:59 ` David Chinner
2007-10-02 13:35   ` Andi Kleen
2007-10-02 16:37 ` Russell Cattelan [this message]
2007-10-03 17:58   ` Andi Kleen
2007-10-03 18:20     ` Russell Cattelan

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=470273C1.60300@thebarn.com \
    --to=cattelan@thebarn.com \
    --cc=ak@suse.de \
    --cc=xfs@oss.sgi.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox