[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[PATCH v1 06/13] xen/arm: assign shared memory to owner when host address not provided



With the introduction of new scenario where host address is not provided
in "xen,shared-mem", the function "assign_shared_memory" shall be adapted
to it too.

Shared memory will already be allocated from heap, when calling
"assign_shared_memory" with unprovided host address.
So in "assign_shared_memory", we just need to assign these static shared pages
to its owner domain using function "assign_pages", and add as many
additional reference as the number of borrowers.

Signed-off-by: Penny Zheng <penny.zheng@xxxxxxx>
---
 xen/arch/arm/domain_build.c | 160 ++++++++++++++++++++++++++++++------
 1 file changed, 133 insertions(+), 27 deletions(-)

diff --git a/xen/arch/arm/domain_build.c b/xen/arch/arm/domain_build.c
index 3de96882a5..faf0784bb0 100644
--- a/xen/arch/arm/domain_build.c
+++ b/xen/arch/arm/domain_build.c
@@ -817,8 +817,12 @@ static bool __init is_shm_allocated_to_domio(struct 
shm_membank *shm_membank)
 {
     struct page_info *page;
     struct domain *d;
+    paddr_t pbase;
 
-    page = maddr_to_page(shm_membank->mem.bank->start);
+    pbase = shm_membank->mem.banks.meminfo ?
+            shm_membank->mem.banks.meminfo->bank[0].start :
+            shm_membank->mem.bank->start;
+    page = maddr_to_page(pbase);
     d = page_get_owner_and_reference(page);
     if ( d == NULL )
         return false;
@@ -907,6 +911,7 @@ static mfn_t __init acquire_shared_memory_bank(struct 
domain *d,
     mfn_t smfn;
     unsigned long nr_pfns;
     int res;
+    struct page_info *page;
 
     /*
      * Pages of statically shared memory shall be included
@@ -922,33 +927,82 @@ static mfn_t __init acquire_shared_memory_bank(struct 
domain *d,
     d->max_pages += nr_pfns;
 
     smfn = maddr_to_mfn(pbase);
-    res = acquire_domstatic_pages(d, smfn, nr_pfns, 0);
-    if ( res )
+    page = mfn_to_page(smfn);
+    /*
+     * If page is allocated from heap as static shared memory, then we just
+     * assign it to the owner domain
+     */
+    if ( page->count_info == (PGC_state_inuse | PGC_static) )
     {
-        printk(XENLOG_ERR
-               "%pd: failed to acquire static memory: %d.\n", d, res);
-        d->max_pages -= nr_pfns;
-        return INVALID_MFN;
+        res = assign_pages(page, nr_pfns, d, 0);
+        if ( res )
+        {
+            printk(XENLOG_ERR
+                   "%pd: failed to assign static memory: %d.\n", d, res);
+            return INVALID_MFN;
+        }
+    }
+    else
+    {
+        res = acquire_domstatic_pages(d, smfn, nr_pfns, 0);
+        if ( res )
+        {
+            printk(XENLOG_ERR
+                   "%pd: failed to acquire static memory: %d.\n", d, res);
+                   d->max_pages -= nr_pfns;
+            return INVALID_MFN;
+        }
     }
 
     return smfn;
 }
 
-static int __init assign_shared_memory(struct domain *d,
-                                       struct shm_membank *shm_membank,
-                                       paddr_t gbase)
+static void __init remove_shared_memory_ref(struct page_info *page,
+                                            unsigned long nr_pages,
+                                            unsigned long nr_borrowers)
 {
-    mfn_t smfn;
-    int ret = 0;
-    unsigned long nr_pages, nr_borrowers, i;
-    struct page_info *page;
-    paddr_t pbase, psize;
+    while ( --nr_pages >= 0 )
+         put_page_nr(page + nr_pages, nr_borrowers);
+}
 
-    pbase = shm_membank->mem.bank->start;
-    psize = shm_membank->mem.bank->size;
+static int __init add_shared_memory_ref(struct domain *d, struct page_info 
*page,
+                                        unsigned long nr_pages,
+                                        unsigned long nr_borrowers)
+{
+    unsigned int i;
 
-    printk("%pd: allocate static shared memory BANK 
%#"PRIpaddr"-%#"PRIpaddr".\n",
-           d, pbase, pbase + psize);
+    /*
+     * Instead of letting borrower domain get a page ref, we add as many
+     * additional reference as the number of borrowers when the owner
+     * is allocated, since there is a chance that owner is created
+     * after borrower.
+     * So if the borrower is created first, it will cause adding pages
+     * in the P2M without reference.
+     */
+    for ( i = 0; i < nr_pages; i++ )
+    {
+        if ( !get_page_nr(page + i, d, nr_borrowers) )
+        {
+            printk(XENLOG_ERR
+                   "Failed to add %lu references to page %"PRI_mfn".\n",
+                   nr_borrowers, mfn_x(page_to_mfn(page)) + i);
+            goto fail;
+        }
+    }
+    return 0;
+
+ fail:
+    remove_shared_memory_ref(page, i, nr_borrowers);
+    return -EINVAL;
+}
+
+static int __init acquire_shared_memory(struct domain *d,
+                                        paddr_t pbase, paddr_t psize,
+                                        paddr_t gbase)
+{
+    mfn_t smfn;
+    int ret = 0;
+    unsigned long nr_pages;
 
     smfn = acquire_shared_memory_bank(d, pbase, psize);
     if ( mfn_eq(smfn, INVALID_MFN) )
@@ -970,6 +1024,44 @@ static int __init assign_shared_memory(struct domain *d,
         }
     }
 
+    return 0;
+}
+
+static int __init assign_shared_memory(struct domain *d,
+                                       struct shm_membank *shm_membank,
+                                       paddr_t gbase)
+{
+    int ret = 0;
+    unsigned long nr_pages, nr_borrowers;
+    struct page_info *page;
+    unsigned int i;
+    struct meminfo *meminfo;
+
+    /* Host address is not provided in "xen,shared-mem" */
+    if ( shm_membank->mem.banks.meminfo )
+    {
+        meminfo = shm_membank->mem.banks.meminfo;
+        for ( i = 0; i < meminfo->nr_banks; i++ )
+        {
+            ret = acquire_shared_memory(d,
+                                        meminfo->bank[i].start,
+                                        meminfo->bank[i].size,
+                                        gbase);
+            if ( ret )
+                return ret;
+
+            gbase += meminfo->bank[i].size;
+        }
+    }
+    else
+    {
+        ret = acquire_shared_memory(d,
+                                    shm_membank->mem.bank->start,
+                                    shm_membank->mem.bank->size, gbase);
+        if ( ret )
+            return ret;
+    }
+
     /*
      * Get the right amount of references per page, which is the number of
      * borrower domains.
@@ -984,23 +1076,37 @@ static int __init assign_shared_memory(struct domain *d,
      * So if the borrower is created first, it will cause adding pages
      * in the P2M without reference.
      */
-    page = mfn_to_page(smfn);
-    for ( i = 0; i < nr_pages; i++ )
+    if ( shm_membank->mem.banks.meminfo )
     {
-        if ( !get_page_nr(page + i, d, nr_borrowers) )
+        meminfo = shm_membank->mem.banks.meminfo;
+        for ( i = 0; i < meminfo->nr_banks; i++ )
         {
-            printk(XENLOG_ERR
-                   "Failed to add %lu references to page %"PRI_mfn".\n",
-                   nr_borrowers, mfn_x(smfn) + i);
-            goto fail;
+            page = mfn_to_page(maddr_to_mfn(meminfo->bank[i].start));
+            nr_pages = PFN_DOWN(meminfo->bank[i].size);
+            ret = add_shared_memory_ref(d, page, nr_pages, nr_borrowers);
+            if ( ret )
+                goto fail;
         }
     }
+    else
+    {
+        page = mfn_to_page(
+                maddr_to_mfn(shm_membank->mem.bank->start));
+        nr_pages = shm_membank->mem.bank->size >> PAGE_SHIFT;
+        ret = add_shared_memory_ref(d, page, nr_pages, nr_borrowers);
+        if ( ret )
+            return ret;
+    }
 
     return 0;
 
  fail:
     while ( --i >= 0 )
-        put_page_nr(page + i, nr_borrowers);
+    {
+        page = mfn_to_page(maddr_to_mfn(meminfo->bank[i].start));
+        nr_pages = PFN_DOWN(meminfo->bank[i].size);
+        remove_shared_memory_ref(page, nr_pages, nr_borrowers);
+    }
     return ret;
 }
 
-- 
2.25.1




 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.