Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 297576
b: refs/heads/master
c: 45cd529
h: refs/heads/master
v: v3
  • Loading branch information
Russell King committed Jan 23, 2012
1 parent 7fe0bd8 commit 498539b
Show file tree
Hide file tree
Showing 4 changed files with 93 additions and 10 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: 6bebb572404f96d367170fb263603cda7251f932
refs/heads/master: 45cd5290bfd358e9885c0bf47a8c46671a92f716
20 changes: 13 additions & 7 deletions trunk/arch/arm/mm/dma-mapping.c
Original file line number Diff line number Diff line change
Expand Up @@ -214,7 +214,8 @@ static int __init consistent_init(void)
core_initcall(consistent_init);

static void *
__dma_alloc_remap(struct page *page, size_t size, gfp_t gfp, pgprot_t prot)
__dma_alloc_remap(struct page *page, size_t size, gfp_t gfp, pgprot_t prot,
const void *caller)
{
struct arm_vmregion *c;
size_t align;
Expand All @@ -241,7 +242,7 @@ __dma_alloc_remap(struct page *page, size_t size, gfp_t gfp, pgprot_t prot)
* Allocate a virtual address in the consistent mapping region.
*/
c = arm_vmregion_alloc(&consistent_head, align, size,
gfp & ~(__GFP_DMA | __GFP_HIGHMEM));
gfp & ~(__GFP_DMA | __GFP_HIGHMEM), caller);
if (c) {
pte_t *pte;
int idx = CONSISTENT_PTE_INDEX(c->vm_start);
Expand Down Expand Up @@ -320,14 +321,14 @@ static void __dma_free_remap(void *cpu_addr, size_t size)

#else /* !CONFIG_MMU */

#define __dma_alloc_remap(page, size, gfp, prot) page_address(page)
#define __dma_alloc_remap(page, size, gfp, prot, c) page_address(page)
#define __dma_free_remap(addr, size) do { } while (0)

#endif /* CONFIG_MMU */

static void *
__dma_alloc(struct device *dev, size_t size, dma_addr_t *handle, gfp_t gfp,
pgprot_t prot)
pgprot_t prot, const void *caller)
{
struct page *page;
void *addr;
Expand All @@ -349,7 +350,7 @@ __dma_alloc(struct device *dev, size_t size, dma_addr_t *handle, gfp_t gfp,
return NULL;

if (!arch_is_coherent())
addr = __dma_alloc_remap(page, size, gfp, prot);
addr = __dma_alloc_remap(page, size, gfp, prot, caller);
else
addr = page_address(page);

Expand All @@ -374,7 +375,8 @@ dma_alloc_coherent(struct device *dev, size_t size, dma_addr_t *handle, gfp_t gf
return memory;

return __dma_alloc(dev, size, handle, gfp,
pgprot_dmacoherent(pgprot_kernel));
pgprot_dmacoherent(pgprot_kernel),
__builtin_return_address(0));
}
EXPORT_SYMBOL(dma_alloc_coherent);

Expand All @@ -386,7 +388,8 @@ void *
dma_alloc_writecombine(struct device *dev, size_t size, dma_addr_t *handle, gfp_t gfp)
{
return __dma_alloc(dev, size, handle, gfp,
pgprot_writecombine(pgprot_kernel));
pgprot_writecombine(pgprot_kernel),
__builtin_return_address(0));
}
EXPORT_SYMBOL(dma_alloc_writecombine);

Expand Down Expand Up @@ -723,6 +726,9 @@ EXPORT_SYMBOL(dma_set_mask);

static int __init dma_debug_do_init(void)
{
#ifdef CONFIG_MMU
arm_vmregion_create_proc("dma-mappings", &consistent_head);
#endif
dma_debug_init(PREALLOC_DMA_DEBUG_ENTRIES);
return 0;
}
Expand Down
76 changes: 75 additions & 1 deletion trunk/arch/arm/mm/vmregion.c
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
#include <linux/fs.h>
#include <linux/spinlock.h>
#include <linux/list.h>
#include <linux/proc_fs.h>
#include <linux/seq_file.h>
#include <linux/slab.h>

#include "vmregion.h"
Expand Down Expand Up @@ -36,7 +39,7 @@

struct arm_vmregion *
arm_vmregion_alloc(struct arm_vmregion_head *head, size_t align,
size_t size, gfp_t gfp)
size_t size, gfp_t gfp, const void *caller)
{
unsigned long start = head->vm_start, addr = head->vm_end;
unsigned long flags;
Expand All @@ -52,6 +55,8 @@ arm_vmregion_alloc(struct arm_vmregion_head *head, size_t align,
if (!new)
goto out;

new->caller = caller;

spin_lock_irqsave(&head->vm_lock, flags);

addr = rounddown(addr - size, align);
Expand Down Expand Up @@ -129,3 +134,72 @@ void arm_vmregion_free(struct arm_vmregion_head *head, struct arm_vmregion *c)

kfree(c);
}

#ifdef CONFIG_PROC_FS
static int arm_vmregion_show(struct seq_file *m, void *p)
{
struct arm_vmregion *c = list_entry(p, struct arm_vmregion, vm_list);

seq_printf(m, "0x%08lx-0x%08lx %7lu", c->vm_start, c->vm_end,
c->vm_end - c->vm_start);
if (c->caller)
seq_printf(m, " %pS", (void *)c->caller);
seq_putc(m, '\n');
return 0;
}

static void *arm_vmregion_start(struct seq_file *m, loff_t *pos)
{
struct arm_vmregion_head *h = m->private;
spin_lock_irq(&h->vm_lock);
return seq_list_start(&h->vm_list, *pos);
}

static void *arm_vmregion_next(struct seq_file *m, void *p, loff_t *pos)
{
struct arm_vmregion_head *h = m->private;
return seq_list_next(p, &h->vm_list, pos);
}

static void arm_vmregion_stop(struct seq_file *m, void *p)
{
struct arm_vmregion_head *h = m->private;
spin_unlock_irq(&h->vm_lock);
}

static const struct seq_operations arm_vmregion_ops = {
.start = arm_vmregion_start,
.stop = arm_vmregion_stop,
.next = arm_vmregion_next,
.show = arm_vmregion_show,
};

static int arm_vmregion_open(struct inode *inode, struct file *file)
{
struct arm_vmregion_head *h = PDE(inode)->data;
int ret = seq_open(file, &arm_vmregion_ops);
if (!ret) {
struct seq_file *m = file->private_data;
m->private = h;
}
return ret;
}

static const struct file_operations arm_vmregion_fops = {
.open = arm_vmregion_open,
.read = seq_read,
.llseek = seq_lseek,
.release = seq_release,
};

int arm_vmregion_create_proc(const char *path, struct arm_vmregion_head *h)
{
proc_create_data(path, S_IRUSR, NULL, &arm_vmregion_fops, h);
return 0;
}
#else
int arm_vmregion_create_proc(const char *path, struct arm_vmregion_head *h)
{
return 0;
}
#endif
5 changes: 4 additions & 1 deletion trunk/arch/arm/mm/vmregion.h
Original file line number Diff line number Diff line change
Expand Up @@ -19,11 +19,14 @@ struct arm_vmregion {
unsigned long vm_end;
struct page *vm_pages;
int vm_active;
const void *caller;
};

struct arm_vmregion *arm_vmregion_alloc(struct arm_vmregion_head *, size_t, size_t, gfp_t);
struct arm_vmregion *arm_vmregion_alloc(struct arm_vmregion_head *, size_t, size_t, gfp_t, const void *);
struct arm_vmregion *arm_vmregion_find(struct arm_vmregion_head *, unsigned long);
struct arm_vmregion *arm_vmregion_find_remove(struct arm_vmregion_head *, unsigned long);
void arm_vmregion_free(struct arm_vmregion_head *, struct arm_vmregion *);

int arm_vmregion_create_proc(const char *, struct arm_vmregion_head *);

#endif

0 comments on commit 498539b

Please sign in to comment.