userfaultfd: Use a seqlock instead of seqcount
On RT write_seqcount_begin() disables preemption which leads to warning in add_wait_queue() while the spinlock_t is acquired. The waitqueue can't be converted to swait_queue because userfaultfd_wake_function() is used as a custom wake function. Use seqlock instead seqcount to avoid the preempt_disable() section during add_wait_queue(). Cc: stable-rt@vger.kernel.org Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
This commit is contained in:
parent
c587de4dc8
commit
cac578e31b
|
@ -56,7 +56,7 @@ struct userfaultfd_ctx {
|
|||
/* waitqueue head for events */
|
||||
wait_queue_head_t event_wqh;
|
||||
/* a refile sequence protected by fault_pending_wqh lock */
|
||||
struct seqcount refile_seq;
|
||||
seqlock_t refile_seq;
|
||||
/* pseudo fd refcounting */
|
||||
refcount_t refcount;
|
||||
/* userfaultfd syscall flags */
|
||||
|
@ -1058,7 +1058,7 @@ static ssize_t userfaultfd_ctx_read(struct userfaultfd_ctx *ctx, int no_wait,
|
|||
* waitqueue could become empty if this is the
|
||||
* only userfault.
|
||||
*/
|
||||
write_seqcount_begin(&ctx->refile_seq);
|
||||
write_seqlock(&ctx->refile_seq);
|
||||
|
||||
/*
|
||||
* The fault_pending_wqh.lock prevents the uwq
|
||||
|
@ -1084,7 +1084,7 @@ static ssize_t userfaultfd_ctx_read(struct userfaultfd_ctx *ctx, int no_wait,
|
|||
list_del(&uwq->wq.entry);
|
||||
add_wait_queue(&ctx->fault_wqh, &uwq->wq);
|
||||
|
||||
write_seqcount_end(&ctx->refile_seq);
|
||||
write_sequnlock(&ctx->refile_seq);
|
||||
|
||||
/* careful to always initialize msg if ret == 0 */
|
||||
*msg = uwq->msg;
|
||||
|
@ -1257,11 +1257,11 @@ static __always_inline void wake_userfault(struct userfaultfd_ctx *ctx,
|
|||
* sure we've userfaults to wake.
|
||||
*/
|
||||
do {
|
||||
seq = read_seqcount_begin(&ctx->refile_seq);
|
||||
seq = read_seqbegin(&ctx->refile_seq);
|
||||
need_wakeup = waitqueue_active(&ctx->fault_pending_wqh) ||
|
||||
waitqueue_active(&ctx->fault_wqh);
|
||||
cond_resched();
|
||||
} while (read_seqcount_retry(&ctx->refile_seq, seq));
|
||||
} while (read_seqretry(&ctx->refile_seq, seq));
|
||||
if (need_wakeup)
|
||||
__wake_userfault(ctx, range);
|
||||
}
|
||||
|
@ -1935,7 +1935,7 @@ static void init_once_userfaultfd_ctx(void *mem)
|
|||
init_waitqueue_head(&ctx->fault_wqh);
|
||||
init_waitqueue_head(&ctx->event_wqh);
|
||||
init_waitqueue_head(&ctx->fd_wqh);
|
||||
seqcount_init(&ctx->refile_seq);
|
||||
seqlock_init(&ctx->refile_seq);
|
||||
}
|
||||
|
||||
SYSCALL_DEFINE1(userfaultfd, int, flags)
|
||||
|
|
Loading…
Reference in New Issue