Skip site navigation (1)Skip section navigation (2)
Date:      Thu, 5 Nov 2015 14:33:46 +0000 (UTC)
From:      =?UTF-8?Q?Roger_Pau_Monn=c3=a9?= <royger@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org
Subject:   svn commit: r290392 - in head/sys: x86/xen xen
Message-ID:  <201511051433.tA5EXkEw013935@repo.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: royger
Date: Thu Nov  5 14:33:46 2015
New Revision: 290392
URL: https://svnweb.freebsd.org/changeset/base/290392

Log:
  xen/intr: fix the event channel enabled per-cpu mask
  
  Fix two issues with the current event channel code, first ENABLED_SETSIZE is
  not correctly defined and then using a BITSET to store the per-cpu masks is
  not portable to other arches, since on arm32 the event channel arrays shared
  with the hypervisor are of type uint64_t and not long. Partially restore the
  previous code but switch the bit operations to use the recently introduced
  xen_{set/clear/test}_bit versions.
  
  Reviewed by:		Julien Grall <julien.grall@citrix.com>
  Sponsored by:		Citrix Systems R&D
  Differential Revision:	https://reviews.freebsd.org/D4080

Modified:
  head/sys/x86/xen/xen_intr.c
  head/sys/xen/xen-os.h

Modified: head/sys/x86/xen/xen_intr.c
==============================================================================
--- head/sys/x86/xen/xen_intr.c	Thu Nov  5 11:06:46 2015	(r290391)
+++ head/sys/x86/xen/xen_intr.c	Thu Nov  5 14:33:46 2015	(r290392)
@@ -71,9 +71,6 @@ __FBSDID("$FreeBSD$");
 
 static MALLOC_DEFINE(M_XENINTR, "xen_intr", "Xen Interrupt Services");
 
-#define ENABLED_SETSIZE	(sizeof(u_long) * 8)
-BITSET_DEFINE(enabledbits, ENABLED_SETSIZE);
-
 /**
  * Per-cpu event channel processing state.
  */
@@ -98,7 +95,7 @@ struct xen_intr_pcpu_data {
 	 * A bitmap of ports that can be serviced from this CPU.
 	 * A set bit means interrupt handling is enabled.
 	 */
-	struct enabledbits evtchn_enabled;
+	u_long	evtchn_enabled[sizeof(u_long) * 8];
 };
 
 /*
@@ -215,7 +212,7 @@ evtchn_cpu_mask_port(u_int cpu, evtchn_p
 	struct xen_intr_pcpu_data *pcpu;
 
 	pcpu = DPCPU_ID_PTR(cpu, xen_intr_pcpu);
-	BIT_CLR_ATOMIC(ENABLED_SETSIZE, port, &pcpu->evtchn_enabled);
+	xen_clear_bit(port, pcpu->evtchn_enabled);
 }
 
 /**
@@ -237,7 +234,7 @@ evtchn_cpu_unmask_port(u_int cpu, evtchn
 	struct xen_intr_pcpu_data *pcpu;
 
 	pcpu = DPCPU_ID_PTR(cpu, xen_intr_pcpu);
-	BIT_SET_ATOMIC(ENABLED_SETSIZE, port, &pcpu->evtchn_enabled);
+	xen_set_bit(port, pcpu->evtchn_enabled);
 }
 
 /**
@@ -499,9 +496,14 @@ static inline u_long
 xen_intr_active_ports(struct xen_intr_pcpu_data *pcpu, shared_info_t *sh,
     u_int idx)
 {
+
+	CTASSERT(sizeof(sh->evtchn_mask[0]) == sizeof(sh->evtchn_pending[0]));
+	CTASSERT(sizeof(sh->evtchn_mask[0]) == sizeof(pcpu->evtchn_enabled[0]));
+	CTASSERT(sizeof(sh->evtchn_mask) == sizeof(sh->evtchn_pending));
+	CTASSERT(sizeof(sh->evtchn_mask) == sizeof(pcpu->evtchn_enabled));
 	return (sh->evtchn_pending[idx]
 	      & ~sh->evtchn_mask[idx]
-	      & pcpu->evtchn_enabled.__bits[idx]);
+	      & pcpu->evtchn_enabled[idx]);
 }
 
 /**
@@ -637,10 +639,8 @@ xen_intr_init(void *dummy __unused)
 	 */
 	CPU_FOREACH(i) {
 		pcpu = DPCPU_ID_PTR(i, xen_intr_pcpu);
-		if (i == 0)
-			BIT_FILL(ENABLED_SETSIZE, &pcpu->evtchn_enabled);
-		else
-			BIT_ZERO(ENABLED_SETSIZE, &pcpu->evtchn_enabled);
+		memset(pcpu->evtchn_enabled, i == 0 ? ~0 : 0,
+		    sizeof(pcpu->evtchn_enabled));
 		xen_intr_intrcnt_add(i);
 	}
 
@@ -753,11 +753,8 @@ xen_intr_resume(struct pic *unused, bool
 		struct xen_intr_pcpu_data *pcpu;
 
 		pcpu = DPCPU_ID_PTR(i, xen_intr_pcpu);
-
-		if (i == 0)
-			BIT_FILL(ENABLED_SETSIZE, &pcpu->evtchn_enabled);
-		else
-			BIT_ZERO(ENABLED_SETSIZE, &pcpu->evtchn_enabled);
+		memset(pcpu->evtchn_enabled, i == 0 ? ~0 : 0,
+		    sizeof(pcpu->evtchn_enabled));
 	}
 
 	/* Mask all event channels. */
@@ -1612,8 +1609,7 @@ xen_intr_dump_port(struct xenisrc *isrc)
 	CPU_FOREACH(i) {
 		pcpu = DPCPU_ID_PTR(i, xen_intr_pcpu);
 		db_printf("cpu#%d: %d ", i,
-		    BIT_ISSET(ENABLED_SETSIZE, isrc->xi_port,
-			&pcpu->evtchn_enabled));
+		    !!xen_test_bit(isrc->xi_port, pcpu->evtchn_enabled));
 	}
 	db_printf("\n");
 }

Modified: head/sys/xen/xen-os.h
==============================================================================
--- head/sys/xen/xen-os.h	Thu Nov  5 11:06:46 2015	(r290391)
+++ head/sys/xen/xen-os.h	Thu Nov  5 14:33:46 2015	(r290392)
@@ -112,6 +112,12 @@ xen_set_bit(int bit, volatile long *addr
 	atomic_set_long(&addr[bit / NBPL], 1UL << (bit % NBPL));
 }
 
+static inline void
+xen_clear_bit(int bit, volatile long *addr)
+{
+	atomic_clear_long(&addr[bit / NBPL], 1UL << (bit % NBPL));
+}
+
 #undef NPBL
 
 /*



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201511051433.tA5EXkEw013935>