> 
> Hi,
> 
>       I am not sure if I should post this question here, but this problem (so
> far) has only appeared on my Dual PII machine, so I guess I'll post it
> here, if I should post it else where, please direct me to that list,
> 
>       My problem is for some reason, i need LARGE amount of 'FREE' memory to
> start my sound application, say, x11amp, mpeg viewer(with sound in that
> movie of course). If I have fairly small amount of 'FREE' memory, say
> less than 20-30MB, those sound applications won't even start 90% of
> time. When I read the log, it says, 
> 
> "Can't allocate DMA buffer"  or something equivalent.
> 

Have you tried my MM patch? I am enclosing it here.


H.J.
----
Index: mm/page_alloc.c
===================================================================
RCS file: /work/cvs/linux/linux/mm/page_alloc.c,v
retrieving revision 1.1.1.31
diff -u -p -r1.1.1.31 page_alloc.c
--- mm/page_alloc.c     1999/05/12 00:50:48     1.1.1.31
+++ mm/page_alloc.c     1999/07/10 17:53:26
@@ -155,12 +155,12 @@ void free_pages(unsigned long addr, unsi
        change_bit((index) >> (1+(order)), (area)->map)
 #define CAN_DMA(x) (PageDMA(x))
 #define ADDRESS(x) (PAGE_OFFSET + ((x) << PAGE_SHIFT))
-#define RMQUEUE(order, gfp_mask) \
+#define RMQUEUE_DMA(order) \
 do { struct free_area_struct * area = free_area+order; \
      unsigned long new_order = order; \
        do { struct page *prev = memory_head(area), *ret = prev->next; \
                while (memory_head(area) != ret) { \
-                       if (!(gfp_mask & __GFP_DMA) || CAN_DMA(ret)) { \
+                       if (CAN_DMA(ret)) { \
                                unsigned long map_nr; \
                                (prev->next = ret->next)->prev = prev; \
                                map_nr = ret - mem_map; \
@@ -176,6 +176,45 @@ do { struct free_area_struct * area = fr
                new_order++; area++; \
        } while (new_order < NR_MEM_LISTS); \
 } while (0)
+#define RMQUEUE_NODMA(order) \
+do { struct free_area_struct * area = free_area+order; \
+     unsigned long new_order = order; \
+       do { struct page *prev = memory_head(area), *ret = prev->next; \
+               while (memory_head(area) != ret) { \
+                       if (!CAN_DMA(ret)) { \
+                               unsigned long map_nr; \
+                               (prev->next = ret->next)->prev = prev; \
+                               map_nr = ret - mem_map; \
+                               MARK_USED(map_nr, new_order, area); \
+                               nr_free_pages -= 1 << order; \
+                               EXPAND(ret, map_nr, order, new_order, area); \
+                               spin_unlock_irqrestore(&page_alloc_lock, flags); \
+                               return ADDRESS(map_nr); \
+                       } \
+                       prev = ret; \
+                       ret = ret->next; \
+               } \
+               new_order++; area++; \
+       } while (new_order < NR_MEM_LISTS); \
+} while (0)
+#define RMQUEUE_ANY(order) \
+do { struct free_area_struct * area = free_area+order; \
+     unsigned long new_order = order; \
+       do { struct page *prev = memory_head(area), *ret = prev->next; \
+               if (memory_head(area) != ret) { \
+                       unsigned long map_nr; \
+                       (prev->next = ret->next)->prev = prev; \
+                       map_nr = ret - mem_map; \
+                       MARK_USED(map_nr, new_order, area); \
+                       nr_free_pages -= 1 << order; \
+                       EXPAND(ret, map_nr, order, new_order, area); \
+                       spin_unlock_irqrestore(&page_alloc_lock, flags); \
+                       return ADDRESS(map_nr); \
+                \
+               } \
+               new_order++; area++; \
+       } while (new_order < NR_MEM_LISTS); \
+} while (0)
 
 #define EXPAND(map,index,low,high,area) \
 do { unsigned long size = 1 << high; \
@@ -236,7 +275,12 @@ unsigned long __get_free_pages(int gfp_m
        }
 ok_to_allocate:
        spin_lock_irqsave(&page_alloc_lock, flags);
-       RMQUEUE(order, gfp_mask);
+       if (gfp_mask & __GFP_DMA)
+               RMQUEUE_DMA(order);
+       else {
+               RMQUEUE_NODMA(order);
+               RMQUEUE_ANY(order);
+       }
        spin_unlock_irqrestore(&page_alloc_lock, flags);
 
        /*
-
Linux SMP list: FIRST see FAQ at http://www.irisa.fr/prive/mentre/smp-faq/
To Unsubscribe: send "unsubscribe linux-smp" to [EMAIL PROTECTED]

Reply via email to