system/ram-discard-manager: drop replay from source interface
Remove replay_populated and replay_discarded from RamDiscardSourceClass now that the RamDiscardManager handles replay iteration internally via is_populated. Remove the now-dead replay methods, helpers, and for_each_populated/discarded_section() from ram-block-attributes, which was the last source still carrying this code. Reviewed-by: Peter Xu <peterx@redhat.com> Acked-by: David Hildenbrand <david@kernel.org> Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com> Link: https://lore.kernel.org/r/20260604-rdm5-v5-6-5768e6a0943d@redhat.com Signed-off-by: Peter Xu <peterx@redhat.com>
Marc-André Lureau committed
Jun 4, 2026 at 17:43 UTC
f46a11c563c5e0d64407f076f8589121fa86f0b0
2 files changed
+10
-172
include/system/ram-discard-manager.h
+10
-42
@@ -77,8 +77,8 @@ static inline void ram_discard_listener_init(RamDiscardListener *rdl,
77
/**
78
* typedef ReplayRamDiscardState:
79
*
80
- * The callback handler for #RamDiscardSourceClass.replay_populated/
81
- * #RamDiscardSourceClass.replay_discarded to invoke on populated/discarded
80
+ * The callback handler used by ram_discard_manager_replay_populated() and
81
+ * ram_discard_manager_replay_discarded() to invoke on populated/discarded
82
* parts.
83
*
84
* @section: the #MemoryRegionSection of populated/discarded part
@@ -134,42 +134,6 @@ struct RamDiscardSourceClass {
134
*/
135
bool (*is_populated)(const RamDiscardSource *rds,
136
const MemoryRegionSection *section);
137
-
138
- /**
139
- * @replay_populated:
140
- *
141
- * Call the #ReplayRamDiscardState callback for all populated parts within
142
- * the #MemoryRegionSection via the #RamDiscardSource.
143
- *
144
- * In case any call fails, no further calls are made.
145
- *
146
- * @rds: the #RamDiscardSource
147
- * @section: the #MemoryRegionSection
148
- * @replay_fn: the #ReplayRamDiscardState callback
149
- * @opaque: pointer to forward to the callback
150
- *
151
- * Returns 0 on success, or a negative error if any notification failed.
152
- */
153
- int (*replay_populated)(const RamDiscardSource *rds,
154
- const MemoryRegionSection *section,
155
- ReplayRamDiscardState replay_fn, void *opaque);
156
-
157
- /**
158
- * @replay_discarded:
159
- *
160
- * Call the #ReplayRamDiscardState callback for all discarded parts within
161
- * the #MemoryRegionSection via the #RamDiscardSource.
162
- *
163
- * @rds: the #RamDiscardSource
164
- * @section: the #MemoryRegionSection
165
- * @replay_fn: the #ReplayRamDiscardState callback
166
- * @opaque: pointer to forward to the callback
167
- *
168
- * Returns 0 on success, or a negative error if any notification failed.
169
- */
170
- int (*replay_discarded)(const RamDiscardSource *rds,
171
- const MemoryRegionSection *section,
172
- ReplayRamDiscardState replay_fn, void *opaque);
137
};
138
139
/**
@@ -226,8 +190,10 @@ bool ram_discard_manager_is_populated(const RamDiscardManager *rdm,
190
/**
191
* ram_discard_manager_replay_populated:
192
*
229
- * A wrapper to call the #RamDiscardSourceClass.replay_populated callback
230
- * of the #RamDiscardSource sources.
193
+ * Iterate the given #MemoryRegionSection at minimum granularity, calling
194
+ * #RamDiscardSourceClass.is_populated for each chunk, and invoke @replay_fn
195
+ * for each contiguous populated range. In case any call fails, no further
196
+ * calls are made.
197
*
198
* @rdm: the #RamDiscardManager
199
* @section: the #MemoryRegionSection
@@ -244,8 +210,10 @@ int ram_discard_manager_replay_populated(const RamDiscardManager *rdm,
210
/**
211
* ram_discard_manager_replay_discarded:
212
*
247
- * A wrapper to call the #RamDiscardSourceClass.replay_discarded callback
248
- * of the #RamDiscardSource sources.
213
+ * Iterate the given #MemoryRegionSection at minimum granularity, calling
214
+ * #RamDiscardSourceClass.is_populated for each chunk, and invoke @replay_fn
215
+ * for each contiguous discarded range. In case any call fails, no further
216
+ * calls are made.
217
*
218
* @rdm: the #RamDiscardManager
219
* @section: the #MemoryRegionSection
system/ram-block-attributes.c
-130
@@ -32,106 +32,6 @@ ram_block_attributes_get_block_size(void)
32
return qemu_real_host_page_size();
33
}
34
35
-typedef int (*ram_block_attributes_section_cb)(MemoryRegionSection *s,
36
- void *arg);
37
-
38
-static int
39
-ram_block_attributes_for_each_populated_section(const RamBlockAttributes *attr,
40
- const MemoryRegionSection *section,
41
- void *arg,
42
- ram_block_attributes_section_cb cb)
43
-{
44
- unsigned long first_bit, last_bit;
45
- uint64_t offset, size;
46
- const size_t block_size = ram_block_attributes_get_block_size();
47
- int ret = 0;
48
-
49
- first_bit = section->offset_within_region / block_size;
50
- first_bit = find_next_bit(attr->bitmap, attr->bitmap_size,
51
- first_bit);
52
-
53
- while (first_bit < attr->bitmap_size) {
54
- MemoryRegionSection tmp = *section;
55
-
56
- offset = first_bit * block_size;
57
- last_bit = find_next_zero_bit(attr->bitmap, attr->bitmap_size,
58
- first_bit + 1) - 1;
59
- size = (last_bit - first_bit + 1) * block_size;
60
-
61
- if (!memory_region_section_intersect_range(&tmp, offset, size)) {
62
- break;
63
- }
64
-
65
- ret = cb(&tmp, arg);
66
- if (ret) {
67
- error_report("%s: Failed to notify RAM discard listener: %s",
68
- __func__, strerror(-ret));
69
- break;
70
- }
71
-
72
- first_bit = find_next_bit(attr->bitmap, attr->bitmap_size,
73
- last_bit + 2);
74
- }
75
-
76
- return ret;
77
-}
78
-
79
-static int
80
-ram_block_attributes_for_each_discarded_section(const RamBlockAttributes *attr,
81
- const MemoryRegionSection *section,
82
- void *arg,
83
- ram_block_attributes_section_cb cb)
84
-{
85
- unsigned long first_bit, last_bit;
86
- uint64_t offset, size;
87
- const size_t block_size = ram_block_attributes_get_block_size();
88
- int ret = 0;
89
-
90
- first_bit = section->offset_within_region / block_size;
91
- first_bit = find_next_zero_bit(attr->bitmap, attr->bitmap_size,
92
- first_bit);
93
-
94
- while (first_bit < attr->bitmap_size) {
95
- MemoryRegionSection tmp = *section;
96
-
97
- offset = first_bit * block_size;
98
- last_bit = find_next_bit(attr->bitmap, attr->bitmap_size,
99
- first_bit + 1) - 1;
100
- size = (last_bit - first_bit + 1) * block_size;
101
-
102
- if (!memory_region_section_intersect_range(&tmp, offset, size)) {
103
- break;
104
- }
105
-
106
- ret = cb(&tmp, arg);
107
- if (ret) {
108
- error_report("%s: Failed to notify RAM discard listener: %s",
109
- __func__, strerror(-ret));
110
- break;
111
- }
112
-
113
- first_bit = find_next_zero_bit(attr->bitmap,
114
- attr->bitmap_size,
115
- last_bit + 2);
116
- }
117
-
118
- return ret;
119
-}
120
-
121
-
122
-typedef struct RamBlockAttributesReplayData {
123
- ReplayRamDiscardState fn;
124
- void *opaque;
125
-} RamBlockAttributesReplayData;
126
-
127
-static int ram_block_attributes_rds_replay_cb(MemoryRegionSection *section,
128
- void *arg)
129
-{
130
- RamBlockAttributesReplayData *data = arg;
131
-
132
- return data->fn(section, data->opaque);
133
-}
134
-
35
/* RamDiscardSource interface implementation */
36
static uint64_t
37
ram_block_attributes_rds_get_min_granularity(const RamDiscardSource *rds,
@@ -159,34 +59,6 @@ ram_block_attributes_rds_is_populated(const RamDiscardSource *rds,
59
return first_discarded_bit > last_bit;
60
}
61
162
-static int
163
-ram_block_attributes_rds_replay_populated(const RamDiscardSource *rds,
164
- const MemoryRegionSection *section,
165
- ReplayRamDiscardState replay_fn,
166
- void *opaque)
167
-{
168
- RamBlockAttributes *attr = RAM_BLOCK_ATTRIBUTES(rds);
169
- RamBlockAttributesReplayData data = { .fn = replay_fn, .opaque = opaque };
170
-
171
- g_assert(section->mr == attr->ram_block->mr);
172
- return ram_block_attributes_for_each_populated_section(attr, section, &data,
173
- ram_block_attributes_rds_replay_cb);
174
-}
175
-
176
-static int
177
-ram_block_attributes_rds_replay_discarded(const RamDiscardSource *rds,
178
- const MemoryRegionSection *section,
179
- ReplayRamDiscardState replay_fn,
180
- void *opaque)
181
-{
182
- RamBlockAttributes *attr = RAM_BLOCK_ATTRIBUTES(rds);
183
- RamBlockAttributesReplayData data = { .fn = replay_fn, .opaque = opaque };
184
-
185
- g_assert(section->mr == attr->ram_block->mr);
186
- return ram_block_attributes_for_each_discarded_section(attr, section, &data,
187
- ram_block_attributes_rds_replay_cb);
188
-}
189
-
62
static bool
63
ram_block_attributes_is_valid_range(RamBlockAttributes *attr, uint64_t offset,
64
uint64_t size)
@@ -346,6 +218,4 @@ static void ram_block_attributes_class_init(ObjectClass *klass,
218
219
rdsc->get_min_granularity = ram_block_attributes_rds_get_min_granularity;
220
rdsc->is_populated = ram_block_attributes_rds_is_populated;
349
- rdsc->replay_populated = ram_block_attributes_rds_replay_populated;
350
- rdsc->replay_discarded = ram_block_attributes_rds_replay_discarded;
221
}