]> err.no Git - linux-2.6/blobdiff - include/linux/mm.h
[PATCH] add slab_is_available() routine for boot code
[linux-2.6] / include / linux / mm.h
index b12d5c76420dc49049cc3f55e1cbc53265d05434..1154684209a4458d1507702e1c4a778d942eda94 100644 (file)
@@ -229,10 +229,9 @@ struct page {
                unsigned long private;          /* Mapping-private opaque data:
                                                 * usually used for buffer_heads
                                                 * if PagePrivate set; used for
-                                                * swp_entry_t if PageSwapCache.
-                                                * When page is free, this
+                                                * swp_entry_t if PageSwapCache;
                                                 * indicates order in the buddy
-                                                * system.
+                                                * system if PG_buddy is set.
                                                 */
                struct address_space *mapping;  /* If low bit clear, points to
                                                 * inode address_space, or NULL.
@@ -286,15 +285,6 @@ struct page {
  *
  * Also, many kernel routines increase the page count before a critical
  * routine so they can be sure the page doesn't go away from under them.
- *
- * Since 2.6.6 (approx), a free page has ->_count = -1.  This is so that we
- * can use atomic_add_negative(-1, page->_count) to detect when the page
- * becomes free and so that we can also use atomic_inc_and_test to atomically
- * detect when we just tried to grab a ref on a page which some other CPU has
- * already deemed to be freeable.
- *
- * NO code should make assumptions about this internal detail!  Use the provided
- * macros which retain the old rules: page_count(page) == 0 is a free page.
  */
 
 /*
@@ -303,8 +293,8 @@ struct page {
  */
 static inline int put_page_testzero(struct page *page)
 {
-       BUG_ON(atomic_read(&page->_count) == -1);
-       return atomic_add_negative(-1, &page->_count);
+       BUG_ON(atomic_read(&page->_count) == 0);
+       return atomic_dec_and_test(&page->_count);
 }
 
 /*
@@ -313,19 +303,16 @@ static inline int put_page_testzero(struct page *page)
  */
 static inline int get_page_unless_zero(struct page *page)
 {
-       return atomic_add_unless(&page->_count, 1, -1);
+       return atomic_inc_not_zero(&page->_count);
 }
 
-#define set_page_count(p,v)    atomic_set(&(p)->_count, (v) - 1)
-#define __put_page(p)          atomic_dec(&(p)->_count)
-
 extern void FASTCALL(__page_cache_release(struct page *));
 
 static inline int page_count(struct page *page)
 {
-       if (PageCompound(page))
+       if (unlikely(PageCompound(page)))
                page = (struct page *)page_private(page);
-       return atomic_read(&page->_count) + 1;
+       return atomic_read(&page->_count);
 }
 
 static inline void get_page(struct page *page)
@@ -335,8 +322,19 @@ static inline void get_page(struct page *page)
        atomic_inc(&page->_count);
 }
 
+/*
+ * Setup the page count before being freed into the page allocator for
+ * the first time (boot or memory hotplug)
+ */
+static inline void init_page_count(struct page *page)
+{
+       atomic_set(&page->_count, 1);
+}
+
 void put_page(struct page *page);
 
+void split_page(struct page *page, unsigned int order);
+
 /*
  * Multiple processes may "see" the same page. E.g. for untouched
  * mappings of /dev/null, all processes see the same page full of
@@ -1049,7 +1047,7 @@ int in_gate_area_no_task(unsigned long addr);
 
 int drop_caches_sysctl_handler(struct ctl_table *, int, struct file *,
                                        void __user *, size_t *, loff_t *);
-int shrink_slab(unsigned long scanned, gfp_t gfp_mask,
+unsigned long shrink_slab(unsigned long scanned, gfp_t gfp_mask,
                        unsigned long lru_pages);
 void drop_pagecache(void);
 void drop_slab(void);