More late merge bug fixes for 2.6.23
cover More late merge bug fixes for 2.6.23
More late bug fixe for 2.6.23.
-Andi
PATCH 1/4 x86_64: Fail dma_alloc_coherent on dma less devices
This should fix an oops with PCMCIA PATA devices
http://bugzilla.kernel.org/show_bug.cgi?id=8424
This is not a full fix for the problem, but probably still the right thing to do.
--- arch/x86_64/kernel/pci-dma.c | 4 ++++ 1 file changed, 4 insertions(+)
arch/x86_64/kernel/pci-dma.c +4 -0
@@ -82,6 +82,10 @@ dma_alloc_coherent(struct device *dev, sif (dma_mask ==0 ) dma_mask =DMA_32BIT_MASK ; +/* Device not DMA able */ +if (dev->dma_mask ==NULL ) +return NULL ; +/* Don't invoke OOM killer */ gfp |= __GFP_NORETRY;
Re: [PATCH] [1/4] x86_64: Fail dma_alloc_coherent on dma less devices
Hmm. I think this is wrong.
Why? Because the regular 32-bit x86 code does this all completely differently, and doesn't use dma_mask at all. Instead, it _only_ uses dev->coherent_dma_mask (which, considering the name of the function, would seem to make sense).
Considering that the oops comes from this:
/* Kludge to make it bug-to-bug compatible with i386. i386
uses the normal dma_mask for alloc_coherent. */
dma_mask &= *dev->dma_mask;and that that code is *old*, and comes from when this file was called arch/x86_64/kernel/pci-gart.c, and the comment doesn't seem to even be correct any more, I really think the proper fix is likely to just *remove* that kludge that causes the oops entirely.
Anyway, I'll apply the patch, because clearly it's not going to make things *worse* (it does avoid the oops that we get now), but I don't think it's really even "probably still the right thing to do". I really think we should just remove the line that causes the oops instead, but that might change behaviour for non-oopsing cases, so I'm not ready to do that at this point.
Hmm? Who feels in charge of the DMA mapping stuff? Muli? James? Anybody?
Linus
Quoted 30 lines · Andi Kleen
This should fix an oops with PCMCIA PATA devices
http://bugzilla.kernel.org/show_bug.cgi?id=8424
This is not a full fix for the problem, but probably still the right thing to do.
Signed-off-by Andi Kleen <[email protected]>--- arch/x86_64/kernel/pci-dma.c | 4 ++++ 1 file changed, 4 insertions(+)Index:
linux/arch/x86_64/kernel/pci-dma.c
===================================================================arch/x86_64/kernel/pci-dma.c +4
-0@@ -82,6 +82,10 @@ dma_alloc_coherent(struct device *dev, sif (dma_mask ==0 ) dma_mask =DMA_32BIT_MASK ; +/* Device not DMA able */ +if (dev->dma_mask ==NULL ) +return NULL ; +/* Don't invoke OOM killer */ gfp |= __GFP_NORETRY;
Re: [PATCH] [1/4] x86_64: Fail dma_alloc_coherent on dma less devices
Quoted 7 lines · On Saturday 18 August 2007 19:22:18 Linus Torvalds wrote:
Hmm. I think this is wrong.
Why? Because the regular 32-bit x86 code does this all completely differently, and doesn't use
dma_maskat all. Instead, it _only_ usesdev->coherent_dma_mask(which, considering the name of the function, would seem to make sense).
Yes, see my discussion with Alan. Likely this needs to be handled in the caller to really fix the problem (pata_pcmcia oopsing when it passes a DMA incapable pcmcia device to dma_alloc_coherent)
Another possible fix proposed by James was to give the pcmcia devices a dma_mask of 0 which would also work.
Quoted 9 lines
Considering that the oops comes from this:
/* Kludge to make it bug-to-bug compatible with i386. i386 uses the normal dma_mask for alloc_coherent. */ dma_mask &= *dev->dma_mask;and that that code is *old*, and comes from when this file was called
arch/x86_64/kernel/pci-gart.c, and the comment doesn't seem to even be
It might be outdated or it might now. The kludge was needed for Alsa because old i386 ignored the consistent mask and they didn't always set it correctly, but that should be obsolete now? I'm not quite sure because sound devices
are not always well tested on large memory systems which are the only ones who show this problem. Takashi, do you know if all alsa drivers set consistent mask correctly now?
But I didn't want to touch that that late -- can do it for .24.
Still failing is probably correct in this case so I included the patch.
-Andi
Re: [PATCH] [1/4] x86_64: Fail dma_alloc_coherent on dma less devices
At Sat, 18 Aug 2007 21:03:25 +0200,
Quoted 11 lines · Andi Kleen
Quoted 10 lines
Considering that the oops comes from this:
/* Kludge to make it bug-to-bug compatible with i386. i386 uses the normal dma_mask for alloc_coherent. */ dma_mask &= *dev->dma_mask;and that that code is *old*, and comes from when this file was called
arch/x86_64/kernel/pci-gart.c, and the comment doesn't seem to even be
Quoted 6 lines
It might be outdated or it might now. The kludge was needed for Alsa because old i386 ignored the consistent mask and they didn't always set it correctly, but that should be obsolete now? I'm not quite sure because sound devices
are not always well tested on large memory systems which are the only ones who show this problem. Takashi, do you know if all alsa drivers set consistent mask correctly now?
Yes, ALSA driver set both masks from the very beginning :)
There are some OSS drivers still calling only pci_set_dma_mask(). Through a quick look, maybe only trident.c needs a fix because it uses a mask < 32bit for ALI devices. Others use 32bit DMA mask.
Takashi
PATCH 2/4 x86_64: Fix to keep watchdog disabled by default for i386/x86_64
In reply to Andi KleenFrom: Daniel Gollub <[email protected]>
Fixed wrong expression which enabled watchdogs even if nmi_watchdog kernel parameter wasn't set. This regression got slightly introduced with commit b7471c6da94d30d3deadc55986cc38d1ff57f9ca.
Introduced NMI_DISABLED (-1) which allows to switch the value of NMI_DEFAULT without breaking the APIC NMI watchdog code (again).
Fixes:
https://bugzilla.novell.com/show_bug.cgi?id=298084
http://bugzilla.kernel.org/show_bug.cgi?id=7839
And likely some more nmi_watchdog=0 related issues.
---
arch/i386/kernel/apic.c +1 -1
@@ -1085,7 +1085,7 @@ static int __init detect_init_APIC (voidif (l &MSR_IA32_APICBASE_ENABLE ) mp_lapic_addr = l &MSR_IA32_APICBASE_BASE ; -if (nmi_watchdog !=NMI_NONE ) +if (nmi_watchdog !=NMI_NONE && nmi_watchdog !=NMI_DISABLED ) nmi_watchdog =NMI_LOCAL_APIC ;printk (KERN_INFO "Found and enabled local APIC!\n" );
arch/i386/kernel/nmi.c +2 -2
@@ -77,7 +77,7 @@ static int __init check_nmi_watchdog(voiunsigned int *prev_nmi_count;int cpu; -if ((nmi_watchdog ==NMI_NONE ) || (nmi_watchdog ==NMI_DEFAULT )) +if ((nmi_watchdog ==NMI_NONE ) || (nmi_watchdog ==NMI_DISABLED ))return 0 ;if (!atomic_read (&nmi_active))
@@ -424,7 +424,7 @@ int proc_nmi_enabled(struct ctl_table *tif (!!old_state == !!nmi_watchdog_enabled)return 0 ; -if (atomic_read (&nmi_active) <0 ) { +if (atomic_read (&nmi_active) <0 || nmi_watchdog ==NMI_DISABLED ) {printk (KERN_WARNING "NMI watchdog is permanently disabled\n" );return -EIO ; }
arch/x86_64/kernel/nmi.c +2 -2
@@ -85,7 +85,7 @@ int __init check_nmi_watchdog (void)int *counts;int cpu; -if ((nmi_watchdog ==NMI_NONE ) || (nmi_watchdog ==NMI_DEFAULT )) +if ((nmi_watchdog ==NMI_NONE ) || (nmi_watchdog ==NMI_DISABLED ))return 0 ;if (!atomic_read (&nmi_active))
@@ -442,7 +442,7 @@ int proc_nmi_enabled(struct ctl_table *tif (!!old_state == !!nmi_watchdog_enabled)return 0 ; -if (atomic_read (&nmi_active) <0 ) { +if (atomic_read (&nmi_active) <0 || nmi_watchdog ==NMI_DISABLED ) {printk (KERN_WARNING "NMI watchdog is permanently disabled\n" );return -EIO ; }
include/asm-i386/nmi.h +2 -1
@@ -33,11 +33,12 @@ extern int nmi_watchdog_tick (struct pt_extern atomic_t nmi_active;extern unsigned int nmi_watchdog; -#define NMI_DEFAULT -1 +#define NMI_DISABLED -1#define NMI_NONE 0#define NMI_IO_APIC 1#define NMI_LOCAL_APIC 2#define NMI_INVALID 3 +#define NMI_DEFAULT NMI_DISABLEDstruct ctl_table ;struct file ;
include/asm-x86_64/nmi.h +2 -1
@@ -64,11 +64,12 @@ extern int setup_nmi_watchdog(char *);extern atomic_t nmi_active;extern unsigned int nmi_watchdog; -#define NMI_DEFAULT -1 +#define NMI_DISABLED -1#define NMI_NONE 0#define NMI_IO_APIC 1#define NMI_LOCAL_APIC 2#define NMI_INVALID 3 +#define NMI_DEFAULT NMI_DISABLEDstruct ctl_table ;struct file ;
PATCH 3/4 x86_64: Change PMDS invocation to single macro
In reply to Andi KleenVery old binutils (2.12.90...) seem to have trouble with newlines in assembler macro invocation. They put them into the resulting argument expansion. In this case this lead to a parse error because a .rept expression ended up spread over multiple lines. Change the PMDS() invocation to a single line.
arch/x86_64/kernel/head.S +1 -2
@@ -345,8 +345,7 @@ NEXT_PAGE(level2_kernel_pgt) /* 40MB kernel mapping. The kernel code cannot be bigger than that. When you change this change KERNEL_TEXT_SIZE in page.h too. */ /* (2^48-(2*1024*1024*1024)-((2^39)*511)-((2^30)*510)) = 0 */ - PMDS(0x0000000000000000, __PAGE_KERNEL_LARGE_EXEC|_PAGE_GLOBAL, - KERNEL_TEXT_SIZE/PMD_SIZE) + PMDS(0x0000000000000000, __PAGE_KERNEL_LARGE_EXEC|_PAGE_GLOBAL, KERNEL_TEXT_SIZE/PMD_SIZE) /* Module mapping starts here */ .fill (PTRS_PER_PMD - (KERNEL_TEXT_SIZE/PMD_SIZE)),8,0
Re: [PATCH] [3/4] x86_64: Change PMDS invocation to single macro
Quoted 12 lines · Andi Kleen
Very old binutils (2.12.90...) seem to have trouble with newlines
in assembler macro invocation. They put them into the resulting
argument expansion. In this case this lead to a parse error because
a .rept expression ended up spread over multiple lines. Change thePMDS()invocation to a single line.Signed-off-by Andi Kleen <[email protected]>Index:
linux/arch/x86_64/kernel/head.S
===================================================================
arch/x86_64/kernel/head.S NEXT_PAGE(level2_kernel_pgt) · line 348
Quoted 6 lines
arch/x86_64/kernel/head.S +1
-2@@ -345,8 +345,7 @@ NEXT_PAGE(level2_kernel_pgt) /* 40MB kernel mapping. The kernel code cannot be bigger than that. When you change this change KERNEL_TEXT_SIZE in page.h too. */ /* (2^48-(2*1024*1024*1024)-((2^39)*511)-((2^30)*510)) = 0 */ - PMDS(0x0000000000000000, __PAGE_KERNEL_LARGE_EXEC|_PAGE_GLOBAL, - KERNEL_TEXT_SIZE/PMD_SIZE) + PMDS(0x0000000000000000, __PAGE_KERNEL_LARGE_EXEC|_PAGE_GLOBAL, KERNEL_TEXT_SIZE/PMD_SIZE)
Can you please add a comment, that this line must stay in a single line for the above reason? I would expect that the next who does some code clean up will break it again.
arch/x86_64/kernel/head.S NEXT_PAGE(level2_kernel_pgt) · line 350
Quoted 2 lines
arch/x86_64/kernel/head.S +0
-0/* Module mapping starts here */ .fill (PTRS_PER_PMD - (KERNEL_TEXT_SIZE/PMD_SIZE)),8,0
Regards,
Signature · 11 lines
Clemens Koller _______________________________ R&D Imaging Devices Anagramm GmbH Rupert-Mayer-Str. 45/1 81379 Muenchen Germany http://www.anagramm-technology.com Phone: +49-89-741518-50 Fax: +49-89-741518-19
Re: [PATCH] [3/4] x86_64: Change PMDS invocation to single macro
Quoted 3 lines
Can you please add a comment, that this line must stay in a single line for the above reason? I would expect that the next who does some code clean up will break it again.
Then we would need to add it to all macros essentially. That wouldn't be economical.
-Andi
PATCH 4/4 x86_64: Check for .cfi_rel_offset in CFI probe
In reply to Andi KleenVery old 64bit binutils have .cfi_startproc/endproc, but no .cfi_rel_offset. Check for .cfi_rel_offset too.
arch/x86_64/Makefile +2 -2
@@ -57,8 +57,8 @@ cflags-y += $(call cc-option,-mno-sse -m cflags-y += -maccumulate-outgoing-args # do binutils support CFI? -cflags-y += $(call as-instr,.cfi_startproc\n.cfi_endproc,-DCONFIG_AS_CFI=1,) -AFLAGS += $(call as-instr,.cfi_startproc\n.cfi_endproc,-DCONFIG_AS_CFI=1,) +cflags-y += $(call as-instr,.cfi_startproc\n.cfi_rel_offset rsp${comma}0\n.cfi_endproc,-DCONFIG_AS_CFI=1,) +AFLAGS += $(call as-instr,.cfi_startproc\n.cfi_rel_offset rsp${comma}0\n.cfi_endproc,-DCONFIG_AS_CFI=1,) # is .cfi_signal_frame supported too? cflags-y += $(call as-instr,.cfi_startproc\n.cfi_signal_frame\n.cfi_endproc,-DCONFIG_AS_CFI_SIGNAL_FRAME=1,)
arch/i386/Makefile +2 -2
@@ -51,8 +51,8 @@ cflags-y += -maccumulate-outgoing-args CFLAGS += $(shell if [ $(call cc-version) -lt 0400 ] ; then echo $(call cc-option,-fno-unit-at-a-time); fi ;) # do binutils support CFI? -cflags-y += $(call as-instr,.cfi_startproc\n.cfi_endproc,-DCONFIG_AS_CFI=1,) -AFLAGS += $(call as-instr,.cfi_startproc\n.cfi_endproc,-DCONFIG_AS_CFI=1,) +cflags-y += $(call as-instr,.cfi_startproc\n.cfi_rel_offset esp${comma}0\n.cfi_endproc,-DCONFIG_AS_CFI=1,) +AFLAGS += $(call as-instr,.cfi_startproc\n.cfi_rel_offset esp${comma}0\n.cfi_endproc,-DCONFIG_AS_CFI=1,) # is .cfi_signal_frame supported too? cflags-y += $(call as-instr,.cfi_startproc\n.cfi_signal_frame\n.cfi_endproc,-DCONFIG_AS_CFI_SIGNAL_FRAME=1,)