diff --git a/core-opts.c b/core-opts.c index 5ee7f9933..06f5d8697 100644 --- a/core-opts.c +++ b/core-opts.c @@ -717,6 +717,7 @@ const struct option stress_long_options[] = { { "pci", 1, 0, OPT_pci}, { "pci-dev", 1, 0, OPT_pci_dev}, { "pci-ops", 1, 0, OPT_pci_ops }, + { "pci-ops-rate", 1, 0, OPT_pci_ops_rate }, #if defined(STRESS_PERF_STATS) && \ defined(HAVE_LINUX_PERF_EVENT_H) { "perf", 0, 0, OPT_perf_stats }, diff --git a/core-opts.h b/core-opts.h index 1e05d694d..88a557ab0 100644 --- a/core-opts.h +++ b/core-opts.h @@ -1040,6 +1040,7 @@ typedef enum { OPT_pci, OPT_pci_dev, OPT_pci_ops, + OPT_pci_ops_rate, OPT_perf_stats, diff --git a/stress-ng.1 b/stress-ng.1 index 729276905..0a5adc105 100644 --- a/stress-ng.1 +++ b/stress-ng.1 @@ -2,7 +2,7 @@ .\" First parameter, NAME, should be all caps .\" Second parameter, SECTION, should be 1-8, maybe w/ subsection .\" other parameters are allowed: see man(7), man(1) -.TH STRESS-NG 1 "30 January 2025" +.TH STRESS-NG 1 "8 February 2025" .\" Please adjust this date whenever revising the manpage. .\" .\" Some roff macros, for reference: @@ -5890,6 +5890,10 @@ hexadecimal digit. stop pci stress workers after N PCI subdirectory exercising operations. .RE .TP +.B \-\-pci\-ops\-rate N +specify the PCI bogo-ops per second rate. This is useful for PCI bandwidth +limiting and on x86 systems this may reduce uncore transactions. +.TP .B Personality stressor .RS 5 .TQ diff --git a/stress-pci.c b/stress-pci.c index 4ccd91722..af75e7cc0 100644 --- a/stress-pci.c +++ b/stress-pci.c @@ -28,7 +28,8 @@ static const stress_help_t help[] = { }; static const stress_opt_t opts[] = { - { OPT_pci_dev, "pci-dev", TYPE_ID_STR, 0, 0, NULL }, + { OPT_pci_dev, "pci-dev", TYPE_ID_STR, 0, 0, NULL }, + { OPT_pci_ops_rate, "pci-ops-rate", TYPE_ID_UINT32, 1, 1000000, NULL }, END_OPT, }; @@ -301,6 +302,12 @@ static int stress_pci(stress_args_t *args) NOCLOBBER stress_pci_info_t *pci_info_list; NOCLOBBER stress_pci_info_t *pci_info; int ret; + uint32_t pci_ops_rate = 0; /* zero = unlimited */ + double t_start; + double t_delta; + + (void)stress_get_setting("pci-ops-rate", &pci_ops_rate); + t_delta = pci_ops_rate > 0 ? (double)args->num_instances / (double)pci_ops_rate : 0.0; stress_set_proc_state(args->name, STRESS_STATE_SYNC_WAIT); stress_sync_start_wait(args); @@ -324,6 +331,7 @@ static int stress_pci(stress_args_t *args) return EXIT_NO_RESOURCE; } + t_start = stress_time_now(); do { for (pci_info = pci_info_list; pci_info; pci_info = pci_info->next) { if (UNLIKELY(!stress_continue(args))) @@ -337,8 +345,19 @@ static int stress_pci(stress_args_t *args) if (pci_info->ignore) continue; + stress_pci_exercise(args, pci_info); stress_bogo_inc(args); + if (pci_ops_rate > 0) { + double t_next = t_start + (stress_bogo_get(args) * t_delta); + double t_sleep = t_next - stress_time_now(); + uint64_t ns; + + if (LIKELY(t_sleep > 0.0)) { + ns = (uint64_t)(t_sleep * STRESS_DBL_NANOSECOND); + shim_nanosleep_uint64(ns); + } + } } } while (stress_continue(args));