powerpc: Wire up /proc/vmallocinfo to our ioremap()
authorBenjamin Herrenschmidt <benh@kernel.crashing.org>
Sun, 22 Feb 2009 16:19:14 +0000 (16:19 +0000)
committerBenjamin Herrenschmidt <benh@kernel.crashing.org>
Wed, 11 Mar 2009 06:10:14 +0000 (17:10 +1100)
This adds the necessary bits and pieces to powerpc implementation of
ioremap to benefit from caller tracking in /proc/vmallocinfo, at least
for ioremap's done after mem init as the older ones aren't tracked.

Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
arch/powerpc/include/asm/io.h
arch/powerpc/include/asm/machdep.h
arch/powerpc/mm/pgtable_32.c
arch/powerpc/mm/pgtable_64.c
arch/powerpc/platforms/cell/io-workarounds.c
arch/powerpc/platforms/iseries/setup.c

index 494cd8b0a278a8b8299f149cd765505513c6b3bb..001f2f11c19bbf9f1cfaa1f0e417986eacdb80f5 100644 (file)
@@ -632,6 +632,9 @@ static inline void iosync(void)
  *   ioremap_flags and cannot be hooked (but can be used by a hook on one
  *   of the previous ones)
  *
+ * * __ioremap_caller is the same as above but takes an explicit caller
+ *   reference rather than using __builtin_return_address(0)
+ *
  * * __iounmap, is the low level implementation used by iounmap and cannot
  *   be hooked (but can be used by a hook on iounmap)
  *
@@ -646,6 +649,9 @@ extern void iounmap(volatile void __iomem *addr);
 
 extern void __iomem *__ioremap(phys_addr_t, unsigned long size,
                               unsigned long flags);
+extern void __iomem *__ioremap_caller(phys_addr_t, unsigned long size,
+                                     unsigned long flags, void *caller);
+
 extern void __iounmap(volatile void __iomem *addr);
 
 extern void __iomem * __ioremap_at(phys_addr_t pa, void *ea,
index 6c34a0df82fd370edcbaa05f6036e7e81b495b79..0efdb1dfdc5f577ea336d4a96fd8dd246d703514 100644 (file)
@@ -90,7 +90,7 @@ struct machdep_calls {
        void            (*tce_flush)(struct iommu_table *tbl);
 
        void __iomem *  (*ioremap)(phys_addr_t addr, unsigned long size,
-                                  unsigned long flags);
+                                  unsigned long flags, void *caller);
        void            (*iounmap)(volatile void __iomem *token);
 
 #ifdef CONFIG_PM
index 58bcaeba728d6b6a57355f1736d8737e6f0bbd3b..0f8c4371dfab0bfaa699c79b3230d4dfd1a7fe81 100644 (file)
@@ -129,7 +129,8 @@ pgtable_t pte_alloc_one(struct mm_struct *mm, unsigned long address)
 void __iomem *
 ioremap(phys_addr_t addr, unsigned long size)
 {
-       return __ioremap(addr, size, _PAGE_NO_CACHE | _PAGE_GUARDED);
+       return __ioremap_caller(addr, size, _PAGE_NO_CACHE | _PAGE_GUARDED,
+                               __builtin_return_address(0));
 }
 EXPORT_SYMBOL(ioremap);
 
@@ -143,12 +144,19 @@ ioremap_flags(phys_addr_t addr, unsigned long size, unsigned long flags)
        /* we don't want to let _PAGE_USER and _PAGE_EXEC leak out */
        flags &= ~(_PAGE_USER | _PAGE_EXEC | _PAGE_HWEXEC);
 
-       return __ioremap(addr, size, flags);
+       return __ioremap_caller(addr, size, flags, __builtin_return_address(0));
 }
 EXPORT_SYMBOL(ioremap_flags);
 
 void __iomem *
 __ioremap(phys_addr_t addr, unsigned long size, unsigned long flags)
+{
+       return __ioremap_caller(addr, size, flags, __builtin_return_address(0));
+}
+
+void __iomem *
+__ioremap_caller(phys_addr_t addr, unsigned long size, unsigned long flags,
+                void *caller)
 {
        unsigned long v, i;
        phys_addr_t p;
@@ -212,7 +220,7 @@ __ioremap(phys_addr_t addr, unsigned long size, unsigned long flags)
 
        if (mem_init_done) {
                struct vm_struct *area;
-               area = get_vm_area(size, VM_IOREMAP);
+               area = get_vm_area_caller(size, VM_IOREMAP, caller);
                if (area == 0)
                        return NULL;
                v = (unsigned long) area->addr;
index 365e61ae5dbcf54f7f4789d2cfed5bb7072201e3..bfa7db6b2fd5446e193669a1afd02d09f7f9aab9 100644 (file)
@@ -144,8 +144,8 @@ void __iounmap_at(void *ea, unsigned long size)
        unmap_kernel_range((unsigned long)ea, size);
 }
 
-void __iomem * __ioremap(phys_addr_t addr, unsigned long size,
-                        unsigned long flags)
+void __iomem * __ioremap_caller(phys_addr_t addr, unsigned long size,
+                               unsigned long flags, void *caller)
 {
        phys_addr_t paligned;
        void __iomem *ret;
@@ -168,8 +168,9 @@ void __iomem * __ioremap(phys_addr_t addr, unsigned long size,
        if (mem_init_done) {
                struct vm_struct *area;
 
-               area = __get_vm_area(size, VM_IOREMAP,
-                                    ioremap_bot, IOREMAP_END);
+               area = __get_vm_area_caller(size, VM_IOREMAP,
+                                           ioremap_bot, IOREMAP_END,
+                                           caller);
                if (area == NULL)
                        return NULL;
                ret = __ioremap_at(paligned, area->addr, size, flags);
@@ -186,19 +187,27 @@ void __iomem * __ioremap(phys_addr_t addr, unsigned long size,
        return ret;
 }
 
+void __iomem * __ioremap(phys_addr_t addr, unsigned long size,
+                        unsigned long flags)
+{
+       return __ioremap_caller(addr, size, flags, __builtin_return_address(0));
+}
 
 void __iomem * ioremap(phys_addr_t addr, unsigned long size)
 {
        unsigned long flags = _PAGE_NO_CACHE | _PAGE_GUARDED;
+       void *caller = __builtin_return_address(0);
 
        if (ppc_md.ioremap)
-               return ppc_md.ioremap(addr, size, flags);
-       return __ioremap(addr, size, flags);
+               return ppc_md.ioremap(addr, size, flags, caller);
+       return __ioremap_caller(addr, size, flags, caller);
 }
 
 void __iomem * ioremap_flags(phys_addr_t addr, unsigned long size,
                             unsigned long flags)
 {
+       void *caller = __builtin_return_address(0);
+
        /* writeable implies dirty for kernel addresses */
        if (flags & _PAGE_RW)
                flags |= _PAGE_DIRTY;
@@ -207,8 +216,8 @@ void __iomem * ioremap_flags(phys_addr_t addr, unsigned long size,
        flags &= ~(_PAGE_USER | _PAGE_EXEC);
 
        if (ppc_md.ioremap)
-               return ppc_md.ioremap(addr, size, flags);
-       return __ioremap(addr, size, flags);
+               return ppc_md.ioremap(addr, size, flags, caller);
+       return __ioremap_caller(addr, size, flags, caller);
 }
 
 
index 059cad6c3f694864901ce067d2409fc33ce6d6f8..5c1118e31940bf39d3a88926a16fc883c4f30d5f 100644 (file)
@@ -131,10 +131,10 @@ static const struct ppc_pci_io __devinitconst iowa_pci_io = {
 };
 
 static void __iomem *iowa_ioremap(phys_addr_t addr, unsigned long size,
-                                               unsigned long flags)
+                                 unsigned long flags, void *caller)
 {
        struct iowa_bus *bus;
-       void __iomem *res = __ioremap(addr, size, flags);
+       void __iomem *res = __ioremap_caller(addr, size, flags, caller);
        int busno;
 
        bus = iowa_pci_find(0, (unsigned long)addr);
index 24519b96d6ad07b22bf1d64cd419fb603076aa61..a6cd3394feaa4d5baa313a51475209ae0382cd98 100644 (file)
@@ -617,7 +617,7 @@ static void iseries_dedicated_idle(void)
 }
 
 static void __iomem *iseries_ioremap(phys_addr_t address, unsigned long size,
-                                    unsigned long flags)
+                                    unsigned long flags, void *caller)
 {
        return (void __iomem *)address;
 }