@@ -212,3 +212,117 @@ Finally we move core 4-7 over to the new group and make sure that the
212
212
kernel and the tasks running there get 50% of the cache.
213
213
214
214
# echo C0 > p0/cpus
215
+
216
+ 4) Locking between applications
217
+
218
+ Certain operations on the resctrl filesystem, composed of read/writes
219
+ to/from multiple files, must be atomic.
220
+
221
+ As an example, the allocation of an exclusive reservation of L3 cache
222
+ involves:
223
+
224
+ 1. Read the cbmmasks from each directory
225
+ 2. Find a contiguous set of bits in the global CBM bitmask that is clear
226
+ in any of the directory cbmmasks
227
+ 3. Create a new directory
228
+ 4. Set the bits found in step 2 to the new directory "schemata" file
229
+
230
+ If two applications attempt to allocate space concurrently then they can
231
+ end up allocating the same bits so the reservations are shared instead of
232
+ exclusive.
233
+
234
+ To coordinate atomic operations on the resctrlfs and to avoid the problem
235
+ above, the following locking procedure is recommended:
236
+
237
+ Locking is based on flock, which is available in libc and also as a shell
238
+ script command
239
+
240
+ Write lock:
241
+
242
+ A) Take flock(LOCK_EX) on /sys/fs/resctrl
243
+ B) Read/write the directory structure.
244
+ C) funlock
245
+
246
+ Read lock:
247
+
248
+ A) Take flock(LOCK_SH) on /sys/fs/resctrl
249
+ B) If success read the directory structure.
250
+ C) funlock
251
+
252
+ Example with bash:
253
+
254
+ # Atomically read directory structure
255
+ $ flock -s /sys/fs/resctrl/ find /sys/fs/resctrl
256
+
257
+ # Read directory contents and create new subdirectory
258
+
259
+ $ cat create-dir.sh
260
+ find /sys/fs/resctrl/ > output.txt
261
+ mask = function-of(output.txt)
262
+ mkdir /sys/fs/resctrl/newres/
263
+ echo mask > /sys/fs/resctrl/newres/schemata
264
+
265
+ $ flock /sys/fs/resctrl/ ./create-dir.sh
266
+
267
+ Example with C:
268
+
269
+ /*
270
+ * Example code do take advisory locks
271
+ * before accessing resctrl filesystem
272
+ */
273
+ #include <sys/file.h>
274
+ #include <stdlib.h>
275
+
276
+ void resctrl_take_shared_lock(int fd)
277
+ {
278
+ int ret;
279
+
280
+ /* take shared lock on resctrl filesystem */
281
+ ret = flock(fd, LOCK_SH);
282
+ if (ret) {
283
+ perror("flock");
284
+ exit(-1);
285
+ }
286
+ }
287
+
288
+ void resctrl_take_exclusive_lock(int fd)
289
+ {
290
+ int ret;
291
+
292
+ /* release lock on resctrl filesystem */
293
+ ret = flock(fd, LOCK_EX);
294
+ if (ret) {
295
+ perror("flock");
296
+ exit(-1);
297
+ }
298
+ }
299
+
300
+ void resctrl_release_lock(int fd)
301
+ {
302
+ int ret;
303
+
304
+ /* take shared lock on resctrl filesystem */
305
+ ret = flock(fd, LOCK_UN);
306
+ if (ret) {
307
+ perror("flock");
308
+ exit(-1);
309
+ }
310
+ }
311
+
312
+ void main(void)
313
+ {
314
+ int fd, ret;
315
+
316
+ fd = open("/sys/fs/resctrl", O_DIRECTORY);
317
+ if (fd == -1) {
318
+ perror("open");
319
+ exit(-1);
320
+ }
321
+ resctrl_take_shared_lock(fd);
322
+ /* code to read directory contents */
323
+ resctrl_release_lock(fd);
324
+
325
+ resctrl_take_exclusive_lock(fd);
326
+ /* code to read and write directory contents */
327
+ resctrl_release_lock(fd);
328
+ }
0 commit comments