BNX2X: hacks around the MC assert problem
authorBarret Rhoden <brho@cs.berkeley.edu>
Thu, 19 Mar 2015 18:38:50 +0000 (14:38 -0400)
committerBarret Rhoden <brho@cs.berkeley.edu>
Thu, 19 Mar 2015 19:01:14 +0000 (15:01 -0400)
Our get_cont_pages() does not return pages aligned to the *order* of the
allocation.  This means higher order allocs, like 2^3 pages might not
come on an 8*PGSIZE boundary.  Apparently, this was enough to trigger
the MC assert for some high-order alloc.

The dirtiness comes in where we don't free the contig region.  Hopefully
we're not leaking too much.  (only once per NIC, so far).

This is mostly a stopgap til we fix our shitty memory allocator.

kern/drivers/net/bnx2x/akaros_compat.h

index bc9e283..5d61ff1 100644 (file)
@@ -84,11 +84,17 @@ static inline void *__dma_alloc_coherent(size_t size, dma_addr_t *dma_handle,
                                          gfp_t flags)
 {
        size_t order = LOG2_UP(nr_pages(size));
-       void *vaddr = get_cont_pages(order, flags);
+       /* our shitty allocator doesn't align the higher order allocations, so we
+        * go 2x, and align manually.  we don't save the original pointer, so we
+        * can't free them later. */
+       void *vaddr = get_cont_pages(order > 0 ?  order + 1 : order,
+                                    flags);
        if (!vaddr) {
                *dma_handle = 0;
                return 0;
        }
+       /* manual alignment.  order 0 allocs are already page aligned */
+       vaddr = ALIGN(vaddr, PGSIZE << order);
        *dma_handle = PADDR(vaddr);
        return vaddr;
 }
@@ -106,6 +112,10 @@ static inline void __dma_free_coherent(size_t size, void *cpu_addr,
                                        dma_addr_t dma_handle)
 {
        size_t order = LOG2_UP(nr_pages(size));
+       if (order > 0) {
+               warn("Not freeing high order alloc!  Fix the allocator!");
+               return;
+       }
        free_cont_pages(cpu_addr, order);
 }