Commit f6239d3f authored by Davidlohr Bueso's avatar Davidlohr Bueso Committed by Dan Williams
Browse files

rcuwait: Support timeouts



The rcuwait utility provides an efficient and safe single
wait/wake mechanism. It is used in situations where queued
wait is the wrong semantics, and often too bulky. For example,
cases where the wait is already done under a lock.

In the past, rcuwait has been extended to support beyond only
uninterruptible sleep, and similarly, there are users that can
benefit for the addition of timeouts.

As such, tntroduce rcuwait_wait_event_timeout(), with semantics
equivalent to calls for queued wait counterparts.

Acked-by: default avatarPeter Zijlstra (Intel) <peterz@infradead.org>
Signed-off-by: default avatarDavidlohr Bueso <dave@stgolabs.net>
Link: https://lore.kernel.org/r/20230523170927.20685-2-dave@stgolabs.net


Signed-off-by: default avatarDan Williams <dan.j.williams@intel.com>
parent a70fc4ed
Loading
Loading
Loading
Loading
+20 −3
Original line number Diff line number Diff line
@@ -49,9 +49,9 @@ static inline void prepare_to_rcuwait(struct rcuwait *w)

extern void finish_rcuwait(struct rcuwait *w);

#define rcuwait_wait_event(w, condition, state)				\
#define ___rcuwait_wait_event(w, condition, state, ret, cmd)		\
({									\
	int __ret = 0;							\
	long __ret = ret;						\
	prepare_to_rcuwait(w);						\
	for (;;) {							\
		/*							\
@@ -67,10 +67,27 @@ extern void finish_rcuwait(struct rcuwait *w);
			break;						\
		}							\
									\
		schedule();						\
		cmd;							\
	}								\
	finish_rcuwait(w);						\
	__ret;								\
})

#define rcuwait_wait_event(w, condition, state)				\
	___rcuwait_wait_event(w, condition, state, 0, schedule())

#define __rcuwait_wait_event_timeout(w, condition, state, timeout)	\
	___rcuwait_wait_event(w, ___wait_cond_timeout(condition),	\
			      state, timeout,				\
			      __ret = schedule_timeout(__ret))

#define rcuwait_wait_event_timeout(w, condition, state, timeout)	\
({									\
	long __ret = timeout;						\
	if (!___wait_cond_timeout(condition))				\
		__ret = __rcuwait_wait_event_timeout(w, condition,	\
						     state, timeout);	\
	__ret;								\
})

#endif /* _LINUX_RCUWAIT_H_ */