SE: move page allocation from PageTable to Process
authorSteve Reinhardt <steve.reinhardt@amd.com>
Sun, 23 Oct 2011 05:30:08 +0000 (22:30 -0700)
committerSteve Reinhardt <steve.reinhardt@amd.com>
Sun, 23 Oct 2011 05:30:08 +0000 (22:30 -0700)
PageTable supported an allocate() call that called back
through the Process to allocate memory, but did not have
a method to map addresses without allocating new pages.
It makes more sense for Process to do the allocation, so
this method was renamed allocateMem() and moved to Process,
and uses a new map() call on PageTable.

The remaining uses of the process pointer in PageTable
were only to get the name and the PID, so by passing these
in directly in the constructor, we can make PageTable
completely independent of Process.

17 files changed:
src/arch/alpha/process.cc
src/arch/arm/linux/process.cc
src/arch/arm/process.cc
src/arch/mips/process.cc
src/arch/power/process.cc
src/arch/sparc/process.cc
src/arch/x86/process.cc
src/kern/tru64/tru64.hh
src/mem/page_table.cc
src/mem/page_table.hh
src/mem/translating_port.cc
src/sim/process.cc
src/sim/process.hh
src/sim/syscall_emul.cc
src/sim/syscall_emul.hh
src/sim/system.cc
src/sim/system.hh

index 637fbe065673e95246078faff2f1b7c3f3c2ce5d..4a3079264554f0dff76acd3b129202c3028466f7 100644 (file)
@@ -126,7 +126,7 @@ AlphaLiveProcess::argsInit(int intSize, int pageSize)
     stack_min = roundDown(stack_min, pageSize);
     stack_size = stack_base - stack_min;
     // map memory
-    pTable->allocate(stack_min, roundUp(stack_size, pageSize));
+    allocateMem(stack_min, roundUp(stack_size, pageSize));
 
     // map out initial stack contents
     Addr argv_array_base = stack_min + intSize; // room for argc
index f177492521292c5605f97a8eac6deffdb814d3a9..c65962d00d6ad01dcc2e1f51af21ce2c00c562b5 100644 (file)
@@ -503,7 +503,7 @@ void
 ArmLinuxProcess::initState()
 {
     ArmLiveProcess::initState();
-    pTable->allocate(commPage, PageBytes);
+    allocateMem(commPage, PageBytes);
     ThreadContext *tc = system->getThreadContext(contextIds[0]);
 
     uint8_t swiNeg1[] = {
index c3b02744e6f9bf3805afc374157a7e098ecfa03d..aa5d7dfcec15e7f2c870d68040edc2a48340ad32 100644 (file)
@@ -251,8 +251,7 @@ ArmLiveProcess::argsInit(int intSize, int pageSize)
     stack_size = stack_base - stack_min;
 
     // map memory
-    pTable->allocate(roundDown(stack_min, pageSize),
-                     roundUp(stack_size, pageSize));
+    allocateMem(roundDown(stack_min, pageSize), roundUp(stack_size, pageSize));
 
     // map out initial stack contents
     uint32_t sentry_base = stack_base - sentry_size;
index c62b60b986a552fb3eb21268d8c43e0a517c61d1..5643ff18ae7d56bc6d8c90ac1ea4174d46739fd3 100644 (file)
@@ -136,7 +136,7 @@ MipsLiveProcess::argsInit(int pageSize)
     stack_min = roundDown(stack_min, pageSize);
     stack_size = stack_base - stack_min;
     // map memory
-    pTable->allocate(stack_min, roundUp(stack_size, pageSize));
+    allocateMem(stack_min, roundUp(stack_size, pageSize));
 
     // map out initial stack contents
     IntType argv_array_base = stack_min + intSize; // room for argc
index d12e3eab6c69d276e454d205307b569e77a190eb..788c7cc0cb72ef1f9e466a99c0baaa1ac497fb2a 100644 (file)
@@ -187,8 +187,7 @@ PowerLiveProcess::argsInit(int intSize, int pageSize)
     stack_size = stack_base - stack_min;
 
     // map memory
-    pTable->allocate(roundDown(stack_min, pageSize),
-                     roundUp(stack_size, pageSize));
+    allocateMem(roundDown(stack_min, pageSize), roundUp(stack_size, pageSize));
 
     // map out initial stack contents
     uint32_t sentry_base = stack_base - sentry_size;
index 3eee3d137b11eb7d7e05acf885202c83eafd1be6..5c594dcbc1da700f754e9dec06d8bed9e7856a19 100644 (file)
@@ -316,8 +316,7 @@ SparcLiveProcess::argsInit(int pageSize)
     stack_size = stack_base - stack_min;
 
     // Allocate space for the stack
-    pTable->allocate(roundDown(stack_min, pageSize),
-                     roundUp(stack_size, pageSize));
+    allocateMem(roundDown(stack_min, pageSize), roundUp(stack_size, pageSize));
 
     // map out initial stack contents
     IntType sentry_base = stack_base - sentry_size;
index 79a1407768964a429b210584f253c779fadf0966..f5ba787c9fac776b44c28306da7e81598653e65d 100644 (file)
@@ -167,7 +167,7 @@ X86_64LiveProcess::initState()
     argsInit(sizeof(uint64_t), VMPageSize);
 
        // Set up the vsyscall page for this process.
-    pTable->allocate(vsyscallPage.base, vsyscallPage.size);
+    allocateMem(vsyscallPage.base, vsyscallPage.size);
     uint8_t vtimeBlob[] = {
         0x48,0xc7,0xc0,0xc9,0x00,0x00,0x00,    // mov    $0xc9,%rax
         0x0f,0x05,                             // syscall
@@ -265,7 +265,7 @@ I386LiveProcess::initState()
      * Set up a GDT for this process. The whole GDT wouldn't really be for
      * this process, but the only parts we care about are.
      */
-    pTable->allocate(_gdtStart, _gdtSize);
+    allocateMem(_gdtStart, _gdtSize);
     uint64_t zero = 0;
     assert(_gdtSize % sizeof(zero) == 0);
     for (Addr gdtCurrent = _gdtStart;
@@ -274,7 +274,7 @@ I386LiveProcess::initState()
     }
 
     // Set up the vsyscall page for this process.
-    pTable->allocate(vsyscallPage.base, vsyscallPage.size);
+    allocateMem(vsyscallPage.base, vsyscallPage.size);
     uint8_t vsyscallBlob[] = {
         0x51,       // push %ecx
         0x52,       // push %edp
@@ -577,8 +577,7 @@ X86LiveProcess::argsInit(int pageSize,
     stack_size = stack_base - stack_min;
 
     // map memory
-    pTable->allocate(roundDown(stack_min, pageSize),
-                     roundUp(stack_size, pageSize));
+    allocateMem(roundDown(stack_min, pageSize), roundUp(stack_size, pageSize));
 
     // map out initial stack contents
     IntType sentry_base = stack_base - sentry_size;
index 09cbb166d56c8653f1530edc3df6ad714cdd0292..4da4cfe530a85e5782fe43866712a510b8d59d55 100644 (file)
@@ -564,7 +564,7 @@ class Tru64 : public OperatingSystem
                 stack_base, stack_size);
 
         // map memory
-        process->pTable->allocate(rounded_stack_base, rounded_stack_size);
+        process->allocateMem(rounded_stack_base, rounded_stack_size);
 
         argp->address = gtoh(rounded_stack_base);
         argp.copyOut(tc->getMemPort());
@@ -683,7 +683,7 @@ class Tru64 : public OperatingSystem
         // Register this as a valid address range with the process
         base_addr = roundDown(base_addr, VMPageSize);
         int size = cur_addr - base_addr;
-        process->pTable->allocate(base_addr, roundUp(size, VMPageSize));
+        process->allocateMem(base_addr, roundUp(size, VMPageSize));
 
         config.copyOut(tc->getMemPort());
         slot_state.copyOut(tc->getMemPort());
index 745872319e293520292382ec0373132271e9ada5..7622c2d4882302f3e5a413614c02fae287d42784 100644 (file)
 #include "debug/MMU.hh"
 #include "mem/page_table.hh"
 #include "sim/faults.hh"
-#include "sim/process.hh"
 #include "sim/sim_object.hh"
-#include "sim/system.hh"
 
 using namespace std;
 using namespace TheISA;
 
-PageTable::PageTable(Process *_process, Addr _pageSize)
+PageTable::PageTable(const std::string &__name, uint64_t _pid, Addr _pageSize)
     : pageSize(_pageSize), offsetMask(mask(floorLog2(_pageSize))),
-      process(_process)
+      pid(_pid), _name(__name)
 {
     assert(isPowerOf2(pageSize));
     pTableCache[0].vaddr = 0;
@@ -67,21 +65,20 @@ PageTable::~PageTable()
 }
 
 void
-PageTable::allocate(Addr vaddr, int64_t size, bool clobber)
+PageTable::map(Addr vaddr, Addr paddr, int64_t size, bool clobber)
 {
     // starting address must be page aligned
     assert(pageOffset(vaddr) == 0);
 
     DPRINTF(MMU, "Allocating Page: %#x-%#x\n", vaddr, vaddr+ size);
 
-    for (; size > 0; size -= pageSize, vaddr += pageSize) {
+    for (; size > 0; size -= pageSize, vaddr += pageSize, paddr += pageSize) {
         if (!clobber && (pTable.find(vaddr) != pTable.end())) {
             // already mapped
             fatal("PageTable::allocate: address 0x%x already mapped", vaddr);
         }
 
-        pTable[vaddr] = TheISA::TlbEntry(process->M5_pid, vaddr,
-                                         process->system->new_page());
+        pTable[vaddr] = TheISA::TlbEntry(pid, vaddr, paddr);
         updateCache(vaddr, pTable[vaddr]);
     }
 }
@@ -108,11 +105,11 @@ PageTable::remap(Addr vaddr, int64_t size, Addr new_vaddr)
 }
 
 void
-PageTable::deallocate(Addr vaddr, int64_t size)
+PageTable::unmap(Addr vaddr, int64_t size)
 {
     assert(pageOffset(vaddr) == 0);
 
-    DPRINTF(MMU, "Deallocating page: %#x-%#x\n", vaddr, vaddr+ size);
+    DPRINTF(MMU, "Unmapping page: %#x-%#x\n", vaddr, vaddr+ size);
 
     for (; size > 0; size -= pageSize, vaddr += pageSize) {
         PTableItr iter = pTable.find(vaddr);
@@ -208,7 +205,7 @@ PageTable::serialize(std::ostream &os)
     PTableItr iter = pTable.begin();
     PTableItr end = pTable.end();
     while (iter != end) {
-        os << "\n[" << csprintf("%s.Entry%d", process->name(), count) << "]\n";
+        os << "\n[" << csprintf("%s.Entry%d", name(), count) << "]\n";
 
         paramOut(os, "vaddr", iter->first);
         iter->second.serialize(os);
@@ -230,9 +227,9 @@ PageTable::unserialize(Checkpoint *cp, const std::string &section)
     pTable.clear();
 
     while(i < count) {
-        paramIn(cp, csprintf("%s.Entry%d", process->name(), i), "vaddr", vaddr);
+        paramIn(cp, csprintf("%s.Entry%d", name(), i), "vaddr", vaddr);
         entry = new TheISA::TlbEntry();
-        entry->unserialize(cp, csprintf("%s.Entry%d", process->name(), i));
+        entry->unserialize(cp, csprintf("%s.Entry%d", name(), i));
         pTable[vaddr] = *entry;
         ++i;
     }
index d60f4a433be013e45cdfbbfd9bead5ee95be8bd0..b1b5227bed74a2faffb8a05b80e82fdb5c2c5a17 100644 (file)
@@ -46,8 +46,6 @@
 #include "mem/request.hh"
 #include "sim/serialize.hh"
 
-class Process;
-
 /**
  * Page Table Declaration.
  */
@@ -68,20 +66,25 @@ class PageTable
     const Addr pageSize;
     const Addr offsetMask;
 
-    Process *process;
+    const uint64_t pid;
+    const std::string _name;
 
   public:
 
-    PageTable(Process *_process, Addr _pageSize = TheISA::VMPageSize);
+    PageTable(const std::string &__name, uint64_t _pid,
+              Addr _pageSize = TheISA::VMPageSize);
 
     ~PageTable();
 
+    // for DPRINTF compatibility
+    const std::string name() const { return _name; }
+
     Addr pageAlign(Addr a)  { return (a & ~offsetMask); }
     Addr pageOffset(Addr a) { return (a &  offsetMask); }
 
-    void allocate(Addr vaddr, int64_t size, bool clobber = false);
+    void map(Addr vaddr, Addr paddr, int64_t size, bool clobber = false);
     void remap(Addr vaddr, int64_t size, Addr new_vaddr);
-    void deallocate(Addr vaddr, int64_t size);
+    void unmap(Addr vaddr, int64_t size);
 
     /**
      * Check if any pages in a region are already allocated
index 80c68c6bdbf12adc74fa55875372b6b5831aeb76..3ea728349853b6c469beaca26d8bbbda8889ac13 100644 (file)
@@ -86,8 +86,8 @@ TranslatingPort::tryWriteBlob(Addr addr, uint8_t *p, int size)
 
         if (!pTable->translate(gen.addr(), paddr)) {
             if (allocating == Always) {
-                pTable->allocate(roundDown(gen.addr(), VMPageSize),
-                                 VMPageSize);
+                process->allocateMem(roundDown(gen.addr(), VMPageSize),
+                                     VMPageSize);
             } else if (allocating == NextPage) {
                 // check if we've accessed the next page on the stack
                 if (!process->fixupStackFault(gen.addr()))
@@ -123,8 +123,8 @@ TranslatingPort::tryMemsetBlob(Addr addr, uint8_t val, int size)
 
         if (!pTable->translate(gen.addr(), paddr)) {
             if (allocating == Always) {
-                pTable->allocate(roundDown(gen.addr(), VMPageSize),
-                                 VMPageSize);
+                process->allocateMem(roundDown(gen.addr(), VMPageSize),
+                                     VMPageSize);
                 pTable->translate(gen.addr(), paddr);
             } else {
                 return false;
index 62b9b7002564bb868c1cd3067f655fbe8958407e..ba106fb6369362878e377b4fe1e2cff2c313a6f7 100644 (file)
@@ -169,7 +169,7 @@ Process::Process(ProcessParams * params)
 
     mmap_start = mmap_end = 0;
     nxm_start = nxm_end = 0;
-    pTable = new PageTable(this);
+    pTable = new PageTable(name(), M5_pid);
     // other parameters will be initialized when the program is loaded
 }
 
@@ -328,13 +328,21 @@ Process::sim_fd_obj(int tgt_fd)
     return &fd_map[tgt_fd];
 }
 
+void
+Process::allocateMem(Addr vaddr, int64_t size, bool clobber)
+{
+    int npages = divCeil(size, (int64_t)VMPageSize);
+    Addr paddr = system->allocPhysPages(npages);
+    pTable->map(vaddr, paddr, size, clobber);
+}
+
 bool
 Process::fixupStackFault(Addr vaddr)
 {
     // Check if this is already on the stack and there's just no page there
     // yet.
     if (vaddr >= stack_min && vaddr < stack_base) {
-        pTable->allocate(roundDown(vaddr, VMPageSize), VMPageSize);
+        allocateMem(roundDown(vaddr, VMPageSize), VMPageSize);
         return true;
     }
 
@@ -347,7 +355,7 @@ Process::fixupStackFault(Addr vaddr)
                 fatal("Maximum stack size exceeded\n");
             if (stack_base - stack_min > 8 * 1024 * 1024)
                 fatal("Over max stack size for one thread\n");
-            pTable->allocate(stack_min, TheISA::PageBytes);
+            allocateMem(stack_min, TheISA::PageBytes);
             inform("Increasing stack size by one page.");
         };
         return true;
index d48b1b463aeec2c2736620acd0d6b86675cee2db..4c31597b474663aeceefb1c0d28e980070a51237 100644 (file)
@@ -212,6 +212,8 @@ class Process : public SimObject
 
     virtual void syscall(int64_t callnum, ThreadContext *tc) = 0;
 
+    void allocateMem(Addr vaddr, int64_t size, bool clobber = false);
+
     /// Attempt to fix up a fault at vaddr by allocating a page on the stack.
     /// @return Whether the fault has been fixed.
     bool fixupStackFault(Addr vaddr);
index 6873d4aa4cc80b2426987b128c1b055dd88b51c8..203eaff2a1f05072ae8e0072897581fd7ebab2a9 100644 (file)
@@ -166,8 +166,7 @@ brkFunc(SyscallDesc *desc, int num, LiveProcess *p, ThreadContext *tc)
         for (ChunkGenerator gen(p->brk_point, new_brk - p->brk_point,
                                 VMPageSize); !gen.done(); gen.next()) {
             if (!p->pTable->translate(gen.addr()))
-                p->pTable->allocate(roundDown(gen.addr(), VMPageSize),
-                                    VMPageSize);
+                p->allocateMem(roundDown(gen.addr(), VMPageSize), VMPageSize);
 
             // if the address is already there, zero it out
             else {
index 9bcf58844f5c3caf61f617a682db720c01a1331a..50bf1a52f430360697d236f357358158ffcaf58e 100644 (file)
@@ -677,7 +677,7 @@ mremapFunc(SyscallDesc *desc, int callnum, LiveProcess *process, ThreadContext *
     if (new_length > old_length) {
         if ((start + old_length) == process->mmap_end) {
             uint64_t diff = new_length - old_length;
-            process->pTable->allocate(process->mmap_end, diff);
+            process->allocateMem(process->mmap_end, diff);
             process->mmap_end += diff;
             return start;
         } else {
@@ -691,15 +691,15 @@ mremapFunc(SyscallDesc *desc, int callnum, LiveProcess *process, ThreadContext *
                         process->mmap_end, process->mmap_end + new_length, new_length);
                 start = process->mmap_end;
                 // add on the remaining unallocated pages
-                process->pTable->allocate(start + old_length, new_length - old_length);
+                process->allocateMem(start + old_length,
+                                     new_length - old_length);
                 process->mmap_end += new_length;
                 warn("returning %08p as start\n", start);
                 return start;
             }
         }
     } else {
-        process->pTable->deallocate(start + new_length, old_length -
-                new_length);
+        process->pTable->unmap(start + new_length, old_length - new_length);
         return start;
     }
 }
@@ -1065,7 +1065,7 @@ mmapFunc(SyscallDesc *desc, int num, LiveProcess *p, ThreadContext *tc)
         }
     }
 
-    p->pTable->allocate(start, length, clobber);
+    p->allocateMem(start, length, clobber);
 
     return start;
 }
index 81a8a05742b405e45552eb5c5f9773226fce52b0..c58830c10970082d101b2cf8ec3f725747314efa 100644 (file)
@@ -275,10 +275,10 @@ System::replaceThreadContext(ThreadContext *tc, int context_id)
 
 #if !FULL_SYSTEM
 Addr
-System::new_page()
+System::allocPhysPages(int npages)
 {
     Addr return_addr = pagePtr << LogVMPageSize;
-    ++pagePtr;
+    pagePtr += npages;
     if (return_addr >= physmem->size())
         fatal("Out of memory, please increase size of physical memory.");
     return return_addr;
index a6bc47fc0b62137ceab10abb9a63d0415d2b8732..ed5193dfd4b0fea5c78395ebb6552b4455eb68e8 100644 (file)
@@ -287,7 +287,9 @@ class System : public SimObject
 
 #else
 
-    Addr new_page();
+    /// Allocate npages contiguous unused physical pages
+    /// @return Starting address of first page
+    Addr allocPhysPages(int npages);
 
 #endif // FULL_SYSTEM