diff --git a/base/process_util.h b/base/process_util.h
index fe1b4d2b42001..7801d4c57959a 100644
--- a/base/process_util.h
+++ b/base/process_util.h
@@ -323,12 +323,16 @@ class ProcessMetrics {
   ~ProcessMetrics();
 
   // Returns the current space allocated for the pagefile, in bytes (these pages
-  // may or may not be in memory).
+  // may or may not be in memory).  On Linux, this returns the total virtual
+  // memory size.
   size_t GetPagefileUsage() const;
   // Returns the peak space allocated for the pagefile, in bytes.
   size_t GetPeakPagefileUsage() const;
-  // Returns the current working set size, in bytes.
+  // Returns the current working set size, in bytes.  On Linux, this returns
+  // the resident set size.
   size_t GetWorkingSetSize() const;
+  // Returns the peak working set size, in bytes.
+  size_t GetPeakWorkingSetSize() const;
   // Returns private usage, in bytes. Private bytes is the amount
   // of memory currently allocated to a process that cannot be shared.
   // Note: returns 0 on unsupported OSes: prior to XP SP2.
diff --git a/base/process_util_linux.cc b/base/process_util_linux.cc
index b542e6fecefd5..178fbce51714e 100644
--- a/base/process_util_linux.cc
+++ b/base/process_util_linux.cc
@@ -25,6 +25,18 @@ enum ParsingState {
   KEY_VALUE
 };
 
+// Reads /proc/<pid>/stat and populates |proc_stats| with the values split by
+// spaces.
+void GetProcStats(pid_t pid, std::vector<std::string>* proc_stats) {
+  FilePath stat_file("/proc");
+  stat_file = stat_file.Append(IntToString(pid));
+  stat_file = stat_file.Append("stat");
+  std::string mem_stats;
+  if (!file_util::ReadFileToString(stat_file, &mem_stats))
+    return;
+  SplitString(mem_stats, ' ', proc_stats);
+}
+
 }  // namespace
 
 namespace base {
@@ -187,11 +199,46 @@ bool NamedProcessIterator::IncludeEntry() {
   return filter_->Includes(entry_.pid, entry_.ppid);
 }
 
+// On linux, we return vsize.
+size_t ProcessMetrics::GetPagefileUsage() const {
+  std::vector<std::string> proc_stats;
+  GetProcStats(process_, &proc_stats);
+  const size_t kVmSize = 22;
+  if (proc_stats.size() > kVmSize)
+    return static_cast<size_t>(StringToInt(proc_stats[kVmSize]));
+  return 0;
+}
+
+size_t ProcessMetrics::GetPeakPagefileUsage() const {
+  NOTIMPLEMENTED();
+  return 0;
+}
+
+// On linux, we return RSS.
+size_t ProcessMetrics::GetWorkingSetSize() const {
+  std::vector<std::string> proc_stats;
+  GetProcStats(process_, &proc_stats);
+  const size_t kVmRss = 23;
+  if (proc_stats.size() > kVmRss) {
+    size_t num_pages = static_cast<size_t>(StringToInt(proc_stats[kVmRss]));
+    return num_pages * getpagesize();
+  }
+  return 0;
+}
+
+size_t ProcessMetrics::GetPeakWorkingSetSize() const {
+  NOTIMPLEMENTED();
+  return 0;
+}
+
 // To have /proc/self/io file you must enable CONFIG_TASK_IO_ACCOUNTING
 // in your kernel configuration.
 bool ProcessMetrics::GetIOCounters(IoCounters* io_counters) const {
   std::string proc_io_contents;
-  if (!file_util::ReadFileToString(L"/proc/self/io", &proc_io_contents))
+  FilePath io_file("/proc");
+  io_file = io_file.Append(IntToString(process_));
+  io_file = io_file.Append("io");
+  if (!file_util::ReadFileToString(io_file, &proc_io_contents))
     return false;
 
   (*io_counters).OtherOperationCount = 0;
diff --git a/base/process_util_mac.mm b/base/process_util_mac.mm
index bcdaffe9bc233..de59896d9f63b 100644
--- a/base/process_util_mac.mm
+++ b/base/process_util_mac.mm
@@ -233,4 +233,24 @@ bool ProcessMetrics::GetIOCounters(IoCounters* io_counters) const {
   return false;
 }
 
+size_t ProcessMetrics::GetPagefileUsage() const {
+  NOTIMPLEMENTED();
+  return 0;
+}
+
+size_t ProcessMetrics::GetPeakPagefileUsage() const {
+  NOTIMPLEMENTED();
+  return 0;
+}
+
+size_t ProcessMetrics::GetWorkingSetSize() const {
+  NOTIMPLEMENTED();
+  return 0;
+}
+
+size_t ProcessMetrics::GetPeakWorkingSetSize() const {
+  NOTIMPLEMENTED();
+  return 0;
+}
+
 }  // namespace base
diff --git a/base/process_util_win.cc b/base/process_util_win.cc
index 265c26f03b09d..8b9ede863152a 100644
--- a/base/process_util_win.cc
+++ b/base/process_util_win.cc
@@ -520,6 +520,15 @@ size_t ProcessMetrics::GetWorkingSetSize() const {
   return 0;
 }
 
+// Returns the peak working set size, in bytes.
+size_t ProcessMetrics::GetPeakWorkingSetSize() const {
+  PROCESS_MEMORY_COUNTERS pmc;
+  if (GetProcessMemoryInfo(process_, &pmc, sizeof(pmc))) {
+    return pmc.PeakWorkingSetSize;
+  }
+  return 0;
+}
+
 size_t ProcessMetrics::GetPrivateBytes() const {
   // PROCESS_MEMORY_COUNTERS_EX is not supported until XP SP2.
   // GetProcessMemoryInfo() will simply fail on prior OS. So the requested
diff --git a/chrome/chrome.gyp b/chrome/chrome.gyp
index 0815db48cc2e0..87dde3db8d389 100644
--- a/chrome/chrome.gyp
+++ b/chrome/chrome.gyp
@@ -2912,6 +2912,7 @@
       'target_name': 'page_cycler_tests',
       'type': 'executable',
       'dependencies': [
+        'app',
         'chrome_resources',
         'chrome_strings',
         'test_support_ui',
diff --git a/chrome/test/page_cycler/page_cycler_test.cc b/chrome/test/page_cycler/page_cycler_test.cc
index 308581a3df15f..e3aae9643b756 100644
--- a/chrome/test/page_cycler/page_cycler_test.cc
+++ b/chrome/test/page_cycler/page_cycler_test.cc
@@ -16,7 +16,6 @@
 #include "chrome/test/automation/window_proxy.h"
 #include "chrome/test/chrome_process_util.h"
 #include "chrome/test/ui/ui_test.h"
-#include "chrome/test/perf/mem_usage.h"
 #include "googleurl/src/gurl.h"
 #include "net/base/net_util.h"
 
@@ -84,8 +83,6 @@ class PageCyclerTest : public UITest {
     ASSERT_FALSE(timings->empty());
   }
 
-#if defined(OS_WIN)
-  // TODO(port): Port chrome_process_util and remove windowsisms.
   void PrintIOPerfInfo(const char* test_name) {
     FilePath data_dir;
     PathService::Get(chrome::DIR_USER_DATA, &data_dir);
@@ -100,10 +97,10 @@ class PageCyclerTest : public UITest {
       }
 
       scoped_ptr<base::ProcessMetrics> process_metrics;
-      IO_COUNTERS io_counters;
       process_metrics.reset(
           base::ProcessMetrics::CreateProcessMetrics(process_handle));
-      ZeroMemory(&io_counters, sizeof(io_counters));
+      IoCounters io_counters;
+      memset(&io_counters, 0, sizeof(io_counters));
 
       if (process_metrics.get()->GetIOCounters(&io_counters)) {
         // Print out IO performance.  We assume that the values can be
@@ -163,35 +160,50 @@ class PageCyclerTest : public UITest {
 
     ChromeProcessList::const_iterator it;
     for (it = chrome_processes.begin(); it != chrome_processes.end(); ++it) {
-      size_t peak_virtual_size;
-      size_t current_virtual_size;
-      size_t peak_working_set_size;
-      size_t current_working_set_size;
-      if (GetMemoryInfo(*it, &peak_virtual_size, &current_virtual_size,
-                        &peak_working_set_size, &current_working_set_size)) {
-        std::string chrome_name = (*it == browser_process_pid) ? "_b" : "_r";
-
-        std::string trace_name(test_name);
-        PrintResult("vm_peak", chrome_name,
-                    "vm_pk" + chrome_name + trace_name,
-                    peak_virtual_size, "bytes",
-                    true /* important */);
-        PrintResult("vm_final", chrome_name,
-                    "vm_f" + chrome_name + trace_name,
-                    current_virtual_size, "bytes",
-                    false /* not important */);
-        PrintResult("ws_peak", chrome_name,
-                    "ws_pk" + chrome_name + trace_name,
-                    peak_working_set_size, "bytes",
-                    true /* important */);
-        PrintResult("ws_final", chrome_name,
-                    "ws_pk" + chrome_name + trace_name,
-                    current_working_set_size, "bytes",
-                    false /* not important */);
+      base::ProcessHandle process_handle;
+      if (!base::OpenProcessHandle(*it, &process_handle)) {
+        NOTREACHED();
       }
+
+      scoped_ptr<base::ProcessMetrics> process_metrics;
+      process_metrics.reset(
+          base::ProcessMetrics::CreateProcessMetrics(process_handle));
+
+      std::string chrome_name = (*it == browser_process_pid) ? "_b" : "_r";
+
+      std::string trace_name(test_name);
+#if defined(OS_WIN)
+      PrintResult("vm_peak", chrome_name,
+                  "vm_pk" + chrome_name + trace_name,
+                  process_metrics->GetPeakPagefileUsage(), "bytes",
+                  true /* important */);
+      PrintResult("vm_final", chrome_name,
+                  "vm_f" + chrome_name + trace_name,
+                  process_metrics->GetPagefileUsage(), "bytes",
+                  false /* not important */);
+      PrintResult("ws_peak", chrome_name,
+                  "ws_pk" + chrome_name + trace_name,
+                  process_metrics->GetPeakWorkingSetSize(), "bytes",
+                  true /* important */);
+      PrintResult("ws_final", chrome_name,
+                  "ws_f" + chrome_name + trace_name,
+                  process_metrics->GetWorkingSetSize(), "bytes",
+                  false /* not important */);
+#elif defined(OS_LINUX)
+      PrintResult("vm_size_final", chrome_name,
+                  "vm_size_f" + chrome_name + trace_name,
+                  process_metrics->GetPagefileUsage(), "bytes",
+                  true /* important */);
+      PrintResult("vm_rss_final", chrome_name,
+                  "vm_rss_f" + chrome_name + trace_name,
+                  process_metrics->GetWorkingSetSize(), "bytes",
+                  true /* important */);
+#else
+      NOTIMPLEMENTED();
+#endif
+      base::CloseProcessHandle(process_handle);
     }
   }
-#endif  // defined(OS_WIN)
 
   // When use_http is true, the test name passed here will be used directly in
   // the path to the test data, so it must be safe for use in a URL without
@@ -204,11 +216,8 @@ class PageCyclerTest : public UITest {
     if (timings.empty())
       return;
 
-#if defined(OS_WIN)
-    // TODO(port): Enable when Print{MemoryUsage,IOPerf}Info are ported.
     PrintMemoryUsageInfo("");
     PrintIOPerfInfo("");
-#endif  // defined(OS_WIN)
 
     wprintf(L"\nPages: [%ls]\n", pages.c_str());
     PrintResultList("times", "", "t", timings, "ms",
@@ -224,7 +233,13 @@ class PageCyclerReferenceTest : public PageCyclerTest {
     FilePath dir;
     PathService::Get(chrome::DIR_TEST_TOOLS, &dir);
     dir = dir.AppendASCII("reference_build");
+#if defined(OS_WIN)
     dir = dir.AppendASCII("chrome");
+#elif defined(OS_LINUX)
+    dir = dir.AppendASCII("chrome_linux");
+#elif defined(OS_MACOSX)
+    dir = dir.AppendASCII("chrome_mac");
+#endif
     browser_directory_ = dir;
     UITest::SetUp();
   }
@@ -236,11 +251,8 @@ class PageCyclerReferenceTest : public PageCyclerTest {
     if (timings.empty())
       return;
 
-#if defined(OS_WIN)
-    // TODO(port): Enable when Print{MemoryUsage,IOPerf}Info are ported.
     PrintMemoryUsageInfo("_ref");
     PrintIOPerfInfo("_ref");
-#endif  // defined(OS_WIN)
 
     PrintResultList("times", "", "t_ref", timings, "ms",
                     true /* important */);