util: add GroupLock for two-group mutual exclusion#6183
util: add GroupLock for two-group mutual exclusion#6183gadididi wants to merge 1 commit intoceph:develfrom
Conversation
d07791d to
667953c
Compare
nixpanic
left a comment
There was a problem hiding this comment.
Sounds like what we can use.
I wonder if this is over-kill for the rare cases this would be an issue? Is there an alternative that would be simpler?
In theory this could cause blocking for long time. If one group (say NodeStageVolume) gets called often, in quick succession, a NodeUnstageVolume could be blocked until all NodeStageVolume calls are handled. I don't think that will be problematic for our use now, but it may be something to document so other users are warned?
|
@nixpanic , Hi!
I searched for
right. I can make it more fair with kind of queue (like in the origin algorithm here: https://dl.acm.org/doi/10.1145/301308.301319) . UPDATE ABOUT THE QUEUE:adding fairness (like a FIFO queue) would make the code significantly more complex - we'd need to manage a wait queue, allocate queue entries, and handle wakeup ordering. I'll add a comment documenting this limitation so future users are aware. what do you think? In our case, when few pods are created\deleted in same time I think there is big chance for: time | descriptionT1 - |
|
There is no need to implement fairness/queuing. I do not expect significant issues for the intended use-case (NVMe-oF connect/disconnect). The number of operations that will get blocked should be minimal as (un)staging volumes is not done in a continuous stream anyway. A note like the proposed would be very good to have as a reminder though. |
Add GroupLock type that allows operations within the same group to run concurrently while blocking operations from the other group. This wiil be in used to coordinate NVMe-oF Stage and Unstage operations - multiple Stage calls can run in parallel, multiple Unstage calls can run in parallel, but Stage and Unstage block each other. This can be in used in any place which needs lock between 2 types of group. The implementation is based on Keane and Moir's "group mutual exclusion algorithm", but simplified for exactly two groups using Golang condition variables. Operations in group A wait if any group B operations are active, and vice versa. When the last operation in a group completes,all waiting operations in the other group are woken up together. Also added some test, simulate parallel workers: - Multiple same-group operations run concurrently - Different groups block each other - No deadlock under heavy contention - Mutual exclusion is never violated - All waiting operations start together when unblocked Signed-off-by: gadi-didi <[email protected]>
667953c to
5574e4f
Compare
Add GroupLock type that allows operations within the same group to run concurrently while blocking operations from the other group. This wiil be in used to coordinate NVMe-oF Stage and Unstage operations - multiple Stage calls can run in parallel,
multiple Unstage calls can run in parallel, but Stage and Unstage block each other.
This can be in used in any place which needs lock between 2 types of group.
The implementation is based on Keane and Moir's "group mutual exclusion algorithm", but simplified for exactly two groups using Golang condition variables.
Operations in group A wait if any group B operations are active, and vice versa.
When the last operation in a group completes, all waiting operations in the other group are woken up together.
Also added some test, simulate parallel workers:
Related PR
#6163 - once this phase1 PR will be merged, the next phase is adding group lock for connect\ disconnect OP.
Checklist:
guidelines in the developer
guide.
Request
notes
updated with breaking and/or notable changes for the next major release.
Show available bot commands
These commands are normally not required, but in case of issues, leave any of
the following bot commands in an otherwise empty comment in this PR:
/retest ci/centos/<job-name>: retest the<job-name>after unrelatedfailure (please report the failure too!)