File 19156-page-list-simplify.patch of Package xen

# HG changeset patch
# User Keir Fraser <keir.fraser@citrix.com>
# Date 1233748907 0
# Node ID 97ca3400d17c5f14af3c36145963d7c6c9a9416e
# Parent  1b2fdbb337160639d0fb7c5bb3f097bef643dd7c
Eliminate some special page list accessors

Since page_list_move_tail(), page_list_splice_init(), and
page_list_is_eol() are only used by relinquish_memory(), and that
function can easily be changed to use more generic accessors, just
eliminate them altogether.

Signed-off-by: Jan Beulich <jbeulich@novell.com>

--- 2009-06-17.orig/xen/arch/x86/domain.c	2009-06-17 14:13:44.000000000 +0200
+++ 2009-06-17/xen/arch/x86/domain.c	2009-06-17 14:15:11.000000000 +0200
@@ -1620,23 +1620,20 @@ int hypercall_xlat_continuation(unsigned
 static int relinquish_memory(
     struct domain *d, struct page_list_head *list, unsigned long type)
 {
-    struct page_info  *page, *cur;
+    struct page_info  *page;
     unsigned long     x, y;
     int               ret = 0;
 
     /* Use a recursive lock, as we may enter 'free_domheap_page'. */
     spin_lock_recursive(&d->page_alloc_lock);
 
-    page = page_list_first(list);
-    while ( !page_list_is_eol(page, list) )
+    while ( (page = page_list_remove_head(list)) )
     {
         /* Grab a reference to the page so it won't disappear from under us. */
         if ( unlikely(!get_page(page, d)) )
         {
             /* Couldn't get a reference -- someone is freeing this page. */
-            cur = page;
-            page = page_list_next(page, list);
-            page_list_move_tail(cur, list, &d->arch.relmem_list);
+            page_list_add_tail(page, &d->arch.relmem_list);
             continue;
         }
 
@@ -1648,6 +1645,7 @@ static int relinquish_memory(
             break;
         case -EAGAIN:
         case -EINTR:
+            page_list_add(page, list);
             set_bit(_PGT_pinned, &page->u.inuse.type_info);
             put_page(page);
             goto out;
@@ -1684,6 +1682,7 @@ static int relinquish_memory(
                 case 0:
                     break;
                 case -EINTR:
+                    page_list_add(page, list);
                     page->u.inuse.type_info |= PGT_validated;
                     if ( x & PGT_partial )
                         put_page(page);
@@ -1691,6 +1690,7 @@ static int relinquish_memory(
                     ret = -EAGAIN;
                     goto out;
                 case -EAGAIN:
+                    page_list_add(page, list);
                     page->u.inuse.type_info |= PGT_partial;
                     if ( x & PGT_partial )
                         put_page(page);
@@ -1707,11 +1707,9 @@ static int relinquish_memory(
             }
         }
 
-        /* Follow the list chain and /then/ potentially free the page. */
-        cur = page;
-        page = page_list_next(page, list);
-        page_list_move_tail(cur, list, &d->arch.relmem_list);
-        put_page(cur);
+        /* Put the page on the list and /then/ potentially free it. */
+        page_list_add_tail(page, &d->arch.relmem_list);
+        put_page(page);
 
         if ( hypercall_preempt_check() )
         {
@@ -1720,7 +1718,8 @@ static int relinquish_memory(
         }
     }
 
-    page_list_splice_init(&d->arch.relmem_list, list);
+    /* list is empty at this point. */
+    page_list_move(list, &d->arch.relmem_list);
 
  out:
     spin_unlock_recursive(&d->page_alloc_lock);
--- 2009-06-17.orig/xen/include/xen/mm.h	2009-06-17 14:13:44.000000000 +0200
+++ 2009-06-17/xen/include/xen/mm.h	2009-06-17 14:31:01.000000000 +0200
@@ -123,12 +123,6 @@ page_list_prev(const struct page_info *p
 {
     return page != head->next ? mfn_to_page(page->list.prev) : NULL;
 }
-static inline int
-page_list_is_eol(const struct page_info *page,
-                 const struct page_list_head *head)
-{
-    return !page;
-}
 static inline void
 page_list_add(struct page_info *page, struct page_list_head *head)
 {
@@ -212,13 +206,6 @@ page_list_del2(struct page_info *page, s
         prev->list.next = page->list.next;
     }
 }
-static inline void
-page_list_move_tail(struct page_info *page, struct page_list_head *list,
-                    struct page_list_head *head)
-{
-    page_list_del(page, list);
-    page_list_add_tail(page, head);
-}
 static inline struct page_info *
 page_list_remove_head(struct page_list_head *head)
 {
@@ -230,16 +217,12 @@ page_list_remove_head(struct page_list_h
     return page;
 }
 static inline void
-page_list_splice_init(struct page_list_head *list, struct page_list_head *head)
+page_list_move(struct page_list_head *dst, struct page_list_head *src)
 {
-    if ( !page_list_empty(list) )
+    if ( !page_list_empty(src) )
     {
-        if ( head->next )
-            head->tail->list.next = page_to_mfn(list->next);
-        else
-            head->next = list->next;
-        head->tail = list->tail;
-        INIT_PAGE_LIST_HEAD(list);
+        *dst = *src;
+        INIT_PAGE_LIST_HEAD(src);
     }
 }
 
@@ -264,19 +247,18 @@ page_list_splice_init(struct page_list_h
                                                     struct page_info, list)
 # define page_list_next(pg, hd)          list_entry((pg)->list.next, \
                                                     struct page_info, list)
-# define page_list_is_eol(pg, hd)        (&(pg)->list == (hd))
 # define page_list_add(pg, hd)           list_add(&(pg)->list, hd)
 # define page_list_add_tail(pg, hd)      list_add_tail(&(pg)->list, hd)
 # define page_list_del(pg, hd)           list_del(&(pg)->list)
 # define page_list_del2(pg, hd1, hd2)    list_del(&(pg)->list)
-# define page_list_move_tail(pg, o, n)   list_move_tail(&(pg)->list, n)
 # define page_list_remove_head(hd)       (!page_list_empty(hd) ? \
     ({ \
         struct page_info *__pg = page_list_first(hd); \
         list_del(&__pg->list); \
         __pg; \
     }) : NULL)
-# define page_list_splice_init           list_splice_init
+# define page_list_move(dst, src)        (!list_empty(src) ? \
+    list_replace_init(src, dst) : (void)0)
 # define page_list_for_each(pos, head)   list_for_each_entry(pos, head, list)
 # define page_list_for_each_safe(pos, tmp, head) \
     list_for_each_entry_safe(pos, tmp, head, list)
openSUSE Build Service is sponsored by