[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[RFC] Xen crashes on ASSERT on suspend/resume, suggested fix


  • To: <xen-devel@xxxxxxxxxxxxxxxxxxxx>
  • From: Stefano Stabellini <stefano.stabellini@xxxxxxx>
  • Date: Thu, 18 May 2023 16:44:53 -0700
  • Arc-authentication-results: i=1; mx.microsoft.com 1; spf=pass (sender ip is 165.204.84.17) smtp.rcpttodomain=lists.xenproject.org smtp.mailfrom=amd.com; dmarc=pass (p=quarantine sp=quarantine pct=100) action=none header.from=amd.com; dkim=none (message not signed); arc=none
  • Arc-message-signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=microsoft.com; s=arcselector9901; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-AntiSpam-MessageData-ChunkCount:X-MS-Exchange-AntiSpam-MessageData-0:X-MS-Exchange-AntiSpam-MessageData-1; bh=eBEWT/dwzg5bHP+LJqopgQqdSF83NK+k3UHbU9VyfRg=; b=fBJ5rvflvABHgSYNohQ7163SBLGNGlB8fQoNH/FF/w0u+dLobOf7kNEN9OcSHlvh0wLouTbxoXmMjDTPeucKHzOX6TSbfwXrD9PDb11F0Of0HK8G/Xie+flL9/Pc0Pj8BJrUByLY1J2Sx/4Mos68NypCcfSxw+M6tzwWIZRI6gdqiM0f41uLho4DkTgmaHfrCFHXsWPbjMMq/wOKTy9+S7Cd1k3S+LPUp3w85zyqe//KrQG6hHHs/Y85ntYw7M6QPxL6awDagQq6+5+A/ZnsIRyQx/yasNeFYLDK+97s1ucjsNUVwUbbJjjTqaPq5v1FOe0wOMF1YOK9kyYweGcDWA==
  • Arc-seal: i=1; a=rsa-sha256; s=arcselector9901; d=microsoft.com; cv=none; b=SZb1yO3ncl/YKeaSmEwHFtLIPsBYzrqJWcwg6AS3HDrAz8n8yxB/43tQdc+2tndrXqgXZ1gHgglxO5YbrIvnuOtRPICNrpEOF3JCthYq05nSWduAxFAxAJp8BPuMuxU7HKwPTnb5aT9WkHBlaJ8Hghrkx55Pkj5HjMN5GBYe8Bok8FTG3OHfgDmJVMPTQPH0BTjhZcjO1slHk5GSvR9E2p/CVFclsnmpLj5xvgHUb9e5l0cTslLFd56Ks0tOkO3A47noNQU80CVJTBq5agFKo7BdrAAQo6qgTN0O10FiDGW9bAK9bZosuVc9RKybiHQJ8gvMwhcbUnZ8du+Wv458fQ==
  • Cc: <stefano.stabellini@xxxxxxx>, <jbeulich@xxxxxxxx>, <andrew.cooper3@xxxxxxxxxx>, <roger.pau@xxxxxxxxxx>, <xenia.ragiadakou@xxxxxxx>
  • Delivery-date: Thu, 18 May 2023 23:45:26 +0000
  • List-id: Xen developer discussion <xen-devel.lists.xenproject.org>

Hi all,

After many PVH Dom0 suspend/resume cycles we are seeing the following
Xen crash (it is random and doesn't reproduce reliably):

(XEN) [555.042981][<ffff82d04032a137>] R 
arch/x86/irq.c#_clear_irq_vector+0x214/0x2bd
(XEN) [555.042986][<ffff82d04032a74c>] F destroy_irq+0xe2/0x1b8
(XEN) [555.042991][<ffff82d0403276db>] F msi_free_irq+0x5e/0x1a7
(XEN) [555.042995][<ffff82d04032da2d>] F unmap_domain_pirq+0x441/0x4b4
(XEN) [555.043001][<ffff82d0402d29b9>] F 
arch/x86/hvm/vmsi.c#vpci_msi_disable+0xc0/0x155
(XEN) [555.043006][<ffff82d0402d39fc>] F vpci_msi_arch_disable+0x1e/0x2b
(XEN) [555.043013][<ffff82d04026561c>] F 
drivers/vpci/msi.c#control_write+0x109/0x10e
(XEN) [555.043018][<ffff82d0402640c3>] F vpci_write+0x11f/0x268
(XEN) [555.043024][<ffff82d0402c726a>] F 
arch/x86/hvm/io.c#vpci_portio_write+0xa0/0xa7
(XEN) [555.043029][<ffff82d0402c6682>] F hvm_process_io_intercept+0x203/0x26f
(XEN) [555.043034][<ffff82d0402c6718>] F hvm_io_intercept+0x2a/0x4c
(XEN) [555.043039][<ffff82d0402b6353>] F 
arch/x86/hvm/emulate.c#hvmemul_do_io+0x29b/0x5f6
(XEN) [555.043043][<ffff82d0402b66dd>] F 
arch/x86/hvm/emulate.c#hvmemul_do_io_buffer+0x2f/0x6a
(XEN) [555.043048][<ffff82d0402b7bde>] F hvmemul_do_pio_buffer+0x33/0x35
(XEN) [555.043053][<ffff82d0402c7042>] F handle_pio+0x6d/0x1b4
(XEN) [555.043059][<ffff82d04029ec20>] F svm_vmexit_handler+0x10bf/0x18b0
(XEN) [555.043064][<ffff82d0402034e5>] F svm_stgi_label+0x8/0x18
(XEN) [555.043067]
(XEN) [555.469861]
(XEN) [555.471855] ****************************************
(XEN) [555.477315] Panic on CPU 9:
(XEN) [555.480608] Assertion 'per_cpu(vector_irq, cpu)[old_vector] == irq' 
failed at arch/x86/irq.c:233
(XEN) [555.489882] ****************************************

Looking at the code in question, the ASSERT looks wrong to me.

Specifically, if you see send_cleanup_vector and
irq_move_cleanup_interrupt, it is entirely possible to have old_vector
still valid and also move_in_progress still set, but only some of the
per_cpu(vector_irq, me)[vector] cleared. It seems to me that this could
happen especially when an MSI has a large old_cpu_mask.

While we go and clear per_cpu(vector_irq, me)[vector] in each CPU one by
one, the state is that not all per_cpu(vector_irq, me)[vector] are
cleared and old_vector is still set.

If at this point we enter _clear_irq_vector, we are going to hit the
ASSERT above.

My suggestion was to turn the ASSERT into an if. Any better ideas?

Cheers,

Stefano

diff --git a/xen/arch/x86/irq.c b/xen/arch/x86/irq.c
index 20150b1c7f..c82c6b350a 100644
--- a/xen/arch/x86/irq.c
+++ b/xen/arch/x86/irq.c
@@ -230,9 +230,11 @@ static void _clear_irq_vector(struct irq_desc *desc)
 
         for_each_cpu(cpu, tmp_mask)
         {
-            ASSERT(per_cpu(vector_irq, cpu)[old_vector] == irq);
-            TRACE_3D(TRC_HW_IRQ_MOVE_FINISH, irq, old_vector, cpu);
-            per_cpu(vector_irq, cpu)[old_vector] = ~irq;
+            if ( per_cpu(vector_irq, cpu)[old_vector] == irq )
+            {
+                TRACE_3D(TRC_HW_IRQ_MOVE_FINISH, irq, old_vector, cpu);
+                per_cpu(vector_irq, cpu)[old_vector] = ~irq;
+            }
         }
 
         release_old_vec(desc);



 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.