From patchwork Thu Oct 15 06:07:07 2009 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Akinobu Mita X-Patchwork-Id: 36062 X-Patchwork-Delegate: davem@davemloft.net Return-Path: X-Original-To: patchwork-incoming@ozlabs.org Delivered-To: patchwork-incoming@ozlabs.org Received: from vger.kernel.org (vger.kernel.org [209.132.176.167]) by ozlabs.org (Postfix) with ESMTP id 4294AB7063 for ; Thu, 15 Oct 2009 17:15:17 +1100 (EST) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S934283AbZJOGH5 (ORCPT ); Thu, 15 Oct 2009 02:07:57 -0400 Received: (majordomo@vger.kernel.org) by vger.kernel.org id S1753753AbZJOGH5 (ORCPT ); Thu, 15 Oct 2009 02:07:57 -0400 Received: from mail-yw0-f176.google.com ([209.85.211.176]:46496 "EHLO mail-yw0-f176.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1752101AbZJOGHy (ORCPT ); Thu, 15 Oct 2009 02:07:54 -0400 Received: by ywh6 with SMTP id 6so537720ywh.4 for ; Wed, 14 Oct 2009 23:07:17 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=gamma; h=domainkey-signature:received:received:date:from:to:cc:subject :message-id:references:mime-version:content-type:content-disposition :in-reply-to:user-agent; bh=zt0RNvBThTR3fVsk8ZQEHiH3bRV+FYivDbYnWUglF6Q=; b=AsIaxluUr2bb/pLwk5FKvRbcQvl3KgGoZjFmCYcvUxcmE1hCuMVLNG0ePgczEUCR6q xktZuo7CHcimT9aFpng/HLRlMvDdVDFCI8p2Rj1AN10vWGqyEuUdXp0vpfSuhsJvhuJw PAbozhRx6qTzFzfNxqwge3RVdvapY4Z0fG6NI= DomainKey-Signature: a=rsa-sha1; c=nofws; d=gmail.com; s=gamma; h=date:from:to:cc:subject:message-id:references:mime-version :content-type:content-disposition:in-reply-to:user-agent; b=Z8Lm9lqnDwaBz3RdmJ4q73v6WnoX2Y1RWkoH2jo73DjdTkR4yAppr3LIjjsF3aKWFt 9qbG0go6WPvLHfBA3w+ys+hyU0ewg/Zmw7I+IlVpVv+PIaIHQ0B1dB+sF25zUnDV9Ibj /9I6jJq3jtE4GH4/NMiwHRpGkBpPdVw8ixZYc= Received: by 10.150.132.11 with SMTP id f11mr16573835ybd.296.1255586837702; Wed, 14 Oct 2009 23:07:17 -0700 (PDT) Received: from localhost.localdomain ([220.110.185.192]) by mx.google.com with ESMTPS id 13sm331730gxk.9.2009.10.14.23.07.11 (version=TLSv1/SSLv3 cipher=RC4-MD5); Wed, 14 Oct 2009 23:07:16 -0700 (PDT) Date: Thu, 15 Oct 2009 15:07:07 +0900 From: Akinobu Mita To: Andrew Morton Cc: linux-kernel@vger.kernel.org, FUJITA Tomonori , "David S. Miller" , sparclinux@vger.kernel.org, Benjamin Herrenschmidt , Paul Mackerras , linuxppc-dev@ozlabs.org, Thomas Gleixner , Ingo Molnar , "H. Peter Anvin" , x86@kernel.org, Greg Kroah-Hartman , Lothar Wassmann , linux-usb@vger.kernel.org, Roland Dreier , Yevgeny Petrilin , netdev@vger.kernel.org, Tony Luck , Fenghua Yu , linux-ia64@vger.kernel.org, linux-altix@sgi.com, Kyle Hubert Subject: [PATCH -mmotm -v2] Fix bitmap-introduce-bitmap_set-bitmap_clear-bitmap_find_next_zero_area. patch Message-ID: <20091015060706.GA26956@localhost.localdomain> References: <1255076961-21325-1-git-send-email-akinobu.mita@gmail.com> <1255076961-21325-2-git-send-email-akinobu.mita@gmail.com> <20091009164100.85a36188.akpm@linux-foundation.org> <20091013021818.GA3898@localhost.localdomain> <20091013091017.GA18431@localhost.localdomain> <20091014032258.GA18527@localhost.localdomain> MIME-Version: 1.0 Content-Disposition: inline In-Reply-To: <20091014032258.GA18527@localhost.localdomain> User-Agent: Mutt/1.5.18 (2008-05-17) Sender: sparclinux-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: sparclinux@vger.kernel.org From: Akinobu Mita Subject: Fix bitmap-introduce-bitmap_set-bitmap_clear-bitmap_find_next_zero_area.patch - Rewrite bitmap_set and bitmap_clear Instead of setting or clearing for each bit. - Fix off-by-one errors in bitmap_find_next_zero_area This bug was derived from find_next_zero_area in iommu-helper. - Add kerneldoc for bitmap_find_next_zero_area This patch is supposed to be folded into bitmap-introduce-bitmap_set-bitmap_clear-bitmap_find_next_zero_area.patch * -v2 - Remove an extra test at the "index" value by find_next_bit Index was just returned by find_next_zero_bit, so we know it's zero. Noticed-by: Kyle Hubert Signed-off-by: Akinobu Mita --- lib/bitmap.c | 62 ++++++++++++++++++++++++++++++++++++++++++++------------- 1 files changed, 48 insertions(+), 14 deletions(-) diff --git a/lib/bitmap.c b/lib/bitmap.c index 2415da4..962b863 100644 --- a/lib/bitmap.c +++ b/lib/bitmap.c @@ -271,28 +271,62 @@ int __bitmap_weight(const unsigned long *bitmap, int bits) } EXPORT_SYMBOL(__bitmap_weight); -void bitmap_set(unsigned long *map, int i, int len) -{ - int end = i + len; +#define BITMAP_FIRST_WORD_MASK(start) (~0UL << ((start) % BITS_PER_LONG)) - while (i < end) { - __set_bit(i, map); - i++; +void bitmap_set(unsigned long *map, int start, int nr) +{ + unsigned long *p = map + BIT_WORD(start); + const int size = start + nr; + int bits_to_set = BITS_PER_LONG - (start % BITS_PER_LONG); + unsigned long mask_to_set = BITMAP_FIRST_WORD_MASK(start); + + while (nr - bits_to_set >= 0) { + *p |= mask_to_set; + nr -= bits_to_set; + bits_to_set = BITS_PER_LONG; + mask_to_set = ~0UL; + p++; + } + if (nr) { + mask_to_set &= BITMAP_LAST_WORD_MASK(size); + *p |= mask_to_set; } } EXPORT_SYMBOL(bitmap_set); void bitmap_clear(unsigned long *map, int start, int nr) { - int end = start + nr; - - while (start < end) { - __clear_bit(start, map); - start++; + unsigned long *p = map + BIT_WORD(start); + const int size = start + nr; + int bits_to_clear = BITS_PER_LONG - (start % BITS_PER_LONG); + unsigned long mask_to_clear = BITMAP_FIRST_WORD_MASK(start); + + while (nr - bits_to_clear >= 0) { + *p &= ~mask_to_clear; + nr -= bits_to_clear; + bits_to_clear = BITS_PER_LONG; + mask_to_clear = ~0UL; + p++; + } + if (nr) { + mask_to_clear &= BITMAP_LAST_WORD_MASK(size); + *p &= ~mask_to_clear; } } EXPORT_SYMBOL(bitmap_clear); +/* + * bitmap_find_next_zero_area - find a contiguous aligned zero area + * @map: The address to base the search on + * @size: The bitmap size in bits + * @start: The bitnumber to start searching at + * @nr: The number of zeroed bits we're looking for + * @align_mask: Alignment mask for zero area + * + * The @align_mask should be one less than a power of 2; the effect is that + * the bit offset of all zero areas this function finds is multiples of that + * power of 2. A @align_mask of 0 means no alignment is required. + */ unsigned long bitmap_find_next_zero_area(unsigned long *map, unsigned long size, unsigned long start, @@ -304,12 +338,12 @@ again: index = find_next_zero_bit(map, size, start); /* Align allocation */ - index = (index + align_mask) & ~align_mask; + index = __ALIGN_MASK(index, align_mask); end = index + nr; - if (end >= size) + if (end > size) return end; - i = find_next_bit(map, end, index); + i = find_next_bit(map, end, index + 1); if (i < end) { start = i + 1; goto again;