Skip site navigation (1)Skip section navigation (2)
Date:      Thu, 18 Oct 2012 12:06:26 +0000 (UTC)
From:      Marius Strobl <marius@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-9@freebsd.org
Subject:   svn commit: r241681 - in stable/9/sys: dev/esp kern sparc64/include sparc64/sparc64
Message-ID:  <201210181206.q9IC6Qbc029881@svn.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: marius
Date: Thu Oct 18 12:06:26 2012
New Revision: 241681
URL: http://svn.freebsd.org/changeset/base/241681

Log:
  MFC: r239864
  
  - Unlike cache invalidation and TLB demapping IPIs, reading registers from
    other CPUs doesn't require locking so get rid of it. As the latter is used
    for the timecounter on certain machine models, using a spin lock in this
    case can lead to a deadlock with the upcoming callout(9) rework.
  - Merge r134227/r167250 from x86:
    Avoid cross-IPI SMP deadlock by using the smp_ipi_mtx spin lock not only
    for smp_rendezvous_cpus() but also for the MD cache invalidation and TLB
    demapping IPIs.
  - Mark some unused function arguments as such.

Modified:
  stable/9/sys/dev/esp/ncr53c9x.c
  stable/9/sys/kern/subr_witness.c
  stable/9/sys/sparc64/include/smp.h
  stable/9/sys/sparc64/sparc64/mp_machdep.c
  stable/9/sys/sparc64/sparc64/tick.c
Directory Properties:
  stable/9/sys/   (props changed)
  stable/9/sys/amd64/include/xen/   (props changed)
  stable/9/sys/boot/   (props changed)
  stable/9/sys/boot/i386/efi/   (props changed)
  stable/9/sys/boot/ia64/efi/   (props changed)
  stable/9/sys/boot/ia64/ski/   (props changed)
  stable/9/sys/boot/powerpc/boot1.chrp/   (props changed)
  stable/9/sys/boot/powerpc/ofw/   (props changed)
  stable/9/sys/cddl/contrib/opensolaris/   (props changed)
  stable/9/sys/conf/   (props changed)
  stable/9/sys/contrib/dev/acpica/   (props changed)
  stable/9/sys/contrib/octeon-sdk/   (props changed)
  stable/9/sys/contrib/pf/   (props changed)
  stable/9/sys/contrib/x86emu/   (props changed)
  stable/9/sys/dev/   (props changed)
  stable/9/sys/dev/e1000/   (props changed)
  stable/9/sys/dev/isp/   (props changed)
  stable/9/sys/dev/ixgbe/   (props changed)
  stable/9/sys/dev/puc/   (props changed)
  stable/9/sys/fs/   (props changed)
  stable/9/sys/fs/ntfs/   (props changed)
  stable/9/sys/modules/   (props changed)

Modified: stable/9/sys/dev/esp/ncr53c9x.c
==============================================================================
--- stable/9/sys/dev/esp/ncr53c9x.c	Thu Oct 18 12:04:56 2012	(r241680)
+++ stable/9/sys/dev/esp/ncr53c9x.c	Thu Oct 18 12:06:26 2012	(r241681)
@@ -26,7 +26,7 @@
  *
  */
 
-/*	$NetBSD: ncr53c9x.c,v 1.143 2011/07/31 18:39:00 jakllsch Exp $	*/
+/*	$NetBSD: ncr53c9x.c,v 1.145 2012/06/18 21:23:56 martin Exp $	*/
 
 /*-
  * Copyright (c) 1998, 2002 The NetBSD Foundation, Inc.
@@ -256,7 +256,7 @@ ncr53c9x_attach(struct ncr53c9x_softc *s
 		return (EINVAL);
 	}
 
-	device_printf(sc->sc_dev, "%s, %dMHz, SCSI ID %d\n",
+	device_printf(sc->sc_dev, "%s, %d MHz, SCSI ID %d\n",
 	    ncr53c9x_variant_names[sc->sc_rev], sc->sc_freq, sc->sc_id);
 
 	sc->sc_ntarg = (sc->sc_rev == NCR_VARIANT_FAS366) ? 16 : 8;
@@ -890,11 +890,8 @@ ncr53c9x_select(struct ncr53c9x_softc *s
 		sc->sc_cmdp = cmd;
 		error = NCRDMA_SETUP(sc, &sc->sc_cmdp, &sc->sc_cmdlen, 0,
 		    &dmasize);
-		if (error != 0) {
-			sc->sc_cmdlen = 0;
-			sc->sc_cmdp = NULL;
+		if (error != 0)
 			goto cmd;
-		}
 
 		/* Program the SCSI counter. */
 		NCR_SET_COUNT(sc, dmasize);
@@ -920,6 +917,7 @@ cmd:
 	 */
 
 	/* Now get the command into the FIFO. */
+	sc->sc_cmdlen = 0;
 	ncr53c9x_wrfifo(sc, cmd, clen);
 
 	/* And get the target's attention. */
@@ -1771,7 +1769,7 @@ ncr53c9x_msgin(struct ncr53c9x_softc *sc
 	struct ncr53c9x_linfo *li;
 	struct ncr53c9x_tinfo *ti;
 	uint8_t *pb;
-	int lun, plen;
+	int len, lun;
 
 	NCR_LOCK_ASSERT(sc, MA_OWNED);
 
@@ -1818,15 +1816,15 @@ ncr53c9x_msgin(struct ncr53c9x_softc *sc
 		 */
 		case NCR_RESELECTED:
 			pb = sc->sc_imess + 1;
-			plen = sc->sc_imlen - 1;
+			len = sc->sc_imlen - 1;
 			break;
 
 		default:
 			pb = sc->sc_imess;
-			plen = sc->sc_imlen;
+			len = sc->sc_imlen;
 		}
 
-		if (__verify_msg_format(pb, plen))
+		if (__verify_msg_format(pb, len))
 			goto gotit;
 	}
 
@@ -1963,6 +1961,29 @@ gotit:
 			sc->sc_dleft = ecb->dleft;
 			break;
 
+		case MSG_IGN_WIDE_RESIDUE:
+			NCR_MSGS(("ignore wide residue (%d bytes)",
+			    sc->sc_imess[1]));
+			if (sc->sc_imess[1] != 1) {
+				xpt_print_path(ecb->ccb->ccb_h.path);
+				printf("unexpected MESSAGE IGNORE WIDE "
+				    "RESIDUE (%d bytes); sending REJECT\n",
+				    sc->sc_imess[1]);
+				goto reject;
+			}
+			/*
+			 * If there was a last transfer of an even number of
+			 * bytes, wipe the "done" memory and adjust by one
+			 * byte (sc->sc_imess[1]).
+			 */
+			len = sc->sc_dleft - ecb->dleft;
+			if (len != 0 && (len & 1) == 0) {
+				ecb->flags &= ~ECB_TENTATIVE_DONE;
+				sc->sc_dp = (char *)sc->sc_dp - 1;
+				sc->sc_dleft--;
+			}
+			break;
+
 		case MSG_EXTENDED:
 			NCR_MSGS(("extended(%x) ", sc->sc_imess[2]));
 			switch (sc->sc_imess[2]) {
@@ -2272,6 +2293,7 @@ cmd:
 	/*
 	 * XXX FIFO size
 	 */
+	sc->sc_cmdlen = 0;
 	ncr53c9x_flushfifo(sc);
 	ncr53c9x_wrfifo(sc, sc->sc_omp, sc->sc_omlen);
 	NCRCMD(sc, NCRCMD_TRANS);
@@ -2811,9 +2833,10 @@ again:
 				 * (Timing problems?)
 				 */
 				if (sc->sc_features & NCR_F_DMASELECT) {
-					if (sc->sc_cmdlen == 0)
+					if (sc->sc_cmdlen == 0) {
 						/* Hope for the best... */
 						break;
+					}
 				} else if ((NCR_READ_REG(sc, NCR_FFLAG) &
 				    NCRFIFO_FF) == 0) {
 					/* Hope for the best... */
@@ -2986,11 +3009,8 @@ msgin:
 			sc->sc_cmdp = (void *)&ecb->cmd.cmd;
 			error = NCRDMA_SETUP(sc, &sc->sc_cmdp, &sc->sc_cmdlen,
 			    0, &size);
-			if (error != 0) {
-				sc->sc_cmdlen = 0;
-				sc->sc_cmdp = NULL;
+			if (error != 0)
 				goto cmd;
-			}
 
 			/* Program the SCSI counter. */
 			NCR_SET_COUNT(sc, size);
@@ -3005,6 +3025,7 @@ msgin:
 			break;
 		}
 cmd:
+		sc->sc_cmdlen = 0;
 		ncr53c9x_wrfifo(sc, (uint8_t *)&ecb->cmd.cmd, ecb->clen);
 		NCRCMD(sc, NCRCMD_TRANS);
 		sc->sc_prevphase = COMMAND_PHASE;
@@ -3046,7 +3067,7 @@ setup_xfer:
 			goto finish;
 		}
 
-		/* Target returned to data phase: wipe "done" memory */
+		/* Target returned to data phase: wipe "done" memory. */
 		ecb->flags &= ~ECB_TENTATIVE_DONE;
 
 		/* Program the SCSI counter. */
@@ -3105,8 +3126,8 @@ shortcut:
 	 * overhead to pay.  For example, selecting, sending a message
 	 * and command and then doing some work can be done in one "pass".
 	 *
-	 * The delay is a heuristic.  It is 2 when at 20MHz, 2 at 25MHz and 1
-	 * at 40MHz. This needs testing.
+	 * The delay is a heuristic.  It is 2 when at 20 MHz, 2 at 25 MHz and
+	 * 1 at 40 MHz.  This needs testing.
 	 */
 	microtime(&wait);
 	wait.tv_usec += 50 / sc->sc_freq;
@@ -3191,8 +3212,7 @@ ncr53c9x_callout(void *arg)
 		ncr53c9x_abort(sc, ecb);
 
 		/* Disable sync mode if stuck in a data phase. */
-		if (ecb == sc->sc_nexus &&
-		    ti->curr.offset != 0 &&
+		if (ecb == sc->sc_nexus && ti->curr.offset != 0 &&
 		    (sc->sc_phase & (MSGI | CDI)) == 0) {
 			/* XXX ASYNC CALLBACK! */
 			ti->goal.offset = 0;

Modified: stable/9/sys/kern/subr_witness.c
==============================================================================
--- stable/9/sys/kern/subr_witness.c	Thu Oct 18 12:04:56 2012	(r241680)
+++ stable/9/sys/kern/subr_witness.c	Thu Oct 18 12:06:26 2012	(r241681)
@@ -668,9 +668,6 @@ static struct witness_order_list_entry o
 	 */
 	{ "intrcnt", &lock_class_mtx_spin },
 	{ "icu", &lock_class_mtx_spin },
-#if defined(SMP) && defined(__sparc64__)
-	{ "ipi", &lock_class_mtx_spin },
-#endif
 #ifdef __i386__
 	{ "allpmaps", &lock_class_mtx_spin },
 	{ "descriptor tables", &lock_class_mtx_spin },

Modified: stable/9/sys/sparc64/include/smp.h
==============================================================================
--- stable/9/sys/sparc64/include/smp.h	Thu Oct 18 12:04:56 2012	(r241680)
+++ stable/9/sys/sparc64/include/smp.h	Thu Oct 18 12:06:26 2012	(r241681)
@@ -109,7 +109,6 @@ extern	cpu_ipi_single_t *cpu_ipi_single;
 
 void	mp_init(u_int cpu_impl);
 
-extern	struct mtx ipi_mtx;
 extern	struct ipi_cache_args ipi_cache_args;
 extern	struct ipi_rd_args ipi_rd_args;
 extern	struct ipi_tlb_args ipi_tlb_args;
@@ -169,7 +168,7 @@ ipi_dcache_page_inval(void *func, vm_pad
 		return (NULL);
 	sched_pin();
 	ica = &ipi_cache_args;
-	mtx_lock_spin(&ipi_mtx);
+	mtx_lock_spin(&smp_ipi_mtx);
 	ica->ica_mask = all_cpus;
 	CPU_CLR(PCPU_GET(cpuid), &ica->ica_mask);
 	ica->ica_pa = pa;
@@ -186,7 +185,7 @@ ipi_icache_page_inval(void *func, vm_pad
 		return (NULL);
 	sched_pin();
 	ica = &ipi_cache_args;
-	mtx_lock_spin(&ipi_mtx);
+	mtx_lock_spin(&smp_ipi_mtx);
 	ica->ica_mask = all_cpus;
 	CPU_CLR(PCPU_GET(cpuid), &ica->ica_mask);
 	ica->ica_pa = pa;
@@ -203,7 +202,6 @@ ipi_rd(u_int cpu, void *func, u_long *va
 		return (NULL);
 	sched_pin();
 	ira = &ipi_rd_args;
-	mtx_lock_spin(&ipi_mtx);
 	CPU_SETOF(cpu, &ira->ira_mask);
 	ira->ira_val = val;
 	cpu_ipi_single(cpu, 0, (u_long)func, (u_long)ira);
@@ -227,7 +225,7 @@ ipi_tlb_context_demap(struct pmap *pm)
 		return (NULL);
 	}
 	ita = &ipi_tlb_args;
-	mtx_lock_spin(&ipi_mtx);
+	mtx_lock_spin(&smp_ipi_mtx);
 	ita->ita_mask = cpus;
 	ita->ita_pmap = pm;
 	cpu_ipi_selected(cpus, 0, (u_long)tl_ipi_tlb_context_demap,
@@ -252,7 +250,7 @@ ipi_tlb_page_demap(struct pmap *pm, vm_o
 		return (NULL);
 	}
 	ita = &ipi_tlb_args;
-	mtx_lock_spin(&ipi_mtx);
+	mtx_lock_spin(&smp_ipi_mtx);
 	ita->ita_mask = cpus;
 	ita->ita_pmap = pm;
 	ita->ita_va = va;
@@ -277,7 +275,7 @@ ipi_tlb_range_demap(struct pmap *pm, vm_
 		return (NULL);
 	}
 	ita = &ipi_tlb_args;
-	mtx_lock_spin(&ipi_mtx);
+	mtx_lock_spin(&smp_ipi_mtx);
 	ita->ita_mask = cpus;
 	ita->ita_pmap = pm;
 	ita->ita_start = start;
@@ -295,7 +293,19 @@ ipi_wait(void *cookie)
 	if ((mask = cookie) != NULL) {
 		while (!CPU_EMPTY(mask))
 			;
-		mtx_unlock_spin(&ipi_mtx);
+		mtx_unlock_spin(&smp_ipi_mtx);
+		sched_unpin();
+	}
+}
+
+static __inline void
+ipi_wait_unlocked(void *cookie)
+{
+	volatile cpuset_t *mask;
+
+	if ((mask = cookie) != NULL) {
+		while (!CPU_EMPTY(mask))
+			;
 		sched_unpin();
 	}
 }
@@ -352,7 +362,13 @@ ipi_tlb_range_demap(struct pmap *pm __un
 }
 
 static __inline void
-ipi_wait(void *cookie)
+ipi_wait(void *cookie __unused)
+{
+
+}
+
+static __inline void
+ipi_wait_unlocked(void *cookie __unused)
 {
 
 }

Modified: stable/9/sys/sparc64/sparc64/mp_machdep.c
==============================================================================
--- stable/9/sys/sparc64/sparc64/mp_machdep.c	Thu Oct 18 12:04:56 2012	(r241680)
+++ stable/9/sys/sparc64/sparc64/mp_machdep.c	Thu Oct 18 12:06:26 2012	(r241681)
@@ -113,8 +113,6 @@ struct	ipi_rd_args ipi_rd_args;
 struct	ipi_tlb_args ipi_tlb_args;
 struct	pcb stoppcbs[MAXCPU];
 
-struct	mtx ipi_mtx;
-
 cpu_ipi_selected_t *cpu_ipi_selected;
 cpu_ipi_single_t *cpu_ipi_single;
 
@@ -280,8 +278,6 @@ void
 cpu_mp_start(void)
 {
 
-	mtx_init(&ipi_mtx, "ipi", NULL, MTX_SPIN);
-
 	intr_setup(PIL_AST, cpu_ipi_ast, -1, NULL, NULL);
 	intr_setup(PIL_RENDEZVOUS, (ih_func_t *)smp_rendezvous_action,
 	    -1, NULL, NULL);
@@ -503,13 +499,13 @@ cpu_mp_shutdown(void)
 }
 
 static void
-cpu_ipi_ast(struct trapframe *tf)
+cpu_ipi_ast(struct trapframe *tf __unused)
 {
 
 }
 
 static void
-cpu_ipi_stop(struct trapframe *tf)
+cpu_ipi_stop(struct trapframe *tf __unused)
 {
 	u_int cpuid;
 

Modified: stable/9/sys/sparc64/sparc64/tick.c
==============================================================================
--- stable/9/sys/sparc64/sparc64/tick.c	Thu Oct 18 12:04:56 2012	(r241680)
+++ stable/9/sys/sparc64/sparc64/tick.c	Thu Oct 18 12:06:26 2012	(r241681)
@@ -332,7 +332,7 @@ stick_get_timecount_mp(struct timecounte
 	if (curcpu == 0)
 		stick = rdstick();
 	else
-		ipi_wait(ipi_rd(0, tl_ipi_stick_rd, &stick));
+		ipi_wait_unlocked(ipi_rd(0, tl_ipi_stick_rd, &stick));
 	sched_unpin();
 	return (stick);
 }
@@ -346,7 +346,7 @@ tick_get_timecount_mp(struct timecounter
 	if (curcpu == 0)
 		tick = rd(tick);
 	else
-		ipi_wait(ipi_rd(0, tl_ipi_tick_rd, &tick));
+		ipi_wait_unlocked(ipi_rd(0, tl_ipi_tick_rd, &tick));
 	sched_unpin();
 	return (tick);
 }



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