Message ID | 1457342485-16628-1-git-send-email-thunder.leizhen@huawei.com |
---|---|
State | New |
Headers | show |
Suppose: CONFIG_SPARSEMEM is opened. CONFIG_DMA_API_DEBUG or CONFIG_CMA is opened. Then virt_to_page or phys_to_page will be called. Finally, in __pfn_to_page, __sec = __pfn_to_section(__pfn) is NULL. So access section->section_mem_map will trigger exception. --------- #define __pfn_to_page(pfn) \ ({ unsigned long __pfn = (pfn); \ struct mem_section *__sec = __pfn_to_section(__pfn); \ __section_mem_map_addr(__sec) + __pfn; \ }) static inline struct page *__section_mem_map_addr(struct mem_section *section) { unsigned long map = section->section_mem_map; map &= SECTION_MAP_MASK; return (struct page *)map; } On 2016/3/7 17:21, Zhen Lei wrote: > Do this to keep consistent with kfree, which tolerate ptr is NULL. > > Signed-off-by: Zhen Lei <thunder.leizhen@huawei.com> > --- > include/linux/dma-mapping.h | 5 ++++- > 1 file changed, 4 insertions(+), 1 deletion(-) > > diff --git a/include/linux/dma-mapping.h b/include/linux/dma-mapping.h > index 75857cd..fdd4294 100644 > --- a/include/linux/dma-mapping.h > +++ b/include/linux/dma-mapping.h > @@ -402,7 +402,10 @@ static inline void *dma_alloc_coherent(struct device *dev, size_t size, > static inline void dma_free_coherent(struct device *dev, size_t size, > void *cpu_addr, dma_addr_t dma_handle) > { > - return dma_free_attrs(dev, size, cpu_addr, dma_handle, NULL); > + if (unlikely(!cpu_addr)) > + return; > + > + dma_free_attrs(dev, size, cpu_addr, dma_handle, NULL); > } > > static inline void *dma_alloc_noncoherent(struct device *dev, size_t size, > -- > 2.5.0 > > > > . >
On 2016/3/7 19:41, One Thousand Gnomes wrote: > On Mon, 7 Mar 2016 17:21:25 +0800 > Zhen Lei <thunder.leizhen@huawei.com> wrote: > >> Do this to keep consistent with kfree, which tolerate ptr is NULL. >> >> Signed-off-by: Zhen Lei <thunder.leizhen@huawei.com> > > This is inlined code so you are adding extra logic to every single > instance of a call to the function. What is it's total effect on kernel > size ? This a simple if statement, I think it will only generates two instructions. Maybe I need move it into function dma_free_attrs, as below: if (!ops->free || !cpu_addr) return; So that, it only generates one instruction. And dma_free_noncoherent can also be impacted. Or I changed it to BUG_ON(!cpu_addr)? Otherwise, I move it into ops->free, but that maybe more ARCHs. > > Alan > > . >
On 2016/3/8 6:59, Andrew Morton wrote: > On Mon, 7 Mar 2016 18:43:47 +0800 "Leizhen (ThunderTown)" <thunder.leizhen@huawei.com> wrote: > >> Suppose: >> CONFIG_SPARSEMEM is opened. >> CONFIG_DMA_API_DEBUG or CONFIG_CMA is opened. >> >> Then virt_to_page or phys_to_page will be called. Finally, in __pfn_to_page, __sec = __pfn_to_section(__pfn) is NULL. >> So access section->section_mem_map will trigger exception. >> >> --------- >> >> #define __pfn_to_page(pfn) \ >> ({ unsigned long __pfn = (pfn); \ >> struct mem_section *__sec = __pfn_to_section(__pfn); \ >> __section_mem_map_addr(__sec) + __pfn; \ >> }) >> >> static inline struct page *__section_mem_map_addr(struct mem_section *section) >> { >> unsigned long map = section->section_mem_map; >> map &= SECTION_MAP_MASK; >> return (struct page *)map; >> } > > I'm having a bit of trouble understanding this. > > Perhaps you could explain the bug more carefully (inclusion of an oops > output would help) then we'll be in a better position to understand the > proposed fix(es). > Unable to handle kernel paging request at virtual address ffffffc020d3b2b8 pgd = ffffffc083a61000 [ffffffc020d3b2b8] *pgd=0000000000000000, *pud=0000000000000000 CPU: 4 PID: 1489 Comm: malloc_dma_1 Tainted: G O Hardware name: task: ffffffc00d7d26c0 ti: ffffffc0837fc000 task.ti: ffffffc0837fc000 PC is at __dma_free_coherent.isra.10+0x74/0xc8 LR is at __dma_free+0x9c/0xb0 pc : [<ffffffc000214d10>] lr : [<ffffffc000214e00>] pstate: 80000145 sp : ffffffc0837ff700 x29: ffffffc0837ff700 x28: 0000000000000000 x27: 0000000000000000 x26: ffffffffffffffff x25: ffffffc000d1b1d0 x24: ffffffffffffffff x23: 0000000000a00000 x22: ffffffbfff5fffff x21: 0000000000100000 x20: ffffffc2e21f7010 x19: ffffffffffffffff x18: 0000000000000000 x17: 0000007f9360a2b0 x16: ffffffc000541040 x15: ffffffffffffffff x14: ffffffffffffffff x13: ffffffffffffffff x12: 0000000000000001 x11: 0000000000000068 x10: 0000000000000040 x9 : ffffffc000214e00 x8 : ffffffc2e54586b0 x7 : 0000000000000000 x6 : 0000000000000004 x5 : ffffffc000214d64 x4 : 0000000000000000 x3 : 0000000003ffffff x2 : 00000003ffffffff x1 : 000fffffffffffff x0 : ffffffc000d3b2c0 Process malloc_dma_1 (pid: 1489, stack limit = 0xffffffc0837fc020) Stack: (0xffffffc0837ff700 to 0xffffffc083800000) f700: ffffffc0837ff730 ffffffc000214e00 0000000000100000 0000000000000000 f720: ffffffc2e21f7010 ffffffc0837ff7d0 ffffffc0837ff770 ffffffbffc1d6134 f740: ffffffc2e21f7010 00000000000001a0 0000000000000064 ffffffc0837ff7d0 f760: ffffffc000c9fa20 ffffffc0837ffaf0 ffffffc0837ffe10 ffffffc000239b0c f780: ffffffc00d54a280 ffffffc000d1ef58 ffffffc000957163 ffffffc2e21f7000 f7a0: ffffffbffc1d6030 0000000000000000 0000000000000000 0000000000000000 f7c0: 0000000000000000 0000000000000000 ffffffc013000000 ffffffc013c00000 f7e0: ffffffc013f00000 ffffffc014200000 ffffffc014600000 ffffffc014a00000 f800: ffffffc014e00000 ffffffc015200000 ffffffc015600000 ffffffc015a00000 f820: ffffffc015e00000 ffffffc016200000 ffffffc016600000 ffffffc016a00000 f840: ffffffc016e00000 ffffffc017200000 ffffffc017600000 ffffffc017a00000 f860: ffffffc017e00000 ffffffc018200000 ffffffc018600000 ffffffc018a00000 f880: ffffffc018e00000 ffffffc019200000 ffffffc019600000 ffffffc019a00000 f8a0: ffffffc019e00000 ffffffc01a200000 ffffffc01a600000 ffffffc01aa00000 f8c0: ffffffc01ae00000 ffffffc01b200000 ffffffc01b600000 ffffffc01ba00000 f8e0: ffffffc01be00000 ffffffc01c200000 ffffffc01c600000 ffffffc01ca00000 f900: ffffffc01ce00000 ffffffc01d200000 ffffffc01d600000 ffffffc01da00000 f920: ffffffc01de00000 ffffffc01e200000 ffffffc01e400000 ffffffc01e600000 f940: ffffffc01e900000 ffffffc01ea00000 ffffffc01eb00000 ffffffc01ec00000 f960: ffffffc01ee00000 ffffffc01f200000 0000000000000000 0000000000000000 f980: 0000000000000000 0000000000000000 0000000000000000 0000000000000000 f9a0: 0000000000000000 0000000000000000 0000000000000000 0000000000000000 f9c0: 0000000000000000 0000000000000000 0000000000000000 0000000000000000 f9e0: 0000000000000000 0000000000000000 0000000000000000 0000000000000000 fa00: 0000000000000000 0000000000000000 0000000000000000 0000000000000000 fa20: 0000000000000000 0000000000000000 0000000000000000 0000000000000000 fa40: 0000000000000000 0000000000000000 0000000000000000 0000000000000000 fa60: 0000000000000000 0000000000000000 0000000000000000 0000000000000000 fa80: 0000000000000000 0000000000000000 0000000000000000 0000000000000000 faa0: 0000000000000000 0000000000000000 0000000000000000 0000000000000000 fac0: 0000000000000000 0000000000000000 0000000000000000 0000000000000000 fae0: 0000000000000000 0000000000000000 0000000013a00000 0000000014600000 fb00: 0000000014900000 0000000014c00000 0000000015000000 0000000015400000 fb20: 0000000015800000 0000000015c00000 0000000016000000 0000000016400000 fb40: 0000000016800000 0000000016c00000 0000000017000000 0000000017400000 fb60: 0000000017800000 0000000017c00000 0000000018000000 0000000018400000 fb80: 0000000018800000 0000000018c00000 0000000019000000 0000000019400000 fba0: 0000000019800000 0000000019c00000 000000001a000000 000000001a400000 fbc0: 000000001a800000 000000001ac00000 000000001b000000 000000001b400000 fbe0: 000000001b800000 000000001bc00000 000000001c000000 000000001c400000 fc00: 000000001c800000 000000001cc00000 000000001d000000 000000001d400000 fc20: 000000001d800000 000000001dc00000 000000001e000000 000000001e400000 fc40: 000000001e800000 000000001ec00000 000000001ee00000 000000001f000000 fc60: 000000001f300000 000000001f400000 000000001f500000 000000001f600000 fc80: 000000001f800000 000000001fc00000 ffffffffffffffff ffffffffffffffff fca0: ffffffffffffffff ffffffffffffffff ffffffffffffffff ffffffffffffffff fcc0: ffffffffffffffff ffffffffffffffff ffffffffffffffff ffffffffffffffff fce0: ffffffffffffffff ffffffffffffffff ffffffffffffffff ffffffffffffffff fd00: ffffffffffffffff ffffffffffffffff ffffffffffffffff ffffffffffffffff fd20: ffffffffffffffff ffffffffffffffff ffffffffffffffff ffffffffffffffff fd40: ffffffffffffffff ffffffffffffffff ffffffffffffffff ffffffffffffffff fd60: ffffffffffffffff ffffffffffffffff ffffffffffffffff ffffffffffffffff fd80: ffffffffffffffff ffffffffffffffff ffffffffffffffff ffffffffffffffff fda0: ffffffffffffffff ffffffffffffffff ffffffffffffffff ffffffffffffffff fdc0: ffffffffffffffff ffffffffffffffff ffffffffffffffff ffffffffffffffff fde0: ffffffffffffffff ffffffffffffffff ffffffffffffffff ffffffffffffffff fe00: ffffffffffffffff ffffffffffffffff 0000000000000000 ffffffc0002045b0 fe20: ffffffc000239a20 ffffffc00d54a280 0000000000000000 0000000000000000 fe40: 0000000000000000 0000000000000000 0000000000000000 0000000000000000 fe60: ffffffc0837ffe80 ffffffc2e21f7000 00000000e54c1280 0000000000000000 fe80: 0000000000000000 0040000100244964 ffffffc0837ffe90 ffffffc0837ffe90 fea0: 0000000000000000 0000000000000000 0000000000000000 00400001002045a4 fec0: ffffffc0837ffec0 ffffffc0837ffec0 0000000000000000 0000000000000000 fee0: 0000000000000000 0000000000000000 0000000000000000 0000000000000000 ff00: 0000000000000000 0000000000000000 0000000000000000 0000000000000000 ff20: 0000000000000000 0000000000000000 0000000000000000 0000000000000000 ff40: 0000000000000000 0000000000000000 0000000000000000 0000000000000000 ff60: 0000000000000000 0000000000000000 0000000000000000 0000000000000000 ff80: 0000000000000000 0000000000000000 0000000000000000 0000000000000000 ffa0: 0000000000000000 0000000000000000 0000000000000000 0000000000000000 ffc0: 0000000000000000 0000000000000000 0000000000000000 0000000000000005 ffe0: 0000000000000000 0000000000000000 0000000000000000 0000000000000000 Call trace: [<ffffffc000214d10>] __dma_free_coherent.isra.10+0x74/0xc8 [<ffffffc000214e00>] __dma_free+0x9c/0xb0 [<ffffffbffc1d6134>] malloc_dma+0x104/0x158 [dma_alloc_coherent_mtmalloc] [<ffffffc000239b0c>] kthread+0xec/0xfc Code: 62fc5ed3 205900f0 00000b91 63fc66d3 (007863f8) ---[ end trace 8b2106a7528c8712 ]--- > Thanks. > > . >
diff --git a/include/linux/dma-mapping.h b/include/linux/dma-mapping.h index 75857cd..fdd4294 100644 --- a/include/linux/dma-mapping.h +++ b/include/linux/dma-mapping.h @@ -402,7 +402,10 @@ static inline void *dma_alloc_coherent(struct device *dev, size_t size, static inline void dma_free_coherent(struct device *dev, size_t size, void *cpu_addr, dma_addr_t dma_handle) { - return dma_free_attrs(dev, size, cpu_addr, dma_handle, NULL); + if (unlikely(!cpu_addr)) + return; + + dma_free_attrs(dev, size, cpu_addr, dma_handle, NULL); } static inline void *dma_alloc_noncoherent(struct device *dev, size_t size,
Do this to keep consistent with kfree, which tolerate ptr is NULL. Signed-off-by: Zhen Lei <thunder.leizhen@huawei.com> --- include/linux/dma-mapping.h | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) -- 2.5.0