mirror of
https://github.com/Fishwaldo/build.git
synced 2025-03-26 00:31:47 +00:00
1716 lines
56 KiB
Diff
1716 lines
56 KiB
Diff
diff --git a/Makefile b/Makefile
|
|
index af0a40e..c156161 100644
|
|
--- a/Makefile
|
|
+++ b/Makefile
|
|
@@ -1,6 +1,6 @@
|
|
VERSION = 3
|
|
PATCHLEVEL = 4
|
|
-SUBLEVEL = 43
|
|
+SUBLEVEL = 44
|
|
EXTRAVERSION =
|
|
NAME = Saber-toothed Squirrel
|
|
|
|
diff --git a/arch/arm/configs/at91sam9g45_defconfig b/arch/arm/configs/at91sam9g45_defconfig
|
|
index 606d48f..8aab786 100644
|
|
--- a/arch/arm/configs/at91sam9g45_defconfig
|
|
+++ b/arch/arm/configs/at91sam9g45_defconfig
|
|
@@ -173,7 +173,6 @@ CONFIG_MMC=y
|
|
# CONFIG_MMC_BLOCK_BOUNCE is not set
|
|
CONFIG_SDIO_UART=m
|
|
CONFIG_MMC_ATMELMCI=y
|
|
-CONFIG_MMC_ATMELMCI_DMA=y
|
|
CONFIG_LEDS_ATMEL_PWM=y
|
|
CONFIG_LEDS_GPIO=y
|
|
CONFIG_LEDS_TRIGGER_TIMER=y
|
|
diff --git a/arch/arm/include/asm/pgtable.h b/arch/arm/include/asm/pgtable.h
|
|
index 41dc31f..cc5e50f 100644
|
|
--- a/arch/arm/include/asm/pgtable.h
|
|
+++ b/arch/arm/include/asm/pgtable.h
|
|
@@ -61,6 +61,15 @@ extern void __pgd_error(const char *file, int line, pgd_t);
|
|
#define FIRST_USER_ADDRESS PAGE_SIZE
|
|
|
|
/*
|
|
+ * Use TASK_SIZE as the ceiling argument for free_pgtables() and
|
|
+ * free_pgd_range() to avoid freeing the modules pmd when LPAE is enabled (pmd
|
|
+ * page shared between user and kernel).
|
|
+ */
|
|
+#ifdef CONFIG_ARM_LPAE
|
|
+#define USER_PGTABLES_CEILING TASK_SIZE
|
|
+#endif
|
|
+
|
|
+/*
|
|
* The pgprot_* and protection_map entries will be fixed up in runtime
|
|
* to include the cachable and bufferable bits based on memory policy,
|
|
* as well as any architecture dependent bits like global/ASID and SMP
|
|
diff --git a/arch/arm/mach-at91/setup.c b/arch/arm/mach-at91/setup.c
|
|
index 55293a7..5db5174 100644
|
|
--- a/arch/arm/mach-at91/setup.c
|
|
+++ b/arch/arm/mach-at91/setup.c
|
|
@@ -326,7 +326,7 @@ static void at91_dt_rstc(void)
|
|
|
|
of_id = of_match_node(rstc_ids, np);
|
|
if (!of_id)
|
|
- panic("AT91: rtsc no restart function availlable\n");
|
|
+ panic("AT91: rtsc no restart function available\n");
|
|
|
|
arm_pm_restart = of_id->data;
|
|
|
|
diff --git a/arch/avr32/configs/favr-32_defconfig b/arch/avr32/configs/favr-32_defconfig
|
|
index 19973b0..59e4cc9 100644
|
|
--- a/arch/avr32/configs/favr-32_defconfig
|
|
+++ b/arch/avr32/configs/favr-32_defconfig
|
|
@@ -122,7 +122,6 @@ CONFIG_USB_G_SERIAL=m
|
|
CONFIG_USB_CDC_COMPOSITE=m
|
|
CONFIG_MMC=y
|
|
CONFIG_MMC_ATMELMCI=y
|
|
-CONFIG_MMC_ATMELMCI_DMA=y
|
|
CONFIG_NEW_LEDS=y
|
|
CONFIG_LEDS_CLASS=y
|
|
CONFIG_LEDS_ATMEL_PWM=m
|
|
diff --git a/arch/avr32/configs/merisc_defconfig b/arch/avr32/configs/merisc_defconfig
|
|
index 3befab9..65de443 100644
|
|
--- a/arch/avr32/configs/merisc_defconfig
|
|
+++ b/arch/avr32/configs/merisc_defconfig
|
|
@@ -102,7 +102,6 @@ CONFIG_FRAMEBUFFER_CONSOLE=y
|
|
CONFIG_LOGO=y
|
|
CONFIG_MMC=y
|
|
CONFIG_MMC_ATMELMCI=y
|
|
-CONFIG_MMC_ATMELMCI_DMA=y
|
|
CONFIG_NEW_LEDS=y
|
|
CONFIG_LEDS_CLASS=y
|
|
CONFIG_LEDS_ATMEL_PWM=y
|
|
diff --git a/arch/ia64/include/asm/futex.h b/arch/ia64/include/asm/futex.h
|
|
index d2bf1fd..76acbcd 100644
|
|
--- a/arch/ia64/include/asm/futex.h
|
|
+++ b/arch/ia64/include/asm/futex.h
|
|
@@ -106,16 +106,15 @@ futex_atomic_cmpxchg_inatomic(u32 *uval, u32 __user *uaddr,
|
|
return -EFAULT;
|
|
|
|
{
|
|
- register unsigned long r8 __asm ("r8");
|
|
+ register unsigned long r8 __asm ("r8") = 0;
|
|
unsigned long prev;
|
|
__asm__ __volatile__(
|
|
" mf;; \n"
|
|
- " mov %0=r0 \n"
|
|
" mov ar.ccv=%4;; \n"
|
|
"[1:] cmpxchg4.acq %1=[%2],%3,ar.ccv \n"
|
|
" .xdata4 \"__ex_table\", 1b-., 2f-. \n"
|
|
"[2:]"
|
|
- : "=r" (r8), "=r" (prev)
|
|
+ : "+r" (r8), "=&r" (prev)
|
|
: "r" (uaddr), "r" (newval),
|
|
"rO" ((long) (unsigned) oldval)
|
|
: "memory");
|
|
diff --git a/arch/ia64/include/asm/mca.h b/arch/ia64/include/asm/mca.h
|
|
index 43f96ab..8c70961 100644
|
|
--- a/arch/ia64/include/asm/mca.h
|
|
+++ b/arch/ia64/include/asm/mca.h
|
|
@@ -143,6 +143,7 @@ extern unsigned long __per_cpu_mca[NR_CPUS];
|
|
extern int cpe_vector;
|
|
extern int ia64_cpe_irq;
|
|
extern void ia64_mca_init(void);
|
|
+extern void ia64_mca_irq_init(void);
|
|
extern void ia64_mca_cpu_init(void *);
|
|
extern void ia64_os_mca_dispatch(void);
|
|
extern void ia64_os_mca_dispatch_end(void);
|
|
diff --git a/arch/ia64/kernel/irq.c b/arch/ia64/kernel/irq.c
|
|
index ad69606..f2c41828 100644
|
|
--- a/arch/ia64/kernel/irq.c
|
|
+++ b/arch/ia64/kernel/irq.c
|
|
@@ -23,6 +23,8 @@
|
|
#include <linux/interrupt.h>
|
|
#include <linux/kernel_stat.h>
|
|
|
|
+#include <asm/mca.h>
|
|
+
|
|
/*
|
|
* 'what should we do if we get a hw irq event on an illegal vector'.
|
|
* each architecture has to answer this themselves.
|
|
@@ -83,6 +85,12 @@ bool is_affinity_mask_valid(const struct cpumask *cpumask)
|
|
|
|
#endif /* CONFIG_SMP */
|
|
|
|
+int __init arch_early_irq_init(void)
|
|
+{
|
|
+ ia64_mca_irq_init();
|
|
+ return 0;
|
|
+}
|
|
+
|
|
#ifdef CONFIG_HOTPLUG_CPU
|
|
unsigned int vectors_in_migration[NR_IRQS];
|
|
|
|
diff --git a/arch/ia64/kernel/mca.c b/arch/ia64/kernel/mca.c
|
|
index 65bf9cd..d7396db 100644
|
|
--- a/arch/ia64/kernel/mca.c
|
|
+++ b/arch/ia64/kernel/mca.c
|
|
@@ -2074,22 +2074,16 @@ ia64_mca_init(void)
|
|
printk(KERN_INFO "MCA related initialization done\n");
|
|
}
|
|
|
|
+
|
|
/*
|
|
- * ia64_mca_late_init
|
|
- *
|
|
- * Opportunity to setup things that require initialization later
|
|
- * than ia64_mca_init. Setup a timer to poll for CPEs if the
|
|
- * platform doesn't support an interrupt driven mechanism.
|
|
- *
|
|
- * Inputs : None
|
|
- * Outputs : Status
|
|
+ * These pieces cannot be done in ia64_mca_init() because it is called before
|
|
+ * early_irq_init() which would wipe out our percpu irq registrations. But we
|
|
+ * cannot leave them until ia64_mca_late_init() because by then all the other
|
|
+ * processors have been brought online and have set their own CMC vectors to
|
|
+ * point at a non-existant action. Called from arch_early_irq_init().
|
|
*/
|
|
-static int __init
|
|
-ia64_mca_late_init(void)
|
|
+void __init ia64_mca_irq_init(void)
|
|
{
|
|
- if (!mca_init)
|
|
- return 0;
|
|
-
|
|
/*
|
|
* Configure the CMCI/P vector and handler. Interrupts for CMC are
|
|
* per-processor, so AP CMC interrupts are setup in smp_callin() (smpboot.c).
|
|
@@ -2108,6 +2102,23 @@ ia64_mca_late_init(void)
|
|
/* Setup the CPEI/P handler */
|
|
register_percpu_irq(IA64_CPEP_VECTOR, &mca_cpep_irqaction);
|
|
#endif
|
|
+}
|
|
+
|
|
+/*
|
|
+ * ia64_mca_late_init
|
|
+ *
|
|
+ * Opportunity to setup things that require initialization later
|
|
+ * than ia64_mca_init. Setup a timer to poll for CPEs if the
|
|
+ * platform doesn't support an interrupt driven mechanism.
|
|
+ *
|
|
+ * Inputs : None
|
|
+ * Outputs : Status
|
|
+ */
|
|
+static int __init
|
|
+ia64_mca_late_init(void)
|
|
+{
|
|
+ if (!mca_init)
|
|
+ return 0;
|
|
|
|
register_hotcpu_notifier(&mca_cpu_notifier);
|
|
|
|
diff --git a/arch/ia64/kvm/vtlb.c b/arch/ia64/kvm/vtlb.c
|
|
index 4332f7e..a7869f8 100644
|
|
--- a/arch/ia64/kvm/vtlb.c
|
|
+++ b/arch/ia64/kvm/vtlb.c
|
|
@@ -256,7 +256,7 @@ u64 guest_vhpt_lookup(u64 iha, u64 *pte)
|
|
"srlz.d;;"
|
|
"ssm psr.i;;"
|
|
"srlz.d;;"
|
|
- : "=r"(ret) : "r"(iha), "r"(pte):"memory");
|
|
+ : "=&r"(ret) : "r"(iha), "r"(pte) : "memory");
|
|
|
|
return ret;
|
|
}
|
|
diff --git a/arch/powerpc/kernel/head_64.S b/arch/powerpc/kernel/head_64.S
|
|
index 9e07bd0..1a3607b 100644
|
|
--- a/arch/powerpc/kernel/head_64.S
|
|
+++ b/arch/powerpc/kernel/head_64.S
|
|
@@ -489,6 +489,7 @@ _GLOBAL(copy_and_flush)
|
|
sync
|
|
addi r5,r5,8
|
|
addi r6,r6,8
|
|
+ isync
|
|
blr
|
|
|
|
.align 8
|
|
diff --git a/arch/powerpc/platforms/cell/spufs/inode.c b/arch/powerpc/platforms/cell/spufs/inode.c
|
|
index 1d75c92..ad697f8 100644
|
|
--- a/arch/powerpc/platforms/cell/spufs/inode.c
|
|
+++ b/arch/powerpc/platforms/cell/spufs/inode.c
|
|
@@ -99,6 +99,7 @@ spufs_new_inode(struct super_block *sb, umode_t mode)
|
|
if (!inode)
|
|
goto out;
|
|
|
|
+ inode->i_ino = get_next_ino();
|
|
inode->i_mode = mode;
|
|
inode->i_uid = current_fsuid();
|
|
inode->i_gid = current_fsgid();
|
|
diff --git a/arch/x86/kernel/irq.c b/arch/x86/kernel/irq.c
|
|
index 3dafc60..a14a835 100644
|
|
--- a/arch/x86/kernel/irq.c
|
|
+++ b/arch/x86/kernel/irq.c
|
|
@@ -165,10 +165,6 @@ u64 arch_irq_stat_cpu(unsigned int cpu)
|
|
u64 arch_irq_stat(void)
|
|
{
|
|
u64 sum = atomic_read(&irq_err_count);
|
|
-
|
|
-#ifdef CONFIG_X86_IO_APIC
|
|
- sum += atomic_read(&irq_mis_count);
|
|
-#endif
|
|
return sum;
|
|
}
|
|
|
|
diff --git a/arch/x86/kvm/emulate.c b/arch/x86/kvm/emulate.c
|
|
index 8375622..8c45818 100644
|
|
--- a/arch/x86/kvm/emulate.c
|
|
+++ b/arch/x86/kvm/emulate.c
|
|
@@ -3737,6 +3737,10 @@ static int decode_operand(struct x86_emulate_ctxt *ctxt, struct operand *op,
|
|
break;
|
|
case OpMem8:
|
|
ctxt->memop.bytes = 1;
|
|
+ if (ctxt->memop.type == OP_REG) {
|
|
+ ctxt->memop.addr.reg = decode_register(ctxt, ctxt->modrm_rm, 1);
|
|
+ fetch_register_operand(&ctxt->memop);
|
|
+ }
|
|
goto mem_common;
|
|
case OpMem16:
|
|
ctxt->memop.bytes = 2;
|
|
diff --git a/arch/x86/xen/enlighten.c b/arch/x86/xen/enlighten.c
|
|
index 194dbcd..2992678 100644
|
|
--- a/arch/x86/xen/enlighten.c
|
|
+++ b/arch/x86/xen/enlighten.c
|
|
@@ -1515,8 +1515,11 @@ static int __cpuinit xen_hvm_cpu_notify(struct notifier_block *self,
|
|
switch (action) {
|
|
case CPU_UP_PREPARE:
|
|
xen_vcpu_setup(cpu);
|
|
- if (xen_have_vector_callback)
|
|
+ if (xen_have_vector_callback) {
|
|
xen_init_lock_cpu(cpu);
|
|
+ if (xen_feature(XENFEAT_hvm_safe_pvclock))
|
|
+ xen_setup_timer(cpu);
|
|
+ }
|
|
break;
|
|
default:
|
|
break;
|
|
diff --git a/arch/x86/xen/time.c b/arch/x86/xen/time.c
|
|
index 0296a95..054cc01 100644
|
|
--- a/arch/x86/xen/time.c
|
|
+++ b/arch/x86/xen/time.c
|
|
@@ -497,7 +497,11 @@ static void xen_hvm_setup_cpu_clockevents(void)
|
|
{
|
|
int cpu = smp_processor_id();
|
|
xen_setup_runstate_info(cpu);
|
|
- xen_setup_timer(cpu);
|
|
+ /*
|
|
+ * xen_setup_timer(cpu) - snprintf is bad in atomic context. Hence
|
|
+ * doing it xen_hvm_cpu_notify (which gets called by smp_init during
|
|
+ * early bootup and also during CPU hotplug events).
|
|
+ */
|
|
xen_setup_cpu_clockevents();
|
|
}
|
|
|
|
diff --git a/drivers/acpi/pci_root.c b/drivers/acpi/pci_root.c
|
|
index 7aff631..5b0f075 100644
|
|
--- a/drivers/acpi/pci_root.c
|
|
+++ b/drivers/acpi/pci_root.c
|
|
@@ -247,8 +247,8 @@ static acpi_status acpi_pci_query_osc(struct acpi_pci_root *root,
|
|
*control &= OSC_PCI_CONTROL_MASKS;
|
|
capbuf[OSC_CONTROL_TYPE] = *control | root->osc_control_set;
|
|
} else {
|
|
- /* Run _OSC query for all possible controls. */
|
|
- capbuf[OSC_CONTROL_TYPE] = OSC_PCI_CONTROL_MASKS;
|
|
+ /* Run _OSC query only with existing controls. */
|
|
+ capbuf[OSC_CONTROL_TYPE] = root->osc_control_set;
|
|
}
|
|
|
|
status = acpi_pci_run_osc(root->device->handle, capbuf, &result);
|
|
diff --git a/drivers/i2c/busses/i2c-xiic.c b/drivers/i2c/busses/i2c-xiic.c
|
|
index 2bded76..d70106e 100644
|
|
--- a/drivers/i2c/busses/i2c-xiic.c
|
|
+++ b/drivers/i2c/busses/i2c-xiic.c
|
|
@@ -311,10 +311,8 @@ static void xiic_fill_tx_fifo(struct xiic_i2c *i2c)
|
|
/* last message in transfer -> STOP */
|
|
data |= XIIC_TX_DYN_STOP_MASK;
|
|
dev_dbg(i2c->adap.dev.parent, "%s TX STOP\n", __func__);
|
|
-
|
|
- xiic_setreg16(i2c, XIIC_DTR_REG_OFFSET, data);
|
|
- } else
|
|
- xiic_setreg8(i2c, XIIC_DTR_REG_OFFSET, data);
|
|
+ }
|
|
+ xiic_setreg16(i2c, XIIC_DTR_REG_OFFSET, data);
|
|
}
|
|
}
|
|
|
|
diff --git a/drivers/md/md.c b/drivers/md/md.c
|
|
index e0930bb..7b45b5e 100644
|
|
--- a/drivers/md/md.c
|
|
+++ b/drivers/md/md.c
|
|
@@ -1587,8 +1587,8 @@ static int super_1_load(struct md_rdev *rdev, struct md_rdev *refdev, int minor_
|
|
sector, count, 1) == 0)
|
|
return -EINVAL;
|
|
}
|
|
- } else if (sb->bblog_offset == 0)
|
|
- rdev->badblocks.shift = -1;
|
|
+ } else if (sb->bblog_offset != 0)
|
|
+ rdev->badblocks.shift = 0;
|
|
|
|
if (!refdev) {
|
|
ret = 1;
|
|
@@ -3107,7 +3107,7 @@ int md_rdev_init(struct md_rdev *rdev)
|
|
* be used - I wonder if that matters
|
|
*/
|
|
rdev->badblocks.count = 0;
|
|
- rdev->badblocks.shift = 0;
|
|
+ rdev->badblocks.shift = -1; /* disabled until explicitly enabled */
|
|
rdev->badblocks.page = kmalloc(PAGE_SIZE, GFP_KERNEL);
|
|
seqlock_init(&rdev->badblocks.lock);
|
|
if (rdev->badblocks.page == NULL)
|
|
@@ -3179,9 +3179,6 @@ static struct md_rdev *md_import_device(dev_t newdev, int super_format, int supe
|
|
goto abort_free;
|
|
}
|
|
}
|
|
- if (super_format == -1)
|
|
- /* hot-add for 0.90, or non-persistent: so no badblocks */
|
|
- rdev->badblocks.shift = -1;
|
|
|
|
return rdev;
|
|
|
|
diff --git a/drivers/mfd/adp5520.c b/drivers/mfd/adp5520.c
|
|
index 8d816cc..105f820 100644
|
|
--- a/drivers/mfd/adp5520.c
|
|
+++ b/drivers/mfd/adp5520.c
|
|
@@ -36,6 +36,7 @@ struct adp5520_chip {
|
|
struct blocking_notifier_head notifier_list;
|
|
int irq;
|
|
unsigned long id;
|
|
+ uint8_t mode;
|
|
};
|
|
|
|
static int __adp5520_read(struct i2c_client *client,
|
|
@@ -326,7 +327,10 @@ static int adp5520_suspend(struct device *dev)
|
|
struct i2c_client *client = to_i2c_client(dev);
|
|
struct adp5520_chip *chip = dev_get_drvdata(&client->dev);
|
|
|
|
- adp5520_clr_bits(chip->dev, ADP5520_MODE_STATUS, ADP5520_nSTNBY);
|
|
+ adp5520_read(chip->dev, ADP5520_MODE_STATUS, &chip->mode);
|
|
+ /* All other bits are W1C */
|
|
+ chip->mode &= ADP5520_BL_EN | ADP5520_DIM_EN | ADP5520_nSTNBY;
|
|
+ adp5520_write(chip->dev, ADP5520_MODE_STATUS, 0);
|
|
return 0;
|
|
}
|
|
|
|
@@ -335,7 +339,7 @@ static int adp5520_resume(struct device *dev)
|
|
struct i2c_client *client = to_i2c_client(dev);
|
|
struct adp5520_chip *chip = dev_get_drvdata(&client->dev);
|
|
|
|
- adp5520_set_bits(chip->dev, ADP5520_MODE_STATUS, ADP5520_nSTNBY);
|
|
+ adp5520_write(chip->dev, ADP5520_MODE_STATUS, chip->mode);
|
|
return 0;
|
|
}
|
|
#endif
|
|
diff --git a/drivers/mmc/core/mmc.c b/drivers/mmc/core/mmc.c
|
|
index 54df5ad..5352cd7 100644
|
|
--- a/drivers/mmc/core/mmc.c
|
|
+++ b/drivers/mmc/core/mmc.c
|
|
@@ -385,13 +385,13 @@ static int mmc_read_ext_csd(struct mmc_card *card, u8 *ext_csd)
|
|
ext_csd[EXT_CSD_SEC_FEATURE_SUPPORT];
|
|
card->ext_csd.raw_trim_mult =
|
|
ext_csd[EXT_CSD_TRIM_MULT];
|
|
+ card->ext_csd.raw_partition_support = ext_csd[EXT_CSD_PARTITION_SUPPORT];
|
|
if (card->ext_csd.rev >= 4) {
|
|
/*
|
|
* Enhanced area feature support -- check whether the eMMC
|
|
* card has the Enhanced area enabled. If so, export enhanced
|
|
* area offset and size to user by adding sysfs interface.
|
|
*/
|
|
- card->ext_csd.raw_partition_support = ext_csd[EXT_CSD_PARTITION_SUPPORT];
|
|
if ((ext_csd[EXT_CSD_PARTITION_SUPPORT] & 0x2) &&
|
|
(ext_csd[EXT_CSD_PARTITION_ATTRIBUTE] & 0x1)) {
|
|
hc_erase_grp_sz =
|
|
diff --git a/drivers/mmc/host/Kconfig b/drivers/mmc/host/Kconfig
|
|
index 2bc06e7..dbdd907 100644
|
|
--- a/drivers/mmc/host/Kconfig
|
|
+++ b/drivers/mmc/host/Kconfig
|
|
@@ -297,16 +297,6 @@ config MMC_ATMELMCI
|
|
|
|
endchoice
|
|
|
|
-config MMC_ATMELMCI_DMA
|
|
- bool "Atmel MCI DMA support"
|
|
- depends on MMC_ATMELMCI && (AVR32 || ARCH_AT91SAM9G45) && DMA_ENGINE
|
|
- help
|
|
- Say Y here to have the Atmel MCI driver use a DMA engine to
|
|
- do data transfers and thus increase the throughput and
|
|
- reduce the CPU utilization.
|
|
-
|
|
- If unsure, say N.
|
|
-
|
|
config MMC_IMX
|
|
tristate "Motorola i.MX Multimedia Card Interface support"
|
|
depends on ARCH_MX1
|
|
diff --git a/drivers/mmc/host/atmel-mci.c b/drivers/mmc/host/atmel-mci.c
|
|
index e94476b..2a822d9 100644
|
|
--- a/drivers/mmc/host/atmel-mci.c
|
|
+++ b/drivers/mmc/host/atmel-mci.c
|
|
@@ -165,6 +165,7 @@ struct atmel_mci {
|
|
void __iomem *regs;
|
|
|
|
struct scatterlist *sg;
|
|
+ unsigned int sg_len;
|
|
unsigned int pio_offset;
|
|
|
|
struct atmel_mci_slot *cur_slot;
|
|
@@ -754,6 +755,7 @@ static u32 atmci_prepare_data(struct atmel_mci *host, struct mmc_data *data)
|
|
data->error = -EINPROGRESS;
|
|
|
|
host->sg = data->sg;
|
|
+ host->sg_len = data->sg_len;
|
|
host->data = data;
|
|
host->data_chan = NULL;
|
|
|
|
@@ -1592,7 +1594,8 @@ static void atmci_read_data_pio(struct atmel_mci *host)
|
|
if (offset == sg->length) {
|
|
flush_dcache_page(sg_page(sg));
|
|
host->sg = sg = sg_next(sg);
|
|
- if (!sg)
|
|
+ host->sg_len--;
|
|
+ if (!sg || !host->sg_len)
|
|
goto done;
|
|
|
|
offset = 0;
|
|
@@ -1605,7 +1608,8 @@ static void atmci_read_data_pio(struct atmel_mci *host)
|
|
|
|
flush_dcache_page(sg_page(sg));
|
|
host->sg = sg = sg_next(sg);
|
|
- if (!sg)
|
|
+ host->sg_len--;
|
|
+ if (!sg || !host->sg_len)
|
|
goto done;
|
|
|
|
offset = 4 - remaining;
|
|
@@ -1659,7 +1663,8 @@ static void atmci_write_data_pio(struct atmel_mci *host)
|
|
nbytes += 4;
|
|
if (offset == sg->length) {
|
|
host->sg = sg = sg_next(sg);
|
|
- if (!sg)
|
|
+ host->sg_len--;
|
|
+ if (!sg || !host->sg_len)
|
|
goto done;
|
|
|
|
offset = 0;
|
|
@@ -1673,7 +1678,8 @@ static void atmci_write_data_pio(struct atmel_mci *host)
|
|
nbytes += remaining;
|
|
|
|
host->sg = sg = sg_next(sg);
|
|
- if (!sg) {
|
|
+ host->sg_len--;
|
|
+ if (!sg || !host->sg_len) {
|
|
atmci_writel(host, ATMCI_TDR, value);
|
|
goto done;
|
|
}
|
|
@@ -2190,10 +2196,8 @@ static int __exit atmci_remove(struct platform_device *pdev)
|
|
atmci_readl(host, ATMCI_SR);
|
|
clk_disable(host->mck);
|
|
|
|
-#ifdef CONFIG_MMC_ATMELMCI_DMA
|
|
if (host->dma.chan)
|
|
dma_release_channel(host->dma.chan);
|
|
-#endif
|
|
|
|
free_irq(platform_get_irq(pdev, 0), host);
|
|
iounmap(host->regs);
|
|
diff --git a/drivers/net/ethernet/freescale/gianfar_ptp.c b/drivers/net/ethernet/freescale/gianfar_ptp.c
|
|
index 5fd620b..ca2748a 100644
|
|
--- a/drivers/net/ethernet/freescale/gianfar_ptp.c
|
|
+++ b/drivers/net/ethernet/freescale/gianfar_ptp.c
|
|
@@ -127,7 +127,6 @@ struct gianfar_ptp_registers {
|
|
|
|
#define DRIVER "gianfar_ptp"
|
|
#define DEFAULT_CKSEL 1
|
|
-#define N_ALARM 1 /* first alarm is used internally to reset fipers */
|
|
#define N_EXT_TS 2
|
|
#define REG_SIZE sizeof(struct gianfar_ptp_registers)
|
|
|
|
@@ -410,7 +409,7 @@ static struct ptp_clock_info ptp_gianfar_caps = {
|
|
.owner = THIS_MODULE,
|
|
.name = "gianfar clock",
|
|
.max_adj = 512000,
|
|
- .n_alarm = N_ALARM,
|
|
+ .n_alarm = 0,
|
|
.n_ext_ts = N_EXT_TS,
|
|
.n_per_out = 0,
|
|
.pps = 1,
|
|
diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c b/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c
|
|
index 6d1f6c5..8f95545 100644
|
|
--- a/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c
|
|
+++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c
|
|
@@ -2263,6 +2263,16 @@ static irqreturn_t ixgbe_msix_other(int irq, void *data)
|
|
* with the write to EICR.
|
|
*/
|
|
eicr = IXGBE_READ_REG(hw, IXGBE_EICS);
|
|
+
|
|
+ /* The lower 16bits of the EICR register are for the queue interrupts
|
|
+ * which should be masked here in order to not accidently clear them if
|
|
+ * the bits are high when ixgbe_msix_other is called. There is a race
|
|
+ * condition otherwise which results in possible performance loss
|
|
+ * especially if the ixgbe_msix_other interrupt is triggering
|
|
+ * consistently (as it would when PPS is turned on for the X540 device)
|
|
+ */
|
|
+ eicr &= 0xFFFF0000;
|
|
+
|
|
IXGBE_WRITE_REG(hw, IXGBE_EICR, eicr);
|
|
|
|
if (eicr & IXGBE_EICR_LSC)
|
|
diff --git a/drivers/net/wireless/mwifiex/pcie.c b/drivers/net/wireless/mwifiex/pcie.c
|
|
index 9abb8f5..59e946a 100644
|
|
--- a/drivers/net/wireless/mwifiex/pcie.c
|
|
+++ b/drivers/net/wireless/mwifiex/pcie.c
|
|
@@ -1828,9 +1828,9 @@ static void mwifiex_pcie_cleanup(struct mwifiex_adapter *adapter)
|
|
if (pdev) {
|
|
pci_iounmap(pdev, card->pci_mmap);
|
|
pci_iounmap(pdev, card->pci_mmap1);
|
|
-
|
|
- pci_release_regions(pdev);
|
|
pci_disable_device(pdev);
|
|
+ pci_release_region(pdev, 2);
|
|
+ pci_release_region(pdev, 0);
|
|
pci_set_drvdata(pdev, NULL);
|
|
}
|
|
}
|
|
diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c
|
|
index 111569c..d08c0d8 100644
|
|
--- a/drivers/pci/pci.c
|
|
+++ b/drivers/pci/pci.c
|
|
@@ -673,15 +673,11 @@ static int pci_platform_power_transition(struct pci_dev *dev, pci_power_t state)
|
|
error = platform_pci_set_power_state(dev, state);
|
|
if (!error)
|
|
pci_update_current_state(dev, state);
|
|
- /* Fall back to PCI_D0 if native PM is not supported */
|
|
- if (!dev->pm_cap)
|
|
- dev->current_state = PCI_D0;
|
|
- } else {
|
|
+ } else
|
|
error = -ENODEV;
|
|
- /* Fall back to PCI_D0 if native PM is not supported */
|
|
- if (!dev->pm_cap)
|
|
- dev->current_state = PCI_D0;
|
|
- }
|
|
+
|
|
+ if (error && !dev->pm_cap) /* Fall back to PCI_D0 */
|
|
+ dev->current_state = PCI_D0;
|
|
|
|
return error;
|
|
}
|
|
diff --git a/drivers/rtc/rtc-cmos.c b/drivers/rtc/rtc-cmos.c
|
|
index 7d5f56e..5f8844c 100644
|
|
--- a/drivers/rtc/rtc-cmos.c
|
|
+++ b/drivers/rtc/rtc-cmos.c
|
|
@@ -805,9 +805,8 @@ static int cmos_suspend(struct device *dev)
|
|
mask = RTC_IRQMASK;
|
|
tmp &= ~mask;
|
|
CMOS_WRITE(tmp, RTC_CONTROL);
|
|
+ hpet_mask_rtc_irq_bit(mask);
|
|
|
|
- /* shut down hpet emulation - we don't need it for alarm */
|
|
- hpet_mask_rtc_irq_bit(RTC_PIE|RTC_AIE|RTC_UIE);
|
|
cmos_checkintr(cmos, tmp);
|
|
}
|
|
spin_unlock_irq(&rtc_lock);
|
|
@@ -872,6 +871,7 @@ static int cmos_resume(struct device *dev)
|
|
rtc_update_irq(cmos->rtc, 1, mask);
|
|
tmp &= ~RTC_AIE;
|
|
hpet_mask_rtc_irq_bit(RTC_AIE);
|
|
+ hpet_rtc_timer_init();
|
|
} while (mask & RTC_AIE);
|
|
spin_unlock_irq(&rtc_lock);
|
|
}
|
|
diff --git a/drivers/s390/char/sclp_cmd.c b/drivers/s390/char/sclp_cmd.c
|
|
index 231a1d8..e73b219 100644
|
|
--- a/drivers/s390/char/sclp_cmd.c
|
|
+++ b/drivers/s390/char/sclp_cmd.c
|
|
@@ -509,6 +509,8 @@ static void __init sclp_add_standby_memory(void)
|
|
add_memory_merged(0);
|
|
}
|
|
|
|
+#define MEM_SCT_SIZE (1UL << SECTION_SIZE_BITS)
|
|
+
|
|
static void __init insert_increment(u16 rn, int standby, int assigned)
|
|
{
|
|
struct memory_increment *incr, *new_incr;
|
|
@@ -521,7 +523,7 @@ static void __init insert_increment(u16 rn, int standby, int assigned)
|
|
new_incr->rn = rn;
|
|
new_incr->standby = standby;
|
|
if (!standby)
|
|
- new_incr->usecount = 1;
|
|
+ new_incr->usecount = rzm > MEM_SCT_SIZE ? rzm/MEM_SCT_SIZE : 1;
|
|
last_rn = 0;
|
|
prev = &sclp_mem_list;
|
|
list_for_each_entry(incr, &sclp_mem_list, list) {
|
|
diff --git a/drivers/tty/pty.c b/drivers/tty/pty.c
|
|
index 636c539..cf9a191 100644
|
|
--- a/drivers/tty/pty.c
|
|
+++ b/drivers/tty/pty.c
|
|
@@ -607,6 +607,9 @@ static int ptmx_open(struct inode *inode, struct file *filp)
|
|
|
|
nonseekable_open(inode, filp);
|
|
|
|
+ /* We refuse fsnotify events on ptmx, since it's a shared resource */
|
|
+ filp->f_mode |= FMODE_NONOTIFY;
|
|
+
|
|
retval = tty_alloc_file(filp);
|
|
if (retval)
|
|
return retval;
|
|
diff --git a/drivers/tty/serial/serial_core.c b/drivers/tty/serial/serial_core.c
|
|
index 246b823..4185cc5 100644
|
|
--- a/drivers/tty/serial/serial_core.c
|
|
+++ b/drivers/tty/serial/serial_core.c
|
|
@@ -1877,6 +1877,8 @@ int uart_suspend_port(struct uart_driver *drv, struct uart_port *uport)
|
|
mutex_unlock(&port->mutex);
|
|
return 0;
|
|
}
|
|
+ put_device(tty_dev);
|
|
+
|
|
if (console_suspend_enabled || !uart_console(uport))
|
|
uport->suspended = 1;
|
|
|
|
@@ -1942,9 +1944,11 @@ int uart_resume_port(struct uart_driver *drv, struct uart_port *uport)
|
|
disable_irq_wake(uport->irq);
|
|
uport->irq_wake = 0;
|
|
}
|
|
+ put_device(tty_dev);
|
|
mutex_unlock(&port->mutex);
|
|
return 0;
|
|
}
|
|
+ put_device(tty_dev);
|
|
uport->suspended = 0;
|
|
|
|
/*
|
|
diff --git a/drivers/tty/tty_io.c b/drivers/tty/tty_io.c
|
|
index bf9f987..b28d635 100644
|
|
--- a/drivers/tty/tty_io.c
|
|
+++ b/drivers/tty/tty_io.c
|
|
@@ -938,10 +938,10 @@ void start_tty(struct tty_struct *tty)
|
|
|
|
EXPORT_SYMBOL(start_tty);
|
|
|
|
+/* We limit tty time update visibility to every 8 seconds or so. */
|
|
static void tty_update_time(struct timespec *time)
|
|
{
|
|
- unsigned long sec = get_seconds();
|
|
- sec -= sec % 60;
|
|
+ unsigned long sec = get_seconds() & ~7;
|
|
if ((long)(sec - time->tv_sec) > 0)
|
|
time->tv_sec = sec;
|
|
}
|
|
diff --git a/drivers/usb/core/devio.c b/drivers/usb/core/devio.c
|
|
index 404413b..336b82d 100644
|
|
--- a/drivers/usb/core/devio.c
|
|
+++ b/drivers/usb/core/devio.c
|
|
@@ -681,6 +681,8 @@ static int check_ctrlrecip(struct dev_state *ps, unsigned int requesttype,
|
|
index &= 0xff;
|
|
switch (requesttype & USB_RECIP_MASK) {
|
|
case USB_RECIP_ENDPOINT:
|
|
+ if ((index & ~USB_DIR_IN) == 0)
|
|
+ return 0;
|
|
ret = findintfep(ps->dev, index);
|
|
if (ret >= 0)
|
|
ret = checkintf(ps, ret);
|
|
diff --git a/drivers/usb/misc/appledisplay.c b/drivers/usb/misc/appledisplay.c
|
|
index ac0d75a..9f7003e 100644
|
|
--- a/drivers/usb/misc/appledisplay.c
|
|
+++ b/drivers/usb/misc/appledisplay.c
|
|
@@ -63,6 +63,7 @@ static const struct usb_device_id appledisplay_table[] = {
|
|
{ APPLEDISPLAY_DEVICE(0x9219) },
|
|
{ APPLEDISPLAY_DEVICE(0x921c) },
|
|
{ APPLEDISPLAY_DEVICE(0x921d) },
|
|
+ { APPLEDISPLAY_DEVICE(0x9236) },
|
|
|
|
/* Terminating entry */
|
|
{ }
|
|
diff --git a/drivers/usb/serial/ftdi_sio.c b/drivers/usb/serial/ftdi_sio.c
|
|
index 07a4fb0..e5ccafc 100644
|
|
--- a/drivers/usb/serial/ftdi_sio.c
|
|
+++ b/drivers/usb/serial/ftdi_sio.c
|
|
@@ -197,6 +197,7 @@ static struct usb_device_id id_table_combined [] = {
|
|
{ USB_DEVICE(FTDI_VID, FTDI_OPENDCC_THROTTLE_PID) },
|
|
{ USB_DEVICE(FTDI_VID, FTDI_OPENDCC_GATEWAY_PID) },
|
|
{ USB_DEVICE(FTDI_VID, FTDI_OPENDCC_GBM_PID) },
|
|
+ { USB_DEVICE(FTDI_VID, FTDI_OPENDCC_GBM_BOOST_PID) },
|
|
{ USB_DEVICE(NEWPORT_VID, NEWPORT_AGILIS_PID) },
|
|
{ USB_DEVICE(INTERBIOMETRICS_VID, INTERBIOMETRICS_IOBOARD_PID) },
|
|
{ USB_DEVICE(INTERBIOMETRICS_VID, INTERBIOMETRICS_MINI_IOBOARD_PID) },
|
|
@@ -878,7 +879,9 @@ static struct usb_device_id id_table_combined [] = {
|
|
{ USB_DEVICE(FTDI_VID, FTDI_DOTEC_PID) },
|
|
{ USB_DEVICE(QIHARDWARE_VID, MILKYMISTONE_JTAGSERIAL_PID),
|
|
.driver_info = (kernel_ulong_t)&ftdi_jtag_quirk },
|
|
- { USB_DEVICE(ST_VID, ST_STMCLT1030_PID),
|
|
+ { USB_DEVICE(ST_VID, ST_STMCLT_2232_PID),
|
|
+ .driver_info = (kernel_ulong_t)&ftdi_jtag_quirk },
|
|
+ { USB_DEVICE(ST_VID, ST_STMCLT_4232_PID),
|
|
.driver_info = (kernel_ulong_t)&ftdi_stmclite_quirk },
|
|
{ USB_DEVICE(FTDI_VID, FTDI_RF_R106) },
|
|
{ USB_DEVICE(FTDI_VID, FTDI_DISTORTEC_JTAG_LOCK_PICK_PID),
|
|
diff --git a/drivers/usb/serial/ftdi_sio_ids.h b/drivers/usb/serial/ftdi_sio_ids.h
|
|
index e79861e..9852827 100644
|
|
--- a/drivers/usb/serial/ftdi_sio_ids.h
|
|
+++ b/drivers/usb/serial/ftdi_sio_ids.h
|
|
@@ -74,6 +74,7 @@
|
|
#define FTDI_OPENDCC_THROTTLE_PID 0xBFDA
|
|
#define FTDI_OPENDCC_GATEWAY_PID 0xBFDB
|
|
#define FTDI_OPENDCC_GBM_PID 0xBFDC
|
|
+#define FTDI_OPENDCC_GBM_BOOST_PID 0xBFDD
|
|
|
|
/* NZR SEM 16+ USB (http://www.nzr.de) */
|
|
#define FTDI_NZR_SEM_USB_PID 0xC1E0 /* NZR SEM-LOG16+ */
|
|
@@ -1150,7 +1151,8 @@
|
|
* STMicroelectonics
|
|
*/
|
|
#define ST_VID 0x0483
|
|
-#define ST_STMCLT1030_PID 0x3747 /* ST Micro Connect Lite STMCLT1030 */
|
|
+#define ST_STMCLT_2232_PID 0x3746
|
|
+#define ST_STMCLT_4232_PID 0x3747
|
|
|
|
/*
|
|
* Papouch products (http://www.papouch.com/)
|
|
diff --git a/drivers/usb/serial/option.c b/drivers/usb/serial/option.c
|
|
index 78c4774..16efe0a 100644
|
|
--- a/drivers/usb/serial/option.c
|
|
+++ b/drivers/usb/serial/option.c
|
|
@@ -347,6 +347,7 @@ static void option_instat_callback(struct urb *urb);
|
|
/* Olivetti products */
|
|
#define OLIVETTI_VENDOR_ID 0x0b3c
|
|
#define OLIVETTI_PRODUCT_OLICARD100 0xc000
|
|
+#define OLIVETTI_PRODUCT_OLICARD145 0xc003
|
|
|
|
/* Celot products */
|
|
#define CELOT_VENDOR_ID 0x211f
|
|
@@ -1273,6 +1274,7 @@ static const struct usb_device_id option_ids[] = {
|
|
{ USB_DEVICE(SIEMENS_VENDOR_ID, CINTERION_PRODUCT_HC28_MDMNET) },
|
|
|
|
{ USB_DEVICE(OLIVETTI_VENDOR_ID, OLIVETTI_PRODUCT_OLICARD100) },
|
|
+ { USB_DEVICE(OLIVETTI_VENDOR_ID, OLIVETTI_PRODUCT_OLICARD145) },
|
|
{ USB_DEVICE(CELOT_VENDOR_ID, CELOT_PRODUCT_CT680M) }, /* CT-650 CDMA 450 1xEVDO modem */
|
|
{ USB_DEVICE(ONDA_VENDOR_ID, ONDA_MT825UP) }, /* ONDA MT825UP modem */
|
|
{ USB_DEVICE_AND_INTERFACE_INFO(SAMSUNG_VENDOR_ID, SAMSUNG_PRODUCT_GT_B3730, USB_CLASS_CDC_DATA, 0x00, 0x00) }, /* Samsung GT-B3730 LTE USB modem.*/
|
|
@@ -1350,6 +1352,12 @@ static const struct usb_device_id option_ids[] = {
|
|
{ USB_DEVICE(TPLINK_VENDOR_ID, TPLINK_PRODUCT_MA180),
|
|
.driver_info = (kernel_ulong_t)&net_intf4_blacklist },
|
|
{ USB_DEVICE(CHANGHONG_VENDOR_ID, CHANGHONG_PRODUCT_CH690) },
|
|
+ { USB_DEVICE_AND_INTERFACE_INFO(0x2001, 0x7d01, 0xff, 0x02, 0x01) }, /* D-Link DWM-156 (variant) */
|
|
+ { USB_DEVICE_AND_INTERFACE_INFO(0x2001, 0x7d01, 0xff, 0x00, 0x00) }, /* D-Link DWM-156 (variant) */
|
|
+ { USB_DEVICE_AND_INTERFACE_INFO(0x2001, 0x7d02, 0xff, 0x02, 0x01) },
|
|
+ { USB_DEVICE_AND_INTERFACE_INFO(0x2001, 0x7d02, 0xff, 0x00, 0x00) },
|
|
+ { USB_DEVICE_AND_INTERFACE_INFO(0x2001, 0x7d03, 0xff, 0x02, 0x01) },
|
|
+ { USB_DEVICE_AND_INTERFACE_INFO(0x2001, 0x7d03, 0xff, 0x00, 0x00) },
|
|
{ } /* Terminating entry */
|
|
};
|
|
MODULE_DEVICE_TABLE(usb, option_ids);
|
|
diff --git a/drivers/usb/storage/cypress_atacb.c b/drivers/usb/storage/cypress_atacb.c
|
|
index 5fe451d..c1f6751 100644
|
|
--- a/drivers/usb/storage/cypress_atacb.c
|
|
+++ b/drivers/usb/storage/cypress_atacb.c
|
|
@@ -248,14 +248,26 @@ static int cypress_probe(struct usb_interface *intf,
|
|
{
|
|
struct us_data *us;
|
|
int result;
|
|
+ struct usb_device *device;
|
|
|
|
result = usb_stor_probe1(&us, intf, id,
|
|
(id - cypress_usb_ids) + cypress_unusual_dev_list);
|
|
if (result)
|
|
return result;
|
|
|
|
- us->protocol_name = "Transparent SCSI with Cypress ATACB";
|
|
- us->proto_handler = cypress_atacb_passthrough;
|
|
+ /* Among CY7C68300 chips, the A revision does not support Cypress ATACB
|
|
+ * Filter out this revision from EEPROM default descriptor values
|
|
+ */
|
|
+ device = interface_to_usbdev(intf);
|
|
+ if (device->descriptor.iManufacturer != 0x38 ||
|
|
+ device->descriptor.iProduct != 0x4e ||
|
|
+ device->descriptor.iSerialNumber != 0x64) {
|
|
+ us->protocol_name = "Transparent SCSI with Cypress ATACB";
|
|
+ us->proto_handler = cypress_atacb_passthrough;
|
|
+ } else {
|
|
+ us->protocol_name = "Transparent SCSI";
|
|
+ us->proto_handler = usb_stor_transparent_scsi_command;
|
|
+ }
|
|
|
|
result = usb_stor_probe2(us);
|
|
return result;
|
|
diff --git a/drivers/video/console/fbcon.c b/drivers/video/console/fbcon.c
|
|
index 18ded2d..a01317c 100644
|
|
--- a/drivers/video/console/fbcon.c
|
|
+++ b/drivers/video/console/fbcon.c
|
|
@@ -1228,6 +1228,8 @@ static void fbcon_deinit(struct vc_data *vc)
|
|
finished:
|
|
|
|
fbcon_free_font(p, free_font);
|
|
+ if (free_font)
|
|
+ vc->vc_font.data = NULL;
|
|
|
|
if (!con_is_bound(&fb_con))
|
|
fbcon_exit();
|
|
diff --git a/fs/dcache.c b/fs/dcache.c
|
|
index f104945..e498de2 100644
|
|
--- a/fs/dcache.c
|
|
+++ b/fs/dcache.c
|
|
@@ -1238,8 +1238,10 @@ void shrink_dcache_parent(struct dentry * parent)
|
|
LIST_HEAD(dispose);
|
|
int found;
|
|
|
|
- while ((found = select_parent(parent, &dispose)) != 0)
|
|
+ while ((found = select_parent(parent, &dispose)) != 0) {
|
|
shrink_dentry_list(&dispose);
|
|
+ cond_resched();
|
|
+ }
|
|
}
|
|
EXPORT_SYMBOL(shrink_dcache_parent);
|
|
|
|
diff --git a/fs/exec.c b/fs/exec.c
|
|
index e3a7e36d..2b7f5ff 100644
|
|
--- a/fs/exec.c
|
|
+++ b/fs/exec.c
|
|
@@ -627,7 +627,7 @@ static int shift_arg_pages(struct vm_area_struct *vma, unsigned long shift)
|
|
* when the old and new regions overlap clear from new_end.
|
|
*/
|
|
free_pgd_range(&tlb, new_end, old_end, new_end,
|
|
- vma->vm_next ? vma->vm_next->vm_start : 0);
|
|
+ vma->vm_next ? vma->vm_next->vm_start : USER_PGTABLES_CEILING);
|
|
} else {
|
|
/*
|
|
* otherwise, clean from old_start; this is done to not touch
|
|
@@ -636,7 +636,7 @@ static int shift_arg_pages(struct vm_area_struct *vma, unsigned long shift)
|
|
* for the others its just a little faster.
|
|
*/
|
|
free_pgd_range(&tlb, old_start, old_end, new_end,
|
|
- vma->vm_next ? vma->vm_next->vm_start : 0);
|
|
+ vma->vm_next ? vma->vm_next->vm_start : USER_PGTABLES_CEILING);
|
|
}
|
|
tlb_finish_mmu(&tlb, new_end, old_end);
|
|
|
|
diff --git a/fs/ext4/Kconfig b/fs/ext4/Kconfig
|
|
index 9ed1bb1..5459168 100644
|
|
--- a/fs/ext4/Kconfig
|
|
+++ b/fs/ext4/Kconfig
|
|
@@ -82,4 +82,5 @@ config EXT4_DEBUG
|
|
Enables run-time debugging support for the ext4 filesystem.
|
|
|
|
If you select Y here, then you will be able to turn on debugging
|
|
- with a command such as "echo 1 > /sys/kernel/debug/ext4/mballoc-debug"
|
|
+ with a command such as:
|
|
+ echo 1 > /sys/module/ext4/parameters/mballoc_debug
|
|
diff --git a/fs/ext4/ext4_jbd2.h b/fs/ext4/ext4_jbd2.h
|
|
index 83b20fc..6b23a96 100644
|
|
--- a/fs/ext4/ext4_jbd2.h
|
|
+++ b/fs/ext4/ext4_jbd2.h
|
|
@@ -164,16 +164,20 @@ static inline void ext4_journal_callback_add(handle_t *handle,
|
|
* ext4_journal_callback_del: delete a registered callback
|
|
* @handle: active journal transaction handle on which callback was registered
|
|
* @jce: registered journal callback entry to unregister
|
|
+ * Return true if object was sucessfully removed
|
|
*/
|
|
-static inline void ext4_journal_callback_del(handle_t *handle,
|
|
+static inline bool ext4_journal_callback_try_del(handle_t *handle,
|
|
struct ext4_journal_cb_entry *jce)
|
|
{
|
|
+ bool deleted;
|
|
struct ext4_sb_info *sbi =
|
|
EXT4_SB(handle->h_transaction->t_journal->j_private);
|
|
|
|
spin_lock(&sbi->s_md_lock);
|
|
+ deleted = !list_empty(&jce->jce_list);
|
|
list_del_init(&jce->jce_list);
|
|
spin_unlock(&sbi->s_md_lock);
|
|
+ return deleted;
|
|
}
|
|
|
|
int
|
|
diff --git a/fs/ext4/mballoc.c b/fs/ext4/mballoc.c
|
|
index 6c32dd8..ec970cb 100644
|
|
--- a/fs/ext4/mballoc.c
|
|
+++ b/fs/ext4/mballoc.c
|
|
@@ -4436,11 +4436,11 @@ ext4_mb_free_metadata(handle_t *handle, struct ext4_buddy *e4b,
|
|
node = rb_prev(new_node);
|
|
if (node) {
|
|
entry = rb_entry(node, struct ext4_free_data, efd_node);
|
|
- if (can_merge(entry, new_entry)) {
|
|
+ if (can_merge(entry, new_entry) &&
|
|
+ ext4_journal_callback_try_del(handle, &entry->efd_jce)) {
|
|
new_entry->efd_start_cluster = entry->efd_start_cluster;
|
|
new_entry->efd_count += entry->efd_count;
|
|
rb_erase(node, &(db->bb_free_root));
|
|
- ext4_journal_callback_del(handle, &entry->efd_jce);
|
|
kmem_cache_free(ext4_free_data_cachep, entry);
|
|
}
|
|
}
|
|
@@ -4448,10 +4448,10 @@ ext4_mb_free_metadata(handle_t *handle, struct ext4_buddy *e4b,
|
|
node = rb_next(new_node);
|
|
if (node) {
|
|
entry = rb_entry(node, struct ext4_free_data, efd_node);
|
|
- if (can_merge(new_entry, entry)) {
|
|
+ if (can_merge(new_entry, entry) &&
|
|
+ ext4_journal_callback_try_del(handle, &entry->efd_jce)) {
|
|
new_entry->efd_count += entry->efd_count;
|
|
rb_erase(node, &(db->bb_free_root));
|
|
- ext4_journal_callback_del(handle, &entry->efd_jce);
|
|
kmem_cache_free(ext4_free_data_cachep, entry);
|
|
}
|
|
}
|
|
diff --git a/fs/ext4/resize.c b/fs/ext4/resize.c
|
|
index 3fc0e8b..9202b22 100644
|
|
--- a/fs/ext4/resize.c
|
|
+++ b/fs/ext4/resize.c
|
|
@@ -1202,6 +1202,8 @@ static void ext4_update_super(struct super_block *sb,
|
|
|
|
/* Update the global fs size fields */
|
|
sbi->s_groups_count += flex_gd->count;
|
|
+ sbi->s_blockfile_groups = min_t(ext4_group_t, sbi->s_groups_count,
|
|
+ (EXT4_MAX_BLOCK_FILE_PHYS / EXT4_BLOCKS_PER_GROUP(sb)));
|
|
|
|
/* Update the reserved block counts only once the new group is
|
|
* active. */
|
|
diff --git a/fs/ext4/super.c b/fs/ext4/super.c
|
|
index 88bb68d..b93de81 100644
|
|
--- a/fs/ext4/super.c
|
|
+++ b/fs/ext4/super.c
|
|
@@ -437,10 +437,13 @@ static void ext4_journal_commit_callback(journal_t *journal, transaction_t *txn)
|
|
struct super_block *sb = journal->j_private;
|
|
struct ext4_sb_info *sbi = EXT4_SB(sb);
|
|
int error = is_journal_aborted(journal);
|
|
- struct ext4_journal_cb_entry *jce, *tmp;
|
|
+ struct ext4_journal_cb_entry *jce;
|
|
|
|
+ BUG_ON(txn->t_state == T_FINISHED);
|
|
spin_lock(&sbi->s_md_lock);
|
|
- list_for_each_entry_safe(jce, tmp, &txn->t_private_list, jce_list) {
|
|
+ while (!list_empty(&txn->t_private_list)) {
|
|
+ jce = list_entry(txn->t_private_list.next,
|
|
+ struct ext4_journal_cb_entry, jce_list);
|
|
list_del_init(&jce->jce_list);
|
|
spin_unlock(&sbi->s_md_lock);
|
|
jce->jce_func(sb, jce, error);
|
|
diff --git a/fs/fscache/stats.c b/fs/fscache/stats.c
|
|
index 4765190..73c0bd7 100644
|
|
--- a/fs/fscache/stats.c
|
|
+++ b/fs/fscache/stats.c
|
|
@@ -276,5 +276,5 @@ const struct file_operations fscache_stats_fops = {
|
|
.open = fscache_stats_open,
|
|
.read = seq_read,
|
|
.llseek = seq_lseek,
|
|
- .release = seq_release,
|
|
+ .release = single_release,
|
|
};
|
|
diff --git a/fs/jbd2/commit.c b/fs/jbd2/commit.c
|
|
index 840f70f..a0dcbd62 100644
|
|
--- a/fs/jbd2/commit.c
|
|
+++ b/fs/jbd2/commit.c
|
|
@@ -325,7 +325,7 @@ void jbd2_journal_commit_transaction(journal_t *journal)
|
|
int space_left = 0;
|
|
int first_tag = 0;
|
|
int tag_flag;
|
|
- int i, to_free = 0;
|
|
+ int i;
|
|
int tag_bytes = journal_tag_bytes(journal);
|
|
struct buffer_head *cbh = NULL; /* For transactional checksums */
|
|
__u32 crc32_sum = ~0;
|
|
@@ -1044,7 +1044,7 @@ restart_loop:
|
|
journal->j_stats.run.rs_blocks_logged += stats.run.rs_blocks_logged;
|
|
spin_unlock(&journal->j_history_lock);
|
|
|
|
- commit_transaction->t_state = T_FINISHED;
|
|
+ commit_transaction->t_state = T_COMMIT_CALLBACK;
|
|
J_ASSERT(commit_transaction == journal->j_committing_transaction);
|
|
journal->j_commit_sequence = commit_transaction->t_tid;
|
|
journal->j_committing_transaction = NULL;
|
|
@@ -1059,38 +1059,44 @@ restart_loop:
|
|
journal->j_average_commit_time*3) / 4;
|
|
else
|
|
journal->j_average_commit_time = commit_time;
|
|
+
|
|
write_unlock(&journal->j_state_lock);
|
|
|
|
- if (commit_transaction->t_checkpoint_list == NULL &&
|
|
- commit_transaction->t_checkpoint_io_list == NULL) {
|
|
- __jbd2_journal_drop_transaction(journal, commit_transaction);
|
|
- to_free = 1;
|
|
+ if (journal->j_checkpoint_transactions == NULL) {
|
|
+ journal->j_checkpoint_transactions = commit_transaction;
|
|
+ commit_transaction->t_cpnext = commit_transaction;
|
|
+ commit_transaction->t_cpprev = commit_transaction;
|
|
} else {
|
|
- if (journal->j_checkpoint_transactions == NULL) {
|
|
- journal->j_checkpoint_transactions = commit_transaction;
|
|
- commit_transaction->t_cpnext = commit_transaction;
|
|
- commit_transaction->t_cpprev = commit_transaction;
|
|
- } else {
|
|
- commit_transaction->t_cpnext =
|
|
- journal->j_checkpoint_transactions;
|
|
- commit_transaction->t_cpprev =
|
|
- commit_transaction->t_cpnext->t_cpprev;
|
|
- commit_transaction->t_cpnext->t_cpprev =
|
|
- commit_transaction;
|
|
- commit_transaction->t_cpprev->t_cpnext =
|
|
+ commit_transaction->t_cpnext =
|
|
+ journal->j_checkpoint_transactions;
|
|
+ commit_transaction->t_cpprev =
|
|
+ commit_transaction->t_cpnext->t_cpprev;
|
|
+ commit_transaction->t_cpnext->t_cpprev =
|
|
+ commit_transaction;
|
|
+ commit_transaction->t_cpprev->t_cpnext =
|
|
commit_transaction;
|
|
- }
|
|
}
|
|
spin_unlock(&journal->j_list_lock);
|
|
-
|
|
+ /* Drop all spin_locks because commit_callback may be block.
|
|
+ * __journal_remove_checkpoint() can not destroy transaction
|
|
+ * under us because it is not marked as T_FINISHED yet */
|
|
if (journal->j_commit_callback)
|
|
journal->j_commit_callback(journal, commit_transaction);
|
|
|
|
trace_jbd2_end_commit(journal, commit_transaction);
|
|
jbd_debug(1, "JBD2: commit %d complete, head %d\n",
|
|
journal->j_commit_sequence, journal->j_tail_sequence);
|
|
- if (to_free)
|
|
- jbd2_journal_free_transaction(commit_transaction);
|
|
|
|
+ write_lock(&journal->j_state_lock);
|
|
+ spin_lock(&journal->j_list_lock);
|
|
+ commit_transaction->t_state = T_FINISHED;
|
|
+ /* Recheck checkpoint lists after j_list_lock was dropped */
|
|
+ if (commit_transaction->t_checkpoint_list == NULL &&
|
|
+ commit_transaction->t_checkpoint_io_list == NULL) {
|
|
+ __jbd2_journal_drop_transaction(journal, commit_transaction);
|
|
+ jbd2_journal_free_transaction(commit_transaction);
|
|
+ }
|
|
+ spin_unlock(&journal->j_list_lock);
|
|
+ write_unlock(&journal->j_state_lock);
|
|
wake_up(&journal->j_wait_done_commit);
|
|
}
|
|
diff --git a/fs/lockd/clntlock.c b/fs/lockd/clntlock.c
|
|
index ca0a080..193f04c 100644
|
|
--- a/fs/lockd/clntlock.c
|
|
+++ b/fs/lockd/clntlock.c
|
|
@@ -144,6 +144,9 @@ int nlmclnt_block(struct nlm_wait *block, struct nlm_rqst *req, long timeout)
|
|
timeout);
|
|
if (ret < 0)
|
|
return -ERESTARTSYS;
|
|
+ /* Reset the lock status after a server reboot so we resend */
|
|
+ if (block->b_status == nlm_lck_denied_grace_period)
|
|
+ block->b_status = nlm_lck_blocked;
|
|
req->a_res.status = block->b_status;
|
|
return 0;
|
|
}
|
|
diff --git a/fs/lockd/clntproc.c b/fs/lockd/clntproc.c
|
|
index a3a0987..8392cb8 100644
|
|
--- a/fs/lockd/clntproc.c
|
|
+++ b/fs/lockd/clntproc.c
|
|
@@ -551,9 +551,6 @@ again:
|
|
status = nlmclnt_block(block, req, NLMCLNT_POLL_TIMEOUT);
|
|
if (status < 0)
|
|
break;
|
|
- /* Resend the blocking lock request after a server reboot */
|
|
- if (resp->status == nlm_lck_denied_grace_period)
|
|
- continue;
|
|
if (resp->status != nlm_lck_blocked)
|
|
break;
|
|
}
|
|
diff --git a/fs/nfs/nfs4proc.c b/fs/nfs/nfs4proc.c
|
|
index 3035187..04f449c 100644
|
|
--- a/fs/nfs/nfs4proc.c
|
|
+++ b/fs/nfs/nfs4proc.c
|
|
@@ -1362,6 +1362,12 @@ int nfs4_open_delegation_recall(struct nfs_open_context *ctx, struct nfs4_state
|
|
case -ENOMEM:
|
|
err = 0;
|
|
goto out;
|
|
+ case -NFS4ERR_DELAY:
|
|
+ case -NFS4ERR_GRACE:
|
|
+ set_bit(NFS_DELEGATED_STATE, &state->flags);
|
|
+ ssleep(1);
|
|
+ err = -EAGAIN;
|
|
+ goto out;
|
|
}
|
|
err = nfs4_handle_exception(server, err, &exception);
|
|
} while (exception.retry);
|
|
diff --git a/fs/nfsd/nfs4state.c b/fs/nfsd/nfs4state.c
|
|
index abd785e..f90b197 100644
|
|
--- a/fs/nfsd/nfs4state.c
|
|
+++ b/fs/nfsd/nfs4state.c
|
|
@@ -213,13 +213,7 @@ static void __nfs4_file_put_access(struct nfs4_file *fp, int oflag)
|
|
{
|
|
if (atomic_dec_and_test(&fp->fi_access[oflag])) {
|
|
nfs4_file_put_fd(fp, oflag);
|
|
- /*
|
|
- * It's also safe to get rid of the RDWR open *if*
|
|
- * we no longer have need of the other kind of access
|
|
- * or if we already have the other kind of open:
|
|
- */
|
|
- if (fp->fi_fds[1-oflag]
|
|
- || atomic_read(&fp->fi_access[1 - oflag]) == 0)
|
|
+ if (atomic_read(&fp->fi_access[1 - oflag]) == 0)
|
|
nfs4_file_put_fd(fp, O_RDWR);
|
|
}
|
|
}
|
|
diff --git a/fs/nfsd/nfs4xdr.c b/fs/nfsd/nfs4xdr.c
|
|
index ace6745..1798846 100644
|
|
--- a/fs/nfsd/nfs4xdr.c
|
|
+++ b/fs/nfsd/nfs4xdr.c
|
|
@@ -343,10 +343,7 @@ nfsd4_decode_fattr(struct nfsd4_compoundargs *argp, u32 *bmval,
|
|
all 32 bits of 'nseconds'. */
|
|
READ_BUF(12);
|
|
len += 12;
|
|
- READ32(dummy32);
|
|
- if (dummy32)
|
|
- return nfserr_inval;
|
|
- READ32(iattr->ia_atime.tv_sec);
|
|
+ READ64(iattr->ia_atime.tv_sec);
|
|
READ32(iattr->ia_atime.tv_nsec);
|
|
if (iattr->ia_atime.tv_nsec >= (u32)1000000000)
|
|
return nfserr_inval;
|
|
@@ -369,10 +366,7 @@ nfsd4_decode_fattr(struct nfsd4_compoundargs *argp, u32 *bmval,
|
|
all 32 bits of 'nseconds'. */
|
|
READ_BUF(12);
|
|
len += 12;
|
|
- READ32(dummy32);
|
|
- if (dummy32)
|
|
- return nfserr_inval;
|
|
- READ32(iattr->ia_mtime.tv_sec);
|
|
+ READ64(iattr->ia_mtime.tv_sec);
|
|
READ32(iattr->ia_mtime.tv_nsec);
|
|
if (iattr->ia_mtime.tv_nsec >= (u32)1000000000)
|
|
return nfserr_inval;
|
|
@@ -2371,8 +2365,7 @@ out_acl:
|
|
if (bmval1 & FATTR4_WORD1_TIME_ACCESS) {
|
|
if ((buflen -= 12) < 0)
|
|
goto out_resource;
|
|
- WRITE32(0);
|
|
- WRITE32(stat.atime.tv_sec);
|
|
+ WRITE64((s64)stat.atime.tv_sec);
|
|
WRITE32(stat.atime.tv_nsec);
|
|
}
|
|
if (bmval1 & FATTR4_WORD1_TIME_DELTA) {
|
|
@@ -2385,15 +2378,13 @@ out_acl:
|
|
if (bmval1 & FATTR4_WORD1_TIME_METADATA) {
|
|
if ((buflen -= 12) < 0)
|
|
goto out_resource;
|
|
- WRITE32(0);
|
|
- WRITE32(stat.ctime.tv_sec);
|
|
+ WRITE64((s64)stat.ctime.tv_sec);
|
|
WRITE32(stat.ctime.tv_nsec);
|
|
}
|
|
if (bmval1 & FATTR4_WORD1_TIME_MODIFY) {
|
|
if ((buflen -= 12) < 0)
|
|
goto out_resource;
|
|
- WRITE32(0);
|
|
- WRITE32(stat.mtime.tv_sec);
|
|
+ WRITE64((s64)stat.mtime.tv_sec);
|
|
WRITE32(stat.mtime.tv_nsec);
|
|
}
|
|
if (bmval1 & FATTR4_WORD1_MOUNTED_ON_FILEID) {
|
|
diff --git a/fs/sysfs/dir.c b/fs/sysfs/dir.c
|
|
index 45024ef..9a5f07d 100644
|
|
--- a/fs/sysfs/dir.c
|
|
+++ b/fs/sysfs/dir.c
|
|
@@ -994,6 +994,7 @@ static int sysfs_readdir(struct file * filp, void * dirent, filldir_t filldir)
|
|
enum kobj_ns_type type;
|
|
const void *ns;
|
|
ino_t ino;
|
|
+ loff_t off;
|
|
|
|
type = sysfs_ns_type(parent_sd);
|
|
ns = sysfs_info(dentry->d_sb)->ns[type];
|
|
@@ -1016,6 +1017,7 @@ static int sysfs_readdir(struct file * filp, void * dirent, filldir_t filldir)
|
|
return 0;
|
|
}
|
|
mutex_lock(&sysfs_mutex);
|
|
+ off = filp->f_pos;
|
|
for (pos = sysfs_dir_pos(ns, parent_sd, filp->f_pos, pos);
|
|
pos;
|
|
pos = sysfs_dir_next_pos(ns, parent_sd, filp->f_pos, pos)) {
|
|
@@ -1027,19 +1029,24 @@ static int sysfs_readdir(struct file * filp, void * dirent, filldir_t filldir)
|
|
len = strlen(name);
|
|
ino = pos->s_ino;
|
|
type = dt_type(pos);
|
|
- filp->f_pos = pos->s_hash;
|
|
+ off = filp->f_pos = pos->s_hash;
|
|
filp->private_data = sysfs_get(pos);
|
|
|
|
mutex_unlock(&sysfs_mutex);
|
|
- ret = filldir(dirent, name, len, filp->f_pos, ino, type);
|
|
+ ret = filldir(dirent, name, len, off, ino, type);
|
|
mutex_lock(&sysfs_mutex);
|
|
if (ret < 0)
|
|
break;
|
|
}
|
|
mutex_unlock(&sysfs_mutex);
|
|
- if ((filp->f_pos > 1) && !pos) { /* EOF */
|
|
- filp->f_pos = INT_MAX;
|
|
+
|
|
+ /* don't reference last entry if its refcount is dropped */
|
|
+ if (!pos) {
|
|
filp->private_data = NULL;
|
|
+
|
|
+ /* EOF and not changed as 0 or 1 in read/write path */
|
|
+ if (off == filp->f_pos && off > 1)
|
|
+ filp->f_pos = INT_MAX;
|
|
}
|
|
return 0;
|
|
}
|
|
diff --git a/include/asm-generic/pgtable.h b/include/asm-generic/pgtable.h
|
|
index c7ec2cd..9a6eb25 100644
|
|
--- a/include/asm-generic/pgtable.h
|
|
+++ b/include/asm-generic/pgtable.h
|
|
@@ -7,6 +7,16 @@
|
|
#include <linux/mm_types.h>
|
|
#include <linux/bug.h>
|
|
|
|
+/*
|
|
+ * On almost all architectures and configurations, 0 can be used as the
|
|
+ * upper ceiling to free_pgtables(): on many architectures it has the same
|
|
+ * effect as using TASK_SIZE. However, there is one configuration which
|
|
+ * must impose a more careful limit, to avoid freeing kernel pgtables.
|
|
+ */
|
|
+#ifndef USER_PGTABLES_CEILING
|
|
+#define USER_PGTABLES_CEILING 0UL
|
|
+#endif
|
|
+
|
|
#ifndef __HAVE_ARCH_PTEP_SET_ACCESS_FLAGS
|
|
extern int ptep_set_access_flags(struct vm_area_struct *vma,
|
|
unsigned long address, pte_t *ptep,
|
|
diff --git a/include/linux/ipc_namespace.h b/include/linux/ipc_namespace.h
|
|
index 8a297a5..497c6cc 100644
|
|
--- a/include/linux/ipc_namespace.h
|
|
+++ b/include/linux/ipc_namespace.h
|
|
@@ -42,8 +42,8 @@ struct ipc_namespace {
|
|
|
|
size_t shm_ctlmax;
|
|
size_t shm_ctlall;
|
|
+ unsigned long shm_tot;
|
|
int shm_ctlmni;
|
|
- int shm_tot;
|
|
/*
|
|
* Defines whether IPC_RMID is forced for _all_ shm segments regardless
|
|
* of shmctl()
|
|
diff --git a/include/linux/jbd2.h b/include/linux/jbd2.h
|
|
index 2ed66ef..dd6444f 100644
|
|
--- a/include/linux/jbd2.h
|
|
+++ b/include/linux/jbd2.h
|
|
@@ -470,6 +470,7 @@ struct transaction_s
|
|
T_COMMIT,
|
|
T_COMMIT_DFLUSH,
|
|
T_COMMIT_JFLUSH,
|
|
+ T_COMMIT_CALLBACK,
|
|
T_FINISHED
|
|
} t_state;
|
|
|
|
diff --git a/ipc/shm.c b/ipc/shm.c
|
|
index 406c5b2..85d81b4 100644
|
|
--- a/ipc/shm.c
|
|
+++ b/ipc/shm.c
|
|
@@ -450,7 +450,7 @@ static int newseg(struct ipc_namespace *ns, struct ipc_params *params)
|
|
size_t size = params->u.size;
|
|
int error;
|
|
struct shmid_kernel *shp;
|
|
- int numpages = (size + PAGE_SIZE -1) >> PAGE_SHIFT;
|
|
+ size_t numpages = (size + PAGE_SIZE - 1) >> PAGE_SHIFT;
|
|
struct file * file;
|
|
char name[13];
|
|
int id;
|
|
diff --git a/kernel/cgroup.c b/kernel/cgroup.c
|
|
index a4c47d1b..4eb1ed3 100644
|
|
--- a/kernel/cgroup.c
|
|
+++ b/kernel/cgroup.c
|
|
@@ -2020,7 +2020,7 @@ static int cgroup_attach_proc(struct cgroup *cgrp, struct task_struct *leader)
|
|
if (!group)
|
|
return -ENOMEM;
|
|
/* pre-allocate to guarantee space while iterating in rcu read-side. */
|
|
- retval = flex_array_prealloc(group, 0, group_size - 1, GFP_KERNEL);
|
|
+ retval = flex_array_prealloc(group, 0, group_size, GFP_KERNEL);
|
|
if (retval)
|
|
goto out_free_group_list;
|
|
|
|
diff --git a/kernel/hrtimer.c b/kernel/hrtimer.c
|
|
index e4cee8d..60f7e32 100644
|
|
--- a/kernel/hrtimer.c
|
|
+++ b/kernel/hrtimer.c
|
|
@@ -298,6 +298,10 @@ ktime_t ktime_sub_ns(const ktime_t kt, u64 nsec)
|
|
} else {
|
|
unsigned long rem = do_div(nsec, NSEC_PER_SEC);
|
|
|
|
+ /* Make sure nsec fits into long */
|
|
+ if (unlikely(nsec > KTIME_SEC_MAX))
|
|
+ return (ktime_t){ .tv64 = KTIME_MAX };
|
|
+
|
|
tmp = ktime_set((long)nsec, rem);
|
|
}
|
|
|
|
@@ -1308,6 +1312,8 @@ retry:
|
|
|
|
expires = ktime_sub(hrtimer_get_expires(timer),
|
|
base->offset);
|
|
+ if (expires.tv64 < 0)
|
|
+ expires.tv64 = KTIME_MAX;
|
|
if (expires.tv64 < expires_next.tv64)
|
|
expires_next = expires;
|
|
break;
|
|
diff --git a/kernel/time/tick-broadcast.c b/kernel/time/tick-broadcast.c
|
|
index a13987a..239a323 100644
|
|
--- a/kernel/time/tick-broadcast.c
|
|
+++ b/kernel/time/tick-broadcast.c
|
|
@@ -66,6 +66,8 @@ static void tick_broadcast_start_periodic(struct clock_event_device *bc)
|
|
*/
|
|
int tick_check_broadcast_device(struct clock_event_device *dev)
|
|
{
|
|
+ struct clock_event_device *cur = tick_broadcast_device.evtdev;
|
|
+
|
|
if ((dev->features & CLOCK_EVT_FEAT_DUMMY) ||
|
|
(tick_broadcast_device.evtdev &&
|
|
tick_broadcast_device.evtdev->rating >= dev->rating) ||
|
|
@@ -73,6 +75,8 @@ int tick_check_broadcast_device(struct clock_event_device *dev)
|
|
return 0;
|
|
|
|
clockevents_exchange_device(tick_broadcast_device.evtdev, dev);
|
|
+ if (cur)
|
|
+ cur->event_handler = clockevents_handle_noop;
|
|
tick_broadcast_device.evtdev = dev;
|
|
if (!cpumask_empty(tick_get_broadcast_mask()))
|
|
tick_broadcast_start_periodic(dev);
|
|
diff --git a/kernel/time/tick-common.c b/kernel/time/tick-common.c
|
|
index da6c9ec..ead79bc 100644
|
|
--- a/kernel/time/tick-common.c
|
|
+++ b/kernel/time/tick-common.c
|
|
@@ -323,6 +323,7 @@ static void tick_shutdown(unsigned int *cpup)
|
|
*/
|
|
dev->mode = CLOCK_EVT_MODE_UNUSED;
|
|
clockevents_exchange_device(dev, NULL);
|
|
+ dev->event_handler = clockevents_handle_noop;
|
|
td->evtdev = NULL;
|
|
}
|
|
raw_spin_unlock_irqrestore(&tick_device_lock, flags);
|
|
diff --git a/kernel/trace/ftrace.c b/kernel/trace/ftrace.c
|
|
index a3c1dd9..c962d31 100644
|
|
--- a/kernel/trace/ftrace.c
|
|
+++ b/kernel/trace/ftrace.c
|
|
@@ -624,7 +624,7 @@ int ftrace_profile_pages_init(struct ftrace_profile_stat *stat)
|
|
|
|
pages = DIV_ROUND_UP(functions, PROFILES_PER_PAGE);
|
|
|
|
- for (i = 0; i < pages; i++) {
|
|
+ for (i = 1; i < pages; i++) {
|
|
pg->next = (void *)get_zeroed_page(GFP_KERNEL);
|
|
if (!pg->next)
|
|
goto out_free;
|
|
@@ -3611,7 +3611,8 @@ out:
|
|
if (fail)
|
|
return -EINVAL;
|
|
|
|
- ftrace_graph_filter_enabled = 1;
|
|
+ ftrace_graph_filter_enabled = !!(*idx);
|
|
+
|
|
return 0;
|
|
}
|
|
|
|
diff --git a/kernel/trace/trace.c b/kernel/trace/trace.c
|
|
index 8beda39..b29ebd3 100644
|
|
--- a/kernel/trace/trace.c
|
|
+++ b/kernel/trace/trace.c
|
|
@@ -4717,6 +4717,8 @@ static __init int tracer_init_debugfs(void)
|
|
trace_access_lock_init();
|
|
|
|
d_tracer = tracing_init_dentry();
|
|
+ if (!d_tracer)
|
|
+ return 0;
|
|
|
|
trace_create_file("tracing_enabled", 0644, d_tracer,
|
|
&global_trace, &tracing_ctrl_fops);
|
|
diff --git a/kernel/trace/trace_stack.c b/kernel/trace/trace_stack.c
|
|
index d4545f4..c70f6bf 100644
|
|
--- a/kernel/trace/trace_stack.c
|
|
+++ b/kernel/trace/trace_stack.c
|
|
@@ -20,13 +20,24 @@
|
|
|
|
#define STACK_TRACE_ENTRIES 500
|
|
|
|
+#ifdef CC_USING_FENTRY
|
|
+# define fentry 1
|
|
+#else
|
|
+# define fentry 0
|
|
+#endif
|
|
+
|
|
static unsigned long stack_dump_trace[STACK_TRACE_ENTRIES+1] =
|
|
{ [0 ... (STACK_TRACE_ENTRIES)] = ULONG_MAX };
|
|
static unsigned stack_dump_index[STACK_TRACE_ENTRIES];
|
|
|
|
+/*
|
|
+ * Reserve one entry for the passed in ip. This will allow
|
|
+ * us to remove most or all of the stack size overhead
|
|
+ * added by the stack tracer itself.
|
|
+ */
|
|
static struct stack_trace max_stack_trace = {
|
|
- .max_entries = STACK_TRACE_ENTRIES,
|
|
- .entries = stack_dump_trace,
|
|
+ .max_entries = STACK_TRACE_ENTRIES - 1,
|
|
+ .entries = &stack_dump_trace[1],
|
|
};
|
|
|
|
static unsigned long max_stack_size;
|
|
@@ -40,25 +51,34 @@ static DEFINE_MUTEX(stack_sysctl_mutex);
|
|
int stack_tracer_enabled;
|
|
static int last_stack_tracer_enabled;
|
|
|
|
-static inline void check_stack(void)
|
|
+static inline void
|
|
+check_stack(unsigned long ip, unsigned long *stack)
|
|
{
|
|
unsigned long this_size, flags;
|
|
unsigned long *p, *top, *start;
|
|
+ static int tracer_frame;
|
|
+ int frame_size = ACCESS_ONCE(tracer_frame);
|
|
int i;
|
|
|
|
- this_size = ((unsigned long)&this_size) & (THREAD_SIZE-1);
|
|
+ this_size = ((unsigned long)stack) & (THREAD_SIZE-1);
|
|
this_size = THREAD_SIZE - this_size;
|
|
+ /* Remove the frame of the tracer */
|
|
+ this_size -= frame_size;
|
|
|
|
if (this_size <= max_stack_size)
|
|
return;
|
|
|
|
/* we do not handle interrupt stacks yet */
|
|
- if (!object_is_on_stack(&this_size))
|
|
+ if (!object_is_on_stack(stack))
|
|
return;
|
|
|
|
local_irq_save(flags);
|
|
arch_spin_lock(&max_stack_lock);
|
|
|
|
+ /* In case another CPU set the tracer_frame on us */
|
|
+ if (unlikely(!frame_size))
|
|
+ this_size -= tracer_frame;
|
|
+
|
|
/* a race could have already updated it */
|
|
if (this_size <= max_stack_size)
|
|
goto out;
|
|
@@ -71,10 +91,18 @@ static inline void check_stack(void)
|
|
save_stack_trace(&max_stack_trace);
|
|
|
|
/*
|
|
+ * Add the passed in ip from the function tracer.
|
|
+ * Searching for this on the stack will skip over
|
|
+ * most of the overhead from the stack tracer itself.
|
|
+ */
|
|
+ stack_dump_trace[0] = ip;
|
|
+ max_stack_trace.nr_entries++;
|
|
+
|
|
+ /*
|
|
* Now find where in the stack these are.
|
|
*/
|
|
i = 0;
|
|
- start = &this_size;
|
|
+ start = stack;
|
|
top = (unsigned long *)
|
|
(((unsigned long)start & ~(THREAD_SIZE-1)) + THREAD_SIZE);
|
|
|
|
@@ -98,6 +126,18 @@ static inline void check_stack(void)
|
|
found = 1;
|
|
/* Start the search from here */
|
|
start = p + 1;
|
|
+ /*
|
|
+ * We do not want to show the overhead
|
|
+ * of the stack tracer stack in the
|
|
+ * max stack. If we haven't figured
|
|
+ * out what that is, then figure it out
|
|
+ * now.
|
|
+ */
|
|
+ if (unlikely(!tracer_frame) && i == 1) {
|
|
+ tracer_frame = (p - stack) *
|
|
+ sizeof(unsigned long);
|
|
+ max_stack_size -= tracer_frame;
|
|
+ }
|
|
}
|
|
}
|
|
|
|
@@ -113,6 +153,7 @@ static inline void check_stack(void)
|
|
static void
|
|
stack_trace_call(unsigned long ip, unsigned long parent_ip)
|
|
{
|
|
+ unsigned long stack;
|
|
int cpu;
|
|
|
|
if (unlikely(!ftrace_enabled || stack_trace_disabled))
|
|
@@ -125,7 +166,26 @@ stack_trace_call(unsigned long ip, unsigned long parent_ip)
|
|
if (per_cpu(trace_active, cpu)++ != 0)
|
|
goto out;
|
|
|
|
- check_stack();
|
|
+ /*
|
|
+ * When fentry is used, the traced function does not get
|
|
+ * its stack frame set up, and we lose the parent.
|
|
+ * The ip is pretty useless because the function tracer
|
|
+ * was called before that function set up its stack frame.
|
|
+ * In this case, we use the parent ip.
|
|
+ *
|
|
+ * By adding the return address of either the parent ip
|
|
+ * or the current ip we can disregard most of the stack usage
|
|
+ * caused by the stack tracer itself.
|
|
+ *
|
|
+ * The function tracer always reports the address of where the
|
|
+ * mcount call was, but the stack will hold the return address.
|
|
+ */
|
|
+ if (fentry)
|
|
+ ip = parent_ip;
|
|
+ else
|
|
+ ip += MCOUNT_INSN_SIZE;
|
|
+
|
|
+ check_stack(ip, &stack);
|
|
|
|
out:
|
|
per_cpu(trace_active, cpu)--;
|
|
@@ -373,6 +433,8 @@ static __init int stack_trace_init(void)
|
|
struct dentry *d_tracer;
|
|
|
|
d_tracer = tracing_init_dentry();
|
|
+ if (!d_tracer)
|
|
+ return 0;
|
|
|
|
trace_create_file("stack_max_size", 0644, d_tracer,
|
|
&max_stack_size, &stack_max_size_fops);
|
|
diff --git a/kernel/trace/trace_stat.c b/kernel/trace/trace_stat.c
|
|
index 96cffb2..847f88a 100644
|
|
--- a/kernel/trace/trace_stat.c
|
|
+++ b/kernel/trace/trace_stat.c
|
|
@@ -307,6 +307,8 @@ static int tracing_stat_init(void)
|
|
struct dentry *d_tracing;
|
|
|
|
d_tracing = tracing_init_dentry();
|
|
+ if (!d_tracing)
|
|
+ return 0;
|
|
|
|
stat_dir = debugfs_create_dir("trace_stat", d_tracing);
|
|
if (!stat_dir)
|
|
diff --git a/mm/mmap.c b/mm/mmap.c
|
|
index 2add0a1..3635d47 100644
|
|
--- a/mm/mmap.c
|
|
+++ b/mm/mmap.c
|
|
@@ -1920,7 +1920,7 @@ static void unmap_region(struct mm_struct *mm,
|
|
unmap_vmas(&tlb, vma, start, end, &nr_accounted, NULL);
|
|
vm_unacct_memory(nr_accounted);
|
|
free_pgtables(&tlb, vma, prev ? prev->vm_end : FIRST_USER_ADDRESS,
|
|
- next ? next->vm_start : 0);
|
|
+ next ? next->vm_start : USER_PGTABLES_CEILING);
|
|
tlb_finish_mmu(&tlb, start, end);
|
|
}
|
|
|
|
@@ -2308,7 +2308,7 @@ void exit_mmap(struct mm_struct *mm)
|
|
unmap_vmas(&tlb, vma, 0, -1, &nr_accounted, NULL);
|
|
vm_unacct_memory(nr_accounted);
|
|
|
|
- free_pgtables(&tlb, vma, FIRST_USER_ADDRESS, 0);
|
|
+ free_pgtables(&tlb, vma, FIRST_USER_ADDRESS, USER_PGTABLES_CEILING);
|
|
tlb_finish_mmu(&tlb, 0, -1);
|
|
|
|
/*
|
|
diff --git a/net/wireless/reg.c b/net/wireless/reg.c
|
|
index 4dc8347..796a0ee 100644
|
|
--- a/net/wireless/reg.c
|
|
+++ b/net/wireless/reg.c
|
|
@@ -862,7 +862,7 @@ static void handle_channel(struct wiphy *wiphy,
|
|
return;
|
|
|
|
REG_DBG_PRINT("Disabling freq %d MHz\n", chan->center_freq);
|
|
- chan->flags = IEEE80211_CHAN_DISABLED;
|
|
+ chan->flags |= IEEE80211_CHAN_DISABLED;
|
|
return;
|
|
}
|
|
|
|
diff --git a/sound/soc/codecs/max98088.c b/sound/soc/codecs/max98088.c
|
|
index af7324b..4790568 100644
|
|
--- a/sound/soc/codecs/max98088.c
|
|
+++ b/sound/soc/codecs/max98088.c
|
|
@@ -2006,7 +2006,7 @@ static int max98088_probe(struct snd_soc_codec *codec)
|
|
ret);
|
|
goto err_access;
|
|
}
|
|
- dev_info(codec->dev, "revision %c\n", ret + 'A');
|
|
+ dev_info(codec->dev, "revision %c\n", ret - 0x40 + 'A');
|
|
|
|
snd_soc_write(codec, M98088_REG_51_PWR_SYS, M98088_PWRSV);
|
|
|
|
diff --git a/sound/usb/card.c b/sound/usb/card.c
|
|
index 388460d..b41730d 100644
|
|
--- a/sound/usb/card.c
|
|
+++ b/sound/usb/card.c
|
|
@@ -611,7 +611,9 @@ int snd_usb_autoresume(struct snd_usb_audio *chip)
|
|
int err = -ENODEV;
|
|
|
|
down_read(&chip->shutdown_rwsem);
|
|
- if (!chip->shutdown && !chip->probing)
|
|
+ if (chip->probing)
|
|
+ err = 0;
|
|
+ else if (!chip->shutdown)
|
|
err = usb_autopm_get_interface(chip->pm_intf);
|
|
up_read(&chip->shutdown_rwsem);
|
|
|
|
diff --git a/sound/usb/midi.c b/sound/usb/midi.c
|
|
index 34b9bb7..e5fee18 100644
|
|
--- a/sound/usb/midi.c
|
|
+++ b/sound/usb/midi.c
|
|
@@ -126,7 +126,6 @@ struct snd_usb_midi {
|
|
struct snd_usb_midi_in_endpoint *in;
|
|
} endpoints[MIDI_MAX_ENDPOINTS];
|
|
unsigned long input_triggered;
|
|
- bool autopm_reference;
|
|
unsigned int opened[2];
|
|
unsigned char disconnected;
|
|
unsigned char input_running;
|
|
@@ -1040,7 +1039,6 @@ static int substream_open(struct snd_rawmidi_substream *substream, int dir,
|
|
{
|
|
struct snd_usb_midi* umidi = substream->rmidi->private_data;
|
|
struct snd_kcontrol *ctl;
|
|
- int err;
|
|
|
|
down_read(&umidi->disc_rwsem);
|
|
if (umidi->disconnected) {
|
|
@@ -1051,13 +1049,6 @@ static int substream_open(struct snd_rawmidi_substream *substream, int dir,
|
|
mutex_lock(&umidi->mutex);
|
|
if (open) {
|
|
if (!umidi->opened[0] && !umidi->opened[1]) {
|
|
- err = usb_autopm_get_interface(umidi->iface);
|
|
- umidi->autopm_reference = err >= 0;
|
|
- if (err < 0 && err != -EACCES) {
|
|
- mutex_unlock(&umidi->mutex);
|
|
- up_read(&umidi->disc_rwsem);
|
|
- return -EIO;
|
|
- }
|
|
if (umidi->roland_load_ctl) {
|
|
ctl = umidi->roland_load_ctl;
|
|
ctl->vd[0].access |= SNDRV_CTL_ELEM_ACCESS_INACTIVE;
|
|
@@ -1080,8 +1071,6 @@ static int substream_open(struct snd_rawmidi_substream *substream, int dir,
|
|
snd_ctl_notify(umidi->card,
|
|
SNDRV_CTL_EVENT_MASK_INFO, &ctl->id);
|
|
}
|
|
- if (umidi->autopm_reference)
|
|
- usb_autopm_put_interface(umidi->iface);
|
|
}
|
|
}
|
|
mutex_unlock(&umidi->mutex);
|
|
@@ -2256,6 +2245,8 @@ int snd_usbmidi_create(struct snd_card *card,
|
|
return err;
|
|
}
|
|
|
|
+ usb_autopm_get_interface_no_resume(umidi->iface);
|
|
+
|
|
list_add_tail(&umidi->list, midi_list);
|
|
return 0;
|
|
}
|
|
diff --git a/sound/usb/stream.c b/sound/usb/stream.c
|
|
index 5ff8010..33a335b 100644
|
|
--- a/sound/usb/stream.c
|
|
+++ b/sound/usb/stream.c
|
|
@@ -168,6 +168,14 @@ static int parse_uac_endpoint_attributes(struct snd_usb_audio *chip,
|
|
if (!csep && altsd->bNumEndpoints >= 2)
|
|
csep = snd_usb_find_desc(alts->endpoint[1].extra, alts->endpoint[1].extralen, NULL, USB_DT_CS_ENDPOINT);
|
|
|
|
+ /*
|
|
+ * If we can't locate the USB_DT_CS_ENDPOINT descriptor in the extra
|
|
+ * bytes after the first endpoint, go search the entire interface.
|
|
+ * Some devices have it directly *before* the standard endpoint.
|
|
+ */
|
|
+ if (!csep)
|
|
+ csep = snd_usb_find_desc(alts->extra, alts->extralen, NULL, USB_DT_CS_ENDPOINT);
|
|
+
|
|
if (!csep || csep->bLength < 7 ||
|
|
csep->bDescriptorSubtype != UAC_EP_GENERAL) {
|
|
snd_printk(KERN_WARNING "%d:%u:%d : no or invalid"
|