diff --git a/[refs] b/[refs] index 07d3340c63e7..8a3b89849ab4 100644 --- a/[refs] +++ b/[refs] @@ -1,2 +1,2 @@ --- -refs/heads/master: 6f48ea58dd039aa8627d378284031a8df8826dc9 +refs/heads/master: a7e2ca17039edb5f782be519eaf9d8ea500ba7cc diff --git a/trunk/Documentation/filesystems/f2fs.txt b/trunk/Documentation/filesystems/f2fs.txt index dcf338e62b71..8fbd8b46ee34 100644 --- a/trunk/Documentation/filesystems/f2fs.txt +++ b/trunk/Documentation/filesystems/f2fs.txt @@ -175,9 +175,9 @@ consists of multiple segments as described below. align with the zone size <-| |-> align with the segment size _________________________________________________________________________ - | | | Segment | Node | Segment | | - | Superblock | Checkpoint | Info. | Address | Summary | Main | - | (SB) | (CP) | Table (SIT) | Table (NAT) | Area (SSA) | | + | | | Node | Segment | Segment | | + | Superblock | Checkpoint | Address | Info. | Summary | Main | + | (SB) | (CP) | Table (NAT) | Table (SIT) | Area (SSA) | | |____________|_____2______|______N______|______N______|______N_____|__N___| . . . . @@ -200,14 +200,14 @@ consists of multiple segments as described below. : It contains file system information, bitmaps for valid NAT/SIT sets, orphan inode lists, and summary entries of current active segments. -- Segment Information Table (SIT) - : It contains segment information such as valid block count and bitmap for the - validity of all the blocks. - - Node Address Table (NAT) : It is composed of a block address table for all the node blocks stored in Main area. +- Segment Information Table (SIT) + : It contains segment information such as valid block count and bitmap for the + validity of all the blocks. + - Segment Summary Area (SSA) : It contains summary entries which contains the owner information of all the data and node blocks stored in Main area. @@ -236,13 +236,13 @@ For file system consistency, each CP points to which NAT and SIT copies are valid, as shown as below. +--------+----------+---------+ - | CP | SIT | NAT | + | CP | NAT | SIT | +--------+----------+---------+ . . . . . . . . . . . . +-------+-------+--------+--------+--------+--------+ - | CP #0 | CP #1 | SIT #0 | SIT #1 | NAT #0 | NAT #1 | + | CP #0 | CP #1 | NAT #0 | NAT #1 | SIT #0 | SIT #1 | +-------+-------+--------+--------+--------+--------+ | ^ ^ | | | diff --git a/trunk/MAINTAINERS b/trunk/MAINTAINERS index 8ae709e34523..3105c4868c4e 100644 --- a/trunk/MAINTAINERS +++ b/trunk/MAINTAINERS @@ -6585,7 +6585,7 @@ F: drivers/media/platform/s3c-camif/ F: include/media/s3c_camif.h SERIAL DRIVERS -M: Greg Kroah-Hartman +M: Alan Cox L: linux-serial@vger.kernel.org S: Maintained F: drivers/tty/serial diff --git a/trunk/Makefile b/trunk/Makefile index 2cd4c6be44f2..253a455d8d8d 100644 --- a/trunk/Makefile +++ b/trunk/Makefile @@ -169,7 +169,7 @@ SUBARCH := $(shell uname -m | sed -e s/i.86/i386/ -e s/sun4u/sparc64/ \ -e s/arm.*/arm/ -e s/sa110/arm/ \ -e s/s390x/s390/ -e s/parisc64/parisc/ \ -e s/ppc.*/powerpc/ -e s/mips.*/mips/ \ - -e s/sh[234].*/sh/ -e s/aarch64.*/arm64/ ) + -e s/sh[234].*/sh/ ) # Cross compiling and selecting different set of gcc/bin-utils # --------------------------------------------------------------------------- diff --git a/trunk/arch/arm64/include/asm/elf.h b/trunk/arch/arm64/include/asm/elf.h index fe32c0e4ac01..07fea290d7c1 100644 --- a/trunk/arch/arm64/include/asm/elf.h +++ b/trunk/arch/arm64/include/asm/elf.h @@ -26,10 +26,7 @@ typedef unsigned long elf_greg_t; -#define ELF_NGREG (sizeof(struct user_pt_regs) / sizeof(elf_greg_t)) -#define ELF_CORE_COPY_REGS(dest, regs) \ - *(struct user_pt_regs *)&(dest) = (regs)->user_regs; - +#define ELF_NGREG (sizeof (struct pt_regs) / sizeof(elf_greg_t)) typedef elf_greg_t elf_gregset_t[ELF_NGREG]; typedef struct user_fpsimd_state elf_fpregset_t; diff --git a/trunk/arch/m68k/include/asm/dma-mapping.h b/trunk/arch/m68k/include/asm/dma-mapping.h index 3e6b8445af6a..17f7a45948ea 100644 --- a/trunk/arch/m68k/include/asm/dma-mapping.h +++ b/trunk/arch/m68k/include/asm/dma-mapping.h @@ -21,22 +21,6 @@ extern void *dma_alloc_coherent(struct device *, size_t, extern void dma_free_coherent(struct device *, size_t, void *, dma_addr_t); -static inline void *dma_alloc_attrs(struct device *dev, size_t size, - dma_addr_t *dma_handle, gfp_t flag, - struct dma_attrs *attrs) -{ - /* attrs is not supported and ignored */ - return dma_alloc_coherent(dev, size, dma_handle, flag); -} - -static inline void dma_free_attrs(struct device *dev, size_t size, - void *cpu_addr, dma_addr_t dma_handle, - struct dma_attrs *attrs) -{ - /* attrs is not supported and ignored */ - dma_free_coherent(dev, size, cpu_addr, dma_handle); -} - static inline void *dma_alloc_noncoherent(struct device *dev, size_t size, dma_addr_t *handle, gfp_t flag) { diff --git a/trunk/arch/m68k/include/asm/unistd.h b/trunk/arch/m68k/include/asm/unistd.h index f9337f614660..847994ce6804 100644 --- a/trunk/arch/m68k/include/asm/unistd.h +++ b/trunk/arch/m68k/include/asm/unistd.h @@ -4,7 +4,7 @@ #include -#define NR_syscalls 349 +#define NR_syscalls 348 #define __ARCH_WANT_OLD_READDIR #define __ARCH_WANT_OLD_STAT diff --git a/trunk/arch/m68k/include/uapi/asm/unistd.h b/trunk/arch/m68k/include/uapi/asm/unistd.h index 625f321001dc..b94bfbf90705 100644 --- a/trunk/arch/m68k/include/uapi/asm/unistd.h +++ b/trunk/arch/m68k/include/uapi/asm/unistd.h @@ -353,6 +353,5 @@ #define __NR_process_vm_readv 345 #define __NR_process_vm_writev 346 #define __NR_kcmp 347 -#define __NR_finit_module 348 #endif /* _UAPI_ASM_M68K_UNISTD_H_ */ diff --git a/trunk/arch/m68k/kernel/syscalltable.S b/trunk/arch/m68k/kernel/syscalltable.S index 3f04ea0ab802..c30da5b3f2db 100644 --- a/trunk/arch/m68k/kernel/syscalltable.S +++ b/trunk/arch/m68k/kernel/syscalltable.S @@ -368,5 +368,4 @@ ENTRY(sys_call_table) .long sys_process_vm_readv /* 345 */ .long sys_process_vm_writev .long sys_kcmp - .long sys_finit_module diff --git a/trunk/arch/parisc/kernel/entry.S b/trunk/arch/parisc/kernel/entry.S index eb7850b46c25..bfb44247d7a7 100644 --- a/trunk/arch/parisc/kernel/entry.S +++ b/trunk/arch/parisc/kernel/entry.S @@ -1865,7 +1865,7 @@ syscall_restore: /* Are we being ptraced? */ ldw TASK_FLAGS(%r1),%r19 - ldi _TIF_SYSCALL_TRACE_MASK,%r2 + ldi (_TIF_SINGLESTEP|_TIF_BLOCKSTEP),%r2 and,COND(=) %r19,%r2,%r0 b,n syscall_restore_rfi @@ -1978,23 +1978,15 @@ syscall_restore_rfi: /* sr2 should be set to zero for userspace syscalls */ STREG %r0,TASK_PT_SR2(%r1) +pt_regs_ok: LDREG TASK_PT_GR31(%r1),%r2 - depi 3,31,2,%r2 /* ensure return to user mode. */ - STREG %r2,TASK_PT_IAOQ0(%r1) + depi 3,31,2,%r2 /* ensure return to user mode. */ + STREG %r2,TASK_PT_IAOQ0(%r1) ldo 4(%r2),%r2 STREG %r2,TASK_PT_IAOQ1(%r1) - b intr_restore copy %r25,%r16 - -pt_regs_ok: - LDREG TASK_PT_IAOQ0(%r1),%r2 - depi 3,31,2,%r2 /* ensure return to user mode. */ - STREG %r2,TASK_PT_IAOQ0(%r1) - LDREG TASK_PT_IAOQ1(%r1),%r2 - depi 3,31,2,%r2 - STREG %r2,TASK_PT_IAOQ1(%r1) b intr_restore - copy %r25,%r16 + nop .import schedule,code syscall_do_resched: diff --git a/trunk/arch/parisc/kernel/irq.c b/trunk/arch/parisc/kernel/irq.c index 0299d63cd112..c0b1affc06a8 100644 --- a/trunk/arch/parisc/kernel/irq.c +++ b/trunk/arch/parisc/kernel/irq.c @@ -410,13 +410,11 @@ void __init init_IRQ(void) { local_irq_disable(); /* PARANOID - should already be disabled */ mtctl(~0UL, 23); /* EIRR : clear all pending external intr */ + claim_cpu_irqs(); #ifdef CONFIG_SMP - if (!cpu_eiem) { - claim_cpu_irqs(); + if (!cpu_eiem) cpu_eiem = EIEM_MASK(IPI_IRQ) | EIEM_MASK(TIMER_IRQ); - } #else - claim_cpu_irqs(); cpu_eiem = EIEM_MASK(TIMER_IRQ); #endif set_eiem(cpu_eiem); /* EIEM : enable all external intr */ diff --git a/trunk/arch/parisc/kernel/ptrace.c b/trunk/arch/parisc/kernel/ptrace.c index 534abd4936e1..857c2f545470 100644 --- a/trunk/arch/parisc/kernel/ptrace.c +++ b/trunk/arch/parisc/kernel/ptrace.c @@ -26,7 +26,7 @@ #include /* PSW bits we allow the debugger to modify */ -#define USER_PSW_BITS (PSW_N | PSW_B | PSW_V | PSW_CB) +#define USER_PSW_BITS (PSW_N | PSW_V | PSW_CB) /* * Called by kernel/ptrace.c when detaching.. diff --git a/trunk/arch/parisc/kernel/signal.c b/trunk/arch/parisc/kernel/signal.c index fd051705a407..537996955998 100644 --- a/trunk/arch/parisc/kernel/signal.c +++ b/trunk/arch/parisc/kernel/signal.c @@ -190,10 +190,8 @@ get_sigframe(struct k_sigaction *ka, unsigned long sp, size_t frame_size) DBG(1,"get_sigframe: ka = %#lx, sp = %#lx, frame_size = %#lx\n", (unsigned long)ka, sp, frame_size); - /* Align alternate stack and reserve 64 bytes for the signal - handler's frame marker. */ if ((ka->sa.sa_flags & SA_ONSTACK) != 0 && ! sas_ss_flags(sp)) - sp = (current->sas_ss_sp + 0x7f) & ~0x3f; /* Stacks grow up! */ + sp = current->sas_ss_sp; /* Stacks grow up! */ DBG(1,"get_sigframe: Returning sp = %#lx\n", (unsigned long)sp); return (void __user *) sp; /* Stacks grow up. Fun. */ diff --git a/trunk/arch/parisc/math-emu/cnv_float.h b/trunk/arch/parisc/math-emu/cnv_float.h index 933423fa5144..9071e093164a 100644 --- a/trunk/arch/parisc/math-emu/cnv_float.h +++ b/trunk/arch/parisc/math-emu/cnv_float.h @@ -347,15 +347,16 @@ Sgl_isinexact_to_fix(sgl_value,exponent) #define Duint_from_sgl_mantissa(sgl_value,exponent,dresultA,dresultB) \ - {unsigned int val = Sall(sgl_value) << SGL_EXP_LENGTH; \ + {Sall(sgl_value) <<= SGL_EXP_LENGTH; /* left-justify */ \ if (exponent <= 31) { \ - Dintp1(dresultA) = 0; \ - Dintp2(dresultB) = val >> (31 - exponent); \ + Dintp1(dresultA) = 0; \ + Dintp2(dresultB) = (unsigned)Sall(sgl_value) >> (31 - exponent); \ } \ else { \ - Dintp1(dresultA) = val >> (63 - exponent); \ - Dintp2(dresultB) = exponent <= 62 ? val << (exponent - 31) : 0; \ + Dintp1(dresultA) = Sall(sgl_value) >> (63 - exponent); \ + Dintp2(dresultB) = Sall(sgl_value) << (exponent - 31); \ } \ + Sall(sgl_value) >>= SGL_EXP_LENGTH; /* return to original */ \ } #define Duint_setzero(dresultA,dresultB) \ diff --git a/trunk/arch/x86/kernel/cpu/perf_event.c b/trunk/arch/x86/kernel/cpu/perf_event.c index 6774c17a5576..4428fd178bce 100644 --- a/trunk/arch/x86/kernel/cpu/perf_event.c +++ b/trunk/arch/x86/kernel/cpu/perf_event.c @@ -340,6 +340,9 @@ int x86_setup_perfctr(struct perf_event *event) /* BTS is currently only allowed for user-mode. */ if (!attr->exclude_kernel) return -EOPNOTSUPP; + + if (!attr->exclude_guest) + return -EOPNOTSUPP; } hwc->config |= config; @@ -382,6 +385,9 @@ int x86_pmu_hw_config(struct perf_event *event) if (event->attr.precise_ip) { int precise = 0; + if (!event->attr.exclude_guest) + return -EOPNOTSUPP; + /* Support for constant skid */ if (x86_pmu.pebs_active && !x86_pmu.pebs_broken) { precise++; diff --git a/trunk/arch/x86/kernel/step.c b/trunk/arch/x86/kernel/step.c index 9b4d51d0c0d0..cd3b2438a980 100644 --- a/trunk/arch/x86/kernel/step.c +++ b/trunk/arch/x86/kernel/step.c @@ -165,11 +165,10 @@ void set_task_blockstep(struct task_struct *task, bool on) * Ensure irq/preemption can't change debugctl in between. * Note also that both TIF_BLOCKSTEP and debugctl should * be changed atomically wrt preemption. - * - * NOTE: this means that set/clear TIF_BLOCKSTEP is only safe if - * task is current or it can't be running, otherwise we can race - * with __switch_to_xtra(). We rely on ptrace_freeze_traced() but - * PTRACE_KILL is not safe. + * FIXME: this means that set/clear TIF_BLOCKSTEP is simply + * wrong if task != current, SIGKILL can wakeup the stopped + * tracee and set/clear can play with the running task, this + * can confuse the next __switch_to_xtra(). */ local_irq_disable(); debugctl = get_debugctlmsr(); diff --git a/trunk/drivers/ata/ahci.c b/trunk/drivers/ata/ahci.c index 497912732566..7862d17976b7 100644 --- a/trunk/drivers/ata/ahci.c +++ b/trunk/drivers/ata/ahci.c @@ -53,7 +53,6 @@ enum { AHCI_PCI_BAR_STA2X11 = 0, - AHCI_PCI_BAR_ENMOTUS = 2, AHCI_PCI_BAR_STANDARD = 5, }; @@ -411,9 +410,6 @@ static const struct pci_device_id ahci_pci_tbl[] = { { PCI_VDEVICE(ASMEDIA, 0x0611), board_ahci }, /* ASM1061 */ { PCI_VDEVICE(ASMEDIA, 0x0612), board_ahci }, /* ASM1062 */ - /* Enmotus */ - { PCI_DEVICE(0x1c44, 0x8000), board_ahci }, - /* Generic, PCI class code for AHCI */ { PCI_ANY_ID, PCI_ANY_ID, PCI_ANY_ID, PCI_ANY_ID, PCI_CLASS_STORAGE_SATA_AHCI, 0xffffff, board_ahci }, @@ -1102,11 +1098,9 @@ static int ahci_init_one(struct pci_dev *pdev, const struct pci_device_id *ent) dev_info(&pdev->dev, "PDC42819 can only drive SATA devices with this driver\n"); - /* Both Connext and Enmotus devices use non-standard BARs */ + /* The Connext uses non-standard BAR */ if (pdev->vendor == PCI_VENDOR_ID_STMICRO && pdev->device == 0xCC06) ahci_pci_bar = AHCI_PCI_BAR_STA2X11; - else if (pdev->vendor == 0x1c44 && pdev->device == 0x8000) - ahci_pci_bar = AHCI_PCI_BAR_ENMOTUS; /* acquire resources */ rc = pcim_enable_device(pdev); diff --git a/trunk/drivers/ata/libahci.c b/trunk/drivers/ata/libahci.c index 6cd7805e47ca..320712a7b9ea 100644 --- a/trunk/drivers/ata/libahci.c +++ b/trunk/drivers/ata/libahci.c @@ -1951,13 +1951,13 @@ static void ahci_set_aggressive_devslp(struct ata_port *ap, bool sleep) /* Use the nominal value 10 ms if the read MDAT is zero, * the nominal value of DETO is 20 ms. */ - if (dev->devslp_timing[ATA_LOG_DEVSLP_VALID] & + if (dev->sata_settings[ATA_LOG_DEVSLP_VALID] & ATA_LOG_DEVSLP_VALID_MASK) { - mdat = dev->devslp_timing[ATA_LOG_DEVSLP_MDAT] & + mdat = dev->sata_settings[ATA_LOG_DEVSLP_MDAT] & ATA_LOG_DEVSLP_MDAT_MASK; if (!mdat) mdat = 10; - deto = dev->devslp_timing[ATA_LOG_DEVSLP_DETO]; + deto = dev->sata_settings[ATA_LOG_DEVSLP_DETO]; if (!deto) deto = 20; } else { diff --git a/trunk/drivers/ata/libata-core.c b/trunk/drivers/ata/libata-core.c index 46cd3f4c6aaa..9e8b99af400d 100644 --- a/trunk/drivers/ata/libata-core.c +++ b/trunk/drivers/ata/libata-core.c @@ -2325,28 +2325,24 @@ int ata_dev_configure(struct ata_device *dev) } } - /* Check and mark DevSlp capability. Get DevSlp timing variables - * from SATA Settings page of Identify Device Data Log. - */ - if (ata_id_has_devslp(dev->id)) { - u8 sata_setting[ATA_SECT_SIZE]; - int i, j; - + /* check and mark DevSlp capability */ + if (ata_id_has_devslp(dev->id)) dev->flags |= ATA_DFLAG_DEVSLP; + + /* Obtain SATA Settings page from Identify Device Data Log, + * which contains DevSlp timing variables etc. + * Exclude old devices with ata_id_has_ncq() + */ + if (ata_id_has_ncq(dev->id)) { err_mask = ata_read_log_page(dev, ATA_LOG_SATA_ID_DEV_DATA, ATA_LOG_SATA_SETTINGS, - sata_setting, + dev->sata_settings, 1); if (err_mask) ata_dev_dbg(dev, "failed to get Identify Device Data, Emask 0x%x\n", err_mask); - else - for (i = 0; i < ATA_LOG_DEVSLP_SIZE; i++) { - j = ATA_LOG_DEVSLP_OFFSET + i; - dev->devslp_timing[i] = sata_setting[j]; - } } dev->cdb_len = 16; diff --git a/trunk/drivers/ata/libata-eh.c b/trunk/drivers/ata/libata-eh.c index bcf4437214f5..bf039b0e97b7 100644 --- a/trunk/drivers/ata/libata-eh.c +++ b/trunk/drivers/ata/libata-eh.c @@ -2094,7 +2094,7 @@ static unsigned int ata_eh_speed_down(struct ata_device *dev, */ static inline int ata_eh_worth_retry(struct ata_queued_cmd *qc) { - if (qc->err_mask & AC_ERR_MEDIA) + if (qc->flags & AC_ERR_MEDIA) return 0; /* don't retry media errors */ if (qc->flags & ATA_QCFLAG_IO) return 1; /* otherwise retry anything from fs stack */ diff --git a/trunk/drivers/gpio/gpio-mvebu.c b/trunk/drivers/gpio/gpio-mvebu.c index 6819d63cb167..7d9bd94be8d2 100644 --- a/trunk/drivers/gpio/gpio-mvebu.c +++ b/trunk/drivers/gpio/gpio-mvebu.c @@ -547,6 +547,7 @@ static int mvebu_gpio_probe(struct platform_device *pdev) mvchip->membase = devm_request_and_ioremap(&pdev->dev, res); if (! mvchip->membase) { dev_err(&pdev->dev, "Cannot ioremap\n"); + kfree(mvchip->chip.label); return -ENOMEM; } @@ -556,12 +557,14 @@ static int mvebu_gpio_probe(struct platform_device *pdev) res = platform_get_resource(pdev, IORESOURCE_MEM, 1); if (! res) { dev_err(&pdev->dev, "Cannot get memory resource\n"); + kfree(mvchip->chip.label); return -ENODEV; } mvchip->percpu_membase = devm_request_and_ioremap(&pdev->dev, res); if (! mvchip->percpu_membase) { dev_err(&pdev->dev, "Cannot ioremap\n"); + kfree(mvchip->chip.label); return -ENOMEM; } } @@ -622,6 +625,7 @@ static int mvebu_gpio_probe(struct platform_device *pdev) mvchip->irqbase = irq_alloc_descs(-1, 0, ngpios, -1); if (mvchip->irqbase < 0) { dev_err(&pdev->dev, "no irqs\n"); + kfree(mvchip->chip.label); return -ENOMEM; } @@ -629,6 +633,7 @@ static int mvebu_gpio_probe(struct platform_device *pdev) mvchip->membase, handle_level_irq); if (! gc) { dev_err(&pdev->dev, "Cannot allocate generic irq_chip\n"); + kfree(mvchip->chip.label); return -ENOMEM; } @@ -663,6 +668,7 @@ static int mvebu_gpio_probe(struct platform_device *pdev) irq_remove_generic_chip(gc, IRQ_MSK(ngpios), IRQ_NOREQUEST, IRQ_LEVEL | IRQ_NOPROBE); kfree(gc); + kfree(mvchip->chip.label); return -ENODEV; } diff --git a/trunk/drivers/gpio/gpio-samsung.c b/trunk/drivers/gpio/gpio-samsung.c index 76be7eed79de..01f7fe955590 100644 --- a/trunk/drivers/gpio/gpio-samsung.c +++ b/trunk/drivers/gpio/gpio-samsung.c @@ -32,6 +32,7 @@ #include #include +#include #include #include @@ -445,7 +446,7 @@ static struct samsung_gpio_cfg s3c24xx_gpiocfg_banka = { }; #endif -#if defined(CONFIG_ARCH_EXYNOS4) || defined(CONFIG_SOC_EXYNOS5250) +#if defined(CONFIG_ARCH_EXYNOS4) || defined(CONFIG_ARCH_EXYNOS5) static struct samsung_gpio_cfg exynos_gpio_cfg = { .set_pull = exynos_gpio_setpull, .get_pull = exynos_gpio_getpull, @@ -2445,7 +2446,7 @@ static struct samsung_gpio_chip exynos4_gpios_3[] = { }; #endif -#ifdef CONFIG_SOC_EXYNOS5250 +#ifdef CONFIG_ARCH_EXYNOS5 static struct samsung_gpio_chip exynos5_gpios_1[] = { { .chip = { @@ -2613,7 +2614,7 @@ static struct samsung_gpio_chip exynos5_gpios_1[] = { }; #endif -#ifdef CONFIG_SOC_EXYNOS5250 +#ifdef CONFIG_ARCH_EXYNOS5 static struct samsung_gpio_chip exynos5_gpios_2[] = { { .chip = { @@ -2674,7 +2675,7 @@ static struct samsung_gpio_chip exynos5_gpios_2[] = { }; #endif -#ifdef CONFIG_SOC_EXYNOS5250 +#ifdef CONFIG_ARCH_EXYNOS5 static struct samsung_gpio_chip exynos5_gpios_3[] = { { .chip = { @@ -2710,7 +2711,7 @@ static struct samsung_gpio_chip exynos5_gpios_3[] = { }; #endif -#ifdef CONFIG_SOC_EXYNOS5250 +#ifdef CONFIG_ARCH_EXYNOS5 static struct samsung_gpio_chip exynos5_gpios_4[] = { { .chip = { @@ -3009,7 +3010,7 @@ static __init int samsung_gpiolib_init(void) int i, nr_chips; int group = 0; -#if defined(CONFIG_PINCTRL_EXYNOS) || defined(CONFIG_PINCTRL_EXYNOS5440) +#ifdef CONFIG_PINCTRL_SAMSUNG /* * This gpio driver includes support for device tree support and there * are platforms using it. In order to maintain compatibility with those @@ -3025,7 +3026,6 @@ static __init int samsung_gpiolib_init(void) static const struct of_device_id exynos_pinctrl_ids[] = { { .compatible = "samsung,pinctrl-exynos4210", }, { .compatible = "samsung,pinctrl-exynos4x12", }, - { .compatible = "samsung,pinctrl-exynos5440", }, }; for_each_matching_node(pctrl_np, exynos_pinctrl_ids) if (pctrl_np && of_device_is_available(pctrl_np)) diff --git a/trunk/drivers/media/i2c/m5mols/m5mols_core.c b/trunk/drivers/media/i2c/m5mols/m5mols_core.c index d4e7567b367c..8a8d42fe2633 100644 --- a/trunk/drivers/media/i2c/m5mols/m5mols_core.c +++ b/trunk/drivers/media/i2c/m5mols/m5mols_core.c @@ -556,7 +556,7 @@ static int m5mols_get_fmt(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh, mutex_lock(&info->lock); format = __find_format(info, fh, fmt->which, info->res_type); - if (format) + if (!format) fmt->format = *format; else ret = -EINVAL; diff --git a/trunk/drivers/media/platform/omap3isp/ispvideo.c b/trunk/drivers/media/platform/omap3isp/ispvideo.c index 8dac17511e61..e0d73a642186 100644 --- a/trunk/drivers/media/platform/omap3isp/ispvideo.c +++ b/trunk/drivers/media/platform/omap3isp/ispvideo.c @@ -35,6 +35,9 @@ #include #include #include +#include +#include +#include #include "ispvideo.h" #include "isp.h" diff --git a/trunk/drivers/media/platform/s5p-fimc/fimc-mdevice.c b/trunk/drivers/media/platform/s5p-fimc/fimc-mdevice.c index b4a68ecf0ca7..4ab99f3a7b09 100644 --- a/trunk/drivers/media/platform/s5p-fimc/fimc-mdevice.c +++ b/trunk/drivers/media/platform/s5p-fimc/fimc-mdevice.c @@ -593,7 +593,7 @@ static int __fimc_md_create_flite_source_links(struct fimc_md *fmd) { struct media_entity *source, *sink; unsigned int flags = MEDIA_LNK_FL_ENABLED; - int i, ret = 0; + int i, ret; for (i = 0; i < FIMC_LITE_MAX_DEVS; i++) { struct fimc_lite *fimc = fmd->fimc_lite[i]; diff --git a/trunk/drivers/media/platform/s5p-mfc/s5p_mfc.c b/trunk/drivers/media/platform/s5p-mfc/s5p_mfc.c index 681bc6ba149d..379f57433711 100644 --- a/trunk/drivers/media/platform/s5p-mfc/s5p_mfc.c +++ b/trunk/drivers/media/platform/s5p-mfc/s5p_mfc.c @@ -412,48 +412,62 @@ static void s5p_mfc_handle_frame(struct s5p_mfc_ctx *ctx, } /* Error handling for interrupt */ -static void s5p_mfc_handle_error(struct s5p_mfc_dev *dev, - struct s5p_mfc_ctx *ctx, unsigned int reason, unsigned int err) +static void s5p_mfc_handle_error(struct s5p_mfc_ctx *ctx, + unsigned int reason, unsigned int err) { + struct s5p_mfc_dev *dev; unsigned long flags; - mfc_err("Interrupt Error: %08x\n", err); + /* If no context is available then all necessary + * processing has been done. */ + if (ctx == NULL) + return; - if (ctx != NULL) { - /* Error recovery is dependent on the state of context */ - switch (ctx->state) { - case MFCINST_RES_CHANGE_INIT: - case MFCINST_RES_CHANGE_FLUSH: - case MFCINST_RES_CHANGE_END: - case MFCINST_FINISHING: - case MFCINST_FINISHED: - case MFCINST_RUNNING: - /* It is higly probable that an error occured - * while decoding a frame */ - clear_work_bit(ctx); - ctx->state = MFCINST_ERROR; - /* Mark all dst buffers as having an error */ - spin_lock_irqsave(&dev->irqlock, flags); - s5p_mfc_hw_call(dev->mfc_ops, cleanup_queue, - &ctx->dst_queue, &ctx->vq_dst); - /* Mark all src buffers as having an error */ - s5p_mfc_hw_call(dev->mfc_ops, cleanup_queue, - &ctx->src_queue, &ctx->vq_src); - spin_unlock_irqrestore(&dev->irqlock, flags); - wake_up_ctx(ctx, reason, err); - break; - default: - clear_work_bit(ctx); - ctx->state = MFCINST_ERROR; - wake_up_ctx(ctx, reason, err); - break; - } - } - if (test_and_clear_bit(0, &dev->hw_lock) == 0) - BUG(); + dev = ctx->dev; + mfc_err("Interrupt Error: %08x\n", err); s5p_mfc_hw_call(dev->mfc_ops, clear_int_flags, dev); - s5p_mfc_clock_off(); wake_up_dev(dev, reason, err); + + /* Error recovery is dependent on the state of context */ + switch (ctx->state) { + case MFCINST_INIT: + /* This error had to happen while acquireing instance */ + case MFCINST_GOT_INST: + /* This error had to happen while parsing the header */ + case MFCINST_HEAD_PARSED: + /* This error had to happen while setting dst buffers */ + case MFCINST_RETURN_INST: + /* This error had to happen while releasing instance */ + clear_work_bit(ctx); + wake_up_ctx(ctx, reason, err); + if (test_and_clear_bit(0, &dev->hw_lock) == 0) + BUG(); + s5p_mfc_clock_off(); + ctx->state = MFCINST_ERROR; + break; + case MFCINST_FINISHING: + case MFCINST_FINISHED: + case MFCINST_RUNNING: + /* It is higly probable that an error occured + * while decoding a frame */ + clear_work_bit(ctx); + ctx->state = MFCINST_ERROR; + /* Mark all dst buffers as having an error */ + spin_lock_irqsave(&dev->irqlock, flags); + s5p_mfc_hw_call(dev->mfc_ops, cleanup_queue, &ctx->dst_queue, + &ctx->vq_dst); + /* Mark all src buffers as having an error */ + s5p_mfc_hw_call(dev->mfc_ops, cleanup_queue, &ctx->src_queue, + &ctx->vq_src); + spin_unlock_irqrestore(&dev->irqlock, flags); + if (test_and_clear_bit(0, &dev->hw_lock) == 0) + BUG(); + s5p_mfc_clock_off(); + break; + default: + mfc_err("Encountered an error interrupt which had not been handled\n"); + break; + } return; } @@ -618,7 +632,7 @@ static irqreturn_t s5p_mfc_irq(int irq, void *priv) dev->warn_start) s5p_mfc_handle_frame(ctx, reason, err); else - s5p_mfc_handle_error(dev, ctx, reason, err); + s5p_mfc_handle_error(ctx, reason, err); clear_bit(0, &dev->enter_suspend); break; diff --git a/trunk/drivers/media/usb/gspca/kinect.c b/trunk/drivers/media/usb/gspca/kinect.c index 3773a8a745df..40ad6687ee5d 100644 --- a/trunk/drivers/media/usb/gspca/kinect.c +++ b/trunk/drivers/media/usb/gspca/kinect.c @@ -381,7 +381,6 @@ static const struct sd_desc sd_desc = { /* -- module initialisation -- */ static const struct usb_device_id device_table[] = { {USB_DEVICE(0x045e, 0x02ae)}, - {USB_DEVICE(0x045e, 0x02bf)}, {} }; diff --git a/trunk/drivers/media/usb/gspca/sonixb.c b/trunk/drivers/media/usb/gspca/sonixb.c index 1220340e7602..70511d5f9538 100644 --- a/trunk/drivers/media/usb/gspca/sonixb.c +++ b/trunk/drivers/media/usb/gspca/sonixb.c @@ -496,7 +496,7 @@ static void reg_w(struct gspca_dev *gspca_dev, } } -static void i2c_w(struct gspca_dev *gspca_dev, const u8 *buf) +static void i2c_w(struct gspca_dev *gspca_dev, const __u8 *buffer) { int retry = 60; @@ -504,19 +504,16 @@ static void i2c_w(struct gspca_dev *gspca_dev, const u8 *buf) return; /* is i2c ready */ - reg_w(gspca_dev, 0x08, buf, 8); + reg_w(gspca_dev, 0x08, buffer, 8); while (retry--) { if (gspca_dev->usb_err < 0) return; - msleep(1); + msleep(10); reg_r(gspca_dev, 0x08); if (gspca_dev->usb_buf[0] & 0x04) { if (gspca_dev->usb_buf[0] & 0x08) { dev_err(gspca_dev->v4l2_dev.dev, - "i2c error writing %02x %02x %02x %02x" - " %02x %02x %02x %02x\n", - buf[0], buf[1], buf[2], buf[3], - buf[4], buf[5], buf[6], buf[7]); + "i2c write error\n"); gspca_dev->usb_err = -EIO; } return; @@ -533,7 +530,7 @@ static void i2c_w_vector(struct gspca_dev *gspca_dev, for (;;) { if (gspca_dev->usb_err < 0) return; - i2c_w(gspca_dev, *buffer); + reg_w(gspca_dev, 0x08, *buffer, 8); len -= 8; if (len <= 0) break; diff --git a/trunk/drivers/media/usb/gspca/sonixj.c b/trunk/drivers/media/usb/gspca/sonixj.c index 36307a9028a9..5a86047b846f 100644 --- a/trunk/drivers/media/usb/gspca/sonixj.c +++ b/trunk/drivers/media/usb/gspca/sonixj.c @@ -1550,7 +1550,6 @@ static void i2c_w1(struct gspca_dev *gspca_dev, u8 reg, u8 val) 0, gspca_dev->usb_buf, 8, 500); - msleep(2); if (ret < 0) { pr_err("i2c_w1 err %d\n", ret); gspca_dev->usb_err = ret; diff --git a/trunk/drivers/media/usb/uvc/uvc_ctrl.c b/trunk/drivers/media/usb/uvc/uvc_ctrl.c index d5baab17a5ef..2bb7613ddebb 100644 --- a/trunk/drivers/media/usb/uvc/uvc_ctrl.c +++ b/trunk/drivers/media/usb/uvc/uvc_ctrl.c @@ -1431,10 +1431,8 @@ int uvc_ctrl_set(struct uvc_video_chain *chain, int ret; ctrl = uvc_find_control(chain, xctrl->id, &mapping); - if (ctrl == NULL) + if (ctrl == NULL || (ctrl->info.flags & UVC_CTRL_FLAG_SET_CUR) == 0) return -EINVAL; - if (!(ctrl->info.flags & UVC_CTRL_FLAG_SET_CUR)) - return -EACCES; /* Clamp out of range values. */ switch (mapping->v4l2_type) { diff --git a/trunk/drivers/media/usb/uvc/uvc_v4l2.c b/trunk/drivers/media/usb/uvc/uvc_v4l2.c index 68d59b527492..f2ee8c6b0d8d 100644 --- a/trunk/drivers/media/usb/uvc/uvc_v4l2.c +++ b/trunk/drivers/media/usb/uvc/uvc_v4l2.c @@ -657,7 +657,8 @@ static long uvc_v4l2_do_ioctl(struct file *file, unsigned int cmd, void *arg) ret = uvc_ctrl_get(chain, ctrl); if (ret < 0) { uvc_ctrl_rollback(handle); - ctrls->error_idx = i; + ctrls->error_idx = ret == -ENOENT + ? ctrls->count : i; return ret; } } @@ -685,7 +686,8 @@ static long uvc_v4l2_do_ioctl(struct file *file, unsigned int cmd, void *arg) ret = uvc_ctrl_set(chain, ctrl); if (ret < 0) { uvc_ctrl_rollback(handle); - ctrls->error_idx = cmd == VIDIOC_S_EXT_CTRLS + ctrls->error_idx = (ret == -ENOENT && + cmd == VIDIOC_S_EXT_CTRLS) ? ctrls->count : i; return ret; } diff --git a/trunk/drivers/media/v4l2-core/videobuf2-core.c b/trunk/drivers/media/v4l2-core/videobuf2-core.c index e02c4797b1c6..9f81be23a81f 100644 --- a/trunk/drivers/media/v4l2-core/videobuf2-core.c +++ b/trunk/drivers/media/v4l2-core/videobuf2-core.c @@ -921,10 +921,8 @@ static void __fill_vb2_buffer(struct vb2_buffer *vb, const struct v4l2_buffer *b * In videobuf we use our internal V4l2_planes struct for * single-planar buffers as well, for simplicity. */ - if (V4L2_TYPE_IS_OUTPUT(b->type)) { + if (V4L2_TYPE_IS_OUTPUT(b->type)) v4l2_planes[0].bytesused = b->bytesused; - v4l2_planes[0].data_offset = 0; - } if (b->memory == V4L2_MEMORY_USERPTR) { v4l2_planes[0].m.userptr = b->m.userptr; diff --git a/trunk/drivers/misc/ti-st/st_kim.c b/trunk/drivers/misc/ti-st/st_kim.c index 9ff942a346ed..83269f1d16e3 100644 --- a/trunk/drivers/misc/ti-st/st_kim.c +++ b/trunk/drivers/misc/ti-st/st_kim.c @@ -468,6 +468,11 @@ long st_kim_start(void *kim_data) if (pdata->chip_enable) pdata->chip_enable(kim_gdata); + /* Configure BT nShutdown to HIGH state */ + gpio_set_value(kim_gdata->nshutdown, GPIO_LOW); + mdelay(5); /* FIXME: a proper toggle */ + gpio_set_value(kim_gdata->nshutdown, GPIO_HIGH); + mdelay(100); /* re-initialize the completion */ INIT_COMPLETION(kim_gdata->ldisc_installed); /* send notification to UIM */ @@ -509,7 +514,8 @@ long st_kim_start(void *kim_data) * (b) upon failure to either install ldisc or download firmware. * The function is responsible to (a) notify UIM about un-installation, * (b) flush UART if the ldisc was installed. - * (c) invoke platform's chip disabling routine. + * (c) reset BT_EN - pull down nshutdown at the end. + * (d) invoke platform's chip disabling routine. */ long st_kim_stop(void *kim_data) { @@ -541,6 +547,13 @@ long st_kim_stop(void *kim_data) err = -ETIMEDOUT; } + /* By default configure BT nShutdown to LOW state */ + gpio_set_value(kim_gdata->nshutdown, GPIO_LOW); + mdelay(1); + gpio_set_value(kim_gdata->nshutdown, GPIO_HIGH); + mdelay(1); + gpio_set_value(kim_gdata->nshutdown, GPIO_LOW); + /* platform specific disable */ if (pdata->chip_disable) pdata->chip_disable(kim_gdata); @@ -733,6 +746,20 @@ static int kim_probe(struct platform_device *pdev) /* refer to itself */ kim_gdata->core_data->kim_data = kim_gdata; + /* Claim the chip enable nShutdown gpio from the system */ + kim_gdata->nshutdown = pdata->nshutdown_gpio; + err = gpio_request(kim_gdata->nshutdown, "kim"); + if (unlikely(err)) { + pr_err(" gpio %ld request failed ", kim_gdata->nshutdown); + return err; + } + + /* Configure nShutdown GPIO as output=0 */ + err = gpio_direction_output(kim_gdata->nshutdown, 0); + if (unlikely(err)) { + pr_err(" unable to configure gpio %ld", kim_gdata->nshutdown); + return err; + } /* get reference of pdev for request_firmware */ kim_gdata->kim_pdev = pdev; @@ -779,10 +806,18 @@ static int kim_probe(struct platform_device *pdev) static int kim_remove(struct platform_device *pdev) { + /* free the GPIOs requested */ + struct ti_st_plat_data *pdata = pdev->dev.platform_data; struct kim_data_s *kim_gdata; kim_gdata = dev_get_drvdata(&pdev->dev); + /* Free the Bluetooth/FM/GPIO + * nShutdown gpio from the system + */ + gpio_free(pdata->nshutdown_gpio); + pr_info("nshutdown GPIO Freed"); + debugfs_remove_recursive(kim_debugfs_dir); sysfs_remove_group(&pdev->dev.kobj, &uim_attr_grp); pr_info("sysfs entries removed"); diff --git a/trunk/drivers/pci/hotplug/pciehp.h b/trunk/drivers/pci/hotplug/pciehp.h index 2c113de94323..26ffd3e3fb74 100644 --- a/trunk/drivers/pci/hotplug/pciehp.h +++ b/trunk/drivers/pci/hotplug/pciehp.h @@ -44,6 +44,7 @@ extern bool pciehp_poll_mode; extern int pciehp_poll_time; extern bool pciehp_debug; extern bool pciehp_force; +extern struct workqueue_struct *pciehp_wq; #define dbg(format, arg...) \ do { \ @@ -77,7 +78,6 @@ struct slot { struct hotplug_slot *hotplug_slot; struct delayed_work work; /* work for button event */ struct mutex lock; - struct workqueue_struct *wq; }; struct event_info { diff --git a/trunk/drivers/pci/hotplug/pciehp_core.c b/trunk/drivers/pci/hotplug/pciehp_core.c index 939bd1d4b5b1..916bf4f53aba 100644 --- a/trunk/drivers/pci/hotplug/pciehp_core.c +++ b/trunk/drivers/pci/hotplug/pciehp_core.c @@ -42,6 +42,7 @@ bool pciehp_debug; bool pciehp_poll_mode; int pciehp_poll_time; bool pciehp_force; +struct workqueue_struct *pciehp_wq; #define DRIVER_VERSION "0.4" #define DRIVER_AUTHOR "Dan Zink , Greg Kroah-Hartman , Dely Sy " @@ -339,13 +340,18 @@ static int __init pcied_init(void) { int retval = 0; + pciehp_wq = alloc_workqueue("pciehp", 0, 0); + if (!pciehp_wq) + return -ENOMEM; + pciehp_firmware_init(); retval = pcie_port_service_register(&hpdriver_portdrv); dbg("pcie_port_service_register = %d\n", retval); info(DRIVER_DESC " version: " DRIVER_VERSION "\n"); - if (retval) + if (retval) { + destroy_workqueue(pciehp_wq); dbg("Failure to register service\n"); - + } return retval; } @@ -353,6 +359,7 @@ static void __exit pcied_cleanup(void) { dbg("unload_pciehpd()\n"); pcie_port_service_unregister(&hpdriver_portdrv); + destroy_workqueue(pciehp_wq); info(DRIVER_DESC " version: " DRIVER_VERSION " unloaded\n"); } diff --git a/trunk/drivers/pci/hotplug/pciehp_ctrl.c b/trunk/drivers/pci/hotplug/pciehp_ctrl.c index 38f018679175..27f44295a657 100644 --- a/trunk/drivers/pci/hotplug/pciehp_ctrl.c +++ b/trunk/drivers/pci/hotplug/pciehp_ctrl.c @@ -49,7 +49,7 @@ static int queue_interrupt_event(struct slot *p_slot, u32 event_type) info->p_slot = p_slot; INIT_WORK(&info->work, interrupt_event_handler); - queue_work(p_slot->wq, &info->work); + queue_work(pciehp_wq, &info->work); return 0; } @@ -344,7 +344,7 @@ void pciehp_queue_pushbutton_work(struct work_struct *work) kfree(info); goto out; } - queue_work(p_slot->wq, &info->work); + queue_work(pciehp_wq, &info->work); out: mutex_unlock(&p_slot->lock); } @@ -377,7 +377,7 @@ static void handle_button_press_event(struct slot *p_slot) if (ATTN_LED(ctrl)) pciehp_set_attention_status(p_slot, 0); - queue_delayed_work(p_slot->wq, &p_slot->work, 5*HZ); + queue_delayed_work(pciehp_wq, &p_slot->work, 5*HZ); break; case BLINKINGOFF_STATE: case BLINKINGON_STATE: @@ -439,7 +439,7 @@ static void handle_surprise_event(struct slot *p_slot) else p_slot->state = POWERON_STATE; - queue_work(p_slot->wq, &info->work); + queue_work(pciehp_wq, &info->work); } static void interrupt_event_handler(struct work_struct *work) diff --git a/trunk/drivers/pci/hotplug/pciehp_hpc.c b/trunk/drivers/pci/hotplug/pciehp_hpc.c index 5127f3f41821..13b2eaf7ba43 100644 --- a/trunk/drivers/pci/hotplug/pciehp_hpc.c +++ b/trunk/drivers/pci/hotplug/pciehp_hpc.c @@ -773,32 +773,23 @@ static void pcie_shutdown_notification(struct controller *ctrl) static int pcie_init_slot(struct controller *ctrl) { struct slot *slot; - char name[32]; slot = kzalloc(sizeof(*slot), GFP_KERNEL); if (!slot) return -ENOMEM; - snprintf(name, sizeof(name), "pciehp-%u", PSN(ctrl)); - slot->wq = alloc_workqueue(name, 0, 0); - if (!slot->wq) - goto abort; - slot->ctrl = ctrl; mutex_init(&slot->lock); INIT_DELAYED_WORK(&slot->work, pciehp_queue_pushbutton_work); ctrl->slot = slot; return 0; -abort: - kfree(slot); - return -ENOMEM; } static void pcie_cleanup_slot(struct controller *ctrl) { struct slot *slot = ctrl->slot; cancel_delayed_work(&slot->work); - destroy_workqueue(slot->wq); + flush_workqueue(pciehp_wq); kfree(slot); } diff --git a/trunk/drivers/pci/hotplug/shpchp.h b/trunk/drivers/pci/hotplug/shpchp.h index b849f995075a..ca64932e658b 100644 --- a/trunk/drivers/pci/hotplug/shpchp.h +++ b/trunk/drivers/pci/hotplug/shpchp.h @@ -46,6 +46,8 @@ extern bool shpchp_poll_mode; extern int shpchp_poll_time; extern bool shpchp_debug; +extern struct workqueue_struct *shpchp_wq; +extern struct workqueue_struct *shpchp_ordered_wq; #define dbg(format, arg...) \ do { \ @@ -89,7 +91,6 @@ struct slot { struct list_head slot_list; struct delayed_work work; /* work for button event */ struct mutex lock; - struct workqueue_struct *wq; u8 hp_slot; }; diff --git a/trunk/drivers/pci/hotplug/shpchp_core.c b/trunk/drivers/pci/hotplug/shpchp_core.c index 3100c52c837c..b6de307248e4 100644 --- a/trunk/drivers/pci/hotplug/shpchp_core.c +++ b/trunk/drivers/pci/hotplug/shpchp_core.c @@ -39,6 +39,8 @@ bool shpchp_debug; bool shpchp_poll_mode; int shpchp_poll_time; +struct workqueue_struct *shpchp_wq; +struct workqueue_struct *shpchp_ordered_wq; #define DRIVER_VERSION "0.4" #define DRIVER_AUTHOR "Dan Zink , Greg Kroah-Hartman , Dely Sy " @@ -127,14 +129,6 @@ static int init_slots(struct controller *ctrl) slot->device = ctrl->slot_device_offset + i; slot->hpc_ops = ctrl->hpc_ops; slot->number = ctrl->first_slot + (ctrl->slot_num_inc * i); - - snprintf(name, sizeof(name), "shpchp-%d", slot->number); - slot->wq = alloc_workqueue(name, 0, 0); - if (!slot->wq) { - retval = -ENOMEM; - goto error_info; - } - mutex_init(&slot->lock); INIT_DELAYED_WORK(&slot->work, shpchp_queue_pushbutton_work); @@ -154,7 +148,7 @@ static int init_slots(struct controller *ctrl) if (retval) { ctrl_err(ctrl, "pci_hp_register failed with error %d\n", retval); - goto error_slotwq; + goto error_info; } get_power_status(hotplug_slot, &info->power_status); @@ -166,8 +160,6 @@ static int init_slots(struct controller *ctrl) } return 0; -error_slotwq: - destroy_workqueue(slot->wq); error_info: kfree(info); error_hpslot: @@ -188,7 +180,8 @@ void cleanup_slots(struct controller *ctrl) slot = list_entry(tmp, struct slot, slot_list); list_del(&slot->slot_list); cancel_delayed_work(&slot->work); - destroy_workqueue(slot->wq); + flush_workqueue(shpchp_wq); + flush_workqueue(shpchp_ordered_wq); pci_hp_deregister(slot->hotplug_slot); } } @@ -371,12 +364,25 @@ static struct pci_driver shpc_driver = { static int __init shpcd_init(void) { - int retval; + int retval = 0; + + shpchp_wq = alloc_ordered_workqueue("shpchp", 0); + if (!shpchp_wq) + return -ENOMEM; + + shpchp_ordered_wq = alloc_ordered_workqueue("shpchp_ordered", 0); + if (!shpchp_ordered_wq) { + destroy_workqueue(shpchp_wq); + return -ENOMEM; + } retval = pci_register_driver(&shpc_driver); dbg("%s: pci_register_driver = %d\n", __func__, retval); info(DRIVER_DESC " version: " DRIVER_VERSION "\n"); - + if (retval) { + destroy_workqueue(shpchp_ordered_wq); + destroy_workqueue(shpchp_wq); + } return retval; } @@ -384,6 +390,8 @@ static void __exit shpcd_cleanup(void) { dbg("unload_shpchpd()\n"); pci_unregister_driver(&shpc_driver); + destroy_workqueue(shpchp_ordered_wq); + destroy_workqueue(shpchp_wq); info(DRIVER_DESC " version: " DRIVER_VERSION " unloaded\n"); } diff --git a/trunk/drivers/pci/hotplug/shpchp_ctrl.c b/trunk/drivers/pci/hotplug/shpchp_ctrl.c index 58499277903a..f9b5a52e4115 100644 --- a/trunk/drivers/pci/hotplug/shpchp_ctrl.c +++ b/trunk/drivers/pci/hotplug/shpchp_ctrl.c @@ -51,7 +51,7 @@ static int queue_interrupt_event(struct slot *p_slot, u32 event_type) info->p_slot = p_slot; INIT_WORK(&info->work, interrupt_event_handler); - queue_work(p_slot->wq, &info->work); + queue_work(shpchp_wq, &info->work); return 0; } @@ -453,7 +453,7 @@ void shpchp_queue_pushbutton_work(struct work_struct *work) kfree(info); goto out; } - queue_work(p_slot->wq, &info->work); + queue_work(shpchp_ordered_wq, &info->work); out: mutex_unlock(&p_slot->lock); } @@ -501,7 +501,7 @@ static void handle_button_press_event(struct slot *p_slot) p_slot->hpc_ops->green_led_blink(p_slot); p_slot->hpc_ops->set_attention_status(p_slot, 0); - queue_delayed_work(p_slot->wq, &p_slot->work, 5*HZ); + queue_delayed_work(shpchp_wq, &p_slot->work, 5*HZ); break; case BLINKINGOFF_STATE: case BLINKINGON_STATE: diff --git a/trunk/drivers/pci/pcie/Kconfig b/trunk/drivers/pci/pcie/Kconfig index fde4a32a0295..6c8bc5809787 100644 --- a/trunk/drivers/pci/pcie/Kconfig +++ b/trunk/drivers/pci/pcie/Kconfig @@ -82,4 +82,4 @@ endchoice config PCIE_PME def_bool y - depends on PCIEPORTBUS && PM_RUNTIME && ACPI + depends on PCIEPORTBUS && PM_RUNTIME && EXPERIMENTAL && ACPI diff --git a/trunk/drivers/pci/pcie/aer/aerdrv_core.c b/trunk/drivers/pci/pcie/aer/aerdrv_core.c index 564d97f94b6c..421bbc5fee32 100644 --- a/trunk/drivers/pci/pcie/aer/aerdrv_core.c +++ b/trunk/drivers/pci/pcie/aer/aerdrv_core.c @@ -630,7 +630,6 @@ static void aer_recover_work_func(struct work_struct *work) continue; } do_recovery(pdev, entry.severity); - pci_dev_put(pdev); } } #endif diff --git a/trunk/drivers/pci/pcie/aspm.c b/trunk/drivers/pci/pcie/aspm.c index 8474b6a4fc9b..b52630b8eada 100644 --- a/trunk/drivers/pci/pcie/aspm.c +++ b/trunk/drivers/pci/pcie/aspm.c @@ -771,9 +771,6 @@ void pcie_clear_aspm(struct pci_bus *bus) { struct pci_dev *child; - if (aspm_force) - return; - /* * Clear any ASPM setup that the firmware has carried out on this bus */ diff --git a/trunk/drivers/vfio/pci/vfio_pci_rdwr.c b/trunk/drivers/vfio/pci/vfio_pci_rdwr.c index f72323ef618f..4362d9e7baa3 100644 --- a/trunk/drivers/vfio/pci/vfio_pci_rdwr.c +++ b/trunk/drivers/vfio/pci/vfio_pci_rdwr.c @@ -240,17 +240,17 @@ ssize_t vfio_pci_mem_readwrite(struct vfio_pci_device *vdev, char __user *buf, filled = 1; } else { /* Drop writes, fill reads with FF */ - filled = min((size_t)(x_end - pos), count); if (!iswrite) { char val = 0xFF; size_t i; - for (i = 0; i < filled; i++) { + for (i = 0; i < x_end - pos; i++) { if (put_user(val, buf + i)) goto out; } } + filled = x_end - pos; } count -= filled; diff --git a/trunk/fs/Kconfig b/trunk/fs/Kconfig index 780725a463b1..cfe512fd1caf 100644 --- a/trunk/fs/Kconfig +++ b/trunk/fs/Kconfig @@ -68,6 +68,16 @@ source "fs/quota/Kconfig" source "fs/autofs4/Kconfig" source "fs/fuse/Kconfig" +config CUSE + tristate "Character device in Userspace support" + depends on FUSE_FS + help + This FUSE extension allows character devices to be + implemented in userspace. + + If you want to develop or use userspace character device + based on CUSE, answer Y or M. + config GENERIC_ACL bool select FS_POSIX_ACL diff --git a/trunk/fs/f2fs/acl.c b/trunk/fs/f2fs/acl.c index 137af4255da6..e95b94945d5f 100644 --- a/trunk/fs/f2fs/acl.c +++ b/trunk/fs/f2fs/acl.c @@ -191,14 +191,15 @@ struct posix_acl *f2fs_get_acl(struct inode *inode, int type) retval = f2fs_getxattr(inode, name_index, "", value, retval); } - if (retval > 0) + if (retval < 0) { + if (retval == -ENODATA) + acl = NULL; + else + acl = ERR_PTR(retval); + } else { acl = f2fs_acl_from_disk(value, retval); - else if (retval == -ENODATA) - acl = NULL; - else - acl = ERR_PTR(retval); + } kfree(value); - if (!IS_ERR(acl)) set_cached_acl(inode, type, acl); diff --git a/trunk/fs/f2fs/checkpoint.c b/trunk/fs/f2fs/checkpoint.c index ff3c8439af87..6ef36c37e2be 100644 --- a/trunk/fs/f2fs/checkpoint.c +++ b/trunk/fs/f2fs/checkpoint.c @@ -214,6 +214,7 @@ void add_orphan_inode(struct f2fs_sb_info *sbi, nid_t ino) goto retry; } new->ino = ino; + INIT_LIST_HEAD(&new->list); /* add new_oentry into list which is sorted by inode number */ if (orphan) { @@ -771,7 +772,7 @@ void init_orphan_info(struct f2fs_sb_info *sbi) sbi->n_orphans = 0; } -int __init create_checkpoint_caches(void) +int create_checkpoint_caches(void) { orphan_entry_slab = f2fs_kmem_cache_create("f2fs_orphan_entry", sizeof(struct orphan_inode_entry), NULL); diff --git a/trunk/fs/f2fs/data.c b/trunk/fs/f2fs/data.c index 7bd22a201125..3aa5ce7cab83 100644 --- a/trunk/fs/f2fs/data.c +++ b/trunk/fs/f2fs/data.c @@ -547,15 +547,6 @@ static int f2fs_write_data_page(struct page *page, #define MAX_DESIRED_PAGES_WP 4096 -static int __f2fs_writepage(struct page *page, struct writeback_control *wbc, - void *data) -{ - struct address_space *mapping = data; - int ret = mapping->a_ops->writepage(page, wbc); - mapping_set_error(mapping, ret); - return ret; -} - static int f2fs_write_data_pages(struct address_space *mapping, struct writeback_control *wbc) { @@ -572,7 +563,7 @@ static int f2fs_write_data_pages(struct address_space *mapping, if (!S_ISDIR(inode->i_mode)) mutex_lock(&sbi->writepages); - ret = write_cache_pages(mapping, wbc, __f2fs_writepage, mapping); + ret = generic_writepages(mapping, wbc); if (!S_ISDIR(inode->i_mode)) mutex_unlock(&sbi->writepages); f2fs_submit_bio(sbi, DATA, (wbc->sync_mode == WB_SYNC_ALL)); @@ -698,11 +689,6 @@ static int f2fs_set_data_page_dirty(struct page *page) return 0; } -static sector_t f2fs_bmap(struct address_space *mapping, sector_t block) -{ - return generic_block_bmap(mapping, block, get_data_block_ro); -} - const struct address_space_operations f2fs_dblock_aops = { .readpage = f2fs_read_data_page, .readpages = f2fs_read_data_pages, @@ -714,5 +700,4 @@ const struct address_space_operations f2fs_dblock_aops = { .invalidatepage = f2fs_invalidate_data_page, .releasepage = f2fs_release_data_page, .direct_IO = f2fs_direct_IO, - .bmap = f2fs_bmap, }; diff --git a/trunk/fs/f2fs/debug.c b/trunk/fs/f2fs/debug.c index c8c37307b326..0e0380a588ad 100644 --- a/trunk/fs/f2fs/debug.c +++ b/trunk/fs/f2fs/debug.c @@ -26,7 +26,6 @@ static LIST_HEAD(f2fs_stat_list); static struct dentry *debugfs_root; -static DEFINE_MUTEX(f2fs_stat_mutex); static void update_general_status(struct f2fs_sb_info *sbi) { @@ -181,14 +180,18 @@ static int stat_show(struct seq_file *s, void *v) int i = 0; int j; - mutex_lock(&f2fs_stat_mutex); list_for_each_entry_safe(si, next, &f2fs_stat_list, stat_list) { + mutex_lock(&si->stat_lock); + if (!si->sbi) { + mutex_unlock(&si->stat_lock); + continue; + } update_general_status(si->sbi); seq_printf(s, "\n=====[ partition info. #%d ]=====\n", i++); - seq_printf(s, "[SB: 1] [CP: 2] [SIT: %d] [NAT: %d] ", - si->sit_area_segs, si->nat_area_segs); + seq_printf(s, "[SB: 1] [CP: 2] [NAT: %d] [SIT: %d] ", + si->nat_area_segs, si->sit_area_segs); seq_printf(s, "[SSA: %d] [MAIN: %d", si->ssa_area_segs, si->main_area_segs); seq_printf(s, "(OverProv:%d Resv:%d)]\n\n", @@ -283,8 +286,8 @@ static int stat_show(struct seq_file *s, void *v) seq_printf(s, "\nMemory: %u KB = static: %u + cached: %u\n", (si->base_mem + si->cache_mem) >> 10, si->base_mem >> 10, si->cache_mem >> 10); + mutex_unlock(&si->stat_lock); } - mutex_unlock(&f2fs_stat_mutex); return 0; } @@ -300,7 +303,7 @@ static const struct file_operations stat_fops = { .release = single_release, }; -int f2fs_build_stats(struct f2fs_sb_info *sbi) +static int init_stats(struct f2fs_sb_info *sbi) { struct f2fs_super_block *raw_super = F2FS_RAW_SUPER(sbi); struct f2fs_stat_info *si; @@ -310,6 +313,9 @@ int f2fs_build_stats(struct f2fs_sb_info *sbi) return -ENOMEM; si = sbi->stat_info; + mutex_init(&si->stat_lock); + list_add_tail(&si->stat_list, &f2fs_stat_list); + si->all_area_segs = le32_to_cpu(raw_super->segment_count); si->sit_area_segs = le32_to_cpu(raw_super->segment_count_sit); si->nat_area_segs = le32_to_cpu(raw_super->segment_count_nat); @@ -319,11 +325,21 @@ int f2fs_build_stats(struct f2fs_sb_info *sbi) si->main_area_zones = si->main_area_sections / le32_to_cpu(raw_super->secs_per_zone); si->sbi = sbi; + return 0; +} - mutex_lock(&f2fs_stat_mutex); - list_add_tail(&si->stat_list, &f2fs_stat_list); - mutex_unlock(&f2fs_stat_mutex); +int f2fs_build_stats(struct f2fs_sb_info *sbi) +{ + int retval; + + retval = init_stats(sbi); + if (retval) + return retval; + if (!debugfs_root) + debugfs_root = debugfs_create_dir("f2fs", NULL); + + debugfs_create_file("status", S_IRUGO, debugfs_root, NULL, &stat_fops); return 0; } @@ -331,22 +347,14 @@ void f2fs_destroy_stats(struct f2fs_sb_info *sbi) { struct f2fs_stat_info *si = sbi->stat_info; - mutex_lock(&f2fs_stat_mutex); list_del(&si->stat_list); - mutex_unlock(&f2fs_stat_mutex); - + mutex_lock(&si->stat_lock); + si->sbi = NULL; + mutex_unlock(&si->stat_lock); kfree(sbi->stat_info); } -void __init f2fs_create_root_stats(void) -{ - debugfs_root = debugfs_create_dir("f2fs", NULL); - if (debugfs_root) - debugfs_create_file("status", S_IRUGO, debugfs_root, - NULL, &stat_fops); -} - -void f2fs_destroy_root_stats(void) +void destroy_root_stats(void) { debugfs_remove_recursive(debugfs_root); debugfs_root = NULL; diff --git a/trunk/fs/f2fs/dir.c b/trunk/fs/f2fs/dir.c index 989980e16d0b..951ed52748f6 100644 --- a/trunk/fs/f2fs/dir.c +++ b/trunk/fs/f2fs/dir.c @@ -503,7 +503,7 @@ void f2fs_delete_entry(struct f2fs_dir_entry *dentry, struct page *page, } if (inode) { - inode->i_ctime = CURRENT_TIME; + inode->i_ctime = dir->i_ctime = dir->i_mtime = CURRENT_TIME; drop_nlink(inode); if (S_ISDIR(inode->i_mode)) { drop_nlink(inode); diff --git a/trunk/fs/f2fs/f2fs.h b/trunk/fs/f2fs/f2fs.h index c8e2d751ef9c..13c6dfbb7183 100644 --- a/trunk/fs/f2fs/f2fs.h +++ b/trunk/fs/f2fs/f2fs.h @@ -211,11 +211,11 @@ struct dnode_of_data { static inline void set_new_dnode(struct dnode_of_data *dn, struct inode *inode, struct page *ipage, struct page *npage, nid_t nid) { - memset(dn, 0, sizeof(*dn)); dn->inode = inode; dn->inode_page = ipage; dn->node_page = npage; dn->nid = nid; + dn->inode_page_locked = 0; } /* @@ -877,8 +877,6 @@ bool f2fs_empty_dir(struct inode *); * super.c */ int f2fs_sync_fs(struct super_block *, int); -extern __printf(3, 4) -void f2fs_msg(struct super_block *, const char *, const char *, ...); /* * hash.c @@ -914,7 +912,7 @@ int restore_node_summary(struct f2fs_sb_info *, unsigned int, void flush_nat_entries(struct f2fs_sb_info *); int build_node_manager(struct f2fs_sb_info *); void destroy_node_manager(struct f2fs_sb_info *); -int __init create_node_manager_caches(void); +int create_node_manager_caches(void); void destroy_node_manager_caches(void); /* @@ -966,7 +964,7 @@ void sync_dirty_dir_inodes(struct f2fs_sb_info *); void block_operations(struct f2fs_sb_info *); void write_checkpoint(struct f2fs_sb_info *, bool, bool); void init_orphan_info(struct f2fs_sb_info *); -int __init create_checkpoint_caches(void); +int create_checkpoint_caches(void); void destroy_checkpoint_caches(void); /* @@ -986,9 +984,9 @@ int do_write_data_page(struct page *); int start_gc_thread(struct f2fs_sb_info *); void stop_gc_thread(struct f2fs_sb_info *); block_t start_bidx_of_node(unsigned int); -int f2fs_gc(struct f2fs_sb_info *); +int f2fs_gc(struct f2fs_sb_info *, int); void build_gc_manager(struct f2fs_sb_info *); -int __init create_gc_caches(void); +int create_gc_caches(void); void destroy_gc_caches(void); /* @@ -1060,8 +1058,7 @@ struct f2fs_stat_info { int f2fs_build_stats(struct f2fs_sb_info *); void f2fs_destroy_stats(struct f2fs_sb_info *); -void __init f2fs_create_root_stats(void); -void f2fs_destroy_root_stats(void); +void destroy_root_stats(void); #else #define stat_inc_call_count(si) #define stat_inc_seg_count(si, type) @@ -1071,8 +1068,7 @@ void f2fs_destroy_root_stats(void); static inline int f2fs_build_stats(struct f2fs_sb_info *sbi) { return 0; } static inline void f2fs_destroy_stats(struct f2fs_sb_info *sbi) { } -static inline void __init f2fs_create_root_stats(void) { } -static inline void f2fs_destroy_root_stats(void) { } +static inline void destroy_root_stats(void) { } #endif extern const struct file_operations f2fs_dir_operations; diff --git a/trunk/fs/f2fs/file.c b/trunk/fs/f2fs/file.c index 3191b52aafb0..7f9ea9271ebe 100644 --- a/trunk/fs/f2fs/file.c +++ b/trunk/fs/f2fs/file.c @@ -96,9 +96,8 @@ static int f2fs_vm_page_mkwrite(struct vm_area_struct *vma, } static const struct vm_operations_struct f2fs_file_vm_ops = { - .fault = filemap_fault, - .page_mkwrite = f2fs_vm_page_mkwrite, - .remap_pages = generic_file_remap_pages, + .fault = filemap_fault, + .page_mkwrite = f2fs_vm_page_mkwrite, }; static int need_to_sync_dir(struct f2fs_sb_info *sbi, struct inode *inode) @@ -138,9 +137,6 @@ int f2fs_sync_file(struct file *file, loff_t start, loff_t end, int datasync) if (ret) return ret; - /* guarantee free sections for fsync */ - f2fs_balance_fs(sbi); - mutex_lock(&inode->i_mutex); if (datasync && !(inode->i_state & I_DIRTY_DATASYNC)) @@ -411,8 +407,6 @@ int truncate_hole(struct inode *inode, pgoff_t pg_start, pgoff_t pg_end) struct dnode_of_data dn; struct f2fs_sb_info *sbi = F2FS_SB(inode->i_sb); - f2fs_balance_fs(sbi); - mutex_lock_op(sbi, DATA_TRUNC); set_new_dnode(&dn, inode, NULL, NULL, 0); err = get_dnode_of_data(&dn, index, RDONLY_NODE); @@ -540,6 +534,7 @@ static long f2fs_fallocate(struct file *file, int mode, loff_t offset, loff_t len) { struct inode *inode = file->f_path.dentry->d_inode; + struct f2fs_sb_info *sbi = F2FS_SB(inode->i_sb); long ret; if (mode & ~(FALLOC_FL_KEEP_SIZE | FALLOC_FL_PUNCH_HOLE)) @@ -550,10 +545,7 @@ static long f2fs_fallocate(struct file *file, int mode, else ret = expand_inode_data(inode, offset, len, mode); - if (!ret) { - inode->i_mtime = inode->i_ctime = CURRENT_TIME; - mark_inode_dirty(inode); - } + f2fs_balance_fs(sbi); return ret; } diff --git a/trunk/fs/f2fs/gc.c b/trunk/fs/f2fs/gc.c index c386910dacc5..b0ec721e984a 100644 --- a/trunk/fs/f2fs/gc.c +++ b/trunk/fs/f2fs/gc.c @@ -78,7 +78,7 @@ static int gc_thread_func(void *data) sbi->bg_gc++; - if (f2fs_gc(sbi) == GC_NONE) + if (f2fs_gc(sbi, 1) == GC_NONE) wait_ms = GC_THREAD_NOGC_SLEEP_TIME; else if (wait_ms == GC_THREAD_NOGC_SLEEP_TIME) wait_ms = GC_THREAD_MAX_SLEEP_TIME; @@ -424,11 +424,7 @@ static int gc_node_segment(struct f2fs_sb_info *sbi, } /* - * Calculate start block index indicating the given node offset. - * Be careful, caller should give this node offset only indicating direct node - * blocks. If any node offsets, which point the other types of node blocks such - * as indirect or double indirect node blocks, are given, it must be a caller's - * bug. + * Calculate start block index that this node page contains */ block_t start_bidx_of_node(unsigned int node_ofs) { @@ -655,44 +651,62 @@ static int do_garbage_collect(struct f2fs_sb_info *sbi, unsigned int segno, return ret; } -int f2fs_gc(struct f2fs_sb_info *sbi) +int f2fs_gc(struct f2fs_sb_info *sbi, int nGC) { + unsigned int segno; + int old_free_secs, cur_free_secs; + int gc_status, nfree; struct list_head ilist; - unsigned int segno, i; int gc_type = BG_GC; - int gc_status = GC_NONE; INIT_LIST_HEAD(&ilist); gc_more: - if (!(sbi->sb->s_flags & MS_ACTIVE)) - goto stop; + nfree = 0; + gc_status = GC_NONE; if (has_not_enough_free_secs(sbi)) - gc_type = FG_GC; + old_free_secs = reserved_sections(sbi); + else + old_free_secs = free_sections(sbi); - if (!__get_victim(sbi, &segno, gc_type, NO_CHECK_TYPE)) - goto stop; + while (sbi->sb->s_flags & MS_ACTIVE) { + int i; + if (has_not_enough_free_secs(sbi)) + gc_type = FG_GC; - for (i = 0; i < sbi->segs_per_sec; i++) { - /* - * do_garbage_collect will give us three gc_status: - * GC_ERROR, GC_DONE, and GC_BLOCKED. - * If GC is finished uncleanly, we have to return - * the victim to dirty segment list. - */ - gc_status = do_garbage_collect(sbi, segno + i, &ilist, gc_type); - if (gc_status != GC_DONE) + cur_free_secs = free_sections(sbi) + nfree; + + /* We got free space successfully. */ + if (nGC < cur_free_secs - old_free_secs) break; + + if (!__get_victim(sbi, &segno, gc_type, NO_CHECK_TYPE)) + break; + + for (i = 0; i < sbi->segs_per_sec; i++) { + /* + * do_garbage_collect will give us three gc_status: + * GC_ERROR, GC_DONE, and GC_BLOCKED. + * If GC is finished uncleanly, we have to return + * the victim to dirty segment list. + */ + gc_status = do_garbage_collect(sbi, segno + i, + &ilist, gc_type); + if (gc_status != GC_DONE) + goto stop; + nfree++; + } } - if (has_not_enough_free_secs(sbi)) { +stop: + if (has_not_enough_free_secs(sbi) || gc_status == GC_BLOCKED) { write_checkpoint(sbi, (gc_status == GC_BLOCKED), false); - if (has_not_enough_free_secs(sbi)) + if (nfree) goto gc_more; } -stop: mutex_unlock(&sbi->gc_mutex); put_gc_inode(&ilist); + BUG_ON(!list_empty(&ilist)); return gc_status; } @@ -701,7 +715,7 @@ void build_gc_manager(struct f2fs_sb_info *sbi) DIRTY_I(sbi)->v_ops = &default_v_ops; } -int __init create_gc_caches(void) +int create_gc_caches(void) { winode_slab = f2fs_kmem_cache_create("f2fs_gc_inodes", sizeof(struct inode_entry), NULL); diff --git a/trunk/fs/f2fs/inode.c b/trunk/fs/f2fs/inode.c index 794241777322..bf20b4d03214 100644 --- a/trunk/fs/f2fs/inode.c +++ b/trunk/fs/f2fs/inode.c @@ -217,9 +217,6 @@ int f2fs_write_inode(struct inode *inode, struct writeback_control *wbc) inode->i_ino == F2FS_META_INO(sbi)) return 0; - if (wbc) - f2fs_balance_fs(sbi); - node_page = get_node_page(sbi, inode->i_ino); if (IS_ERR(node_page)) return PTR_ERR(node_page); diff --git a/trunk/fs/f2fs/node.c b/trunk/fs/f2fs/node.c index 9bda63c9c166..5066bfd256c9 100644 --- a/trunk/fs/f2fs/node.c +++ b/trunk/fs/f2fs/node.c @@ -1124,12 +1124,6 @@ static int f2fs_write_node_page(struct page *page, return 0; } -/* - * It is very important to gather dirty pages and write at once, so that we can - * submit a big bio without interfering other data writes. - * Be default, 512 pages (2MB), a segment size, is quite reasonable. - */ -#define COLLECT_DIRTY_NODES 512 static int f2fs_write_node_pages(struct address_space *mapping, struct writeback_control *wbc) { @@ -1137,16 +1131,17 @@ static int f2fs_write_node_pages(struct address_space *mapping, struct block_device *bdev = sbi->sb->s_bdev; long nr_to_write = wbc->nr_to_write; - /* First check balancing cached NAT entries */ + if (wbc->for_kupdate) + return 0; + + if (get_pages(sbi, F2FS_DIRTY_NODES) == 0) + return 0; + if (try_to_free_nats(sbi, NAT_ENTRY_PER_BLOCK)) { write_checkpoint(sbi, false, false); return 0; } - /* collect a number of dirty node pages and write together */ - if (get_pages(sbi, F2FS_DIRTY_NODES) < COLLECT_DIRTY_NODES) - return 0; - /* if mounting is failed, skip writing node pages */ wbc->nr_to_write = bio_get_nr_vecs(bdev); sync_node_pages(sbi, 0, wbc); @@ -1737,7 +1732,7 @@ void destroy_node_manager(struct f2fs_sb_info *sbi) kfree(nm_i); } -int __init create_node_manager_caches(void) +int create_node_manager_caches(void) { nat_entry_slab = f2fs_kmem_cache_create("nat_entry", sizeof(struct nat_entry), NULL); diff --git a/trunk/fs/f2fs/recovery.c b/trunk/fs/f2fs/recovery.c index f42e4060b399..b571fee677d5 100644 --- a/trunk/fs/f2fs/recovery.c +++ b/trunk/fs/f2fs/recovery.c @@ -67,7 +67,7 @@ static int recover_dentry(struct page *ipage, struct inode *inode) kunmap(page); f2fs_put_page(page, 0); } else { - err = f2fs_add_link(&dent, inode); + f2fs_add_link(&dent, inode); } iput(dir); out: @@ -151,6 +151,7 @@ static int find_fsync_dnodes(struct f2fs_sb_info *sbi, struct list_head *head) goto out; } + INIT_LIST_HEAD(&entry->list); list_add_tail(&entry->list, head); entry->blkaddr = blkaddr; } @@ -173,9 +174,10 @@ static int find_fsync_dnodes(struct f2fs_sb_info *sbi, struct list_head *head) static void destroy_fsync_dnodes(struct f2fs_sb_info *sbi, struct list_head *head) { - struct fsync_inode_entry *entry, *tmp; - - list_for_each_entry_safe(entry, tmp, head, list) { + struct list_head *this; + struct fsync_inode_entry *entry; + list_for_each(this, head) { + entry = list_entry(this, struct fsync_inode_entry, list); iput(entry->inode); list_del(&entry->list); kmem_cache_free(fsync_entry_slab, entry); diff --git a/trunk/fs/f2fs/segment.c b/trunk/fs/f2fs/segment.c index 4b0099066582..de6240922b0a 100644 --- a/trunk/fs/f2fs/segment.c +++ b/trunk/fs/f2fs/segment.c @@ -31,7 +31,7 @@ void f2fs_balance_fs(struct f2fs_sb_info *sbi) */ if (has_not_enough_free_secs(sbi)) { mutex_lock(&sbi->gc_mutex); - f2fs_gc(sbi); + f2fs_gc(sbi, 1); } } diff --git a/trunk/fs/f2fs/super.c b/trunk/fs/f2fs/super.c index 37fad04c8669..08a94c814bdc 100644 --- a/trunk/fs/f2fs/super.c +++ b/trunk/fs/f2fs/super.c @@ -53,18 +53,6 @@ static match_table_t f2fs_tokens = { {Opt_err, NULL}, }; -void f2fs_msg(struct super_block *sb, const char *level, const char *fmt, ...) -{ - struct va_format vaf; - va_list args; - - va_start(args, fmt); - vaf.fmt = fmt; - vaf.va = &args; - printk("%sF2FS-fs (%s): %pV\n", level, sb->s_id, &vaf); - va_end(args); -} - static void init_once(void *foo) { struct f2fs_inode_info *fi = (struct f2fs_inode_info *) foo; @@ -137,8 +125,6 @@ int f2fs_sync_fs(struct super_block *sb, int sync) if (sync) write_checkpoint(sbi, false, false); - else - f2fs_balance_fs(sbi); return 0; } @@ -261,8 +247,7 @@ static const struct export_operations f2fs_export_ops = { .get_parent = f2fs_get_parent, }; -static int parse_options(struct super_block *sb, struct f2fs_sb_info *sbi, - char *options) +static int parse_options(struct f2fs_sb_info *sbi, char *options) { substring_t args[MAX_OPT_ARGS]; char *p; @@ -301,8 +286,7 @@ static int parse_options(struct super_block *sb, struct f2fs_sb_info *sbi, break; #else case Opt_nouser_xattr: - f2fs_msg(sb, KERN_INFO, - "nouser_xattr options not supported"); + pr_info("nouser_xattr options not supported\n"); break; #endif #ifdef CONFIG_F2FS_FS_POSIX_ACL @@ -311,7 +295,7 @@ static int parse_options(struct super_block *sb, struct f2fs_sb_info *sbi, break; #else case Opt_noacl: - f2fs_msg(sb, KERN_INFO, "noacl options not supported"); + pr_info("noacl options not supported\n"); break; #endif case Opt_active_logs: @@ -325,9 +309,8 @@ static int parse_options(struct super_block *sb, struct f2fs_sb_info *sbi, set_opt(sbi, DISABLE_EXT_IDENTIFY); break; default: - f2fs_msg(sb, KERN_ERR, - "Unrecognized mount option \"%s\" or missing value", - p); + pr_err("Unrecognized mount option \"%s\" or missing value\n", + p); return -EINVAL; } } @@ -354,36 +337,23 @@ static loff_t max_file_size(unsigned bits) return result; } -static int sanity_check_raw_super(struct super_block *sb, - struct f2fs_super_block *raw_super) +static int sanity_check_raw_super(struct f2fs_super_block *raw_super) { unsigned int blocksize; - if (F2FS_SUPER_MAGIC != le32_to_cpu(raw_super->magic)) { - f2fs_msg(sb, KERN_INFO, - "Magic Mismatch, valid(0x%x) - read(0x%x)", - F2FS_SUPER_MAGIC, le32_to_cpu(raw_super->magic)); + if (F2FS_SUPER_MAGIC != le32_to_cpu(raw_super->magic)) return 1; - } /* Currently, support only 4KB block size */ blocksize = 1 << le32_to_cpu(raw_super->log_blocksize); - if (blocksize != PAGE_CACHE_SIZE) { - f2fs_msg(sb, KERN_INFO, - "Invalid blocksize (%u), supports only 4KB\n", - blocksize); + if (blocksize != PAGE_CACHE_SIZE) return 1; - } if (le32_to_cpu(raw_super->log_sectorsize) != - F2FS_LOG_SECTOR_SIZE) { - f2fs_msg(sb, KERN_INFO, "Invalid log sectorsize"); + F2FS_LOG_SECTOR_SIZE) return 1; - } if (le32_to_cpu(raw_super->log_sectors_per_block) != - F2FS_LOG_SECTORS_PER_BLOCK) { - f2fs_msg(sb, KERN_INFO, "Invalid log sectors per block"); + F2FS_LOG_SECTORS_PER_BLOCK) return 1; - } return 0; } @@ -443,17 +413,14 @@ static int f2fs_fill_super(struct super_block *sb, void *data, int silent) if (!sbi) return -ENOMEM; - /* set a block size */ - if (!sb_set_blocksize(sb, F2FS_BLKSIZE)) { - f2fs_msg(sb, KERN_ERR, "unable to set blocksize"); + /* set a temporary block size */ + if (!sb_set_blocksize(sb, F2FS_BLKSIZE)) goto free_sbi; - } /* read f2fs raw super block */ raw_super_buf = sb_bread(sb, 0); if (!raw_super_buf) { err = -EIO; - f2fs_msg(sb, KERN_ERR, "unable to read superblock"); goto free_sbi; } raw_super = (struct f2fs_super_block *) @@ -471,14 +438,12 @@ static int f2fs_fill_super(struct super_block *sb, void *data, int silent) set_opt(sbi, POSIX_ACL); #endif /* parse mount options */ - if (parse_options(sb, sbi, (char *)data)) + if (parse_options(sbi, (char *)data)) goto free_sb_buf; /* sanity checking of raw super */ - if (sanity_check_raw_super(sb, raw_super)) { - f2fs_msg(sb, KERN_ERR, "Can't find a valid F2FS filesystem"); + if (sanity_check_raw_super(raw_super)) goto free_sb_buf; - } sb->s_maxbytes = max_file_size(le32_to_cpu(raw_super->log_blocksize)); sb->s_max_links = F2FS_LINK_MAX; @@ -512,23 +477,18 @@ static int f2fs_fill_super(struct super_block *sb, void *data, int silent) /* get an inode for meta space */ sbi->meta_inode = f2fs_iget(sb, F2FS_META_INO(sbi)); if (IS_ERR(sbi->meta_inode)) { - f2fs_msg(sb, KERN_ERR, "Failed to read F2FS meta data inode"); err = PTR_ERR(sbi->meta_inode); goto free_sb_buf; } err = get_valid_checkpoint(sbi); - if (err) { - f2fs_msg(sb, KERN_ERR, "Failed to get valid F2FS checkpoint"); + if (err) goto free_meta_inode; - } /* sanity checking of checkpoint */ err = -EINVAL; - if (sanity_check_ckpt(raw_super, sbi->ckpt)) { - f2fs_msg(sb, KERN_ERR, "Invalid F2FS checkpoint"); + if (sanity_check_ckpt(raw_super, sbi->ckpt)) goto free_cp; - } sbi->total_valid_node_count = le32_to_cpu(sbi->ckpt->valid_node_count); @@ -542,28 +502,25 @@ static int f2fs_fill_super(struct super_block *sb, void *data, int silent) INIT_LIST_HEAD(&sbi->dir_inode_list); spin_lock_init(&sbi->dir_inode_lock); + /* init super block */ + if (!sb_set_blocksize(sb, sbi->blocksize)) + goto free_cp; + init_orphan_info(sbi); /* setup f2fs internal modules */ err = build_segment_manager(sbi); - if (err) { - f2fs_msg(sb, KERN_ERR, - "Failed to initialize F2FS segment manager"); + if (err) goto free_sm; - } err = build_node_manager(sbi); - if (err) { - f2fs_msg(sb, KERN_ERR, - "Failed to initialize F2FS node manager"); + if (err) goto free_nm; - } build_gc_manager(sbi); /* get an inode for node space */ sbi->node_inode = f2fs_iget(sb, F2FS_NODE_INO(sbi)); if (IS_ERR(sbi->node_inode)) { - f2fs_msg(sb, KERN_ERR, "Failed to read node inode"); err = PTR_ERR(sbi->node_inode); goto free_nm; } @@ -576,7 +533,6 @@ static int f2fs_fill_super(struct super_block *sb, void *data, int silent) /* read root inode and dentry */ root = f2fs_iget(sb, F2FS_ROOT_INO(sbi)); if (IS_ERR(root)) { - f2fs_msg(sb, KERN_ERR, "Failed to read root inode"); err = PTR_ERR(root); goto free_node_inode; } @@ -640,7 +596,7 @@ static struct file_system_type f2fs_fs_type = { .fs_flags = FS_REQUIRES_DEV, }; -static int __init init_inodecache(void) +static int init_inodecache(void) { f2fs_inode_cachep = f2fs_kmem_cache_create("f2fs_inode_cache", sizeof(struct f2fs_inode_info), NULL); @@ -675,17 +631,14 @@ static int __init init_f2fs_fs(void) err = create_checkpoint_caches(); if (err) goto fail; - err = register_filesystem(&f2fs_fs_type); - if (err) - goto fail; - f2fs_create_root_stats(); + return register_filesystem(&f2fs_fs_type); fail: return err; } static void __exit exit_f2fs_fs(void) { - f2fs_destroy_root_stats(); + destroy_root_stats(); unregister_filesystem(&f2fs_fs_type); destroy_checkpoint_caches(); destroy_gc_caches(); diff --git a/trunk/fs/f2fs/xattr.c b/trunk/fs/f2fs/xattr.c index 8038c0496504..940136a3d3a6 100644 --- a/trunk/fs/f2fs/xattr.c +++ b/trunk/fs/f2fs/xattr.c @@ -318,8 +318,6 @@ int f2fs_setxattr(struct inode *inode, int name_index, const char *name, if (name_len > 255 || value_len > MAX_VALUE_LEN) return -ERANGE; - f2fs_balance_fs(sbi); - mutex_lock_op(sbi, NODE_NEW); if (!fi->i_xattr_nid) { /* Allocate new attribute block */ diff --git a/trunk/fs/fuse/Kconfig b/trunk/fs/fuse/Kconfig index 1b2f6c2c3aaf..0cf160a94eda 100644 --- a/trunk/fs/fuse/Kconfig +++ b/trunk/fs/fuse/Kconfig @@ -4,24 +4,12 @@ config FUSE_FS With FUSE it is possible to implement a fully functional filesystem in a userspace program. - There's also a companion library: libfuse2. This library is available - from the FUSE homepage: + There's also companion library: libfuse. This library along with + utilities is available from the FUSE homepage: - although chances are your distribution already has that library - installed if you've installed the "fuse" package itself. See for more information. See for needed library/utility version. If you want to develop a userspace FS, or if you want to use a filesystem based on FUSE, answer Y or M. - -config CUSE - tristate "Character device in Userspace support" - depends on FUSE_FS - help - This FUSE extension allows character devices to be - implemented in userspace. - - If you want to develop or use a userspace character device - based on CUSE, answer Y or M. diff --git a/trunk/fs/fuse/cuse.c b/trunk/fs/fuse/cuse.c index e397b675b029..ee8d55042298 100644 --- a/trunk/fs/fuse/cuse.c +++ b/trunk/fs/fuse/cuse.c @@ -45,6 +45,7 @@ #include #include #include +#include #include #include @@ -62,7 +63,7 @@ struct cuse_conn { bool unrestricted_ioctl; }; -static DEFINE_MUTEX(cuse_lock); /* protects registration */ +static DEFINE_SPINLOCK(cuse_lock); /* protects cuse_conntbl */ static struct list_head cuse_conntbl[CUSE_CONNTBL_LEN]; static struct class *cuse_class; @@ -113,14 +114,14 @@ static int cuse_open(struct inode *inode, struct file *file) int rc; /* look up and get the connection */ - mutex_lock(&cuse_lock); + spin_lock(&cuse_lock); list_for_each_entry(pos, cuse_conntbl_head(devt), list) if (pos->dev->devt == devt) { fuse_conn_get(&pos->fc); cc = pos; break; } - mutex_unlock(&cuse_lock); + spin_unlock(&cuse_lock); /* dead? */ if (!cc) @@ -266,7 +267,7 @@ static int cuse_parse_one(char **pp, char *end, char **keyp, char **valp) static int cuse_parse_devinfo(char *p, size_t len, struct cuse_devinfo *devinfo) { char *end = p + len; - char *uninitialized_var(key), *uninitialized_var(val); + char *key, *val; int rc; while (true) { @@ -304,14 +305,14 @@ static void cuse_gendev_release(struct device *dev) */ static void cuse_process_init_reply(struct fuse_conn *fc, struct fuse_req *req) { - struct cuse_conn *cc = fc_to_cc(fc), *pos; + struct cuse_conn *cc = fc_to_cc(fc); struct cuse_init_out *arg = req->out.args[0].value; struct page *page = req->pages[0]; struct cuse_devinfo devinfo = { }; struct device *dev; struct cdev *cdev; dev_t devt; - int rc, i; + int rc; if (req->out.h.error || arg->major != FUSE_KERNEL_VERSION || arg->minor < 11) { @@ -355,24 +356,15 @@ static void cuse_process_init_reply(struct fuse_conn *fc, struct fuse_req *req) dev_set_drvdata(dev, cc); dev_set_name(dev, "%s", devinfo.name); - mutex_lock(&cuse_lock); - - /* make sure the device-name is unique */ - for (i = 0; i < CUSE_CONNTBL_LEN; ++i) { - list_for_each_entry(pos, &cuse_conntbl[i], list) - if (!strcmp(dev_name(pos->dev), dev_name(dev))) - goto err_unlock; - } - rc = device_add(dev); if (rc) - goto err_unlock; + goto err_device; /* register cdev */ rc = -ENOMEM; cdev = cdev_alloc(); if (!cdev) - goto err_unlock; + goto err_device; cdev->owner = THIS_MODULE; cdev->ops = &cuse_frontend_fops; @@ -385,8 +377,9 @@ static void cuse_process_init_reply(struct fuse_conn *fc, struct fuse_req *req) cc->cdev = cdev; /* make the device available */ + spin_lock(&cuse_lock); list_add(&cc->list, cuse_conntbl_head(devt)); - mutex_unlock(&cuse_lock); + spin_unlock(&cuse_lock); /* announce device availability */ dev_set_uevent_suppress(dev, 0); @@ -398,8 +391,7 @@ static void cuse_process_init_reply(struct fuse_conn *fc, struct fuse_req *req) err_cdev: cdev_del(cdev); -err_unlock: - mutex_unlock(&cuse_lock); +err_device: put_device(dev); err_region: unregister_chrdev_region(devt, 1); @@ -528,9 +520,9 @@ static int cuse_channel_release(struct inode *inode, struct file *file) int rc; /* remove from the conntbl, no more access from this point on */ - mutex_lock(&cuse_lock); + spin_lock(&cuse_lock); list_del_init(&cc->list); - mutex_unlock(&cuse_lock); + spin_unlock(&cuse_lock); /* remove device */ if (cc->dev) diff --git a/trunk/fs/fuse/dev.c b/trunk/fs/fuse/dev.c index e83351aa5bad..c16335315e5d 100644 --- a/trunk/fs/fuse/dev.c +++ b/trunk/fs/fuse/dev.c @@ -692,6 +692,8 @@ static int fuse_try_move_page(struct fuse_copy_state *cs, struct page **pagep) struct page *oldpage = *pagep; struct page *newpage; struct pipe_buffer *buf = cs->pipebufs; + struct address_space *mapping; + pgoff_t index; unlock_request(cs->fc, cs->req); fuse_copy_finish(cs); @@ -722,6 +724,9 @@ static int fuse_try_move_page(struct fuse_copy_state *cs, struct page **pagep) if (fuse_check_page(newpage) != 0) goto out_fallback_unlock; + mapping = oldpage->mapping; + index = oldpage->index; + /* * This is a new and locked page, it shouldn't be mapped or * have any special flags on it diff --git a/trunk/fs/fuse/file.c b/trunk/fs/fuse/file.c index f3ab824fa302..e21d4d8f87e3 100644 --- a/trunk/fs/fuse/file.c +++ b/trunk/fs/fuse/file.c @@ -2177,8 +2177,8 @@ fuse_direct_IO(int rw, struct kiocb *iocb, const struct iovec *iov, return ret; } -static long fuse_file_fallocate(struct file *file, int mode, loff_t offset, - loff_t length) +long fuse_file_fallocate(struct file *file, int mode, loff_t offset, + loff_t length) { struct fuse_file *ff = file->private_data; struct fuse_conn *fc = ff->fc; @@ -2213,6 +2213,7 @@ static long fuse_file_fallocate(struct file *file, int mode, loff_t offset, return err; } +EXPORT_SYMBOL_GPL(fuse_file_fallocate); static const struct file_operations fuse_file_operations = { .llseek = fuse_file_llseek, diff --git a/trunk/include/asm-generic/dma-mapping-broken.h b/trunk/include/asm-generic/dma-mapping-broken.h index 6c32af918c2f..ccf7b4f34a3c 100644 --- a/trunk/include/asm-generic/dma-mapping-broken.h +++ b/trunk/include/asm-generic/dma-mapping-broken.h @@ -16,22 +16,6 @@ extern void dma_free_coherent(struct device *dev, size_t size, void *cpu_addr, dma_addr_t dma_handle); -static inline void *dma_alloc_attrs(struct device *dev, size_t size, - dma_addr_t *dma_handle, gfp_t flag, - struct dma_attrs *attrs) -{ - /* attrs is not supported and ignored */ - return dma_alloc_coherent(dev, size, dma_handle, flag); -} - -static inline void dma_free_attrs(struct device *dev, size_t size, - void *cpu_addr, dma_addr_t dma_handle, - struct dma_attrs *attrs) -{ - /* attrs is not supported and ignored */ - dma_free_coherent(dev, size, cpu_addr, dma_handle); -} - #define dma_alloc_noncoherent(d, s, h, f) dma_alloc_coherent(d, s, h, f) #define dma_free_noncoherent(d, s, v, h) dma_free_coherent(d, s, v, h) diff --git a/trunk/include/linux/ata.h b/trunk/include/linux/ata.h index 8f7a3d68371a..408da9502177 100644 --- a/trunk/include/linux/ata.h +++ b/trunk/include/linux/ata.h @@ -297,12 +297,10 @@ enum { ATA_LOG_SATA_NCQ = 0x10, ATA_LOG_SATA_ID_DEV_DATA = 0x30, ATA_LOG_SATA_SETTINGS = 0x08, - ATA_LOG_DEVSLP_OFFSET = 0x30, - ATA_LOG_DEVSLP_SIZE = 0x08, - ATA_LOG_DEVSLP_MDAT = 0x00, + ATA_LOG_DEVSLP_MDAT = 0x30, ATA_LOG_DEVSLP_MDAT_MASK = 0x1F, - ATA_LOG_DEVSLP_DETO = 0x01, - ATA_LOG_DEVSLP_VALID = 0x07, + ATA_LOG_DEVSLP_DETO = 0x31, + ATA_LOG_DEVSLP_VALID = 0x37, ATA_LOG_DEVSLP_VALID_MASK = 0x80, /* READ/WRITE LONG (obsolete) */ diff --git a/trunk/include/linux/libata.h b/trunk/include/linux/libata.h index 649e5f86b5f0..83ba0ab2c915 100644 --- a/trunk/include/linux/libata.h +++ b/trunk/include/linux/libata.h @@ -652,8 +652,8 @@ struct ata_device { u32 gscr[SATA_PMP_GSCR_DWORDS]; /* PMP GSCR block */ }; - /* DEVSLP Timing Variables from Identify Device Data Log */ - u8 devslp_timing[ATA_LOG_DEVSLP_SIZE]; + /* Identify Device Data Log (30h), SATA Settings (page 08h) */ + u8 sata_settings[ATA_SECT_SIZE]; /* error history */ int spdn_cnt; diff --git a/trunk/include/linux/sched.h b/trunk/include/linux/sched.h index d2112477ff5e..6fc8f45de4e9 100644 --- a/trunk/include/linux/sched.h +++ b/trunk/include/linux/sched.h @@ -2714,16 +2714,7 @@ static inline void thread_group_cputime_init(struct signal_struct *sig) extern void recalc_sigpending_and_wake(struct task_struct *t); extern void recalc_sigpending(void); -extern void signal_wake_up_state(struct task_struct *t, unsigned int state); - -static inline void signal_wake_up(struct task_struct *t, bool resume) -{ - signal_wake_up_state(t, resume ? TASK_WAKEKILL : 0); -} -static inline void ptrace_signal_wake_up(struct task_struct *t, bool resume) -{ - signal_wake_up_state(t, resume ? __TASK_TRACED : 0); -} +extern void signal_wake_up(struct task_struct *t, int resume_stopped); /* * Wrappers for p->thread_info->cpu access. No-op on UP. diff --git a/trunk/kernel/async.c b/trunk/kernel/async.c index 6f34904a0b53..a1d585c351d6 100644 --- a/trunk/kernel/async.c +++ b/trunk/kernel/async.c @@ -86,27 +86,18 @@ static atomic_t entry_count; */ static async_cookie_t __lowest_in_progress(struct async_domain *running) { - async_cookie_t first_running = next_cookie; /* infinity value */ - async_cookie_t first_pending = next_cookie; /* ditto */ struct async_entry *entry; - /* - * Both running and pending lists are sorted but not disjoint. - * Take the first cookies from both and return the min. - */ if (!list_empty(&running->domain)) { entry = list_first_entry(&running->domain, typeof(*entry), list); - first_running = entry->cookie; + return entry->cookie; } - list_for_each_entry(entry, &async_pending, list) { - if (entry->running == running) { - first_pending = entry->cookie; - break; - } - } + list_for_each_entry(entry, &async_pending, list) + if (entry->running == running) + return entry->cookie; - return min(first_running, first_pending); + return next_cookie; /* "infinity" value */ } static async_cookie_t lowest_in_progress(struct async_domain *running) @@ -127,17 +118,13 @@ static void async_run_entry_fn(struct work_struct *work) { struct async_entry *entry = container_of(work, struct async_entry, work); - struct async_entry *pos; unsigned long flags; ktime_t uninitialized_var(calltime), delta, rettime; struct async_domain *running = entry->running; - /* 1) move self to the running queue, make sure it stays sorted */ + /* 1) move self to the running queue */ spin_lock_irqsave(&async_lock, flags); - list_for_each_entry_reverse(pos, &running->domain, list) - if (entry->cookie < pos->cookie) - break; - list_move_tail(&entry->list, &pos->list); + list_move_tail(&entry->list, &running->domain); spin_unlock_irqrestore(&async_lock, flags); /* 2) run (and print duration) */ diff --git a/trunk/kernel/ptrace.c b/trunk/kernel/ptrace.c index 6cbeaae4406d..612a56126851 100644 --- a/trunk/kernel/ptrace.c +++ b/trunk/kernel/ptrace.c @@ -117,45 +117,11 @@ void __ptrace_unlink(struct task_struct *child) * TASK_KILLABLE sleeps. */ if (child->jobctl & JOBCTL_STOP_PENDING || task_is_traced(child)) - ptrace_signal_wake_up(child, true); + signal_wake_up(child, task_is_traced(child)); spin_unlock(&child->sighand->siglock); } -/* Ensure that nothing can wake it up, even SIGKILL */ -static bool ptrace_freeze_traced(struct task_struct *task) -{ - bool ret = false; - - /* Lockless, nobody but us can set this flag */ - if (task->jobctl & JOBCTL_LISTENING) - return ret; - - spin_lock_irq(&task->sighand->siglock); - if (task_is_traced(task) && !__fatal_signal_pending(task)) { - task->state = __TASK_TRACED; - ret = true; - } - spin_unlock_irq(&task->sighand->siglock); - - return ret; -} - -static void ptrace_unfreeze_traced(struct task_struct *task) -{ - if (task->state != __TASK_TRACED) - return; - - WARN_ON(!task->ptrace || task->parent != current); - - spin_lock_irq(&task->sighand->siglock); - if (__fatal_signal_pending(task)) - wake_up_state(task, __TASK_TRACED); - else - task->state = TASK_TRACED; - spin_unlock_irq(&task->sighand->siglock); -} - /** * ptrace_check_attach - check whether ptracee is ready for ptrace operation * @child: ptracee to check for @@ -185,29 +151,24 @@ static int ptrace_check_attach(struct task_struct *child, bool ignore_state) * be changed by us so it's not changing right after this. */ read_lock(&tasklist_lock); - if (child->ptrace && child->parent == current) { - WARN_ON(child->state == __TASK_TRACED); + if ((child->ptrace & PT_PTRACED) && child->parent == current) { /* * child->sighand can't be NULL, release_task() * does ptrace_unlink() before __exit_signal(). */ - if (ignore_state || ptrace_freeze_traced(child)) + spin_lock_irq(&child->sighand->siglock); + WARN_ON_ONCE(task_is_stopped(child)); + if (ignore_state || (task_is_traced(child) && + !(child->jobctl & JOBCTL_LISTENING))) ret = 0; + spin_unlock_irq(&child->sighand->siglock); } read_unlock(&tasklist_lock); - if (!ret && !ignore_state) { - if (!wait_task_inactive(child, __TASK_TRACED)) { - /* - * This can only happen if may_ptrace_stop() fails and - * ptrace_stop() changes ->state back to TASK_RUNNING, - * so we should not worry about leaking __TASK_TRACED. - */ - WARN_ON(child->state == __TASK_TRACED); - ret = -ESRCH; - } - } + if (!ret && !ignore_state) + ret = wait_task_inactive(child, TASK_TRACED) ? 0 : -ESRCH; + /* All systems go.. */ return ret; } @@ -356,7 +317,7 @@ static int ptrace_attach(struct task_struct *task, long request, */ if (task_is_stopped(task) && task_set_jobctl_pending(task, JOBCTL_TRAP_STOP | JOBCTL_TRAPPING)) - signal_wake_up_state(task, __TASK_STOPPED); + signal_wake_up(task, 1); spin_unlock(&task->sighand->siglock); @@ -776,7 +737,7 @@ int ptrace_request(struct task_struct *child, long request, * tracee into STOP. */ if (likely(task_set_jobctl_pending(child, JOBCTL_TRAP_STOP))) - ptrace_signal_wake_up(child, child->jobctl & JOBCTL_LISTENING); + signal_wake_up(child, child->jobctl & JOBCTL_LISTENING); unlock_task_sighand(child, &flags); ret = 0; @@ -802,7 +763,7 @@ int ptrace_request(struct task_struct *child, long request, * start of this trap and now. Trigger re-trap. */ if (child->jobctl & JOBCTL_TRAP_NOTIFY) - ptrace_signal_wake_up(child, true); + signal_wake_up(child, true); ret = 0; } unlock_task_sighand(child, &flags); @@ -939,8 +900,6 @@ SYSCALL_DEFINE4(ptrace, long, request, long, pid, unsigned long, addr, goto out_put_task_struct; ret = arch_ptrace(child, request, addr, data); - if (ret || request != PTRACE_DETACH) - ptrace_unfreeze_traced(child); out_put_task_struct: put_task_struct(child); @@ -1080,11 +1039,8 @@ asmlinkage long compat_sys_ptrace(compat_long_t request, compat_long_t pid, ret = ptrace_check_attach(child, request == PTRACE_KILL || request == PTRACE_INTERRUPT); - if (!ret) { + if (!ret) ret = compat_arch_ptrace(child, request, addr, data); - if (ret || request != PTRACE_DETACH) - ptrace_unfreeze_traced(child); - } out_put_task_struct: put_task_struct(child); diff --git a/trunk/kernel/sched/core.c b/trunk/kernel/sched/core.c index 26058d0bebba..257002c13bb0 100644 --- a/trunk/kernel/sched/core.c +++ b/trunk/kernel/sched/core.c @@ -1523,8 +1523,7 @@ static void try_to_wake_up_local(struct task_struct *p) */ int wake_up_process(struct task_struct *p) { - WARN_ON(task_is_stopped_or_traced(p)); - return try_to_wake_up(p, TASK_NORMAL, 0); + return try_to_wake_up(p, TASK_ALL, 0); } EXPORT_SYMBOL(wake_up_process); diff --git a/trunk/kernel/signal.c b/trunk/kernel/signal.c index 3d09cf6cde75..53cd5c4d1172 100644 --- a/trunk/kernel/signal.c +++ b/trunk/kernel/signal.c @@ -680,17 +680,23 @@ int dequeue_signal(struct task_struct *tsk, sigset_t *mask, siginfo_t *info) * No need to set need_resched since signal event passing * goes through ->blocked */ -void signal_wake_up_state(struct task_struct *t, unsigned int state) +void signal_wake_up(struct task_struct *t, int resume) { + unsigned int mask; + set_tsk_thread_flag(t, TIF_SIGPENDING); + /* - * TASK_WAKEKILL also means wake it up in the stopped/traced/killable + * For SIGKILL, we want to wake it up in the stopped/traced/killable * case. We don't check t->state here because there is a race with it * executing another processor and just now entering stopped state. * By using wake_up_state, we ensure the process will wake up and * handle its death signal. */ - if (!wake_up_state(t, state | TASK_INTERRUPTIBLE)) + mask = TASK_INTERRUPTIBLE; + if (resume) + mask |= TASK_WAKEKILL; + if (!wake_up_state(t, mask)) kick_process(t); } @@ -838,7 +844,7 @@ static void ptrace_trap_notify(struct task_struct *t) assert_spin_locked(&t->sighand->siglock); task_set_jobctl_pending(t, JOBCTL_TRAP_NOTIFY); - ptrace_signal_wake_up(t, t->jobctl & JOBCTL_LISTENING); + signal_wake_up(t, t->jobctl & JOBCTL_LISTENING); } /* @@ -1794,10 +1800,6 @@ static inline int may_ptrace_stop(void) * If SIGKILL was already sent before the caller unlocked * ->siglock we must see ->core_state != NULL. Otherwise it * is safe to enter schedule(). - * - * This is almost outdated, a task with the pending SIGKILL can't - * block in TASK_TRACED. But PTRACE_EVENT_EXIT can be reported - * after SIGKILL was already dequeued. */ if (unlikely(current->mm->core_state) && unlikely(current->mm == current->parent->mm)) @@ -1923,7 +1925,6 @@ static void ptrace_stop(int exit_code, int why, int clear_code, siginfo_t *info) if (gstop_done) do_notify_parent_cldstop(current, false, why); - /* tasklist protects us from ptrace_freeze_traced() */ __set_current_state(TASK_RUNNING); if (clear_code) current->exit_code = 0; diff --git a/trunk/kernel/trace/ftrace.c b/trunk/kernel/trace/ftrace.c index 41473b4ad7a4..3ffe4c5ad3f3 100644 --- a/trunk/kernel/trace/ftrace.c +++ b/trunk/kernel/trace/ftrace.c @@ -3998,7 +3998,7 @@ static int ftrace_module_notify(struct notifier_block *self, struct notifier_block ftrace_module_nb = { .notifier_call = ftrace_module_notify, - .priority = INT_MAX, /* Run before anything that can use kprobes */ + .priority = 0, }; extern unsigned long __start_mcount_loc[]; diff --git a/trunk/security/device_cgroup.c b/trunk/security/device_cgroup.c index d794abcc4b3b..19ecc8de9e6b 100644 --- a/trunk/security/device_cgroup.c +++ b/trunk/security/device_cgroup.c @@ -215,9 +215,7 @@ static void devcgroup_css_free(struct cgroup *cgroup) struct dev_cgroup *dev_cgroup; dev_cgroup = cgroup_to_devcgroup(cgroup); - mutex_lock(&devcgroup_mutex); dev_exception_clean(dev_cgroup); - mutex_unlock(&devcgroup_mutex); kfree(dev_cgroup); } diff --git a/trunk/security/integrity/evm/evm_crypto.c b/trunk/security/integrity/evm/evm_crypto.c index 7dd538ef5b83..dfb26918699c 100644 --- a/trunk/security/integrity/evm/evm_crypto.c +++ b/trunk/security/integrity/evm/evm_crypto.c @@ -205,9 +205,9 @@ int evm_update_evmxattr(struct dentry *dentry, const char *xattr_name, rc = __vfs_setxattr_noperm(dentry, XATTR_NAME_EVM, &xattr_data, sizeof(xattr_data), 0); - } else if (rc == -ENODATA && inode->i_op->removexattr) { - rc = inode->i_op->removexattr(dentry, XATTR_NAME_EVM); } + else if (rc == -ENODATA) + rc = inode->i_op->removexattr(dentry, XATTR_NAME_EVM); return rc; } diff --git a/trunk/sound/pci/hda/hda_codec.c b/trunk/sound/pci/hda/hda_codec.c index 822df971972c..b8fb0a5adb9b 100644 --- a/trunk/sound/pci/hda/hda_codec.c +++ b/trunk/sound/pci/hda/hda_codec.c @@ -3654,7 +3654,6 @@ static void hda_call_codec_resume(struct hda_codec *codec) hda_set_power_state(codec, AC_PWRST_D0); restore_shutup_pins(codec); hda_exec_init_verbs(codec); - snd_hda_jack_set_dirty_all(codec); if (codec->patch_ops.resume) codec->patch_ops.resume(codec); else { @@ -3666,8 +3665,10 @@ static void hda_call_codec_resume(struct hda_codec *codec) if (codec->jackpoll_interval) hda_jackpoll_work(&codec->jackpoll_work.work); - else + else { + snd_hda_jack_set_dirty_all(codec); snd_hda_jack_report_sync(codec); + } codec->in_pm = 0; snd_hda_power_down(codec); /* flag down before returning */ diff --git a/trunk/sound/pci/hda/patch_conexant.c b/trunk/sound/pci/hda/patch_conexant.c index 009b77a693cf..dd798c3196ff 100644 --- a/trunk/sound/pci/hda/patch_conexant.c +++ b/trunk/sound/pci/hda/patch_conexant.c @@ -4636,12 +4636,6 @@ static const struct hda_codec_preset snd_hda_preset_conexant[] = { .patch = patch_conexant_auto }, { .id = 0x14f15111, .name = "CX20753/4", .patch = patch_conexant_auto }, - { .id = 0x14f15113, .name = "CX20755", - .patch = patch_conexant_auto }, - { .id = 0x14f15114, .name = "CX20756", - .patch = patch_conexant_auto }, - { .id = 0x14f15115, .name = "CX20757", - .patch = patch_conexant_auto }, {} /* terminator */ }; @@ -4665,9 +4659,6 @@ MODULE_ALIAS("snd-hda-codec-id:14f150b9"); MODULE_ALIAS("snd-hda-codec-id:14f1510f"); MODULE_ALIAS("snd-hda-codec-id:14f15110"); MODULE_ALIAS("snd-hda-codec-id:14f15111"); -MODULE_ALIAS("snd-hda-codec-id:14f15113"); -MODULE_ALIAS("snd-hda-codec-id:14f15114"); -MODULE_ALIAS("snd-hda-codec-id:14f15115"); MODULE_LICENSE("GPL"); MODULE_DESCRIPTION("Conexant HD-audio codec"); diff --git a/trunk/sound/pci/hda/patch_realtek.c b/trunk/sound/pci/hda/patch_realtek.c index cf3886171109..f5196277b6e9 100644 --- a/trunk/sound/pci/hda/patch_realtek.c +++ b/trunk/sound/pci/hda/patch_realtek.c @@ -6251,7 +6251,6 @@ static const struct snd_pci_quirk alc269_fixup_tbl[] = { SND_PCI_QUIRK(0x1025, 0x0349, "Acer AOD260", ALC269_FIXUP_INV_DMIC), SND_PCI_QUIRK(0x103c, 0x1586, "HP", ALC269_FIXUP_MIC2_MUTE_LED), SND_PCI_QUIRK(0x103c, 0x1972, "HP Pavilion 17", ALC269_FIXUP_MIC1_MUTE_LED), - SND_PCI_QUIRK(0x103c, 0x1977, "HP Pavilion 14", ALC269_FIXUP_MIC1_MUTE_LED), SND_PCI_QUIRK(0x1043, 0x1427, "Asus Zenbook UX31E", ALC269VB_FIXUP_DMIC), SND_PCI_QUIRK(0x1043, 0x1517, "Asus Zenbook UX31A", ALC269VB_FIXUP_DMIC), SND_PCI_QUIRK(0x1043, 0x1a13, "Asus G73Jw", ALC269_FIXUP_ASUS_G73JW), @@ -6266,7 +6265,6 @@ static const struct snd_pci_quirk alc269_fixup_tbl[] = { SND_PCI_QUIRK(0x104d, 0x9084, "Sony VAIO", ALC275_FIXUP_SONY_HWEQ), SND_PCI_QUIRK_VENDOR(0x104d, "Sony VAIO", ALC269_FIXUP_SONY_VAIO), SND_PCI_QUIRK(0x1028, 0x0470, "Dell M101z", ALC269_FIXUP_DELL_M101Z), - SND_PCI_QUIRK(0x1025, 0x0740, "Acer AO725", ALC271_FIXUP_HP_GATE_MIC_JACK), SND_PCI_QUIRK(0x1025, 0x0742, "Acer AO756", ALC271_FIXUP_HP_GATE_MIC_JACK), SND_PCI_QUIRK_VENDOR(0x1025, "Acer Aspire", ALC271_FIXUP_DMIC), SND_PCI_QUIRK(0x10cf, 0x1475, "Lifebook", ALC269_FIXUP_LIFEBOOK), diff --git a/trunk/tools/perf/MANIFEST b/trunk/tools/perf/MANIFEST index 39d41068484f..80db3f4bcf7a 100644 --- a/trunk/tools/perf/MANIFEST +++ b/trunk/tools/perf/MANIFEST @@ -11,21 +11,11 @@ lib/rbtree.c include/linux/swab.h arch/*/include/asm/unistd*.h arch/*/include/asm/perf_regs.h -arch/*/include/uapi/asm/unistd*.h -arch/*/include/uapi/asm/perf_regs.h arch/*/lib/memcpy*.S arch/*/lib/memset*.S include/linux/poison.h include/linux/magic.h include/linux/hw_breakpoint.h -include/linux/rbtree_augmented.h -include/uapi/linux/perf_event.h -include/uapi/linux/const.h -include/uapi/linux/swab.h -include/uapi/linux/hw_breakpoint.h arch/x86/include/asm/svm.h arch/x86/include/asm/vmx.h arch/x86/include/asm/kvm_host.h -arch/x86/include/uapi/asm/svm.h -arch/x86/include/uapi/asm/vmx.h -arch/x86/include/uapi/asm/kvm.h diff --git a/trunk/tools/perf/Makefile b/trunk/tools/perf/Makefile index 8ab05e543ef4..891bc77bdb2c 100644 --- a/trunk/tools/perf/Makefile +++ b/trunk/tools/perf/Makefile @@ -58,7 +58,7 @@ ARCH ?= $(shell echo $(uname_M) | sed -e s/i.86/i386/ -e s/sun4u/sparc64/ \ -e s/arm.*/arm/ -e s/sa110/arm/ \ -e s/s390x/s390/ -e s/parisc64/parisc/ \ -e s/ppc.*/powerpc/ -e s/mips.*/mips/ \ - -e s/sh[234].*/sh/ -e s/aarch64.*/arm64/ ) + -e s/sh[234].*/sh/ ) NO_PERF_REGS := 1 CC = $(CROSS_COMPILE)gcc