forked from luck/tmp_suning_uos_patched
rcuwait: Add @state argument to rcuwait_wait_event()
Extend rcuwait_wait_event() with a state variable so that it is not restricted to UNINTERRUPTIBLE waits. Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org> Signed-off-by: Thomas Gleixner <tglx@linutronix.de> Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org> Link: https://lkml.kernel.org/r/20200321113241.824030968@linutronix.de
This commit is contained in:
parent
d964ea7014
commit
80fbaf1c3f
|
@ -3,6 +3,7 @@
|
||||||
#define _LINUX_RCUWAIT_H_
|
#define _LINUX_RCUWAIT_H_
|
||||||
|
|
||||||
#include <linux/rcupdate.h>
|
#include <linux/rcupdate.h>
|
||||||
|
#include <linux/sched/signal.h>
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* rcuwait provides a way of blocking and waking up a single
|
* rcuwait provides a way of blocking and waking up a single
|
||||||
|
@ -30,23 +31,30 @@ extern void rcuwait_wake_up(struct rcuwait *w);
|
||||||
* The caller is responsible for locking around rcuwait_wait_event(),
|
* The caller is responsible for locking around rcuwait_wait_event(),
|
||||||
* such that writes to @task are properly serialized.
|
* such that writes to @task are properly serialized.
|
||||||
*/
|
*/
|
||||||
#define rcuwait_wait_event(w, condition) \
|
#define rcuwait_wait_event(w, condition, state) \
|
||||||
({ \
|
({ \
|
||||||
|
int __ret = 0; \
|
||||||
rcu_assign_pointer((w)->task, current); \
|
rcu_assign_pointer((w)->task, current); \
|
||||||
for (;;) { \
|
for (;;) { \
|
||||||
/* \
|
/* \
|
||||||
* Implicit barrier (A) pairs with (B) in \
|
* Implicit barrier (A) pairs with (B) in \
|
||||||
* rcuwait_wake_up(). \
|
* rcuwait_wake_up(). \
|
||||||
*/ \
|
*/ \
|
||||||
set_current_state(TASK_UNINTERRUPTIBLE); \
|
set_current_state(state); \
|
||||||
if (condition) \
|
if (condition) \
|
||||||
break; \
|
break; \
|
||||||
\
|
\
|
||||||
|
if (signal_pending_state(state, current)) { \
|
||||||
|
__ret = -EINTR; \
|
||||||
|
break; \
|
||||||
|
} \
|
||||||
|
\
|
||||||
schedule(); \
|
schedule(); \
|
||||||
} \
|
} \
|
||||||
\
|
\
|
||||||
WRITE_ONCE((w)->task, NULL); \
|
WRITE_ONCE((w)->task, NULL); \
|
||||||
__set_current_state(TASK_RUNNING); \
|
__set_current_state(TASK_RUNNING); \
|
||||||
|
__ret; \
|
||||||
})
|
})
|
||||||
|
|
||||||
#endif /* _LINUX_RCUWAIT_H_ */
|
#endif /* _LINUX_RCUWAIT_H_ */
|
||||||
|
|
|
@ -234,7 +234,7 @@ void percpu_down_write(struct percpu_rw_semaphore *sem)
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/* Wait for all active readers to complete. */
|
/* Wait for all active readers to complete. */
|
||||||
rcuwait_wait_event(&sem->writer, readers_active_check(sem));
|
rcuwait_wait_event(&sem->writer, readers_active_check(sem), TASK_UNINTERRUPTIBLE);
|
||||||
}
|
}
|
||||||
EXPORT_SYMBOL_GPL(percpu_down_write);
|
EXPORT_SYMBOL_GPL(percpu_down_write);
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue
Block a user