diff options
author | Sebastian Ott <sebott@linux.vnet.ibm.com> | 2009-09-22 16:58:34 -0400 |
---|---|---|
committer | Martin Schwidefsky <schwidefsky@de.ibm.com> | 2009-09-22 16:58:41 -0400 |
commit | 255305536c1b56ad09590f1400fb2c788265e34e (patch) | |
tree | 23c97143b3ffe1598f76bc01b94407fa0c7d79d4 /drivers/s390/cio/css.c | |
parent | 2f17644d1cd0121daa0a997ff4eca5b3b44d1fae (diff) |
[S390] cio: introduce css_eval_scheduled
Use css_eval_scheduled to determine if all scheduled subchannel
evaluation is finished. Wait for this value to be 0 in the
channel subsystem init function.
Signed-off-by: Sebastian Ott <sebott@linux.vnet.ibm.com>
Signed-off-by: Martin Schwidefsky <schwidefsky@de.ibm.com>
Diffstat (limited to 'drivers/s390/cio/css.c')
-rw-r--r-- | drivers/s390/cio/css.c | 16 |
1 files changed, 16 insertions, 0 deletions
diff --git a/drivers/s390/cio/css.c b/drivers/s390/cio/css.c index 95805da2bb2..59c4b94cdb4 100644 --- a/drivers/s390/cio/css.c +++ b/drivers/s390/cio/css.c | |||
@@ -409,10 +409,14 @@ static void css_evaluate_subchannel(struct subchannel_id schid, int slow) | |||
409 | 409 | ||
410 | static struct idset *slow_subchannel_set; | 410 | static struct idset *slow_subchannel_set; |
411 | static spinlock_t slow_subchannel_lock; | 411 | static spinlock_t slow_subchannel_lock; |
412 | static wait_queue_head_t css_eval_wq; | ||
413 | static atomic_t css_eval_scheduled; | ||
412 | 414 | ||
413 | static int __init slow_subchannel_init(void) | 415 | static int __init slow_subchannel_init(void) |
414 | { | 416 | { |
415 | spin_lock_init(&slow_subchannel_lock); | 417 | spin_lock_init(&slow_subchannel_lock); |
418 | atomic_set(&css_eval_scheduled, 0); | ||
419 | init_waitqueue_head(&css_eval_wq); | ||
416 | slow_subchannel_set = idset_sch_new(); | 420 | slow_subchannel_set = idset_sch_new(); |
417 | if (!slow_subchannel_set) { | 421 | if (!slow_subchannel_set) { |
418 | CIO_MSG_EVENT(0, "could not allocate slow subchannel set\n"); | 422 | CIO_MSG_EVENT(0, "could not allocate slow subchannel set\n"); |
@@ -468,9 +472,17 @@ static int slow_eval_unknown_fn(struct subchannel_id schid, void *data) | |||
468 | 472 | ||
469 | static void css_slow_path_func(struct work_struct *unused) | 473 | static void css_slow_path_func(struct work_struct *unused) |
470 | { | 474 | { |
475 | unsigned long flags; | ||
476 | |||
471 | CIO_TRACE_EVENT(4, "slowpath"); | 477 | CIO_TRACE_EVENT(4, "slowpath"); |
472 | for_each_subchannel_staged(slow_eval_known_fn, slow_eval_unknown_fn, | 478 | for_each_subchannel_staged(slow_eval_known_fn, slow_eval_unknown_fn, |
473 | NULL); | 479 | NULL); |
480 | spin_lock_irqsave(&slow_subchannel_lock, flags); | ||
481 | if (idset_is_empty(slow_subchannel_set)) { | ||
482 | atomic_set(&css_eval_scheduled, 0); | ||
483 | wake_up(&css_eval_wq); | ||
484 | } | ||
485 | spin_unlock_irqrestore(&slow_subchannel_lock, flags); | ||
474 | } | 486 | } |
475 | 487 | ||
476 | static DECLARE_WORK(slow_path_work, css_slow_path_func); | 488 | static DECLARE_WORK(slow_path_work, css_slow_path_func); |
@@ -482,6 +494,7 @@ void css_schedule_eval(struct subchannel_id schid) | |||
482 | 494 | ||
483 | spin_lock_irqsave(&slow_subchannel_lock, flags); | 495 | spin_lock_irqsave(&slow_subchannel_lock, flags); |
484 | idset_sch_add(slow_subchannel_set, schid); | 496 | idset_sch_add(slow_subchannel_set, schid); |
497 | atomic_set(&css_eval_scheduled, 1); | ||
485 | queue_work(slow_path_wq, &slow_path_work); | 498 | queue_work(slow_path_wq, &slow_path_work); |
486 | spin_unlock_irqrestore(&slow_subchannel_lock, flags); | 499 | spin_unlock_irqrestore(&slow_subchannel_lock, flags); |
487 | } | 500 | } |
@@ -492,6 +505,7 @@ void css_schedule_eval_all(void) | |||
492 | 505 | ||
493 | spin_lock_irqsave(&slow_subchannel_lock, flags); | 506 | spin_lock_irqsave(&slow_subchannel_lock, flags); |
494 | idset_fill(slow_subchannel_set); | 507 | idset_fill(slow_subchannel_set); |
508 | atomic_set(&css_eval_scheduled, 1); | ||
495 | queue_work(slow_path_wq, &slow_path_work); | 509 | queue_work(slow_path_wq, &slow_path_work); |
496 | spin_unlock_irqrestore(&slow_subchannel_lock, flags); | 510 | spin_unlock_irqrestore(&slow_subchannel_lock, flags); |
497 | } | 511 | } |
@@ -1007,6 +1021,8 @@ static int __init channel_subsystem_init_sync(void) | |||
1007 | { | 1021 | { |
1008 | /* Allocate and register subchannels. */ | 1022 | /* Allocate and register subchannels. */ |
1009 | for_each_subchannel(setup_subchannel, NULL); | 1023 | for_each_subchannel(setup_subchannel, NULL); |
1024 | /* Wait for the evaluation of subchannels to finish. */ | ||
1025 | wait_event(css_eval_wq, atomic_read(&css_eval_scheduled) == 0); | ||
1010 | 1026 | ||
1011 | /* Wait for the initialization of ccw devices to finish. */ | 1027 | /* Wait for the initialization of ccw devices to finish. */ |
1012 | wait_event(ccw_device_init_wq, | 1028 | wait_event(ccw_device_init_wq, |