public inbox for kvm@vger.kernel.org
 help / color / mirror / Atom feed
From: Michael Mueller <mimu@linux.ibm.com>
To: Halil Pasic <pasic@linux.ibm.com>
Cc: KVM Mailing List <kvm@vger.kernel.org>,
	Linux-S390 Mailing List <linux-s390@vger.kernel.org>,
	linux-kernel@vger.kernel.org,
	Martin Schwidefsky <schwidefsky@de.ibm.com>,
	Heiko Carstens <heiko.carstens@de.ibm.com>,
	Christian Borntraeger <borntraeger@de.ibm.com>,
	Janosch Frank <frankja@linux.ibm.com>,
	David Hildenbrand <david@redhat.com>,
	Cornelia Huck <cohuck@redhat.com>,
	Pierre Morel <pmorel@linux.ibm.com>
Subject: Re: [PATCH v5 13/15] KVM: s390: add function process_gib_alert_list()
Date: Tue, 8 Jan 2019 16:21:17 +0100	[thread overview]
Message-ID: <7e4a5077-00f0-3a0f-e21a-5bbc2fa14b70@linux.ibm.com> (raw)
In-Reply-To: <20190108135919.18048dd4@oc2783563651>



On 08.01.19 13:59, Halil Pasic wrote:
> On Wed, 19 Dec 2018 20:17:54 +0100
> Michael Mueller <mimu@linux.ibm.com> wrote:
> 
>> This function processes the Gib Alert List (GAL). It is required
>> to run when either a gib alert interruption has been received or
>> a gisa that is in the alert list is cleared or dropped.
>>
>> The GAL is build up by millicode, when the respective ISC bit is
>> set in the Interruption Alert Mask (IAM) and an interruption of
>> that class is observed.
>>
>> Signed-off-by: Michael Mueller <mimu@linux.ibm.com>
>> ---
>>   arch/s390/kvm/interrupt.c | 140 ++++++++++++++++++++++++++++++++++++++++++++++
>>   1 file changed, 140 insertions(+)
>>
>> diff --git a/arch/s390/kvm/interrupt.c b/arch/s390/kvm/interrupt.c
>> index 48a93f5e5333..03e7ba4f215a 100644
>> --- a/arch/s390/kvm/interrupt.c
>> +++ b/arch/s390/kvm/interrupt.c
>> @@ -2941,6 +2941,146 @@ int kvm_s390_get_irq_state(struct kvm_vcpu *vcpu, __u8 __user *buf, int len)
>>   	return n;
>>   }
>>   
>> +static int __try_airqs_kick(struct kvm *kvm, u8 ipm)
>> +{
>> +	struct kvm_s390_float_interrupt *fi = &kvm->arch.float_int;
>> +	struct kvm_vcpu *vcpu = NULL, *kick_vcpu[MAX_ISC + 1];
>> +	int online_vcpus = atomic_read(&kvm->online_vcpus);
>> +	u8 ioint_mask, isc_mask, kick_mask = 0x00;
>> +	int vcpu_id, kicked = 0;
>> +
>> +	/* Loop over vcpus in WAIT state. */
>> +	for (vcpu_id = find_first_bit(fi->idle_mask, online_vcpus);
>> +	     /* Until all pending ISCs have a vcpu open for airqs. */
>> +	     (~kick_mask & ipm) && vcpu_id < online_vcpus;
>> +	     vcpu_id = find_next_bit(fi->idle_mask, online_vcpus, vcpu_id)) {
>> +		vcpu = kvm_get_vcpu(kvm, vcpu_id);
>> +		if (psw_ioint_disabled(vcpu))
>> +			continue;
>> +		ioint_mask = (u8)(vcpu->arch.sie_block->gcr[6] >> 24);
>> +		for (isc_mask = 0x80; isc_mask; isc_mask >>= 1) {
>> +			/* ISC pending in IPM ? */
>> +			if (!(ipm & isc_mask))
>> +				continue;
>> +			/* vcpu for this ISC already found ? */
>> +			if (kick_mask & isc_mask)
>> +				continue;
>> +			/* vcpu open for airq of this ISC ? */
>> +			if (!(ioint_mask & isc_mask))
>> +				continue;
>> +			/* use this vcpu (for all ISCs in ioint_mask) */
>> +			kick_mask |= ioint_mask;
>> +			kick_vcpu[kicked++] = vcpu;
> 
> Assuming that the vcpu can/will take all ISCs it's currently open for
> does not seem right. We kind of rely on this assumption here, or?

My latest version of this routine already follows a different strategy.
It looks for a horizontal distribution of pending ISCs among idle vcpus.

> 
>> +		}
>> +	}
>> +
>> +	if (vcpu && ~kick_mask & ipm)
>> +		VM_EVENT(kvm, 4, "gib alert undeliverable isc mask
>> 0x%02x",
>> +			 ~kick_mask & ipm);
>> +
>> +	for (vcpu_id = 0; vcpu_id < kicked; vcpu_id++)
>> +		kvm_s390_vcpu_wakeup(kick_vcpu[vcpu_id]);
>> +
>> +	return (online_vcpus != 0) ? kicked : -ENODEV;
>> +}
>> +
>> +static void __floating_airqs_kick(struct kvm *kvm)
>> +{
>> +	struct kvm_s390_float_interrupt *fi = &kvm->arch.float_int;
>> +	int online_vcpus, kicked;
>> +	u8 ipm_t0, ipm;
>> +
>> +	/* Get IPM and return if clean, IAM has been restored. */
>> +	ipm = get_ipm(kvm->arch.gisa, IRQ_FLAG_IAM);
>> +	if (!ipm)
>> +		return;
>> +retry:
>> +	ipm_t0 = ipm;
>> +
>> +	/* Try to kick some vcpus in WAIT state. */
>> +	kicked = __try_airqs_kick(kvm, ipm);
>> +	if (kicked < 0)
>> +		return;
>> +
>> +	/* Get IPM and return if clean, IAM has been restored. */
>> +	ipm = get_ipm(kvm->arch.gisa, IRQ_FLAG_IAM);
>> +	if (!ipm)
>> +		return;
>> +
>> +	/* Start over, if new ISC bits are pending in IPM. */
>> +	if ((ipm_t0 ^ ipm) & ~ipm_t0)
>> +		goto retry;
>> +
> 
> <MARK A>
> 
>> +	/*
>> +	 * Return as we just kicked at least one vcpu in WAIT state
>> +	 * open for airqs. The IAM will be restored latest when one
>> +	 * of them goes into WAIT or STOP state.
>> +	 */
>> +	if (kicked > 0)
>> +		return;
> 
> </MARK A>
> 
>> +
>> +	/*
>> +	 * No vcpu was kicked either because no vcpu was in WAIT state
>> +	 * or none of the vcpus in WAIT state are open for airqs.
>> +	 * Return immediately if no vcpus are in WAIT state.
>> +	 * There are vcpus in RUN state. They will process the airqs
>> +	 * if not closed for airqs as well. In that case the system will
>> +	 * delay airqs until a vcpu decides to take airqs again.
>> +	 */
>> +	online_vcpus = atomic_read(&kvm->online_vcpus);
>> +	if (!bitmap_weight(fi->idle_mask, online_vcpus))
>> +		return;
>> +
>> +	/*
>> +	 * None of the vcpus in WAIT state take airqs and we might
>> +	 * have no running vcpus as at least one vcpu is in WAIT state
>> +	 * and IPM is dirty.
>> +	 */
>> +	set_iam(kvm->arch.gisa, kvm->arch.iam);
>> +}
>> +
>> +#define NULL_GISA_ADDR 0x00000000UL
>> +#define NONE_GISA_ADDR 0x00000001UL
>> +#define GISA_ADDR_MASK 0xfffff000UL
>> +
>> +static void __maybe_unused process_gib_alert_list(void)
>> +{
>> +	u32 final, next_alert, origin = 0UL;
>> +	struct kvm_s390_gisa *gisa;
>> +	struct kvm *kvm;
>> +
>> +	do {
>> +		/*
>> +		 * If the NONE_GISA_ADDR is still stored in the alert list
>> +		 * origin, we will leave the outer loop. No further GISA has
>> +		 * been added to the alert list by millicode while processing
>> +		 * the current alert list.
>> +		 */
>> +		final = (origin & NONE_GISA_ADDR);
>> +		/*
>> +		 * Cut off the alert list and store the NONE_GISA_ADDR in the
>> +		 * alert list origin to avoid further GAL interruptions.
>> +		 * A new alert list can be build up by millicode in parallel
>> +		 * for guests not in the yet cut-off alert list. When in the
>> +		 * final loop, store the NULL_GISA_ADDR instead. This will re-
>> +		 * enable GAL interruptions on the host again.
>> +		 */
>> +		origin = xchg(&gib->alert_list_origin,
>> +			      (!final) ? NONE_GISA_ADDR : NULL_GISA_ADDR);
>> +		/* Loop through the just cut-off alert list. */
>> +		while (origin & GISA_ADDR_MASK) {
>> +			gisa = (struct kvm_s390_gisa *)(u64)origin;
>> +			next_alert = gisa->next_alert;
>> +			/* Unlink the GISA from the alert list. */
>> +			gisa->next_alert = origin;
>> +			kvm = container_of(gisa, struct sie_page2, gisa)->kvm;
>> +			/* Kick suitable vcpus */
>> +			__floating_airqs_kick(kvm);
> 
> We may finish handling the alerted gisa with iam not set e.g.
> via some vcpus kicked but ipm still dirty and some vcpus still in wait,
> or?

My above mentioned change to the routine identifying the vcpus to kick
will select one vcpu for each ISC pending if possible (depends on the
number of idle vcpus and their respective interruption masks and the
pending ISCs).

That does not exclude the principle scenario that maybe only one vcpu
is kicked and multiple ISCs are pending (ipm still dirty) although
have never observed this with a Linux guest.

What I was trying to avoid was a kind of busy loop running in addition
to the kicked vcpus monitoring the IPM state for resource utilization
reasons.

> 
>  From the comments it seems we speculate on being in a safe state, as
> these are supposed to return to wait or stop soon-ish, and we will set
> iam then (See <MARK A>). I don't quite understand.


Yes, the next vcpu going idle shall restore the IAM or process the
top ISC pending if the iomask (GCR) allows. vcpus are not allowed to go 
in disabled wait (IO int disabled by PSW). If all vcpus always (for
some time) mask a specific ISC the guest does not want to get 
interrupted for that ISC but will as soon a running vcpu will open
the mask again.

> 
> According to my current understanding we might end up loosing initiative
> in this scenario. Or am I wrong?

I currently don't have proof for you being wrong but have not observed
the situation yet.

> 
> Regards,
> Halil
> 
>> +			origin = next_alert;
>> +		}
>> +	} while (!final);
>> +}
>> +
>>   static void nullify_gisa(struct kvm_s390_gisa *gisa)
>>   {
>>   	memset(gisa, 0, sizeof(struct kvm_s390_gisa));
> 

-

  reply	other threads:[~2019-01-08 15:21 UTC|newest]

Thread overview: 72+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2018-12-19 19:17 [PATCH v5 00/15] KVM: s390: make use of the GIB Michael Mueller
2018-12-19 19:17 ` [PATCH v5 01/15] KVM: s390: unregister debug feature on failing arch init Michael Mueller
2018-12-19 20:10   ` Cornelia Huck
2018-12-20  7:49     ` Michael Mueller
2018-12-20  7:55       ` Christian Borntraeger
2018-12-19 19:17 ` [PATCH v5 02/15] KVM: s390: coding style issue kvm_s390_gisa_init/clear() Michael Mueller
2018-12-19 20:13   ` Cornelia Huck
2019-01-02 16:50   ` Pierre Morel
2019-01-07 16:16     ` Michael Mueller
2018-12-19 19:17 ` [PATCH v5 03/15] KVM: s390: factor out nullify_gisa() Michael Mueller
2018-12-19 19:17 ` [PATCH v5 04/15] KVM: s390: use pending_irqs_no_gisa() where appropriate Michael Mueller
2018-12-19 20:16   ` Cornelia Huck
2019-01-02 16:52   ` Pierre Morel
2018-12-19 19:17 ` [PATCH v5 05/15] KVM: s390: unify pending_irqs() and pending_irqs_no_gisa() Michael Mueller
2018-12-20 10:09   ` Michael Mueller
2018-12-20 11:06   ` Cornelia Huck
2018-12-20 11:49     ` Michael Mueller
2018-12-20 12:15       ` Halil Pasic
2018-12-20 12:21       ` Cornelia Huck
2018-12-20 12:33         ` Michael Mueller
2018-12-20 15:43           ` pierre morel
2018-12-20 16:40             ` Michael Mueller
2018-12-19 19:17 ` [PATCH v5 06/15] KVM: s390: remove prefix kvm_s390_gisa_ from static inline functions Michael Mueller
2018-12-20 12:24   ` Cornelia Huck
2018-12-20 14:37     ` Michael Mueller
2018-12-19 19:17 ` [PATCH v5 07/15] s390/cio: add function chsc_sgib() Michael Mueller
2018-12-19 19:17 ` [PATCH v5 08/15] KVM: s390: add the GIB and its related life-cyle functions Michael Mueller
2018-12-20 12:28   ` Cornelia Huck
2019-01-03  9:49   ` Pierre Morel
2019-01-07 16:25     ` Michael Mueller
2018-12-19 19:17 ` [PATCH v5 09/15] KVM: s390: add kvm reference to struct sie_page2 Michael Mueller
2018-12-19 19:17 ` [PATCH v5 10/15] KVM: s390: add functions to (un)register GISC with GISA Michael Mueller
2018-12-20 14:32   ` Michael Mueller
2019-01-02 17:29   ` Pierre Morel
2019-01-02 18:26     ` Pierre Morel
2019-01-04 13:19     ` Cornelia Huck
2019-01-07 17:38       ` Michael Mueller
2019-01-08 10:34         ` Cornelia Huck
2019-01-08 13:07           ` Michael Mueller
2019-01-08 13:35             ` Cornelia Huck
2019-01-08 13:36           ` Halil Pasic
2019-01-08 13:41             ` Cornelia Huck
2019-01-08 14:23               ` Halil Pasic
2018-12-19 19:17 ` [PATCH v5 11/15] KVM: s390: restore IAM in get_ipm() when IPM is clean Michael Mueller
2019-01-03 15:06   ` Pierre Morel
2019-01-07 18:17     ` Michael Mueller
2019-01-06 23:32   ` Halil Pasic
2019-01-08  8:06     ` Michael Mueller
2018-12-19 19:17 ` [PATCH v5 12/15] KVM: s390: do not restore IAM immediately before SIE entry Michael Mueller
2019-01-03 15:00   ` Pierre Morel
2019-01-07 17:53     ` Michael Mueller
2018-12-19 19:17 ` [PATCH v5 13/15] KVM: s390: add function process_gib_alert_list() Michael Mueller
2019-01-03 14:43   ` Pierre Morel
2019-01-07 19:18     ` Michael Mueller
2019-01-08 14:27       ` Halil Pasic
2019-01-09 11:39       ` Pierre Morel
2019-01-07 19:19     ` Michael Mueller
2019-01-08  6:37       ` Heiko Carstens
2019-01-08 12:59   ` Halil Pasic
2019-01-08 15:21     ` Michael Mueller [this message]
2019-01-08 18:34       ` Halil Pasic
2019-01-09 12:14       ` Pierre Morel
2019-01-09 13:10         ` Halil Pasic
2019-01-09 14:49           ` Pierre Morel
2019-01-09 16:18             ` Halil Pasic
2018-12-19 19:17 ` [PATCH v5 14/15] KVM: s390: add and wire function gib_alert_irq_handler() Michael Mueller
2019-01-03 15:16   ` Pierre Morel
2019-01-08 10:06     ` Michael Mueller
2019-01-09 12:35       ` Pierre Morel
2018-12-19 19:17 ` [PATCH v5 15/15] KVM: s390: start using the GIB Michael Mueller
2019-01-02 17:45   ` Pierre Morel
2019-01-08  9:03     ` Michael Mueller

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=7e4a5077-00f0-3a0f-e21a-5bbc2fa14b70@linux.ibm.com \
    --to=mimu@linux.ibm.com \
    --cc=borntraeger@de.ibm.com \
    --cc=cohuck@redhat.com \
    --cc=david@redhat.com \
    --cc=frankja@linux.ibm.com \
    --cc=heiko.carstens@de.ibm.com \
    --cc=kvm@vger.kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-s390@vger.kernel.org \
    --cc=pasic@linux.ibm.com \
    --cc=pmorel@linux.ibm.com \
    --cc=schwidefsky@de.ibm.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox