File: userspace_swap.h

package info (click to toggle)
chromium 139.0.7258.127-1
  • links: PTS, VCS
  • area: main
  • in suites:
  • size: 6,122,068 kB
  • sloc: cpp: 35,100,771; ansic: 7,163,530; javascript: 4,103,002; python: 1,436,920; asm: 946,517; xml: 746,709; pascal: 187,653; perl: 88,691; sh: 88,436; objc: 79,953; sql: 51,488; cs: 44,583; fortran: 24,137; makefile: 22,147; tcl: 15,277; php: 13,980; yacc: 8,984; ruby: 7,485; awk: 3,720; lisp: 3,096; lex: 1,327; ada: 727; jsp: 228; sed: 36
file content (198 lines) | stat: -rw-r--r-- 8,066 bytes parent folder | download | duplicates (6)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
// Copyright 2020 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#ifndef CHROMEOS_ASH_COMPONENTS_MEMORY_USERSPACE_SWAP_USERSPACE_SWAP_H_
#define CHROMEOS_ASH_COMPONENTS_MEMORY_USERSPACE_SWAP_USERSPACE_SWAP_H_

#include <sys/mman.h>
#include <cstdint>
#include <vector>

#include "base/component_export.h"
#include "base/process/process_handle.h"
#include "base/threading/platform_thread.h"
#include "base/time/time.h"
#include "chromeos/ash/components/memory/userspace_swap/region.h"
#include "chromeos/ash/components/memory/userspace_swap/userspace_swap.mojom.h"
#include "mojo/public/cpp/bindings/remote.h"
#include "services/resource_coordinator/public/mojom/memory_instrumentation/memory_instrumentation.mojom.h"

#ifndef MREMAP_DONTUNMAP
#define MREMAP_DONTUNMAP 4
#endif

namespace userspace_swap {
namespace mojom {
class UserspaceSwap;
}  // namespace mojom
}  // namespace userspace_swap

// This file is for containing the browser and renderer common userspace swap
// components such as helper functions and structures.
namespace ash {
namespace memory {
namespace userspace_swap {

class UserfaultFD;
class SwapFile;

// UserspaceSwapConfig is a structure which contains all configuration values
// for userspace swap.
struct COMPONENT_EXPORT(USERSPACE_SWAP) UserspaceSwapConfig {
  UserspaceSwapConfig();
  UserspaceSwapConfig(const UserspaceSwapConfig& other);

  // Returns the Current UserspaceSwapConfig.
  static const UserspaceSwapConfig& Get();
  friend std::ostream& operator<<(std::ostream& out,
                                  const UserspaceSwapConfig& c);

  // enabled is true if the userspace swap feature is enabled.
  bool enabled;

  // Number of pages per region represents the number of pages we will use for
  // each chunk we attempt to swap at a time.
  uint16_t number_of_pages_per_region;

  // If true the swap file will be compressed on disk.
  bool use_compressed_swap_file;

  // Minimum disk space swap available is the lower limit of free disk space on
  // the swap device. If the available space on the device backing storage
  // is lower than this value no further swapping is allowed, this prevents
  // userspace swap from exhausting disk space.
  uint64_t minimum_swap_disk_space_available;

  // Maximum swap disk space represents the maxmium disk space userspace swap is
  // allowed to use across all renderers.
  uint64_t maximum_swap_disk_space_bytes;

  // Renderer maximum disk file size represents the maximum size a swap file may
  // for an individual renderer.
  uint64_t renderer_maximum_disk_swap_file_size_bytes;

  // Renderer region limit per swap limits the number of regions that that an
  // individual renderer can swap on each swap, note that each region is
  // configured by the number of pages per region so these two together limit
  // the total number of pages per swap round of a process.
  uint32_t renderer_region_limit_per_swap;

  // The blocked refault time is the minimum time a region must be swapped out
  // without being blocked. This prevents disk thrashing where if a region
  // is immediately refaulted we don't want to swap it again as it'll likely be
  // needed in the future, for example, if a region has a blocked refault time
  // of 30s if it is refaulted in less than 30s it will never be swapped again.
  base::TimeDelta blocked_refault_time;

  // Graph walk frequency represents the (shortest) duration in which you can
  // walk the graph, that is, a graph walk frequency of 60s means that you will
  // not walk the graph more than once every 60s.
  base::TimeDelta graph_walk_frequency;

  // The process Swap frequency limits the frequency on which a process may be
  // swapped, for example 60s means that a process will not be swapped more than
  // once every 60s.
  base::TimeDelta process_swap_frequency;

  // Invisible Time Before Swap is the amount of time a renderer must be
  // invisible before it can be considered for swap.
  base::TimeDelta invisible_time_before_swap;

  // Swap on freeze, if true will swap a process when all frames are frozen.
  bool swap_on_freeze;

  // Swap on moderate pressure will walk the graph (based on the frequency of
  // graph walk frequency) looking for renderers to swap based on visibility
  // state.
  bool swap_on_moderate_pressure;

  // Shuffle maps order will randomly shuffle the processes maps ordering before
  // swapping, it does this so that subsequent swaps can start from different
  // memory regions.
  bool shuffle_maps_on_swap;
};

// Returns true if the kernel supports all the features necessary for userspace
// swap. These features are userfaultfd(2) and mremap(2) with MREMAP_DONTUNMAP
// support this method is the source of truth for the browser UserspaceSwap and
// the rendererer UserspaceSwapImpl.
COMPONENT_EXPORT(USERSPACE_SWAP) bool KernelSupportsUserspaceSwap();

// Returns true if there is kernel support for userspace swap and the feature is
// enabled.
COMPONENT_EXPORT(USERSPACE_SWAP) bool UserspaceSwapSupportedAndEnabled();

// GetGlobalSwapDiskspaceUsed returns the number of bytes currently on disk for
// ALL renderers.
COMPONENT_EXPORT(USERSPACE_SWAP) uint64_t GetGlobalSwapDiskspaceUsed();

// GetGlobalMemoryReclaimed returns the number of bytes (physical memory) which
// has been reclaimed by userspace swap. This number may not match what is on
// disk due to encryption and compression.
COMPONENT_EXPORT(USERSPACE_SWAP) uint64_t GetGlobalMemoryReclaimed();

// DisableSwapGlobally is the global swap kill switch, it prevents any further
// swapping.
COMPONENT_EXPORT(USERSPACE_SWAP) void DisableSwapGlobally();

// Returns true if swap is allowed (globally).
COMPONENT_EXPORT(USERSPACE_SWAP) bool IsSwapAllowedGlobally();

// RendererSwapData is attached to a ProcessNode and owned by the ProcessNode on
// the PerformanceManager graph.
class COMPONENT_EXPORT(USERSPACE_SWAP) RendererSwapData {
 public:
  virtual ~RendererSwapData();

  static std::unique_ptr<RendererSwapData> Create(
      int render_process_host_id,
      base::ProcessId pid,
      std::unique_ptr<UserfaultFD> uffd,
      std::unique_ptr<SwapFile> swap_file,
      const Region& swap_remap_area,
      mojo::PendingRemote<::userspace_swap::mojom::UserspaceSwap> remote);

  // Returns the Render Process Host ID associated with this RendererSwapData.
  virtual int render_process_host_id() const = 0;

  // If true this renderer has not been disallowed swap.
  virtual bool SwapAllowed() const = 0;

  // DisallowSwap prevents further swapping of this renderer. This cannot be
  // unset.
  virtual void DisallowSwap() = 0;

  // There is a subtle difference between SwapdiskspaceWrittenBytes and
  // SwapDiskspaceUsedBytes. Because punching a hole in a file may not reclaim a
  // block on disk only after the entire block has been punched will the space
  // actually be reclaimed on disk. However, SwapDiskspaceWrittenBytes will
  // contain the total number of bytes that we think are on disk, these numbers
  // will be equal when there is no waste of block space on disk.
  virtual uint64_t SwapDiskspaceWrittenBytes() const = 0;
  virtual uint64_t SwapDiskspaceUsedBytes() const = 0;

  virtual uint64_t ReclaimedBytes() const = 0;

 protected:
  RendererSwapData();
};

// SwapRenderer will initiate a swap on the renderer belonging to the
// RendererSwapData |data|. |size_limit_bytes| is a limit imposed by the system
// based on settings.
COMPONENT_EXPORT(USERSPACE_SWAP)
bool SwapRenderer(RendererSwapData* data, size_t size_limit_bytes);

// GetPartitionAllocSuperPagesInUse will return |max_superpages| worth of
// regions that are currently allocated by PartitionAlloc.
COMPONENT_EXPORT(USERSPACE_SWAP)
bool GetPartitionAllocSuperPagesInUse(
    int32_t max_superpages,
    std::vector<::userspace_swap::mojom::MemoryRegionPtr>& regions);

}  // namespace userspace_swap
}  // namespace memory
}  // namespace ash

#endif  // CHROMEOS_ASH_COMPONENTS_MEMORY_USERSPACE_SWAP_USERSPACE_SWAP_H_