Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 165332
b: refs/heads/master
c: 2553055
h: refs/heads/master
v: v3
  • Loading branch information
Sebastian Ott authored and Martin Schwidefsky committed Sep 22, 2009
1 parent d2b5e7e commit 1768bed
Show file tree
Hide file tree
Showing 4 changed files with 28 additions and 1 deletion.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: 2f17644d1cd0121daa0a997ff4eca5b3b44d1fae
refs/heads/master: 255305536c1b56ad09590f1400fb2c788265e34e
16 changes: 16 additions & 0 deletions trunk/drivers/s390/cio/css.c
Original file line number Diff line number Diff line change
Expand Up @@ -409,10 +409,14 @@ static void css_evaluate_subchannel(struct subchannel_id schid, int slow)

static struct idset *slow_subchannel_set;
static spinlock_t slow_subchannel_lock;
static wait_queue_head_t css_eval_wq;
static atomic_t css_eval_scheduled;

static int __init slow_subchannel_init(void)
{
spin_lock_init(&slow_subchannel_lock);
atomic_set(&css_eval_scheduled, 0);
init_waitqueue_head(&css_eval_wq);
slow_subchannel_set = idset_sch_new();
if (!slow_subchannel_set) {
CIO_MSG_EVENT(0, "could not allocate slow subchannel set\n");
Expand Down Expand Up @@ -468,9 +472,17 @@ static int slow_eval_unknown_fn(struct subchannel_id schid, void *data)

static void css_slow_path_func(struct work_struct *unused)
{
unsigned long flags;

CIO_TRACE_EVENT(4, "slowpath");
for_each_subchannel_staged(slow_eval_known_fn, slow_eval_unknown_fn,
NULL);
spin_lock_irqsave(&slow_subchannel_lock, flags);
if (idset_is_empty(slow_subchannel_set)) {
atomic_set(&css_eval_scheduled, 0);
wake_up(&css_eval_wq);
}
spin_unlock_irqrestore(&slow_subchannel_lock, flags);
}

static DECLARE_WORK(slow_path_work, css_slow_path_func);
Expand All @@ -482,6 +494,7 @@ void css_schedule_eval(struct subchannel_id schid)

spin_lock_irqsave(&slow_subchannel_lock, flags);
idset_sch_add(slow_subchannel_set, schid);
atomic_set(&css_eval_scheduled, 1);
queue_work(slow_path_wq, &slow_path_work);
spin_unlock_irqrestore(&slow_subchannel_lock, flags);
}
Expand All @@ -492,6 +505,7 @@ void css_schedule_eval_all(void)

spin_lock_irqsave(&slow_subchannel_lock, flags);
idset_fill(slow_subchannel_set);
atomic_set(&css_eval_scheduled, 1);
queue_work(slow_path_wq, &slow_path_work);
spin_unlock_irqrestore(&slow_subchannel_lock, flags);
}
Expand Down Expand Up @@ -1007,6 +1021,8 @@ static int __init channel_subsystem_init_sync(void)
{
/* Allocate and register subchannels. */
for_each_subchannel(setup_subchannel, NULL);
/* Wait for the evaluation of subchannels to finish. */
wait_event(css_eval_wq, atomic_read(&css_eval_scheduled) == 0);

/* Wait for the initialization of ccw devices to finish. */
wait_event(ccw_device_init_wq,
Expand Down
10 changes: 10 additions & 0 deletions trunk/drivers/s390/cio/idset.c
Original file line number Diff line number Diff line change
Expand Up @@ -110,3 +110,13 @@ int idset_sch_get_first(struct idset *set, struct subchannel_id *schid)
}
return rc;
}

int idset_is_empty(struct idset *set)
{
int bitnum;

bitnum = find_first_bit(set->bitmap, set->num_ssid * set->num_id);
if (bitnum >= set->num_ssid * set->num_id)
return 1;
return 0;
}
1 change: 1 addition & 0 deletions trunk/drivers/s390/cio/idset.h
Original file line number Diff line number Diff line change
Expand Up @@ -21,5 +21,6 @@ void idset_sch_add(struct idset *set, struct subchannel_id id);
void idset_sch_del(struct idset *set, struct subchannel_id id);
int idset_sch_contains(struct idset *set, struct subchannel_id id);
int idset_sch_get_first(struct idset *set, struct subchannel_id *id);
int idset_is_empty(struct idset *set);

#endif /* S390_IDSET_H */

0 comments on commit 1768bed

Please sign in to comment.