Skip to content

Commit affd862

Browse files
rstorozhrkanagar
authored andcommitted
Prefer MMIO interface in AUTO selection on Linux (ERDT+MRRM sysfs detection)
Presence of the tables ERDT and MRRM shows that MMIO interace is supported. Choose it by default. Signed-off-by: Roman Storozhenko <roman.storozhenko@intel.com>
1 parent 1bd5de4 commit affd862

7 files changed

Lines changed: 114 additions & 10 deletions

File tree

‎lib/acpi.c‎

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -50,9 +50,8 @@
5050
#include <sys/types.h>
5151
#include <unistd.h>
5252

53-
#define DEV_MEM "/dev/mem"
54-
#define EFI_SYSTAB "/sys/firmware/efi/systab"
55-
#define ACPI_TABLE_FS_PATH "/sys/firmware/acpi/tables"
53+
#define DEV_MEM "/dev/mem"
54+
#define EFI_SYSTAB "/sys/firmware/efi/systab"
5655

5756
#define BIOS_RO_MEM_ADDR 0x000E0000LLU
5857
#define BIOS_RO_MEM_SIZE 0x00020000LLU

‎lib/acpi.h‎

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,9 @@ typedef uint32_t acpi_size;
5757
#error "Unsupported architecture"
5858
#endif
5959

60+
/* ACPI tables root directory in sysfs */
61+
#define ACPI_TABLE_FS_PATH "/sys/firmware/acpi/tables"
62+
6063
/**
6164
* ACPI Table
6265
*/

‎lib/cap.c‎

Lines changed: 36 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -50,8 +50,10 @@
5050

5151
#include "cap.h"
5252

53+
#include "acpi.h"
5354
#include "allocation.h"
5455
#include "api.h"
56+
#include "common.h"
5557
#include "cores_domains.h"
5658
#include "cpu_registers.h"
5759
#include "cpuinfo.h"
@@ -71,6 +73,9 @@
7173

7274
#include <stdlib.h>
7375
#include <string.h>
76+
#ifdef __linux__
77+
#include <unistd.h>
78+
#endif
7479

7580
/**
7681
* ---------------------------------------
@@ -80,6 +85,11 @@
8085

8186
#define PROC_CPUINFO "/proc/cpuinfo"
8287

88+
#ifdef __linux__
89+
#define ACPI_ERDT_TABLE (ACPI_TABLE_FS_PATH "/" ACPI_TABLE_SIG_ERDT)
90+
#define ACPI_MRRM_TABLE (ACPI_TABLE_FS_PATH "/" ACPI_TABLE_SIG_MRRM)
91+
#endif
92+
8393
/**
8494
* ---------------------------------------
8595
* Local data types
@@ -618,6 +628,26 @@ _cap_interface_to_string(enum pqos_interface interface)
618628
}
619629
}
620630

631+
#ifdef __linux__
632+
/**
633+
* @brief Checks if MMIO interface prerequisites are present via Linux sysfs
634+
*
635+
* MMIO interface requires both ERDT and MRRM ACPI tables.
636+
* This mirrors the requirement already enforced in pqos_init() for MMIO.
637+
*
638+
* @return 1 if MMIO is supported, 0 otherwise
639+
*/
640+
PQOS_STATIC int
641+
mmio_is_supported_sysfs(void)
642+
{
643+
if (!pqos_file_exists(ACPI_ERDT_TABLE) ||
644+
!pqos_file_exists(ACPI_MRRM_TABLE))
645+
return 0;
646+
647+
return 1;
648+
}
649+
#endif
650+
621651
/**
622652
* @brief Detects interface
623653
*
@@ -689,7 +719,10 @@ discover_interface(enum pqos_interface requested_interface,
689719
}
690720
} else if (requested_interface == PQOS_INTER_AUTO) {
691721
#ifdef __linux__
692-
if (resctrl_is_supported() == PQOS_RETVAL_OK)
722+
/* Prefer MMIO if platform supports it */
723+
if (mmio_is_supported_sysfs())
724+
*interface = PQOS_INTER_MMIO;
725+
else if (resctrl_is_supported() == PQOS_RETVAL_OK)
693726
*interface = PQOS_INTER_OS;
694727
else
695728
*interface = PQOS_INTER_MSR;
@@ -700,8 +733,8 @@ discover_interface(enum pqos_interface requested_interface,
700733
*interface = requested_interface;
701734
}
702735

703-
LOG_INFO("Selected interface: %s\n",
704-
_cap_interface_to_string(*interface));
736+
fprintf(stdout, "Selected interface: %s\n",
737+
_cap_interface_to_string(*interface));
705738
return PQOS_RETVAL_OK;
706739
}
707740

‎pqos/main.c‎

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1171,9 +1171,11 @@ static const char help_printf_long[] =
11711171
" If automatic detection is selected ('auto'), it:\n"
11721172
" 1) Takes RDT_IFACE environment variable\n"
11731173
" into account if this variable is set\n"
1174-
" 2) Selects OS interface if the kernel interface\n"
1174+
" 2) Selects MMIO interface if supported\n"
1175+
" (ERDT and MRRM ACPI tables present)\n"
1176+
" 3) Selects OS interface if the kernel interface\n"
11751177
" is supported\n"
1176-
" 3) Selects MSR interface otherwise\n\n"
1178+
" 4) Selects MSR interface otherwise\n\n"
11771179
"---------------- MMIO interface help section ----------------\n"
11781180
"------------------- Detect capabilities --------------------\n"
11791181
" --print-mem-regions print memory mapped regions\n"

‎pqos/pqos.8‎

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -333,9 +333,11 @@ INTERFACE can be set to either 'auto' (default), 'msr' or 'os'. If automatic det
333333
.br
334334
1) Takes RDT_IFACE environment variable into account if this variable is set
335335
.br
336-
2) Selects OS interface if the kernel interface is supported
336+
2) Selects MMIO interface if supported (ERDT and MRRM ACPI tables present)
337337
.br
338-
3) Selects MSR interface otherwise
338+
3) Selects OS interface if the kernel interface is supported
339+
.br
340+
4) Selects MSR interface otherwise
339341
.SH NOTES
340342
.PP
341343
CMT, MBM and CAT are configured using Model Specific Registers (MSRs). The pqos software

‎unit-test/lib/Makefile‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -758,6 +758,7 @@ $(BIN_DIR)/test_cap_static: ./test_cap_static.c $(LIB_OBJS)
758758
mkdir -p $(BIN_DIR)
759759
$(CC) $(CFLAGS) $(WRAP) \
760760
-Wl,--wrap=getenv \
761+
-Wl,--wrap=access \
761762
-Wl,--wrap=malloc \
762763
-Wl,--wrap=hw_cap_l3ca_discover \
763764
-Wl,--wrap=os_cap_l3ca_discover \

‎unit-test/lib/test_cap_static.c‎

Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,9 @@
3535
#include "pqos.h"
3636
#include "test.h"
3737
#include "test_cap.h"
38+
#ifdef __linux__
39+
#include <unistd.h>
40+
#endif
3841

3942
/* ======== helpers ======= */
4043

@@ -110,6 +113,17 @@ __wrap_getenv(const char *name)
110113
return mock_ptr_type(char *);
111114
}
112115

116+
#ifdef __linux__
117+
int
118+
__wrap_access(const char *pathname, int mode)
119+
{
120+
function_called();
121+
check_expected_ptr(pathname);
122+
check_expected(mode);
123+
return mock_type(int);
124+
}
125+
#endif
126+
113127
static int log_init_result = LOG_RETVAL_OK;
114128
int
115129
__wrap_log_init(int fd_log __attribute__((unused)),
@@ -534,18 +548,68 @@ test_discover_interface_auto_linux(void **state __attribute__((unused)))
534548

535549
disable_check_log_printf();
536550

551+
/* MMIO supported (both ERDT and MRRM present) -> select MMIO */
552+
interface = -1;
553+
expect_function_call(__wrap_getenv);
554+
will_return(__wrap_getenv, NULL);
555+
expect_function_call(__wrap_access);
556+
expect_string(__wrap_access, pathname,
557+
"/sys/firmware/acpi/tables/ERDT");
558+
expect_value(__wrap_access, mode, F_OK);
559+
will_return(__wrap_access, 0);
560+
expect_function_call(__wrap_access);
561+
expect_string(__wrap_access, pathname,
562+
"/sys/firmware/acpi/tables/MRRM");
563+
expect_value(__wrap_access, mode, F_OK);
564+
will_return(__wrap_access, 0);
565+
ret = discover_interface(PQOS_INTER_AUTO, &interface);
566+
assert_int_equal(ret, PQOS_RETVAL_OK);
567+
assert_int_equal(interface, PQOS_INTER_MMIO);
568+
569+
/* ERDT missing -> fall through to OS if resctrl supported */
570+
interface = -1;
571+
expect_function_call(__wrap_getenv);
572+
will_return(__wrap_getenv, NULL);
573+
expect_function_call(__wrap_access);
574+
expect_string(__wrap_access, pathname,
575+
"/sys/firmware/acpi/tables/ERDT");
576+
expect_value(__wrap_access, mode, F_OK);
577+
will_return(__wrap_access, -1);
578+
expect_function_call(__wrap_resctrl_is_supported);
579+
will_return(__wrap_resctrl_is_supported, PQOS_RETVAL_OK);
580+
ret = discover_interface(PQOS_INTER_AUTO, &interface);
581+
assert_int_equal(ret, PQOS_RETVAL_OK);
582+
assert_int_equal(interface, PQOS_INTER_OS);
583+
584+
/* ERDT present but MRRM missing -> fall through to OS if resctrl */
537585
interface = -1;
538586
expect_function_call(__wrap_getenv);
539587
will_return(__wrap_getenv, NULL);
588+
expect_function_call(__wrap_access);
589+
expect_string(__wrap_access, pathname,
590+
"/sys/firmware/acpi/tables/ERDT");
591+
expect_value(__wrap_access, mode, F_OK);
592+
will_return(__wrap_access, 0);
593+
expect_function_call(__wrap_access);
594+
expect_string(__wrap_access, pathname,
595+
"/sys/firmware/acpi/tables/MRRM");
596+
expect_value(__wrap_access, mode, F_OK);
597+
will_return(__wrap_access, -1);
540598
expect_function_call(__wrap_resctrl_is_supported);
541599
will_return(__wrap_resctrl_is_supported, PQOS_RETVAL_OK);
542600
ret = discover_interface(PQOS_INTER_AUTO, &interface);
543601
assert_int_equal(ret, PQOS_RETVAL_OK);
544602
assert_int_equal(interface, PQOS_INTER_OS);
545603

604+
/* MMIO not supported, resctrl not supported -> select MSR */
546605
interface = -1;
547606
expect_function_call(__wrap_getenv);
548607
will_return(__wrap_getenv, NULL);
608+
expect_function_call(__wrap_access);
609+
expect_string(__wrap_access, pathname,
610+
"/sys/firmware/acpi/tables/ERDT");
611+
expect_value(__wrap_access, mode, F_OK);
612+
will_return(__wrap_access, -1);
549613
expect_function_call(__wrap_resctrl_is_supported);
550614
will_return(__wrap_resctrl_is_supported, PQOS_RETVAL_ERROR);
551615
ret = discover_interface(PQOS_INTER_AUTO, &interface);

0 commit comments

Comments
 (0)