public inbox for linux-ia64@vger.kernel.org
 help / color / mirror / Atom feed
From: Prarit Bhargava <prarit@sgi.com>
To: linux-ia64@vger.kernel.org
Subject: Re: [PATCH] SN2 user-MMIO CPU migration
Date: Thu, 26 Jan 2006 23:44:14 +0000	[thread overview]
Message-ID: <43D95ECE.2020104@sgi.com> (raw)
In-Reply-To: <20060118163305.Y42462@chenjesu.americas.sgi.com>

[-- Attachment #1: Type: text/plain, Size: 434 bytes --]

Luck, Tony wrote:
> But sadly it still says:
> 
> arch/ia64/sn/kernel/sn2/sn2_smp.c:110: warning: initialization discards qualifiers from pointer target type
> arch/ia64/sn/kernel/sn2/sn2_smp.c:111: warning: ISO C90 forbids mixed declarations and code
> 
> The double ;; is responsible for error on 111, need an extra volatile on 110?

Tony -- again, my apologies.  This time I double-checked that sn2_smp.c 
cleanly compiles.

P.




[-- Attachment #2: newpatch.patch --]
[-- Type: text/plain, Size: 9906 bytes --]

On SN2, MMIO writes which are issued from separate processors are not
guaranteed to arrive in any particular order at the IO hardware.  When
performing such writes from the kernel this is not a problem, as a
kernel thread will not migrate to another CPU during execution, and
mmiowb() calls can guarantee write ordering when control of the IO
resource is allowed to move between threads.

However, when MMIO writes can be performed from user space (e.g. DRM)
there are no such guarantees and mechanisms, as the process may
context-switch at any time, and may migrate to a different CPU as part
of the switch.  For such programs/hardware to operate correctly, it is
required that the MMIO writes from the old CPU be accepted by the IO
hardware before subsequent writes from the new CPU can be issued.

The following patch implements this behavior on SN2 by waiting for a
Shub register to indicate that these writes have been accepted.  This
is placed in the context switch-in path, and only performs the wait
when the newly scheduled task changes CPUs.

Signed-off-by: Prarit Bhargava <prarit@sgi.com>
Signed-off-by: Brent Casavant <bcasavan@sgi.com>

---

Take 6. Fixed build warnings.  This reintroduces the "volatile"
specifier that Keith and Ken want removed, as the pda_t has
volatile specifiers in its member elements, and as Keith said
that we should keep the specifier until the icc ia64_hint()
macro is fixed (Ken currently has a patch pending).

---
commit ff50f390c79bb090166bd1fdd653be22cbaca5d3
tree 251dd80647bd3a0140f5f31c35c125094c035f9c
parent 3ee68c4af3fd7228c1be63254b9f884614f9ebb2
author root <root@altix3.lab.boston.redhat.com> Thu, 26 Jan 2006 19:34:57 -0500
committer root <root@altix3.lab.boston.redhat.com> Thu, 26 Jan 2006 19:34:57 -0500

 arch/ia64/sn/kernel/setup.c       |    6 ++++--
 arch/ia64/sn/kernel/sn2/sn2_smp.c |   23 ++++++++++++++++++++++-
 include/asm-ia64/machvec.h        |   13 +++++++++++++
 include/asm-ia64/machvec_sn2.h    |    4 +++-
 include/asm-ia64/processor.h      |    3 ++-
 include/asm-ia64/system.h         |    7 +++++++
 include/asm-ia64/thread_info.h    |    1 +
 7 files changed, 52 insertions(+), 5 deletions(-)

diff --git a/arch/ia64/sn/kernel/setup.c b/arch/ia64/sn/kernel/setup.c
--- a/arch/ia64/sn/kernel/setup.c
+++ b/arch/ia64/sn/kernel/setup.c
@@ -3,7 +3,7 @@
  * License.  See the file "COPYING" in the main directory of this archive
  * for more details.
  *
- * Copyright (C) 1999,2001-2005 Silicon Graphics, Inc. All rights reserved.
+ * Copyright (C) 1999,2001-2006 Silicon Graphics, Inc. All rights reserved.
  */
 
 #include <linux/config.h>
@@ -496,6 +496,7 @@ void __init sn_setup(char **cmdline_p)
 	 * for sn.
 	 */
 	pm_power_off = ia64_sn_power_down;
+	current->thread.flags |= IA64_THREAD_MIGRATION;
 }
 
 /**
@@ -654,7 +655,8 @@ void __init sn_cpu_init(void)
 			SH2_PIO_WRITE_STATUS_1, SH2_PIO_WRITE_STATUS_3};
 		u64 *pio;
 		pio = is_shub1() ? pio1 : pio2;
-		pda->pio_write_status_addr = (volatile unsigned long *) LOCAL_MMR_ADDR(pio[slice]);
+		pda->pio_write_status_addr =
+		   (volatile unsigned long *)GLOBAL_MMR_ADDR(nasid, pio[slice]);
 		pda->pio_write_status_val = is_shub1() ? SH_PIO_WRITE_STATUS_PENDING_WRITE_COUNT_MASK : 0;
 	}
 
diff --git a/arch/ia64/sn/kernel/sn2/sn2_smp.c b/arch/ia64/sn/kernel/sn2/sn2_smp.c
--- a/arch/ia64/sn/kernel/sn2/sn2_smp.c
+++ b/arch/ia64/sn/kernel/sn2/sn2_smp.c
@@ -5,7 +5,7 @@
  * License.  See the file "COPYING" in the main directory of this archive
  * for more details.
  *
- * Copyright (C) 2000-2005 Silicon Graphics, Inc. All rights reserved.
+ * Copyright (C) 2000-2006 Silicon Graphics, Inc. All rights reserved.
  */
 
 #include <linux/init.h>
@@ -169,6 +169,27 @@ static inline unsigned long wait_piowc(v
 	return ws;
 }
 
+/**
+ * sn_migrate - SN-specific task migration actions
+ * @task: Task being migrated to new CPU
+ *
+ * SN2 PIO writes from separate CPUs are not guaranteed to arrive in order.
+ * Context switching user threads which have memory-mapped MMIO may cause
+ * PIOs to issue from seperate CPUs, thus the PIO writes must be drained
+ * from the previous CPU's Shub before execution resumes on the new CPU.
+ */
+void sn_migrate(struct task_struct *task)
+{
+	pda_t *last_pda = pdacpu(task_thread_info(task)->last_cpu);
+	volatile unsigned long *adr = last_pda->pio_write_status_addr;
+	unsigned long val = last_pda->pio_write_status_val;
+
+	/* Drain PIO writes from old CPU's Shub */
+	while (unlikely((*adr & SH_PIO_WRITE_STATUS_PENDING_WRITE_COUNT_MASK)
+			!= val))
+		cpu_relax();
+}
+
 void sn_tlb_migrate_finish(struct mm_struct *mm)
 {
 	if (mm == current->mm)
diff --git a/include/asm-ia64/machvec.h b/include/asm-ia64/machvec.h
--- a/include/asm-ia64/machvec.h
+++ b/include/asm-ia64/machvec.h
@@ -20,6 +20,7 @@ struct scatterlist;
 struct page;
 struct mm_struct;
 struct pci_bus;
+struct task_struct;
 
 typedef void ia64_mv_setup_t (char **);
 typedef void ia64_mv_cpu_init_t (void);
@@ -34,6 +35,7 @@ typedef int ia64_mv_pci_legacy_read_t (s
 				       u8 size);
 typedef int ia64_mv_pci_legacy_write_t (struct pci_bus *, u16 port, u32 val,
 					u8 size);
+typedef void ia64_mv_migrate_t(struct task_struct * task);
 
 /* DMA-mapping interface: */
 typedef void ia64_mv_dma_init (void);
@@ -85,6 +87,11 @@ machvec_noop_mm (struct mm_struct *mm)
 {
 }
 
+static inline void
+machvec_noop_task (struct task_struct *task)
+{
+}
+
 extern void machvec_setup (char **);
 extern void machvec_timer_interrupt (int, void *, struct pt_regs *);
 extern void machvec_dma_sync_single (struct device *, dma_addr_t, size_t, int);
@@ -146,6 +153,7 @@ extern void machvec_tlb_migrate_finish (
 #  define platform_readw_relaxed        ia64_mv.readw_relaxed
 #  define platform_readl_relaxed        ia64_mv.readl_relaxed
 #  define platform_readq_relaxed        ia64_mv.readq_relaxed
+#  define platform_migrate		ia64_mv.migrate
 # endif
 
 /* __attribute__((__aligned__(16))) is required to make size of the
@@ -194,6 +202,7 @@ struct ia64_machine_vector {
 	ia64_mv_readw_relaxed_t *readw_relaxed;
 	ia64_mv_readl_relaxed_t *readl_relaxed;
 	ia64_mv_readq_relaxed_t *readq_relaxed;
+	ia64_mv_migrate_t *migrate;
 } __attribute__((__aligned__(16))); /* align attrib? see above comment */
 
 #define MACHVEC_INIT(name)			\
@@ -238,6 +247,7 @@ struct ia64_machine_vector {
 	platform_readw_relaxed,			\
 	platform_readl_relaxed,			\
 	platform_readq_relaxed,			\
+	platform_migrate,			\
 }
 
 extern struct ia64_machine_vector ia64_mv;
@@ -386,5 +396,8 @@ extern ia64_mv_dma_supported		swiotlb_dm
 #ifndef platform_readq_relaxed
 # define platform_readq_relaxed	__ia64_readq_relaxed
 #endif
+#ifndef platform_migrate
+# define platform_migrate machvec_noop_task
+#endif
 
 #endif /* _ASM_IA64_MACHVEC_H */
diff --git a/include/asm-ia64/machvec_sn2.h b/include/asm-ia64/machvec_sn2.h
--- a/include/asm-ia64/machvec_sn2.h
+++ b/include/asm-ia64/machvec_sn2.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2002-2003 Silicon Graphics, Inc.  All Rights Reserved.
+ * Copyright (c) 2002-2003,2006 Silicon Graphics, Inc.  All Rights Reserved.
  * 
  * This program is free software; you can redistribute it and/or modify it 
  * under the terms of version 2 of the GNU General Public License 
@@ -71,6 +71,7 @@ extern ia64_mv_dma_sync_single_for_devic
 extern ia64_mv_dma_sync_sg_for_device	sn_dma_sync_sg_for_device;
 extern ia64_mv_dma_mapping_error	sn_dma_mapping_error;
 extern ia64_mv_dma_supported		sn_dma_supported;
+extern ia64_mv_migrate_t		sn_migrate;
 
 /*
  * This stuff has dual use!
@@ -120,6 +121,7 @@ extern ia64_mv_dma_supported		sn_dma_sup
 #define platform_dma_sync_sg_for_device	sn_dma_sync_sg_for_device
 #define platform_dma_mapping_error		sn_dma_mapping_error
 #define platform_dma_supported		sn_dma_supported
+#define platform_migrate		sn_migrate
 
 #include <asm/sn/io.h>
 
diff --git a/include/asm-ia64/processor.h b/include/asm-ia64/processor.h
--- a/include/asm-ia64/processor.h
+++ b/include/asm-ia64/processor.h
@@ -50,7 +50,8 @@
 #define IA64_THREAD_PM_VALID	(__IA64_UL(1) << 2)	/* performance registers valid? */
 #define IA64_THREAD_UAC_NOPRINT	(__IA64_UL(1) << 3)	/* don't log unaligned accesses */
 #define IA64_THREAD_UAC_SIGBUS	(__IA64_UL(1) << 4)	/* generate SIGBUS on unaligned acc. */
-							/* bit 5 is currently unused */
+#define IA64_THREAD_MIGRATION	(__IA64_UL(1) << 5)	/* require migration
+							   sync at ctx sw */
 #define IA64_THREAD_FPEMU_NOPRINT (__IA64_UL(1) << 6)	/* don't log any fpswa faults */
 #define IA64_THREAD_FPEMU_SIGFPE  (__IA64_UL(1) << 7)	/* send a SIGFPE for fpswa faults */
 
diff --git a/include/asm-ia64/system.h b/include/asm-ia64/system.h
--- a/include/asm-ia64/system.h
+++ b/include/asm-ia64/system.h
@@ -244,6 +244,13 @@ extern void ia64_load_extra (struct task
 		__ia64_save_fpu((prev)->thread.fph);				\
 	}									\
 	__switch_to(prev, next, last);						\
+	/* "next" in old context is "current" in new context */			\
+	if (unlikely((current->thread.flags & IA64_THREAD_MIGRATION) &&	       \
+		     (task_cpu(current) !=				       \
+		      		      task_thread_info(current)->last_cpu))) { \
+		platform_migrate(current);				       \
+		task_thread_info(current)->last_cpu = task_cpu(current);       \
+	}								       \
 } while (0)
 #else
 # define switch_to(prev,next,last)	__switch_to(prev, next, last)
diff --git a/include/asm-ia64/thread_info.h b/include/asm-ia64/thread_info.h
--- a/include/asm-ia64/thread_info.h
+++ b/include/asm-ia64/thread_info.h
@@ -26,6 +26,7 @@ struct thread_info {
 	struct exec_domain *exec_domain;/* execution domain */
 	__u32 flags;			/* thread_info flags (see TIF_*) */
 	__u32 cpu;			/* current CPU */
+	__u32 last_cpu;			/* Last CPU thread ran on */
 	mm_segment_t addr_limit;	/* user-level address space limit */
 	int preempt_count;		/* 0=premptable, <0=BUG; will also serve as bh-counter */
 	struct restart_block restart_block;

  parent reply	other threads:[~2006-01-26 23:44 UTC|newest]

Thread overview: 73+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2006-01-20  0:06 [PATCH] SN2 user-MMIO CPU migration Brent Casavant
2006-01-20  2:18 ` Jesse Barnes
2006-01-20  6:47   ` Brent Casavant
2006-01-20 17:36     ` Jesse Barnes
2006-01-20 20:01       ` Brent Casavant
2006-01-20 13:26   ` Jack Steiner
2006-01-20 17:31     ` Jesse Barnes
2006-01-20 19:00       ` Jack Steiner
2006-01-20  8:36 ` Ingo Molnar
2006-01-20 16:14   ` Brent Casavant
2006-01-24  0:33 ` Brent Casavant
2006-01-24  0:48 ` Luck, Tony
2006-01-24  1:23 ` Brent Casavant
2006-01-24  1:42 ` Keith Owens
2006-01-24  3:41 ` Grant Grundler
2006-01-24  6:30 ` Brent Casavant
2006-01-24  6:41 ` Brent Casavant
2006-01-24  7:04 ` Grant Grundler
2006-01-24  9:02 ` Ingo Molnar
2006-01-24  9:14 ` Jes Sorensen
2006-01-24 12:10 ` Robin Holt
2006-01-24 16:40 ` Grant Grundler
2006-01-24 16:52 ` Brent Casavant
2006-01-24 16:57 ` Brent Casavant
2006-01-24 17:00 ` Robin Holt
2006-01-24 17:33 ` Luck, Tony
2006-01-24 18:42 ` Grant Grundler
2006-01-24 21:12 ` Brent Casavant
2006-01-24 21:41 ` Ingo Molnar
2006-01-24 21:43 ` Chen, Kenneth W
2006-01-24 21:51 ` Luck, Tony
2006-01-24 22:04 ` Brent Casavant
2006-01-24 22:07 ` Chen, Kenneth W
2006-01-24 22:12 ` Brent Casavant
2006-01-24 22:19 ` Chen, Kenneth W
2006-01-24 22:31 ` Chen, Kenneth W
2006-01-24 22:41 ` Brent Casavant
2006-01-24 23:25 ` Chen, Kenneth W
2006-01-24 23:28 ` Brent Casavant
2006-01-24 23:36 ` Chen, Kenneth W
2006-01-24 23:54 ` Brent Casavant
2006-01-25  0:10 ` Brent Casavant
2006-01-25  0:29 ` Chen, Kenneth W
2006-01-25  6:27 ` Keith Owens
2006-01-25  9:04 ` Chen, Kenneth W
2006-01-25  9:24 ` Chen, Kenneth W
2006-01-25 17:04 ` Brent Casavant
2006-01-25 17:45 ` Brent Casavant
2006-01-25 17:48 ` Brent Casavant
2006-01-25 19:01 ` Chen, Kenneth W
2006-01-25 19:15 ` Brent Casavant
2006-01-25 19:43 ` Jack Steiner
2006-01-25 22:49 ` Brent Casavant
2006-01-25 23:09 ` Brent Casavant
2006-01-25 23:49 ` Brent Casavant
2006-01-25 23:56 ` Chen, Kenneth W
2006-01-26  1:06 ` Luck, Tony
2006-01-26  1:31 ` Prarit Bhargava
2006-01-26  2:43 ` Keith Owens
2006-01-26  4:40 ` Brent Casavant
2006-01-26 16:29 ` Brent Casavant
2006-01-26 16:41 ` Prarit Bhargava
2006-01-26 19:29 ` Brent Casavant
2006-01-26 19:54 ` Luck, Tony
2006-01-26 20:28 ` Brent Casavant
2006-01-26 21:05 ` Luck, Tony
2006-01-26 21:34 ` Prarit Bhargava
2006-01-26 22:11 ` Luck, Tony
2006-01-26 23:08 ` Luck, Tony
2006-01-26 23:21 ` Prarit Bhargava
2006-01-26 23:44 ` Prarit Bhargava [this message]
2006-01-27  0:07 ` Chen, Kenneth W
2006-01-27 14:01 ` Prarit Bhargava

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=43D95ECE.2020104@sgi.com \
    --to=prarit@sgi.com \
    --cc=linux-ia64@vger.kernel.org \
    /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