Skip to content

Commit 7f68682

Browse files
committed
intelrdt: add support for generic schemata update
This patch enhances Intel RDT management by enabling updates to the generic `schemata` file within a resctrl group. Closes: #1746 Signed-off-by: Giuseppe Scrivano <[email protected]>
1 parent ca40dac commit 7f68682

File tree

7 files changed

+94
-22
lines changed

7 files changed

+94
-22
lines changed

src/libcrun/container.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4688,7 +4688,7 @@ libcrun_container_update_intel_rdt (libcrun_context_t *context, const char *id,
46884688
if (UNLIKELY (container == NULL))
46894689
return -1;
46904690

4691-
return libcrun_update_intel_rdt (id, container, update->l3_cache_schema, update->mem_bw_schema, err);
4691+
return libcrun_update_intel_rdt (id, container, update->l3_cache_schema, update->mem_bw_schema, update->schemata, err);
46924692
}
46934693

46944694
static int

src/libcrun/container.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -271,6 +271,7 @@ struct libcrun_intel_rdt_update
271271
{
272272
const char *l3_cache_schema;
273273
const char *mem_bw_schema;
274+
char *const *schemata;
274275
};
275276

276277
LIBCRUN_PUBLIC int libcrun_container_update_intel_rdt (libcrun_context_t *context, const char *id,

src/libcrun/intelrdt.c

Lines changed: 34 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,8 @@
2626
#include <sched.h>
2727
#include <fcntl.h>
2828
#include <sys/vfs.h>
29+
#include <unistd.h>
30+
#include <errno.h>
2931

3032
#define INTEL_RDT_MOUNT_POINT "/sys/fs/resctrl"
3133
#define SCHEMATA_FILE "schemata"
@@ -45,10 +47,21 @@ is_rdt_mounted (libcrun_error_t *err)
4547
return sfs.f_type == RDTGROUP_SUPER_MAGIC;
4648
}
4749

48-
static int
49-
get_rdt_value (char **out, const char *l3_cache_schema, const char *mem_bw_schema)
50+
int
51+
get_rdt_value (char **out, const char *l3_cache_schema, const char *mem_bw_schema, char *const *schemata)
5052
{
51-
return xasprintf (out, "%s%s%s\n", l3_cache_schema ?: "", (l3_cache_schema && mem_bw_schema) ? "\n" : "", mem_bw_schema ?: "");
53+
cleanup_free char *schemata_joined = NULL;
54+
size_t schemata_size = 0;
55+
56+
while (schemata && schemata[schemata_size])
57+
schemata_size++;
58+
59+
if (schemata_size > 0)
60+
schemata_joined = str_join_array (0, schemata_size, schemata, "\n");
61+
62+
return xasprintf (out, "%s%s%s%s%s\n", l3_cache_schema ?: "",
63+
(l3_cache_schema && mem_bw_schema) ? "\n" : "", mem_bw_schema ?: "",
64+
((l3_cache_schema || mem_bw_schema) && schemata_joined) ? "\n" : "", schemata_joined ?: "");
5265
}
5366

5467
struct key_value
@@ -189,12 +202,12 @@ validate_rdt_configuration (const char *name, const char *l3_cache_schema, const
189202
}
190203

191204
static int
192-
write_intelrdt_string (int fd, const char *file, const char *l3_cache_schema, const char *mem_bw_schema, libcrun_error_t *err)
205+
write_intelrdt_string (int fd, const char *file, const char *l3_cache_schema, const char *mem_bw_schema, char *const *schemata, libcrun_error_t *err)
193206
{
194207
cleanup_free char *formatted = NULL;
195208
int len, ret;
196209

197-
len = get_rdt_value (&formatted, l3_cache_schema, mem_bw_schema);
210+
len = get_rdt_value (&formatted, l3_cache_schema, mem_bw_schema, schemata);
198211
if (len < 0)
199212
return crun_make_error (err, errno, "internal error get_rdt_value");
200213

@@ -237,6 +250,8 @@ resctl_create (const char *name, bool explicit_clos_id, bool *created, const cha
237250
int exist;
238251
int ret;
239252

253+
*created = false;
254+
240255
ret = is_rdt_mounted (err);
241256
if (UNLIKELY (ret < 0))
242257
return ret;
@@ -269,9 +284,12 @@ resctl_create (const char *name, bool explicit_clos_id, bool *created, const cha
269284
return validate_rdt_configuration (name, l3_cache_schema, mem_bw_schema, err);
270285

271286
/* At this point, assume it was created. */
287+
ret = crun_ensure_directory (path, 0755, true, err);
288+
if (UNLIKELY (ret < 0))
289+
return ret;
272290
*created = true;
273291

274-
return crun_ensure_directory (path, 0755, true, err);
292+
return 0;
275293
}
276294

277295
int
@@ -292,33 +310,34 @@ resctl_move_task_to (const char *name, pid_t pid, libcrun_error_t *err)
292310
}
293311

294312
int
295-
resctl_update (const char *name, const char *l3_cache_schema, const char *mem_bw_schema, libcrun_error_t *err)
313+
resctl_update (const char *name, const char *l3_cache_schema, const char *mem_bw_schema,
314+
char *const *schemata, libcrun_error_t *err)
296315
{
316+
const char *actual_l3_cache_schema = l3_cache_schema;
297317
cleanup_free char *cleaned_l3_cache_schema = NULL;
298318
cleanup_free char *path = NULL;
299319
cleanup_close int fd = -1;
300320
int ret;
301321

302322
/* Nothing to do. */
303-
if (l3_cache_schema == NULL && mem_bw_schema == NULL)
323+
if (l3_cache_schema == NULL && mem_bw_schema == NULL && schemata == NULL)
304324
return 0;
305325

306326
ret = append_paths (&path, err, INTEL_RDT_MOUNT_POINT, name, SCHEMATA_FILE, NULL);
307327
if (UNLIKELY (ret < 0))
308328
return ret;
309329

310330
if (l3_cache_schema && strstr (l3_cache_schema, "MB:"))
311-
l3_cache_schema = cleaned_l3_cache_schema = intelrdt_clean_l3_cache_schema (l3_cache_schema);
331+
{
332+
cleaned_l3_cache_schema = intelrdt_clean_l3_cache_schema (l3_cache_schema);
333+
actual_l3_cache_schema = cleaned_l3_cache_schema;
334+
}
312335

313336
fd = open (path, O_WRONLY | O_CLOEXEC);
314337
if (UNLIKELY (fd < 0))
315-
return crun_make_error (err, errno, "open `%s`", path);
338+
return crun_make_error (err, errno, "open `%s` for writing", path);
316339

317-
ret = write_intelrdt_string (fd, path, l3_cache_schema, mem_bw_schema, err);
318-
if (UNLIKELY (ret < 0))
319-
return ret;
320-
321-
return 0;
340+
return write_intelrdt_string (fd, path, actual_l3_cache_schema, mem_bw_schema, schemata, err);
322341
}
323342

324343
int

src/libcrun/intelrdt.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@
2626

2727
int resctl_create (const char *name, bool explicit_clos_id, bool *created, const char *l3_cache_schema, const char *mem_bw_schema, libcrun_error_t *err);
2828
int resctl_move_task_to (const char *name, pid_t pid, libcrun_error_t *err);
29-
int resctl_update (const char *name, const char *l3_cache_schema, const char *mem_bw_schema, libcrun_error_t *err);
29+
int resctl_update (const char *name, const char *l3_cache_schema, const char *mem_bw_schema, char *const *schemata, libcrun_error_t *err);
3030
int resctl_destroy (const char *name, libcrun_error_t *err);
3131

3232
#endif

src/libcrun/linux.c

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5784,7 +5784,7 @@ libcrun_apply_intelrdt (const char *ctr_name, libcrun_container_t *container, pi
57845784

57855785
if (actions & LIBCRUN_INTELRDT_UPDATE)
57865786
{
5787-
ret = resctl_update (name, def->linux->intel_rdt->l3cache_schema, def->linux->intel_rdt->mem_bw_schema, err);
5787+
ret = resctl_update (name, def->linux->intel_rdt->l3cache_schema, def->linux->intel_rdt->mem_bw_schema, def->linux->intel_rdt->schemata, err);
57885788
if (UNLIKELY (ret < 0))
57895789
goto fail;
57905790
}
@@ -5819,13 +5819,13 @@ libcrun_destroy_intelrdt (const char *name, libcrun_error_t *err)
58195819
}
58205820

58215821
int
5822-
libcrun_update_intel_rdt (const char *ctr_name, libcrun_container_t *container, const char *l3_cache_schema, const char *mem_bw_schema, libcrun_error_t *err)
5822+
libcrun_update_intel_rdt (const char *ctr_name, libcrun_container_t *container, const char *l3_cache_schema, const char *mem_bw_schema, char *const *schemata, libcrun_error_t *err)
58235823
{
58245824
const char *name;
58255825

58265826
name = libcrun_get_intelrdt_name (ctr_name, container, NULL);
58275827

5828-
return resctl_update (name, l3_cache_schema, mem_bw_schema, err);
5828+
return resctl_update (name, l3_cache_schema, mem_bw_schema, schemata, err);
58295829
}
58305830

58315831
/* Change the current directory and make sure the current working

src/libcrun/linux.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -143,7 +143,7 @@ int libcrun_apply_intelrdt (const char *ctr_name, libcrun_container_t *container
143143

144144
int libcrun_destroy_intelrdt (const char *name, libcrun_error_t *err);
145145

146-
int libcrun_update_intel_rdt (const char *ctr_name, libcrun_container_t *container, const char *l3_cache_schema, const char *mem_bw_schema, libcrun_error_t *err);
146+
int libcrun_update_intel_rdt (const char *ctr_name, libcrun_container_t *container, const char *l3_cache_schema, const char *mem_bw_schema, char *const *schemata, libcrun_error_t *err);
147147

148148
int libcrun_safe_chdir (const char *path, libcrun_error_t *err);
149149

tests/tests_libcrun_intelrdt.c

Lines changed: 53 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ typedef int (*test) ();
2626

2727
extern int compare_rdt_configurations (const char *a, const char *b);
2828
extern char *intelrdt_clean_l3_cache_schema (const char *l3_cache_schema);
29+
extern int get_rdt_value (char **out, const char *l3_cache_schema, const char *mem_bw_schema, char *const *schemata);
2930

3031
static int
3132
test_compare_rdt_configurations ()
@@ -75,6 +76,56 @@ test_intelrdt_clean_l3_cache_schema ()
7576
return 0;
7677
}
7778

79+
static int
80+
test_get_rdt_value ()
81+
{
82+
#define COMPARE(L3, MB, SCHEMATA, EXPECTED) \
83+
do \
84+
{ \
85+
char *result = NULL; \
86+
int r = get_rdt_value (&result, L3, MB, SCHEMATA); \
87+
int cmp = strcmp (result, EXPECTED); \
88+
free (result); \
89+
if (cmp != 0) \
90+
return 1; \
91+
} while (0)
92+
93+
COMPARE (NULL, NULL, NULL, "\n");
94+
95+
COMPARE ("L3=foo", NULL, NULL, "L3=foo\n");
96+
COMPARE (NULL, "MB=bar", NULL, "MB=bar\n");
97+
COMPARE ("L3=foo", "MB=bar", NULL, "L3=foo\nMB=bar\n");
98+
99+
{
100+
char *schemata1[] = { "S1", "S2", NULL };
101+
COMPARE (NULL, NULL, schemata1, "S1\nS2\n");
102+
}
103+
104+
{
105+
char *schemata2[] = { "S1", "S2", NULL };
106+
COMPARE ("L3=foo", NULL, schemata2, "L3=foo\nS1\nS2\n");
107+
}
108+
109+
{
110+
char *schemata3[] = { "S1", "S2", NULL };
111+
COMPARE (NULL, "MB=bar", schemata3, "MB=bar\nS1\nS2\n");
112+
}
113+
114+
{
115+
char *schemata4[] = { "S1", "S2", NULL };
116+
COMPARE ("L3=foo", "MB=bar", schemata4, "L3=foo\nMB=bar\nS1\nS2\n");
117+
}
118+
119+
{
120+
char *schemata5[] = { NULL };
121+
COMPARE (NULL, NULL, schemata5, "\n");
122+
}
123+
124+
#undef COMPARE
125+
126+
return 0;
127+
}
128+
78129
static void
79130
run_and_print_test_result (const char *name, int id, test t)
80131
{
@@ -97,8 +148,9 @@ int
97148
main ()
98149
{
99150
int id = 1;
100-
printf ("1..2\n");
151+
printf ("1..3\n");
101152
RUN_TEST (test_compare_rdt_configurations);
102153
RUN_TEST (test_intelrdt_clean_l3_cache_schema);
154+
RUN_TEST (test_get_rdt_value);
103155
return 0;
104156
}

0 commit comments

Comments
 (0)