changeset df7c3f99ebca in /z/repo/gem5
details: http://repo.gem5.org/gem5?cmd=changeset;node=df7c3f99ebca
description:
        Mem: Separate the host and guest views of memory backing store

        This patch moves all the memory backing store operations from the
        independent memory controllers to the global physical memory. The main
        reason for this patch is to allow address striping in a future set of
        patches, but at this point it already provides some useful
        functionality in that it is now possible to change the number of
        memory controllers and their address mapping in combination with
        checkpointing. Thus, the host and guest view of the memory backing
        store are now completely separate.

        With this patch, the individual memory controllers are far simpler as
        all responsibility for serializing/unserializing is moved to the
        physical memory. Currently, the functionality is more or less moved
        from AbstractMemory to PhysicalMemory without any major
        changes. However, in a future patch the physical memory will also
        resolve any ranges that are interleaved and properly assign the
        backing store to the memory controllers, and keep the host memory as a
        single contigous chunk per address range.

        Functionality for future extensions which involve CPU virtualization
        also enable the host to get pointers to the backing store.

diffstat:

 src/mem/abstract_mem.cc |  179 +-------------------------
 src/mem/abstract_mem.hh |  104 ++++++++++----
 src/mem/physical.cc     |  327 +++++++++++++++++++++++++++++++++++++++++++++++-
 src/mem/physical.hh     |  116 +++++++++++++++-
 src/sim/root.cc         |    2 +-
 src/sim/serialize.hh    |    2 +-
 src/sim/system.cc       |   10 +-
 util/cpt_upgrader.py    |   36 ++++-
 8 files changed, 548 insertions(+), 228 deletions(-)

diffs (truncated from 985 to 300 lines):

diff -r e57c7d9736a5 -r df7c3f99ebca src/mem/abstract_mem.cc
--- a/src/mem/abstract_mem.cc   Mon Oct 15 08:12:29 2012 -0400
+++ b/src/mem/abstract_mem.cc   Mon Oct 15 08:12:32 2012 -0400
@@ -42,19 +42,6 @@
  *          Andreas Hansson
  */
 
-#include <sys/mman.h>
-#include <sys/types.h>
-#include <sys/user.h>
-#include <fcntl.h>
-#include <unistd.h>
-#include <zlib.h>
-
-#include <cerrno>
-#include <cstdio>
-#include <climits>
-#include <iostream>
-#include <string>
-
 #include "arch/registers.hh"
 #include "config/the_isa.hh"
 #include "debug/LLSC.hh"
@@ -72,29 +59,12 @@
 {
     if (size() % TheISA::PageBytes != 0)
         panic("Memory Size not divisible by page size\n");
-
-    if (params()->null)
-        return;
-
-    int map_flags = MAP_ANON | MAP_PRIVATE;
-    pmemAddr = (uint8_t *)mmap(NULL, size(),
-                               PROT_READ | PROT_WRITE, map_flags, -1, 0);
-
-    if (pmemAddr == (void *)MAP_FAILED) {
-        perror("mmap");
-        fatal("Could not mmap!\n");
-    }
-
-    //If requested, initialize all the memory to 0
-    if (p->zero)
-        memset(pmemAddr, 0, size());
 }
 
-
-AbstractMemory::~AbstractMemory()
+void
+AbstractMemory::setBackingStore(uint8_t* pmem_addr)
 {
-    if (pmemAddr)
-        munmap((char*)pmemAddr, size());
+    pmemAddr = pmem_addr;
 }
 
 void
@@ -443,146 +413,3 @@
               pkt->cmdString());
     }
 }
-
-void
-AbstractMemory::serialize(ostream &os)
-{
-    if (!pmemAddr)
-        return;
-
-    gzFile compressedMem;
-    string filename = name() + ".physmem";
-    long _size = range.size();
-
-    SERIALIZE_SCALAR(filename);
-    SERIALIZE_SCALAR(_size);
-
-    // write memory file
-    string thefile = Checkpoint::dir() + "/" + filename.c_str();
-    int fd = creat(thefile.c_str(), 0664);
-    if (fd < 0) {
-        perror("creat");
-        fatal("Can't open physical memory checkpoint file '%s'\n", filename);
-    }
-
-    compressedMem = gzdopen(fd, "wb");
-    if (compressedMem == NULL)
-        fatal("Insufficient memory to allocate compression state for %s\n",
-                filename);
-
-    uint64_t pass_size = 0;
-    // gzwrite fails if (int)len < 0 (gzwrite returns int)
-    for (uint64_t written = 0; written < size(); written += pass_size) {
-        pass_size = (uint64_t)INT_MAX < (size() - written) ?
-            (uint64_t)INT_MAX : (size() - written);
-
-        if (gzwrite(compressedMem, pmemAddr + written,
-                    (unsigned int) pass_size) != (int)pass_size) {
-            fatal("Write failed on physical memory checkpoint file '%s'\n",
-                  filename);
-        }
-    }
-
-    if (gzclose(compressedMem))
-        fatal("Close failed on physical memory checkpoint file '%s'\n",
-              filename);
-
-    list<LockedAddr>::iterator i = lockedAddrList.begin();
-
-    vector<Addr> lal_addr;
-    vector<int> lal_cid;
-    while (i != lockedAddrList.end()) {
-        lal_addr.push_back(i->addr);
-        lal_cid.push_back(i->contextId);
-        i++;
-    }
-    arrayParamOut(os, "lal_addr", lal_addr);
-    arrayParamOut(os, "lal_cid", lal_cid);
-}
-
-void
-AbstractMemory::unserialize(Checkpoint *cp, const string &section)
-{
-    if (!pmemAddr)
-        return;
-
-    gzFile compressedMem;
-    long *tempPage;
-    long *pmem_current;
-    uint64_t curSize;
-    uint32_t bytesRead;
-    const uint32_t chunkSize = 16384;
-
-    string filename;
-
-    UNSERIALIZE_SCALAR(filename);
-
-    filename = cp->cptDir + "/" + filename;
-
-    // mmap memoryfile
-    int fd = open(filename.c_str(), O_RDONLY);
-    if (fd < 0) {
-        perror("open");
-        fatal("Can't open physical memory checkpoint file '%s'", filename);
-    }
-
-    compressedMem = gzdopen(fd, "rb");
-    if (compressedMem == NULL)
-        fatal("Insufficient memory to allocate compression state for %s\n",
-                filename);
-
-    // unmap file that was mmapped in the constructor
-    // This is done here to make sure that gzip and open don't muck with our
-    // nice large space of memory before we reallocate it
-    munmap((char*)pmemAddr, size());
-
-    long _size;
-    UNSERIALIZE_SCALAR(_size);
-    if (_size > params()->range.size())
-        fatal("Memory size has changed! size %lld, param size %lld\n",
-              _size, params()->range.size());
-
-    pmemAddr = (uint8_t *)mmap(NULL, size(),
-        PROT_READ | PROT_WRITE, MAP_ANON | MAP_PRIVATE, -1, 0);
-
-    if (pmemAddr == (void *)MAP_FAILED) {
-        perror("mmap");
-        fatal("Could not mmap physical memory!\n");
-    }
-
-    curSize = 0;
-    tempPage = (long*)malloc(chunkSize);
-    if (tempPage == NULL)
-        fatal("Unable to malloc memory to read file %s\n", filename);
-
-    /* Only copy bytes that are non-zero, so we don't give the VM system hell 
*/
-    while (curSize < size()) {
-        bytesRead = gzread(compressedMem, tempPage, chunkSize);
-        if (bytesRead == 0)
-            break;
-
-        assert(bytesRead % sizeof(long) == 0);
-
-        for (uint32_t x = 0; x < bytesRead / sizeof(long); x++)
-        {
-             if (*(tempPage+x) != 0) {
-                 pmem_current = (long*)(pmemAddr + curSize + x * sizeof(long));
-                 *pmem_current = *(tempPage+x);
-             }
-        }
-        curSize += bytesRead;
-    }
-
-    free(tempPage);
-
-    if (gzclose(compressedMem))
-        fatal("Close failed on physical memory checkpoint file '%s'\n",
-              filename);
-
-    vector<Addr> lal_addr;
-    vector<int> lal_cid;
-    arrayParamIn(cp, section, "lal_addr", lal_addr);
-    arrayParamIn(cp, section, "lal_cid", lal_cid);
-    for(int i = 0; i < lal_addr.size(); i++)
-        lockedAddrList.push_front(LockedAddr(lal_addr[i], lal_cid[i]));
-}
diff -r e57c7d9736a5 -r df7c3f99ebca src/mem/abstract_mem.hh
--- a/src/mem/abstract_mem.hh   Mon Oct 15 08:12:29 2012 -0400
+++ b/src/mem/abstract_mem.hh   Mon Oct 15 08:12:32 2012 -0400
@@ -57,6 +57,43 @@
 class System;
 
 /**
+ * Locked address class that represents a physical address and a
+ * context id.
+ */
+class LockedAddr {
+
+  private:
+
+    // on alpha, minimum LL/SC granularity is 16 bytes, so lower
+    // bits need to masked off.
+    static const Addr Addr_Mask = 0xf;
+
+  public:
+
+    // locked address
+    Addr addr;
+
+    // locking hw context
+    const int contextId;
+
+    static Addr mask(Addr paddr) { return (paddr & ~Addr_Mask); }
+
+    // check for matching execution context
+    bool matchesContext(Request *req) const
+    {
+        return (contextId == req->contextId());
+    }
+
+    LockedAddr(Request *req) : addr(mask(req->getPaddr())),
+                               contextId(req->contextId())
+    {}
+
+    // constructor for unserialization use
+    LockedAddr(Addr _addr, int _cid) : addr(_addr), contextId(_cid)
+    {}
+};
+
+/**
  * An abstract memory represents a contiguous block of physical
  * memory, with an associated address range, and also provides basic
  * functionality for reading and writing this memory without any
@@ -79,34 +116,6 @@
     // Should the memory appear in the global address map
     bool inAddrMap;
 
-    class LockedAddr {
-
-      public:
-        // on alpha, minimum LL/SC granularity is 16 bytes, so lower
-        // bits need to masked off.
-        static const Addr Addr_Mask = 0xf;
-
-        static Addr mask(Addr paddr) { return (paddr & ~Addr_Mask); }
-
-        Addr addr;      // locked address
-        int contextId;     // locking hw context
-
-        // check for matching execution context
-        bool matchesContext(Request *req)
-        {
-            return (contextId == req->contextId());
-        }
-
-        LockedAddr(Request *req) : addr(mask(req->getPaddr())),
-                                   contextId(req->contextId())
-        {
-        }
-        // constructor for unserialization use
-        LockedAddr(Addr _addr, int _cid) : addr(_addr), contextId(_cid)
-        {
-        }
-    };
-
     std::list<LockedAddr> lockedAddrList;
 
     // helper function for checkLockedAddrs(): we really want to
@@ -183,7 +192,41 @@
     typedef AbstractMemoryParams Params;
 
     AbstractMemory(const Params* p);
-    virtual ~AbstractMemory();
+    virtual ~AbstractMemory() {}
+
+    /**
+     * See if this is a null memory that should never store data and
+     * always return zero.
+     *
+     * @return true if null
+     */
+    bool isNull() const { return params()->null; }
+
_______________________________________________
gem5-dev mailing list
[email protected]
http://m5sim.org/mailman/listinfo/gem5-dev

Reply via email to