s390/cio: More efficient handling of CHPID availability events
The CIO layer processes hardware events that indicate that a channel path has become available by performing a scan of available subchannels using the Store Subchannel (STSCH) instruction. Performing too many STSCH instructions in a tight loop can cause high Hypervisor overhead which can negatively impact the performance of the virtual machine as a whole. This patch reduces the number of STSCH instructions performed while processing a resource accessibility event and while varying a CHPID online. In both cases, Linux first performs a STSCH instruction on each unused subchannel to see if the subchannel has become available. If the STSCH instruction indicates that the subchannel is available, a full evaluation of this subchannel is scheduled. Since the full evaluation includes performing a STSCH instruction, the initial STSCH is unnecessary and can be removed. Signed-off-by: Peter Oberparleiter <oberpar@linux.vnet.ibm.com> Reviewed-by: Sebastian Ott <sebott@linux.vnet.ibm.com> Signed-off-by: Martin Schwidefsky <schwidefsky@de.ibm.com>
This commit is contained in:
parent
319e2e3f63
commit
449666dd1e
1 changed files with 4 additions and 36 deletions
|
@ -237,26 +237,6 @@ void chsc_chp_offline(struct chp_id chpid)
|
||||||
for_each_subchannel_staged(s390_subchannel_remove_chpid, NULL, &link);
|
for_each_subchannel_staged(s390_subchannel_remove_chpid, NULL, &link);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int s390_process_res_acc_new_sch(struct subchannel_id schid, void *data)
|
|
||||||
{
|
|
||||||
struct schib schib;
|
|
||||||
/*
|
|
||||||
* We don't know the device yet, but since a path
|
|
||||||
* may be available now to the device we'll have
|
|
||||||
* to do recognition again.
|
|
||||||
* Since we don't have any idea about which chpid
|
|
||||||
* that beast may be on we'll have to do a stsch
|
|
||||||
* on all devices, grr...
|
|
||||||
*/
|
|
||||||
if (stsch_err(schid, &schib))
|
|
||||||
/* We're through */
|
|
||||||
return -ENXIO;
|
|
||||||
|
|
||||||
/* Put it on the slow path. */
|
|
||||||
css_schedule_eval(schid);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int __s390_process_res_acc(struct subchannel *sch, void *data)
|
static int __s390_process_res_acc(struct subchannel *sch, void *data)
|
||||||
{
|
{
|
||||||
spin_lock_irq(sch->lock);
|
spin_lock_irq(sch->lock);
|
||||||
|
@ -287,8 +267,8 @@ static void s390_process_res_acc(struct chp_link *link)
|
||||||
* The more information we have (info), the less scanning
|
* The more information we have (info), the less scanning
|
||||||
* will we have to do.
|
* will we have to do.
|
||||||
*/
|
*/
|
||||||
for_each_subchannel_staged(__s390_process_res_acc,
|
for_each_subchannel_staged(__s390_process_res_acc, NULL, link);
|
||||||
s390_process_res_acc_new_sch, link);
|
css_schedule_reprobe();
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
|
@ -663,19 +643,6 @@ static int s390_subchannel_vary_chpid_on(struct subchannel *sch, void *data)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
|
||||||
__s390_vary_chpid_on(struct subchannel_id schid, void *data)
|
|
||||||
{
|
|
||||||
struct schib schib;
|
|
||||||
|
|
||||||
if (stsch_err(schid, &schib))
|
|
||||||
/* We're through */
|
|
||||||
return -ENXIO;
|
|
||||||
/* Put it on the slow path. */
|
|
||||||
css_schedule_eval(schid);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* chsc_chp_vary - propagate channel-path vary operation to subchannels
|
* chsc_chp_vary - propagate channel-path vary operation to subchannels
|
||||||
* @chpid: channl-path ID
|
* @chpid: channl-path ID
|
||||||
|
@ -694,7 +661,8 @@ int chsc_chp_vary(struct chp_id chpid, int on)
|
||||||
/* Try to update the channel path description. */
|
/* Try to update the channel path description. */
|
||||||
chp_update_desc(chp);
|
chp_update_desc(chp);
|
||||||
for_each_subchannel_staged(s390_subchannel_vary_chpid_on,
|
for_each_subchannel_staged(s390_subchannel_vary_chpid_on,
|
||||||
__s390_vary_chpid_on, &chpid);
|
NULL, &chpid);
|
||||||
|
css_schedule_reprobe();
|
||||||
} else
|
} else
|
||||||
for_each_subchannel_staged(s390_subchannel_vary_chpid_off,
|
for_each_subchannel_staged(s390_subchannel_vary_chpid_off,
|
||||||
NULL, &chpid);
|
NULL, &chpid);
|
||||||
|
|
Loading…
Add table
Reference in a new issue