From 474c6adf8f4972990de661f1c57e3d3f187a4a3a Mon Sep 17 00:00:00 2001 From: Matthew Rosato Date: Thu, 11 Apr 2024 14:36:34 -0400 Subject: [PATCH] libap: use custom wait time for file locks If many invocations of mdevctl occur simultaneously (as can happen with libvirt) then waiting for 5-60 seconds per lock retry is simply too long. Anticipating this possibility, retry more frequently but also attempt significantly more retries than before. Reported-by: Marc Hartmayer Reviewed-by: Boris Fiuczynski Reviewed-by: Marc Hartmayer Tested-by: Marc Hartmayer Signed-off-by: Matthew Rosato Signed-off-by: Steffen Eiden --- include/lib/ap.h | 4 +++- libap/ap.c | 26 ++++++++++++++++++++++++-- 2 files changed, 27 insertions(+), 3 deletions(-) diff --git a/include/lib/ap.h b/include/lib/ap.h index 58baeeb5..057a78e4 100644 --- a/include/lib/ap.h +++ b/include/lib/ap.h @@ -21,7 +21,9 @@ #define AP_UDEV_FILE "/etc/udev/rules.d/41-ap.rules" #define AP_LOCKFILE "/run/lock/s390apconfig.lock" -#define AP_LOCK_RETRIES 15 +#define AP_LOCK_RETRIES 3000 +#define AP_LOCK_DELAY_US 30000 /* wait at least 30ms between lock retries */ +#define AP_LOCK_VARIANCE_US 3000 /* or as much as 33ms */ /* apmask and aqmask are each represented as 67 character strings with: * '0x' leading characters diff --git a/libap/ap.c b/libap/ap.c index e683b291..5c2f406d 100644 --- a/libap/ap.c +++ b/libap/ap.c @@ -11,12 +11,15 @@ #include #include #include +#include #include +#include #include #include #include #include #include +#include #ifdef HAVE_JSONC #include @@ -698,6 +701,20 @@ void ap_list_remove_all(struct util_list *list) } } +static unsigned int random_delay(void) +{ + static bool libap_seed = true; + struct timeval t; + + if (libap_seed) { + gettimeofday(&t, NULL); + srand((unsigned int)((t.tv_sec + t.tv_usec) % UINT_MAX)); + libap_seed = false; + } + + return AP_LOCK_DELAY_US + (rand() % AP_LOCK_VARIANCE_US); +} + /** * Acquire the ap config lock using this Process ID * @@ -707,7 +724,9 @@ void ap_list_remove_all(struct util_list *list) */ int ap_get_lock(void) { - return util_lockfile_lock(AP_LOCKFILE, AP_LOCK_RETRIES); + unsigned int delay = random_delay(); + + return util_lockfile_lock_cw(AP_LOCKFILE, AP_LOCK_RETRIES, delay, delay); } /** @@ -719,7 +738,10 @@ int ap_get_lock(void) */ int ap_get_lock_callout(void) { - return util_lockfile_parent_lock(AP_LOCKFILE, AP_LOCK_RETRIES); + unsigned int delay = random_delay(); + + return util_lockfile_parent_lock_cw(AP_LOCKFILE, AP_LOCK_RETRIES, delay, + delay); } /**