git: a725d61825f3 - main - rangelock: if CAS for removal failed, restart list iteration
- Go to: [ bottom of page ] [ top of archives ] [ this month ]
Date: Wed, 21 Aug 2024 15:21:44 UTC
The branch main has been updated by kib: URL: https://cgit.FreeBSD.org/src/commit/?id=a725d61825f32ea00d07a2064431a02fd640313a commit a725d61825f32ea00d07a2064431a02fd640313a Author: Konstantin Belousov <kib@FreeBSD.org> AuthorDate: 2024-08-16 05:45:52 +0000 Commit: Konstantin Belousov <kib@FreeBSD.org> CommitDate: 2024-08-21 15:19:36 +0000 rangelock: if CAS for removal failed, restart list iteration Our next pointer is invalid and cannot be followed. Tested by: markj, pho Sponsored by: The FreeBSD Foundation --- sys/kern/kern_rangelock.c | 17 +++++++++++------ 1 file changed, 11 insertions(+), 6 deletions(-) diff --git a/sys/kern/kern_rangelock.c b/sys/kern/kern_rangelock.c index 2667bf30fb6f..d9042f364737 100644 --- a/sys/kern/kern_rangelock.c +++ b/sys/kern/kern_rangelock.c @@ -539,6 +539,7 @@ rl_r_validate(struct rangelock *lock, struct rl_q_entry *e, bool trylock, { struct rl_q_entry *cur, *next, **prev; +again: prev = &e->rl_q_next; cur = rl_q_load(prev); MPASS(!rl_e_is_marked(cur)); /* nobody can unlock e yet */ @@ -551,9 +552,10 @@ rl_r_validate(struct rangelock *lock, struct rl_q_entry *e, bool trylock, if (rl_q_cas(prev, cur, next)) { cur->rl_q_free = *free; *free = cur; + cur = next; + continue; } - cur = next; - continue; + goto again; } if (rl_e_is_rlock(cur)) { prev = &cur->rl_q_next; @@ -583,6 +585,7 @@ rl_w_validate(struct rangelock *lock, struct rl_q_entry *e, { struct rl_q_entry *cur, *next, **prev; +again: prev = (struct rl_q_entry **)&lock->head; cur = rl_q_load(prev); MPASS(!rl_e_is_marked(cur)); /* head is not marked */ @@ -595,9 +598,10 @@ rl_w_validate(struct rangelock *lock, struct rl_q_entry *e, if (rl_q_cas(prev, cur, next)) { cur->rl_q_next = *free; *free = cur; + cur = next; + continue; } - cur = next; - continue; + goto again; } if (cur->rl_q_end <= e->rl_q_start) { prev = &cur->rl_q_next; @@ -642,9 +646,10 @@ again: #endif cur->rl_q_free = *free; *free = cur; + cur = next; + continue; } - cur = next; - continue; + goto again; } }