Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 449666dd authored by Peter Oberparleiter's avatar Peter Oberparleiter Committed by Martin Schwidefsky
Browse files

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: default avatarPeter Oberparleiter <oberpar@linux.vnet.ibm.com>
Reviewed-by: default avatarSebastian Ott <sebott@linux.vnet.ibm.com>
Signed-off-by: default avatarMartin Schwidefsky <schwidefsky@de.ibm.com>
parent 319e2e3f
Loading
Loading
Loading
Loading
+4 −36
Original line number Original line Diff line number Diff line
@@ -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);