From: David Mosberger <davidm@hpl.hp.com>
To: linux-ia64@vger.kernel.org
Subject: [Linux-ia64] new kernel diff (relative to 2.3.99-pre5)
Date: Tue, 25 Apr 2000 03:31:50 +0000 [thread overview]
Message-ID: <marc-linux-ia64-105590678205032@msgid-missing> (raw)
A new IA-64 kernel diff is now available at:
ftp://ftp.kernel.org/linux/kernel/ports/ia64/
in files linux-2.3.99-pre5-ia64-000424.diff*. This diff is relative
to 2.3.99-pre5 and should work reasonably well on SMP (much better
than the previous patch, for sure...). The changes since the previous
patch are below. In summary:
- Don't prevent concurrent execution of IPI and timer interrupts.
This gets rid of the extremely frequent "ITM in past" messages we
were seeing. Thanks to Asit for pointing this out. Apparently,
this bug was fixed a while ago already and got re-introduced when
we switched to the new irq code (based on the x86 code). My bad.
- Put the itm[cpu].next value in a separate cachline for each CPU.
This ain't pretty and I think we'll want a separate global variable
(perhaps cpu[NUM_CPUS]) instead so we can collect (small) variables
that need to be per-CPU so that we don't waste most of a cache-line
for each such variable. But for now, this will do.
- Disable the gettimeoffset() code for SMP. That code doesn't work
_unless_ the ITC on all CPUs are in perfect synchrony. The effect
of this is that gettimeofday() will return values with timer-tick
(currently 10ms) resolution only. If someone has a smart idea on
how to do this properly on an SMP without assuming the presence of
an external timer chip and without causing extra IPIs, I'm all
ears. ;-)
- Various minor updates to sync up with 2.3.99-pre5. A noteworthy
change that the glibc folks should pay attention to: there are two
new system calls: madvise() and mincore(). We should add glibc
stubs for these (perhaps they're in glibc-2.2 already?).
- Some minor spinlock fixes.
Enjoy,
--david
diff -urN linux-davidm/arch/ia64/kernel/irq.c linux-2.3.99-pre5-lia/arch/ia64/kernel/irq.c
--- linux-davidm/arch/ia64/kernel/irq.c Fri Apr 21 18:50:34 2000
+++ linux-2.3.99-pre5-lia/arch/ia64/kernel/irq.c Mon Apr 24 17:12:22 2000
@@ -582,7 +582,8 @@
if (!(status & (IRQ_DISABLED | IRQ_INPROGRESS))) {
action = desc->action;
status &= ~IRQ_PENDING; /* we commit to handling */
- status |= IRQ_INPROGRESS; /* we are handling it */
+ if (!(status & IRQ_PER_CPU))
+ status |= IRQ_INPROGRESS; /* we are handling it */
}
desc->status = status;
diff -urN linux-davidm/arch/ia64/kernel/irq_ia64.c linux-2.3.99-pre5-lia/arch/ia64/kernel/irq_ia64.c
--- linux-davidm/arch/ia64/kernel/irq_ia64.c Fri Apr 21 18:50:34 2000
+++ linux-2.3.99-pre5-lia/arch/ia64/kernel/irq_ia64.c Mon Apr 24 19:00:21 2000
@@ -210,12 +210,12 @@
ia64_set_lrr0(0, 1);
ia64_set_lrr1(0, 1);
- irq_desc[TIMER_IRQ].handler = &irq_type_ia64_sapic;
irq_desc[IA64_SPURIOUS_INT].handler = &irq_type_ia64_sapic;
#ifdef CONFIG_SMP
/*
* Configure the IPI vector and handler
*/
+ irq_desc[IPI_IRQ].status |= IRQ_PER_CPU;
irq_desc[IPI_IRQ].handler = &irq_type_ia64_sapic;
setup_irq(IPI_IRQ, &ipi_irqaction);
#endif
diff -urN linux-davidm/arch/ia64/kernel/ivt.S linux-2.3.99-pre5-lia/arch/ia64/kernel/ivt.S
--- linux-davidm/arch/ia64/kernel/ivt.S Fri Apr 21 18:50:34 2000
+++ linux-2.3.99-pre5-lia/arch/ia64/kernel/ivt.S Fri Apr 21 20:18:50 2000
@@ -441,9 +441,6 @@
tbit.z p6,p0=r17,IA64_PSR_IS_BIT // IA64 instruction set?
;;
(p6) mov r16=r18 // if so, use cr.iip instead of cr.ifa
-#if 0
- ;;
-#endif
mov pr=r31,-1
#endif /* CONFIG_ITANIUM */
movl r30\x1f // load continuation point in case of nested fault
@@ -581,7 +578,7 @@
SAVE_REST
;;
alloc r14=ar.pfs,0,0,2,0 // must be first in an insn group
-#ifdef CONFIG_ITANIUM_ASTEP_SPECIFIC
+#ifdef CONFIG_ITANIUM_ASTEP_SPECIFIC
mov out0=r0 // defer reading of cr.ivr to handle_irq...
#else
mov out0=cr.ivr // pass cr.ivr as first arg
diff -urN linux-davidm/arch/ia64/kernel/process.c linux-2.3.99-pre5-lia/arch/ia64/kernel/process.c
--- linux-davidm/arch/ia64/kernel/process.c Fri Mar 10 15:24:02 2000
+++ linux-2.3.99-pre5-lia/arch/ia64/kernel/process.c Fri Apr 21 21:53:49 2000
@@ -98,11 +98,18 @@
if (pm_idle)
(*pm_idle)();
#ifdef CONFIG_ITANIUM_ASTEP_SPECIFIC
- if (ia64_get_itm() < ia64_get_itc()) {
- extern void ia64_reset_itm (void);
+ {
+ u64 itc, itm;
- printk("cpu_idle: ITM in past, resetting it...\n");
- ia64_reset_itm();
+ itc = ia64_get_itc();
+ itm = ia64_get_itm();
+ if (time_after(itc, itm)) {
+ extern void ia64_reset_itm (void);
+
+ printk("cpu_idle: ITM in past, resetting it (itc=%lx,itm=%lx:%lums)...\n",
+ itc, itm, (itc - itm)/500000);
+ ia64_reset_itm();
+ }
}
#endif
}
diff -urN linux-davidm/arch/ia64/kernel/time.c linux-2.3.99-pre5-lia/arch/ia64/kernel/time.c
--- linux-davidm/arch/ia64/kernel/time.c Fri Apr 21 18:50:34 2000
+++ linux-2.3.99-pre5-lia/arch/ia64/kernel/time.c Mon Apr 24 18:58:49 2000
@@ -34,7 +34,10 @@
static struct {
unsigned long delta;
- unsigned long next[NR_CPUS];
+ union {
+ unsigned long count;
+ unsigned char pad[SMP_CACHE_BYTES];
+ } next[NR_CPUS];
} itm;
static void
@@ -69,16 +72,24 @@
static inline unsigned long
gettimeoffset (void)
{
+#ifdef CONFIG_SMP
+ /*
+ * The code below doesn't work for SMP because only CPU 0
+ * keeps track of the time.
+ */
+ return 0;
+#else
unsigned long now = ia64_get_itc();
unsigned long elapsed_cycles, lost;
- elapsed_cycles = now - (itm.next[smp_processor_id()] - itm.delta);
+ elapsed_cycles = now - (itm.next[smp_processor_id()].count - itm.delta);
lost = lost_ticks;
if (lost)
elapsed_cycles += lost*itm.delta;
return (elapsed_cycles*my_cpu_data.usec_per_cyc) >> IA64_USEC_PER_CYC_SHIFT;
+#endif
}
void
@@ -164,7 +175,7 @@
do_timer(regs);
#endif
- itm.next[cpu] += itm.delta;
+ itm.next[cpu].count += itm.delta;
/*
* There is a race condition here: to be on the "safe"
* side, we process timer ticks until itm.next is
@@ -172,8 +183,8 @@
* interval. This should give us enough time to set
* the new itm value without losing a timer tick.
*/
- if (time_after(itm.next[cpu], ia64_get_itc() + itm.delta/2)) {
- ia64_set_itm(itm.next[cpu]);
+ if (time_after(itm.next[cpu].count, ia64_get_itc() + itm.delta/2)) {
+ ia64_set_itm(itm.next[cpu].count);
break;
}
@@ -182,19 +193,21 @@
* SoftSDV in SMP mode is _slow_, so we do "lose" ticks,
* but it's really OK...
*/
+ write_unlock(&xtime_lock);
if (count > 0 && jiffies - last_time > 5*HZ)
count = 0;
if (count++ = 0) {
last_time = jiffies;
if (!printed) {
printk("Lost clock tick on CPU %d (now=%lx, next=%lx)!!\n",
- cpu, ia64_get_itc(), itm.next[cpu]);
+ cpu, ia64_get_itc(), itm.next[cpu].count);
printed = 1;
- }
# ifdef CONFIG_IA64_DEBUG_IRQ
- printk("last_cli_ip=%lx\n", last_cli_ip);
+ printk("last_cli_ip=%lx\n", last_cli_ip);
# endif
+ }
}
+ write_lock(&xtime_lock);
#endif
}
write_unlock(&xtime_lock);
@@ -202,7 +215,7 @@
#ifdef CONFIG_ITANIUM_ASTEP_SPECIFIC
-void
+void
ia64_reset_itm (void)
{
unsigned long flags;
@@ -220,11 +233,14 @@
void __init
ia64_cpu_local_tick(void)
{
+#ifdef CONFIG_IA64_SOFTSDV_HACKS
+ ia64_set_itc(0);
+#endif
+
/* arrange for the cycle counter to generate a timer interrupt: */
ia64_set_itv(TIMER_IRQ, 0);
- ia64_set_itc(0);
- itm.next[smp_processor_id()] = ia64_get_itc() + itm.delta;
- ia64_set_itm(itm.next[smp_processor_id()]);
+ itm.next[smp_processor_id()].count = ia64_get_itc() + itm.delta;
+ ia64_set_itm(itm.next[smp_processor_id()].count);
}
void __init
@@ -313,6 +329,8 @@
time_init (void)
{
/* we can't do request_irq() here because the kmalloc() would fail... */
+ irq_desc[TIMER_IRQ].status |= IRQ_PER_CPU;
+ irq_desc[TIMER_IRQ].handler = &irq_type_ia64_sapic;
setup_irq(TIMER_IRQ, &timer_irqaction);
efi_gettimeofday(&xtime);
diff -urN linux-davidm/drivers/ide/piix.c linux-2.3.99-pre5-lia/drivers/ide/piix.c
--- linux-davidm/drivers/ide/piix.c Wed Mar 22 17:18:44 2000
+++ linux-2.3.99-pre5-lia/drivers/ide/piix.c Fri Apr 21 00:00:32 2000
@@ -396,8 +396,11 @@
void __init ide_init_piix (ide_hwif_t *hwif)
{
+#if 0
+ /* autoprobe instead... --davidm 00/04/20 */
if (!hwif->irq)
hwif->irq = hwif->channel ? 15 : 14;
+#endif
hwif->tuneproc = &piix_tune_drive;
hwif->drives[0].autotune = 1;
diff -urN linux-davidm/fs/binfmt_elf.c linux-2.3.99-pre5-lia/fs/binfmt_elf.c
--- linux-davidm/fs/binfmt_elf.c Fri Apr 21 18:50:35 2000
+++ linux-2.3.99-pre5-lia/fs/binfmt_elf.c Thu Apr 20 17:43:21 2000
@@ -282,8 +282,8 @@
set_brk(ia32_mm_addr(vaddr + load_addr), vaddr + load_addr + eppnt->p_memsz);
memset((char *) vaddr + load_addr + eppnt->p_filesz, 0,
eppnt->p_memsz - eppnt->p_filesz);
- read_exec(interpreter->f_dentry, eppnt->p_offset,
- (char *)(vaddr + load_addr), eppnt->p_filesz, 0);
+ kernel_read(interpreter, eppnt->p_offset, (char *)(vaddr + load_addr),
+ eppnt->p_filesz);
map_addr = vaddr + load_addr;
#else /* !CONFIG_BINFMT_ELF32 */
map_addr = do_mmap(interpreter,
@@ -299,9 +299,8 @@
(unsigned long) eppnt->p_memsz, (unsigned long) eppnt->p_filesz);
map_addr = vaddr + load_addr;
do_brk(map_addr & PAGE_MASK, eppnt->p_filesz);
- if (read_exec(file->f_dentry, eppnt->p_offset, (char *) map_addr,
- eppnt->p_filesz, 0)
- < 0)
+ if (kernel_read(interpreter, eppnt->p_offset, (char *) map_addr,
+ eppnt->p_filesz) < 0)
goto out_close;
}
@@ -650,8 +649,8 @@
set_brk(ia32_mm_addr(vaddr + load_bias), vaddr + load_bias + elf_ppnt->p_memsz);
memset((char *) vaddr + load_bias + elf_ppnt->p_filesz, 0,
elf_ppnt->p_memsz - elf_ppnt->p_filesz);
- read_exec(bprm->dentry, elf_ppnt->p_offset,
- (char *)(vaddr + load_bias), elf_ppnt->p_filesz, 0);
+ kernel_read(bprm->file, elf_ppnt->p_offset, (char *) (vaddr + load_bias),
+ elf_ppnt->p_filesz);
error = vaddr + load_bias;
#else /* CONFIG_BINFMT_ELF32 */
error = do_mmap(bprm->file, ELF_PAGESTART(load_bias + vaddr),
@@ -667,8 +666,8 @@
(unsigned long)elf_ppnt->p_filesz);
error = vaddr + load_bias;
do_brk(error & PAGE_MASK, elf_ppnt->p_filesz);
- error = read_exec(bprm->dentry, elf_ppnt->p_offset, (char *) error,
- elf_ppnt->p_filesz, 0);
+ error = kernel_read(bprm->file, elf_ppnt->p_offset, (char *) error,
+ elf_ppnt->p_filesz);
}
if (!load_addr_set) {
diff -urN linux-davidm/include/asm-ia64/spinlock.h linux-2.3.99-pre5-lia/include/asm-ia64/spinlock.h
--- linux-davidm/include/asm-ia64/spinlock.h Fri Apr 21 18:50:35 2000
+++ linux-2.3.99-pre5-lia/include/asm-ia64/spinlock.h Mon Apr 24 17:17:15 2000
@@ -9,6 +9,8 @@
* This file is used for SMP configurations only.
*/
+#include <linux/kernel.h>
+
#include <asm/system.h>
#include <asm/bitops.h>
#include <asm/atomic.h>
@@ -40,7 +42,7 @@
"cmp4.eq p0,p7 = r0, r2\n" \
"(p7) br.cond.spnt.few 1b\n" \
";;\n" \
- :: "m" __atomic_fool_gcc((x)) : "r2", "r29")
+ :: "m" __atomic_fool_gcc((x)) : "r2", "r29", "memory")
#else
#define spin_lock(x) \
@@ -55,22 +57,12 @@
#define spin_is_locked(x) ((x)->lock != 0)
-#define spin_unlock(x) (((spinlock_t *) x)->lock = 0)
+#define spin_unlock(x) ({((spinlock_t *) x)->lock = 0; barrier();})
/* Streamlined !test_and_set_bit(0, (x)) */
-#define spin_trylock(x) \
-({ \
- spinlock_t *__x = (x); \
- __u32 old; \
- \
- do { \
- old = __x->lock; \
- } while (cmpxchg_acq(&__x->lock, old, 1) != old); \
- old = 0; \
-})
+#define spin_trylock(x) (cmpxchg_acq(&(x)->lock, 0, 1) = 0)
-#define spin_unlock_wait(x) \
- ({ do { barrier(); } while(((volatile spinlock_t *)x)->lock); })
+#define spin_unlock_wait(x) ({ do { barrier(); } while ((x)->lock); })
typedef struct {
volatile int read_counter:31;
@@ -78,45 +70,49 @@
} rwlock_t;
#define RW_LOCK_UNLOCKED (rwlock_t) { 0, 0 }
-#define read_lock(rw) \
-do { \
- int tmp = 0; \
- __asm__ __volatile__ ("1:\tfetchadd4.acq %0 = %1, 1\n" \
- ";;\n" \
- "tbit.nz p6,p0 = %0, 31\n" \
- "(p6) br.cond.sptk.few 2f\n" \
- ".section .text.lock,\"ax\"\n" \
- "2:\tfetchadd4.rel %0 = %1, -1\n" \
- ";;\n" \
- "3:\tld4.acq %0 = %1\n" \
- ";;\n" \
- "tbit.nz p6,p0 = %0, 31\n" \
- "(p6) br.cond.sptk.few 3b\n" \
- "br.cond.sptk.few 1b\n" \
- ";;\n" \
- ".previous\n": "=r" (tmp), "=m" (__atomic_fool_gcc(rw))); \
+#define read_lock(rw) \
+do { \
+ int tmp = 0; \
+ __asm__ __volatile__ ("1:\tfetchadd4.acq %0 = %1, 1\n" \
+ ";;\n" \
+ "tbit.nz p6,p0 = %0, 31\n" \
+ "(p6) br.cond.sptk.few 2f\n" \
+ ".section .text.lock,\"ax\"\n" \
+ "2:\tfetchadd4.rel %0 = %1, -1\n" \
+ ";;\n" \
+ "3:\tld4.acq %0 = %1\n" \
+ ";;\n" \
+ "tbit.nz p6,p0 = %0, 31\n" \
+ "(p6) br.cond.sptk.few 3b\n" \
+ "br.cond.sptk.few 1b\n" \
+ ";;\n" \
+ ".previous\n" \
+ : "=r" (tmp), "=m" (__atomic_fool_gcc(rw)) \
+ :: "memory"); \
} while(0)
-#define read_unlock(rw) \
-do { \
- int tmp = 0; \
- __asm__ __volatile__ ("fetchadd4.rel %0 = %1, -1\n" \
- : "=r" (tmp) : "m" (__atomic_fool_gcc(rw))); \
+#define read_unlock(rw) \
+do { \
+ int tmp = 0; \
+ __asm__ __volatile__ ("fetchadd4.rel %0 = %1, -1\n" \
+ : "=r" (tmp) \
+ : "m" (__atomic_fool_gcc(rw)) \
+ : "memory"); \
} while(0)
#define write_lock(rw) \
-while(1) { \
+do { \
do { \
- } while (!test_and_set_bit(31, (rw))); \
- if ((rw)->read_counter) { \
- clear_bit(31, (rw)); \
- while ((rw)->read_counter) \
- ; \
- } else { \
- break; \
- } \
-}
+ while ((rw)->write_lock); \
+ } while (test_and_set_bit(31, (rw))); \
+ while ((rw)->read_counter); \
+ barrier(); \
+} while (0)
-#define write_unlock(x) (clear_bit(31, (x)))
+/*
+ * clear_bit() has "acq" semantics; we're really need "rel" semantics,
+ * but for simplicity, we simply do a fence for now...
+ */
+#define write_unlock(x) ({clear_bit(31, (x)); mb();})
#endif /* _ASM_IA64_SPINLOCK_H */
diff -urN linux-davidm/include/linux/irq.h linux-2.3.99-pre5-lia/include/linux/irq.h
--- linux-davidm/include/linux/irq.h Fri Apr 21 18:50:35 2000
+++ linux-2.3.99-pre5-lia/include/linux/irq.h Mon Apr 24 17:17:24 2000
@@ -18,6 +18,7 @@
#define IRQ_WAITING 32 /* IRQ not yet seen - for autodetection */
#define IRQ_LEVEL 64 /* IRQ level triggered */
#define IRQ_MASKED 128 /* IRQ masked - shouldn't be seen again */
+#define IRQ_PER_CPU 256 /* IRQ is per CPU */
/*
* Interrupt controller descriptor. This is all we need
diff -urN linux-davidm/kernel/module.c linux-2.3.99-pre5-lia/kernel/module.c
--- linux-davidm/kernel/module.c Fri Apr 21 18:50:35 2000
+++ linux-2.3.99-pre5-lia/kernel/module.c Thu Apr 20 10:28:24 2000
@@ -800,6 +800,7 @@
{
struct module_ref *dep;
unsigned i;
+
/* Let the module clean up. */
if (mod->flags & MOD_RUNNING)
@@ -1000,12 +1001,6 @@
#else /* CONFIG_MODULES */
/* Dummy syscalls for people who don't want modules */
-
-int
-try_inc_mod_count (struct module *mod)
-{
- return 1;
-}
asmlinkage unsigned long
sys_create_module(const char *name_user, size_t size)
diff -urN linux-davidm/kernel/printk.c linux-2.3.99-pre5-lia/kernel/printk.c
--- linux-davidm/kernel/printk.c Fri Apr 21 18:50:35 2000
+++ linux-2.3.99-pre5-lia/kernel/printk.c Fri Apr 21 18:29:29 2000
@@ -14,6 +14,8 @@
* manfreds@colorfullife.com
*/
+#include <linux/config.h>
+
#include <linux/mm.h>
#include <linux/tty_driver.h>
#include <linux/smp_lock.h>
@@ -504,7 +506,7 @@
#define VGABASE ((char *)0x00000000000b8000)
-static int current_ypos = 0, current_xpos = 0;
+static int current_ypos = 50, current_xpos = 0;
void
early_printk (const char *str)
@@ -515,13 +517,13 @@
while ((c = *str++) != '\0') {
if (current_ypos >= 50) {
/* scroll 1 line up */
- for(k = 1, j = 0; k < 50; k++, j++) {
- for(i = 0; i < 80; i++) {
+ for (k = 1, j = 0; k < 50; k++, j++) {
+ for (i = 0; i < 80; i++) {
writew(readw(VGABASE + 2*(80*k + i)),
VGABASE + 2*(80*j + i));
}
}
- for(i = 0; i < 80; i++) {
+ for (i = 0; i < 80; i++) {
writew(0x720, VGABASE + 2*(80*j + i));
}
current_ypos = 49;
next reply other threads:[~2000-04-25 3:31 UTC|newest]
Thread overview: 13+ messages / expand[flat|nested] mbox.gz Atom feed top
2000-04-25 3:31 David Mosberger [this message]
2000-04-25 9:29 ` [Linux-ia64] new kernel diff (relative to 2.3.99-pre5) Christoph Rohland
2000-04-25 9:50 ` Jes Sorensen
2000-04-25 10:23 ` Christoph Rohland
2000-04-26 1:32 ` Jesse Barnes
2000-04-26 2:18 ` Johannes Erdfelt
2000-04-26 5:29 ` Seth, Rohit
2000-04-26 21:18 ` Jesse Barnes
2000-05-02 4:22 ` David Mosberger
2000-05-02 6:59 ` [Linux-ia64] new kernel diff (relative to v2.3.99-pre6) David Mosberger
2000-05-02 19:17 ` Kevin Buettner
2000-05-02 20:48 ` David Mosberger
2000-05-02 21:52 ` David Mosberger
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=marc-linux-ia64-105590678205032@msgid-missing \
--to=davidm@hpl.hp.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