From 02c271ca5bc95384b5e1d01bd87977c5f865cd60 Mon Sep 17 00:00:00 2001 From: "Luis R. Rodriguez" Date: Fri, 29 Mar 2013 16:13:17 -0700 Subject: [PATCH] compat: backport memweight() mcgrof@frijol ~/linux-next (git::master)$ git describe --contains 639b9e34 v3.6-rc1~41^2~73 commit 639b9e34f15e4b2c30068a4e4485586af0cdf709 Author: Akinobu Mita Date: Mon Jul 30 14:40:55 2012 -0700 string: introduce memweight() memweight() is the function that counts the total number of bits set in memory area. Unlike bitmap_weight(), memweight() takes pointer and size in bytes to specify a memory area which does not need to be aligned to long-word boundary. [akpm@linux-foundation.org: rename `w' to `ret'] Signed-off-by: Akinobu Mita Cc: Anders Larsen Cc: Alasdair Kergon Cc: Laurent Pinchart Cc: Mark Fasheh Cc: Joel Becker Cc: Jan Kara Cc: Andreas Dilger Cc: "Theodore Ts'o" Cc: Matthew Wilcox Cc: Mauro Carvalho Chehab Cc: Tony Luck Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds Signed-off-by: Luis R. Rodriguez --- backport/compat/compat-3.6.c | 38 +++++++++++++++++++++++++++++ backport/include/linux/compat-3.6.h | 3 +++ 2 files changed, 41 insertions(+) diff --git a/backport/compat/compat-3.6.c b/backport/compat/compat-3.6.c index 113e3a867221..a50fc987f569 100644 --- a/backport/compat/compat-3.6.c +++ b/backport/compat/compat-3.6.c @@ -10,6 +10,44 @@ #include #include +#include +#include +#include + +/** + * memweight - count the total number of bits set in memory area + * @ptr: pointer to the start of the area + * @bytes: the size of the area + */ +size_t memweight(const void *ptr, size_t bytes) +{ + size_t ret = 0; + size_t longs; + const unsigned char *bitmap = ptr; + + for (; bytes > 0 && ((unsigned long)bitmap) % sizeof(long); + bytes--, bitmap++) + ret += hweight8(*bitmap); + + longs = bytes / sizeof(long); + if (longs) { + BUG_ON(longs >= INT_MAX / BITS_PER_LONG); + ret += bitmap_weight((unsigned long *)bitmap, + longs * BITS_PER_LONG); + bytes -= longs * sizeof(long); + bitmap += longs * sizeof(long); + } + /* + * The reason that this last loop is distinct from the preceding + * bitmap_weight() call is to compute 1-bits in the last region smaller + * than sizeof(long) properly on big-endian systems. + */ + for (; bytes > 0; bytes--, bitmap++) + ret += hweight8(*bitmap); + + return ret; +} +EXPORT_SYMBOL_GPL(memweight); /** * sg_alloc_table_from_pages - Allocate and initialize an sg table from diff --git a/backport/include/linux/compat-3.6.h b/backport/include/linux/compat-3.6.h index d9c964ed3f9a..bef0503aeff9 100644 --- a/backport/include/linux/compat-3.6.h +++ b/backport/include/linux/compat-3.6.h @@ -7,6 +7,9 @@ #include +#define memweight LINUX_BACKPORT(memweight) +extern size_t memweight(const void *ptr, size_t bytes); + /* backports efc42bc9 */ #define sg_alloc_table_from_pages LINUX_BACKPORT(sg_alloc_table_from_pages) int sg_alloc_table_from_pages(struct sg_table *sgt, -- 2.30.2