Import 2.1.89
[davej-history.git] / mm / page_alloc.c
index a2b41cf..c3aef90 100644 (file)
@@ -108,20+108,36 @@ static spinlock_t page_alloc_lock;
  * but this had better return false if any reasonable "get_free_page()"
  * allocation could currently fail..
  *
- * Right now we just require that the highest memory order should
- * have at least two entries. Whether this makes sense or not
- * under real load is to be tested, but it also gives us some
- * guarantee about memory fragmentation (essentially, it means
- * that there should be at least two large areas available).
+ * Currently we approve of the following situations:
+ * - the highest memory order has two entries
+ * - the highest memory order has one free entry and:
+ *     - the next-highest memory order has two free entries
+ * - the highest memory order has one free entry and:
+ *     - the next-highest memory order has one free entry
+ *     - the next-next-highest memory order has two free entries
+ *
+ * [previously, there had to be two entries of the highest memory
+ *  order, but this lead to problems on large-memory machines.]
  */
 int free_memory_available(void)
 {
-       int retval;
+       int i, retval = 0;
        unsigned long flags;
-       struct free_area_struct * last = free_area + NR_MEM_LISTS - 1;
+       struct free_area_struct * list = NULL;
 
        spin_lock_irqsave(&page_alloc_lock, flags);
-       retval =  (last->next != memory_head(last)) && (last->next->next != memory_head(last));
+       /* We fall through the loop if the list contains one
+        * item. -- thanks to Colin Plumb <colin@nyx.net>
+        */
+       for (i = 1; i < 4; ++i) {
+               list = free_area + NR_MEM_LISTS - i;
+               if (list->next == memory_head(list))
+                       break;
+               if (list->next->next == memory_head(list))
+                       continue;
+               retval = 1;
+               break;
+       }
        spin_unlock_irqrestore(&page_alloc_lock, flags);
        return retval;
 }
close