diff --git a/arch/x86/include/asm/perf_event.h b/arch/x86/include/asm/perf_event.h index 8bdf74902293489a031aa300a605447e83b96341..ab4cf7c12c40ada26bd7a6e3e05a587e950c5aa5 100644 --- a/arch/x86/include/asm/perf_event.h +++ b/arch/x86/include/asm/perf_event.h @@ -7,7 +7,7 @@ */ #define INTEL_PMC_MAX_GENERIC 32 -#define INTEL_PMC_MAX_FIXED 3 +#define INTEL_PMC_MAX_FIXED 4 #define INTEL_PMC_IDX_FIXED 32 #define X86_PMC_IDX_MAX 64 diff --git a/arch/x86/kernel/cpu/mcheck/therm_throt.c b/arch/x86/kernel/cpu/mcheck/therm_throt.c index 2da67b70ba989821db25e3190a5c68964f9e1c26..bc57b5988589adb7668a510e38e6b8fabb568ce1 100644 --- a/arch/x86/kernel/cpu/mcheck/therm_throt.c +++ b/arch/x86/kernel/cpu/mcheck/therm_throt.c @@ -184,10 +184,10 @@ static void therm_throt_process(bool new_event, int event, int level) /* if we just entered the thermal event */ if (new_event) { if (event == THERMAL_THROTTLING_EVENT) - pr_crit("CPU%d: %s temperature above threshold, cpu clock throttled (total events = %lu)\n", - this_cpu, - level == CORE_LEVEL ? "Core" : "Package", - state->count); + pr_notice("CPU%d: %s temperature above threshold, cpu clock throttled (total events = %lu)\n", + this_cpu, + level == CORE_LEVEL ? "Core" : "Package", + state->count); return; } if (old_event) { diff --git a/drivers/ata/libata-core.c b/drivers/ata/libata-core.c index b8c3f9e6af8994820c30b40889154f87511014e0..48e52a08997c0161805d87fba53624bc3ed40546 100644 --- a/drivers/ata/libata-core.c +++ b/drivers/ata/libata-core.c @@ -2118,7 +2118,7 @@ static bool ata_identify_page_supported(struct ata_device *dev, u8 page) unsigned int err, i; if (!ata_log_supported(dev, ATA_LOG_IDENTIFY_DEVICE)) { - ata_dev_warn(dev, "ATA Identify Device Log not supported\n"); + ata_dev_notice(dev, "ATA Identify Device Log not supported\n"); return false; } @@ -2192,7 +2192,7 @@ static void ata_dev_config_ncq_send_recv(struct ata_device *dev) unsigned int err_mask; if (!ata_log_supported(dev, ATA_LOG_NCQ_SEND_RECV)) { - ata_dev_warn(dev, "NCQ Send/Recv Log not supported\n"); + ata_dev_notice(dev, "NCQ Send/Recv Log not supported\n"); return; } err_mask = ata_read_log_page(dev, ATA_LOG_NCQ_SEND_RECV, @@ -2221,8 +2221,8 @@ static void ata_dev_config_ncq_non_data(struct ata_device *dev) unsigned int err_mask; if (!ata_log_supported(dev, ATA_LOG_NCQ_NON_DATA)) { - ata_dev_warn(dev, - "NCQ Send/Recv Log not supported\n"); + ata_dev_notice(dev, + "NCQ Send/Recv Log not supported\n"); return; } err_mask = ata_read_log_page(dev, ATA_LOG_NCQ_NON_DATA, @@ -2552,14 +2552,14 @@ int ata_dev_configure(struct ata_device *dev) if (ata_id_is_cfa(id)) { /* CPRM may make this media unusable */ if (id[ATA_ID_CFA_KEY_MGMT] & 1) - ata_dev_warn(dev, + ata_dev_notice(dev, "supports DRM functions and may not be fully accessible\n"); snprintf(revbuf, 7, "CFA"); } else { snprintf(revbuf, 7, "ATA-%d", ata_id_major_version(id)); /* Warn the user if the device has TPM extensions */ if (ata_id_has_tpm(id)) - ata_dev_warn(dev, + ata_dev_notice(dev, "supports DRM functions and may not be fully accessible\n"); } @@ -2775,8 +2775,8 @@ int ata_dev_configure(struct ata_device *dev) } if ((dev->horkage & ATA_HORKAGE_FIRMWARE_WARN) && print_info) { - ata_dev_warn(dev, "WARNING: device requires firmware update to be fully functional\n"); - ata_dev_warn(dev, " contact the vendor or visit http://ata.wiki.kernel.org\n"); + ata_dev_notice(dev, "WARNING: device requires firmware update to be fully functional\n"); + ata_dev_notice(dev, " contact the vendor or visit http://ata.wiki.kernel.org\n"); } return 0; diff --git a/drivers/base/bus.c b/drivers/base/bus.c index 8bfd27ec73d60d1d18a43f9bfcff29b4eb9a50a6..585e2e1c9c8f4760309e47f052e377da56135e9b 100644 --- a/drivers/base/bus.c +++ b/drivers/base/bus.c @@ -31,6 +31,9 @@ static struct kset *system_kset; #define to_drv_attr(_attr) container_of(_attr, struct driver_attribute, attr) +#define DRIVER_ATTR_IGNORE_LOCKDEP(_name, _mode, _show, _store) \ + struct driver_attribute driver_attr_##_name = \ + __ATTR_IGNORE_LOCKDEP(_name, _mode, _show, _store) static int __must_check bus_rescan_devices_helper(struct device *dev, void *data); @@ -195,7 +198,7 @@ static ssize_t unbind_store(struct device_driver *drv, const char *buf, bus_put(bus); return err; } -static DRIVER_ATTR_WO(unbind); +static DRIVER_ATTR_IGNORE_LOCKDEP(unbind, S_IWUSR, NULL, unbind_store); /* * Manually attach a device to a driver. @@ -231,7 +234,7 @@ static ssize_t bind_store(struct device_driver *drv, const char *buf, bus_put(bus); return err; } -static DRIVER_ATTR_WO(bind); +static DRIVER_ATTR_IGNORE_LOCKDEP(bind, S_IWUSR, NULL, bind_store); static ssize_t show_drivers_autoprobe(struct bus_type *bus, char *buf) { diff --git a/drivers/usb/core/usb-acpi.c b/drivers/usb/core/usb-acpi.c index e221861b3187c2fcbceb4b3ee58b70d2fca5fa53..8424b3a27e7eb53773b97f78157caf2cd4e35eb4 100644 --- a/drivers/usb/core/usb-acpi.c +++ b/drivers/usb/core/usb-acpi.c @@ -12,6 +12,7 @@ #include <linux/acpi.h> #include <linux/pci.h> #include <linux/usb/hcd.h> +#include <linux/dmi.h> #include "hub.h" @@ -81,6 +82,20 @@ int usb_acpi_set_power_state(struct usb_device *hdev, int index, bool enable) } EXPORT_SYMBOL_GPL(usb_acpi_set_power_state); +static const struct dmi_system_id intel_icl_broken_acpi[] = { + { + .ident = "ICL RVP", + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "Intel Corporation"), + DMI_MATCH(DMI_PRODUCT_NAME, "Ice Lake Client Platform"), + }, + }, + + { } +}; + +static bool acpi_connection_type_broken; + static enum usb_port_connect_type usb_acpi_get_connect_type(acpi_handle handle, struct acpi_pld_info *pld) { @@ -89,6 +104,10 @@ static enum usb_port_connect_type usb_acpi_get_connect_type(acpi_handle handle, union acpi_object *upc; acpi_status status; + /* Work around unknown ACPI instruction error on ICL RVP BIOSes. */ + if (acpi_connection_type_broken) + return USB_PORT_CONNECT_TYPE_UNKNOWN; + /* * According to 9.14 in ACPI Spec 6.2. _PLD indicates whether usb port * is user visible and _UPC indicates whether it is connectable. If @@ -235,6 +254,11 @@ static struct acpi_bus_type usb_acpi_bus = { int usb_acpi_register(void) { + if (dmi_check_system(intel_icl_broken_acpi)) { + pr_info("USB ACPI connection type broken.\n"); + acpi_connection_type_broken = true; + } + return register_acpi_bus_type(&usb_acpi_bus); } diff --git a/include/linux/device.h b/include/linux/device.h index 1b25c7a43f4cc85604fbb0e0becab482edcb84a4..41424d6e27c7222179a3d46e1a788a8d2a946d1e 100644 --- a/include/linux/device.h +++ b/include/linux/device.h @@ -327,6 +327,7 @@ struct driver_attribute { #define DRIVER_ATTR_WO(_name) \ struct driver_attribute driver_attr_##_name = __ATTR_WO(_name) + extern int __must_check driver_create_file(struct device_driver *driver, const struct driver_attribute *attr); extern void driver_remove_file(struct device_driver *driver, diff --git a/kernel/events/core.c b/kernel/events/core.c index 84530ab358c37ad876744d5ebda5d277dfb6d065..75912ae91fbbcdf9dd7f778b86b6885c41e92afc 100644 --- a/kernel/events/core.c +++ b/kernel/events/core.c @@ -9737,7 +9737,8 @@ void perf_pmu_unregister(struct pmu *pmu) device_del(pmu->dev); put_device(pmu->dev); } - free_pmu_context(pmu); + if (!find_pmu_context(pmu->task_ctx_nr)) + free_pmu_context(pmu); mutex_unlock(&pmus_lock); } EXPORT_SYMBOL_GPL(perf_pmu_unregister); diff --git a/kernel/locking/lockdep_internals.h b/kernel/locking/lockdep_internals.h index 88c847a41c8ae78ea8fdfc75476b85c259466200..746aec91f5b8408ece6ce4edcf5b41a27adb1b7a 100644 --- a/kernel/locking/lockdep_internals.h +++ b/kernel/locking/lockdep_internals.h @@ -69,7 +69,7 @@ enum { #else #define MAX_LOCKDEP_ENTRIES 32768UL -#define MAX_LOCKDEP_CHAINS_BITS 16 +#define MAX_LOCKDEP_CHAINS_BITS 17 /* * Stack-trace: tightly packed array of stack backtrace diff --git a/kernel/panic.c b/kernel/panic.c index f6d549a29a5c85cfdc2de0f07e6f0e956a1268ce..9241f2240ea32e78cd8f375e805bb2a857e34da3 100644 --- a/kernel/panic.c +++ b/kernel/panic.c @@ -180,13 +180,6 @@ void panic(const char *fmt, ...) buf[len - 1] = '\0'; pr_emerg("Kernel panic - not syncing: %s\n", buf); -#ifdef CONFIG_DEBUG_BUGVERBOSE - /* - * Avoid nested stack-dumping if a panic occurs during oops processing - */ - if (!test_taint(TAINT_DIE) && oops_in_progress <= 1) - dump_stack(); -#endif /* * If we have crashed and we have a crash kernel loaded let it handle @@ -221,6 +214,14 @@ void panic(const char *fmt, ...) */ atomic_notifier_call_chain(&panic_notifier_list, 0, buf); +#ifdef CONFIG_DEBUG_BUGVERBOSE + /* + * Avoid nested stack-dumping if a panic occurs during oops processing + */ + if (!test_taint(TAINT_DIE) && oops_in_progress <= 1) + dump_stack(); +#endif + /* Call flush even twice. It tries harder with a single online CPU */ printk_safe_flush_on_panic(); kmsg_dump(KMSG_DUMP_PANIC); @@ -510,14 +511,9 @@ struct warn_args { va_list args; }; -void __warn(const char *file, int line, void *caller, unsigned taint, - struct pt_regs *regs, struct warn_args *args) +static void show_location(const char *file, int line, void *caller, + struct warn_args *args) { - disable_trace_on_warning(); - - if (args) - pr_warn(CUT_HERE); - if (file) pr_warn("WARNING: CPU: %d PID: %d at %s:%d %pS\n", raw_smp_processor_id(), current->pid, file, line, @@ -528,6 +524,17 @@ void __warn(const char *file, int line, void *caller, unsigned taint, if (args) vprintk(args->fmt, args->args); +} + +void __warn(const char *file, int line, void *caller, unsigned taint, + struct pt_regs *regs, struct warn_args *args) +{ + disable_trace_on_warning(); + + if (args) + pr_warn(CUT_HERE); + + show_location(file, line, caller, args); if (panic_on_warn) { /* @@ -549,6 +556,8 @@ void __warn(const char *file, int line, void *caller, unsigned taint, print_irqtrace_events(current); + show_location(file, line, caller, args); + print_oops_end_marker(); /* Just a warning, don't kill lockdep. */ diff --git a/kernel/trace/Kconfig b/kernel/trace/Kconfig index 5e3de28c7677396aaa4360dcf2f51fb9b365b626..d838ba908e0520f0f52cfc6d62e08f2e834742b9 100644 --- a/kernel/trace/Kconfig +++ b/kernel/trace/Kconfig @@ -114,6 +114,13 @@ config TRACING select EVENT_TRACING select TRACE_CLOCK +config GLOBAL_TRACE_BUF_SIZE + int + prompt "Global ftrace buffer size (for trace_printk)" if EXPERT + range 0 4194034 + default 1441792 # 16384 * 88 (sizeof(struct print_entry)) + depends on TRACING + config GENERIC_TRACER bool select TRACING diff --git a/kernel/trace/trace.c b/kernel/trace/trace.c index ff1c4b20cd0a6d29209950fa006542c71b8c43ef..9ccbeaae959fa104ff1e1f67a1bff94648f7024b 100644 --- a/kernel/trace/trace.c +++ b/kernel/trace/trace.c @@ -614,9 +614,7 @@ int tracing_is_enabled(void) * to not have to wait for all that output. Anyway this can be * boot time and run time configurable. */ -#define TRACE_BUF_SIZE_DEFAULT 1441792UL /* 16384 * 88 (sizeof(entry)) */ - -static unsigned long trace_buf_size = TRACE_BUF_SIZE_DEFAULT; +static unsigned long trace_buf_size = CONFIG_GLOBAL_TRACE_BUF_SIZE; /* trace_types holds a link list of available tracers. */ static struct tracer *trace_types __read_mostly; diff --git a/mm/oom_kill.c b/mm/oom_kill.c index 6589f60d50186aca3812be1a9ae3d8ba7369b87b..2fb50f7d982d527f7def54cb2c8de13dcba6f4a0 100644 --- a/mm/oom_kill.c +++ b/mm/oom_kill.c @@ -49,6 +49,8 @@ #define CREATE_TRACE_POINTS #include <trace/events/oom.h> +static bool task_will_free_mem(struct task_struct *task); + int sysctl_panic_on_oom; int sysctl_oom_kill_allocating_task; int sysctl_oom_dump_tasks = 1; @@ -209,19 +211,27 @@ unsigned long oom_badness(struct task_struct *p, struct mem_cgroup *memcg, if (oom_unkillable_task(p, memcg, nodemask)) return 0; + /* + * If we cannot lock the task's mm, it is in the process of being + * removed, so select it as the target of the repear and see if it + * recovers enough memory to continue. + */ p = find_lock_task_mm(p); if (!p) - return 0; + return ULONG_MAX; + + if (task_will_free_mem(p)) { + task_unlock(p); + return ULONG_MAX; + } /* * Do not even consider tasks which are explicitly marked oom - * unkillable or have been already oom reaped or the are in - * the middle of vfork + * unkillable or are in the middle of vfork (and so still share their + * parent's mm). */ adj = (long)p->signal->oom_score_adj; - if (adj == OOM_SCORE_ADJ_MIN || - test_bit(MMF_OOM_SKIP, &p->mm->flags) || - in_vfork(p)) { + if (adj == OOM_SCORE_ADJ_MIN || in_vfork(p)) { task_unlock(p); return 0; } @@ -801,11 +811,12 @@ static bool task_will_free_mem(struct task_struct *task) return false; /* - * This task has already been drained by the oom reaper so there are - * only small chances it will free some more + * This task has already been selected for the oom reaper, but + * the reaper is unable to make progress. Continue to dogpile + * on top until it succeeds. */ if (test_bit(MMF_OOM_SKIP, &mm->flags)) - return false; + return true; if (atomic_read(&mm->mm_users) <= 1) return true; diff --git a/mm/vmalloc.c b/mm/vmalloc.c index 97d4b25d0373102a197ba1de455a944cf7204061..6e229053c783671ef3d8cca920af0b6d4e82cdaa 100644 --- a/mm/vmalloc.c +++ b/mm/vmalloc.c @@ -131,80 +131,27 @@ static void vunmap_page_range(unsigned long addr, unsigned long end) } while (pgd++, addr = next, addr != end); } -static int vmap_pte_range(pmd_t *pmd, unsigned long addr, - unsigned long end, pgprot_t prot, struct page **pages, int *nr) -{ - pte_t *pte; - - /* - * nr is a running index into the array which helps higher level - * callers keep track of where we're up to. - */ - - pte = pte_alloc_kernel(pmd, addr); - if (!pte) - return -ENOMEM; - do { - struct page *page = pages[*nr]; - - if (WARN_ON(!pte_none(*pte))) - return -EBUSY; - if (WARN_ON(!page)) - return -ENOMEM; - set_pte_at(&init_mm, addr, pte, mk_pte(page, prot)); - (*nr)++; - } while (pte++, addr += PAGE_SIZE, addr != end); - return 0; -} +struct vmap_page { + pgprot_t prot; + struct page **pages; + unsigned long count; +}; -static int vmap_pmd_range(pud_t *pud, unsigned long addr, - unsigned long end, pgprot_t prot, struct page **pages, int *nr) +static int vmap_page(pte_t *pte, pgtable_t token, + unsigned long addr, void *data) { - pmd_t *pmd; - unsigned long next; + struct vmap_page *v = data; + struct page *page; - pmd = pmd_alloc(&init_mm, pud, addr); - if (!pmd) - return -ENOMEM; - do { - next = pmd_addr_end(addr, end); - if (vmap_pte_range(pmd, addr, next, prot, pages, nr)) - return -ENOMEM; - } while (pmd++, addr = next, addr != end); - return 0; -} + if (WARN_ON(!pte_none(*pte))) + return -EBUSY; -static int vmap_pud_range(p4d_t *p4d, unsigned long addr, - unsigned long end, pgprot_t prot, struct page **pages, int *nr) -{ - pud_t *pud; - unsigned long next; - - pud = pud_alloc(&init_mm, p4d, addr); - if (!pud) + page = v->pages[v->count]; + if (WARN_ON(!page)) return -ENOMEM; - do { - next = pud_addr_end(addr, end); - if (vmap_pmd_range(pud, addr, next, prot, pages, nr)) - return -ENOMEM; - } while (pud++, addr = next, addr != end); - return 0; -} - -static int vmap_p4d_range(pgd_t *pgd, unsigned long addr, - unsigned long end, pgprot_t prot, struct page **pages, int *nr) -{ - p4d_t *p4d; - unsigned long next; - p4d = p4d_alloc(&init_mm, pgd, addr); - if (!p4d) - return -ENOMEM; - do { - next = p4d_addr_end(addr, end); - if (vmap_pud_range(p4d, addr, next, prot, pages, nr)) - return -ENOMEM; - } while (p4d++, addr = next, addr != end); + set_pte_at(&init_mm, addr, pte, mk_pte(page, v->prot)); + v->count++; return 0; } @@ -217,22 +164,37 @@ static int vmap_p4d_range(pgd_t *pgd, unsigned long addr, static int vmap_page_range_noflush(unsigned long start, unsigned long end, pgprot_t prot, struct page **pages) { - pgd_t *pgd; - unsigned long next; - unsigned long addr = start; - int err = 0; - int nr = 0; + struct vmap_page v = { prot, pages }; + int err; - BUG_ON(addr >= end); - pgd = pgd_offset_k(addr); - do { - next = pgd_addr_end(addr, end); - err = vmap_p4d_range(pgd, addr, next, prot, pages, &nr); - if (err) - return err; - } while (pgd++, addr = next, addr != end); + if ((end - start) >> PAGE_SHIFT > INT_MAX) + return -EINVAL; + + /* FIXME: See bugzilla link and + * https://www.spinics.net/lists/sparclinux/msg16581.html for why this + * is full of regrets. + * + * Quoting that mail: + +On Fri, 28 Oct 2016 21:15:48 +0100 Chris Wilson <chris@xxxxxxxxxxxxxxxxxx> wrote: +> > Bisect points to commit 0c79e3331f08 ("mm/vmalloc: replace opencoded 4-level +> > page walkers"). Reverting this patch fixes the problem. +> +> Hmm, apply_to_pte_range() has a BUG_ON(pmd_huge(*pmd)) but the old +> vmap_pte_range() does not and neither has the code to handle that case. +> Presuming that the BUG_ON() there is actually meaningful. + +Thanks, I'll drop mm-vmalloc-replace-opencoded-4-level-page-walkers.patch for now. + + * we never got any further with tracking this one down. + */ + err = apply_to_page_range(&init_mm, start, end - start, vmap_page, &v); + if (unlikely(err)) { + vunmap_page_range(start, start + (v.count << PAGE_SHIFT)); + return err; + } - return nr; + return v.count; } static int vmap_page_range(unsigned long start, unsigned long end, diff --git a/net/sched/sch_generic.c b/net/sched/sch_generic.c index de1663f7d3ad6e2c06cd2e031036cef5979366a5..dfced88a0da12037135bf485baa04ac0966d34e4 100644 --- a/net/sched/sch_generic.c +++ b/net/sched/sch_generic.c @@ -456,7 +456,12 @@ static void dev_watchdog(struct timer_list *t) } } - if (some_queue_timedout) { + /* The noise is pissing off our CI and upstream doesn't + * move on the bug report: + * + * https://bugzilla.kernel.org/show_bug.cgi?id=196399 + */ + if (some_queue_timedout && 0) { WARN_ONCE(1, KERN_INFO "NETDEV WATCHDOG: %s (%s): transmit queue %u timed out\n", dev->name, netdev_drivername(dev), i); dev->netdev_ops->ndo_tx_timeout(dev);