Move common wait loop code into a new macro called wait_event_locked() (merge r3591 from trunk)

git-svn-id: http://svn.code.sf.net/p/scst/svn/branches/2.2.x@6078 d57e44dd-8a1f-0410-8b47-8ef2f437770f
This commit is contained in:
Bart Van Assche
2015-02-11 08:49:54 +00:00
parent 0eef47f3fe
commit 74c2750e5a
5 changed files with 53 additions and 156 deletions

View File

@@ -1084,22 +1084,8 @@ int istrd(void *arg)
spin_lock_bh(&p->rd_lock);
while (!kthread_should_stop()) {
wait_queue_t wait;
init_waitqueue_entry(&wait, current);
if (!test_rd_list(p)) {
add_wait_queue_exclusive_head(&p->rd_waitQ, &wait);
for (;;) {
set_current_state(TASK_INTERRUPTIBLE);
if (test_rd_list(p))
break;
spin_unlock_bh(&p->rd_lock);
schedule();
spin_lock_bh(&p->rd_lock);
}
set_current_state(TASK_RUNNING);
remove_wait_queue(&p->rd_waitQ, &wait);
}
wait_event_locked(p->rd_waitQ, test_rd_list(p), lock_bh,
p->rd_lock);
scst_do_job_rd(p);
}
spin_unlock_bh(&p->rd_lock);
@@ -1866,22 +1852,8 @@ int istwr(void *arg)
spin_lock_bh(&p->wr_lock);
while (!kthread_should_stop()) {
wait_queue_t wait;
init_waitqueue_entry(&wait, current);
if (!test_wr_list(p)) {
add_wait_queue_exclusive_head(&p->wr_waitQ, &wait);
for (;;) {
set_current_state(TASK_INTERRUPTIBLE);
if (test_wr_list(p))
break;
spin_unlock_bh(&p->wr_lock);
schedule();
spin_lock_bh(&p->wr_lock);
}
set_current_state(TASK_RUNNING);
remove_wait_queue(&p->wr_waitQ, &wait);
}
wait_event_locked(p->wr_waitQ, test_wr_list(p), lock_bh,
p->wr_lock);
scst_do_job_wr(p);
}
spin_unlock_bh(&p->wr_lock);

View File

@@ -4177,17 +4177,45 @@ int scst_get_max_lun_commands(struct scst_session *sess, uint64_t lun);
* allows exclusive wake ups of threads in LIFO order. We need it to let (yet)
* unneeded threads sleep and not pollute CPU cache by their stacks.
*/
static inline void add_wait_queue_exclusive_head(wait_queue_head_t *q,
wait_queue_t *wait)
static inline void prepare_to_wait_exclusive_head(wait_queue_head_t *q,
wait_queue_t *wait, int state)
{
unsigned long flags;
wait->flags |= WQ_FLAG_EXCLUSIVE;
spin_lock_irqsave(&q->lock, flags);
__add_wait_queue(q, wait);
if (list_empty(&wait->task_list))
__add_wait_queue(q, wait);
set_current_state(state);
spin_unlock_irqrestore(&q->lock, flags);
}
/**
* wait_event_locked() - Wait until a condition becomes true.
* @wq: Wait queue to wait on if @condition is false.
* @condition: Condition to wait for. Can be any C expression.
* @lock_type: One of lock, lock_bh or lock_irq.
* @lock: A spinlock.
*
* Caller must hold lock of type @lock_type on @lock.
*/
#define wait_event_locked(wq, condition, lock_type, lock) \
if (!(condition)) { \
DEFINE_WAIT(__wait); \
\
do { \
prepare_to_wait_exclusive_head(&(wq), &__wait, \
TASK_INTERRUPTIBLE); \
if (condition) \
break; \
spin_un ## lock_type(&(lock)); \
schedule(); \
spin_ ## lock_type(&(lock)); \
} while (!(condition)); \
finish_wait(&(wq), &__wait); \
}
#ifndef CONFIG_SCST_PROC
/*

View File

@@ -1862,29 +1862,13 @@ static int dev_user_get_next_cmd(struct scst_user_dev *dev,
struct scst_user_cmd **ucmd)
{
int res = 0;
wait_queue_t wait;
TRACE_ENTRY();
init_waitqueue_entry(&wait, current);
while (1) {
if (!test_cmd_threads(dev)) {
add_wait_queue_exclusive_head(
&dev->udev_cmd_threads.cmd_list_waitQ,
&wait);
for (;;) {
set_current_state(TASK_INTERRUPTIBLE);
if (test_cmd_threads(dev))
break;
spin_unlock_irq(&dev->udev_cmd_threads.cmd_list_lock);
schedule();
spin_lock_irq(&dev->udev_cmd_threads.cmd_list_lock);
}
set_current_state(TASK_RUNNING);
remove_wait_queue(&dev->udev_cmd_threads.cmd_list_waitQ,
&wait);
}
wait_event_locked(dev->udev_cmd_threads.cmd_list_waitQ,
test_cmd_threads(dev), lock_irq,
dev->udev_cmd_threads.cmd_list_lock);
dev_user_process_scst_commands(dev);
@@ -3633,22 +3617,8 @@ static int dev_user_cleanup_thread(void *arg)
spin_lock(&cleanup_lock);
while (!kthread_should_stop()) {
wait_queue_t wait;
init_waitqueue_entry(&wait, current);
if (!test_cleanup_list()) {
add_wait_queue_exclusive(&cleanup_list_waitQ, &wait);
for (;;) {
set_current_state(TASK_INTERRUPTIBLE);
if (test_cleanup_list())
break;
spin_unlock(&cleanup_lock);
schedule();
spin_lock(&cleanup_lock);
}
set_current_state(TASK_RUNNING);
remove_wait_queue(&cleanup_list_waitQ, &wait);
}
wait_event_locked(cleanup_list_waitQ, test_cleanup_list(),
lock, cleanup_lock);
/*
* We have to poll devices, because commands can go from SCST

View File

@@ -454,26 +454,10 @@ static int sysfs_work_thread_fn(void *arg)
spin_lock(&sysfs_work_lock);
while (!kthread_should_stop()) {
wait_queue_t wait;
init_waitqueue_entry(&wait, current);
if (one_time_only && !test_sysfs_work_list())
break;
if (!test_sysfs_work_list()) {
add_wait_queue_exclusive(&sysfs_work_waitQ, &wait);
for (;;) {
set_current_state(TASK_INTERRUPTIBLE);
if (test_sysfs_work_list())
break;
spin_unlock(&sysfs_work_lock);
schedule();
spin_lock(&sysfs_work_lock);
}
set_current_state(TASK_RUNNING);
remove_wait_queue(&sysfs_work_waitQ, &wait);
}
wait_event_locked(sysfs_work_waitQ, test_sysfs_work_list(),
lock, sysfs_work_lock);
scst_process_sysfs_works();
}
spin_unlock(&sysfs_work_lock);

View File

@@ -4044,23 +4044,9 @@ int scst_init_thread(void *arg)
spin_lock_irq(&scst_init_lock);
while (!kthread_should_stop()) {
wait_queue_t wait;
init_waitqueue_entry(&wait, current);
if (!test_init_cmd_list()) {
add_wait_queue_exclusive(&scst_init_cmd_list_waitQ,
&wait);
for (;;) {
set_current_state(TASK_INTERRUPTIBLE);
if (test_init_cmd_list())
break;
spin_unlock_irq(&scst_init_lock);
schedule();
spin_lock_irq(&scst_init_lock);
}
set_current_state(TASK_RUNNING);
remove_wait_queue(&scst_init_cmd_list_waitQ, &wait);
}
wait_event_locked(scst_init_cmd_list_waitQ,
test_init_cmd_list(),
lock_irq, scst_init_lock);
scst_do_job_init();
}
spin_unlock_irq(&scst_init_lock);
@@ -4389,24 +4375,9 @@ int scst_cmd_thread(void *arg)
spin_lock_irq(&p_cmd_threads->cmd_list_lock);
while (!kthread_should_stop()) {
wait_queue_t wait;
init_waitqueue_entry(&wait, current);
if (!test_cmd_threads(p_cmd_threads)) {
add_wait_queue_exclusive_head(
&p_cmd_threads->cmd_list_waitQ,
&wait);
for (;;) {
set_current_state(TASK_INTERRUPTIBLE);
if (test_cmd_threads(p_cmd_threads))
break;
spin_unlock_irq(&p_cmd_threads->cmd_list_lock);
schedule();
spin_lock_irq(&p_cmd_threads->cmd_list_lock);
}
set_current_state(TASK_RUNNING);
remove_wait_queue(&p_cmd_threads->cmd_list_waitQ, &wait);
}
wait_event_locked(p_cmd_threads->cmd_list_waitQ,
test_cmd_threads(p_cmd_threads), lock_irq,
p_cmd_threads->cmd_list_lock);
if (tm_dbg_is_release()) {
spin_unlock_irq(&p_cmd_threads->cmd_list_lock);
@@ -5865,23 +5836,9 @@ int scst_tm_thread(void *arg)
spin_lock_irq(&scst_mcmd_lock);
while (!kthread_should_stop()) {
wait_queue_t wait;
init_waitqueue_entry(&wait, current);
if (!test_mgmt_cmd_list()) {
add_wait_queue_exclusive(&scst_mgmt_cmd_list_waitQ,
&wait);
for (;;) {
set_current_state(TASK_INTERRUPTIBLE);
if (test_mgmt_cmd_list())
break;
spin_unlock_irq(&scst_mcmd_lock);
schedule();
spin_lock_irq(&scst_mcmd_lock);
}
set_current_state(TASK_RUNNING);
remove_wait_queue(&scst_mgmt_cmd_list_waitQ, &wait);
}
wait_event_locked(scst_mgmt_cmd_list_waitQ,
test_mgmt_cmd_list(), lock_irq,
scst_mcmd_lock);
while (!list_empty(&scst_active_mgmt_cmd_list)) {
int rc;
@@ -6697,22 +6654,8 @@ int scst_global_mgmt_thread(void *arg)
spin_lock_irq(&scst_mgmt_lock);
while (!kthread_should_stop()) {
wait_queue_t wait;
init_waitqueue_entry(&wait, current);
if (!test_mgmt_list()) {
add_wait_queue_exclusive(&scst_mgmt_waitQ, &wait);
for (;;) {
set_current_state(TASK_INTERRUPTIBLE);
if (test_mgmt_list())
break;
spin_unlock_irq(&scst_mgmt_lock);
schedule();
spin_lock_irq(&scst_mgmt_lock);
}
set_current_state(TASK_RUNNING);
remove_wait_queue(&scst_mgmt_waitQ, &wait);
}
wait_event_locked(scst_mgmt_waitQ, test_mgmt_list(), lock_irq,
scst_mgmt_lock);
while (!list_empty(&scst_sess_init_list)) {
sess = list_first_entry(&scst_sess_init_list,