[PATCH v2 08/10] powerpc: use for_each_sg()

2015-05-01 Thread Akinobu Mita
This replaces the plain loop over the sglist array with for_each_sg()
macro which consists of sg_next() function calls.  Since powerpc does
select ARCH_HAS_SG_CHAIN, it is necessary to use for_each_sg() in
order to loop over each sg element.  This also help find problems with
drivers that do not properly initialize their sg tables when
CONFIG_DEBUG_SG is enabled.

Signed-off-by: Akinobu Mita 
Cc: Benjamin Herrenschmidt 
Cc: Paul Mackerras 
Cc: Michael Ellerman 
Cc: linuxppc-dev@lists.ozlabs.org
Cc: linux-a...@vger.kernel.org
---
* New patch from v2

 arch/powerpc/kernel/vio.c | 10 +-
 1 file changed, 5 insertions(+), 5 deletions(-)

diff --git a/arch/powerpc/kernel/vio.c b/arch/powerpc/kernel/vio.c
index 5bfdab9..b7a6844 100644
--- a/arch/powerpc/kernel/vio.c
+++ b/arch/powerpc/kernel/vio.c
@@ -557,11 +557,11 @@ static int vio_dma_iommu_map_sg(struct device *dev, 
struct scatterlist *sglist,
struct vio_dev *viodev = to_vio_dev(dev);
struct iommu_table *tbl;
struct scatterlist *sgl;
-   int ret, count = 0;
+   int ret, count;
size_t alloc_size = 0;
 
tbl = get_iommu_table_base(dev);
-   for (sgl = sglist; count < nelems; count++, sgl++)
+   for_each_sg(sglist, sgl, nelems, count)
alloc_size += roundup(sgl->length, IOMMU_PAGE_SIZE(tbl));
 
if (vio_cmo_alloc(viodev, alloc_size)) {
@@ -577,7 +577,7 @@ static int vio_dma_iommu_map_sg(struct device *dev, struct 
scatterlist *sglist,
return ret;
}
 
-   for (sgl = sglist, count = 0; count < ret; count++, sgl++)
+   for_each_sg(sglist, sgl, ret, count)
alloc_size -= roundup(sgl->dma_length, IOMMU_PAGE_SIZE(tbl));
if (alloc_size)
vio_cmo_dealloc(viodev, alloc_size);
@@ -594,10 +594,10 @@ static void vio_dma_iommu_unmap_sg(struct device *dev,
struct iommu_table *tbl;
struct scatterlist *sgl;
size_t alloc_size = 0;
-   int count = 0;
+   int count;
 
tbl = get_iommu_table_base(dev);
-   for (sgl = sglist; count < nelems; count++, sgl++)
+   for_each_sg(sglist, sgl, nelems, count)
alloc_size += roundup(sgl->dma_length, IOMMU_PAGE_SIZE(tbl));
 
dma_iommu_ops.unmap_sg(dev, sglist, nelems, direction, attrs);
-- 
1.9.1

___
Linuxppc-dev mailing list
Linuxppc-dev@lists.ozlabs.org
https://lists.ozlabs.org/listinfo/linuxppc-dev

Re: [PATCH 2/2] mm: fix undefined reference to `.kernel_map_pages' on PPC builds

2015-01-22 Thread Akinobu Mita
2015-01-23 5:41 GMT+09:00 Kim Phillips :
> On Thu, 22 Jan 2015 10:45:51 +0900
> Joonsoo Kim  wrote:
>
>> On Wed, Jan 21, 2015 at 09:57:59PM +0900, Akinobu Mita wrote:
>> > 2015-01-21 9:07 GMT+09:00 Andrew Morton :
>> > > On Tue, 20 Jan 2015 15:01:50 -0800 j...@joshtriplett.org wrote:
>> > >
>> > >> On Tue, Jan 20, 2015 at 02:02:00PM -0600, Kim Phillips wrote:
>> > >> > It's possible to configure DEBUG_PAGEALLOC without PAGE_POISONING on
>> > >> > ppc.  Fix building the generic kernel_map_pages() implementation in
>> > >> > this case:
>> > >> >
>> > >> >   LD  init/built-in.o
>> > >> > mm/built-in.o: In function `free_pages_prepare':
>> > >> > mm/page_alloc.c:770: undefined reference to `.kernel_map_pages'
>> > >> > mm/built-in.o: In function `prep_new_page':
>> > >> > mm/page_alloc.c:933: undefined reference to `.kernel_map_pages'
>> > >> > mm/built-in.o: In function `map_pages':
>> > >> > mm/compaction.c:61: undefined reference to `.kernel_map_pages'
>> > >> > make: *** [vmlinux] Error 1
>> >
>> > kernel_map_pages() is static inline function since commit 031bc5743f15
>> > ("mm/debug-pagealloc: make debug-pagealloc boottime configurable").
>> >
>> > But there is old declaration in 'arch/powerpc/include/asm/cacheflush.h'.
>> > Removing it or changing s/kernel_map_pages/__kernel_map_pages/ in this
>> > header file or something can fix this problem?
>> >
>> > The architecture which has ARCH_SUPPORTS_DEBUG_PAGEALLOC
>> > including PPC should not build mm/debug-pagealloc.o
>>
>> Yes, architecture with ARCH_SUPPORTS_DEBUG_PAGEALLOC should not build
>> mm/debug-pagealloc.o. I attach the patch to remove old declaration.
>> I hope it will fix Kim's problem.
>>
>> -->8--
>> From 7cb9d1ed8a785df152cb8934e187031c8ebd1bb2 Mon Sep 17 00:00:00 2001
>> From: Joonsoo Kim 
>> Date: Thu, 22 Jan 2015 10:28:58 +0900
>> Subject: [PATCH] mm/debug_pagealloc: fix build failure on ppc and some other
>>  archs
>>
>> Kim Phillips reported following build failure.
>>
>>   LD  init/built-in.o
>>   mm/built-in.o: In function `free_pages_prepare':
>>   mm/page_alloc.c:770: undefined reference to `.kernel_map_pages'
>>   mm/built-in.o: In function `prep_new_page':
>>   mm/page_alloc.c:933: undefined reference to `.kernel_map_pages'
>>   mm/built-in.o: In function `map_pages':
>>   mm/compaction.c:61: undefined reference to `.kernel_map_pages'
>>   make: *** [vmlinux] Error 1
>>
>> Reason for this problem is that commit 031bc5743f15
>> ("mm/debug-pagealloc: make debug-pagealloc boottime configurable") forgot
>> to remove old declaration of kernel_map_pages() in some architectures.
>> This patch removes them to fix build failure.
>>
>> Reported-by: Kim Phillips 
>> Signed-off-by: Joonsoo Kim 
>> ---
>
> Thanks. Now I get this:
>
>   LD  init/built-in.o
> mm/built-in.o: In function `kernel_map_pages':
> include/linux/mm.h:2076: undefined reference to `.__kernel_map_pages'
> include/linux/mm.h:2076: undefined reference to `.__kernel_map_pages'
> include/linux/mm.h:2076: undefined reference to `.__kernel_map_pages'
> Makefile:925: recipe for target 'vmlinux' failed
> make: *** [vmlinux] Error 1
>
> but, AFAICT, that's not because this patch is invalid: it's because
> __kernel_map_pages() isn't implemented in
> arch/powerpc/mm/pgtable_64.c, i.e., for non-PPC_STD_MMU_64 PPC64
> machines.

Then, in order to use generic __kernel_map_pages() in mm/debug-pagealloc.c,
CONFIG_ARCH_SUPPORTS_DEBUG_PAGEALLOC shouldn't be selected in
arch/powerpc/Kconfig, when CONFIG_PPC_STD_MMU_64 isn't defined.
___
Linuxppc-dev mailing list
Linuxppc-dev@lists.ozlabs.org
https://lists.ozlabs.org/listinfo/linuxppc-dev

Re: [PATCH 2/2] mm: fix undefined reference to `.kernel_map_pages' on PPC builds

2015-01-21 Thread Akinobu Mita
2015-01-21 9:07 GMT+09:00 Andrew Morton :
> On Tue, 20 Jan 2015 15:01:50 -0800 j...@joshtriplett.org wrote:
>
>> On Tue, Jan 20, 2015 at 02:02:00PM -0600, Kim Phillips wrote:
>> > It's possible to configure DEBUG_PAGEALLOC without PAGE_POISONING on
>> > ppc.  Fix building the generic kernel_map_pages() implementation in
>> > this case:
>> >
>> >   LD  init/built-in.o
>> > mm/built-in.o: In function `free_pages_prepare':
>> > mm/page_alloc.c:770: undefined reference to `.kernel_map_pages'
>> > mm/built-in.o: In function `prep_new_page':
>> > mm/page_alloc.c:933: undefined reference to `.kernel_map_pages'
>> > mm/built-in.o: In function `map_pages':
>> > mm/compaction.c:61: undefined reference to `.kernel_map_pages'
>> > make: *** [vmlinux] Error 1

kernel_map_pages() is static inline function since commit 031bc5743f15
("mm/debug-pagealloc: make debug-pagealloc boottime configurable").

But there is old declaration in 'arch/powerpc/include/asm/cacheflush.h'.
Removing it or changing s/kernel_map_pages/__kernel_map_pages/ in this
header file or something can fix this problem?

The architecture which has ARCH_SUPPORTS_DEBUG_PAGEALLOC
including PPC should not build mm/debug-pagealloc.o
___
Linuxppc-dev mailing list
Linuxppc-dev@lists.ozlabs.org
https://lists.ozlabs.org/listinfo/linuxppc-dev

[PATCH] powerpc: remove unused BITOP_LE_SWIZZLE macro

2013-03-02 Thread Akinobu Mita
The BITOP_LE_SWIZZLE macro was used in the little-endian bitops functions
for powerpc.  But these functions were converted to generic bitops and
the BITOP_LE_SWIZZLE is not used anymore.

Signed-off-by: Akinobu Mita 
Cc: Benjamin Herrenschmidt 
Cc: Paul Mackerras 
Cc: linuxppc-dev@lists.ozlabs.org
---
 arch/powerpc/include/asm/bitops.h | 2 --
 1 file changed, 2 deletions(-)

diff --git a/arch/powerpc/include/asm/bitops.h 
b/arch/powerpc/include/asm/bitops.h
index ef918a2..08bd299 100644
--- a/arch/powerpc/include/asm/bitops.h
+++ b/arch/powerpc/include/asm/bitops.h
@@ -52,8 +52,6 @@
 #define smp_mb__before_clear_bit() smp_mb()
 #define smp_mb__after_clear_bit()  smp_mb()
 
-#define BITOP_LE_SWIZZLE   ((BITS_PER_LONG-1) & ~0x7)
-
 /* Macro for generating the ***_bits() functions */
 #define DEFINE_BITOP(fn, op, prefix, postfix)  \
 static __inline__ void fn(unsigned long mask,  \
-- 
1.8.1.2

___
Linuxppc-dev mailing list
Linuxppc-dev@lists.ozlabs.org
https://lists.ozlabs.org/listinfo/linuxppc-dev


Re: [PATCH] powerpc+of: Rename and fix OF reconfig notifier error inject module

2012-12-13 Thread Akinobu Mita
2012/12/13 Benjamin Herrenschmidt :
> This module used to inject errors in the pSeries specific dynamic
> reconfiguration notifiers. Those are gone however, replaced by
> generic notifiers for changes to the device-tree. So let's update
> the module to deal with these instead and rename it along the way.
>
> Signed-off-by: Benjamin Herrenschmidt 

Looks good.

Acked-by: Akinobu Mita 
___
Linuxppc-dev mailing list
Linuxppc-dev@lists.ozlabs.org
https://lists.ozlabs.org/listinfo/linuxppc-dev


[PATCH] powerpc: use asm-generic/bitops/le.h

2012-11-04 Thread Akinobu Mita
The only difference between powerpc and asm-generic le-bitops is
test_bit_le().  Usually all bitops require a long aligned bitmap.
But powerpc test_bit_le() can take an unaligned address.

There is no special callsite of test_bit_le() that needs unaligned
access in powerpc as far as I can see.  So convert to use
asm-generic/bitops/le.h for powerpc.

Signed-off-by: Akinobu Mita 
Cc: Benjamin Herrenschmidt 
Cc: Paul Mackerras 
Cc: linuxppc-dev@lists.ozlabs.org
---
 arch/powerpc/include/asm/bitops.h | 55 +--
 1 file changed, 1 insertion(+), 54 deletions(-)

diff --git a/arch/powerpc/include/asm/bitops.h 
b/arch/powerpc/include/asm/bitops.h
index 920596f..ef918a2 100644
--- a/arch/powerpc/include/asm/bitops.h
+++ b/arch/powerpc/include/asm/bitops.h
@@ -278,61 +278,8 @@ unsigned long __arch_hweight64(__u64 w);
 #include 
 
 /* Little-endian versions */
+#include 
 
-static __inline__ int test_bit_le(unsigned long nr,
- __const__ void *addr)
-{
-   __const__ unsigned char *tmp = (__const__ unsigned char *) addr;
-   return (tmp[nr >> 3] >> (nr & 7)) & 1;
-}
-
-static inline void set_bit_le(int nr, void *addr)
-{
-   set_bit(nr ^ BITOP_LE_SWIZZLE, addr);
-}
-
-static inline void clear_bit_le(int nr, void *addr)
-{
-   clear_bit(nr ^ BITOP_LE_SWIZZLE, addr);
-}
-
-static inline void __set_bit_le(int nr, void *addr)
-{
-   __set_bit(nr ^ BITOP_LE_SWIZZLE, addr);
-}
-
-static inline void __clear_bit_le(int nr, void *addr)
-{
-   __clear_bit(nr ^ BITOP_LE_SWIZZLE, addr);
-}
-
-static inline int test_and_set_bit_le(int nr, void *addr)
-{
-   return test_and_set_bit(nr ^ BITOP_LE_SWIZZLE, addr);
-}
-
-static inline int test_and_clear_bit_le(int nr, void *addr)
-{
-   return test_and_clear_bit(nr ^ BITOP_LE_SWIZZLE, addr);
-}
-
-static inline int __test_and_set_bit_le(int nr, void *addr)
-{
-   return __test_and_set_bit(nr ^ BITOP_LE_SWIZZLE, addr);
-}
-
-static inline int __test_and_clear_bit_le(int nr, void *addr)
-{
-   return __test_and_clear_bit(nr ^ BITOP_LE_SWIZZLE, addr);
-}
-
-#define find_first_zero_bit_le(addr, size) \
-   find_next_zero_bit_le((addr), (size), 0)
-unsigned long find_next_zero_bit_le(const void *addr,
-   unsigned long size, unsigned long offset);
-
-unsigned long find_next_bit_le(const void *addr,
-   unsigned long size, unsigned long offset);
 /* Bitmap functions for the ext2 filesystem */
 
 #include 
-- 
1.7.11.7

___
Linuxppc-dev mailing list
Linuxppc-dev@lists.ozlabs.org
https://lists.ozlabs.org/listinfo/linuxppc-dev


[PATCH] powerpc: remove BITOP_MASK and BITOP_WORD from asm/bitops.h

2012-11-04 Thread Akinobu Mita
Replace BITOP_MASK and BITOP_WORD with BIT_MASK and BIT_WORD defined
in linux/bitops.h and remove BITOP_* which are not used anymore.

Signed-off-by: Akinobu Mita 
Cc: Benjamin Herrenschmidt 
Cc: Paul Mackerras 
Cc: linuxppc-dev@lists.ozlabs.org
---
 arch/powerpc/include/asm/bitops.h | 20 +---
 1 file changed, 9 insertions(+), 11 deletions(-)

diff --git a/arch/powerpc/include/asm/bitops.h 
b/arch/powerpc/include/asm/bitops.h
index dc2cf9c..920596f 100644
--- a/arch/powerpc/include/asm/bitops.h
+++ b/arch/powerpc/include/asm/bitops.h
@@ -52,8 +52,6 @@
 #define smp_mb__before_clear_bit() smp_mb()
 #define smp_mb__after_clear_bit()  smp_mb()
 
-#define BITOP_MASK(nr) (1UL << ((nr) % BITS_PER_LONG))
-#define BITOP_WORD(nr) ((nr) / BITS_PER_LONG)
 #define BITOP_LE_SWIZZLE   ((BITS_PER_LONG-1) & ~0x7)
 
 /* Macro for generating the ***_bits() functions */
@@ -83,22 +81,22 @@ DEFINE_BITOP(change_bits, xor, "", "")
 
 static __inline__ void set_bit(int nr, volatile unsigned long *addr)
 {
-   set_bits(BITOP_MASK(nr), addr + BITOP_WORD(nr));
+   set_bits(BIT_MASK(nr), addr + BIT_WORD(nr));
 }
 
 static __inline__ void clear_bit(int nr, volatile unsigned long *addr)
 {
-   clear_bits(BITOP_MASK(nr), addr + BITOP_WORD(nr));
+   clear_bits(BIT_MASK(nr), addr + BIT_WORD(nr));
 }
 
 static __inline__ void clear_bit_unlock(int nr, volatile unsigned long *addr)
 {
-   clear_bits_unlock(BITOP_MASK(nr), addr + BITOP_WORD(nr));
+   clear_bits_unlock(BIT_MASK(nr), addr + BIT_WORD(nr));
 }
 
 static __inline__ void change_bit(int nr, volatile unsigned long *addr)
 {
-   change_bits(BITOP_MASK(nr), addr + BITOP_WORD(nr));
+   change_bits(BIT_MASK(nr), addr + BIT_WORD(nr));
 }
 
 /* Like DEFINE_BITOP(), with changes to the arguments to 'op' and the output
@@ -136,26 +134,26 @@ DEFINE_TESTOP(test_and_change_bits, xor, 
PPC_ATOMIC_ENTRY_BARRIER,
 static __inline__ int test_and_set_bit(unsigned long nr,
   volatile unsigned long *addr)
 {
-   return test_and_set_bits(BITOP_MASK(nr), addr + BITOP_WORD(nr)) != 0;
+   return test_and_set_bits(BIT_MASK(nr), addr + BIT_WORD(nr)) != 0;
 }
 
 static __inline__ int test_and_set_bit_lock(unsigned long nr,
   volatile unsigned long *addr)
 {
-   return test_and_set_bits_lock(BITOP_MASK(nr),
-   addr + BITOP_WORD(nr)) != 0;
+   return test_and_set_bits_lock(BIT_MASK(nr),
+   addr + BIT_WORD(nr)) != 0;
 }
 
 static __inline__ int test_and_clear_bit(unsigned long nr,
 volatile unsigned long *addr)
 {
-   return test_and_clear_bits(BITOP_MASK(nr), addr + BITOP_WORD(nr)) != 0;
+   return test_and_clear_bits(BIT_MASK(nr), addr + BIT_WORD(nr)) != 0;
 }
 
 static __inline__ int test_and_change_bit(unsigned long nr,
  volatile unsigned long *addr)
 {
-   return test_and_change_bits(BITOP_MASK(nr), addr + BITOP_WORD(nr)) != 0;
+   return test_and_change_bits(BIT_MASK(nr), addr + BIT_WORD(nr)) != 0;
 }
 
 #include 
-- 
1.7.11.7

___
Linuxppc-dev mailing list
Linuxppc-dev@lists.ozlabs.org
https://lists.ozlabs.org/listinfo/linuxppc-dev


[PATCH] powerpc: iommu: use bitmap library

2012-11-04 Thread Akinobu Mita
 - Caluculate the bitmap size with BITS_TO_LONGS()
 - Use bitmap_empty() to verify that all bits are cleared

This also includes a printk to pr_warn() conversion.

Signed-off-by: Akinobu Mita 
Cc: Benjamin Herrenschmidt 
Cc: Paul Mackerras 
Cc: linuxppc-dev@lists.ozlabs.org
---
 arch/powerpc/kernel/iommu.c | 16 +---
 1 file changed, 5 insertions(+), 11 deletions(-)

diff --git a/arch/powerpc/kernel/iommu.c b/arch/powerpc/kernel/iommu.c
index 8226c6c..c862fd7 100644
--- a/arch/powerpc/kernel/iommu.c
+++ b/arch/powerpc/kernel/iommu.c
@@ -656,7 +656,7 @@ struct iommu_table *iommu_init_table(struct iommu_table 
*tbl, int nid)
struct iommu_pool *p;
 
/* number of bytes needed for the bitmap */
-   sz = (tbl->it_size + 7) >> 3;
+   sz = BITS_TO_LONGS(tbl->it_size) * sizeof(unsigned long);
 
page = alloc_pages_node(nid, GFP_ATOMIC, get_order(sz));
if (!page)
@@ -708,7 +708,7 @@ struct iommu_table *iommu_init_table(struct iommu_table 
*tbl, int nid)
 
 void iommu_free_table(struct iommu_table *tbl, const char *node_name)
 {
-   unsigned long bitmap_sz, i;
+   unsigned long bitmap_sz;
unsigned int order;
 
if (!tbl || !tbl->it_map) {
@@ -718,17 +718,11 @@ void iommu_free_table(struct iommu_table *tbl, const char 
*node_name)
}
 
/* verify that table contains no entries */
-   /* it_size is in entries, and we're examining 64 at a time */
-   for (i = 0; i < (tbl->it_size/64); i++) {
-   if (tbl->it_map[i] != 0) {
-   printk(KERN_WARNING "%s: Unexpected TCEs for %s\n",
-   __func__, node_name);
-   break;
-   }
-   }
+   if (!bitmap_empty(tbl->it_map, tbl->it_size))
+   pr_warn("%s: Unexpected TCEs for %s\n", __func__, node_name);
 
/* calculate bitmap size in bytes */
-   bitmap_sz = (tbl->it_size + 7) / 8;
+   bitmap_sz = BITS_TO_LONGS(tbl->it_size) * sizeof(unsigned long);
 
/* free bitmap */
order = get_order(bitmap_sz);
-- 
1.7.11.7

___
Linuxppc-dev mailing list
Linuxppc-dev@lists.ozlabs.org
https://lists.ozlabs.org/listinfo/linuxppc-dev


Re: [PATCH -v5 0/6] notifier error injection

2012-07-04 Thread Akinobu Mita
2012/7/4 Andrew Morton :
> On Sat, 30 Jun 2012 14:59:24 +0900
> Akinobu Mita  wrote:
>
>> This provides kernel modules that can be used to test the error handling
>> of notifier call chain failures by injecting artifical errors to the
>> following notifier chain callbacks.
>
> No updates to Documentation/fault-injection/?

Thanks for the remainder.
I'll prepare to add a document to it.
___
Linuxppc-dev mailing list
Linuxppc-dev@lists.ozlabs.org
https://lists.ozlabs.org/listinfo/linuxppc-dev


[PATCH -v5 1/6] fault-injection: notifier error injection

2012-06-30 Thread Akinobu Mita
The notifier error injection provides the ability to inject artifical
errors to specified notifier chain callbacks.  It is useful to test the
error handling of notifier call chain failures.

This adds common basic functions to define which type of events can be
fail and to initialize the debugfs interface to control what error code
should be returned and which event should be failed.

Signed-off-by: Akinobu Mita 
Cc: Pavel Machek 
Cc: "Rafael J. Wysocki" 
Cc: linux...@lists.linux-foundation.org
Cc: Greg KH 
Cc: linux...@kvack.org
Cc: Benjamin Herrenschmidt 
Cc: Paul Mackerras 
Cc: linuxppc-dev@lists.ozlabs.org
Cc: Michael Ellerman 
---
No changes since v4

 lib/Kconfig.debug   |   11 +
 lib/Makefile|1 +
 lib/notifier-error-inject.c |  112 +++
 lib/notifier-error-inject.h |   24 ++
 4 files changed, 148 insertions(+)
 create mode 100644 lib/notifier-error-inject.c
 create mode 100644 lib/notifier-error-inject.h

diff --git a/lib/Kconfig.debug b/lib/Kconfig.debug
index ff5bdee..c848758 100644
--- a/lib/Kconfig.debug
+++ b/lib/Kconfig.debug
@@ -1084,6 +1084,17 @@ config LKDTM
Documentation on how to use the module can be found in
Documentation/fault-injection/provoke-crashes.txt
 
+config NOTIFIER_ERROR_INJECTION
+   tristate "Notifier error injection"
+   depends on DEBUG_KERNEL
+   select DEBUG_FS
+   help
+ This option provides the ability to inject artifical errors to
+ specified notifier chain callbacks. It is useful to test the error
+ handling of notifier call chain failures.
+
+ Say N if unsure.
+
 config CPU_NOTIFIER_ERROR_INJECT
tristate "CPU notifier error injection module"
depends on HOTPLUG_CPU && DEBUG_KERNEL
diff --git a/lib/Makefile b/lib/Makefile
index 8c31a0c..23fba9e 100644
--- a/lib/Makefile
+++ b/lib/Makefile
@@ -90,6 +90,7 @@ obj-$(CONFIG_AUDIT_GENERIC) += audit.o
 obj-$(CONFIG_SWIOTLB) += swiotlb.o
 obj-$(CONFIG_IOMMU_HELPER) += iommu-helper.o
 obj-$(CONFIG_FAULT_INJECTION) += fault-inject.o
+obj-$(CONFIG_NOTIFIER_ERROR_INJECTION) += notifier-error-inject.o
 obj-$(CONFIG_CPU_NOTIFIER_ERROR_INJECT) += cpu-notifier-error-inject.o
 
 lib-$(CONFIG_GENERIC_BUG) += bug.o
diff --git a/lib/notifier-error-inject.c b/lib/notifier-error-inject.c
new file mode 100644
index 000..44b92cb
--- /dev/null
+++ b/lib/notifier-error-inject.c
@@ -0,0 +1,112 @@
+#include 
+
+#include "notifier-error-inject.h"
+
+static int debugfs_errno_set(void *data, u64 val)
+{
+   *(int *)data = clamp_t(int, val, -MAX_ERRNO, 0);
+   return 0;
+}
+
+static int debugfs_errno_get(void *data, u64 *val)
+{
+   *val = *(int *)data;
+   return 0;
+}
+
+DEFINE_SIMPLE_ATTRIBUTE(fops_errno, debugfs_errno_get, debugfs_errno_set,
+   "%lld\n");
+
+static struct dentry *debugfs_create_errno(const char *name, mode_t mode,
+   struct dentry *parent, int *value)
+{
+   return debugfs_create_file(name, mode, parent, value, &fops_errno);
+}
+
+static int notifier_err_inject_callback(struct notifier_block *nb,
+   unsigned long val, void *p)
+{
+   int err = 0;
+   struct notifier_err_inject *err_inject =
+   container_of(nb, struct notifier_err_inject, nb);
+   struct notifier_err_inject_action *action;
+
+   for (action = err_inject->actions; action->name; action++) {
+   if (action->val == val) {
+   err = action->error;
+   break;
+   }
+   }
+   if (err)
+   pr_info("Injecting error (%d) to %s\n", err, action->name);
+
+   return notifier_from_errno(err);
+}
+
+struct dentry *notifier_err_inject_dir;
+EXPORT_SYMBOL_GPL(notifier_err_inject_dir);
+
+struct dentry *notifier_err_inject_init(const char *name, struct dentry 
*parent,
+   struct notifier_err_inject *err_inject, int priority)
+{
+   struct notifier_err_inject_action *action;
+   mode_t mode = S_IFREG | S_IRUSR | S_IWUSR;
+   struct dentry *dir;
+   struct dentry *actions_dir;
+
+   err_inject->nb.notifier_call = notifier_err_inject_callback;
+   err_inject->nb.priority = priority;
+
+   dir = debugfs_create_dir(name, parent);
+   if (!dir)
+   return ERR_PTR(-ENOMEM);
+
+   actions_dir = debugfs_create_dir("actions", dir);
+   if (!actions_dir)
+   goto fail;
+
+   for (action = err_inject->actions; action->name; action++) {
+   struct dentry *action_dir;
+
+   action_dir = debugfs_create_dir(action->name, actions_dir);
+   if (!action_dir)
+   goto fail;
+
+   /*
+* Create debugfs r/w file containing action->error. If
+  

[PATCH -v5 0/6] notifier error injection

2012-06-30 Thread Akinobu Mita
This provides kernel modules that can be used to test the error handling
of notifier call chain failures by injecting artifical errors to the
following notifier chain callbacks.

 * CPU notifier
 * PM notifier
 * memory hotplug notifier
 * powerpc pSeries reconfig notifier

Example: Inject CPU offline error (-1 == -EPERM)

# cd /sys/kernel/debug/notifier-error-inject/cpu
# echo -1 > actions/CPU_DOWN_PREPARE/error
# echo 0 > /sys/devices/system/cpu/cpu1/online
bash: echo: write error: Operation not permitted

This also adds cpu and memory hotplug tests to tools/testing/selftests 
These tests first do simple online and offline test and then do fault
injection tests if notifier error injection module is available.

Changelog:

* v5 (change only testing scripts)
- make testing scripts a part of tools/testing/selftests
- do simple on/offline tests even if no notifier error injection support

* v4 (It is about 11 months since v3)
- prefix all APIs with notifier_err_inject_*
- rearrange debugfs interface
  (e.g. $DEBUGFS/cpu-notifier-error-inject/CPU_DOWN_PREPARE -->
$DEBUGFS/notifier-error-inject/cpu/actions/CPU_DOWN_PREPARE/error)
- update modules to follow new interface
- add -r option for memory-notifier.sh to specify percent of offlining
  memory blocks

* v3
- rewrite to be kernel modules instead of initializing at late_initcall()s
  (it makes the diffstat look different but most code remains unchanged)
- export err_inject_notifier_block_{init,cleanup} for modules
- export pSeries_reconfig_notifier_{,un}register symbols for a module
- notifier priority can be specified as a module parameter
- add testing scripts in tools/testing/fault-injection

* v2
- "PM: Improve error code of pm_notifier_call_chain()" is now in -next
- "debugfs: add debugfs_create_int" is dropped
- put a comment in err_inject_notifier_block_init()
- only allow valid errno to be injected (-MAX_ERRNO <= errno <= 0)
- improve Kconfig help text
- make CONFIG_PM_NOTIFIER_ERROR_INJECTION visible even if PM_DEBUG is disabled
- make CONFIG_PM_NOTIFIER_ERROR_INJECTION default if PM_DEBUG is enabled

Akinobu Mita (6):
  fault-injection: notifier error injection
  cpu: rewrite cpu-notifier-error-inject module
  PM: PM notifier error injection module
  memory: memory notifier error injection module
  powerpc: pSeries reconfig notifier error injection module
  fault-injection: add selftests for cpu and memory hotplug

 lib/Kconfig.debug  |   91 +++-
 lib/Makefile   |5 +
 lib/cpu-notifier-error-inject.c|   63 +++---
 lib/memory-notifier-error-inject.c |   48 
 lib/notifier-error-inject.c|  112 ++
 lib/notifier-error-inject.h|   24 ++
 lib/pSeries-reconfig-notifier-error-inject.c   |   51 +
 lib/pm-notifier-error-inject.c |   49 +
 tools/testing/selftests/Makefile   |2 +-
 tools/testing/selftests/cpu-hotplug/Makefile   |6 +
 tools/testing/selftests/cpu-hotplug/on-off-test.sh |  221 +++
 tools/testing/selftests/memory-hotplug/Makefile|6 +
 .../selftests/memory-hotplug/on-off-test.sh|  230 
 13 files changed, 867 insertions(+), 41 deletions(-)
 create mode 100644 lib/memory-notifier-error-inject.c
 create mode 100644 lib/notifier-error-inject.c
 create mode 100644 lib/notifier-error-inject.h
 create mode 100644 lib/pSeries-reconfig-notifier-error-inject.c
 create mode 100644 lib/pm-notifier-error-inject.c
 create mode 100644 tools/testing/selftests/cpu-hotplug/Makefile
 create mode 100755 tools/testing/selftests/cpu-hotplug/on-off-test.sh
 create mode 100644 tools/testing/selftests/memory-hotplug/Makefile
 create mode 100755 tools/testing/selftests/memory-hotplug/on-off-test.sh

Cc: Pavel Machek 
Cc: "Rafael J. Wysocki" 
Cc: linux...@lists.linux-foundation.org
Cc: Greg KH 
Cc: linux...@kvack.org
Cc: Benjamin Herrenschmidt 
Cc: Paul Mackerras 
Cc: linuxppc-dev@lists.ozlabs.org
Cc: Américo Wang 
Cc: Michael Ellerman 
Cc: Dave Jones 
-- 
1.7.10.4

___
Linuxppc-dev mailing list
Linuxppc-dev@lists.ozlabs.org
https://lists.ozlabs.org/listinfo/linuxppc-dev

[PATCH -v5 6/6] fault-injection: add selftests for cpu and memory hotplug

2012-06-30 Thread Akinobu Mita
This adds two selftests

* tools/testing/selftests/cpu-hotplug/on-off-test.sh is testing script
for CPU hotplug

1. Online all hot-pluggable CPUs
2. Offline all hot-pluggable CPUs
3. Online all hot-pluggable CPUs again
4. Exit if cpu-notifier-error-inject.ko is not available
5. Offline all hot-pluggable CPUs in preparation for testing
6. Test CPU hot-add error handling by injecting notifier errors
7. Online all hot-pluggable CPUs in preparation for testing
8. Test CPU hot-remove error handling by injecting notifier errors

* tools/testing/selftests/memory-hotplug/on-off-test.sh is doing the
similar thing for memory hotplug.

1. Online all hot-pluggable memory
2. Offline 10% of hot-pluggable memory
3. Online all hot-pluggable memory again
4. Exit if memory-notifier-error-inject.ko is not available
5. Offline 10% of hot-pluggable memory in preparation for testing
6. Test memory hot-add error handling by injecting notifier errors
7. Online all hot-pluggable memory in preparation for testing
8. Test memory hot-remove error handling by injecting notifier errors

Signed-off-by: Akinobu Mita 
Suggested-by: Andrew Morton 
Cc: Pavel Machek 
Cc: "Rafael J. Wysocki" 
Cc: linux...@lists.linux-foundation.org
Cc: Greg KH 
Cc: linux...@kvack.org
Cc: Benjamin Herrenschmidt 
Cc: Paul Mackerras 
Cc: linuxppc-dev@lists.ozlabs.org
Cc: Américo Wang 
Cc: Dave Jones 
---
* v5
- make testing scripts a part of tools/testing/selftests
- do simple on/offline tests even if no notifier error injection support

 tools/testing/selftests/Makefile   |2 +-
 tools/testing/selftests/cpu-hotplug/Makefile   |6 +
 tools/testing/selftests/cpu-hotplug/on-off-test.sh |  221 +++
 tools/testing/selftests/memory-hotplug/Makefile|6 +
 .../selftests/memory-hotplug/on-off-test.sh|  230 
 5 files changed, 464 insertions(+), 1 deletion(-)
 create mode 100644 tools/testing/selftests/cpu-hotplug/Makefile
 create mode 100755 tools/testing/selftests/cpu-hotplug/on-off-test.sh
 create mode 100644 tools/testing/selftests/memory-hotplug/Makefile
 create mode 100755 tools/testing/selftests/memory-hotplug/on-off-test.sh

diff --git a/tools/testing/selftests/Makefile b/tools/testing/selftests/Makefile
index a4162e1..85baf11 100644
--- a/tools/testing/selftests/Makefile
+++ b/tools/testing/selftests/Makefile
@@ -1,4 +1,4 @@
-TARGETS = breakpoints kcmp mqueue vm
+TARGETS = breakpoints kcmp mqueue vm cpu-hotplug memory-hotplug
 
 all:
for TARGET in $(TARGETS); do \
diff --git a/tools/testing/selftests/cpu-hotplug/Makefile 
b/tools/testing/selftests/cpu-hotplug/Makefile
new file mode 100644
index 000..7c9c20f
--- /dev/null
+++ b/tools/testing/selftests/cpu-hotplug/Makefile
@@ -0,0 +1,6 @@
+all:
+
+run_tests:
+   ./on-off-test.sh
+
+clean:
diff --git a/tools/testing/selftests/cpu-hotplug/on-off-test.sh 
b/tools/testing/selftests/cpu-hotplug/on-off-test.sh
new file mode 100755
index 000..bdde7cf
--- /dev/null
+++ b/tools/testing/selftests/cpu-hotplug/on-off-test.sh
@@ -0,0 +1,221 @@
+#!/bin/bash
+
+SYSFS=
+
+prerequisite()
+{
+   msg="skip all tests:"
+
+   if [ $UID != 0 ]; then
+   echo $msg must be run as root >&2
+   exit 0
+   fi
+
+   SYSFS=`mount -t sysfs | head -1 | awk '{ print $3 }'`
+
+   if [ ! -d "$SYSFS" ]; then
+   echo $msg sysfs is not mounted >&2
+   exit 0
+   fi
+
+   if ! ls $SYSFS/devices/system/cpu/cpu* > /dev/null 2>&1; then
+   echo $msg cpu hotplug is not supported >&2
+   exit 0
+   fi
+}
+
+#
+# list all hot-pluggable CPUs
+#
+hotpluggable_cpus()
+{
+   local state=${1:-.\*}
+
+   for cpu in $SYSFS/devices/system/cpu/cpu*; do
+   if [ -f $cpu/online ] && grep -q $state $cpu/online; then
+   echo ${cpu##/*/cpu}
+   fi
+   done
+}
+
+hotplaggable_offline_cpus()
+{
+   hotpluggable_cpus 0
+}
+
+hotpluggable_online_cpus()
+{
+   hotpluggable_cpus 1
+}
+
+cpu_is_online()
+{
+   grep -q 1 $SYSFS/devices/system/cpu/cpu$1/online
+}
+
+cpu_is_offline()
+{
+   grep -q 0 $SYSFS/devices/system/cpu/cpu$1/online
+}
+
+online_cpu()
+{
+   echo 1 > $SYSFS/devices/system/cpu/cpu$1/online
+}
+
+offline_cpu()
+{
+   echo 0 > $SYSFS/devices/system/cpu/cpu$1/online
+}
+
+online_cpu_expect_success()
+{
+   local cpu=$1
+
+   if ! online_cpu $cpu; then
+   echo $FUNCNAME $cpu: unexpected fail >&2
+   elif ! cpu_is_online $cpu; then
+   echo $FUNCNAME $cpu: unexpected offline >&2
+   fi
+}
+
+online_cpu_expect_fail()
+{
+   local cpu=$1
+
+   if online_cpu $cpu 2> /dev/null; then
+   echo $FUNCNAME $cpu: unexpected success >&2
+   elif ! cpu_is_offline $cpu; then
+   echo $FUNCNAME $cpu: unexpected onl

[PATCH -v5 5/6] powerpc: pSeries reconfig notifier error injection module

2012-06-30 Thread Akinobu Mita
This provides the ability to inject artifical errors to pSeries reconfig
notifier chain callbacks.  It is controlled through debugfs interface
under /sys/kernel/debug/notifier-error-inject/pSeries-reconfig

If the notifier call chain should be failed with some events
notified, write the error code to "actions//error".

Signed-off-by: Akinobu Mita 
Cc: Benjamin Herrenschmidt 
Cc: Paul Mackerras 
Cc: linuxppc-dev@lists.ozlabs.org
---
No changes since v4

 lib/Kconfig.debug|   17 +
 lib/Makefile |2 +
 lib/pSeries-reconfig-notifier-error-inject.c |   51 ++
 3 files changed, 70 insertions(+)
 create mode 100644 lib/pSeries-reconfig-notifier-error-inject.c

diff --git a/lib/Kconfig.debug b/lib/Kconfig.debug
index 7cceddc..8f8e226 100644
--- a/lib/Kconfig.debug
+++ b/lib/Kconfig.debug
@@ -1166,6 +1166,23 @@ config MEMORY_NOTIFIER_ERROR_INJECT
 
  If unsure, say N.
 
+config PSERIES_RECONFIG_NOTIFIER_ERROR_INJECT
+   tristate "pSeries reconfig notifier error injection module"
+   depends on PPC_PSERIES && NOTIFIER_ERROR_INJECTION
+   help
+ This option provides the ability to inject artifical errors to
+ pSeries reconfig notifier chain callbacks.  It is controlled
+ through debugfs interface under
+ /sys/kernel/debug/notifier-error-inject/pSeries-reconfig/
+
+ If the notifier call chain should be failed with some events
+ notified, write the error code to "actions//error".
+
+ To compile this code as a module, choose M here: the module will
+ be called memory-notifier-error-inject.
+
+ If unsure, say N.
+
 config FAULT_INJECTION
bool "Fault-injection framework"
depends on DEBUG_KERNEL
diff --git a/lib/Makefile b/lib/Makefile
index a867aa5..d055cb1 100644
--- a/lib/Makefile
+++ b/lib/Makefile
@@ -94,6 +94,8 @@ obj-$(CONFIG_NOTIFIER_ERROR_INJECTION) += 
notifier-error-inject.o
 obj-$(CONFIG_CPU_NOTIFIER_ERROR_INJECT) += cpu-notifier-error-inject.o
 obj-$(CONFIG_PM_NOTIFIER_ERROR_INJECT) += pm-notifier-error-inject.o
 obj-$(CONFIG_MEMORY_NOTIFIER_ERROR_INJECT) += memory-notifier-error-inject.o
+obj-$(CONFIG_PSERIES_RECONFIG_NOTIFIER_ERROR_INJECT) += \
+   pSeries-reconfig-notifier-error-inject.o
 
 lib-$(CONFIG_GENERIC_BUG) += bug.o
 
diff --git a/lib/pSeries-reconfig-notifier-error-inject.c 
b/lib/pSeries-reconfig-notifier-error-inject.c
new file mode 100644
index 000..7f7c98d
--- /dev/null
+++ b/lib/pSeries-reconfig-notifier-error-inject.c
@@ -0,0 +1,51 @@
+#include 
+#include 
+
+#include 
+
+#include "notifier-error-inject.h"
+
+static int priority;
+module_param(priority, int, 0);
+MODULE_PARM_DESC(priority, "specify pSeries reconfig notifier priority");
+
+static struct notifier_err_inject reconfig_err_inject = {
+   .actions = {
+   { NOTIFIER_ERR_INJECT_ACTION(PSERIES_RECONFIG_ADD) },
+   { NOTIFIER_ERR_INJECT_ACTION(PSERIES_RECONFIG_REMOVE) },
+   { NOTIFIER_ERR_INJECT_ACTION(PSERIES_DRCONF_MEM_ADD) },
+   { NOTIFIER_ERR_INJECT_ACTION(PSERIES_DRCONF_MEM_REMOVE) },
+   {}
+   }
+};
+
+static struct dentry *dir;
+
+static int err_inject_init(void)
+{
+   int err;
+
+   dir = notifier_err_inject_init("pSeries-reconfig",
+   notifier_err_inject_dir, &reconfig_err_inject, priority);
+   if (IS_ERR(dir))
+   return PTR_ERR(dir);
+
+   err = pSeries_reconfig_notifier_register(&reconfig_err_inject.nb);
+   if (err)
+   debugfs_remove_recursive(dir);
+
+   return err;
+}
+
+static void err_inject_exit(void)
+{
+   pSeries_reconfig_notifier_unregister(&reconfig_err_inject.nb);
+   debugfs_remove_recursive(dir);
+}
+
+module_init(err_inject_init);
+module_exit(err_inject_exit);
+
+MODULE_DESCRIPTION("pSeries reconfig notifier error injection module");
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("Akinobu Mita ");
-- 
1.7.10.4

___
Linuxppc-dev mailing list
Linuxppc-dev@lists.ozlabs.org
https://lists.ozlabs.org/listinfo/linuxppc-dev


Re: [PATCH -v4 6/6] fault-injection: add notifier error injection testing scripts

2012-06-27 Thread Akinobu Mita
2012/6/27 Andrew Morton :
> On Sat, 23 Jun 2012 23:58:22 +0900
> Akinobu Mita  wrote:
>
>> This adds two testing scripts with notifier error injection
>
> Can we move these into tools/testing/selftests/, so that a "make
> run_tests" runs these tests?
>
> Also, I don't think it's appropriate that "fault-injection" be in the
> path - that's an implementation detail.  What we're testing here is
> memory hotplug, pm, cpu hotplug, etc.  So each test would go into, say,
> tools/testing/selftests/cpu-hotplug.
>
> Now, your cpu-hotplug test only tests a tiny part of the cpu-hotplug
> code.  But it is a start, and creates the place where additional tests
> will be placed in the future.
>
>
> If the kernel configuration means that the tests cannot be run, the
> attempt should succeed so that other tests are not disrupted.  I guess
> that printing a warning in this case is useful.
>
> Probably the selftests will require root permissions - we haven't
> really thought about that much.  If these tests require root (I assume
> they do?) then a sensible approach would be to check for that and to
> emit a warning and return "success".

Thanks for your advice.

I'm going to make the following changes on these scripts

1. Change these paths to:
tools/testing/selftests/{cpu,memory}-hotplug/on-off-test.sh

2. Skip tests and exit(0) with a warning if no root or no sysfs
so that a "make run_tests" doesn't stop.

3. Add tests that simply online and offline cpus (or memory blocks)
and then tests with this notifier error injection features if the
kernel supports.

> My overall take on the fault-injection code is that there has been a
> disappointing amount of uptake: I don't see many developers using them
> for whitebox testing their stuff.  I guess this patchset addresses
> that, in a way.

I hope so. the impact of notifier error injection is restricted to
the particular kernel functionarity and these scripts are easy to run.

On the other hand, fault injection like failslab has a huge impact
on any kernel components and it often results catastrophe to userspace
even if no kernel bug.  I am confident that I can find a certain amount
of kernel bugs with failslab but it requires enough spare time.
___
Linuxppc-dev mailing list
Linuxppc-dev@lists.ozlabs.org
https://lists.ozlabs.org/listinfo/linuxppc-dev


[PATCH -v4 6/6] fault-injection: add notifier error injection testing scripts

2012-06-23 Thread Akinobu Mita
This adds two testing scripts with notifier error injection

* tools/testing/fault-injection/cpu-notifier.sh is testing script for
CPU notifier error handling by using cpu-notifier-error-inject.ko.

1. Offline all hot-pluggable CPUs in preparation for testing
2. Test CPU hot-add error handling by injecting notifier errors
3. Online all hot-pluggable CPUs in preparation for testing
4. Test CPU hot-remove error handling by injecting notifier errors

* tools/testing/fault-injection/memory-notifier.sh is doing the similar
thing for memory hotplug notifier.

1. Offline 10% of hot-pluggable memory in preparation for testing
2. Test memory hot-add error handling by injecting notifier errors
3. Online all hot-pluggable memory in preparation for testing
4. Test memory hot-remove error handling by injecting notifier errors

Signed-off-by: Akinobu Mita 
Suggested-by: Andrew Morton 
Cc: Pavel Machek 
Cc: "Rafael J. Wysocki" 
Cc: linux...@lists.linux-foundation.org
Cc: Greg KH 
Cc: linux...@kvack.org
Cc: Benjamin Herrenschmidt 
Cc: Paul Mackerras 
Cc: linuxppc-dev@lists.ozlabs.org
Cc: Américo Wang 
---
* v4
- add -r option for memory-notifier.sh to specify percent of offlining
  memory blocks

 tools/testing/fault-injection/cpu-notifier.sh|  169 +
 tools/testing/fault-injection/memory-notifier.sh |  176 ++
 2 files changed, 345 insertions(+)
 create mode 100755 tools/testing/fault-injection/cpu-notifier.sh
 create mode 100755 tools/testing/fault-injection/memory-notifier.sh

diff --git a/tools/testing/fault-injection/cpu-notifier.sh 
b/tools/testing/fault-injection/cpu-notifier.sh
new file mode 100755
index 000..af93630
--- /dev/null
+++ b/tools/testing/fault-injection/cpu-notifier.sh
@@ -0,0 +1,169 @@
+#!/bin/bash
+
+#
+# list all hot-pluggable CPUs
+#
+hotpluggable_cpus()
+{
+   local state=${1:-.\*}
+
+   for cpu in /sys/devices/system/cpu/cpu*; do
+   if [ -f $cpu/online ] && grep -q $state $cpu/online; then
+   echo ${cpu##/*/cpu}
+   fi
+   done
+}
+
+hotplaggable_offline_cpus()
+{
+   hotpluggable_cpus 0
+}
+
+hotpluggable_online_cpus()
+{
+   hotpluggable_cpus 1
+}
+
+cpu_is_online()
+{
+   grep -q 1 /sys/devices/system/cpu/cpu$1/online
+}
+
+cpu_is_offline()
+{
+   grep -q 0 /sys/devices/system/cpu/cpu$1/online
+}
+
+add_cpu()
+{
+   echo 1 > /sys/devices/system/cpu/cpu$1/online
+}
+
+remove_cpu()
+{
+   echo 0 > /sys/devices/system/cpu/cpu$1/online
+}
+
+add_cpu_expect_success()
+{
+   local cpu=$1
+
+   if ! add_cpu $cpu; then
+   echo $FUNCNAME $cpu: unexpected fail >&2
+   elif ! cpu_is_online $cpu; then
+   echo $FUNCNAME $cpu: unexpected offline >&2
+   fi
+}
+
+add_cpu_expect_fail()
+{
+   local cpu=$1
+
+   if add_cpu $cpu 2> /dev/null; then
+   echo $FUNCNAME $cpu: unexpected success >&2
+   elif ! cpu_is_offline $cpu; then
+   echo $FUNCNAME $cpu: unexpected online >&2
+   fi
+}
+
+remove_cpu_expect_success()
+{
+   local cpu=$1
+
+   if ! remove_cpu $cpu; then
+   echo $FUNCNAME $cpu: unexpected fail >&2
+   elif ! cpu_is_offline $cpu; then
+   echo $FUNCNAME $cpu: unexpected offline >&2
+   fi
+}
+
+remove_cpu_expect_fail()
+{
+   local cpu=$1
+
+   if remove_cpu $cpu 2> /dev/null; then
+   echo $FUNCNAME $cpu: unexpected success >&2
+   elif ! cpu_is_online $cpu; then
+   echo $FUNCNAME $cpu: unexpected offline >&2
+   fi
+}
+
+if [ $UID != 0 ]; then
+   echo must be run as root >&2
+   exit 1
+fi
+
+error=-12
+priority=0
+
+while getopts e:hp: opt; do
+   case $opt in
+   e)
+   error=$OPTARG
+   ;;
+   h)
+   echo "Usage $0 [ -e errno ] [ -p notifier-priority ]"
+   exit
+   ;;
+   p)
+   priority=$OPTARG
+   ;;
+   esac
+done
+
+if ! [ "$error" -ge -4095 -a "$error" -lt 0 ]; then
+   echo "error code must be -4095 <= errno < 0" >&2
+   exit 1
+fi
+
+DEBUGFS=`mount -t debugfs | head -1 | awk '{ print $3 }'`
+
+if [ ! -d "$DEBUGFS" ]; then
+   echo debugfs is not mounted >&2
+   exit 1
+fi
+
+/sbin/modprobe -r cpu-notifier-error-inject
+/sbin/modprobe -q cpu-notifier-error-inject priority=$priority
+
+NOTIFIER_ERR_INJECT_DIR=$DEBUGFS/notifier-error-inject/cpu
+
+if [ ! -d $NOTIFIER_ERR_INJECT_DIR ]; then
+   echo cpu-notifier-error-inject module is not available >&2
+   exit 1
+fi
+
+#
+# Offline all hot-pluggable CPUs
+#
+echo 0 > $NOTIFIER_ERR_INJECT_DIR/actions/CPU_DOWN_PREPARE/error
+for cpu in `hotpluggable_online_cpus`; do
+   remove_cpu_expect_success $cpu
+done
+
+#
+# Test CPU hot-add 

[PATCH -v4 5/6] powerpc: pSeries reconfig notifier error injection module

2012-06-23 Thread Akinobu Mita
This provides the ability to inject artifical errors to pSeries reconfig
notifier chain callbacks.  It is controlled through debugfs interface
under /sys/kernel/debug/notifier-error-inject/pSeries-reconfig

If the notifier call chain should be failed with some events
notified, write the error code to "actions//error".

Signed-off-by: Akinobu Mita 
Cc: Benjamin Herrenschmidt 
Cc: Paul Mackerras 
Cc: linuxppc-dev@lists.ozlabs.org
---
* v4
- update modules to follow new interface

 lib/Kconfig.debug|   17 +
 lib/Makefile |2 +
 lib/pSeries-reconfig-notifier-error-inject.c |   51 ++
 3 files changed, 70 insertions(+)
 create mode 100644 lib/pSeries-reconfig-notifier-error-inject.c

diff --git a/lib/Kconfig.debug b/lib/Kconfig.debug
index 7cceddc..8f8e226 100644
--- a/lib/Kconfig.debug
+++ b/lib/Kconfig.debug
@@ -1166,6 +1166,23 @@ config MEMORY_NOTIFIER_ERROR_INJECT
 
  If unsure, say N.
 
+config PSERIES_RECONFIG_NOTIFIER_ERROR_INJECT
+   tristate "pSeries reconfig notifier error injection module"
+   depends on PPC_PSERIES && NOTIFIER_ERROR_INJECTION
+   help
+ This option provides the ability to inject artifical errors to
+ pSeries reconfig notifier chain callbacks.  It is controlled
+ through debugfs interface under
+ /sys/kernel/debug/notifier-error-inject/pSeries-reconfig/
+
+ If the notifier call chain should be failed with some events
+ notified, write the error code to "actions//error".
+
+ To compile this code as a module, choose M here: the module will
+ be called memory-notifier-error-inject.
+
+ If unsure, say N.
+
 config FAULT_INJECTION
bool "Fault-injection framework"
depends on DEBUG_KERNEL
diff --git a/lib/Makefile b/lib/Makefile
index a867aa5..d055cb1 100644
--- a/lib/Makefile
+++ b/lib/Makefile
@@ -94,6 +94,8 @@ obj-$(CONFIG_NOTIFIER_ERROR_INJECTION) += 
notifier-error-inject.o
 obj-$(CONFIG_CPU_NOTIFIER_ERROR_INJECT) += cpu-notifier-error-inject.o
 obj-$(CONFIG_PM_NOTIFIER_ERROR_INJECT) += pm-notifier-error-inject.o
 obj-$(CONFIG_MEMORY_NOTIFIER_ERROR_INJECT) += memory-notifier-error-inject.o
+obj-$(CONFIG_PSERIES_RECONFIG_NOTIFIER_ERROR_INJECT) += \
+   pSeries-reconfig-notifier-error-inject.o
 
 lib-$(CONFIG_GENERIC_BUG) += bug.o
 
diff --git a/lib/pSeries-reconfig-notifier-error-inject.c 
b/lib/pSeries-reconfig-notifier-error-inject.c
new file mode 100644
index 000..7f7c98d
--- /dev/null
+++ b/lib/pSeries-reconfig-notifier-error-inject.c
@@ -0,0 +1,51 @@
+#include 
+#include 
+
+#include 
+
+#include "notifier-error-inject.h"
+
+static int priority;
+module_param(priority, int, 0);
+MODULE_PARM_DESC(priority, "specify pSeries reconfig notifier priority");
+
+static struct notifier_err_inject reconfig_err_inject = {
+   .actions = {
+   { NOTIFIER_ERR_INJECT_ACTION(PSERIES_RECONFIG_ADD) },
+   { NOTIFIER_ERR_INJECT_ACTION(PSERIES_RECONFIG_REMOVE) },
+   { NOTIFIER_ERR_INJECT_ACTION(PSERIES_DRCONF_MEM_ADD) },
+   { NOTIFIER_ERR_INJECT_ACTION(PSERIES_DRCONF_MEM_REMOVE) },
+   {}
+   }
+};
+
+static struct dentry *dir;
+
+static int err_inject_init(void)
+{
+   int err;
+
+   dir = notifier_err_inject_init("pSeries-reconfig",
+   notifier_err_inject_dir, &reconfig_err_inject, priority);
+   if (IS_ERR(dir))
+   return PTR_ERR(dir);
+
+   err = pSeries_reconfig_notifier_register(&reconfig_err_inject.nb);
+   if (err)
+   debugfs_remove_recursive(dir);
+
+   return err;
+}
+
+static void err_inject_exit(void)
+{
+   pSeries_reconfig_notifier_unregister(&reconfig_err_inject.nb);
+   debugfs_remove_recursive(dir);
+}
+
+module_init(err_inject_init);
+module_exit(err_inject_exit);
+
+MODULE_DESCRIPTION("pSeries reconfig notifier error injection module");
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("Akinobu Mita ");
-- 
1.7.10.2

___
Linuxppc-dev mailing list
Linuxppc-dev@lists.ozlabs.org
https://lists.ozlabs.org/listinfo/linuxppc-dev


[PATCH -v4 1/6] fault-injection: notifier error injection

2012-06-23 Thread Akinobu Mita
The notifier error injection provides the ability to inject artifical
errors to specified notifier chain callbacks.  It is useful to test the
error handling of notifier call chain failures.

This adds common basic functions to define which type of events can be
fail and to initialize the debugfs interface to control what error code
should be returned and which event should be failed.

Signed-off-by: Akinobu Mita 
Cc: Pavel Machek 
Cc: "Rafael J. Wysocki" 
Cc: linux...@lists.linux-foundation.org
Cc: Greg KH 
Cc: linux...@kvack.org
Cc: Benjamin Herrenschmidt 
Cc: Paul Mackerras 
Cc: linuxppc-dev@lists.ozlabs.org
Cc: Michael Ellerman 
---
* v4
- prefix all APIs with notifier_err_inject_*
- rearrange debugfs interface
  (e.g. $DEBUGFS/cpu-notifier-error-inject/CPU_DOWN_PREPARE -->
$DEBUGFS/notifier-error-inject/cpu/actions/CPU_DOWN_PREPARE/error)

 lib/Kconfig.debug   |   11 +
 lib/Makefile|1 +
 lib/notifier-error-inject.c |  112 +++
 lib/notifier-error-inject.h |   24 ++
 4 files changed, 148 insertions(+)
 create mode 100644 lib/notifier-error-inject.c
 create mode 100644 lib/notifier-error-inject.h

diff --git a/lib/Kconfig.debug b/lib/Kconfig.debug
index ff5bdee..c848758 100644
--- a/lib/Kconfig.debug
+++ b/lib/Kconfig.debug
@@ -1084,6 +1084,17 @@ config LKDTM
Documentation on how to use the module can be found in
Documentation/fault-injection/provoke-crashes.txt
 
+config NOTIFIER_ERROR_INJECTION
+   tristate "Notifier error injection"
+   depends on DEBUG_KERNEL
+   select DEBUG_FS
+   help
+ This option provides the ability to inject artifical errors to
+ specified notifier chain callbacks. It is useful to test the error
+ handling of notifier call chain failures.
+
+ Say N if unsure.
+
 config CPU_NOTIFIER_ERROR_INJECT
tristate "CPU notifier error injection module"
depends on HOTPLUG_CPU && DEBUG_KERNEL
diff --git a/lib/Makefile b/lib/Makefile
index 8c31a0c..23fba9e 100644
--- a/lib/Makefile
+++ b/lib/Makefile
@@ -90,6 +90,7 @@ obj-$(CONFIG_AUDIT_GENERIC) += audit.o
 obj-$(CONFIG_SWIOTLB) += swiotlb.o
 obj-$(CONFIG_IOMMU_HELPER) += iommu-helper.o
 obj-$(CONFIG_FAULT_INJECTION) += fault-inject.o
+obj-$(CONFIG_NOTIFIER_ERROR_INJECTION) += notifier-error-inject.o
 obj-$(CONFIG_CPU_NOTIFIER_ERROR_INJECT) += cpu-notifier-error-inject.o
 
 lib-$(CONFIG_GENERIC_BUG) += bug.o
diff --git a/lib/notifier-error-inject.c b/lib/notifier-error-inject.c
new file mode 100644
index 000..44b92cb
--- /dev/null
+++ b/lib/notifier-error-inject.c
@@ -0,0 +1,112 @@
+#include 
+
+#include "notifier-error-inject.h"
+
+static int debugfs_errno_set(void *data, u64 val)
+{
+   *(int *)data = clamp_t(int, val, -MAX_ERRNO, 0);
+   return 0;
+}
+
+static int debugfs_errno_get(void *data, u64 *val)
+{
+   *val = *(int *)data;
+   return 0;
+}
+
+DEFINE_SIMPLE_ATTRIBUTE(fops_errno, debugfs_errno_get, debugfs_errno_set,
+   "%lld\n");
+
+static struct dentry *debugfs_create_errno(const char *name, mode_t mode,
+   struct dentry *parent, int *value)
+{
+   return debugfs_create_file(name, mode, parent, value, &fops_errno);
+}
+
+static int notifier_err_inject_callback(struct notifier_block *nb,
+   unsigned long val, void *p)
+{
+   int err = 0;
+   struct notifier_err_inject *err_inject =
+   container_of(nb, struct notifier_err_inject, nb);
+   struct notifier_err_inject_action *action;
+
+   for (action = err_inject->actions; action->name; action++) {
+   if (action->val == val) {
+   err = action->error;
+   break;
+   }
+   }
+   if (err)
+   pr_info("Injecting error (%d) to %s\n", err, action->name);
+
+   return notifier_from_errno(err);
+}
+
+struct dentry *notifier_err_inject_dir;
+EXPORT_SYMBOL_GPL(notifier_err_inject_dir);
+
+struct dentry *notifier_err_inject_init(const char *name, struct dentry 
*parent,
+   struct notifier_err_inject *err_inject, int priority)
+{
+   struct notifier_err_inject_action *action;
+   mode_t mode = S_IFREG | S_IRUSR | S_IWUSR;
+   struct dentry *dir;
+   struct dentry *actions_dir;
+
+   err_inject->nb.notifier_call = notifier_err_inject_callback;
+   err_inject->nb.priority = priority;
+
+   dir = debugfs_create_dir(name, parent);
+   if (!dir)
+   return ERR_PTR(-ENOMEM);
+
+   actions_dir = debugfs_create_dir("actions", dir);
+   if (!actions_dir)
+   goto fail;
+
+   for (action = err_inject->actions; action->name; action++) {
+   struct dentry *action_dir;
+
+   action_dir = d

[PATCH -v4 0/6] notifier error injection

2012-06-23 Thread Akinobu Mita
This provides kernel modules that can be used to test the error handling
of notifier call chain failures by injecting artifical errors to the
following notifier chain callbacks.

 * CPU notifier
 * PM notifier
 * memory hotplug notifier
 * powerpc pSeries reconfig notifier

Example: Inject CPU offline error (-1 == -EPERM)

# cd /sys/kernel/debug/notifier-error-inject/cpu
# echo -1 > actions/CPU_DOWN_PREPARE/error
# echo 0 > /sys/devices/system/cpu/cpu1/online
bash: echo: write error: Operation not permitted

There are also handy shell scripts to test CPU and memory hotplug notifier.
Note that these tests didn't detect error handling bugs on my machine but
I still think this feature is usefull to test the code path which is rarely
executed.

Changelog:

* v4 (It is about 11 months since v3)
- prefix all APIs with notifier_err_inject_*
- rearrange debugfs interface
  (e.g. $DEBUGFS/cpu-notifier-error-inject/CPU_DOWN_PREPARE -->
$DEBUGFS/notifier-error-inject/cpu/actions/CPU_DOWN_PREPARE/error)
- update modules to follow new interface
- add -r option for memory-notifier.sh to specify percent of offlining
  memory blocks

* v3
- rewrite to be kernel modules instead of initializing at late_initcall()s
  (it makes the diffstat look different but most code remains unchanged)
- export err_inject_notifier_block_{init,cleanup} for modules
- export pSeries_reconfig_notifier_{,un}register symbols for a module
- notifier priority can be specified as a module parameter
- add testing scripts in tools/testing/fault-injection

* v2
- "PM: Improve error code of pm_notifier_call_chain()" is now in -next
- "debugfs: add debugfs_create_int" is dropped
- put a comment in err_inject_notifier_block_init()
- only allow valid errno to be injected (-MAX_ERRNO <= errno <= 0)
- improve Kconfig help text
- make CONFIG_PM_NOTIFIER_ERROR_INJECTION visible even if PM_DEBUG is disabled
- make CONFIG_PM_NOTIFIER_ERROR_INJECTION default if PM_DEBUG is enabled

Akinobu Mita (6):
  fault-injection: notifier error injection
  cpu: rewrite cpu-notifier-error-inject module
  PM: PM notifier error injection module
  memory: memory notifier error injection module
  powerpc: pSeries reconfig notifier error injection module
  fault-injection: add notifier error injection testing scripts

 lib/Kconfig.debug|   91 ++-
 lib/Makefile |5 +
 lib/cpu-notifier-error-inject.c  |   63 +++-
 lib/memory-notifier-error-inject.c   |   48 ++
 lib/notifier-error-inject.c  |  112 ++
 lib/notifier-error-inject.h  |   24 +++
 lib/pSeries-reconfig-notifier-error-inject.c |   51 +++
 lib/pm-notifier-error-inject.c   |   49 ++
 tools/testing/fault-injection/cpu-notifier.sh|  169 +
 tools/testing/fault-injection/memory-notifier.sh |  176 ++
 10 files changed, 748 insertions(+), 40 deletions(-)
 create mode 100644 lib/memory-notifier-error-inject.c
 create mode 100644 lib/notifier-error-inject.c
 create mode 100644 lib/notifier-error-inject.h
 create mode 100644 lib/pSeries-reconfig-notifier-error-inject.c
 create mode 100644 lib/pm-notifier-error-inject.c
 create mode 100755 tools/testing/fault-injection/cpu-notifier.sh
 create mode 100755 tools/testing/fault-injection/memory-notifier.sh

Cc: Pavel Machek 
Cc: "Rafael J. Wysocki" 
Cc: linux...@lists.linux-foundation.org
Cc: Greg KH 
Cc: linux...@kvack.org
Cc: Benjamin Herrenschmidt 
Cc: Paul Mackerras 
Cc: linuxppc-dev@lists.ozlabs.org
Cc: Américo Wang 
Cc: Michael Ellerman 

-- 
1.7.10.2

___
Linuxppc-dev mailing list
Linuxppc-dev@lists.ozlabs.org
https://lists.ozlabs.org/listinfo/linuxppc-dev

[PATCH] powerpc: use string library

2012-01-27 Thread Akinobu Mita
- Use memchr_inv to check if the data contains all 0xFF bytes.
  It is faster than looping for each byte.

- Use memcmp to compare memory areas

Signed-off-by: Akinobu Mita 
Cc: Benjamin Herrenschmidt 
Cc: linuxppc-dev@lists.ozlabs.org
---
 arch/powerpc/platforms/powermac/nvram.c |   42 ++-
 1 files changed, 19 insertions(+), 23 deletions(-)

diff --git a/arch/powerpc/platforms/powermac/nvram.c 
b/arch/powerpc/platforms/powermac/nvram.c
index 54d2271..da18b26 100644
--- a/arch/powerpc/platforms/powermac/nvram.c
+++ b/arch/powerpc/platforms/powermac/nvram.c
@@ -279,7 +279,7 @@ static u32 core99_check(u8* datas)
 
 static int sm_erase_bank(int bank)
 {
-   int stat, i;
+   int stat;
unsigned long timeout;
 
u8 __iomem *base = (u8 __iomem *)nvram_data + core99_bank*NVRAM_SIZE;
@@ -301,11 +301,10 @@ static int sm_erase_bank(int bank)
out_8(base, SM_FLASH_CMD_CLEAR_STATUS);
out_8(base, SM_FLASH_CMD_RESET);
 
-   for (i=0; ihttps://lists.ozlabs.org/listinfo/linuxppc-dev


[PATCH v3 6/6] fault-injection: add notifier error injection testing scripts

2011-07-23 Thread Akinobu Mita
* tools/testing/fault-injection/cpu-notifier.sh is testing script for
CPU notifier error handling by using cpu-notifier-error-inject.ko.

1. Offline all hot-pluggable CPUs in preparation for testing
2. Test CPU hot-add error handling by injecting notifier errors
3. Online all hot-pluggable CPUs in preparation for testing
4. Test CPU hot-remove error handling by injecting notifier errors

* tools/testing/fault-injection/memory-notifier.sh is doing the same thing
for memory hotplug notifier.

Signed-off-by: Akinobu Mita 
Suggested-by: Andrew Morton 
Cc: Pavel Machek 
Cc: "Rafael J. Wysocki" 
Cc: linux...@lists.linux-foundation.org
Cc: Greg KH 
Cc: linux...@kvack.org
Cc: Benjamin Herrenschmidt 
Cc: Paul Mackerras 
Cc: linuxppc-dev@lists.ozlabs.org
Cc: Américo Wang 
---
* v3
- new patch

 tools/testing/fault-injection/cpu-notifier.sh|  162 +
 tools/testing/fault-injection/memory-notifier.sh |  163 ++
 2 files changed, 325 insertions(+), 0 deletions(-)
 create mode 100755 tools/testing/fault-injection/cpu-notifier.sh
 create mode 100755 tools/testing/fault-injection/memory-notifier.sh

diff --git a/tools/testing/fault-injection/cpu-notifier.sh 
b/tools/testing/fault-injection/cpu-notifier.sh
new file mode 100755
index 000..be02a85
--- /dev/null
+++ b/tools/testing/fault-injection/cpu-notifier.sh
@@ -0,0 +1,162 @@
+#!/bin/bash
+
+#
+# list all hot-pluggable CPUs
+#
+hotpluggable_cpus()
+{
+   local state=${1:-.\*}
+
+   for cpu in /sys/devices/system/cpu/cpu*; do
+   if [ -f $cpu/online ] && grep -q $state $cpu/online; then
+   echo ${cpu##/*/cpu}
+   fi
+   done
+}
+
+hotplaggable_offline_cpus()
+{
+   hotpluggable_cpus 0
+}
+
+hotpluggable_online_cpus()
+{
+   hotpluggable_cpus 1
+}
+
+cpu_is_online()
+{
+   grep -q 1 /sys/devices/system/cpu/cpu$1/online
+}
+
+cpu_is_offline()
+{
+   grep -q 0 /sys/devices/system/cpu/cpu$1/online
+}
+
+add_cpu()
+{
+   echo 1 > /sys/devices/system/cpu/cpu$1/online
+}
+
+remove_cpu()
+{
+   echo 0 > /sys/devices/system/cpu/cpu$1/online
+}
+
+add_cpu_expect_success()
+{
+   local cpu=$1
+
+   if ! add_cpu $cpu; then
+   echo $FUNCNAME $cpu: unexpected fail >&2
+   elif ! cpu_is_online $cpu; then
+   echo $FUNCNAME $cpu: unexpected offline >&2
+   fi
+}
+
+add_cpu_expect_fail()
+{
+   local cpu=$1
+
+   if add_cpu $cpu 2> /dev/null; then
+   echo $FUNCNAME $cpu: unexpected success >&2
+   elif ! cpu_is_offline $cpu; then
+   echo $FUNCNAME $cpu: unexpected online >&2
+   fi
+}
+
+remove_cpu_expect_success()
+{
+   local cpu=$1
+
+   if ! remove_cpu $cpu; then
+   echo $FUNCNAME $cpu: unexpected fail >&2
+   elif ! cpu_is_offline $cpu; then
+   echo $FUNCNAME $cpu: unexpected offline >&2
+   fi
+}
+
+remove_cpu_expect_fail()
+{
+   local cpu=$1
+
+   if remove_cpu $cpu 2> /dev/null; then
+   echo $FUNCNAME $cpu: unexpected success >&2
+   elif ! cpu_is_online $cpu; then
+   echo $FUNCNAME $cpu: unexpected offline >&2
+   fi
+}
+
+if [ $UID != 0 ]; then
+   echo must be run as root >&2
+   exit 1
+fi
+
+error=-12
+priority=0
+
+while getopts e:p: opt; do
+   case $opt in
+   e)
+   error=$OPTARG
+   ;;
+   p)
+   priority=$OPTARG
+   ;;
+   esac
+done
+
+if ! [ "$error" -ge -4095 -a "$error" -lt 0 ]; then
+   echo "error code must be -4095 <= errno < 0" >&2
+   exit 1
+fi
+
+DEBUGFS=`mount -t debugfs | head -1 | awk '{ print $3 }'`
+
+if [ ! -d "$DEBUGFS" ]; then
+   echo debugfs is not mounted >&2
+   exit 1
+fi
+
+/sbin/modprobe -r cpu-notifier-error-inject
+/sbin/modprobe -q cpu-notifier-error-inject priority=$priority
+
+if [ ! -d $DEBUGFS/cpu-notifier-error-inject ]; then
+   echo cpu-notifier-error-inject module is not available >&2
+   exit 1
+fi
+
+#
+# Offline all hot-pluggable CPUs
+#
+echo 0 > $DEBUGFS/cpu-notifier-error-inject/CPU_DOWN_PREPARE
+for cpu in `hotpluggable_online_cpus`; do
+   remove_cpu_expect_success $cpu
+done
+
+#
+# Test CPU hot-add error handling (offline => online)
+#
+echo $error > $DEBUGFS/cpu-notifier-error-inject/CPU_UP_PREPARE
+for cpu in `hotplaggable_offline_cpus`; do
+   add_cpu_expect_fail $cpu
+done
+
+#
+# Online all hot-pluggable CPUs
+#
+echo 0 > $DEBUGFS/cpu-notifier-error-inject/CPU_UP_PREPARE
+for cpu in `hotplaggable_offline_cpus`; do
+   add_cpu_expect_success $cpu
+done
+
+#
+# Test CPU hot-remove error handling (online => offline)
+#
+echo $error > $DEBUGFS/cpu-notifier-error-inject/CPU_DOWN_PREPARE
+for cpu in `hotpluggable_online_cpus`; do
+   remove

[PATCH v3 5/6] powerpc: pSeries reconfig notifier error injection module

2011-07-23 Thread Akinobu Mita
This provides the ability to inject artifical errors to pSeries reconfig
notifier chain callbacks.  It is controlled through debugfs interface
under /sys/kernel/debug/pSeries-reconfig-notifier-error-inject/

Each of the files in the directory represents an event which can be failed
and contains the error code.  If the notifier call chain should be failed
with some events notified, write the error code to the files.

This module needs pSeries_reconfig_notifier_{,un}register symbols to be
exported.

Signed-off-by: Akinobu Mita 
Cc: Benjamin Herrenschmidt 
Cc: Paul Mackerras 
Cc: linuxppc-dev@lists.ozlabs.org
---
* v3
- rewrite to be kernel modules instead of initializing at late_initcall()s
- export pSeries_reconfig_notifier_{,un}register symbols for this module
- notifier priority can be specified as a module parameter

 arch/powerpc/platforms/pseries/reconfig.c|2 +
 lib/Kconfig.debug|   14 +++
 lib/Makefile |2 +
 lib/pSeries-reconfig-notifier-error-inject.c |   48 ++
 4 files changed, 66 insertions(+), 0 deletions(-)
 create mode 100644 lib/pSeries-reconfig-notifier-error-inject.c

diff --git a/arch/powerpc/platforms/pseries/reconfig.c 
b/arch/powerpc/platforms/pseries/reconfig.c
index 168651a..b9808e9 100644
--- a/arch/powerpc/platforms/pseries/reconfig.c
+++ b/arch/powerpc/platforms/pseries/reconfig.c
@@ -103,11 +103,13 @@ int pSeries_reconfig_notifier_register(struct 
notifier_block *nb)
 {
return blocking_notifier_chain_register(&pSeries_reconfig_chain, nb);
 }
+EXPORT_SYMBOL_GPL(pSeries_reconfig_notifier_register);
 
 void pSeries_reconfig_notifier_unregister(struct notifier_block *nb)
 {
blocking_notifier_chain_unregister(&pSeries_reconfig_chain, nb);
 }
+EXPORT_SYMBOL_GPL(pSeries_reconfig_notifier_unregister);
 
 int pSeries_reconfig_notify(unsigned long action, void *p)
 {
diff --git a/lib/Kconfig.debug b/lib/Kconfig.debug
index a2b0856..46298d7 100644
--- a/lib/Kconfig.debug
+++ b/lib/Kconfig.debug
@@ -1099,6 +1099,20 @@ config MEMORY_NOTIFIER_ERROR_INJECT
 
  If unsure, say N.
 
+config PSERIES_RECONFIG_NOTIFIER_ERROR_INJECT
+   tristate "pSeries reconfig notifier error injection module"
+   depends on PPC_PSERIES && NOTIFIER_ERROR_INJECTION
+   help
+ This option provides the ability to inject artifical errors to
+ pSeries reconfig notifier chain callbacks.  It is controlled
+ through debugfs interface under
+ /sys/kernel/debug/pSeries-reconfig-notifier-error-inject/
+
+ To compile this code as a module, choose M here: the module will
+ be called memory-notifier-error-inject.
+
+ If unsure, say N.
+
 config FAULT_INJECTION
bool "Fault-injection framework"
depends on DEBUG_KERNEL
diff --git a/lib/Makefile b/lib/Makefile
index f28914b..e68cea7 100644
--- a/lib/Makefile
+++ b/lib/Makefile
@@ -92,6 +92,8 @@ obj-$(CONFIG_FAULT_INJECTION) += fault-inject.o
 obj-$(CONFIG_CPU_NOTIFIER_ERROR_INJECT) += cpu-notifier-error-inject.o
 obj-$(CONFIG_PM_NOTIFIER_ERROR_INJECT) += pm-notifier-error-inject.o
 obj-$(CONFIG_MEMORY_NOTIFIER_ERROR_INJECT) += memory-notifier-error-inject.o
+obj-$(CONFIG_PSERIES_RECONFIG_NOTIFIER_ERROR_INJECT) += \
+   pSeries-reconfig-notifier-error-inject.o
 
 lib-$(CONFIG_GENERIC_BUG) += bug.o
 
diff --git a/lib/pSeries-reconfig-notifier-error-inject.c 
b/lib/pSeries-reconfig-notifier-error-inject.c
new file mode 100644
index 000..f4ed2b3
--- /dev/null
+++ b/lib/pSeries-reconfig-notifier-error-inject.c
@@ -0,0 +1,48 @@
+#include 
+#include 
+#include 
+
+#include 
+
+static int priority;
+module_param(priority, int, 0);
+MODULE_PARM_DESC(priority, "specify pSeries reconfig notifier priority");
+
+static struct err_inject_notifier_block err_inject_reconfig_nb = {
+   .actions = {
+   { ERR_INJECT_NOTIFIER_ACTION(PSERIES_RECONFIG_ADD) },
+   { ERR_INJECT_NOTIFIER_ACTION(PSERIES_RECONFIG_REMOVE) },
+   { ERR_INJECT_NOTIFIER_ACTION(PSERIES_DRCONF_MEM_ADD) },
+   { ERR_INJECT_NOTIFIER_ACTION(PSERIES_DRCONF_MEM_REMOVE) },
+   {}
+   }
+};
+
+static int err_inject_init(void)
+{
+   int err;
+
+   err = err_inject_notifier_block_init(&err_inject_reconfig_nb,
+   "pSeries-reconfig-notifier-error-inject", priority);
+   if (err)
+   return err;
+
+   err = pSeries_reconfig_notifier_register(&err_inject_reconfig_nb.nb);
+   if (err)
+   err_inject_notifier_block_cleanup(&err_inject_reconfig_nb);
+
+   return err;
+}
+
+static void err_inject_exit(void)
+{
+   pSeries_reconfig_notifier_unregister(&err_inject_reconfig_nb.nb);
+   err_inject_notifier_block_cleanup(&err_inject_reconfig_nb);
+}
+
+module_init(err_inject_init);
+module_exit(err_inject_ex

[PATCH v3 1/6] fault-injection: notifier error injection

2011-07-23 Thread Akinobu Mita
The notifier error injection provides the ability to inject artifical
errors to specified notifier chain callbacks.  It is useful to test the
error handling of notifier call chain failures.

This adds common basic functions to define which type of events can be
fail and to initialize the debugfs interface to control what error code
should be returned and which event should be failed.

Signed-off-by: Akinobu Mita 
Cc: Pavel Machek 
Cc: "Rafael J. Wysocki" 
Cc: linux...@lists.linux-foundation.org
Cc: Greg KH 
Cc: linux...@kvack.org
Cc: Benjamin Herrenschmidt 
Cc: Paul Mackerras 
Cc: linuxppc-dev@lists.ozlabs.org
---
* v3
- export err_inject_notifier_block_{init,cleanup} for modules

 include/linux/notifier.h |   25 ++
 kernel/notifier.c|   83 ++
 lib/Kconfig.debug|   11 ++
 3 files changed, 119 insertions(+), 0 deletions(-)

diff --git a/include/linux/notifier.h b/include/linux/notifier.h
index c0688b0..51882d6 100644
--- a/include/linux/notifier.h
+++ b/include/linux/notifier.h
@@ -278,5 +278,30 @@ extern struct blocking_notifier_head reboot_notifier_list;
 #define VT_UPDATE  0x0004 /* A bigger update occurred */
 #define VT_PREWRITE0x0005 /* A char is about to be written to the 
console */
 
+#ifdef CONFIG_NOTIFIER_ERROR_INJECTION
+
+struct err_inject_notifier_action {
+   unsigned long val;
+   int error;
+   const char *name;
+};
+
+#define ERR_INJECT_NOTIFIER_ACTION(action) \
+   .name = #action, .val = (action),
+
+struct err_inject_notifier_block {
+   struct notifier_block nb;
+   struct dentry *dir;
+   struct err_inject_notifier_action actions[];
+   /* The last slot must be terminated with zero sentinel */
+};
+
+extern int err_inject_notifier_block_init(struct err_inject_notifier_block 
*enb,
+   const char *name, int priority);
+extern void err_inject_notifier_block_cleanup(
+   struct err_inject_notifier_block *enb);
+
+#endif /* CONFIG_NOTIFIER_ERROR_INJECTION */
+
 #endif /* __KERNEL__ */
 #endif /* _LINUX_NOTIFIER_H */
diff --git a/kernel/notifier.c b/kernel/notifier.c
index 2488ba7..8dcb2cc 100644
--- a/kernel/notifier.c
+++ b/kernel/notifier.c
@@ -5,6 +5,7 @@
 #include 
 #include 
 #include 
+#include 
 
 /*
  * Notifier list for kernel code which wants to be called
@@ -584,3 +585,85 @@ int unregister_die_notifier(struct notifier_block *nb)
return atomic_notifier_chain_unregister(&die_chain, nb);
 }
 EXPORT_SYMBOL_GPL(unregister_die_notifier);
+
+#ifdef CONFIG_NOTIFIER_ERROR_INJECTION
+
+static int debugfs_errno_set(void *data, u64 val)
+{
+   *(int *)data = clamp_t(int, val, -MAX_ERRNO, 0);
+   return 0;
+}
+
+static int debugfs_errno_get(void *data, u64 *val)
+{
+   *val = *(int *)data;
+   return 0;
+}
+
+DEFINE_SIMPLE_ATTRIBUTE(fops_errno, debugfs_errno_get, debugfs_errno_set,
+   "%lld\n");
+
+static struct dentry *debugfs_create_errno(const char *name, mode_t mode,
+   struct dentry *parent, int *value)
+{
+   return debugfs_create_file(name, mode, parent, value, &fops_errno);
+}
+
+static int err_inject_notifier_callback(struct notifier_block *nb,
+   unsigned long val, void *p)
+{
+   int err = 0;
+   struct err_inject_notifier_block *enb =
+   container_of(nb, struct err_inject_notifier_block, nb);
+   struct err_inject_notifier_action *action;
+
+   for (action = enb->actions; action->name; action++) {
+   if (action->val == val) {
+   err = action->error;
+   break;
+   }
+   }
+   if (err) {
+   printk(KERN_INFO "Injecting error (%d) to %s\n",
+   err, action->name);
+   }
+
+   return notifier_from_errno(err);
+}
+
+int err_inject_notifier_block_init(struct err_inject_notifier_block *enb,
+   const char *name, int priority)
+{
+   struct err_inject_notifier_action *action;
+   mode_t mode = S_IFREG | S_IRUSR | S_IWUSR;
+
+   enb->nb.notifier_call = err_inject_notifier_callback;
+   enb->nb.priority = priority;
+
+   enb->dir = debugfs_create_dir(name, NULL);
+   if (!enb->dir)
+   return -ENOMEM;
+
+   for (action = enb->actions; action->name; action++) {
+   /*
+* Create debugfs r/w file containing action->error. If
+* notifier call chain is called with action->val, it will
+* fail with the error code
+*/
+   if (!debugfs_create_errno(action->name, mode, enb->dir,
+   &action->error)) {
+   debugfs_remove_recursive(enb->dir);
+ 

[PATCH v2 5/5] powerpc: pSeries reconfig notifier error injection

2011-07-17 Thread Akinobu Mita
This provides the ability to inject artifical errors to pSeries reconfig
notifier chain callbacks.  It is controlled through debugfs interface
under /sys/kernel/debug/pSeries-reconfig-notifier-error-inject/

Each of the files in the directory represents an event which can be
failed and contains the error code.  If the notifier call chain should
be failed with some events notified, write the error code to the files.

Signed-off-by: Akinobu Mita 
Cc: Benjamin Herrenschmidt 
Cc: Paul Mackerras 
Cc: linuxppc-dev@lists.ozlabs.org
---
- Nothing changed from v1

 arch/powerpc/platforms/pseries/reconfig.c |   31 +
 lib/Kconfig.debug |9 
 2 files changed, 40 insertions(+), 0 deletions(-)

diff --git a/arch/powerpc/platforms/pseries/reconfig.c 
b/arch/powerpc/platforms/pseries/reconfig.c
index 168651a..31d9b0f 100644
--- a/arch/powerpc/platforms/pseries/reconfig.c
+++ b/arch/powerpc/platforms/pseries/reconfig.c
@@ -117,6 +117,37 @@ int pSeries_reconfig_notify(unsigned long action, void *p)
return notifier_to_errno(err);
 }
 
+#ifdef CONFIG_PSERIES_RECONFIG_NOTIFIER_ERROR_INJECTION
+
+static struct err_inject_notifier_block err_inject_reconfig_nb = {
+   .actions = {
+   { ERR_INJECT_NOTIFIER_ACTION(PSERIES_RECONFIG_ADD) },
+   { ERR_INJECT_NOTIFIER_ACTION(PSERIES_RECONFIG_REMOVE) },
+   { ERR_INJECT_NOTIFIER_ACTION(PSERIES_DRCONF_MEM_ADD) },
+   { ERR_INJECT_NOTIFIER_ACTION(PSERIES_DRCONF_MEM_REMOVE) },
+   {}
+   }
+};
+
+static int __init err_inject_reconfig_notifier_init(void)
+{
+   int err;
+
+   err = err_inject_notifier_block_init(&err_inject_reconfig_nb,
+   "pSeries-reconfig-notifier-error-inject", -1);
+   if (err)
+   return err;
+
+   err = pSeries_reconfig_notifier_register(&err_inject_reconfig_nb.nb);
+   if (err)
+   err_inject_notifier_block_cleanup(&err_inject_reconfig_nb);
+
+   return err;
+}
+late_initcall(err_inject_reconfig_notifier_init);
+
+#endif /* CONFIG_PSERIES_RECONFIG_NOTIFIER_ERROR_INJECTION */
+
 static int pSeries_reconfig_add_node(const char *path, struct property 
*proplist)
 {
struct device_node *np;
diff --git a/lib/Kconfig.debug b/lib/Kconfig.debug
index 8f5c380..d713000 100644
--- a/lib/Kconfig.debug
+++ b/lib/Kconfig.debug
@@ -1080,6 +1080,15 @@ config MEMORY_NOTIFIER_ERROR_INJECTION
  # echo offline > /sys/devices/system/memory/memoryXXX/state
  bash: echo: write error: Cannot allocate memory
 
+config PSERIES_RECONFIG_NOTIFIER_ERROR_INJECTION
+   bool "pSeries reconfig notifier error injection"
+   depends on PPC_PSERIES && NOTIFIER_ERROR_INJECTION
+   help
+ This option provides the ability to inject artifical errors to
+ pSeries reconfig notifier chain callbacks.  It is controlled
+ through debugfs interface under
+ /sys/kernel/debug/pSeries-reconfig-notifier-error-inject/
+
 config CPU_NOTIFIER_ERROR_INJECT
tristate "CPU notifier error injection module"
depends on HOTPLUG_CPU && DEBUG_KERNEL
-- 
1.7.4.4

___
Linuxppc-dev mailing list
Linuxppc-dev@lists.ozlabs.org
https://lists.ozlabs.org/listinfo/linuxppc-dev


[PATCH v2 1/5] fault-injection: notifier error injection

2011-07-17 Thread Akinobu Mita
The notifier error injection provides the ability to inject artifical
errors to specified notifier chain callbacks. It is useful to test
the error handling of notifier call chain failures.

This adds common basic functions to define which type of events can be
fail and to initialize the debugfs interface to control what error code
should be returned and which event should be failed.

Signed-off-by: Akinobu Mita 
Cc: Pavel Machek 
Cc: "Rafael J. Wysocki" 
Cc: linux...@lists.linux-foundation.org
Cc: Greg Kroah-Hartman 
Cc: linux...@kvack.org
Cc: Benjamin Herrenschmidt 
Cc: Paul Mackerras 
Cc: linuxppc-dev@lists.ozlabs.org
---
* v2
- put a comment in err_inject_notifier_block_init()
- only allow valid errno to be injected (-MAX_ERRNO <= errno <= 0)

 include/linux/notifier.h |   25 ++
 kernel/notifier.c|   81 ++
 lib/Kconfig.debug|   11 ++
 3 files changed, 117 insertions(+), 0 deletions(-)

diff --git a/include/linux/notifier.h b/include/linux/notifier.h
index c0688b0..51882d6 100644
--- a/include/linux/notifier.h
+++ b/include/linux/notifier.h
@@ -278,5 +278,30 @@ extern struct blocking_notifier_head reboot_notifier_list;
 #define VT_UPDATE  0x0004 /* A bigger update occurred */
 #define VT_PREWRITE0x0005 /* A char is about to be written to the 
console */
 
+#ifdef CONFIG_NOTIFIER_ERROR_INJECTION
+
+struct err_inject_notifier_action {
+   unsigned long val;
+   int error;
+   const char *name;
+};
+
+#define ERR_INJECT_NOTIFIER_ACTION(action) \
+   .name = #action, .val = (action),
+
+struct err_inject_notifier_block {
+   struct notifier_block nb;
+   struct dentry *dir;
+   struct err_inject_notifier_action actions[];
+   /* The last slot must be terminated with zero sentinel */
+};
+
+extern int err_inject_notifier_block_init(struct err_inject_notifier_block 
*enb,
+   const char *name, int priority);
+extern void err_inject_notifier_block_cleanup(
+   struct err_inject_notifier_block *enb);
+
+#endif /* CONFIG_NOTIFIER_ERROR_INJECTION */
+
 #endif /* __KERNEL__ */
 #endif /* _LINUX_NOTIFIER_H */
diff --git a/kernel/notifier.c b/kernel/notifier.c
index 2488ba7..8824ae3 100644
--- a/kernel/notifier.c
+++ b/kernel/notifier.c
@@ -5,6 +5,7 @@
 #include 
 #include 
 #include 
+#include 
 
 /*
  * Notifier list for kernel code which wants to be called
@@ -584,3 +585,83 @@ int unregister_die_notifier(struct notifier_block *nb)
return atomic_notifier_chain_unregister(&die_chain, nb);
 }
 EXPORT_SYMBOL_GPL(unregister_die_notifier);
+
+#ifdef CONFIG_NOTIFIER_ERROR_INJECTION
+
+static int debugfs_errno_set(void *data, u64 val)
+{
+   *(int *)data = clamp_t(int, val, -MAX_ERRNO, 0);
+   return 0;
+}
+
+static int debugfs_errno_get(void *data, u64 *val)
+{
+   *val = *(int *)data;
+   return 0;
+}
+
+DEFINE_SIMPLE_ATTRIBUTE(fops_errno, debugfs_errno_get, debugfs_errno_set,
+   "%lld\n");
+
+static struct dentry *debugfs_create_errno(const char *name, mode_t mode,
+   struct dentry *parent, int *value)
+{
+   return debugfs_create_file(name, mode, parent, value, &fops_errno);
+}
+
+static int err_inject_notifier_callback(struct notifier_block *nb,
+   unsigned long val, void *p)
+{
+   int err = 0;
+   struct err_inject_notifier_block *enb =
+   container_of(nb, struct err_inject_notifier_block, nb);
+   struct err_inject_notifier_action *action;
+
+   for (action = enb->actions; action->name; action++) {
+   if (action->val == val) {
+   err = action->error;
+   break;
+   }
+   }
+   if (err) {
+   printk(KERN_INFO "Injecting error (%d) to %s\n",
+   err, action->name);
+   }
+
+   return notifier_from_errno(err);
+}
+
+int err_inject_notifier_block_init(struct err_inject_notifier_block *enb,
+   const char *name, int priority)
+{
+   struct err_inject_notifier_action *action;
+   mode_t mode = S_IFREG | S_IRUSR | S_IWUSR;
+
+   enb->nb.notifier_call = err_inject_notifier_callback;
+   enb->nb.priority = priority;
+
+   enb->dir = debugfs_create_dir(name, NULL);
+   if (!enb->dir)
+   return -ENOMEM;
+
+   for (action = enb->actions; action->name; action++) {
+   /*
+* Create debugfs r/w file containing action->error. If
+* notifier call chain is called with action->val, it will
+* fail with the error code
+*/
+   if (!debugfs_create_errno(action->name, mode, enb->dir,
+   &action->error)) {
+ 

Re: [PATCH 3/7] fault-injection: notifier error injection

2011-07-03 Thread Akinobu Mita
2011/7/4 Pavel Machek :
>
>> +     for (action = enb->actions; action->name; action++) {
>> +             struct dentry *file = debugfs_create_int(action->name, mode,
>> +                                             enb->dir, &action->error);
>> +
>> +             if (!file) {
>> +                     debugfs_remove_recursive(enb->dir);
>> +                     return -ENOMEM;
>> +             }
>
> Few lines how this work would be welcome...?

OK, I'll add a comment like below.

/*
 * Create debugfs r/w file containing action->error. If notifier call
 * chain is called with action->val, it will fail with the error code
 */
___
Linuxppc-dev mailing list
Linuxppc-dev@lists.ozlabs.org
https://lists.ozlabs.org/listinfo/linuxppc-dev


[PATCH 7/7] powerpc: pSeries reconfig notifier error injection

2011-07-03 Thread Akinobu Mita
This provides the ability to inject artifical errors to pSeries reconfig
notifier chain callbacks.  It is controlled through debugfs interface
under /sys/kernel/debug/pSeries-reconfig-notifier-error-inject/

Each of the files in the directory represents an event which can be
failed and contains the error code.  If the notifier call chain should
be failed with some events notified, write the error code to the files.

Signed-off-by: Akinobu Mita 
Cc: Benjamin Herrenschmidt 
Cc: Paul Mackerras 
Cc: linuxppc-dev@lists.ozlabs.org
---
 arch/powerpc/platforms/pseries/reconfig.c |   31 +
 lib/Kconfig.debug |9 
 2 files changed, 40 insertions(+), 0 deletions(-)

diff --git a/arch/powerpc/platforms/pseries/reconfig.c 
b/arch/powerpc/platforms/pseries/reconfig.c
index 168651a..31d9b0f 100644
--- a/arch/powerpc/platforms/pseries/reconfig.c
+++ b/arch/powerpc/platforms/pseries/reconfig.c
@@ -117,6 +117,37 @@ int pSeries_reconfig_notify(unsigned long action, void *p)
return notifier_to_errno(err);
 }
 
+#ifdef CONFIG_PSERIES_RECONFIG_NOTIFIER_ERROR_INJECTION
+
+static struct err_inject_notifier_block err_inject_reconfig_nb = {
+   .actions = {
+   { ERR_INJECT_NOTIFIER_ACTION(PSERIES_RECONFIG_ADD) },
+   { ERR_INJECT_NOTIFIER_ACTION(PSERIES_RECONFIG_REMOVE) },
+   { ERR_INJECT_NOTIFIER_ACTION(PSERIES_DRCONF_MEM_ADD) },
+   { ERR_INJECT_NOTIFIER_ACTION(PSERIES_DRCONF_MEM_REMOVE) },
+   {}
+   }
+};
+
+static int __init err_inject_reconfig_notifier_init(void)
+{
+   int err;
+
+   err = err_inject_notifier_block_init(&err_inject_reconfig_nb,
+   "pSeries-reconfig-notifier-error-inject", -1);
+   if (err)
+   return err;
+
+   err = pSeries_reconfig_notifier_register(&err_inject_reconfig_nb.nb);
+   if (err)
+   err_inject_notifier_block_cleanup(&err_inject_reconfig_nb);
+
+   return err;
+}
+late_initcall(err_inject_reconfig_notifier_init);
+
+#endif /* CONFIG_PSERIES_RECONFIG_NOTIFIER_ERROR_INJECTION */
+
 static int pSeries_reconfig_add_node(const char *path, struct property 
*proplist)
 {
struct device_node *np;
diff --git a/lib/Kconfig.debug b/lib/Kconfig.debug
index 52f0b0e..2becf8c 100644
--- a/lib/Kconfig.debug
+++ b/lib/Kconfig.debug
@@ -1059,6 +1059,15 @@ config MEMORY_NOTIFIER_ERROR_INJECTION
  memory hotplug notifier chain callbacks.  It is controlled through
  debugfs interface under 
/sys/kernel/debug/memory-notifier-error-inject/
 
+config PSERIES_RECONFIG_NOTIFIER_ERROR_INJECTION
+   bool "pSeries reconfig notifier error injection"
+   depends on PPC_PSERIES && NOTIFIER_ERROR_INJECTION
+   help
+ This option provides the ability to inject artifical errors to
+ pSeries reconfig notifier chain callbacks.  It is controlled
+ through debugfs interface under
+ /sys/kernel/debug/pSeries-reconfig-notifier-error-inject/
+
 config CPU_NOTIFIER_ERROR_INJECT
tristate "CPU notifier error injection module"
depends on HOTPLUG_CPU && DEBUG_KERNEL
-- 
1.7.4.4

___
Linuxppc-dev mailing list
Linuxppc-dev@lists.ozlabs.org
https://lists.ozlabs.org/listinfo/linuxppc-dev


[PATCH 3/7] fault-injection: notifier error injection

2011-07-03 Thread Akinobu Mita
The notifier error injection provides the ability to inject artifical
errors to specified notifier chain callbacks. It is useful to test
the error handling of notifier call chain failures.

This adds common basic functions to define which type of events can be
fail and to initialize the debugfs interface to control what error code
should be returned and which event should be failed.

Signed-off-by: Akinobu Mita 
Cc: Pavel Machek 
Cc: "Rafael J. Wysocki" 
Cc: Greg Kroah-Hartman 
Cc: Benjamin Herrenschmidt 
Cc: Paul Mackerras 
Cc: linux...@lists.linux-foundation.org
Cc: linux...@kvack.org
Cc: linuxppc-dev@lists.ozlabs.org
---
 include/linux/notifier.h |   25 
 kernel/notifier.c|   57 ++
 lib/Kconfig.debug|   11 +
 3 files changed, 93 insertions(+), 0 deletions(-)

diff --git a/include/linux/notifier.h b/include/linux/notifier.h
index c0688b0..51882d6 100644
--- a/include/linux/notifier.h
+++ b/include/linux/notifier.h
@@ -278,5 +278,30 @@ extern struct blocking_notifier_head reboot_notifier_list;
 #define VT_UPDATE  0x0004 /* A bigger update occurred */
 #define VT_PREWRITE0x0005 /* A char is about to be written to the 
console */
 
+#ifdef CONFIG_NOTIFIER_ERROR_INJECTION
+
+struct err_inject_notifier_action {
+   unsigned long val;
+   int error;
+   const char *name;
+};
+
+#define ERR_INJECT_NOTIFIER_ACTION(action) \
+   .name = #action, .val = (action),
+
+struct err_inject_notifier_block {
+   struct notifier_block nb;
+   struct dentry *dir;
+   struct err_inject_notifier_action actions[];
+   /* The last slot must be terminated with zero sentinel */
+};
+
+extern int err_inject_notifier_block_init(struct err_inject_notifier_block 
*enb,
+   const char *name, int priority);
+extern void err_inject_notifier_block_cleanup(
+   struct err_inject_notifier_block *enb);
+
+#endif /* CONFIG_NOTIFIER_ERROR_INJECTION */
+
 #endif /* __KERNEL__ */
 #endif /* _LINUX_NOTIFIER_H */
diff --git a/kernel/notifier.c b/kernel/notifier.c
index 2488ba7..8dcc485 100644
--- a/kernel/notifier.c
+++ b/kernel/notifier.c
@@ -5,6 +5,7 @@
 #include 
 #include 
 #include 
+#include 
 
 /*
  * Notifier list for kernel code which wants to be called
@@ -584,3 +585,59 @@ int unregister_die_notifier(struct notifier_block *nb)
return atomic_notifier_chain_unregister(&die_chain, nb);
 }
 EXPORT_SYMBOL_GPL(unregister_die_notifier);
+
+#ifdef CONFIG_NOTIFIER_ERROR_INJECTION
+
+static int err_inject_notifier_callback(struct notifier_block *nb,
+   unsigned long val, void *p)
+{
+   int err = 0;
+   struct err_inject_notifier_block *enb =
+   container_of(nb, struct err_inject_notifier_block, nb);
+   struct err_inject_notifier_action *action;
+
+   for (action = enb->actions; action->name; action++) {
+   if (action->val == val) {
+   err = action->error;
+   break;
+   }
+   }
+   if (err) {
+   printk(KERN_INFO "Injecting error (%d) to %s\n",
+   err, action->name);
+   }
+
+   return notifier_from_errno(err);
+}
+
+int err_inject_notifier_block_init(struct err_inject_notifier_block *enb,
+   const char *name, int priority)
+{
+   struct err_inject_notifier_action *action;
+   mode_t mode = S_IFREG | S_IRUSR | S_IWUSR;
+
+   enb->nb.notifier_call = err_inject_notifier_callback;
+   enb->nb.priority = priority;
+
+   enb->dir = debugfs_create_dir(name, NULL);
+   if (!enb->dir)
+   return -ENOMEM;
+
+   for (action = enb->actions; action->name; action++) {
+   struct dentry *file = debugfs_create_int(action->name, mode,
+   enb->dir, &action->error);
+
+   if (!file) {
+   debugfs_remove_recursive(enb->dir);
+   return -ENOMEM;
+   }
+   }
+   return 0;
+}
+
+void err_inject_notifier_block_cleanup(struct err_inject_notifier_block *enb)
+{
+   debugfs_remove_recursive(enb->dir);
+}
+
+#endif /* CONFIG_NOTIFIER_ERROR_INJECTION */
diff --git a/lib/Kconfig.debug b/lib/Kconfig.debug
index dd373c8..8c6ce7e 100644
--- a/lib/Kconfig.debug
+++ b/lib/Kconfig.debug
@@ -1018,6 +1018,17 @@ config LKDTM
Documentation on how to use the module can be found in
Documentation/fault-injection/provoke-crashes.txt
 
+config NOTIFIER_ERROR_INJECTION
+   bool "Notifier error injection"
+   depends on DEBUG_KERNEL
+   select DEBUG_FS
+   help
+ This option provides the ability to inject artifical errors to
+ specified notifier chain callbacks. It is useful t

[PATCH 2/2] powerpc: improve error code on reconfiguration notifier failure

2011-06-21 Thread Akinobu Mita
Reconfiguration notifier call for device node may fail by several reasons,
but it always assumes kmalloc failures.

This enables reconfiguration notifier call chain to get the actual error
code rather than -ENOMEM by converting all reconfiguration notifier calls
to return encapsulate error code with notifier_from_errno().

Signed-off-by: Akinobu Mita 
Cc: Benjamin Herrenschmidt 
Cc: Paul Mackerras 
Cc: linuxppc-dev@lists.ozlabs.org
---
 arch/powerpc/kernel/prom.c  |8 +++-
 arch/powerpc/platforms/pseries/hotplug-cpu.c|   10 +++---
 arch/powerpc/platforms/pseries/hotplug-memory.c |   16 +---
 arch/powerpc/platforms/pseries/reconfig.c   |4 +---
 4 files changed, 12 insertions(+), 26 deletions(-)

diff --git a/arch/powerpc/kernel/prom.c b/arch/powerpc/kernel/prom.c
index 8c3112a..86677ba 100644
--- a/arch/powerpc/kernel/prom.c
+++ b/arch/powerpc/kernel/prom.c
@@ -862,16 +862,14 @@ static int prom_reconfig_notifier(struct notifier_block 
*nb,
switch (action) {
case PSERIES_RECONFIG_ADD:
err = of_finish_dynamic_node(node);
-   if (err < 0) {
+   if (err < 0)
printk(KERN_ERR "finish_node returned %d\n", err);
-   err = NOTIFY_BAD;
-   }
break;
default:
-   err = NOTIFY_DONE;
+   err = 0;
break;
}
-   return err;
+   return notifier_from_errno(err);
 }
 
 static struct notifier_block prom_reconfig_nb = {
diff --git a/arch/powerpc/platforms/pseries/hotplug-cpu.c 
b/arch/powerpc/platforms/pseries/hotplug-cpu.c
index 46f13a3..bc02885 100644
--- a/arch/powerpc/platforms/pseries/hotplug-cpu.c
+++ b/arch/powerpc/platforms/pseries/hotplug-cpu.c
@@ -330,21 +330,17 @@ static void pseries_remove_processor(struct device_node 
*np)
 static int pseries_smp_notifier(struct notifier_block *nb,
unsigned long action, void *node)
 {
-   int err = NOTIFY_OK;
+   int err = 0;
 
switch (action) {
case PSERIES_RECONFIG_ADD:
-   if (pseries_add_processor(node))
-   err = NOTIFY_BAD;
+   err = pseries_add_processor(node);
break;
case PSERIES_RECONFIG_REMOVE:
pseries_remove_processor(node);
break;
-   default:
-   err = NOTIFY_DONE;
-   break;
}
-   return err;
+   return notifier_from_errno(err);
 }
 
 static struct notifier_block pseries_smp_nb = {
diff --git a/arch/powerpc/platforms/pseries/hotplug-memory.c 
b/arch/powerpc/platforms/pseries/hotplug-memory.c
index 33867ec..1eaefd6 100644
--- a/arch/powerpc/platforms/pseries/hotplug-memory.c
+++ b/arch/powerpc/platforms/pseries/hotplug-memory.c
@@ -197,27 +197,21 @@ static int pseries_drconf_memory(unsigned long *base, 
unsigned int action)
 static int pseries_memory_notifier(struct notifier_block *nb,
unsigned long action, void *node)
 {
-   int err = NOTIFY_OK;
+   int err = 0;
 
switch (action) {
case PSERIES_RECONFIG_ADD:
-   if (pseries_add_memory(node))
-   err = NOTIFY_BAD;
+   err = pseries_add_memory(node);
break;
case PSERIES_RECONFIG_REMOVE:
-   if (pseries_remove_memory(node))
-   err = NOTIFY_BAD;
+   err = pseries_remove_memory(node);
break;
case PSERIES_DRCONF_MEM_ADD:
case PSERIES_DRCONF_MEM_REMOVE:
-   if (pseries_drconf_memory(node, action))
-   err = NOTIFY_BAD;
-   break;
-   default:
-   err = NOTIFY_DONE;
+   err = pseries_drconf_memory(node, action);
break;
}
-   return err;
+   return notifier_from_errno(err);
 }
 
 static struct notifier_block pseries_mem_nb = {
diff --git a/arch/powerpc/platforms/pseries/reconfig.c 
b/arch/powerpc/platforms/pseries/reconfig.c
index 286b6af..168651a 100644
--- a/arch/powerpc/platforms/pseries/reconfig.c
+++ b/arch/powerpc/platforms/pseries/reconfig.c
@@ -114,9 +114,7 @@ int pSeries_reconfig_notify(unsigned long action, void *p)
int err = blocking_notifier_call_chain(&pSeries_reconfig_chain,
action, p);
 
-   if (err == NOTIFY_BAD)
-   return -ENOMEM; /* For now, safe to assume kmalloc failure */
-   return 0;
+   return notifier_to_errno(err);
 }
 
 static int pSeries_reconfig_add_node(const char *path, struct property 
*proplist)
-- 
1.7.4.4

___
Linuxppc-dev mailing list
Linuxppc-dev@lists.ozlabs.org
https://lists.ozlabs.org/listinfo/linuxppc-dev


[PATCH 1/2] powerpc: introduce pSeries_reconfig_notify()

2011-06-21 Thread Akinobu Mita
This introduces pSeries_reconfig_notify() as a just wrapper of
blocking_notifier_call_chain() for pSeries_reconfig_chain.

This is a preparation to improvement of error code on reconfiguration
notifier failure.

Signed-off-by: Akinobu Mita 
Cc: Benjamin Herrenschmidt 
Cc: Paul Mackerras 
Cc: linuxppc-dev@lists.ozlabs.org
---
 arch/powerpc/include/asm/pSeries_reconfig.h |2 +-
 arch/powerpc/platforms/pseries/dlpar.c  |   10 +++-
 arch/powerpc/platforms/pseries/reconfig.c   |   30 --
 3 files changed, 23 insertions(+), 19 deletions(-)

diff --git a/arch/powerpc/include/asm/pSeries_reconfig.h 
b/arch/powerpc/include/asm/pSeries_reconfig.h
index 89d2f99..23cd6cc 100644
--- a/arch/powerpc/include/asm/pSeries_reconfig.h
+++ b/arch/powerpc/include/asm/pSeries_reconfig.h
@@ -17,7 +17,7 @@
 #ifdef CONFIG_PPC_PSERIES
 extern int pSeries_reconfig_notifier_register(struct notifier_block *);
 extern void pSeries_reconfig_notifier_unregister(struct notifier_block *);
-extern struct blocking_notifier_head pSeries_reconfig_chain;
+extern int pSeries_reconfig_notify(unsigned long action, void *p);
 /* Not the best place to put this, will be fixed when we move some
  * of the rtas suspend-me stuff to pseries */
 extern void pSeries_coalesce_init(void);
diff --git a/arch/powerpc/platforms/pseries/dlpar.c 
b/arch/powerpc/platforms/pseries/dlpar.c
index 57ceb92..e9be25b 100644
--- a/arch/powerpc/platforms/pseries/dlpar.c
+++ b/arch/powerpc/platforms/pseries/dlpar.c
@@ -262,12 +262,11 @@ int dlpar_attach_node(struct device_node *dn)
if (!dn->parent)
return -ENOMEM;
 
-   rc = blocking_notifier_call_chain(&pSeries_reconfig_chain,
- PSERIES_RECONFIG_ADD, dn);
-   if (rc == NOTIFY_BAD) {
+   rc = pSeries_reconfig_notify(PSERIES_RECONFIG_ADD, dn);
+   if (rc) {
printk(KERN_ERR "Failed to add device node %s\n",
   dn->full_name);
-   return -ENOMEM; /* For now, safe to assume kmalloc failure */
+   return rc;
}
 
of_attach_node(dn);
@@ -297,8 +296,7 @@ int dlpar_detach_node(struct device_node *dn)
remove_proc_entry(dn->pde->name, parent->pde);
 #endif
 
-   blocking_notifier_call_chain(&pSeries_reconfig_chain,
-   PSERIES_RECONFIG_REMOVE, dn);
+   pSeries_reconfig_notify(PSERIES_RECONFIG_REMOVE, dn);
of_detach_node(dn);
of_node_put(dn); /* Must decrement the refcount */
 
diff --git a/arch/powerpc/platforms/pseries/reconfig.c 
b/arch/powerpc/platforms/pseries/reconfig.c
index 1de2cbb..286b6af 100644
--- a/arch/powerpc/platforms/pseries/reconfig.c
+++ b/arch/powerpc/platforms/pseries/reconfig.c
@@ -97,7 +97,7 @@ static struct device_node *derive_parent(const char *path)
return parent;
 }
 
-BLOCKING_NOTIFIER_HEAD(pSeries_reconfig_chain);
+static BLOCKING_NOTIFIER_HEAD(pSeries_reconfig_chain);
 
 int pSeries_reconfig_notifier_register(struct notifier_block *nb)
 {
@@ -109,6 +109,16 @@ void pSeries_reconfig_notifier_unregister(struct 
notifier_block *nb)
blocking_notifier_chain_unregister(&pSeries_reconfig_chain, nb);
 }
 
+int pSeries_reconfig_notify(unsigned long action, void *p)
+{
+   int err = blocking_notifier_call_chain(&pSeries_reconfig_chain,
+   action, p);
+
+   if (err == NOTIFY_BAD)
+   return -ENOMEM; /* For now, safe to assume kmalloc failure */
+   return 0;
+}
+
 static int pSeries_reconfig_add_node(const char *path, struct property 
*proplist)
 {
struct device_node *np;
@@ -132,11 +142,9 @@ static int pSeries_reconfig_add_node(const char *path, 
struct property *proplist
goto out_err;
}
 
-   err = blocking_notifier_call_chain(&pSeries_reconfig_chain,
- PSERIES_RECONFIG_ADD, np);
-   if (err == NOTIFY_BAD) {
+   err = pSeries_reconfig_notify(PSERIES_RECONFIG_ADD, np);
+   if (err) {
printk(KERN_ERR "Failed to add device node %s\n", path);
-   err = -ENOMEM; /* For now, safe to assume kmalloc failure */
goto out_err;
}
 
@@ -173,8 +181,7 @@ static int pSeries_reconfig_remove_node(struct device_node 
*np)
 
remove_node_proc_entries(np);
 
-   blocking_notifier_call_chain(&pSeries_reconfig_chain,
-   PSERIES_RECONFIG_REMOVE, np);
+   pSeries_reconfig_notify(PSERIES_RECONFIG_REMOVE, np);
of_detach_node(np);
 
of_node_put(parent);
@@ -472,11 +479,10 @@ static int do_update_property(char *buf, size_t bufsize)
else
action = PSERIES_DRCONF_MEM_REMOVE;
 
-   rc = blocking_notifier_call_chain(&pSeries_reconfig_chain,
- action, value);
-  

Re: [PATCH -mm 2/6] powerpc: convert little-endian bitops macros to static inline functions

2011-02-06 Thread Akinobu Mita
2011/2/7 Benjamin Herrenschmidt :
> On Thu, 2011-01-27 at 22:56 +0900, Akinobu Mita wrote:
>> (This patch is intended to be folded into the patch in -mm:
>> powerpc-introduce-little-endian-bitops.patch)
>>
>> The little-endian bitops on powerpc are written as preprocessor
>> macros with the cast to "unsigned long *".
>> This means that even non-pointers will be accepted without an error, and
>> that is a Very Bad Thing.
>>
>> This converts the little-endian bitops macros to static inline functions
>> with proper prototypes.
>
> No objection to the powerpc variant of the patches. What is the status
> with the wholes series tho ? Does it looks like its going to be
> accepted ? Do you expect my Ack and will merge the whole thing at once ?

The whole series now seems acceptable since I fixed two issues
that Linus found annoying. (the naming and the change of prototype)

Please give your ack if it is OK.

I should have fixed them quickly so that the series went upstream
in the last merge windows. But I couldn't because I spent some time
fixing and compile testing for a bisection hole.

> Does it break bisection unless it's merged as one single giant patch ?

I think there is no known problem that breaks bisectability by
this patch series.
___
Linuxppc-dev mailing list
Linuxppc-dev@lists.ozlabs.org
https://lists.ozlabs.org/listinfo/linuxppc-dev


[PATCH -mm 2/6] powerpc: convert little-endian bitops macros to static inline functions

2011-01-27 Thread Akinobu Mita
(This patch is intended to be folded into the patch in -mm:
powerpc-introduce-little-endian-bitops.patch)

The little-endian bitops on powerpc are written as preprocessor
macros with the cast to "unsigned long *".
This means that even non-pointers will be accepted without an error, and
that is a Very Bad Thing.

This converts the little-endian bitops macros to static inline functions
with proper prototypes.

Suggested-by: "H. Peter Anvin" 
Signed-off-by: Akinobu Mita 
Cc: Benjamin Herrenschmidt 
Cc: Paul Mackerras 
Cc: linuxppc-dev@lists.ozlabs.org
---
 arch/powerpc/include/asm/bitops.h |   43 +
 1 files changed, 29 insertions(+), 14 deletions(-)

diff --git a/arch/powerpc/include/asm/bitops.h 
b/arch/powerpc/include/asm/bitops.h
index fe67024..2e56187 100644
--- a/arch/powerpc/include/asm/bitops.h
+++ b/arch/powerpc/include/asm/bitops.h
@@ -288,20 +288,35 @@ static __inline__ int test_bit_le(unsigned long nr,
return (tmp[nr >> 3] >> (nr & 7)) & 1;
 }
 
-#define __set_bit_le(nr, addr) \
-   __set_bit((nr) ^ BITOP_LE_SWIZZLE, (unsigned long *)(addr))
-#define __clear_bit_le(nr, addr) \
-   __clear_bit((nr) ^ BITOP_LE_SWIZZLE, (unsigned long *)(addr))
-
-#define test_and_set_bit_le(nr, addr) \
-   test_and_set_bit((nr) ^ BITOP_LE_SWIZZLE, (unsigned long *)(addr))
-#define test_and_clear_bit_le(nr, addr) \
-   test_and_clear_bit((nr) ^ BITOP_LE_SWIZZLE, (unsigned long *)(addr))
-
-#define __test_and_set_bit_le(nr, addr) \
-   __test_and_set_bit((nr) ^ BITOP_LE_SWIZZLE, (unsigned long *)(addr))
-#define __test_and_clear_bit_le(nr, addr) \
-   __test_and_clear_bit((nr) ^ BITOP_LE_SWIZZLE, (unsigned long *)(addr))
+static inline void __set_bit_le(int nr, void *addr)
+{
+   __set_bit(nr ^ BITOP_LE_SWIZZLE, addr);
+}
+
+static inline void __clear_bit_le(int nr, void *addr)
+{
+   __clear_bit(nr ^ BITOP_LE_SWIZZLE, addr);
+}
+
+static inline int test_and_set_bit_le(int nr, void *addr)
+{
+   return test_and_set_bit(nr ^ BITOP_LE_SWIZZLE, addr);
+}
+
+static inline int test_and_clear_bit_le(int nr, void *addr)
+{
+   return test_and_clear_bit(nr ^ BITOP_LE_SWIZZLE, addr);
+}
+
+static inline int __test_and_set_bit_le(int nr, void *addr)
+{
+   return __test_and_set_bit(nr ^ BITOP_LE_SWIZZLE, addr);
+}
+
+static inline int __test_and_clear_bit_le(int nr, void *addr)
+{
+   return __test_and_clear_bit(nr ^ BITOP_LE_SWIZZLE, addr);
+}
 
 #define find_first_zero_bit_le(addr, size) \
find_next_zero_bit_le((addr), (size), 0)
-- 
1.7.3.4

___
Linuxppc-dev mailing list
Linuxppc-dev@lists.ozlabs.org
https://lists.ozlabs.org/listinfo/linuxppc-dev


[PATCH v5 06/27] powerpc: introduce little-endian bitops

2011-01-22 Thread Akinobu Mita
Introduce little-endian bit operations by renaming existing powerpc
native little-endian bit operations and changing them to take any
pointer types.

Signed-off-by: Akinobu Mita 
Cc: Benjamin Herrenschmidt 
Cc: Paul Mackerras 
Cc: linuxppc-dev@lists.ozlabs.org
---

Change from v4:
 - change the prototypes and add casts in the macro to take any pointer types

The whole series is available in the git branch at:
 git://git.kernel.org/pub/scm/linux/kernel/git/mita/linux-2.6.git le-bitops-v5

 arch/powerpc/include/asm/bitops.h |   46 ++--
 1 files changed, 23 insertions(+), 23 deletions(-)

diff --git a/arch/powerpc/include/asm/bitops.h 
b/arch/powerpc/include/asm/bitops.h
index db567ed..a77f6be 100644
--- a/arch/powerpc/include/asm/bitops.h
+++ b/arch/powerpc/include/asm/bitops.h
@@ -281,27 +281,27 @@ unsigned long __arch_hweight64(__u64 w);
 
 /* Little-endian versions */
 
-static __inline__ int test_le_bit(unsigned long nr,
- __const__ unsigned long *addr)
+static __inline__ int test_bit_le(unsigned long nr,
+ __const__ void *addr)
 {
__const__ unsigned char *tmp = (__const__ unsigned char *) addr;
return (tmp[nr >> 3] >> (nr & 7)) & 1;
 }
 
-#define __set_le_bit(nr, addr) \
-   __set_bit((nr) ^ BITOP_LE_SWIZZLE, (addr))
-#define __clear_le_bit(nr, addr) \
-   __clear_bit((nr) ^ BITOP_LE_SWIZZLE, (addr))
+#define __set_bit_le(nr, addr) \
+   __set_bit((nr) ^ BITOP_LE_SWIZZLE, (unsigned long *)(addr))
+#define __clear_bit_le(nr, addr) \
+   __clear_bit((nr) ^ BITOP_LE_SWIZZLE, (unsigned long *)(addr))
 
-#define test_and_set_le_bit(nr, addr) \
-   test_and_set_bit((nr) ^ BITOP_LE_SWIZZLE, (addr))
-#define test_and_clear_le_bit(nr, addr) \
-   test_and_clear_bit((nr) ^ BITOP_LE_SWIZZLE, (addr))
+#define test_and_set_bit_le(nr, addr) \
+   test_and_set_bit((nr) ^ BITOP_LE_SWIZZLE, (unsigned long *)(addr))
+#define test_and_clear_bit_le(nr, addr) \
+   test_and_clear_bit((nr) ^ BITOP_LE_SWIZZLE, (unsigned long *)(addr))
 
-#define __test_and_set_le_bit(nr, addr) \
-   __test_and_set_bit((nr) ^ BITOP_LE_SWIZZLE, (addr))
-#define __test_and_clear_le_bit(nr, addr) \
-   __test_and_clear_bit((nr) ^ BITOP_LE_SWIZZLE, (addr))
+#define __test_and_set_bit_le(nr, addr) \
+   __test_and_set_bit((nr) ^ BITOP_LE_SWIZZLE, (unsigned long *)(addr))
+#define __test_and_clear_bit_le(nr, addr) \
+   __test_and_clear_bit((nr) ^ BITOP_LE_SWIZZLE, (unsigned long *)(addr))
 
 #define find_first_zero_bit_le(addr, size) \
find_next_zero_bit_le((addr), (size), 0)
@@ -313,16 +313,16 @@ unsigned long find_next_bit_le(const void *addr,
 /* Bitmap functions for the ext2 filesystem */
 
 #define ext2_set_bit(nr,addr) \
-   __test_and_set_le_bit((nr), (unsigned long*)addr)
+   __test_and_set_bit_le((nr), (unsigned long*)addr)
 #define ext2_clear_bit(nr, addr) \
-   __test_and_clear_le_bit((nr), (unsigned long*)addr)
+   __test_and_clear_bit_le((nr), (unsigned long*)addr)
 
 #define ext2_set_bit_atomic(lock, nr, addr) \
-   test_and_set_le_bit((nr), (unsigned long*)addr)
+   test_and_set_bit_le((nr), (unsigned long*)addr)
 #define ext2_clear_bit_atomic(lock, nr, addr) \
-   test_and_clear_le_bit((nr), (unsigned long*)addr)
+   test_and_clear_bit_le((nr), (unsigned long*)addr)
 
-#define ext2_test_bit(nr, addr)  test_le_bit((nr),(unsigned long*)addr)
+#define ext2_test_bit(nr, addr)  test_bit_le((nr),(unsigned long*)addr)
 
 #define ext2_find_first_zero_bit(addr, size) \
find_first_zero_bit_le((unsigned long*)addr, size)
@@ -334,13 +334,13 @@ unsigned long find_next_bit_le(const void *addr,
 /* Bitmap functions for the minix filesystem.  */
 
 #define minix_test_and_set_bit(nr,addr) \
-   __test_and_set_le_bit(nr, (unsigned long *)addr)
+   __test_and_set_bit_le(nr, (unsigned long *)addr)
 #define minix_set_bit(nr,addr) \
-   __set_le_bit(nr, (unsigned long *)addr)
+   __set_bit_le(nr, (unsigned long *)addr)
 #define minix_test_and_clear_bit(nr,addr) \
-   __test_and_clear_le_bit(nr, (unsigned long *)addr)
+   __test_and_clear_bit_le(nr, (unsigned long *)addr)
 #define minix_test_bit(nr,addr) \
-   test_le_bit(nr, (unsigned long *)addr)
+   test_bit_le(nr, (unsigned long *)addr)
 
 #define minix_find_first_zero_bit(addr,size) \
find_first_zero_bit_le((unsigned long *)addr, size)
-- 
1.7.3.4

___
Linuxppc-dev mailing list
Linuxppc-dev@lists.ozlabs.org
https://lists.ozlabs.org/listinfo/linuxppc-dev


[PATCH v4 03/24] powerpc: introduce little-endian bitops

2011-01-16 Thread Akinobu Mita
Introduce little-endian bit operations by renaming existing powerpc
native little-endian bit operations.

Signed-off-by: Akinobu Mita 
Cc: Benjamin Herrenschmidt 
Cc: Paul Mackerras 
Cc: linuxppc-dev@lists.ozlabs.org
---

The whole series is available in the git repository at:
 git://git.kernel.org/pub/scm/linux/kernel/git/mita/linux-2.6.git le-bitops-v4

 arch/powerpc/include/asm/bitops.h |   38 ++--
 1 files changed, 19 insertions(+), 19 deletions(-)

diff --git a/arch/powerpc/include/asm/bitops.h 
b/arch/powerpc/include/asm/bitops.h
index e903264..7b1c5a9 100644
--- a/arch/powerpc/include/asm/bitops.h
+++ b/arch/powerpc/include/asm/bitops.h
@@ -281,29 +281,29 @@ unsigned long __arch_hweight64(__u64 w);
 
 /* Little-endian versions */
 
-static __inline__ int test_le_bit(unsigned long nr,
+static __inline__ int test_bit_le(unsigned long nr,
  __const__ unsigned long *addr)
 {
__const__ unsigned char *tmp = (__const__ unsigned char *) addr;
return (tmp[nr >> 3] >> (nr & 7)) & 1;
 }
 
-#define __set_le_bit(nr, addr) \
+#define __set_bit_le(nr, addr) \
__set_bit((nr) ^ BITOP_LE_SWIZZLE, (addr))
-#define __clear_le_bit(nr, addr) \
+#define __clear_bit_le(nr, addr) \
__clear_bit((nr) ^ BITOP_LE_SWIZZLE, (addr))
 
-#define test_and_set_le_bit(nr, addr) \
+#define test_and_set_bit_le(nr, addr) \
test_and_set_bit((nr) ^ BITOP_LE_SWIZZLE, (addr))
-#define test_and_clear_le_bit(nr, addr) \
+#define test_and_clear_bit_le(nr, addr) \
test_and_clear_bit((nr) ^ BITOP_LE_SWIZZLE, (addr))
 
-#define __test_and_set_le_bit(nr, addr) \
+#define __test_and_set_bit_le(nr, addr) \
__test_and_set_bit((nr) ^ BITOP_LE_SWIZZLE, (addr))
-#define __test_and_clear_le_bit(nr, addr) \
+#define __test_and_clear_bit_le(nr, addr) \
__test_and_clear_bit((nr) ^ BITOP_LE_SWIZZLE, (addr))
 
-#define find_first_zero_le_bit(addr, size) \
+#define find_first_zero_bit_le(addr, size) \
find_next_zero_bit_le((addr), (size), 0)
 unsigned long find_next_zero_bit_le(const unsigned long *addr,
unsigned long size, unsigned long offset);
@@ -313,19 +313,19 @@ unsigned long find_next_bit_le(const unsigned long *addr,
 /* Bitmap functions for the ext2 filesystem */
 
 #define ext2_set_bit(nr,addr) \
-   __test_and_set_le_bit((nr), (unsigned long*)addr)
+   __test_and_set_bit_le((nr), (unsigned long*)addr)
 #define ext2_clear_bit(nr, addr) \
-   __test_and_clear_le_bit((nr), (unsigned long*)addr)
+   __test_and_clear_bit_le((nr), (unsigned long*)addr)
 
 #define ext2_set_bit_atomic(lock, nr, addr) \
-   test_and_set_le_bit((nr), (unsigned long*)addr)
+   test_and_set_bit_le((nr), (unsigned long*)addr)
 #define ext2_clear_bit_atomic(lock, nr, addr) \
-   test_and_clear_le_bit((nr), (unsigned long*)addr)
+   test_and_clear_bit_le((nr), (unsigned long*)addr)
 
-#define ext2_test_bit(nr, addr)  test_le_bit((nr),(unsigned long*)addr)
+#define ext2_test_bit(nr, addr)  test_bit_le((nr),(unsigned long*)addr)
 
 #define ext2_find_first_zero_bit(addr, size) \
-   find_first_zero_le_bit((unsigned long*)addr, size)
+   find_first_zero_bit_le((unsigned long*)addr, size)
 #define ext2_find_next_zero_bit(addr, size, off) \
find_next_zero_bit_le((unsigned long *)addr, size, off)
 
@@ -334,16 +334,16 @@ unsigned long find_next_bit_le(const unsigned long *addr,
 /* Bitmap functions for the minix filesystem.  */
 
 #define minix_test_and_set_bit(nr,addr) \
-   __test_and_set_le_bit(nr, (unsigned long *)addr)
+   __test_and_set_bit_le(nr, (unsigned long *)addr)
 #define minix_set_bit(nr,addr) \
-   __set_le_bit(nr, (unsigned long *)addr)
+   __set_bit_le(nr, (unsigned long *)addr)
 #define minix_test_and_clear_bit(nr,addr) \
-   __test_and_clear_le_bit(nr, (unsigned long *)addr)
+   __test_and_clear_bit_le(nr, (unsigned long *)addr)
 #define minix_test_bit(nr,addr) \
-   test_le_bit(nr, (unsigned long *)addr)
+   test_bit_le(nr, (unsigned long *)addr)
 
 #define minix_find_first_zero_bit(addr,size) \
-   find_first_zero_le_bit((unsigned long *)addr, size)
+   find_first_zero_bit_le((unsigned long *)addr, size)
 
 #include 
 
-- 
1.7.3.4

___
Linuxppc-dev mailing list
Linuxppc-dev@lists.ozlabs.org
https://lists.ozlabs.org/listinfo/linuxppc-dev


[PATCH] powerpc: use simple_read_from_buffer

2010-12-24 Thread Akinobu Mita
Simplify read file operation for /proc/powerpc/rtas/* interface
by using simple_read_from_buffer.

Signed-off-by: Akinobu Mita 
Cc: Benjamin Herrenschmidt 
Cc: Paul Mackerras 
Cc: linuxppc-dev@lists.ozlabs.org
---
 arch/powerpc/kernel/rtas_flash.c |   53 -
 1 files changed, 6 insertions(+), 47 deletions(-)

diff --git a/arch/powerpc/kernel/rtas_flash.c b/arch/powerpc/kernel/rtas_flash.c
index 2b442e6..bf5f5ce 100644
--- a/arch/powerpc/kernel/rtas_flash.c
+++ b/arch/powerpc/kernel/rtas_flash.c
@@ -256,31 +256,16 @@ static ssize_t rtas_flash_read(struct file *file, char 
__user *buf,
struct proc_dir_entry *dp = PDE(file->f_path.dentry->d_inode);
struct rtas_update_flash_t *uf;
char msg[RTAS_MSG_MAXLEN];
-   int msglen;
 
-   uf = (struct rtas_update_flash_t *) dp->data;
+   uf = dp->data;
 
if (!strcmp(dp->name, FIRMWARE_FLASH_NAME)) {
get_flash_status_msg(uf->status, msg);
} else {   /* FIRMWARE_UPDATE_NAME */
sprintf(msg, "%d\n", uf->status);
}
-   msglen = strlen(msg);
-   if (msglen > count)
-   msglen = count;
-
-   if (ppos && *ppos != 0)
-   return 0;   /* be cheap */
-
-   if (!access_ok(VERIFY_WRITE, buf, msglen))
-   return -EINVAL;
 
-   if (copy_to_user(buf, msg, msglen))
-   return -EFAULT;
-
-   if (ppos)
-   *ppos = msglen;
-   return msglen;
+   return simple_read_from_buffer(buf, count, ppos, msg, strlen(msg));
 }
 
 /* constructor for flash_block_cache */
@@ -394,26 +379,13 @@ static ssize_t manage_flash_read(struct file *file, char 
__user *buf,
char msg[RTAS_MSG_MAXLEN];
int msglen;
 
-   args_buf = (struct rtas_manage_flash_t *) dp->data;
+   args_buf = dp->data;
if (args_buf == NULL)
return 0;
 
msglen = sprintf(msg, "%d\n", args_buf->status);
-   if (msglen > count)
-   msglen = count;
 
-   if (ppos && *ppos != 0)
-   return 0;   /* be cheap */
-
-   if (!access_ok(VERIFY_WRITE, buf, msglen))
-   return -EINVAL;
-
-   if (copy_to_user(buf, msg, msglen))
-   return -EFAULT;
-
-   if (ppos)
-   *ppos = msglen;
-   return msglen;
+   return simple_read_from_buffer(buf, count, ppos, msg, msglen);
 }
 
 static ssize_t manage_flash_write(struct file *file, const char __user *buf,
@@ -495,24 +467,11 @@ static ssize_t validate_flash_read(struct file *file, 
char __user *buf,
char msg[RTAS_MSG_MAXLEN];
int msglen;
 
-   args_buf = (struct rtas_validate_flash_t *) dp->data;
+   args_buf = dp->data;
 
-   if (ppos && *ppos != 0)
-   return 0;   /* be cheap */
-   
msglen = get_validate_flash_msg(args_buf, msg);
-   if (msglen > count)
-   msglen = count;
-
-   if (!access_ok(VERIFY_WRITE, buf, msglen))
-   return -EINVAL;
-
-   if (copy_to_user(buf, msg, msglen))
-   return -EFAULT;
 
-   if (ppos)
-   *ppos = msglen;
-   return msglen;
+   return simple_read_from_buffer(buf, count, ppos, msg, msglen);
 }
 
 static ssize_t validate_flash_write(struct file *file, const char __user *buf,
-- 
1.7.3.4

___
Linuxppc-dev mailing list
Linuxppc-dev@lists.ozlabs.org
https://lists.ozlabs.org/listinfo/linuxppc-dev


[PATCH] spufs: use simple_write_to_buffer

2010-12-24 Thread Akinobu Mita
Simplify several write fileoperations for spufs by using
simple_write_to_buffer().

Signed-off-by: Akinobu Mita 
Cc: Benjamin Herrenschmidt 
Cc: Paul Mackerras 
Cc: Jeremy Kerr 
Cc: linuxppc-dev@lists.ozlabs.org
Cc: cbe-oss-...@lists.ozlabs.org
---
 arch/powerpc/platforms/cell/spufs/file.c |   27 +++
 1 files changed, 7 insertions(+), 20 deletions(-)

diff --git a/arch/powerpc/platforms/cell/spufs/file.c 
b/arch/powerpc/platforms/cell/spufs/file.c
index 02f7b11..3c7c3f8 100644
--- a/arch/powerpc/platforms/cell/spufs/file.c
+++ b/arch/powerpc/platforms/cell/spufs/file.c
@@ -219,24 +219,17 @@ spufs_mem_write(struct file *file, const char __user 
*buffer,
loff_t pos = *ppos;
int ret;
 
-   if (pos < 0)
-   return -EINVAL;
if (pos > LS_SIZE)
return -EFBIG;
-   if (size > LS_SIZE - pos)
-   size = LS_SIZE - pos;
 
ret = spu_acquire(ctx);
if (ret)
return ret;
 
local_store = ctx->ops->get_ls(ctx);
-   ret = copy_from_user(local_store + pos, buffer, size);
+   size = simple_write_to_buffer(local_store, LS_SIZE, ppos, buffer, size);
spu_release(ctx);
 
-   if (ret)
-   return -EFAULT;
-   *ppos = pos + size;
return size;
 }
 
@@ -574,18 +567,15 @@ spufs_regs_write(struct file *file, const char __user 
*buffer,
if (*pos >= sizeof(lscsa->gprs))
return -EFBIG;
 
-   size = min_t(ssize_t, sizeof(lscsa->gprs) - *pos, size);
-   *pos += size;
-
ret = spu_acquire_saved(ctx);
if (ret)
return ret;
 
-   ret = copy_from_user((char *)lscsa->gprs + *pos - size,
-buffer, size) ? -EFAULT : size;
+   size = simple_write_to_buffer(lscsa->gprs, sizeof(lscsa->gprs), pos,
+   buffer, size);
 
spu_release_saved(ctx);
-   return ret;
+   return size;
 }
 
 static const struct file_operations spufs_regs_fops = {
@@ -630,18 +620,15 @@ spufs_fpcr_write(struct file *file, const char __user * 
buffer,
if (*pos >= sizeof(lscsa->fpcr))
return -EFBIG;
 
-   size = min_t(ssize_t, sizeof(lscsa->fpcr) - *pos, size);
-
ret = spu_acquire_saved(ctx);
if (ret)
return ret;
 
-   *pos += size;
-   ret = copy_from_user((char *)&lscsa->fpcr + *pos - size,
-buffer, size) ? -EFAULT : size;
+   size = simple_write_to_buffer(&lscsa->fpcr, sizeof(lscsa->fpcr), pos,
+   buffer, size);
 
spu_release_saved(ctx);
-   return ret;
+   return size;
 }
 
 static const struct file_operations spufs_fpcr_fops = {
-- 
1.7.3.4

___
Linuxppc-dev mailing list
Linuxppc-dev@lists.ozlabs.org
https://lists.ozlabs.org/listinfo/linuxppc-dev


[PATCH v3 02/22] bitops: rename generic little-endian bitops functions

2010-11-23 Thread Akinobu Mita
As a preparation for providing little-endian bitops for all architectures,
This removes generic_ prefix from little-endian bitops function names
in asm-generic/bitops/le.h.

s/generic_find_next_le_bit/find_next_le_bit/
s/generic_find_next_zero_le_bit/find_next_zero_le_bit/
s/generic_find_first_zero_le_bit/find_first_zero_le_bit/
s/generic___test_and_set_le_bit/__test_and_set_le_bit/
s/generic___test_and_clear_le_bit/__test_and_clear_le_bit/
s/generic_test_le_bit/test_le_bit/
s/generic___set_le_bit/__set_le_bit/
s/generic___clear_le_bit/__clear_le_bit/
s/generic_test_and_set_le_bit/test_and_set_le_bit/
s/generic_test_and_clear_le_bit/test_and_clear_le_bit/

Signed-off-by: Akinobu Mita 
Acked-by: Arnd Bergmann 
Acked-by: Hans-Christian Egtvedt 
Cc: Geert Uytterhoeven 
Cc: Roman Zippel 
Cc: Andreas Schwab 
Cc: linux-m...@lists.linux-m68k.org
Cc: Greg Ungerer 
Cc: Benjamin Herrenschmidt 
Cc: Paul Mackerras 
Cc: linuxppc-dev@lists.ozlabs.org
Cc: Andy Grover 
Cc: rds-de...@oss.oracle.com
Cc: "David S. Miller" 
Cc: net...@vger.kernel.org
Cc: Avi Kivity 
Cc: Marcelo Tosatti 
Cc: k...@vger.kernel.org
---
No change from previous submission
 arch/avr32/kernel/avr32_ksyms.c  |4 ++--
 arch/avr32/lib/findbit.S |4 ++--
 arch/m68k/include/asm/bitops_mm.h|8 
 arch/m68k/include/asm/bitops_no.h|2 +-
 arch/powerpc/include/asm/bitops.h|   11 ++-
 include/asm-generic/bitops/ext2-non-atomic.h |   12 ++--
 include/asm-generic/bitops/le.h  |   26 +-
 include/asm-generic/bitops/minix-le.h|   10 +-
 lib/find_next_bit.c  |9 -
 net/rds/cong.c   |6 +++---
 virt/kvm/kvm_main.c  |2 +-
 11 files changed, 47 insertions(+), 47 deletions(-)

diff --git a/arch/avr32/kernel/avr32_ksyms.c b/arch/avr32/kernel/avr32_ksyms.c
index 11e310c..c63b943 100644
--- a/arch/avr32/kernel/avr32_ksyms.c
+++ b/arch/avr32/kernel/avr32_ksyms.c
@@ -58,8 +58,8 @@ EXPORT_SYMBOL(find_first_zero_bit);
 EXPORT_SYMBOL(find_next_zero_bit);
 EXPORT_SYMBOL(find_first_bit);
 EXPORT_SYMBOL(find_next_bit);
-EXPORT_SYMBOL(generic_find_next_le_bit);
-EXPORT_SYMBOL(generic_find_next_zero_le_bit);
+EXPORT_SYMBOL(find_next_le_bit);
+EXPORT_SYMBOL(find_next_zero_le_bit);
 
 /* I/O primitives (lib/io-*.S) */
 EXPORT_SYMBOL(__raw_readsb);
diff --git a/arch/avr32/lib/findbit.S b/arch/avr32/lib/findbit.S
index 997b33b..6880d85 100644
--- a/arch/avr32/lib/findbit.S
+++ b/arch/avr32/lib/findbit.S
@@ -123,7 +123,7 @@ ENTRY(find_next_bit)
brgt1b
retal   r11
 
-ENTRY(generic_find_next_le_bit)
+ENTRY(find_next_le_bit)
lsr r8, r10, 5
sub r9, r11, r10
retle   r11
@@ -153,7 +153,7 @@ ENTRY(generic_find_next_le_bit)
brgt1b
retal   r11
 
-ENTRY(generic_find_next_zero_le_bit)
+ENTRY(find_next_zero_le_bit)
lsr r8, r10, 5
sub r9, r11, r10
retle   r11
diff --git a/arch/m68k/include/asm/bitops_mm.h 
b/arch/m68k/include/asm/bitops_mm.h
index b4ecdaa..f1010ab 100644
--- a/arch/m68k/include/asm/bitops_mm.h
+++ b/arch/m68k/include/asm/bitops_mm.h
@@ -366,9 +366,9 @@ static inline int minix_test_bit(int nr, const void *vaddr)
 #define ext2_clear_bit(nr, addr)   __test_and_clear_bit((nr) ^ 24, 
(unsigned long *)(addr))
 #define ext2_clear_bit_atomic(lock, nr, addr)  test_and_clear_bit((nr) ^ 24, 
(unsigned long *)(addr))
 #define ext2_find_next_zero_bit(addr, size, offset) \
-   generic_find_next_zero_le_bit((unsigned long *)addr, size, offset)
+   find_next_zero_le_bit((unsigned long *)addr, size, offset)
 #define ext2_find_next_bit(addr, size, offset) \
-   generic_find_next_le_bit((unsigned long *)addr, size, offset)
+   find_next_le_bit((unsigned long *)addr, size, offset)
 
 static inline int ext2_test_bit(int nr, const void *vaddr)
 {
@@ -398,7 +398,7 @@ static inline int ext2_find_first_zero_bit(const void 
*vaddr, unsigned size)
return (p - addr) * 32 + res;
 }
 
-static inline unsigned long generic_find_next_zero_le_bit(const unsigned long 
*addr,
+static inline unsigned long find_next_zero_le_bit(const unsigned long *addr,
unsigned long size, unsigned long offset)
 {
const unsigned long *p = addr + (offset >> 5);
@@ -440,7 +440,7 @@ static inline int ext2_find_first_bit(const void *vaddr, 
unsigned size)
return (p - addr) * 32 + res;
 }
 
-static inline unsigned long generic_find_next_le_bit(const unsigned long *addr,
+static inline unsigned long find_next_le_bit(const unsigned long *addr,
unsigned long size, unsigned long offset)
 {
const unsigned long *p = addr + (offset >> 5);
diff --git a/arch/m68k/include/asm/bitops_no.h 
b/arch/m68k/include/asm/bitops_no.h
index 9d3cbe5..292e1ce 100644
--- a/arch/m68k/include/asm/bitop

[PATCH v2 02/22] bitops: rename generic little-endian bitops functions

2010-10-21 Thread Akinobu Mita
As a preparation for providing little-endian bitops for all architectures,
This removes generic_ prefix from little-endian bitops function names
in asm-generic/bitops/le.h.

s/generic_find_next_le_bit/find_next_le_bit/
s/generic_find_next_zero_le_bit/find_next_zero_le_bit/
s/generic_find_first_zero_le_bit/find_first_zero_le_bit/
s/generic___test_and_set_le_bit/__test_and_set_le_bit/
s/generic___test_and_clear_le_bit/__test_and_clear_le_bit/
s/generic_test_le_bit/test_le_bit/
s/generic___set_le_bit/__set_le_bit/
s/generic___clear_le_bit/__clear_le_bit/
s/generic_test_and_set_le_bit/test_and_set_le_bit/
s/generic_test_and_clear_le_bit/test_and_clear_le_bit/

Signed-off-by: Akinobu Mita 
Cc: Hans-Christian Egtvedt 
Cc: Geert Uytterhoeven 
Cc: Roman Zippel 
Cc: Andreas Schwab 
Cc: linux-m...@lists.linux-m68k.org
Cc: Greg Ungerer 
Cc: Benjamin Herrenschmidt 
Cc: Paul Mackerras 
Cc: linuxppc-dev@lists.ozlabs.org
Cc: Andy Grover 
Cc: rds-de...@oss.oracle.com
Cc: "David S. Miller" 
Cc: net...@vger.kernel.org
Cc: Avi Kivity 
Cc: Marcelo Tosatti 
Cc: k...@vger.kernel.org
---
No change from previous submission

 arch/avr32/kernel/avr32_ksyms.c  |4 ++--
 arch/avr32/lib/findbit.S |4 ++--
 arch/m68k/include/asm/bitops_mm.h|8 
 arch/m68k/include/asm/bitops_no.h|2 +-
 arch/powerpc/include/asm/bitops.h|   11 ++-
 include/asm-generic/bitops/ext2-non-atomic.h |   12 ++--
 include/asm-generic/bitops/le.h  |   26 +-
 include/asm-generic/bitops/minix-le.h|   10 +-
 lib/find_next_bit.c  |9 -
 net/rds/cong.c   |6 +++---
 virt/kvm/kvm_main.c  |2 +-
 11 files changed, 47 insertions(+), 47 deletions(-)

diff --git a/arch/avr32/kernel/avr32_ksyms.c b/arch/avr32/kernel/avr32_ksyms.c
index 11e310c..c63b943 100644
--- a/arch/avr32/kernel/avr32_ksyms.c
+++ b/arch/avr32/kernel/avr32_ksyms.c
@@ -58,8 +58,8 @@ EXPORT_SYMBOL(find_first_zero_bit);
 EXPORT_SYMBOL(find_next_zero_bit);
 EXPORT_SYMBOL(find_first_bit);
 EXPORT_SYMBOL(find_next_bit);
-EXPORT_SYMBOL(generic_find_next_le_bit);
-EXPORT_SYMBOL(generic_find_next_zero_le_bit);
+EXPORT_SYMBOL(find_next_le_bit);
+EXPORT_SYMBOL(find_next_zero_le_bit);
 
 /* I/O primitives (lib/io-*.S) */
 EXPORT_SYMBOL(__raw_readsb);
diff --git a/arch/avr32/lib/findbit.S b/arch/avr32/lib/findbit.S
index 997b33b..6880d85 100644
--- a/arch/avr32/lib/findbit.S
+++ b/arch/avr32/lib/findbit.S
@@ -123,7 +123,7 @@ ENTRY(find_next_bit)
brgt1b
retal   r11
 
-ENTRY(generic_find_next_le_bit)
+ENTRY(find_next_le_bit)
lsr r8, r10, 5
sub r9, r11, r10
retle   r11
@@ -153,7 +153,7 @@ ENTRY(generic_find_next_le_bit)
brgt1b
retal   r11
 
-ENTRY(generic_find_next_zero_le_bit)
+ENTRY(find_next_zero_le_bit)
lsr r8, r10, 5
sub r9, r11, r10
retle   r11
diff --git a/arch/m68k/include/asm/bitops_mm.h 
b/arch/m68k/include/asm/bitops_mm.h
index b4ecdaa..f1010ab 100644
--- a/arch/m68k/include/asm/bitops_mm.h
+++ b/arch/m68k/include/asm/bitops_mm.h
@@ -366,9 +366,9 @@ static inline int minix_test_bit(int nr, const void *vaddr)
 #define ext2_clear_bit(nr, addr)   __test_and_clear_bit((nr) ^ 24, 
(unsigned long *)(addr))
 #define ext2_clear_bit_atomic(lock, nr, addr)  test_and_clear_bit((nr) ^ 24, 
(unsigned long *)(addr))
 #define ext2_find_next_zero_bit(addr, size, offset) \
-   generic_find_next_zero_le_bit((unsigned long *)addr, size, offset)
+   find_next_zero_le_bit((unsigned long *)addr, size, offset)
 #define ext2_find_next_bit(addr, size, offset) \
-   generic_find_next_le_bit((unsigned long *)addr, size, offset)
+   find_next_le_bit((unsigned long *)addr, size, offset)
 
 static inline int ext2_test_bit(int nr, const void *vaddr)
 {
@@ -398,7 +398,7 @@ static inline int ext2_find_first_zero_bit(const void 
*vaddr, unsigned size)
return (p - addr) * 32 + res;
 }
 
-static inline unsigned long generic_find_next_zero_le_bit(const unsigned long 
*addr,
+static inline unsigned long find_next_zero_le_bit(const unsigned long *addr,
unsigned long size, unsigned long offset)
 {
const unsigned long *p = addr + (offset >> 5);
@@ -440,7 +440,7 @@ static inline int ext2_find_first_bit(const void *vaddr, 
unsigned size)
return (p - addr) * 32 + res;
 }
 
-static inline unsigned long generic_find_next_le_bit(const unsigned long *addr,
+static inline unsigned long find_next_le_bit(const unsigned long *addr,
unsigned long size, unsigned long offset)
 {
const unsigned long *p = addr + (offset >> 5);
diff --git a/arch/m68k/include/asm/bitops_no.h 
b/arch/m68k/include/asm/bitops_no.h
index 9d3cbe5..292e1ce 100644
--- a/arch/m68k/include/asm/bitops_no.h
+++ b/arch/m68k/include/asm

[PATCH] powerpc/512x: fix clk_get() return value

2010-08-31 Thread Akinobu Mita
clk_get() should return an ERR_PTR value on error, not NULL.

Signed-off-by: Akinobu Mita 
Cc: Grant Likely 
Cc: linuxppc-dev@lists.ozlabs.org
---
 arch/powerpc/platforms/512x/clock.c |2 +-
 1 files changed, 1 insertions(+), 1 deletions(-)

diff --git a/arch/powerpc/platforms/512x/clock.c 
b/arch/powerpc/platforms/512x/clock.c
index 5b243bd..3dc2a8d 100644
--- a/arch/powerpc/platforms/512x/clock.c
+++ b/arch/powerpc/platforms/512x/clock.c
@@ -57,7 +57,7 @@ static struct clk *mpc5121_clk_get(struct device *dev, const 
char *id)
int id_match = 0;
 
if (dev == NULL || id == NULL)
-   return NULL;
+   return clk;
 
mutex_lock(&clocks_mutex);
list_for_each_entry(p, &clocks, node) {
-- 
1.7.1.231.gd0b16

___
Linuxppc-dev mailing list
Linuxppc-dev@lists.ozlabs.org
https://lists.ozlabs.org/listinfo/linuxppc-dev


[PATCH] powerpc: use __ratelimit

2010-02-28 Thread Akinobu Mita
Replace open-coded rate limiting logic with __ratelimit().

Signed-off-by: Akinobu Mita 
Cc: Benjamin Herrenschmidt 
Cc: Paul Mackerras 
Cc: linuxppc-...@ozlabs.org
---
 arch/powerpc/platforms/iseries/pci.c |   10 +++---
 1 files changed, 3 insertions(+), 7 deletions(-)

diff --git a/arch/powerpc/platforms/iseries/pci.c 
b/arch/powerpc/platforms/iseries/pci.c
index 175aac8..5873a47 100644
--- a/arch/powerpc/platforms/iseries/pci.c
+++ b/arch/powerpc/platforms/iseries/pci.c
@@ -31,6 +31,7 @@
 #include 
 #include 
 #include 
+#include 
 
 #include 
 #include 
@@ -583,14 +584,9 @@ static inline struct device_node *xlate_iomm_address(
 
orig_addr = (unsigned long __force)addr;
if ((orig_addr < BASE_IO_MEMORY) || (orig_addr >= max_io_memory)) {
-   static unsigned long last_jiffies;
-   static int num_printed;
+   static DEFINE_RATELIMIT_STATE(ratelimit, 60 * HZ, 10);
 
-   if (time_after(jiffies, last_jiffies + 60 * HZ)) {
-   last_jiffies = jiffies;
-   num_printed = 0;
-   }
-   if (num_printed++ < 10)
+   if (__ratelimit(&ratelimit))
printk(KERN_ERR
"iSeries_%s: invalid access at IO address %p\n",
func, addr);
-- 
1.6.0.6

___
Linuxppc-dev mailing list
Linuxppc-dev@lists.ozlabs.org
https://lists.ozlabs.org/listinfo/linuxppc-dev


Re: [PATCH 1/7] bitmap: Introduce bitmap_set, bitmap_clear, bitmap_find_next_zero_area

2009-10-29 Thread Akinobu Mita
2009/10/29 Andrew Morton :
>
> Why were these patches resent?  What changed?
>
> Everybody who is going to review these patches has already reviewed
> them and now they need to review them all again?

I resent the patches because the iommu-helper change was not correct
and I introduced serious bug in bitmap_find_next_zero_area()
if align_mask != 0 in follow-up patch then those were dropped from
the -mm tree.

Only [PATCH 1/7] and [PATCH 2/7] have changes since the first submission of
this patch set.

* [PATCH 1/7]
- Rewrite bitmap_set() and bitmap_clear()
- Let bitmap_find_next_zero_area() check the last bit of the limit
- Add kerneldoc for bitmap_find_next_zero_area()

* [PATCH 2/7]
- Convert find_next_zero_area() to use bitmap_find_next_zero_area() correctly
  iommu-helper doesn't want to search the last bit of the limist in bitmap

* [PATCH 3/7] - [PATCH 7/7]
- No changes
___
Linuxppc-dev mailing list
Linuxppc-dev@lists.ozlabs.org
https://lists.ozlabs.org/listinfo/linuxppc-dev


[PATCH 2/7] iommu-helper: Use bitmap library

2009-10-28 Thread Akinobu Mita
Use bitmap library and kill some unused iommu helper functions.

1. s/iommu_area_free/bitmap_clear/

2. s/iommu_area_reserve/bitmap_set/

3. Use bitmap_find_next_zero_area instead of find_next_zero_area

  This cannot be simple substitution because find_next_zero_area
  doesn't check the last bit of the limit in bitmap

4. Remove iommu_area_free, iommu_area_reserve, and find_next_zero_area

Signed-off-by: Akinobu Mita 
Cc: "David S. Miller" 
Cc: sparcli...@vger.kernel.org
Cc: Benjamin Herrenschmidt 
Cc: Paul Mackerras 
Cc: linuxppc-...@ozlabs.org
Cc: Thomas Gleixner 
Cc: Ingo Molnar 
Cc: "H. Peter Anvin" 
Cc: x...@kernel.org
Cc: FUJITA Tomonori 
Cc: Joerg Roedel 
---
 arch/powerpc/kernel/iommu.c  |4 +-
 arch/sparc/kernel/iommu.c|3 +-
 arch/x86/kernel/amd_iommu.c  |4 +-
 arch/x86/kernel/pci-calgary_64.c |6 ++--
 arch/x86/kernel/pci-gart_64.c|6 ++--
 include/linux/iommu-helper.h |3 --
 lib/iommu-helper.c   |   59 ++
 7 files changed, 21 insertions(+), 64 deletions(-)

diff --git a/arch/powerpc/kernel/iommu.c b/arch/powerpc/kernel/iommu.c
index fd51578..5547ae6 100644
--- a/arch/powerpc/kernel/iommu.c
+++ b/arch/powerpc/kernel/iommu.c
@@ -30,7 +30,7 @@
 #include 
 #include 
 #include 
-#include 
+#include 
 #include 
 #include 
 #include 
@@ -251,7 +251,7 @@ static void __iommu_free(struct iommu_table *tbl, 
dma_addr_t dma_addr,
}
 
ppc_md.tce_free(tbl, entry, npages);
-   iommu_area_free(tbl->it_map, free_entry, npages);
+   bitmap_clear(tbl->it_map, free_entry, npages);
 }
 
 static void iommu_free(struct iommu_table *tbl, dma_addr_t dma_addr,
diff --git a/arch/sparc/kernel/iommu.c b/arch/sparc/kernel/iommu.c
index 7690cc2..5fad949 100644
--- a/arch/sparc/kernel/iommu.c
+++ b/arch/sparc/kernel/iommu.c
@@ -11,6 +11,7 @@
 #include 
 #include 
 #include 
+#include 
 
 #ifdef CONFIG_PCI
 #include 
@@ -169,7 +170,7 @@ void iommu_range_free(struct iommu *iommu, dma_addr_t 
dma_addr, unsigned long np
 
entry = (dma_addr - iommu->page_table_map_base) >> IO_PAGE_SHIFT;
 
-   iommu_area_free(arena->map, entry, npages);
+   bitmap_clear(arena->map, entry, npages);
 }
 
 int iommu_table_init(struct iommu *iommu, int tsbsize,
diff --git a/arch/x86/kernel/amd_iommu.c b/arch/x86/kernel/amd_iommu.c
index 98f230f..08b1d20 100644
--- a/arch/x86/kernel/amd_iommu.c
+++ b/arch/x86/kernel/amd_iommu.c
@@ -19,7 +19,7 @@
 
 #include 
 #include 
-#include 
+#include 
 #include 
 #include 
 #include 
@@ -959,7 +959,7 @@ static void dma_ops_free_addresses(struct dma_ops_domain 
*dom,
 
address = (address % APERTURE_RANGE_SIZE) >> PAGE_SHIFT;
 
-   iommu_area_free(range->bitmap, address, pages);
+   bitmap_clear(range->bitmap, address, pages);
 
 }
 
diff --git a/arch/x86/kernel/pci-calgary_64.c b/arch/x86/kernel/pci-calgary_64.c
index 971a3be..c87bb20 100644
--- a/arch/x86/kernel/pci-calgary_64.c
+++ b/arch/x86/kernel/pci-calgary_64.c
@@ -31,7 +31,7 @@
 #include 
 #include 
 #include 
-#include 
+#include 
 #include 
 #include 
 #include 
@@ -211,7 +211,7 @@ static void iommu_range_reserve(struct iommu_table *tbl,
 
spin_lock_irqsave(&tbl->it_lock, flags);
 
-   iommu_area_reserve(tbl->it_map, index, npages);
+   bitmap_set(tbl->it_map, index, npages);
 
spin_unlock_irqrestore(&tbl->it_lock, flags);
 }
@@ -305,7 +305,7 @@ static void iommu_free(struct iommu_table *tbl, dma_addr_t 
dma_addr,
 
spin_lock_irqsave(&tbl->it_lock, flags);
 
-   iommu_area_free(tbl->it_map, entry, npages);
+   bitmap_clear(tbl->it_map, entry, npages);
 
spin_unlock_irqrestore(&tbl->it_lock, flags);
 }
diff --git a/arch/x86/kernel/pci-gart_64.c b/arch/x86/kernel/pci-gart_64.c
index a7f1b64..156e362 100644
--- a/arch/x86/kernel/pci-gart_64.c
+++ b/arch/x86/kernel/pci-gart_64.c
@@ -23,7 +23,7 @@
 #include 
 #include 
 #include 
-#include 
+#include 
 #include 
 #include 
 #include 
@@ -123,7 +123,7 @@ static void free_iommu(unsigned long offset, int size)
unsigned long flags;
 
spin_lock_irqsave(&iommu_bitmap_lock, flags);
-   iommu_area_free(iommu_gart_bitmap, offset, size);
+   bitmap_clear(iommu_gart_bitmap, offset, size);
if (offset >= next_bit)
next_bit = offset + size;
spin_unlock_irqrestore(&iommu_bitmap_lock, flags);
@@ -782,7 +782,7 @@ void __init gart_iommu_init(void)
 * Out of IOMMU space handling.
 * Reserve some invalid pages at the beginning of the GART.
 */
-   iommu_area_reserve(iommu_gart_bitmap, 0, EMERGENCY_PAGES);
+   bitmap_set(iommu_gart_bitmap, 0, EMERGENCY_PAGES);
 
agp_memory_reserved = iommu_size;
printk(KERN_INFO
diff --git a/include/linux/iommu-helper.h b/include/linux/iommu-helper.h
index 3b068e5..64d1b63 100644
--- a/in

[PATCH 1/7] bitmap: Introduce bitmap_set, bitmap_clear, bitmap_find_next_zero_area

2009-10-28 Thread Akinobu Mita
This introduces new bitmap functions:

bitmap_set: Set specified bit area
bitmap_clear: Clear specified bit area
bitmap_find_next_zero_area: Find free bit area

These are mostly stolen from iommu helper. The differences are:

- Use find_next_bit instead of doing test_bit for each bit

- Rewrite bitmap_set and bitmap_clear

  Instead of setting or clearing for each bit.

- Check the last bit of the limit

  iommu-helper doesn't want to find such area

- The return value if there is no zero area

  find_next_zero_area in iommu helper: returns -1
  bitmap_find_next_zero_area: return >= bitmap size

Signed-off-by: Akinobu Mita 
Cc: FUJITA Tomonori 
Cc: "David S. Miller" 
Cc: sparcli...@vger.kernel.org
Cc: Benjamin Herrenschmidt 
Cc: Paul Mackerras 
Cc: linuxppc-...@ozlabs.org
Cc: Thomas Gleixner 
Cc: Ingo Molnar 
Cc: "H. Peter Anvin" 
Cc: x...@kernel.org
Cc: Greg Kroah-Hartman 
Cc: Lothar Wassmann 
Cc: linux-...@vger.kernel.org
Cc: Roland Dreier 
Cc: Yevgeny Petrilin 
Cc: net...@vger.kernel.org
Cc: Tony Luck 
Cc: Fenghua Yu 
Cc: linux-i...@vger.kernel.org
Cc: linux-al...@sgi.com
Cc: Joerg Roedel 
---
 include/linux/bitmap.h |   11 ++
 lib/bitmap.c   |   81 
 2 files changed, 92 insertions(+), 0 deletions(-)

diff --git a/include/linux/bitmap.h b/include/linux/bitmap.h
index 756d78b..daf8c48 100644
--- a/include/linux/bitmap.h
+++ b/include/linux/bitmap.h
@@ -42,6 +42,9 @@
  * bitmap_empty(src, nbits)Are all bits zero in *src?
  * bitmap_full(src, nbits) Are all bits set in *src?
  * bitmap_weight(src, nbits)   Hamming Weight: number set bits
+ * bitmap_set(dst, pos, nbits) Set specified bit area
+ * bitmap_clear(dst, pos, nbits)   Clear specified bit area
+ * bitmap_find_next_zero_area(buf, len, pos, n, mask)  Find bit free area
  * bitmap_shift_right(dst, src, n, nbits)  *dst = *src >> n
  * bitmap_shift_left(dst, src, n, nbits)   *dst = *src << n
  * bitmap_remap(dst, src, old, new, nbits) *dst = map(old, new)(src)
@@ -108,6 +111,14 @@ extern int __bitmap_subset(const unsigned long *bitmap1,
const unsigned long *bitmap2, int bits);
 extern int __bitmap_weight(const unsigned long *bitmap, int bits);
 
+extern void bitmap_set(unsigned long *map, int i, int len);
+extern void bitmap_clear(unsigned long *map, int start, int nr);
+extern unsigned long bitmap_find_next_zero_area(unsigned long *map,
+unsigned long size,
+unsigned long start,
+unsigned int nr,
+unsigned long align_mask);
+
 extern int bitmap_scnprintf(char *buf, unsigned int len,
const unsigned long *src, int nbits);
 extern int __bitmap_parse(const char *buf, unsigned int buflen, int is_user,
diff --git a/lib/bitmap.c b/lib/bitmap.c
index 7025658..11bf497 100644
--- a/lib/bitmap.c
+++ b/lib/bitmap.c
@@ -271,6 +271,87 @@ int __bitmap_weight(const unsigned long *bitmap, int bits)
 }
 EXPORT_SYMBOL(__bitmap_weight);
 
+#define BITMAP_FIRST_WORD_MASK(start) (~0UL << ((start) % BITS_PER_LONG))
+
+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)
+{
+   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 @al

Re: [PATCH 2/8] bitmap: Introduce bitmap_set, bitmap_clear, bitmap_find_next_zero_area

2009-10-17 Thread Akinobu Mita
>> >> --- a/lib/iommu-helper.c
>> >> +++ b/lib/iommu-helper.c
>> >> @@ -19,7 +19,7 @@ again:
>> >>       index = (index + align_mask) & ~align_mask;
>> >>
>> >>       end = index + nr;
>> >> -     if (end >= size)
>> >> +     if (end > size)
>> >
>> > I think that this is intentional; the last byte of the limit doesn't
>> > work.
>>
>> It looks ok to me. Without above change, find_next_zero_area cannot
>> find a 64 bits zeroed area in next sample code.
>
> I meant that we don't want to find such area for IOMMUs (IIRC, it code
> came from POWER IOMMU).

OK, I see.  I think we need the comment about it.

So we cannot replace find_next_zero_area by bitmap_find_next_zero_area
and current -mmotm has the bug introduced by this patch in iommu-helper
and I also introduced the bug in bitmap_find_next_zero_area if
align_mask != 0 in
bitmap-introduce-bitmap_set-bitmap_clear-bitmap_find_next_zero_area-fix.patch

Andrew, please drop

lib-iommu-helperc-fix-off-by-one-error-in-find_next_zero_area.patch
iommu-helper-simplify-find_next_zero_area.patch
bitmap-introduce-bitmap_set-bitmap_clear-bitmap_find_next_zero_area.patch
bitmap-introduce-bitmap_set-bitmap_clear-bitmap_find_next_zero_area-fix.patch
iommu-helper-use-bitmap-library.patch
isp1362-hcd-use-bitmap_find_next_zero_area.patch
mlx4-use-bitmap_find_next_zero_area.patch
sparc-use-bitmap_find_next_zero_area.patch
ia64-use-bitmap_find_next_zero_area.patch
genalloc-use-bitmap_find_next_zero_area.patch

I'll overhaul the patchset and retry again.
___
Linuxppc-dev mailing list
Linuxppc-dev@lists.ozlabs.org
https://lists.ozlabs.org/listinfo/linuxppc-dev


Re: [PATCH 2/8] bitmap: Introduce bitmap_set, bitmap_clear, bitmap_find_next_zero_area

2009-10-17 Thread Akinobu Mita
2009/10/17 FUJITA Tomonori :
> On Tue, 13 Oct 2009 18:10:17 +0900
> Akinobu Mita  wrote:
>
>> My user space testing exposed off-by-one error find_next_zero_area
>> in iommu-helper. Some zero area cannot be found by this bug.
>>
>> Subject: [PATCH] Fix off-by-one error in find_next_zero_area
>>
>> Signed-off-by: Akinobu Mita 
>> ---
>>  lib/iommu-helper.c |    2 +-
>>  1 files changed, 1 insertions(+), 1 deletions(-)
>>
>> diff --git a/lib/iommu-helper.c b/lib/iommu-helper.c
>> index 75dbda0..afc58bc 100644
>> --- a/lib/iommu-helper.c
>> +++ b/lib/iommu-helper.c
>> @@ -19,7 +19,7 @@ again:
>>       index = (index + align_mask) & ~align_mask;
>>
>>       end = index + nr;
>> -     if (end >= size)
>> +     if (end > size)
>
> I think that this is intentional; the last byte of the limit doesn't
> work.

It looks ok to me. Without above change, find_next_zero_area cannot
find a 64 bits zeroed area in next sample code.

unsigned long offset;

DECLARE_BITMAP(map, 64);

bitmap_clear(map, 0, 64);
offset = find_next_zero_area(map, 64, 0, 64, 0);
if (offset >= 64)
printf("not found\n");
else
printf("found\n");
___
Linuxppc-dev mailing list
Linuxppc-dev@lists.ozlabs.org
https://lists.ozlabs.org/listinfo/linuxppc-dev


[PATCH -mmotm -v2] Fix bitmap-introduce-bitmap_set-bitmap_clear-bitmap_find_next_zero_area. patch

2009-10-14 Thread Akinobu Mita
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;
-- 
1.5.4.3

___
Linuxppc-dev mailing list
Linuxppc-dev@lists.ozlabs.org
https://lists.ozlabs.org/listinfo/linuxppc-dev


Re: [PATCH 2/8] bitmap: Introduce bitmap_set, bitmap_clear, bitmap_find_next_zero_area

2009-10-13 Thread Akinobu Mita
On Wed, Oct 14, 2009 at 08:54:47AM +1100, Michael Ellerman wrote:
> On Tue, 2009-10-13 at 18:10 +0900, Akinobu Mita wrote:
> > My user space testing exposed off-by-one error find_next_zero_area
> > in iommu-helper.
> 
> Why not merge those tests into the kernel as a configurable boot-time
> self-test?

I send the test program that I used. Obviously it needs
better diagnostic messages and cleanup to be added into kernel tests.

#include 
#include 
#include 
#include 

#if 1 /* Copy and paste from kernel source */

#define BITS_PER_BYTE  8
#define BITS_PER_LONG (sizeof(long) * BITS_PER_BYTE)

#define BIT_WORD(nr)((nr) / BITS_PER_LONG)
#define BITOP_WORD(nr)  ((nr) / BITS_PER_LONG)

#define BITMAP_LAST_WORD_MASK(nbits)\
(   \
((nbits) % BITS_PER_LONG) ? \
(1UL<<((nbits) % BITS_PER_LONG))-1 : ~0UL   \
)

#define BITMAP_FIRST_WORD_MASK(start) (~0UL << ((start) % BITS_PER_LONG))

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;
}
}

void bitmap_clear(unsigned long *map, int start, int nr)
{
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;
}
}

static unsigned long __ffs(unsigned long word)
{
int num = 0;

if ((word & 0x) == 0) {
num += 16;
word >>= 16;
}
if ((word & 0xff) == 0) {
num += 8;
word >>= 8;
}
if ((word & 0xf) == 0) {
num += 4;
word >>= 4;
}
if ((word & 0x3) == 0) {
num += 2;
word >>= 2;
}
if ((word & 0x1) == 0)
num += 1;
return num;
}

unsigned long find_next_bit(const unsigned long *addr, unsigned long size,
unsigned long offset)
{
const unsigned long *p = addr + BITOP_WORD(offset);
unsigned long result = offset & ~(BITS_PER_LONG-1);
unsigned long tmp;

if (offset >= size)
return size;
size -= result;
offset %= BITS_PER_LONG;
if (offset) {
tmp = *(p++);
tmp &= (~0UL << offset);
if (size < BITS_PER_LONG)
goto found_first;
if (tmp)
goto found_middle;
size -= BITS_PER_LONG;
result += BITS_PER_LONG;
}
while (size & ~(BITS_PER_LONG-1)) {
if ((tmp = *(p++)))
goto found_middle;
result += BITS_PER_LONG;
size -= BITS_PER_LONG;
}
if (!size)
return result;
tmp = *p;

found_first:
tmp &= (~0UL >> (BITS_PER_LONG - size));
if (tmp == 0UL) /* Are any bits set? */
return result + size;   /* Nope. */
found_middle:
return result + __ffs(tmp);
}

#define ffz(x)  __ffs(~(x))

unsigned long find_next_zero_bit(const unsigned long *addr, unsigned long size,
 unsigned long offset)
{
const unsigned long *p = addr + BITOP_WORD(offset);
unsigned long result = offset & ~(BITS_PER_LONG-1);
unsigned long tmp;

if (offset >= size)
return size;
size -= result;
offset %= BITS_PER_LONG;
if (offset) {
tmp = *(p++);
tmp |= ~0UL >> (BITS_PER_LONG - offset);
if (size < BITS_PER_LONG)
goto found_first;
if (~tmp)
goto found_middle;
 

[PATCH -mmotm] Fix bitmap-introduce-bitmap_set-bitmap_clear-bitmap_find_next_zero_area. patch

2009-10-13 Thread Akinobu Mita
Update PATCH 2/8 based on review comments by Andrew and bugfix
exposed by user space testing.

I didn't change argument of align_mask at this time because it
turned out that it needs more changes in iommu-helper users.

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 error 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

Signed-off-by: Akinobu Mita 
---
 lib/bitmap.c |   60 +
 1 files changed, 47 insertions(+), 13 deletions(-)

diff --git a/lib/bitmap.c b/lib/bitmap.c
index 2415da4..84292c9 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,10 +338,10 @@ 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);
if (i < end) {
-- 
1.5.4.3

___
Linuxppc-dev mailing list
Linuxppc-dev@lists.ozlabs.org
https://lists.ozlabs.org/listinfo/linuxppc-dev


Re: [PATCH 2/8] bitmap: Introduce bitmap_set, bitmap_clear, bitmap_find_next_zero_area

2009-10-13 Thread Akinobu Mita
My user space testing exposed off-by-one error find_next_zero_area
in iommu-helper. Some zero area cannot be found by this bug.

Subject: [PATCH] Fix off-by-one error in find_next_zero_area

Signed-off-by: Akinobu Mita 
---
 lib/iommu-helper.c |2 +-
 1 files changed, 1 insertions(+), 1 deletions(-)

diff --git a/lib/iommu-helper.c b/lib/iommu-helper.c
index 75dbda0..afc58bc 100644
--- a/lib/iommu-helper.c
+++ b/lib/iommu-helper.c
@@ -19,7 +19,7 @@ again:
index = (index + align_mask) & ~align_mask;
 
end = index + nr;
-   if (end >= size)
+   if (end > size)
return -1;
for (i = index; i < end; i++) {
if (test_bit(i, map)) {
-- 
1.5.4.3

___
Linuxppc-dev mailing list
Linuxppc-dev@lists.ozlabs.org
https://lists.ozlabs.org/listinfo/linuxppc-dev


Re: [PATCH 2/8] bitmap: Introduce bitmap_set, bitmap_clear, bitmap_find_next_zero_area

2009-10-12 Thread Akinobu Mita
On Fri, Oct 09, 2009 at 04:41:00PM -0700, Andrew Morton wrote:
> On Fri,  9 Oct 2009 17:29:15 +0900
> Akinobu Mita  wrote:
> 
> > This introduces new bitmap functions:
> > 
> > bitmap_set: Set specified bit area
> > bitmap_clear: Clear specified bit area
> > bitmap_find_next_zero_area: Find free bit area
> > 
> > These are stolen from iommu helper.
> > 
> > I changed the return value of bitmap_find_next_zero_area if there is
> > no zero area.
> > 
> > find_next_zero_area in iommu helper: returns -1
> > bitmap_find_next_zero_area: return >= bitmap size
> 
> I'll plan to merge this patch into 2.6.32 so we can trickle all the
> other patches into subsystems in an orderly fashion.

Sounds good.

> > +void bitmap_set(unsigned long *map, int i, int len)
> > +{
> > +   int end = i + len;
> > +
> > +   while (i < end) {
> > +   __set_bit(i, map);
> > +   i++;
> > +   }
> > +}
> 
> This is really inefficient, isn't it?  It's a pretty trivial matter to
> romp through memory 32 or 64 bits at a time.

OK. I'll do

> > +unsigned long bitmap_find_next_zero_area(unsigned long *map,
> > +unsigned long size,
> > +unsigned long start,
> > +unsigned int nr,
> > +unsigned long align_mask)
> > +{
> > +   unsigned long index, end, i;
> > +again:
> > +   index = find_next_zero_bit(map, size, start);
> > +
> > +   /* Align allocation */
> > +   index = (index + align_mask) & ~align_mask;
> > +
> > +   end = index + nr;
> > +   if (end >= size)
> > +   return end;
> > +   i = find_next_bit(map, end, index);
> > +   if (i < end) {
> > +   start = i + 1;
> > +   goto again;
> > +   }
> > +   return index;
> > +}
> > +EXPORT_SYMBOL(bitmap_find_next_zero_area);
> 
> This needs documentation, please.  It appears that `size' is the size
> of the bitmap and `nr' is the number of zeroed bits we're looking for,
> but an inattentive programmer could get those reversed.
> 
> Also the semantics of `align_mask' could benefit from spelling out.  Is
> the alignment with respect to memory boundaries or with respect to
> `map' or with respect to map+start or what?

OK. I will document it.

And I plan to change bitmap_find_next_zero_area() to take the alignment
instead of an align_mask as Roland said.

> And why does align_mask exist at all?  I was a bit surprised to see it
> there.  In which scenarios will it be non-zero?

Because the users of iommu-helper and mlx4 need the alignment requirement
for the zero area.

arch/powerpc/kernel/iommu.c
arch/x86/kernel/amd_iommu.c
arch/x86/kernel/pci-gart_64.c
drivers/net/mlx4/alloc.c

___
Linuxppc-dev mailing list
Linuxppc-dev@lists.ozlabs.org
https://lists.ozlabs.org/listinfo/linuxppc-dev


[PATCH 3/8] iommu-helper: Use bitmap library

2009-10-09 Thread Akinobu Mita
Use bitmap library and kill some unused iommu helper functions.

Cc: "David S. Miller" 
Cc: sparcli...@vger.kernel.org
Cc: Benjamin Herrenschmidt 
Cc: Paul Mackerras 
Cc: linuxppc-...@ozlabs.org
Cc: Thomas Gleixner 
Cc: Ingo Molnar 
Cc: "H. Peter Anvin" 
Cc: x...@kernel.org
Cc: FUJITA Tomonori 
Signed-off-by: Akinobu Mita 
---
 arch/powerpc/kernel/iommu.c  |4 +-
 arch/sparc/kernel/iommu.c|3 +-
 arch/x86/kernel/amd_iommu.c  |4 +-
 arch/x86/kernel/pci-calgary_64.c |6 ++--
 arch/x86/kernel/pci-gart_64.c|6 ++--
 include/linux/iommu-helper.h |3 --
 lib/iommu-helper.c   |   55 -
 7 files changed, 18 insertions(+), 63 deletions(-)

diff --git a/arch/powerpc/kernel/iommu.c b/arch/powerpc/kernel/iommu.c
index fd51578..5547ae6 100644
--- a/arch/powerpc/kernel/iommu.c
+++ b/arch/powerpc/kernel/iommu.c
@@ -30,7 +30,7 @@
 #include 
 #include 
 #include 
-#include 
+#include 
 #include 
 #include 
 #include 
@@ -251,7 +251,7 @@ static void __iommu_free(struct iommu_table *tbl, 
dma_addr_t dma_addr,
}
 
ppc_md.tce_free(tbl, entry, npages);
-   iommu_area_free(tbl->it_map, free_entry, npages);
+   bitmap_clear(tbl->it_map, free_entry, npages);
 }
 
 static void iommu_free(struct iommu_table *tbl, dma_addr_t dma_addr,
diff --git a/arch/sparc/kernel/iommu.c b/arch/sparc/kernel/iommu.c
index 7690cc2..5fad949 100644
--- a/arch/sparc/kernel/iommu.c
+++ b/arch/sparc/kernel/iommu.c
@@ -11,6 +11,7 @@
 #include 
 #include 
 #include 
+#include 
 
 #ifdef CONFIG_PCI
 #include 
@@ -169,7 +170,7 @@ void iommu_range_free(struct iommu *iommu, dma_addr_t 
dma_addr, unsigned long np
 
entry = (dma_addr - iommu->page_table_map_base) >> IO_PAGE_SHIFT;
 
-   iommu_area_free(arena->map, entry, npages);
+   bitmap_clear(arena->map, entry, npages);
 }
 
 int iommu_table_init(struct iommu *iommu, int tsbsize,
diff --git a/arch/x86/kernel/amd_iommu.c b/arch/x86/kernel/amd_iommu.c
index 98f230f..08b1d20 100644
--- a/arch/x86/kernel/amd_iommu.c
+++ b/arch/x86/kernel/amd_iommu.c
@@ -19,7 +19,7 @@
 
 #include 
 #include 
-#include 
+#include 
 #include 
 #include 
 #include 
@@ -959,7 +959,7 @@ static void dma_ops_free_addresses(struct dma_ops_domain 
*dom,
 
address = (address % APERTURE_RANGE_SIZE) >> PAGE_SHIFT;
 
-   iommu_area_free(range->bitmap, address, pages);
+   bitmap_clear(range->bitmap, address, pages);
 
 }
 
diff --git a/arch/x86/kernel/pci-calgary_64.c b/arch/x86/kernel/pci-calgary_64.c
index 971a3be..c87bb20 100644
--- a/arch/x86/kernel/pci-calgary_64.c
+++ b/arch/x86/kernel/pci-calgary_64.c
@@ -31,7 +31,7 @@
 #include 
 #include 
 #include 
-#include 
+#include 
 #include 
 #include 
 #include 
@@ -211,7 +211,7 @@ static void iommu_range_reserve(struct iommu_table *tbl,
 
spin_lock_irqsave(&tbl->it_lock, flags);
 
-   iommu_area_reserve(tbl->it_map, index, npages);
+   bitmap_set(tbl->it_map, index, npages);
 
spin_unlock_irqrestore(&tbl->it_lock, flags);
 }
@@ -305,7 +305,7 @@ static void iommu_free(struct iommu_table *tbl, dma_addr_t 
dma_addr,
 
spin_lock_irqsave(&tbl->it_lock, flags);
 
-   iommu_area_free(tbl->it_map, entry, npages);
+   bitmap_clear(tbl->it_map, entry, npages);
 
spin_unlock_irqrestore(&tbl->it_lock, flags);
 }
diff --git a/arch/x86/kernel/pci-gart_64.c b/arch/x86/kernel/pci-gart_64.c
index 98a827e..3010cd1 100644
--- a/arch/x86/kernel/pci-gart_64.c
+++ b/arch/x86/kernel/pci-gart_64.c
@@ -22,7 +22,7 @@
 #include 
 #include 
 #include 
-#include 
+#include 
 #include 
 #include 
 #include 
@@ -122,7 +122,7 @@ static void free_iommu(unsigned long offset, int size)
unsigned long flags;
 
spin_lock_irqsave(&iommu_bitmap_lock, flags);
-   iommu_area_free(iommu_gart_bitmap, offset, size);
+   bitmap_clear(iommu_gart_bitmap, offset, size);
if (offset >= next_bit)
next_bit = offset + size;
spin_unlock_irqrestore(&iommu_bitmap_lock, flags);
@@ -781,7 +781,7 @@ void __init gart_iommu_init(void)
 * Out of IOMMU space handling.
 * Reserve some invalid pages at the beginning of the GART.
 */
-   iommu_area_reserve(iommu_gart_bitmap, 0, EMERGENCY_PAGES);
+   bitmap_set(iommu_gart_bitmap, 0, EMERGENCY_PAGES);
 
agp_memory_reserved = iommu_size;
printk(KERN_INFO
diff --git a/include/linux/iommu-helper.h b/include/linux/iommu-helper.h
index 3b068e5..64d1b63 100644
--- a/include/linux/iommu-helper.h
+++ b/include/linux/iommu-helper.h
@@ -14,14 +14,11 @@ static inline unsigned long iommu_device_max_index(unsigned 
long size,
 extern int iommu_is_span_boundary(unsigned int index, unsigned int nr,
  unsigned long shift,
  unsigned long boundary_size);
-extern void 

[PATCH 2/8] bitmap: Introduce bitmap_set, bitmap_clear, bitmap_find_next_zero_area

2009-10-09 Thread Akinobu Mita
This introduces new bitmap functions:

bitmap_set: Set specified bit area
bitmap_clear: Clear specified bit area
bitmap_find_next_zero_area: Find free bit area

These are stolen from iommu helper.

I changed the return value of bitmap_find_next_zero_area if there is
no zero area.

find_next_zero_area in iommu helper: returns -1
bitmap_find_next_zero_area: return >= bitmap size

Cc: FUJITA Tomonori 
Cc: "David S. Miller" 
Cc: sparcli...@vger.kernel.org
Cc: Benjamin Herrenschmidt 
Cc: Paul Mackerras 
Cc: linuxppc-...@ozlabs.org
Cc: Thomas Gleixner 
Cc: Ingo Molnar 
Cc: "H. Peter Anvin" 
Cc: x...@kernel.org
Cc: Greg Kroah-Hartman 
Cc: Lothar Wassmann 
Cc: linux-...@vger.kernel.org
Cc: Roland Dreier 
Cc: Yevgeny Petrilin 
Cc: net...@vger.kernel.org
Cc: Tony Luck 
Cc: Fenghua Yu 
Cc: linux-i...@vger.kernel.org
Cc: linux-al...@sgi.com
Signed-off-by: Akinobu Mita 
---
 include/linux/bitmap.h |   11 +++
 lib/bitmap.c   |   47 +++
 2 files changed, 58 insertions(+), 0 deletions(-)

diff --git a/include/linux/bitmap.h b/include/linux/bitmap.h
index 756d78b..daf8c48 100644
--- a/include/linux/bitmap.h
+++ b/include/linux/bitmap.h
@@ -42,6 +42,9 @@
  * bitmap_empty(src, nbits)Are all bits zero in *src?
  * bitmap_full(src, nbits) Are all bits set in *src?
  * bitmap_weight(src, nbits)   Hamming Weight: number set bits
+ * bitmap_set(dst, pos, nbits) Set specified bit area
+ * bitmap_clear(dst, pos, nbits)   Clear specified bit area
+ * bitmap_find_next_zero_area(buf, len, pos, n, mask)  Find bit free area
  * bitmap_shift_right(dst, src, n, nbits)  *dst = *src >> n
  * bitmap_shift_left(dst, src, n, nbits)   *dst = *src << n
  * bitmap_remap(dst, src, old, new, nbits) *dst = map(old, new)(src)
@@ -108,6 +111,14 @@ extern int __bitmap_subset(const unsigned long *bitmap1,
const unsigned long *bitmap2, int bits);
 extern int __bitmap_weight(const unsigned long *bitmap, int bits);
 
+extern void bitmap_set(unsigned long *map, int i, int len);
+extern void bitmap_clear(unsigned long *map, int start, int nr);
+extern unsigned long bitmap_find_next_zero_area(unsigned long *map,
+unsigned long size,
+unsigned long start,
+unsigned int nr,
+unsigned long align_mask);
+
 extern int bitmap_scnprintf(char *buf, unsigned int len,
const unsigned long *src, int nbits);
 extern int __bitmap_parse(const char *buf, unsigned int buflen, int is_user,
diff --git a/lib/bitmap.c b/lib/bitmap.c
index 7025658..95070fa 100644
--- a/lib/bitmap.c
+++ b/lib/bitmap.c
@@ -271,6 +271,53 @@ 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;
+
+   while (i < end) {
+   __set_bit(i, map);
+   i++;
+   }
+}
+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++;
+   }
+}
+EXPORT_SYMBOL(bitmap_clear);
+
+unsigned long bitmap_find_next_zero_area(unsigned long *map,
+unsigned long size,
+unsigned long start,
+unsigned int nr,
+unsigned long align_mask)
+{
+   unsigned long index, end, i;
+again:
+   index = find_next_zero_bit(map, size, start);
+
+   /* Align allocation */
+   index = (index + align_mask) & ~align_mask;
+
+   end = index + nr;
+   if (end >= size)
+   return end;
+   i = find_next_bit(map, end, index);
+   if (i < end) {
+   start = i + 1;
+   goto again;
+   }
+   return index;
+}
+EXPORT_SYMBOL(bitmap_find_next_zero_area);
+
 /*
  * Bitmap printing & parsing functions: first version by Bill Irwin,
  * second version by Paul Jackson, third by Joe Korty.
-- 
1.5.4.3

___
Linuxppc-dev mailing list
Linuxppc-dev@lists.ozlabs.org
https://lists.ozlabs.org/listinfo/linuxppc-dev


Re: [PATCH v2] Fix highmem build failure

2009-04-02 Thread Akinobu Mita
Looks good. I tested it on x86_32.
___
Linuxppc-dev mailing list
Linuxppc-dev@ozlabs.org
https://ozlabs.org/mailman/listinfo/linuxppc-dev


Re: [PATCH] Fix highmem build failure

2009-04-01 Thread Akinobu Mita
On Wed, Apr 01, 2009 at 04:33:31PM -0500, Kumar Gala wrote:
> The following commit breaks PPC builds with CONFIG_HIGHMEM=y
> 
> commit f4112de6b679d84bd9b9681c7504be7bdfb7c7d5
> Author: Akinobu Mita 
> Date:   Tue Mar 31 15:23:25 2009 -0700
> 
> mm: introduce debug_kmap_atomic
> 

Thanks.
But the definition of debug_kmap_atomic() needs to be outside of
ifdef CONFIG_HIGHMEM. Because debug_kmap_atomic() is used without
CONFIG_HIGHMEM by kmap_atomic_prot_pfn() in arch/x86/mm/iomap_32.c

> --- a/include/linux/highmem.h
> +++ b/include/linux/highmem.h
> @@ -20,6 +20,19 @@ static inline void flush_kernel_dcache_page(struct page 
> *page)
>  #endif
>  
>  #ifdef CONFIG_HIGHMEM
> +#include 
> +
> +#if defined(CONFIG_DEBUG_HIGHMEM) && defined(CONFIG_TRACE_IRQFLAGS_SUPPORT)
> +
> +void debug_kmap_atomic(enum km_type type);
> +
> +#else
> +
> +static inline void debug_kmap_atomic(enum km_type type)
> +{
> +}
> +
> +#endif
>  
>  #include 
>  
___
Linuxppc-dev mailing list
Linuxppc-dev@ozlabs.org
https://ozlabs.org/mailman/listinfo/linuxppc-dev


Re: [PATCH 1/2] eHEA: Capability flag for DLPAR support

2007-07-04 Thread Akinobu Mita
2007/7/4, Jan-Bernd Themann <[EMAIL PROTECTED]>:

> diff --git a/drivers/net/ehea/ehea_main.c b/drivers/net/ehea/ehea_main.c
> index bdb5241..f8c0908 100644
> --- a/drivers/net/ehea/ehea_main.c
> +++ b/drivers/net/ehea/ehea_main.c
> @@ -2923,6 +2923,15 @@ static int check_module_parm(void)
> return ret;
>  }
>
> +static ssize_t ehea_show_capabilities(struct device_driver *drv,
> + char *buf)
> +{
> +   return sprintf(buf, "%d", EHEA_CAPABILITIES);
> +}
> +
> +static DRIVER_ATTR(capabilities, S_IRUSR | S_IRGRP | S_IROTH,
> +  ehea_show_capabilities, NULL);
> +
>  int __init ehea_module_init(void)
>  {
> int ret;
> @@ -2937,12 +2946,20 @@ int __init ehea_module_init(void)
> if (ret)
> ehea_error("failed registering eHEA device driver on ebus");
>

You forgot to put:
return ret;
or
goto out;

> +   ret = driver_create_file(&ehea_driver.driver, 
> &driver_attr_capabilities);
> +   if (ret) {
> +   ehea_error("failed to register capabilities attribute, 
> ret=%d", ret);
> +   ibmebus_unregister_driver(&ehea_driver);
> +   goto out;
> +   }
> +
>  out:
> return ret;
>  }
>
___
Linuxppc-dev mailing list
Linuxppc-dev@ozlabs.org
https://ozlabs.org/mailman/listinfo/linuxppc-dev