Merge tag 'v3.10.69' into update
This is the 3.10.69 stable release
This commit is contained in:
@@ -1,6 +1,6 @@
|
||||
VERSION = 3
|
||||
PATCHLEVEL = 10
|
||||
SUBLEVEL = 68
|
||||
SUBLEVEL = 69
|
||||
EXTRAVERSION =
|
||||
NAME = TOSSUG Baby Fish
|
||||
|
||||
|
||||
@@ -85,6 +85,8 @@ static inline u32 __attribute_const__ read_cpuid_cachetype(void)
|
||||
return read_cpuid(CTR_EL0);
|
||||
}
|
||||
|
||||
void cpuinfo_store_cpu(void);
|
||||
|
||||
#endif /* __ASSEMBLY__ */
|
||||
|
||||
#endif
|
||||
|
||||
+76
-37
@@ -41,6 +41,7 @@
|
||||
#include <linux/memblock.h>
|
||||
#include <linux/of_fdt.h>
|
||||
#include <linux/of_platform.h>
|
||||
#include <linux/personality.h>
|
||||
|
||||
#include <asm/cputype.h>
|
||||
#include <asm/elf.h>
|
||||
@@ -109,7 +110,20 @@ void __init early_print(const char *str, ...)
|
||||
printk("%s", buf);
|
||||
}
|
||||
|
||||
void __init smp_setup_processor_id(void)
|
||||
struct cpuinfo_arm64 {
|
||||
struct cpu cpu;
|
||||
u32 reg_midr;
|
||||
};
|
||||
|
||||
static DEFINE_PER_CPU(struct cpuinfo_arm64, cpu_data);
|
||||
|
||||
void cpuinfo_store_cpu(void)
|
||||
{
|
||||
struct cpuinfo_arm64 *info = this_cpu_ptr(&cpu_data);
|
||||
info->reg_midr = read_cpuid_id();
|
||||
}
|
||||
|
||||
static void __init setup_processor(void)
|
||||
{
|
||||
/*
|
||||
* clear __my_cpu_offset on boot CPU to avoid hang caused by
|
||||
@@ -250,6 +264,8 @@ static void __init setup_machine_fdt(phys_addr_t dt_phys)
|
||||
struct boot_param_header *devtree;
|
||||
unsigned long dt_root;
|
||||
|
||||
cpuinfo_store_cpu();
|
||||
|
||||
/* Check we have a non-NULL DT pointer */
|
||||
if (!dt_phys) {
|
||||
early_print("\n"
|
||||
@@ -416,14 +432,12 @@ static int __init arm64_device_init(void)
|
||||
}
|
||||
arch_initcall_sync(arm64_device_init);
|
||||
|
||||
static DEFINE_PER_CPU(struct cpu, cpu_data);
|
||||
|
||||
static int __init topology_init(void)
|
||||
{
|
||||
int i;
|
||||
|
||||
for_each_possible_cpu(i) {
|
||||
struct cpu *cpu = &per_cpu(cpu_data, i);
|
||||
struct cpu *cpu = &per_cpu(cpu_data.cpu, i);
|
||||
cpu->hotpluggable = 1;
|
||||
register_cpu(cpu, i);
|
||||
}
|
||||
@@ -444,14 +458,41 @@ static const char *hwcap_str[] = {
|
||||
NULL
|
||||
};
|
||||
|
||||
#ifdef CONFIG_COMPAT
|
||||
static const char *compat_hwcap_str[] = {
|
||||
"swp",
|
||||
"half",
|
||||
"thumb",
|
||||
"26bit",
|
||||
"fastmult",
|
||||
"fpa",
|
||||
"vfp",
|
||||
"edsp",
|
||||
"java",
|
||||
"iwmmxt",
|
||||
"crunch",
|
||||
"thumbee",
|
||||
"neon",
|
||||
"vfpv3",
|
||||
"vfpv3d16",
|
||||
"tls",
|
||||
"vfpv4",
|
||||
"idiva",
|
||||
"idivt",
|
||||
"vfpd32",
|
||||
"lpae",
|
||||
"evtstrm"
|
||||
};
|
||||
#endif /* CONFIG_COMPAT */
|
||||
|
||||
static int c_show(struct seq_file *m, void *v)
|
||||
{
|
||||
int i;
|
||||
|
||||
seq_printf(m, "Processor\t: %s rev %d (%s)\n",
|
||||
cpu_name, read_cpuid_id() & 15, ELF_PLATFORM);
|
||||
int i, j;
|
||||
|
||||
for_each_online_cpu(i) {
|
||||
struct cpuinfo_arm64 *cpuinfo = &per_cpu(cpu_data, i);
|
||||
u32 midr = cpuinfo->reg_midr;
|
||||
|
||||
/*
|
||||
* glibc reads /proc/cpuinfo to determine the number of
|
||||
* online processors, looking for lines beginning with
|
||||
@@ -460,39 +501,37 @@ static int c_show(struct seq_file *m, void *v)
|
||||
#ifdef CONFIG_SMP
|
||||
seq_printf(m, "processor\t: %d\n", i);
|
||||
#endif
|
||||
seq_printf(m, "BogoMIPS\t: %lu.%02lu\n\n",
|
||||
seq_printf(m, "BogoMIPS\t: %lu.%02lu\n",
|
||||
loops_per_jiffy / (500000UL/HZ),
|
||||
loops_per_jiffy / (5000UL/HZ) % 100);
|
||||
|
||||
/*
|
||||
* Dump out the common processor features in a single line.
|
||||
* Userspace should read the hwcaps with getauxval(AT_HWCAP)
|
||||
* rather than attempting to parse this, but there's a body of
|
||||
* software which does already (at least for 32-bit).
|
||||
*/
|
||||
seq_puts(m, "Features\t:");
|
||||
if (personality(current->personality) == PER_LINUX32) {
|
||||
#ifdef CONFIG_COMPAT
|
||||
for (j = 0; compat_hwcap_str[j]; j++)
|
||||
if (COMPAT_ELF_HWCAP & (1 << j))
|
||||
seq_printf(m, " %s", compat_hwcap_str[j]);
|
||||
#endif /* CONFIG_COMPAT */
|
||||
} else {
|
||||
for (j = 0; hwcap_str[j]; j++)
|
||||
if (elf_hwcap & (1 << j))
|
||||
seq_printf(m, " %s", hwcap_str[j]);
|
||||
}
|
||||
seq_puts(m, "\n");
|
||||
|
||||
seq_printf(m, "CPU implementer\t: 0x%02x\n", (midr >> 24));
|
||||
seq_printf(m, "CPU architecture: 8\n");
|
||||
seq_printf(m, "CPU variant\t: 0x%x\n", ((midr >> 20) & 0xf));
|
||||
seq_printf(m, "CPU part\t: 0x%03x\n", ((midr >> 4) & 0xfff));
|
||||
seq_printf(m, "CPU revision\t: %d\n\n", (midr & 0xf));
|
||||
}
|
||||
|
||||
/* dump out the processor features */
|
||||
seq_puts(m, "Features\t: ");
|
||||
|
||||
for (i = 0; hwcap_str[i]; i++)
|
||||
if (elf_hwcap & (1 << i))
|
||||
seq_printf(m, "%s ", hwcap_str[i]);
|
||||
#ifdef CONFIG_ARMV7_COMPAT_CPUINFO
|
||||
if (is_compat_task()) {
|
||||
/* Print out the non-optional ARMv8 HW capabilities */
|
||||
seq_printf(m, "wp half thumb fastmult vfp edsp neon vfpv3 tlsi ");
|
||||
seq_printf(m, "vfpv4 idiva idivt ");
|
||||
}
|
||||
#endif
|
||||
|
||||
seq_printf(m, "\nCPU implementer\t: 0x%02x\n", read_cpuid_id() >> 24);
|
||||
seq_printf(m, "CPU architecture: %s\n",
|
||||
#if IS_ENABLED(CONFIG_ARMV7_COMPAT_CPUINFO)
|
||||
is_compat_task() ? "8" :
|
||||
#endif
|
||||
"AArch64");
|
||||
seq_printf(m, "CPU variant\t: 0x%x\n", (read_cpuid_id() >> 20) & 15);
|
||||
seq_printf(m, "CPU part\t: 0x%03x\n", (read_cpuid_id() >> 4) & 0xfff);
|
||||
seq_printf(m, "CPU revision\t: %d\n", read_cpuid_id() & 15);
|
||||
|
||||
seq_puts(m, "\n");
|
||||
|
||||
seq_printf(m, "Hardware\t: %s\n", machine_name);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
@@ -157,6 +157,11 @@ asmlinkage void __cpuinit secondary_start_kernel(void)
|
||||
if (cpu_ops[cpu]->cpu_postboot)
|
||||
cpu_ops[cpu]->cpu_postboot();
|
||||
|
||||
/*
|
||||
* Log the CPU info before it is marked online and might get read.
|
||||
*/
|
||||
cpuinfo_store_cpu();
|
||||
|
||||
/*
|
||||
* OK, now it's safe to let the boot CPU continue. Wait for
|
||||
* the CPU migration code to notice that the CPU is online
|
||||
|
||||
@@ -56,6 +56,8 @@ static struct irq_chip mips_cpu_irq_controller = {
|
||||
.irq_mask_ack = mask_mips_irq,
|
||||
.irq_unmask = unmask_mips_irq,
|
||||
.irq_eoi = unmask_mips_irq,
|
||||
.irq_disable = mask_mips_irq,
|
||||
.irq_enable = unmask_mips_irq,
|
||||
};
|
||||
|
||||
/*
|
||||
@@ -92,6 +94,8 @@ static struct irq_chip mips_mt_cpu_irq_controller = {
|
||||
.irq_mask_ack = mips_mt_cpu_irq_ack,
|
||||
.irq_unmask = unmask_mips_irq,
|
||||
.irq_eoi = unmask_mips_irq,
|
||||
.irq_disable = mask_mips_irq,
|
||||
.irq_enable = unmask_mips_irq,
|
||||
};
|
||||
|
||||
void __init mips_cpu_irq_init(void)
|
||||
|
||||
@@ -109,10 +109,10 @@ asmlinkage __cpuinit void start_secondary(void)
|
||||
else
|
||||
#endif /* CONFIG_MIPS_MT_SMTC */
|
||||
cpu_probe();
|
||||
cpu_report();
|
||||
per_cpu_trap_init(false);
|
||||
mips_clockevent_init();
|
||||
mp_ops->init_secondary();
|
||||
cpu_report();
|
||||
|
||||
/*
|
||||
* XXX parity protection should be folded in here when it's converted
|
||||
|
||||
@@ -67,6 +67,7 @@
|
||||
#define EXIT_REASON_EPT_MISCONFIG 49
|
||||
#define EXIT_REASON_INVEPT 50
|
||||
#define EXIT_REASON_PREEMPTION_TIMER 52
|
||||
#define EXIT_REASON_INVVPID 53
|
||||
#define EXIT_REASON_WBINVD 54
|
||||
#define EXIT_REASON_XSETBV 55
|
||||
#define EXIT_REASON_APIC_WRITE 56
|
||||
@@ -112,6 +113,7 @@
|
||||
{ EXIT_REASON_EOI_INDUCED, "EOI_INDUCED" }, \
|
||||
{ EXIT_REASON_INVALID_STATE, "INVALID_STATE" }, \
|
||||
{ EXIT_REASON_INVD, "INVD" }, \
|
||||
{ EXIT_REASON_INVVPID, "INVVPID" }, \
|
||||
{ EXIT_REASON_INVPCID, "INVPCID" }, \
|
||||
{ EXIT_REASON_PREEMPTION_TIMER, "PREEMPTION_TIMER" }
|
||||
|
||||
|
||||
+22
-3
@@ -438,6 +438,7 @@ struct vcpu_vmx {
|
||||
#endif
|
||||
int gs_ldt_reload_needed;
|
||||
int fs_reload_needed;
|
||||
unsigned long vmcs_host_cr4; /* May not match real cr4 */
|
||||
} host_state;
|
||||
struct {
|
||||
int vm86_active;
|
||||
@@ -4076,11 +4077,16 @@ static void vmx_set_constant_host_state(struct vcpu_vmx *vmx)
|
||||
u32 low32, high32;
|
||||
unsigned long tmpl;
|
||||
struct desc_ptr dt;
|
||||
unsigned long cr4;
|
||||
|
||||
vmcs_writel(HOST_CR0, read_cr0() & ~X86_CR0_TS); /* 22.2.3 */
|
||||
vmcs_writel(HOST_CR4, read_cr4()); /* 22.2.3, 22.2.5 */
|
||||
vmcs_writel(HOST_CR3, read_cr3()); /* 22.2.3 FIXME: shadow tables */
|
||||
|
||||
/* Save the most likely value for this task's CR4 in the VMCS. */
|
||||
cr4 = read_cr4();
|
||||
vmcs_writel(HOST_CR4, cr4); /* 22.2.3, 22.2.5 */
|
||||
vmx->host_state.vmcs_host_cr4 = cr4;
|
||||
|
||||
vmcs_write16(HOST_CS_SELECTOR, __KERNEL_CS); /* 22.2.4 */
|
||||
#ifdef CONFIG_X86_64
|
||||
/*
|
||||
@@ -6248,6 +6254,12 @@ static int handle_invept(struct kvm_vcpu *vcpu)
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int handle_invvpid(struct kvm_vcpu *vcpu)
|
||||
{
|
||||
kvm_queue_exception(vcpu, UD_VECTOR);
|
||||
return 1;
|
||||
}
|
||||
|
||||
/*
|
||||
* The exit handlers return 1 if the exit was handled fully and guest execution
|
||||
* may resume. Otherwise they set the kvm_run parameter to indicate what needs
|
||||
@@ -6293,6 +6305,7 @@ static int (*const kvm_vmx_exit_handlers[])(struct kvm_vcpu *vcpu) = {
|
||||
[EXIT_REASON_MWAIT_INSTRUCTION] = handle_invalid_op,
|
||||
[EXIT_REASON_MONITOR_INSTRUCTION] = handle_invalid_op,
|
||||
[EXIT_REASON_INVEPT] = handle_invept,
|
||||
[EXIT_REASON_INVVPID] = handle_invvpid,
|
||||
};
|
||||
|
||||
static const int kvm_vmx_max_exit_handlers =
|
||||
@@ -6519,7 +6532,7 @@ static bool nested_vmx_exit_handled(struct kvm_vcpu *vcpu)
|
||||
case EXIT_REASON_VMPTRST: case EXIT_REASON_VMREAD:
|
||||
case EXIT_REASON_VMRESUME: case EXIT_REASON_VMWRITE:
|
||||
case EXIT_REASON_VMOFF: case EXIT_REASON_VMON:
|
||||
case EXIT_REASON_INVEPT:
|
||||
case EXIT_REASON_INVEPT: case EXIT_REASON_INVVPID:
|
||||
/*
|
||||
* VMX instructions trap unconditionally. This allows L1 to
|
||||
* emulate them for its L2 guest, i.e., allows 3-level nesting!
|
||||
@@ -6964,7 +6977,7 @@ static void atomic_switch_perf_msrs(struct vcpu_vmx *vmx)
|
||||
static void __noclone vmx_vcpu_run(struct kvm_vcpu *vcpu)
|
||||
{
|
||||
struct vcpu_vmx *vmx = to_vmx(vcpu);
|
||||
unsigned long debugctlmsr;
|
||||
unsigned long debugctlmsr, cr4;
|
||||
|
||||
/* Record the guest's net vcpu time for enforced NMI injections. */
|
||||
if (unlikely(!cpu_has_virtual_nmis() && vmx->soft_vnmi_blocked))
|
||||
@@ -6985,6 +6998,12 @@ static void __noclone vmx_vcpu_run(struct kvm_vcpu *vcpu)
|
||||
if (test_bit(VCPU_REGS_RIP, (unsigned long *)&vcpu->arch.regs_dirty))
|
||||
vmcs_writel(GUEST_RIP, vcpu->arch.regs[VCPU_REGS_RIP]);
|
||||
|
||||
cr4 = read_cr4();
|
||||
if (unlikely(cr4 != vmx->host_state.vmcs_host_cr4)) {
|
||||
vmcs_writel(HOST_CR4, cr4);
|
||||
vmx->host_state.vmcs_host_cr4 = cr4;
|
||||
}
|
||||
|
||||
/* When single-stepping over STI and MOV SS, we must clear the
|
||||
* corresponding interruptibility bits in the guest state. Otherwise
|
||||
* vmentry fails as it then expects bit 14 (BS) in pending debug
|
||||
|
||||
@@ -448,6 +448,22 @@ static const struct dmi_system_id pciprobe_dmi_table[] = {
|
||||
DMI_MATCH(DMI_PRODUCT_NAME, "ftServer"),
|
||||
},
|
||||
},
|
||||
{
|
||||
.callback = set_scan_all,
|
||||
.ident = "Stratus/NEC ftServer",
|
||||
.matches = {
|
||||
DMI_MATCH(DMI_SYS_VENDOR, "NEC"),
|
||||
DMI_MATCH(DMI_PRODUCT_NAME, "Express5800/R32"),
|
||||
},
|
||||
},
|
||||
{
|
||||
.callback = set_scan_all,
|
||||
.ident = "Stratus/NEC ftServer",
|
||||
.matches = {
|
||||
DMI_MATCH(DMI_SYS_VENDOR, "NEC"),
|
||||
DMI_MATCH(DMI_PRODUCT_NAME, "Express5800/R31"),
|
||||
},
|
||||
},
|
||||
{}
|
||||
};
|
||||
|
||||
|
||||
@@ -170,3 +170,4 @@ module_exit(crc32c_mod_fini);
|
||||
MODULE_AUTHOR("Clay Haapala <chaapala@cisco.com>");
|
||||
MODULE_DESCRIPTION("CRC32c (Castagnoli) calculations wrapper for lib/crc32c");
|
||||
MODULE_LICENSE("GPL");
|
||||
MODULE_ALIAS_CRYPTO("crc32c");
|
||||
|
||||
@@ -874,6 +874,7 @@ static int gpiod_export_link(struct device *dev, const char *name,
|
||||
if (tdev != NULL) {
|
||||
status = sysfs_create_link(&dev->kobj, &tdev->kobj,
|
||||
name);
|
||||
put_device(tdev);
|
||||
} else {
|
||||
status = -ENODEV;
|
||||
}
|
||||
@@ -927,7 +928,7 @@ static int gpiod_sysfs_set_active_low(struct gpio_desc *desc, int value)
|
||||
}
|
||||
|
||||
status = sysfs_set_active_low(desc, dev, value);
|
||||
|
||||
put_device(dev);
|
||||
unlock:
|
||||
mutex_unlock(&sysfs_lock);
|
||||
|
||||
|
||||
+4
-4
@@ -100,7 +100,7 @@ ext4_file_dio_write(struct kiocb *iocb, const struct iovec *iov,
|
||||
struct blk_plug plug;
|
||||
int unaligned_aio = 0;
|
||||
ssize_t ret;
|
||||
int overwrite = 0;
|
||||
int *overwrite = iocb->private;
|
||||
size_t length = iov_length(iov, nr_segs);
|
||||
|
||||
if (ext4_test_inode_flag(inode, EXT4_INODE_EXTENTS) &&
|
||||
@@ -118,8 +118,6 @@ ext4_file_dio_write(struct kiocb *iocb, const struct iovec *iov,
|
||||
mutex_lock(&inode->i_mutex);
|
||||
blk_start_plug(&plug);
|
||||
|
||||
iocb->private = &overwrite;
|
||||
|
||||
/* check whether we do a DIO overwrite or not */
|
||||
if (ext4_should_dioread_nolock(inode) && !unaligned_aio &&
|
||||
!file->f_mapping->nrpages && pos + length <= i_size_read(inode)) {
|
||||
@@ -143,7 +141,7 @@ ext4_file_dio_write(struct kiocb *iocb, const struct iovec *iov,
|
||||
* So we should check these two conditions.
|
||||
*/
|
||||
if (err == len && (map.m_flags & EXT4_MAP_MAPPED))
|
||||
overwrite = 1;
|
||||
*overwrite = 1;
|
||||
}
|
||||
|
||||
ret = __generic_file_aio_write(iocb, iov, nr_segs, &iocb->ki_pos);
|
||||
@@ -170,6 +168,7 @@ ext4_file_write(struct kiocb *iocb, const struct iovec *iov,
|
||||
{
|
||||
struct inode *inode = file_inode(iocb->ki_filp);
|
||||
ssize_t ret;
|
||||
int overwrite = 0;
|
||||
|
||||
/*
|
||||
* If we have encountered a bitmap-format file, the size limit
|
||||
@@ -190,6 +189,7 @@ ext4_file_write(struct kiocb *iocb, const struct iovec *iov,
|
||||
}
|
||||
}
|
||||
|
||||
iocb->private = &overwrite;
|
||||
if (unlikely(iocb->ki_filp->f_flags & O_DIRECT))
|
||||
ret = ext4_file_dio_write(iocb, iov, nr_segs, pos);
|
||||
else
|
||||
|
||||
@@ -141,7 +141,6 @@ enum {
|
||||
* @ti_save: Backup of journal_info field of task_struct
|
||||
* @ti_flags: Flags
|
||||
* @ti_count: Nest level
|
||||
* @ti_garbage: List of inode to be put when releasing semaphore
|
||||
*/
|
||||
struct nilfs_transaction_info {
|
||||
u32 ti_magic;
|
||||
@@ -150,7 +149,6 @@ struct nilfs_transaction_info {
|
||||
one of other filesystems has a bug. */
|
||||
unsigned short ti_flags;
|
||||
unsigned short ti_count;
|
||||
struct list_head ti_garbage;
|
||||
};
|
||||
|
||||
/* ti_magic */
|
||||
|
||||
+39
-5
@@ -305,7 +305,6 @@ static void nilfs_transaction_lock(struct super_block *sb,
|
||||
ti->ti_count = 0;
|
||||
ti->ti_save = cur_ti;
|
||||
ti->ti_magic = NILFS_TI_MAGIC;
|
||||
INIT_LIST_HEAD(&ti->ti_garbage);
|
||||
current->journal_info = ti;
|
||||
|
||||
for (;;) {
|
||||
@@ -332,8 +331,6 @@ static void nilfs_transaction_unlock(struct super_block *sb)
|
||||
|
||||
up_write(&nilfs->ns_segctor_sem);
|
||||
current->journal_info = ti->ti_save;
|
||||
if (!list_empty(&ti->ti_garbage))
|
||||
nilfs_dispose_list(nilfs, &ti->ti_garbage, 0);
|
||||
}
|
||||
|
||||
static void *nilfs_segctor_map_segsum_entry(struct nilfs_sc_info *sci,
|
||||
@@ -746,6 +743,15 @@ static void nilfs_dispose_list(struct the_nilfs *nilfs,
|
||||
}
|
||||
}
|
||||
|
||||
static void nilfs_iput_work_func(struct work_struct *work)
|
||||
{
|
||||
struct nilfs_sc_info *sci = container_of(work, struct nilfs_sc_info,
|
||||
sc_iput_work);
|
||||
struct the_nilfs *nilfs = sci->sc_super->s_fs_info;
|
||||
|
||||
nilfs_dispose_list(nilfs, &sci->sc_iput_queue, 0);
|
||||
}
|
||||
|
||||
static int nilfs_test_metadata_dirty(struct the_nilfs *nilfs,
|
||||
struct nilfs_root *root)
|
||||
{
|
||||
@@ -1899,8 +1905,8 @@ static int nilfs_segctor_collect_dirty_files(struct nilfs_sc_info *sci,
|
||||
static void nilfs_segctor_drop_written_files(struct nilfs_sc_info *sci,
|
||||
struct the_nilfs *nilfs)
|
||||
{
|
||||
struct nilfs_transaction_info *ti = current->journal_info;
|
||||
struct nilfs_inode_info *ii, *n;
|
||||
int defer_iput = false;
|
||||
|
||||
spin_lock(&nilfs->ns_inode_lock);
|
||||
list_for_each_entry_safe(ii, n, &sci->sc_dirty_files, i_dirty) {
|
||||
@@ -1911,9 +1917,24 @@ static void nilfs_segctor_drop_written_files(struct nilfs_sc_info *sci,
|
||||
clear_bit(NILFS_I_BUSY, &ii->i_state);
|
||||
brelse(ii->i_bh);
|
||||
ii->i_bh = NULL;
|
||||
list_move_tail(&ii->i_dirty, &ti->ti_garbage);
|
||||
list_del_init(&ii->i_dirty);
|
||||
if (!ii->vfs_inode.i_nlink) {
|
||||
/*
|
||||
* Defer calling iput() to avoid a deadlock
|
||||
* over I_SYNC flag for inodes with i_nlink == 0
|
||||
*/
|
||||
list_add_tail(&ii->i_dirty, &sci->sc_iput_queue);
|
||||
defer_iput = true;
|
||||
} else {
|
||||
spin_unlock(&nilfs->ns_inode_lock);
|
||||
iput(&ii->vfs_inode);
|
||||
spin_lock(&nilfs->ns_inode_lock);
|
||||
}
|
||||
}
|
||||
spin_unlock(&nilfs->ns_inode_lock);
|
||||
|
||||
if (defer_iput)
|
||||
schedule_work(&sci->sc_iput_work);
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -2582,6 +2603,8 @@ static struct nilfs_sc_info *nilfs_segctor_new(struct super_block *sb,
|
||||
INIT_LIST_HEAD(&sci->sc_segbufs);
|
||||
INIT_LIST_HEAD(&sci->sc_write_logs);
|
||||
INIT_LIST_HEAD(&sci->sc_gc_inodes);
|
||||
INIT_LIST_HEAD(&sci->sc_iput_queue);
|
||||
INIT_WORK(&sci->sc_iput_work, nilfs_iput_work_func);
|
||||
init_timer(&sci->sc_timer);
|
||||
|
||||
sci->sc_interval = HZ * NILFS_SC_DEFAULT_TIMEOUT;
|
||||
@@ -2608,6 +2631,8 @@ static void nilfs_segctor_write_out(struct nilfs_sc_info *sci)
|
||||
ret = nilfs_segctor_construct(sci, SC_LSEG_SR);
|
||||
nilfs_transaction_unlock(sci->sc_super);
|
||||
|
||||
flush_work(&sci->sc_iput_work);
|
||||
|
||||
} while (ret && retrycount-- > 0);
|
||||
}
|
||||
|
||||
@@ -2632,6 +2657,9 @@ static void nilfs_segctor_destroy(struct nilfs_sc_info *sci)
|
||||
|| sci->sc_seq_request != sci->sc_seq_done);
|
||||
spin_unlock(&sci->sc_state_lock);
|
||||
|
||||
if (flush_work(&sci->sc_iput_work))
|
||||
flag = true;
|
||||
|
||||
if (flag || !nilfs_segctor_confirm(sci))
|
||||
nilfs_segctor_write_out(sci);
|
||||
|
||||
@@ -2641,6 +2669,12 @@ static void nilfs_segctor_destroy(struct nilfs_sc_info *sci)
|
||||
nilfs_dispose_list(nilfs, &sci->sc_dirty_files, 1);
|
||||
}
|
||||
|
||||
if (!list_empty(&sci->sc_iput_queue)) {
|
||||
nilfs_warning(sci->sc_super, __func__,
|
||||
"iput queue is not empty\n");
|
||||
nilfs_dispose_list(nilfs, &sci->sc_iput_queue, 1);
|
||||
}
|
||||
|
||||
WARN_ON(!list_empty(&sci->sc_segbufs));
|
||||
WARN_ON(!list_empty(&sci->sc_write_logs));
|
||||
|
||||
|
||||
@@ -26,6 +26,7 @@
|
||||
#include <linux/types.h>
|
||||
#include <linux/fs.h>
|
||||
#include <linux/buffer_head.h>
|
||||
#include <linux/workqueue.h>
|
||||
#include <linux/nilfs2_fs.h>
|
||||
#include "nilfs.h"
|
||||
|
||||
@@ -92,6 +93,8 @@ struct nilfs_segsum_pointer {
|
||||
* @sc_nblk_inc: Block count of current generation
|
||||
* @sc_dirty_files: List of files to be written
|
||||
* @sc_gc_inodes: List of GC inodes having blocks to be written
|
||||
* @sc_iput_queue: list of inodes for which iput should be done
|
||||
* @sc_iput_work: work struct to defer iput call
|
||||
* @sc_freesegs: array of segment numbers to be freed
|
||||
* @sc_nfreesegs: number of segments on @sc_freesegs
|
||||
* @sc_dsync_inode: inode whose data pages are written for a sync operation
|
||||
@@ -135,6 +138,8 @@ struct nilfs_sc_info {
|
||||
|
||||
struct list_head sc_dirty_files;
|
||||
struct list_head sc_gc_inodes;
|
||||
struct list_head sc_iput_queue;
|
||||
struct work_struct sc_iput_work;
|
||||
|
||||
__u64 *sc_freesegs;
|
||||
size_t sc_nfreesegs;
|
||||
|
||||
@@ -286,7 +286,7 @@ struct ak4113 {
|
||||
ak4113_write_t *write;
|
||||
ak4113_read_t *read;
|
||||
void *private_data;
|
||||
unsigned int init:1;
|
||||
atomic_t wq_processing;
|
||||
spinlock_t lock;
|
||||
unsigned char regmap[AK4113_WRITABLE_REGS];
|
||||
struct snd_kcontrol *kctls[AK4113_CONTROLS];
|
||||
|
||||
@@ -168,7 +168,7 @@ struct ak4114 {
|
||||
ak4114_write_t * write;
|
||||
ak4114_read_t * read;
|
||||
void * private_data;
|
||||
unsigned int init: 1;
|
||||
atomic_t wq_processing;
|
||||
spinlock_t lock;
|
||||
unsigned char regmap[7];
|
||||
unsigned char txcsb[5];
|
||||
|
||||
@@ -279,6 +279,7 @@ int smpboot_register_percpu_thread(struct smp_hotplug_thread *plug_thread)
|
||||
unsigned int cpu;
|
||||
int ret = 0;
|
||||
|
||||
get_online_cpus();
|
||||
mutex_lock(&smpboot_threads_lock);
|
||||
for_each_online_cpu(cpu) {
|
||||
ret = __smpboot_create_thread(plug_thread, cpu);
|
||||
@@ -291,6 +292,7 @@ int smpboot_register_percpu_thread(struct smp_hotplug_thread *plug_thread)
|
||||
list_add(&plug_thread->list, &hotplug_threads);
|
||||
out:
|
||||
mutex_unlock(&smpboot_threads_lock);
|
||||
put_online_cpus();
|
||||
return ret;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(smpboot_register_percpu_thread);
|
||||
|
||||
+10
-2
@@ -181,6 +181,15 @@ csum_partial_copy(const void *src, void *dst, int len, __wsum sum)
|
||||
EXPORT_SYMBOL(csum_partial_copy);
|
||||
|
||||
#ifndef csum_tcpudp_nofold
|
||||
static inline u32 from64to32(u64 x)
|
||||
{
|
||||
/* add up 32-bit and 32-bit for 32+c bit */
|
||||
x = (x & 0xffffffff) + (x >> 32);
|
||||
/* add up carry.. */
|
||||
x = (x & 0xffffffff) + (x >> 32);
|
||||
return (u32)x;
|
||||
}
|
||||
|
||||
__wsum csum_tcpudp_nofold(__be32 saddr, __be32 daddr,
|
||||
unsigned short len,
|
||||
unsigned short proto,
|
||||
@@ -195,8 +204,7 @@ __wsum csum_tcpudp_nofold(__be32 saddr, __be32 daddr,
|
||||
#else
|
||||
s += (proto + len) << 8;
|
||||
#endif
|
||||
s += (s >> 32);
|
||||
return (__force __wsum)s;
|
||||
return (__force __wsum)from64to32(s);
|
||||
}
|
||||
EXPORT_SYMBOL(csum_tcpudp_nofold);
|
||||
#endif
|
||||
|
||||
+4
-1
@@ -199,7 +199,10 @@ int walk_page_range(unsigned long addr, unsigned long end,
|
||||
*/
|
||||
if ((vma->vm_start <= addr) &&
|
||||
(vma->vm_flags & VM_PFNMAP)) {
|
||||
next = vma->vm_end;
|
||||
if (walk->pte_hole)
|
||||
err = walk->pte_hole(addr, next, walk);
|
||||
if (err)
|
||||
break;
|
||||
pgd = pgd_offset(walk->mm, next);
|
||||
continue;
|
||||
}
|
||||
|
||||
@@ -56,8 +56,7 @@ static inline unsigned char reg_read(struct ak4113 *ak4113, unsigned char reg)
|
||||
|
||||
static void snd_ak4113_free(struct ak4113 *chip)
|
||||
{
|
||||
chip->init = 1; /* don't schedule new work */
|
||||
mb();
|
||||
atomic_inc(&chip->wq_processing); /* don't schedule new work */
|
||||
cancel_delayed_work_sync(&chip->work);
|
||||
kfree(chip);
|
||||
}
|
||||
@@ -89,6 +88,7 @@ int snd_ak4113_create(struct snd_card *card, ak4113_read_t *read,
|
||||
chip->write = write;
|
||||
chip->private_data = private_data;
|
||||
INIT_DELAYED_WORK(&chip->work, ak4113_stats);
|
||||
atomic_set(&chip->wq_processing, 0);
|
||||
|
||||
for (reg = 0; reg < AK4113_WRITABLE_REGS ; reg++)
|
||||
chip->regmap[reg] = pgm[reg];
|
||||
@@ -139,13 +139,11 @@ static void ak4113_init_regs(struct ak4113 *chip)
|
||||
|
||||
void snd_ak4113_reinit(struct ak4113 *chip)
|
||||
{
|
||||
chip->init = 1;
|
||||
mb();
|
||||
flush_delayed_work(&chip->work);
|
||||
if (atomic_inc_return(&chip->wq_processing) == 1)
|
||||
cancel_delayed_work_sync(&chip->work);
|
||||
ak4113_init_regs(chip);
|
||||
/* bring up statistics / event queing */
|
||||
chip->init = 0;
|
||||
if (chip->kctls[0])
|
||||
if (atomic_dec_and_test(&chip->wq_processing))
|
||||
schedule_delayed_work(&chip->work, HZ / 10);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(snd_ak4113_reinit);
|
||||
@@ -632,8 +630,9 @@ static void ak4113_stats(struct work_struct *work)
|
||||
{
|
||||
struct ak4113 *chip = container_of(work, struct ak4113, work.work);
|
||||
|
||||
if (!chip->init)
|
||||
if (atomic_inc_return(&chip->wq_processing) == 1)
|
||||
snd_ak4113_check_rate_and_errors(chip, chip->check_flags);
|
||||
|
||||
schedule_delayed_work(&chip->work, HZ / 10);
|
||||
if (atomic_dec_and_test(&chip->wq_processing))
|
||||
schedule_delayed_work(&chip->work, HZ / 10);
|
||||
}
|
||||
|
||||
@@ -66,8 +66,7 @@ static void reg_dump(struct ak4114 *ak4114)
|
||||
|
||||
static void snd_ak4114_free(struct ak4114 *chip)
|
||||
{
|
||||
chip->init = 1; /* don't schedule new work */
|
||||
mb();
|
||||
atomic_inc(&chip->wq_processing); /* don't schedule new work */
|
||||
cancel_delayed_work_sync(&chip->work);
|
||||
kfree(chip);
|
||||
}
|
||||
@@ -100,6 +99,7 @@ int snd_ak4114_create(struct snd_card *card,
|
||||
chip->write = write;
|
||||
chip->private_data = private_data;
|
||||
INIT_DELAYED_WORK(&chip->work, ak4114_stats);
|
||||
atomic_set(&chip->wq_processing, 0);
|
||||
|
||||
for (reg = 0; reg < 7; reg++)
|
||||
chip->regmap[reg] = pgm[reg];
|
||||
@@ -152,13 +152,11 @@ static void ak4114_init_regs(struct ak4114 *chip)
|
||||
|
||||
void snd_ak4114_reinit(struct ak4114 *chip)
|
||||
{
|
||||
chip->init = 1;
|
||||
mb();
|
||||
flush_delayed_work(&chip->work);
|
||||
if (atomic_inc_return(&chip->wq_processing) == 1)
|
||||
cancel_delayed_work_sync(&chip->work);
|
||||
ak4114_init_regs(chip);
|
||||
/* bring up statistics / event queing */
|
||||
chip->init = 0;
|
||||
if (chip->kctls[0])
|
||||
if (atomic_dec_and_test(&chip->wq_processing))
|
||||
schedule_delayed_work(&chip->work, HZ / 10);
|
||||
}
|
||||
|
||||
@@ -612,10 +610,10 @@ static void ak4114_stats(struct work_struct *work)
|
||||
{
|
||||
struct ak4114 *chip = container_of(work, struct ak4114, work.work);
|
||||
|
||||
if (!chip->init)
|
||||
if (atomic_inc_return(&chip->wq_processing) == 1)
|
||||
snd_ak4114_check_rate_and_errors(chip, chip->check_flags);
|
||||
|
||||
schedule_delayed_work(&chip->work, HZ / 10);
|
||||
if (atomic_dec_and_test(&chip->wq_processing))
|
||||
schedule_delayed_work(&chip->work, HZ / 10);
|
||||
}
|
||||
|
||||
EXPORT_SYMBOL(snd_ak4114_create);
|
||||
|
||||
@@ -331,7 +331,6 @@ static int atmel_ssc_hw_params(struct snd_pcm_substream *substream,
|
||||
struct atmel_pcm_dma_params *dma_params;
|
||||
int dir, channels, bits;
|
||||
u32 tfmr, rfmr, tcmr, rcmr;
|
||||
int start_event;
|
||||
int ret;
|
||||
|
||||
/*
|
||||
@@ -450,19 +449,10 @@ static int atmel_ssc_hw_params(struct snd_pcm_substream *substream,
|
||||
* The SSC transmit clock is obtained from the BCLK signal on
|
||||
* on the TK line, and the SSC receive clock is
|
||||
* generated from the transmit clock.
|
||||
*
|
||||
* For single channel data, one sample is transferred
|
||||
* on the falling edge of the LRC clock.
|
||||
* For two channel data, one sample is
|
||||
* transferred on both edges of the LRC clock.
|
||||
*/
|
||||
start_event = ((channels == 1)
|
||||
? SSC_START_FALLING_RF
|
||||
: SSC_START_EDGE_RF);
|
||||
|
||||
rcmr = SSC_BF(RCMR_PERIOD, 0)
|
||||
| SSC_BF(RCMR_STTDLY, START_DELAY)
|
||||
| SSC_BF(RCMR_START, start_event)
|
||||
| SSC_BF(RCMR_START, SSC_START_FALLING_RF)
|
||||
| SSC_BF(RCMR_CKI, SSC_CKI_RISING)
|
||||
| SSC_BF(RCMR_CKO, SSC_CKO_NONE)
|
||||
| SSC_BF(RCMR_CKS, SSC_CKS_CLOCK);
|
||||
@@ -470,14 +460,14 @@ static int atmel_ssc_hw_params(struct snd_pcm_substream *substream,
|
||||
rfmr = SSC_BF(RFMR_FSEDGE, SSC_FSEDGE_POSITIVE)
|
||||
| SSC_BF(RFMR_FSOS, SSC_FSOS_NONE)
|
||||
| SSC_BF(RFMR_FSLEN, 0)
|
||||
| SSC_BF(RFMR_DATNB, 0)
|
||||
| SSC_BF(RFMR_DATNB, (channels - 1))
|
||||
| SSC_BIT(RFMR_MSBF)
|
||||
| SSC_BF(RFMR_LOOP, 0)
|
||||
| SSC_BF(RFMR_DATLEN, (bits - 1));
|
||||
|
||||
tcmr = SSC_BF(TCMR_PERIOD, 0)
|
||||
| SSC_BF(TCMR_STTDLY, START_DELAY)
|
||||
| SSC_BF(TCMR_START, start_event)
|
||||
| SSC_BF(TCMR_START, SSC_START_FALLING_RF)
|
||||
| SSC_BF(TCMR_CKI, SSC_CKI_FALLING)
|
||||
| SSC_BF(TCMR_CKO, SSC_CKO_NONE)
|
||||
| SSC_BF(TCMR_CKS, SSC_CKS_PIN);
|
||||
@@ -486,7 +476,7 @@ static int atmel_ssc_hw_params(struct snd_pcm_substream *substream,
|
||||
| SSC_BF(TFMR_FSDEN, 0)
|
||||
| SSC_BF(TFMR_FSOS, SSC_FSOS_NONE)
|
||||
| SSC_BF(TFMR_FSLEN, 0)
|
||||
| SSC_BF(TFMR_DATNB, 0)
|
||||
| SSC_BF(TFMR_DATNB, (channels - 1))
|
||||
| SSC_BIT(TFMR_MSBF)
|
||||
| SSC_BF(TFMR_DATDEF, 0)
|
||||
| SSC_BF(TFMR_DATLEN, (bits - 1));
|
||||
|
||||
@@ -1242,6 +1242,9 @@ static int sgtl5000_enable_regulators(struct snd_soc_codec *codec)
|
||||
/* wait for all power rails bring up */
|
||||
udelay(10);
|
||||
|
||||
/* Need 8 clocks before I2C accesses */
|
||||
udelay(1);
|
||||
|
||||
/* read chip information */
|
||||
reg = snd_soc_read(codec, SGTL5000_CHIP_ID);
|
||||
if (((reg & SGTL5000_PARTID_MASK) >> SGTL5000_PARTID_SHIFT) !=
|
||||
|
||||
Reference in New Issue
Block a user