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.
Showing the changes to include/uapi (1 of 2 files). Show all
Unified · Split
| @@ -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 any | |
| 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 | |
| 3 | + * Copyright (C) 2019 - 2023 Intel Corporation | |
| 15 | 4 | */ |
| 16 | 5 | #ifndef _UAPI_LINUX_UM_TIMETRAVEL_H |
| 17 | 6 | #define _UAPI_LINUX_UM_TIMETRAVEL_H |
| @@ -50,6 +39,36 @@ struct um_timetravel_msg { · 32 unmodified lines | ||
| 50 | 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 | + */ | |
| 48 | +enum 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 | + */ | |
| 65 | +enum 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 | 73 | * enum um_timetravel_ops - Operation codes |
| 55 | 74 | */ |
| @@ -57,7 +76,9 @@ enum um_timetravel_ops { · 1 unmodified line | ||
| 57 | 76 | /** |
| 58 | 77 | * @UM_TIMETRAVEL_ACK: response (ACK) to any previous message, |
| 59 | 78 | * this usually doesn't carry any data in the 'time' field |
| 60 | − * unless otherwise specified below | |
| 79 | + * 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 | 83 | UM_TIMETRAVEL_ACK = 0, |
| 63 | 84 | |
| @@ -136,4 +157,134 @@ enum um_timetravel_ops { · 72 unmodified lines | ||
| 136 | 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 | + */ | |
| 169 | +enum 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 | + */ | |
| 182 | +enum 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 | + */ | |
| 238 | +union 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 | + */ | |
| 276 | +struct 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 | 290 | #endif /* _UAPI_LINUX_UM_TIMETRAVEL_H */ |