loop-util: wait a random time before trying again
Let's try to make collisions when multiple clients want to use the same device less likely, by sleeping a random time on collision. The loop device allocation protocol is inherently collision prone: first, a program asks which is the next free loop device, then it tries to acquire it, in a separate, unsynchronized setp. If many peers do this all at the same time, they'll likely all collide when trying to acquire the device, so that they need to ask for a free device again and again. Let's make this a little less prone to collisions, reducing the number of failing attempts: whenever we notice a collision we'll now wait short and randomized time, making it more likely another peer succeeds. (This also adds a similar logic when retrying LOOP_SET_STATUS64, but with a slightly altered calculation, since there we definitely want to wait a bit, under all cases)
This commit is contained in:
parent
786e3a52a2
commit
b202ec2068
|
@ -24,6 +24,7 @@
|
|||
#include "loop-util.h"
|
||||
#include "missing_loop.h"
|
||||
#include "parse-util.h"
|
||||
#include "random-util.h"
|
||||
#include "stat-util.h"
|
||||
#include "stdio-util.h"
|
||||
#include "string-util.h"
|
||||
|
@ -248,7 +249,10 @@ static int loop_configure(
|
|||
goto fail;
|
||||
}
|
||||
|
||||
(void) usleep(50 * USEC_PER_MSEC);
|
||||
/* Sleep some random time, but at least 10ms, at most 250ms. Increase the delay the more
|
||||
* failed attempts we see */
|
||||
(void) usleep(UINT64_C(10) * USEC_PER_MSEC +
|
||||
random_u64() % (UINT64_C(240) * USEC_PER_MSEC * n_attempts/64));
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
@ -414,6 +418,11 @@ int loop_device_make(
|
|||
return -EBUSY;
|
||||
|
||||
loopdev = mfree(loopdev);
|
||||
|
||||
/* Wait some random time, to make collision less likely. Let's pick a random time in the
|
||||
* range 0ms…250ms, linearly scaled by the number of failed attempts. */
|
||||
(void) usleep(random_u64() % (UINT64_C(10) * USEC_PER_MSEC +
|
||||
UINT64_C(240) * USEC_PER_MSEC * n_attempts/64));
|
||||
}
|
||||
|
||||
d = new(LoopDevice, 1);
|
||||
|
|
Loading…
Reference in New Issue