History

um: add shared memory optimisation for time-travel=ext

With external time travel, a LOT of message can end up being exchanged on the socket, taking a significant amount of time just to do that. Add a new shared memory optimisation to that, where a number of changes are made: - the controller sends a client ID and a shared memory FD (and a logging FD we don't use) in the ACK message to the initial START - the shared memory holds the current time and the free_until value, so that there's no need to exchange messages for that - if the client that's running has shared memory support, any client (the running one included) can request the next time it wants to run inside the shared memory, rather than sending a message, by also updating the free_until value - when shared memory is enabled, RUN/WAIT messages no longer have an ACK, further cutting down on messages Together, this can reduce the number of messages very significantly, and reduce overall test/simulation run time.

Johannes Berg committed 2 years ago

Commit bfb80d81 parent e20f9b32 files · +283 −26Browse files

Showing the changes to include/uapi (1 of 2 files). Show all

Unified · Split

include/uapi/linux/um_timetravel.h+165−14
@@ -1,17 +1,6 @@
1/* SPDX-License-Identifier: BSD-3-Clause */
1/*2/*
2 * Permission to use, copy, modify, and/or distribute this software for any3 * Copyright (C) 2019 - 2023 Intel Corporation
3 * purpose with or without fee is hereby granted, provided that the above
4 * copyright notice and this permission notice appear in all copies.
5 *
6 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
7 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
8 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
9 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
10 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
11 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
12 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
13 *
14 * Copyright (C) 2019 Intel Corporation
15 */4 */
16#ifndef _UAPI_LINUX_UM_TIMETRAVEL_H5#ifndef _UAPI_LINUX_UM_TIMETRAVEL_H
17#define _UAPI_LINUX_UM_TIMETRAVEL_H6#define _UAPI_LINUX_UM_TIMETRAVEL_H
@@ -50,6 +39,36 @@ struct um_timetravel_msg { · 32 unmodified lines
50 __u64 time;39 __u64 time;
51};40};
52 41
42/* max number of file descriptors that can be sent/received in a message */
43#define UM_TIMETRAVEL_MAX_FDS 2
44
45/**
46 * enum um_timetravel_shared_mem_fds - fds sent in ACK message for START message
47 */
48enum um_timetravel_shared_mem_fds {
49 /**
50 * @UM_TIMETRAVEL_SHARED_MEMFD: Index of the shared memory file
51 * descriptor in the control message
52 */
53 UM_TIMETRAVEL_SHARED_MEMFD,
54 /**
55 * @UM_TIMETRAVEL_SHARED_LOGFD: Index of the logging file descriptor
56 * in the control message
57 */
58 UM_TIMETRAVEL_SHARED_LOGFD,
59 UM_TIMETRAVEL_SHARED_MAX_FDS,
60};
61
62/**
63 * enum um_timetravel_start_ack - ack-time mask for start message
64 */
65enum um_timetravel_start_ack {
66 /**
67 * @UM_TIMETRAVEL_START_ACK_ID: client ID that controller allocated.
68 */
69 UM_TIMETRAVEL_START_ACK_ID = 0xffff,
70};
71
53/**72/**
54 * enum um_timetravel_ops - Operation codes73 * enum um_timetravel_ops - Operation codes
55 */74 */
@@ -57,7 +76,9 @@ enum um_timetravel_ops { · 1 unmodified line
57 /**76 /**
58 * @UM_TIMETRAVEL_ACK: response (ACK) to any previous message,77 * @UM_TIMETRAVEL_ACK: response (ACK) to any previous message,
59 * this usually doesn't carry any data in the 'time' field78 * this usually doesn't carry any data in the 'time' field
60 * unless otherwise specified below79 * unless otherwise specified below, note: while using shared
80 * memory no ACK for WAIT and RUN messages, for more info see
81 * &struct um_timetravel_schedshm.
61 */82 */
62 UM_TIMETRAVEL_ACK = 0,83 UM_TIMETRAVEL_ACK = 0,
63 84
@@ -136,4 +157,134 @@ enum um_timetravel_ops { · 72 unmodified lines
136 UM_TIMETRAVEL_BROADCAST = 9,157 UM_TIMETRAVEL_BROADCAST = 9,
137};158};
138 159
160/* version of struct um_timetravel_schedshm */
161#define UM_TIMETRAVEL_SCHEDSHM_VERSION 2
162
163/**
164 * enum um_timetravel_schedshm_cap - time travel capabilities of every client
165 *
166 * These flags must be set immediately after processing the ACK to
167 * the START message, before sending any message to the controller.
168 */
169enum um_timetravel_schedshm_cap {
170 /**
171 * @UM_TIMETRAVEL_SCHEDSHM_CAP_TIME_SHARE: client can read current time
172 * update internal time request to shared memory and read
173 * free until and send no Ack on RUN and doesn't expect ACK on
174 * WAIT.
175 */
176 UM_TIMETRAVEL_SCHEDSHM_CAP_TIME_SHARE = 0x1,
177};
178
179/**
180 * enum um_timetravel_schedshm_flags - time travel flags of every client
181 */
182enum um_timetravel_schedshm_flags {
183 /**
184 * @UM_TIMETRAVEL_SCHEDSHM_FLAGS_REQ_RUN: client has a request to run.
185 * It's set by client when it has a request to run, if (and only
186 * if) the @running_id points to a client that is able to use
187 * shared memory, i.e. has %UM_TIMETRAVEL_SCHEDSHM_CAP_TIME_SHARE
188 * (this includes the client itself). Otherwise, a message must
189 * be used.
190 */
191 UM_TIMETRAVEL_SCHEDSHM_FLAGS_REQ_RUN = 0x1,
192};
193
194/**
195 * DOC: Time travel shared memory overview
196 *
197 * The main purpose of the shared memory is to avoid all time travel message
198 * that don't need any action, for example current time can be held in shared
199 * memory without the need of any client to send a message UM_TIMETRAVEL_GET
200 * in order to know what's the time.
201 *
202 * Since this is shared memory with all clients and controller and controller
203 * creates the shared memory space, all time values are absolute to controller
204 * time. So first time client connects to shared memory mode it should take the
205 * current_time value in shared memory and keep it internally as a diff to
206 * shared memory times, and once shared memory is initialized, any interaction
207 * with the controller must happen in the controller time domain, including any
208 * messages (for clients that are not using shared memory, the controller will
209 * handle an offset and make the clients think they start at time zero.)
210 *
211 * Along with the shared memory file descriptor is sent to the client a logging
212 * file descriptor, to have all logs related to shared memory,
213 * logged into one place. note: to have all logs synced into log file at write,
214 * file should be flushed (fflush) after writing to it.
215 *
216 * To avoid memory corruption, we define below for each field who can write to
217 * it at what time, defined in the structure fields.
218 *
219 * To avoid having to pack this struct, all fields in it must be naturally aligned
220 * (i.e. aligned to their size).
221 */
222
223/**
224 * union um_timetravel_schedshm_client - UM time travel client struct
225 *
226 * Every entity using the shared memory including the controller has a place in
227 * the um_timetravel_schedshm clients array, that holds info related to the client
228 * using the shared memory, and can be set only by the client after it gets the
229 * fd memory.
230 *
231 * @capa: bit fields with client capabilities see
232 * &enum um_timetravel_schedshm_cap, set by client once after getting the
233 * shared memory file descriptor.
234 * @flags: bit fields for flags see &enum um_timetravel_schedshm_flags for doc.
235 * @req_time: request time to run, set by client on every request it needs.
236 * @name: unique id sent to the controller by client with START message.
237 */
238union um_timetravel_schedshm_client {
239 struct {
240 __u32 capa;
241 __u32 flags;
242 __u64 req_time;
243 __u64 name;
244 };
245 char reserve[128]; /* reserved for future usage */
246};
247
248/**
249 * struct um_timetravel_schedshm - UM time travel shared memory struct
250 *
251 * @hdr: header fields:
252 * @version: Current version struct UM_TIMETRAVEL_SCHEDSHM_VERSION,
253 * set by controller once at init, clients must check this after mapping
254 * and work without shared memory if they cannot handle the indicated
255 * version.
256 * @len: Length of all the memory including header (@hdr), clients should once
257 * per connection first mmap the header and take the length (@len) to remap the entire size.
258 * This is done in order to support dynamic struct size letting number of
259 * clients be dynamic based on controller support.
260 * @free_until: Stores the next request to run by any client, in order for the
261 * current client to know how long it can still run. A client needs to (at
262 * least) reload this value immediately after communicating with any other
263 * client, since the controller will update this field when a new request
264 * is made by any client. Clients also must update this value when they
265 * insert/update an own request into the shared memory while not running
266 * themselves, and the new request is before than the current value.
267 * current_time: Current time, can only be set by the client in running state
268 * (indicated by @running_id), though that client may only run until @free_until,
269 * so it must remain smaller than @free_until.
270 * @running_id: The current client in state running, set before a client is
271 * notified that it's now running.
272 * @max_clients: size of @clients array, set once at init by the controller.
273 * @clients: clients array see &union um_timetravel_schedshm_client for doc,
274 * set only by client.
275 */
276struct um_timetravel_schedshm {
277 union {
278 struct {
279 __u32 version;
280 __u32 len;
281 __u64 free_until;
282 __u64 current_time;
283 __u16 running_id;
284 __u16 max_clients;
285 };
286 char hdr[4096]; /* align to 4K page size */
287 };
288 union um_timetravel_schedshm_client clients[];
289};
139#endif /* _UAPI_LINUX_UM_TIMETRAVEL_H */290#endif /* _UAPI_LINUX_UM_TIMETRAVEL_H */