commit: 0795663430288e5887e29c41d5ba14f0fb4aa807 Author: Mike Pagano <mpagano <AT> gentoo <DOT> org> AuthorDate: Sat Mar 21 18:58:09 2020 +0000 Commit: Mike Pagano <mpagano <AT> gentoo <DOT> org> CommitDate: Sat Mar 21 18:58:09 2020 +0000 URL: https://gitweb.gentoo.org/proj/linux-patches.git/commit/?id=07956634
Linux patch 5.4.27 Signed-off-by: Mike Pagano <mpagano <AT> gentoo.org> 0000_README | 4 + 1026_linux-5.4.27.patch | 1989 +++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 1993 insertions(+) diff --git a/0000_README b/0000_README index 0a75a39..5a1ab80 100644 --- a/0000_README +++ b/0000_README @@ -147,6 +147,10 @@ Patch: 1025_linux-5.4.26.patch From: http://www.kernel.org Desc: Linux 5.4.26 +Patch: 1026_linux-5.4.27.patch +From: http://www.kernel.org +Desc: Linux 5.4.27 + Patch: 1500_XATTR_USER_PREFIX.patch From: https://bugs.gentoo.org/show_bug.cgi?id=470644 Desc: Support for namespace user.pax.* on tmpfs. diff --git a/1026_linux-5.4.27.patch b/1026_linux-5.4.27.patch new file mode 100644 index 0000000..bf0ff09 --- /dev/null +++ b/1026_linux-5.4.27.patch @@ -0,0 +1,1989 @@ +diff --git a/Documentation/admin-guide/kernel-parameters.txt b/Documentation/admin-guide/kernel-parameters.txt +index 5594c8bf1dcd..b5c933fa971f 100644 +--- a/Documentation/admin-guide/kernel-parameters.txt ++++ b/Documentation/admin-guide/kernel-parameters.txt +@@ -136,6 +136,10 @@ + dynamic table installation which will install SSDT + tables to /sys/firmware/acpi/tables/dynamic. + ++ acpi_no_watchdog [HW,ACPI,WDT] ++ Ignore the ACPI-based watchdog interface (WDAT) and let ++ a native driver control the watchdog device instead. ++ + acpi_rsdp= [ACPI,EFI,KEXEC] + Pass the RSDP address to the kernel, mostly used + on machines running EFI runtime service to boot the +diff --git a/Makefile b/Makefile +index 2250b1bb8aa9..36a0847534dd 100644 +--- a/Makefile ++++ b/Makefile +@@ -1,7 +1,7 @@ + # SPDX-License-Identifier: GPL-2.0 + VERSION = 5 + PATCHLEVEL = 4 +-SUBLEVEL = 26 ++SUBLEVEL = 27 + EXTRAVERSION = + NAME = Kleptomaniac Octopus + +@@ -1237,7 +1237,7 @@ ifneq ($(dtstree),) + %.dtb: include/config/kernel.release scripts_dtc + $(Q)$(MAKE) $(build)=$(dtstree) $(dtstree)/$@ + +-PHONY += dtbs dtbs_install dt_binding_check ++PHONY += dtbs dtbs_install dtbs_check + dtbs dtbs_check: include/config/kernel.release scripts_dtc + $(Q)$(MAKE) $(build)=$(dtstree) + +@@ -1257,6 +1257,7 @@ PHONY += scripts_dtc + scripts_dtc: scripts_basic + $(Q)$(MAKE) $(build)=scripts/dtc + ++PHONY += dt_binding_check + dt_binding_check: scripts_dtc + $(Q)$(MAKE) $(build)=Documentation/devicetree/bindings + +diff --git a/arch/arm/Makefile b/arch/arm/Makefile +index db857d07114f..1fc32b611f8a 100644 +--- a/arch/arm/Makefile ++++ b/arch/arm/Makefile +@@ -307,13 +307,15 @@ endif + ifeq ($(CONFIG_STACKPROTECTOR_PER_TASK),y) + prepare: stack_protector_prepare + stack_protector_prepare: prepare0 +- $(eval KBUILD_CFLAGS += \ ++ $(eval SSP_PLUGIN_CFLAGS := \ + -fplugin-arg-arm_ssp_per_task_plugin-tso=$(shell \ + awk '{if ($$2 == "THREAD_SZ_ORDER") print $$3;}'\ + include/generated/asm-offsets.h) \ + -fplugin-arg-arm_ssp_per_task_plugin-offset=$(shell \ + awk '{if ($$2 == "TI_STACK_CANARY") print $$3;}'\ + include/generated/asm-offsets.h)) ++ $(eval KBUILD_CFLAGS += $(SSP_PLUGIN_CFLAGS)) ++ $(eval GCC_PLUGINS_CFLAGS += $(SSP_PLUGIN_CFLAGS)) + endif + + all: $(notdir $(KBUILD_IMAGE)) +diff --git a/arch/arm/boot/compressed/Makefile b/arch/arm/boot/compressed/Makefile +index 9219389bbe61..1483966dcf23 100644 +--- a/arch/arm/boot/compressed/Makefile ++++ b/arch/arm/boot/compressed/Makefile +@@ -101,7 +101,6 @@ clean-files += piggy_data lib1funcs.S ashldi3.S bswapsdi2.S \ + $(libfdt) $(libfdt_hdrs) hyp-stub.S + + KBUILD_CFLAGS += -DDISABLE_BRANCH_PROFILING +-KBUILD_CFLAGS += $(DISABLE_ARM_SSP_PER_TASK_PLUGIN) + + ifeq ($(CONFIG_FUNCTION_TRACER),y) + ORIG_CFLAGS := $(KBUILD_CFLAGS) +@@ -117,7 +116,8 @@ CFLAGS_fdt_ro.o := $(nossp_flags) + CFLAGS_fdt_rw.o := $(nossp_flags) + CFLAGS_fdt_wip.o := $(nossp_flags) + +-ccflags-y := -fpic $(call cc-option,-mno-single-pic-base,) -fno-builtin -I$(obj) ++ccflags-y := -fpic $(call cc-option,-mno-single-pic-base,) -fno-builtin \ ++ -I$(obj) $(DISABLE_ARM_SSP_PER_TASK_PLUGIN) + asflags-y := -DZIMAGE + + # Supply kernel BSS size to the decompressor via a linker symbol. +diff --git a/arch/arm/kernel/vdso.c b/arch/arm/kernel/vdso.c +index 9bf16c93ee6a..f00e45fa62c4 100644 +--- a/arch/arm/kernel/vdso.c ++++ b/arch/arm/kernel/vdso.c +@@ -92,6 +92,8 @@ static bool __init cntvct_functional(void) + * this. + */ + np = of_find_compatible_node(NULL, NULL, "arm,armv7-timer"); ++ if (!np) ++ np = of_find_compatible_node(NULL, NULL, "arm,armv8-timer"); + if (!np) + goto out_put; + +diff --git a/arch/arm/lib/copy_from_user.S b/arch/arm/lib/copy_from_user.S +index 95b2e1ce559c..f8016e3db65d 100644 +--- a/arch/arm/lib/copy_from_user.S ++++ b/arch/arm/lib/copy_from_user.S +@@ -118,7 +118,7 @@ ENTRY(arm_copy_from_user) + + ENDPROC(arm_copy_from_user) + +- .pushsection .fixup,"ax" ++ .pushsection .text.fixup,"ax" + .align 0 + copy_abort_preamble + ldmfd sp!, {r1, r2, r3} +diff --git a/block/blk-flush.c b/block/blk-flush.c +index b1f0a1ac505c..5aa6fada2259 100644 +--- a/block/blk-flush.c ++++ b/block/blk-flush.c +@@ -399,7 +399,7 @@ void blk_insert_flush(struct request *rq) + */ + if ((policy & REQ_FSEQ_DATA) && + !(policy & (REQ_FSEQ_PREFLUSH | REQ_FSEQ_POSTFLUSH))) { +- blk_mq_request_bypass_insert(rq, false); ++ blk_mq_request_bypass_insert(rq, false, false); + return; + } + +diff --git a/block/blk-mq-sched.c b/block/blk-mq-sched.c +index ca22afd47b3d..74cedea56034 100644 +--- a/block/blk-mq-sched.c ++++ b/block/blk-mq-sched.c +@@ -361,13 +361,19 @@ static bool blk_mq_sched_bypass_insert(struct blk_mq_hw_ctx *hctx, + bool has_sched, + struct request *rq) + { +- /* dispatch flush rq directly */ +- if (rq->rq_flags & RQF_FLUSH_SEQ) { +- spin_lock(&hctx->lock); +- list_add(&rq->queuelist, &hctx->dispatch); +- spin_unlock(&hctx->lock); ++ /* ++ * dispatch flush and passthrough rq directly ++ * ++ * passthrough request has to be added to hctx->dispatch directly. ++ * For some reason, device may be in one situation which can't ++ * handle FS request, so STS_RESOURCE is always returned and the ++ * FS request will be added to hctx->dispatch. However passthrough ++ * request may be required at that time for fixing the problem. If ++ * passthrough request is added to scheduler queue, there isn't any ++ * chance to dispatch it given we prioritize requests in hctx->dispatch. ++ */ ++ if ((rq->rq_flags & RQF_FLUSH_SEQ) || blk_rq_is_passthrough(rq)) + return true; +- } + + if (has_sched) + rq->rq_flags |= RQF_SORTED; +@@ -391,8 +397,32 @@ void blk_mq_sched_insert_request(struct request *rq, bool at_head, + + WARN_ON(e && (rq->tag != -1)); + +- if (blk_mq_sched_bypass_insert(hctx, !!e, rq)) ++ if (blk_mq_sched_bypass_insert(hctx, !!e, rq)) { ++ /* ++ * Firstly normal IO request is inserted to scheduler queue or ++ * sw queue, meantime we add flush request to dispatch queue( ++ * hctx->dispatch) directly and there is at most one in-flight ++ * flush request for each hw queue, so it doesn't matter to add ++ * flush request to tail or front of the dispatch queue. ++ * ++ * Secondly in case of NCQ, flush request belongs to non-NCQ ++ * command, and queueing it will fail when there is any ++ * in-flight normal IO request(NCQ command). When adding flush ++ * rq to the front of hctx->dispatch, it is easier to introduce ++ * extra time to flush rq's latency because of S_SCHED_RESTART ++ * compared with adding to the tail of dispatch queue, then ++ * chance of flush merge is increased, and less flush requests ++ * will be issued to controller. It is observed that ~10% time ++ * is saved in blktests block/004 on disk attached to AHCI/NCQ ++ * drive when adding flush rq to the front of hctx->dispatch. ++ * ++ * Simply queue flush rq to the front of hctx->dispatch so that ++ * intensive flush workloads can benefit in case of NCQ HW. ++ */ ++ at_head = (rq->rq_flags & RQF_FLUSH_SEQ) ? true : at_head; ++ blk_mq_request_bypass_insert(rq, at_head, false); + goto run; ++ } + + if (e && e->type->ops.insert_requests) { + LIST_HEAD(list); +diff --git a/block/blk-mq.c b/block/blk-mq.c +index ec791156e9cc..3c1abab1fdf5 100644 +--- a/block/blk-mq.c ++++ b/block/blk-mq.c +@@ -761,7 +761,7 @@ static void blk_mq_requeue_work(struct work_struct *work) + * merge. + */ + if (rq->rq_flags & RQF_DONTPREP) +- blk_mq_request_bypass_insert(rq, false); ++ blk_mq_request_bypass_insert(rq, false, false); + else + blk_mq_sched_insert_request(rq, true, false, false); + } +@@ -1313,7 +1313,7 @@ bool blk_mq_dispatch_rq_list(struct request_queue *q, struct list_head *list, + q->mq_ops->commit_rqs(hctx); + + spin_lock(&hctx->lock); +- list_splice_init(list, &hctx->dispatch); ++ list_splice_tail_init(list, &hctx->dispatch); + spin_unlock(&hctx->lock); + + /* +@@ -1668,12 +1668,16 @@ void __blk_mq_insert_request(struct blk_mq_hw_ctx *hctx, struct request *rq, + * Should only be used carefully, when the caller knows we want to + * bypass a potential IO scheduler on the target device. + */ +-void blk_mq_request_bypass_insert(struct request *rq, bool run_queue) ++void blk_mq_request_bypass_insert(struct request *rq, bool at_head, ++ bool run_queue) + { + struct blk_mq_hw_ctx *hctx = rq->mq_hctx; + + spin_lock(&hctx->lock); +- list_add_tail(&rq->queuelist, &hctx->dispatch); ++ if (at_head) ++ list_add(&rq->queuelist, &hctx->dispatch); ++ else ++ list_add_tail(&rq->queuelist, &hctx->dispatch); + spin_unlock(&hctx->lock); + + if (run_queue) +@@ -1863,7 +1867,7 @@ insert: + if (bypass_insert) + return BLK_STS_RESOURCE; + +- blk_mq_request_bypass_insert(rq, run_queue); ++ blk_mq_request_bypass_insert(rq, false, run_queue); + return BLK_STS_OK; + } + +@@ -1879,7 +1883,7 @@ static void blk_mq_try_issue_directly(struct blk_mq_hw_ctx *hctx, + + ret = __blk_mq_try_issue_directly(hctx, rq, cookie, false, true); + if (ret == BLK_STS_RESOURCE || ret == BLK_STS_DEV_RESOURCE) +- blk_mq_request_bypass_insert(rq, true); ++ blk_mq_request_bypass_insert(rq, false, true); + else if (ret != BLK_STS_OK) + blk_mq_end_request(rq, ret); + +@@ -1913,7 +1917,7 @@ void blk_mq_try_issue_list_directly(struct blk_mq_hw_ctx *hctx, + if (ret != BLK_STS_OK) { + if (ret == BLK_STS_RESOURCE || + ret == BLK_STS_DEV_RESOURCE) { +- blk_mq_request_bypass_insert(rq, ++ blk_mq_request_bypass_insert(rq, false, + list_empty(list)); + break; + } +diff --git a/block/blk-mq.h b/block/blk-mq.h +index 32c62c64e6c2..f2075978db50 100644 +--- a/block/blk-mq.h ++++ b/block/blk-mq.h +@@ -66,7 +66,8 @@ int blk_mq_alloc_rqs(struct blk_mq_tag_set *set, struct blk_mq_tags *tags, + */ + void __blk_mq_insert_request(struct blk_mq_hw_ctx *hctx, struct request *rq, + bool at_head); +-void blk_mq_request_bypass_insert(struct request *rq, bool run_queue); ++void blk_mq_request_bypass_insert(struct request *rq, bool at_head, ++ bool run_queue); + void blk_mq_insert_requests(struct blk_mq_hw_ctx *hctx, struct blk_mq_ctx *ctx, + struct list_head *list); + +diff --git a/drivers/acpi/acpi_watchdog.c b/drivers/acpi/acpi_watchdog.c +index d827a4a3e946..6e9ec6e3fe47 100644 +--- a/drivers/acpi/acpi_watchdog.c ++++ b/drivers/acpi/acpi_watchdog.c +@@ -55,12 +55,14 @@ static bool acpi_watchdog_uses_rtc(const struct acpi_table_wdat *wdat) + } + #endif + ++static bool acpi_no_watchdog; ++ + static const struct acpi_table_wdat *acpi_watchdog_get_wdat(void) + { + const struct acpi_table_wdat *wdat = NULL; + acpi_status status; + +- if (acpi_disabled) ++ if (acpi_disabled || acpi_no_watchdog) + return NULL; + + status = acpi_get_table(ACPI_SIG_WDAT, 0, +@@ -88,6 +90,14 @@ bool acpi_has_watchdog(void) + } + EXPORT_SYMBOL_GPL(acpi_has_watchdog); + ++/* ACPI watchdog can be disabled on boot command line */ ++static int __init disable_acpi_watchdog(char *str) ++{ ++ acpi_no_watchdog = true; ++ return 1; ++} ++__setup("acpi_no_watchdog", disable_acpi_watchdog); ++ + void __init acpi_watchdog_init(void) + { + const struct acpi_wdat_entry *entries; +diff --git a/drivers/gpu/drm/amd/amdgpu/gmc_v10_0.c b/drivers/gpu/drm/amd/amdgpu/gmc_v10_0.c +index a7ba4c6cf7a1..f642e066e67a 100644 +--- a/drivers/gpu/drm/amd/amdgpu/gmc_v10_0.c ++++ b/drivers/gpu/drm/amd/amdgpu/gmc_v10_0.c +@@ -230,7 +230,8 @@ static void gmc_v10_0_flush_vm_hub(struct amdgpu_device *adev, uint32_t vmid, + unsigned int vmhub, uint32_t flush_type) + { + struct amdgpu_vmhub *hub = &adev->vmhub[vmhub]; +- u32 tmp = gmc_v10_0_get_invalidate_req(vmid, flush_type); ++ u32 inv_req = gmc_v10_0_get_invalidate_req(vmid, flush_type); ++ u32 tmp; + /* Use register 17 for GART */ + const unsigned eng = 17; + unsigned int i; +@@ -258,7 +259,7 @@ static void gmc_v10_0_flush_vm_hub(struct amdgpu_device *adev, uint32_t vmid, + DRM_ERROR("Timeout waiting for sem acquire in VM flush!\n"); + } + +- WREG32_NO_KIQ(hub->vm_inv_eng0_req + eng, tmp); ++ WREG32_NO_KIQ(hub->vm_inv_eng0_req + eng, inv_req); + + /* + * Issue a dummy read to wait for the ACK register to be cleared +diff --git a/drivers/gpu/drm/amd/amdgpu/gmc_v9_0.c b/drivers/gpu/drm/amd/amdgpu/gmc_v9_0.c +index da53a55bf955..688111ef814d 100644 +--- a/drivers/gpu/drm/amd/amdgpu/gmc_v9_0.c ++++ b/drivers/gpu/drm/amd/amdgpu/gmc_v9_0.c +@@ -487,13 +487,13 @@ static void gmc_v9_0_flush_gpu_tlb(struct amdgpu_device *adev, uint32_t vmid, + { + bool use_semaphore = gmc_v9_0_use_invalidate_semaphore(adev, vmhub); + const unsigned eng = 17; +- u32 j, tmp; ++ u32 j, inv_req, tmp; + struct amdgpu_vmhub *hub; + + BUG_ON(vmhub >= adev->num_vmhubs); + + hub = &adev->vmhub[vmhub]; +- tmp = gmc_v9_0_get_invalidate_req(vmid, flush_type); ++ inv_req = gmc_v9_0_get_invalidate_req(vmid, flush_type); + + /* This is necessary for a HW workaround under SRIOV as well + * as GFXOFF under bare metal +@@ -504,7 +504,7 @@ static void gmc_v9_0_flush_gpu_tlb(struct amdgpu_device *adev, uint32_t vmid, + uint32_t req = hub->vm_inv_eng0_req + eng; + uint32_t ack = hub->vm_inv_eng0_ack + eng; + +- amdgpu_virt_kiq_reg_write_reg_wait(adev, req, ack, tmp, ++ amdgpu_virt_kiq_reg_write_reg_wait(adev, req, ack, inv_req, + 1 << vmid); + return; + } +@@ -532,7 +532,7 @@ static void gmc_v9_0_flush_gpu_tlb(struct amdgpu_device *adev, uint32_t vmid, + DRM_ERROR("Timeout waiting for sem acquire in VM flush!\n"); + } + +- WREG32_NO_KIQ(hub->vm_inv_eng0_req + eng, tmp); ++ WREG32_NO_KIQ(hub->vm_inv_eng0_req + eng, inv_req); + + /* + * Issue a dummy read to wait for the ACK register to be cleared +diff --git a/drivers/gpu/drm/amd/powerplay/smu_v11_0.c b/drivers/gpu/drm/amd/powerplay/smu_v11_0.c +index c5257ae3188a..0922d9cd858a 100644 +--- a/drivers/gpu/drm/amd/powerplay/smu_v11_0.c ++++ b/drivers/gpu/drm/amd/powerplay/smu_v11_0.c +@@ -988,8 +988,12 @@ static int smu_v11_0_init_max_sustainable_clocks(struct smu_context *smu) + struct smu_11_0_max_sustainable_clocks *max_sustainable_clocks; + int ret = 0; + +- max_sustainable_clocks = kzalloc(sizeof(struct smu_11_0_max_sustainable_clocks), ++ if (!smu->smu_table.max_sustainable_clocks) ++ max_sustainable_clocks = kzalloc(sizeof(struct smu_11_0_max_sustainable_clocks), + GFP_KERNEL); ++ else ++ max_sustainable_clocks = smu->smu_table.max_sustainable_clocks; ++ + smu->smu_table.max_sustainable_clocks = (void *)max_sustainable_clocks; + + max_sustainable_clocks->uclock = smu->smu_table.boot_values.uclk / 100; +diff --git a/drivers/hid/hid-apple.c b/drivers/hid/hid-apple.c +index 6ac8becc2372..d732d1d10caf 100644 +--- a/drivers/hid/hid-apple.c ++++ b/drivers/hid/hid-apple.c +@@ -340,7 +340,8 @@ static int apple_input_mapping(struct hid_device *hdev, struct hid_input *hi, + unsigned long **bit, int *max) + { + if (usage->hid == (HID_UP_CUSTOM | 0x0003) || +- usage->hid == (HID_UP_MSVENDOR | 0x0003)) { ++ usage->hid == (HID_UP_MSVENDOR | 0x0003) || ++ usage->hid == (HID_UP_HPVENDOR2 | 0x0003)) { + /* The fn key on Apple USB keyboards */ + set_bit(EV_REP, hi->input->evbit); + hid_map_usage_clear(hi, usage, bit, max, EV_KEY, KEY_FN); +diff --git a/drivers/hid/hid-bigbenff.c b/drivers/hid/hid-bigbenff.c +index 3f6abd190df4..db6da21ade06 100644 +--- a/drivers/hid/hid-bigbenff.c ++++ b/drivers/hid/hid-bigbenff.c +@@ -174,6 +174,7 @@ static __u8 pid0902_rdesc_fixed[] = { + struct bigben_device { + struct hid_device *hid; + struct hid_report *report; ++ bool removed; + u8 led_state; /* LED1 = 1 .. LED4 = 8 */ + u8 right_motor_on; /* right motor off/on 0/1 */ + u8 left_motor_force; /* left motor force 0-255 */ +@@ -190,6 +191,9 @@ static void bigben_worker(struct work_struct *work) + struct bigben_device, worker); + struct hid_field *report_field = bigben->report->field[0]; + ++ if (bigben->removed) ++ return; ++ + if (bigben->work_led) { + bigben->work_led = false; + report_field->value[0] = 0x01; /* 1 = led message */ +@@ -220,10 +224,16 @@ static void bigben_worker(struct work_struct *work) + static int hid_bigben_play_effect(struct input_dev *dev, void *data, + struct ff_effect *effect) + { +- struct bigben_device *bigben = data; ++ struct hid_device *hid = input_get_drvdata(dev); ++ struct bigben_device *bigben = hid_get_drvdata(hid); + u8 right_motor_on; + u8 left_motor_force; + ++ if (!bigben) { ++ hid_err(hid, "no device data\n"); ++ return 0; ++ } ++ + if (effect->type != FF_RUMBLE) + return 0; + +@@ -298,8 +308,8 @@ static void bigben_remove(struct hid_device *hid) + { + struct bigben_device *bigben = hid_get_drvdata(hid); + ++ bigben->removed = true; + cancel_work_sync(&bigben->worker); +- hid_hw_close(hid); + hid_hw_stop(hid); + } + +@@ -319,6 +329,7 @@ static int bigben_probe(struct hid_device *hid, + return -ENOMEM; + hid_set_drvdata(hid, bigben); + bigben->hid = hid; ++ bigben->removed = false; + + error = hid_parse(hid); + if (error) { +@@ -341,10 +352,10 @@ static int bigben_probe(struct hid_device *hid, + + INIT_WORK(&bigben->worker, bigben_worker); + +- error = input_ff_create_memless(hidinput->input, bigben, ++ error = input_ff_create_memless(hidinput->input, NULL, + hid_bigben_play_effect); + if (error) +- return error; ++ goto error_hw_stop; + + name_sz = strlen(dev_name(&hid->dev)) + strlen(":red:bigben#") + 1; + +@@ -354,8 +365,10 @@ static int bigben_probe(struct hid_device *hid, + sizeof(struct led_classdev) + name_sz, + GFP_KERNEL + ); +- if (!led) +- return -ENOMEM; ++ if (!led) { ++ error = -ENOMEM; ++ goto error_hw_stop; ++ } + name = (void *)(&led[1]); + snprintf(name, name_sz, + "%s:red:bigben%d", +@@ -369,7 +382,7 @@ static int bigben_probe(struct hid_device *hid, + bigben->leds[n] = led; + error = devm_led_classdev_register(&hid->dev, led); + if (error) +- return error; ++ goto error_hw_stop; + } + + /* initial state: LED1 is on, no rumble effect */ +@@ -383,6 +396,10 @@ static int bigben_probe(struct hid_device *hid, + hid_info(hid, "LED and force feedback support for BigBen gamepad\n"); + + return 0; ++ ++error_hw_stop: ++ hid_hw_stop(hid); ++ return error; + } + + static __u8 *bigben_report_fixup(struct hid_device *hid, __u8 *rdesc, +diff --git a/drivers/hid/hid-google-hammer.c b/drivers/hid/hid-google-hammer.c +index d86a9189e88f..aeb351658ad3 100644 +--- a/drivers/hid/hid-google-hammer.c ++++ b/drivers/hid/hid-google-hammer.c +@@ -473,6 +473,8 @@ static const struct hid_device_id hammer_devices[] = { + USB_VENDOR_ID_GOOGLE, USB_DEVICE_ID_GOOGLE_MAGNEMITE) }, + { HID_DEVICE(BUS_USB, HID_GROUP_GENERIC, + USB_VENDOR_ID_GOOGLE, USB_DEVICE_ID_GOOGLE_MASTERBALL) }, ++ { HID_DEVICE(BUS_USB, HID_GROUP_GENERIC, ++ USB_VENDOR_ID_GOOGLE, USB_DEVICE_ID_GOOGLE_MOONBALL) }, + { HID_DEVICE(BUS_USB, HID_GROUP_GENERIC, + USB_VENDOR_ID_GOOGLE, USB_DEVICE_ID_GOOGLE_STAFF) }, + { HID_DEVICE(BUS_USB, HID_GROUP_GENERIC, +diff --git a/drivers/hid/hid-ids.h b/drivers/hid/hid-ids.h +index 5fc82029a03b..646b98809ed3 100644 +--- a/drivers/hid/hid-ids.h ++++ b/drivers/hid/hid-ids.h +@@ -478,6 +478,7 @@ + #define USB_DEVICE_ID_GOOGLE_WHISKERS 0x5030 + #define USB_DEVICE_ID_GOOGLE_MASTERBALL 0x503c + #define USB_DEVICE_ID_GOOGLE_MAGNEMITE 0x503d ++#define USB_DEVICE_ID_GOOGLE_MOONBALL 0x5044 + + #define USB_VENDOR_ID_GOTOP 0x08f2 + #define USB_DEVICE_ID_SUPER_Q2 0x007f +@@ -726,6 +727,7 @@ + #define USB_DEVICE_ID_LENOVO_X1_COVER 0x6085 + #define USB_DEVICE_ID_LENOVO_X1_TAB 0x60a3 + #define USB_DEVICE_ID_LENOVO_X1_TAB3 0x60b5 ++#define USB_DEVICE_ID_LENOVO_PIXART_USB_MOUSE_608D 0x608d + + #define USB_VENDOR_ID_LG 0x1fd2 + #define USB_DEVICE_ID_LG_MULTITOUCH 0x0064 +diff --git a/drivers/hid/hid-quirks.c b/drivers/hid/hid-quirks.c +index fa58a7cbb3ff..ae64a286a68f 100644 +--- a/drivers/hid/hid-quirks.c ++++ b/drivers/hid/hid-quirks.c +@@ -103,6 +103,7 @@ static const struct hid_device_id hid_quirks[] = { + { HID_USB_DEVICE(USB_VENDOR_ID_KYE, USB_DEVICE_ID_KYE_PENSKETCH_M912), HID_QUIRK_MULTI_INPUT }, + { HID_USB_DEVICE(USB_VENDOR_ID_KYE, USB_DEVICE_ID_KYE_EASYPEN_M406XE), HID_QUIRK_MULTI_INPUT }, + { HID_USB_DEVICE(USB_VENDOR_ID_KYE, USB_DEVICE_ID_PIXART_USB_OPTICAL_MOUSE_ID2), HID_QUIRK_ALWAYS_POLL }, ++ { HID_USB_DEVICE(USB_VENDOR_ID_LENOVO, USB_DEVICE_ID_LENOVO_PIXART_USB_MOUSE_608D), HID_QUIRK_ALWAYS_POLL }, + { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_C007), HID_QUIRK_ALWAYS_POLL }, + { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_C077), HID_QUIRK_ALWAYS_POLL }, + { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_KEYBOARD_G710_PLUS), HID_QUIRK_NOGET }, +diff --git a/drivers/hid/i2c-hid/i2c-hid-dmi-quirks.c b/drivers/hid/i2c-hid/i2c-hid-dmi-quirks.c +index d31ea82b84c1..a66f08041a1a 100644 +--- a/drivers/hid/i2c-hid/i2c-hid-dmi-quirks.c ++++ b/drivers/hid/i2c-hid/i2c-hid-dmi-quirks.c +@@ -341,6 +341,14 @@ static const struct dmi_system_id i2c_hid_dmi_desc_override_table[] = { + }, + .driver_data = (void *)&sipodev_desc + }, ++ { ++ .ident = "Trekstor SURFBOOK E11B", ++ .matches = { ++ DMI_EXACT_MATCH(DMI_SYS_VENDOR, "TREKSTOR"), ++ DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "SURFBOOK E11B"), ++ }, ++ .driver_data = (void *)&sipodev_desc ++ }, + { + .ident = "Direkt-Tek DTLAPY116-2", + .matches = { +diff --git a/drivers/net/ethernet/huawei/hinic/hinic_hw_dev.c b/drivers/net/ethernet/huawei/hinic/hinic_hw_dev.c +index 6f2cf569a283..79b3d53f2fbf 100644 +--- a/drivers/net/ethernet/huawei/hinic/hinic_hw_dev.c ++++ b/drivers/net/ethernet/huawei/hinic/hinic_hw_dev.c +@@ -297,6 +297,7 @@ static int set_hw_ioctxt(struct hinic_hwdev *hwdev, unsigned int rq_depth, + } + + hw_ioctxt.func_idx = HINIC_HWIF_FUNC_IDX(hwif); ++ hw_ioctxt.ppf_idx = HINIC_HWIF_PPF_IDX(hwif); + + hw_ioctxt.set_cmdq_depth = HW_IOCTXT_SET_CMDQ_DEPTH_DEFAULT; + hw_ioctxt.cmdq_depth = 0; +diff --git a/drivers/net/ethernet/huawei/hinic/hinic_hw_dev.h b/drivers/net/ethernet/huawei/hinic/hinic_hw_dev.h +index b069045de416..66fd2340d447 100644 +--- a/drivers/net/ethernet/huawei/hinic/hinic_hw_dev.h ++++ b/drivers/net/ethernet/huawei/hinic/hinic_hw_dev.h +@@ -151,8 +151,8 @@ struct hinic_cmd_hw_ioctxt { + + u8 lro_en; + u8 rsvd3; ++ u8 ppf_idx; + u8 rsvd4; +- u8 rsvd5; + + u16 rq_depth; + u16 rx_buf_sz_idx; +diff --git a/drivers/net/ethernet/huawei/hinic/hinic_hw_if.h b/drivers/net/ethernet/huawei/hinic/hinic_hw_if.h +index 517794509eb2..c7bb9ceca72c 100644 +--- a/drivers/net/ethernet/huawei/hinic/hinic_hw_if.h ++++ b/drivers/net/ethernet/huawei/hinic/hinic_hw_if.h +@@ -137,6 +137,7 @@ + #define HINIC_HWIF_FUNC_IDX(hwif) ((hwif)->attr.func_idx) + #define HINIC_HWIF_PCI_INTF(hwif) ((hwif)->attr.pci_intf_idx) + #define HINIC_HWIF_PF_IDX(hwif) ((hwif)->attr.pf_idx) ++#define HINIC_HWIF_PPF_IDX(hwif) ((hwif)->attr.ppf_idx) + + #define HINIC_FUNC_TYPE(hwif) ((hwif)->attr.func_type) + #define HINIC_IS_PF(hwif) (HINIC_FUNC_TYPE(hwif) == HINIC_PF) +diff --git a/drivers/net/ethernet/huawei/hinic/hinic_hw_qp.h b/drivers/net/ethernet/huawei/hinic/hinic_hw_qp.h +index f4a339b10b10..79091e131418 100644 +--- a/drivers/net/ethernet/huawei/hinic/hinic_hw_qp.h ++++ b/drivers/net/ethernet/huawei/hinic/hinic_hw_qp.h +@@ -94,6 +94,7 @@ struct hinic_rq { + + struct hinic_wq *wq; + ++ struct cpumask affinity_mask; + u32 irq; + u16 msix_entry; + +diff --git a/drivers/net/ethernet/huawei/hinic/hinic_main.c b/drivers/net/ethernet/huawei/hinic/hinic_main.c +index 2411ad270c98..42d00b049c6e 100644 +--- a/drivers/net/ethernet/huawei/hinic/hinic_main.c ++++ b/drivers/net/ethernet/huawei/hinic/hinic_main.c +@@ -356,7 +356,8 @@ static void hinic_enable_rss(struct hinic_dev *nic_dev) + if (!num_cpus) + num_cpus = num_online_cpus(); + +- nic_dev->num_qps = min_t(u16, nic_dev->max_qps, num_cpus); ++ nic_dev->num_qps = hinic_hwdev_num_qps(hwdev); ++ nic_dev->num_qps = min_t(u16, nic_dev->num_qps, num_cpus); + + nic_dev->rss_limit = nic_dev->num_qps; + nic_dev->num_rss = nic_dev->num_qps; +diff --git a/drivers/net/ethernet/huawei/hinic/hinic_rx.c b/drivers/net/ethernet/huawei/hinic/hinic_rx.c +index 56ea6d692f1c..2695ad69fca6 100644 +--- a/drivers/net/ethernet/huawei/hinic/hinic_rx.c ++++ b/drivers/net/ethernet/huawei/hinic/hinic_rx.c +@@ -475,7 +475,6 @@ static int rx_request_irq(struct hinic_rxq *rxq) + struct hinic_hwdev *hwdev = nic_dev->hwdev; + struct hinic_rq *rq = rxq->rq; + struct hinic_qp *qp; +- struct cpumask mask; + int err; + + rx_add_napi(rxq); +@@ -492,8 +491,8 @@ static int rx_request_irq(struct hinic_rxq *rxq) + } + + qp = container_of(rq, struct hinic_qp, rq); +- cpumask_set_cpu(qp->q_id % num_online_cpus(), &mask); +- return irq_set_affinity_hint(rq->irq, &mask); ++ cpumask_set_cpu(qp->q_id % num_online_cpus(), &rq->affinity_mask); ++ return irq_set_affinity_hint(rq->irq, &rq->affinity_mask); + } + + static void rx_free_irq(struct hinic_rxq *rxq) +diff --git a/drivers/net/ethernet/micrel/ks8851_mll.c b/drivers/net/ethernet/micrel/ks8851_mll.c +index 1c9e70c8cc30..58579baf3f7a 100644 +--- a/drivers/net/ethernet/micrel/ks8851_mll.c ++++ b/drivers/net/ethernet/micrel/ks8851_mll.c +@@ -513,14 +513,17 @@ static irqreturn_t ks_irq(int irq, void *pw) + { + struct net_device *netdev = pw; + struct ks_net *ks = netdev_priv(netdev); ++ unsigned long flags; + u16 status; + ++ spin_lock_irqsave(&ks->statelock, flags); + /*this should be the first in IRQ handler */ + ks_save_cmd_reg(ks); + + status = ks_rdreg16(ks, KS_ISR); + if (unlikely(!status)) { + ks_restore_cmd_reg(ks); ++ spin_unlock_irqrestore(&ks->statelock, flags); + return IRQ_NONE; + } + +@@ -546,6 +549,7 @@ static irqreturn_t ks_irq(int irq, void *pw) + ks->netdev->stats.rx_over_errors++; + /* this should be the last in IRQ handler*/ + ks_restore_cmd_reg(ks); ++ spin_unlock_irqrestore(&ks->statelock, flags); + return IRQ_HANDLED; + } + +@@ -615,6 +619,7 @@ static int ks_net_stop(struct net_device *netdev) + + /* shutdown RX/TX QMU */ + ks_disable_qmu(ks); ++ ks_disable_int(ks); + + /* set powermode to soft power down to save power */ + ks_set_powermode(ks, PMECR_PM_SOFTDOWN); +@@ -671,10 +676,9 @@ static netdev_tx_t ks_start_xmit(struct sk_buff *skb, struct net_device *netdev) + { + netdev_tx_t retv = NETDEV_TX_OK; + struct ks_net *ks = netdev_priv(netdev); ++ unsigned long flags; + +- disable_irq(netdev->irq); +- ks_disable_int(ks); +- spin_lock(&ks->statelock); ++ spin_lock_irqsave(&ks->statelock, flags); + + /* Extra space are required: + * 4 byte for alignment, 4 for status/length, 4 for CRC +@@ -688,9 +692,7 @@ static netdev_tx_t ks_start_xmit(struct sk_buff *skb, struct net_device *netdev) + dev_kfree_skb(skb); + } else + retv = NETDEV_TX_BUSY; +- spin_unlock(&ks->statelock); +- ks_enable_int(ks); +- enable_irq(netdev->irq); ++ spin_unlock_irqrestore(&ks->statelock, flags); + return retv; + } + +diff --git a/drivers/net/ethernet/qualcomm/rmnet/rmnet_config.c b/drivers/net/ethernet/qualcomm/rmnet/rmnet_config.c +index 06de59521fc4..fbf4cbcf1a65 100644 +--- a/drivers/net/ethernet/qualcomm/rmnet/rmnet_config.c ++++ b/drivers/net/ethernet/qualcomm/rmnet/rmnet_config.c +@@ -13,25 +13,6 @@ + #include "rmnet_vnd.h" + #include "rmnet_private.h" + +-/* Locking scheme - +- * The shared resource which needs to be protected is realdev->rx_handler_data. +- * For the writer path, this is using rtnl_lock(). The writer paths are +- * rmnet_newlink(), rmnet_dellink() and rmnet_force_unassociate_device(). These +- * paths are already called with rtnl_lock() acquired in. There is also an +- * ASSERT_RTNL() to ensure that we are calling with rtnl acquired. For +- * dereference here, we will need to use rtnl_dereference(). Dev list writing +- * needs to happen with rtnl_lock() acquired for netdev_master_upper_dev_link(). +- * For the reader path, the real_dev->rx_handler_data is called in the TX / RX +- * path. We only need rcu_read_lock() for these scenarios. In these cases, +- * the rcu_read_lock() is held in __dev_queue_xmit() and +- * netif_receive_skb_internal(), so readers need to use rcu_dereference_rtnl() +- * to get the relevant information. For dev list reading, we again acquire +- * rcu_read_lock() in rmnet_dellink() for netdev_master_upper_dev_get_rcu(). +- * We also use unregister_netdevice_many() to free all rmnet devices in +- * rmnet_force_unassociate_device() so we dont lose the rtnl_lock() and free in +- * same context. +- */ +- + /* Local Definitions and Declarations */ + + static const struct nla_policy rmnet_policy[IFLA_RMNET_MAX + 1] = { +@@ -51,9 +32,10 @@ rmnet_get_port_rtnl(const struct net_device *real_dev) + return rtnl_dereference(real_dev->rx_handler_data); + } + +-static int rmnet_unregister_real_device(struct net_device *real_dev, +- struct rmnet_port *port) ++static int rmnet_unregister_real_device(struct net_device *real_dev) + { ++ struct rmnet_port *port = rmnet_get_port_rtnl(real_dev); ++ + if (port->nr_rmnet_devs) + return -EINVAL; + +@@ -61,9 +43,6 @@ static int rmnet_unregister_real_device(struct net_device *real_dev, + + kfree(port); + +- /* release reference on real_dev */ +- dev_put(real_dev); +- + netdev_dbg(real_dev, "Removed from rmnet\n"); + return 0; + } +@@ -89,9 +68,6 @@ static int rmnet_register_real_device(struct net_device *real_dev) + return -EBUSY; + } + +- /* hold on to real dev for MAP data */ +- dev_hold(real_dev); +- + for (entry = 0; entry < RMNET_MAX_LOGICAL_EP; entry++) + INIT_HLIST_HEAD(&port->muxed_ep[entry]); + +@@ -99,28 +75,33 @@ static int rmnet_register_real_device(struct net_device *real_dev) + return 0; + } + +-static void rmnet_unregister_bridge(struct net_device *dev, +- struct rmnet_port *port) ++static void rmnet_unregister_bridge(struct rmnet_port *port) + { +- struct rmnet_port *bridge_port; +- struct net_device *bridge_dev; ++ struct net_device *bridge_dev, *real_dev, *rmnet_dev; ++ struct rmnet_port *real_port; + + if (port->rmnet_mode != RMNET_EPMODE_BRIDGE) + return; + +- /* bridge slave handling */ ++ rmnet_dev = port->rmnet_dev; + if (!port->nr_rmnet_devs) { +- bridge_dev = port->bridge_ep; ++ /* bridge device */ ++ real_dev = port->bridge_ep; ++ bridge_dev = port->dev; + +- bridge_port = rmnet_get_port_rtnl(bridge_dev); +- bridge_port->bridge_ep = NULL; +- bridge_port->rmnet_mode = RMNET_EPMODE_VND; ++ real_port = rmnet_get_port_rtnl(real_dev); ++ real_port->bridge_ep = NULL; ++ real_port->rmnet_mode = RMNET_EPMODE_VND; + } else { ++ /* real device */ + bridge_dev = port->bridge_ep; + +- bridge_port = rmnet_get_port_rtnl(bridge_dev); +- rmnet_unregister_real_device(bridge_dev, bridge_port); ++ port->bridge_ep = NULL; ++ port->rmnet_mode = RMNET_EPMODE_VND; + } ++ ++ netdev_upper_dev_unlink(bridge_dev, rmnet_dev); ++ rmnet_unregister_real_device(bridge_dev); + } + + static int rmnet_newlink(struct net *src_net, struct net_device *dev, +@@ -135,6 +116,11 @@ static int rmnet_newlink(struct net *src_net, struct net_device *dev, + int err = 0; + u16 mux_id; + ++ if (!tb[IFLA_LINK]) { ++ NL_SET_ERR_MSG_MOD(extack, "link not specified"); ++ return -EINVAL; ++ } ++ + real_dev = __dev_get_by_index(src_net, nla_get_u32(tb[IFLA_LINK])); + if (!real_dev || !dev) + return -ENODEV; +@@ -157,7 +143,12 @@ static int rmnet_newlink(struct net *src_net, struct net_device *dev, + if (err) + goto err1; + ++ err = netdev_upper_dev_link(real_dev, dev, extack); ++ if (err < 0) ++ goto err2; ++ + port->rmnet_mode = mode; ++ port->rmnet_dev = dev; + + hlist_add_head_rcu(&ep->hlnode, &port->muxed_ep[mux_id]); + +@@ -173,8 +164,11 @@ static int rmnet_newlink(struct net *src_net, struct net_device *dev, + + return 0; + ++err2: ++ unregister_netdevice(dev); ++ rmnet_vnd_dellink(mux_id, port, ep); + err1: +- rmnet_unregister_real_device(real_dev, port); ++ rmnet_unregister_real_device(real_dev); + err0: + kfree(ep); + return err; +@@ -183,77 +177,74 @@ err0: + static void rmnet_dellink(struct net_device *dev, struct list_head *head) + { + struct rmnet_priv *priv = netdev_priv(dev); +- struct net_device *real_dev; ++ struct net_device *real_dev, *bridge_dev; ++ struct rmnet_port *real_port, *bridge_port; + struct rmnet_endpoint *ep; +- struct rmnet_port *port; +- u8 mux_id; ++ u8 mux_id = priv->mux_id; + + real_dev = priv->real_dev; + +- if (!real_dev || !rmnet_is_real_dev_registered(real_dev)) ++ if (!rmnet_is_real_dev_registered(real_dev)) + return; + +- port = rmnet_get_port_rtnl(real_dev); +- +- mux_id = rmnet_vnd_get_mux(dev); ++ real_port = rmnet_get_port_rtnl(real_dev); ++ bridge_dev = real_port->bridge_ep; ++ if (bridge_dev) { ++ bridge_port = rmnet_get_port_rtnl(bridge_dev); ++ rmnet_unregister_bridge(bridge_port); ++ } + +- ep = rmnet_get_endpoint(port, mux_id); ++ ep = rmnet_get_endpoint(real_port, mux_id); + if (ep) { + hlist_del_init_rcu(&ep->hlnode); +- rmnet_unregister_bridge(dev, port); +- rmnet_vnd_dellink(mux_id, port, ep); ++ rmnet_vnd_dellink(mux_id, real_port, ep); + kfree(ep); + } +- rmnet_unregister_real_device(real_dev, port); + ++ netdev_upper_dev_unlink(real_dev, dev); ++ rmnet_unregister_real_device(real_dev); + unregister_netdevice_queue(dev, head); + } + +-static void rmnet_force_unassociate_device(struct net_device *dev) ++static void rmnet_force_unassociate_device(struct net_device *real_dev) + { +- struct net_device *real_dev = dev; + struct hlist_node *tmp_ep; + struct rmnet_endpoint *ep; + struct rmnet_port *port; + unsigned long bkt_ep; + LIST_HEAD(list); + +- if (!rmnet_is_real_dev_registered(real_dev)) +- return; +- +- ASSERT_RTNL(); +- +- port = rmnet_get_port_rtnl(dev); +- +- rcu_read_lock(); +- rmnet_unregister_bridge(dev, port); +- +- hash_for_each_safe(port->muxed_ep, bkt_ep, tmp_ep, ep, hlnode) { +- unregister_netdevice_queue(ep->egress_dev, &list); +- rmnet_vnd_dellink(ep->mux_id, port, ep); ++ port = rmnet_get_port_rtnl(real_dev); + +- hlist_del_init_rcu(&ep->hlnode); +- kfree(ep); ++ if (port->nr_rmnet_devs) { ++ /* real device */ ++ rmnet_unregister_bridge(port); ++ hash_for_each_safe(port->muxed_ep, bkt_ep, tmp_ep, ep, hlnode) { ++ unregister_netdevice_queue(ep->egress_dev, &list); ++ netdev_upper_dev_unlink(real_dev, ep->egress_dev); ++ rmnet_vnd_dellink(ep->mux_id, port, ep); ++ hlist_del_init_rcu(&ep->hlnode); ++ kfree(ep); ++ } ++ rmnet_unregister_real_device(real_dev); ++ unregister_netdevice_many(&list); ++ } else { ++ rmnet_unregister_bridge(port); + } +- +- rcu_read_unlock(); +- unregister_netdevice_many(&list); +- +- rmnet_unregister_real_device(real_dev, port); + } + + static int rmnet_config_notify_cb(struct notifier_block *nb, + unsigned long event, void *data) + { +- struct net_device *dev = netdev_notifier_info_to_dev(data); ++ struct net_device *real_dev = netdev_notifier_info_to_dev(data); + +- if (!dev) ++ if (!rmnet_is_real_dev_registered(real_dev)) + return NOTIFY_DONE; + + switch (event) { + case NETDEV_UNREGISTER: +- netdev_dbg(dev, "Kernel unregister\n"); +- rmnet_force_unassociate_device(dev); ++ netdev_dbg(real_dev, "Kernel unregister\n"); ++ rmnet_force_unassociate_device(real_dev); + break; + + default: +@@ -295,16 +286,18 @@ static int rmnet_changelink(struct net_device *dev, struct nlattr *tb[], + if (!dev) + return -ENODEV; + +- real_dev = __dev_get_by_index(dev_net(dev), +- nla_get_u32(tb[IFLA_LINK])); +- +- if (!real_dev || !rmnet_is_real_dev_registered(real_dev)) ++ real_dev = priv->real_dev; ++ if (!rmnet_is_real_dev_registered(real_dev)) + return -ENODEV; + + port = rmnet_get_port_rtnl(real_dev); + + if (data[IFLA_RMNET_MUX_ID]) { + mux_id = nla_get_u16(data[IFLA_RMNET_MUX_ID]); ++ if (rmnet_get_endpoint(port, mux_id)) { ++ NL_SET_ERR_MSG_MOD(extack, "MUX ID already exists"); ++ return -EINVAL; ++ } + ep = rmnet_get_endpoint(port, priv->mux_id); + if (!ep) + return -ENODEV; +@@ -379,11 +372,10 @@ struct rtnl_link_ops rmnet_link_ops __read_mostly = { + .fill_info = rmnet_fill_info, + }; + +-/* Needs either rcu_read_lock() or rtnl lock */ +-struct rmnet_port *rmnet_get_port(struct net_device *real_dev) ++struct rmnet_port *rmnet_get_port_rcu(struct net_device *real_dev) + { + if (rmnet_is_real_dev_registered(real_dev)) +- return rcu_dereference_rtnl(real_dev->rx_handler_data); ++ return rcu_dereference_bh(real_dev->rx_handler_data); + else + return NULL; + } +@@ -409,7 +401,7 @@ int rmnet_add_bridge(struct net_device *rmnet_dev, + struct rmnet_port *port, *slave_port; + int err; + +- port = rmnet_get_port(real_dev); ++ port = rmnet_get_port_rtnl(real_dev); + + /* If there is more than one rmnet dev attached, its probably being + * used for muxing. Skip the briding in that case +@@ -417,6 +409,9 @@ int rmnet_add_bridge(struct net_device *rmnet_dev, + if (port->nr_rmnet_devs > 1) + return -EINVAL; + ++ if (port->rmnet_mode != RMNET_EPMODE_VND) ++ return -EINVAL; ++ + if (rmnet_is_real_dev_registered(slave_dev)) + return -EBUSY; + +@@ -424,9 +419,17 @@ int rmnet_add_bridge(struct net_device *rmnet_dev, + if (err) + return -EBUSY; + +- slave_port = rmnet_get_port(slave_dev); ++ err = netdev_master_upper_dev_link(slave_dev, rmnet_dev, NULL, NULL, ++ extack); ++ if (err) { ++ rmnet_unregister_real_device(slave_dev); ++ return err; ++ } ++ ++ slave_port = rmnet_get_port_rtnl(slave_dev); + slave_port->rmnet_mode = RMNET_EPMODE_BRIDGE; + slave_port->bridge_ep = real_dev; ++ slave_port->rmnet_dev = rmnet_dev; + + port->rmnet_mode = RMNET_EPMODE_BRIDGE; + port->bridge_ep = slave_dev; +@@ -438,16 +441,9 @@ int rmnet_add_bridge(struct net_device *rmnet_dev, + int rmnet_del_bridge(struct net_device *rmnet_dev, + struct net_device *slave_dev) + { +- struct rmnet_priv *priv = netdev_priv(rmnet_dev); +- struct net_device *real_dev = priv->real_dev; +- struct rmnet_port *port, *slave_port; ++ struct rmnet_port *port = rmnet_get_port_rtnl(slave_dev); + +- port = rmnet_get_port(real_dev); +- port->rmnet_mode = RMNET_EPMODE_VND; +- port->bridge_ep = NULL; +- +- slave_port = rmnet_get_port(slave_dev); +- rmnet_unregister_real_device(slave_dev, slave_port); ++ rmnet_unregister_bridge(port); + + netdev_dbg(slave_dev, "removed from rmnet as slave\n"); + return 0; +@@ -473,8 +469,8 @@ static int __init rmnet_init(void) + + static void __exit rmnet_exit(void) + { +- unregister_netdevice_notifier(&rmnet_dev_notifier); + rtnl_link_unregister(&rmnet_link_ops); ++ unregister_netdevice_notifier(&rmnet_dev_notifier); + } + + module_init(rmnet_init) +diff --git a/drivers/net/ethernet/qualcomm/rmnet/rmnet_config.h b/drivers/net/ethernet/qualcomm/rmnet/rmnet_config.h +index cd0a6bcbe74a..be515982d628 100644 +--- a/drivers/net/ethernet/qualcomm/rmnet/rmnet_config.h ++++ b/drivers/net/ethernet/qualcomm/rmnet/rmnet_config.h +@@ -28,6 +28,7 @@ struct rmnet_port { + u8 rmnet_mode; + struct hlist_head muxed_ep[RMNET_MAX_LOGICAL_EP]; + struct net_device *bridge_ep; ++ struct net_device *rmnet_dev; + }; + + extern struct rtnl_link_ops rmnet_link_ops; +@@ -65,7 +66,7 @@ struct rmnet_priv { + struct rmnet_priv_stats stats; + }; + +-struct rmnet_port *rmnet_get_port(struct net_device *real_dev); ++struct rmnet_port *rmnet_get_port_rcu(struct net_device *real_dev); + struct rmnet_endpoint *rmnet_get_endpoint(struct rmnet_port *port, u8 mux_id); + int rmnet_add_bridge(struct net_device *rmnet_dev, + struct net_device *slave_dev, +diff --git a/drivers/net/ethernet/qualcomm/rmnet/rmnet_handlers.c b/drivers/net/ethernet/qualcomm/rmnet/rmnet_handlers.c +index 1b74bc160402..29a7bfa2584d 100644 +--- a/drivers/net/ethernet/qualcomm/rmnet/rmnet_handlers.c ++++ b/drivers/net/ethernet/qualcomm/rmnet/rmnet_handlers.c +@@ -159,6 +159,9 @@ static int rmnet_map_egress_handler(struct sk_buff *skb, + static void + rmnet_bridge_handler(struct sk_buff *skb, struct net_device *bridge_dev) + { ++ if (skb_mac_header_was_set(skb)) ++ skb_push(skb, skb->mac_len); ++ + if (bridge_dev) { + skb->dev = bridge_dev; + dev_queue_xmit(skb); +@@ -184,7 +187,7 @@ rx_handler_result_t rmnet_rx_handler(struct sk_buff **pskb) + return RX_HANDLER_PASS; + + dev = skb->dev; +- port = rmnet_get_port(dev); ++ port = rmnet_get_port_rcu(dev); + + switch (port->rmnet_mode) { + case RMNET_EPMODE_VND: +@@ -217,7 +220,7 @@ void rmnet_egress_handler(struct sk_buff *skb) + skb->dev = priv->real_dev; + mux_id = priv->mux_id; + +- port = rmnet_get_port(skb->dev); ++ port = rmnet_get_port_rcu(skb->dev); + if (!port) + goto drop; + +diff --git a/drivers/net/ethernet/qualcomm/rmnet/rmnet_vnd.c b/drivers/net/ethernet/qualcomm/rmnet/rmnet_vnd.c +index 509dfc895a33..26ad40f19c64 100644 +--- a/drivers/net/ethernet/qualcomm/rmnet/rmnet_vnd.c ++++ b/drivers/net/ethernet/qualcomm/rmnet/rmnet_vnd.c +@@ -266,14 +266,6 @@ int rmnet_vnd_dellink(u8 id, struct rmnet_port *port, + return 0; + } + +-u8 rmnet_vnd_get_mux(struct net_device *rmnet_dev) +-{ +- struct rmnet_priv *priv; +- +- priv = netdev_priv(rmnet_dev); +- return priv->mux_id; +-} +- + int rmnet_vnd_do_flow_control(struct net_device *rmnet_dev, int enable) + { + netdev_dbg(rmnet_dev, "Setting VND TX queue state to %d\n", enable); +diff --git a/drivers/net/ethernet/qualcomm/rmnet/rmnet_vnd.h b/drivers/net/ethernet/qualcomm/rmnet/rmnet_vnd.h +index 54cbaf3c3bc4..14d77c709d4a 100644 +--- a/drivers/net/ethernet/qualcomm/rmnet/rmnet_vnd.h ++++ b/drivers/net/ethernet/qualcomm/rmnet/rmnet_vnd.h +@@ -16,6 +16,5 @@ int rmnet_vnd_dellink(u8 id, struct rmnet_port *port, + struct rmnet_endpoint *ep); + void rmnet_vnd_rx_fixup(struct sk_buff *skb, struct net_device *dev); + void rmnet_vnd_tx_fixup(struct sk_buff *skb, struct net_device *dev); +-u8 rmnet_vnd_get_mux(struct net_device *rmnet_dev); + void rmnet_vnd_setup(struct net_device *dev); + #endif /* _RMNET_VND_H_ */ +diff --git a/drivers/net/ethernet/sfc/ptp.c b/drivers/net/ethernet/sfc/ptp.c +index af15a737c675..59b4f16896a8 100644 +--- a/drivers/net/ethernet/sfc/ptp.c ++++ b/drivers/net/ethernet/sfc/ptp.c +@@ -560,13 +560,45 @@ efx_ptp_mac_nic_to_ktime_correction(struct efx_nic *efx, + u32 nic_major, u32 nic_minor, + s32 correction) + { ++ u32 sync_timestamp; + ktime_t kt = { 0 }; ++ s16 delta; + + if (!(nic_major & 0x80000000)) { + WARN_ON_ONCE(nic_major >> 16); +- /* Use the top bits from the latest sync event. */ +- nic_major &= 0xffff; +- nic_major |= (last_sync_timestamp_major(efx) & 0xffff0000); ++ ++ /* Medford provides 48 bits of timestamp, so we must get the top ++ * 16 bits from the timesync event state. ++ * ++ * We only have the lower 16 bits of the time now, but we do ++ * have a full resolution timestamp at some point in past. As ++ * long as the difference between the (real) now and the sync ++ * is less than 2^15, then we can reconstruct the difference ++ * between those two numbers using only the lower 16 bits of ++ * each. ++ * ++ * Put another way ++ * ++ * a - b = ((a mod k) - b) mod k ++ * ++ * when -k/2 < (a-b) < k/2. In our case k is 2^16. We know ++ * (a mod k) and b, so can calculate the delta, a - b. ++ * ++ */ ++ sync_timestamp = last_sync_timestamp_major(efx); ++ ++ /* Because delta is s16 this does an implicit mask down to ++ * 16 bits which is what we need, assuming ++ * MEDFORD_TX_SECS_EVENT_BITS is 16. delta is signed so that ++ * we can deal with the (unlikely) case of sync timestamps ++ * arriving from the future. ++ */ ++ delta = nic_major - sync_timestamp; ++ ++ /* Recover the fully specified time now, by applying the offset ++ * to the (fully specified) sync time. ++ */ ++ nic_major = sync_timestamp + delta; + + kt = ptp->nic_to_kernel_time(nic_major, nic_minor, + correction); +diff --git a/drivers/net/ethernet/xilinx/ll_temac.h b/drivers/net/ethernet/xilinx/ll_temac.h +index 276292bca334..53fb8141f1a6 100644 +--- a/drivers/net/ethernet/xilinx/ll_temac.h ++++ b/drivers/net/ethernet/xilinx/ll_temac.h +@@ -375,10 +375,14 @@ struct temac_local { + int tx_bd_next; + int tx_bd_tail; + int rx_bd_ci; ++ int rx_bd_tail; + + /* DMA channel control setup */ + u32 tx_chnl_ctrl; + u32 rx_chnl_ctrl; ++ u8 coalesce_count_rx; ++ ++ struct delayed_work restart_work; + }; + + /* Wrappers for temac_ior()/temac_iow() function pointers above */ +diff --git a/drivers/net/ethernet/xilinx/ll_temac_main.c b/drivers/net/ethernet/xilinx/ll_temac_main.c +index 21c1b4322ea7..eb480204cdbe 100644 +--- a/drivers/net/ethernet/xilinx/ll_temac_main.c ++++ b/drivers/net/ethernet/xilinx/ll_temac_main.c +@@ -51,6 +51,7 @@ + #include <linux/ip.h> + #include <linux/slab.h> + #include <linux/interrupt.h> ++#include <linux/workqueue.h> + #include <linux/dma-mapping.h> + #include <linux/processor.h> + #include <linux/platform_data/xilinx-ll-temac.h> +@@ -367,6 +368,8 @@ static int temac_dma_bd_init(struct net_device *ndev) + skb_dma_addr = dma_map_single(ndev->dev.parent, skb->data, + XTE_MAX_JUMBO_FRAME_SIZE, + DMA_FROM_DEVICE); ++ if (dma_mapping_error(ndev->dev.parent, skb_dma_addr)) ++ goto out; + lp->rx_bd_v[i].phys = cpu_to_be32(skb_dma_addr); + lp->rx_bd_v[i].len = cpu_to_be32(XTE_MAX_JUMBO_FRAME_SIZE); + lp->rx_bd_v[i].app0 = cpu_to_be32(STS_CTRL_APP0_IRQONEND); +@@ -387,12 +390,13 @@ static int temac_dma_bd_init(struct net_device *ndev) + lp->tx_bd_next = 0; + lp->tx_bd_tail = 0; + lp->rx_bd_ci = 0; ++ lp->rx_bd_tail = RX_BD_NUM - 1; + + /* Enable RX DMA transfers */ + wmb(); + lp->dma_out(lp, RX_CURDESC_PTR, lp->rx_bd_p); + lp->dma_out(lp, RX_TAILDESC_PTR, +- lp->rx_bd_p + (sizeof(*lp->rx_bd_v) * (RX_BD_NUM - 1))); ++ lp->rx_bd_p + (sizeof(*lp->rx_bd_v) * lp->rx_bd_tail)); + + /* Prepare for TX DMA transfer */ + lp->dma_out(lp, TX_CURDESC_PTR, lp->tx_bd_p); +@@ -788,6 +792,9 @@ static void temac_start_xmit_done(struct net_device *ndev) + stat = be32_to_cpu(cur_p->app0); + } + ++ /* Matches barrier in temac_start_xmit */ ++ smp_mb(); ++ + netif_wake_queue(ndev); + } + +@@ -830,9 +837,19 @@ temac_start_xmit(struct sk_buff *skb, struct net_device *ndev) + cur_p = &lp->tx_bd_v[lp->tx_bd_tail]; + + if (temac_check_tx_bd_space(lp, num_frag + 1)) { +- if (!netif_queue_stopped(ndev)) +- netif_stop_queue(ndev); +- return NETDEV_TX_BUSY; ++ if (netif_queue_stopped(ndev)) ++ return NETDEV_TX_BUSY; ++ ++ netif_stop_queue(ndev); ++ ++ /* Matches barrier in temac_start_xmit_done */ ++ smp_mb(); ++ ++ /* Space might have just been freed - check again */ ++ if (temac_check_tx_bd_space(lp, num_frag)) ++ return NETDEV_TX_BUSY; ++ ++ netif_wake_queue(ndev); + } + + cur_p->app0 = 0; +@@ -850,12 +867,16 @@ temac_start_xmit(struct sk_buff *skb, struct net_device *ndev) + skb_dma_addr = dma_map_single(ndev->dev.parent, skb->data, + skb_headlen(skb), DMA_TO_DEVICE); + cur_p->len = cpu_to_be32(skb_headlen(skb)); ++ if (WARN_ON_ONCE(dma_mapping_error(ndev->dev.parent, skb_dma_addr))) { ++ dev_kfree_skb_any(skb); ++ ndev->stats.tx_dropped++; ++ return NETDEV_TX_OK; ++ } + cur_p->phys = cpu_to_be32(skb_dma_addr); + ptr_to_txbd((void *)skb, cur_p); + + for (ii = 0; ii < num_frag; ii++) { +- lp->tx_bd_tail++; +- if (lp->tx_bd_tail >= TX_BD_NUM) ++ if (++lp->tx_bd_tail >= TX_BD_NUM) + lp->tx_bd_tail = 0; + + cur_p = &lp->tx_bd_v[lp->tx_bd_tail]; +@@ -863,6 +884,27 @@ temac_start_xmit(struct sk_buff *skb, struct net_device *ndev) + skb_frag_address(frag), + skb_frag_size(frag), + DMA_TO_DEVICE); ++ if (dma_mapping_error(ndev->dev.parent, skb_dma_addr)) { ++ if (--lp->tx_bd_tail < 0) ++ lp->tx_bd_tail = TX_BD_NUM - 1; ++ cur_p = &lp->tx_bd_v[lp->tx_bd_tail]; ++ while (--ii >= 0) { ++ --frag; ++ dma_unmap_single(ndev->dev.parent, ++ be32_to_cpu(cur_p->phys), ++ skb_frag_size(frag), ++ DMA_TO_DEVICE); ++ if (--lp->tx_bd_tail < 0) ++ lp->tx_bd_tail = TX_BD_NUM - 1; ++ cur_p = &lp->tx_bd_v[lp->tx_bd_tail]; ++ } ++ dma_unmap_single(ndev->dev.parent, ++ be32_to_cpu(cur_p->phys), ++ skb_headlen(skb), DMA_TO_DEVICE); ++ dev_kfree_skb_any(skb); ++ ndev->stats.tx_dropped++; ++ return NETDEV_TX_OK; ++ } + cur_p->phys = cpu_to_be32(skb_dma_addr); + cur_p->len = cpu_to_be32(skb_frag_size(frag)); + cur_p->app0 = 0; +@@ -884,31 +926,56 @@ temac_start_xmit(struct sk_buff *skb, struct net_device *ndev) + return NETDEV_TX_OK; + } + ++static int ll_temac_recv_buffers_available(struct temac_local *lp) ++{ ++ int available; ++ ++ if (!lp->rx_skb[lp->rx_bd_ci]) ++ return 0; ++ available = 1 + lp->rx_bd_tail - lp->rx_bd_ci; ++ if (available <= 0) ++ available += RX_BD_NUM; ++ return available; ++} + + static void ll_temac_recv(struct net_device *ndev) + { + struct temac_local *lp = netdev_priv(ndev); +- struct sk_buff *skb, *new_skb; +- unsigned int bdstat; +- struct cdmac_bd *cur_p; +- dma_addr_t tail_p, skb_dma_addr; +- int length; + unsigned long flags; ++ int rx_bd; ++ bool update_tail = false; + + spin_lock_irqsave(&lp->rx_lock, flags); + +- tail_p = lp->rx_bd_p + sizeof(*lp->rx_bd_v) * lp->rx_bd_ci; +- cur_p = &lp->rx_bd_v[lp->rx_bd_ci]; +- +- bdstat = be32_to_cpu(cur_p->app0); +- while ((bdstat & STS_CTRL_APP0_CMPLT)) { ++ /* Process all received buffers, passing them on network ++ * stack. After this, the buffer descriptors will be in an ++ * un-allocated stage, where no skb is allocated for it, and ++ * they are therefore not available for TEMAC/DMA. ++ */ ++ do { ++ struct cdmac_bd *bd = &lp->rx_bd_v[lp->rx_bd_ci]; ++ struct sk_buff *skb = lp->rx_skb[lp->rx_bd_ci]; ++ unsigned int bdstat = be32_to_cpu(bd->app0); ++ int length; ++ ++ /* While this should not normally happen, we can end ++ * here when GFP_ATOMIC allocations fail, and we ++ * therefore have un-allocated buffers. ++ */ ++ if (!skb) ++ break; + +- skb = lp->rx_skb[lp->rx_bd_ci]; +- length = be32_to_cpu(cur_p->app4) & 0x3FFF; ++ /* Loop over all completed buffer descriptors */ ++ if (!(bdstat & STS_CTRL_APP0_CMPLT)) ++ break; + +- dma_unmap_single(ndev->dev.parent, be32_to_cpu(cur_p->phys), ++ dma_unmap_single(ndev->dev.parent, be32_to_cpu(bd->phys), + XTE_MAX_JUMBO_FRAME_SIZE, DMA_FROM_DEVICE); ++ /* The buffer is not valid for DMA anymore */ ++ bd->phys = 0; ++ bd->len = 0; + ++ length = be32_to_cpu(bd->app4) & 0x3FFF; + skb_put(skb, length); + skb->protocol = eth_type_trans(skb, ndev); + skb_checksum_none_assert(skb); +@@ -923,43 +990,102 @@ static void ll_temac_recv(struct net_device *ndev) + * (back) for proper IP checksum byte order + * (be16). + */ +- skb->csum = htons(be32_to_cpu(cur_p->app3) & 0xFFFF); ++ skb->csum = htons(be32_to_cpu(bd->app3) & 0xFFFF); + skb->ip_summed = CHECKSUM_COMPLETE; + } + + if (!skb_defer_rx_timestamp(skb)) + netif_rx(skb); ++ /* The skb buffer is now owned by network stack above */ ++ lp->rx_skb[lp->rx_bd_ci] = NULL; + + ndev->stats.rx_packets++; + ndev->stats.rx_bytes += length; + +- new_skb = netdev_alloc_skb_ip_align(ndev, +- XTE_MAX_JUMBO_FRAME_SIZE); +- if (!new_skb) { +- spin_unlock_irqrestore(&lp->rx_lock, flags); +- return; ++ rx_bd = lp->rx_bd_ci; ++ if (++lp->rx_bd_ci >= RX_BD_NUM) ++ lp->rx_bd_ci = 0; ++ } while (rx_bd != lp->rx_bd_tail); ++ ++ /* DMA operations will halt when the last buffer descriptor is ++ * processed (ie. the one pointed to by RX_TAILDESC_PTR). ++ * When that happens, no more interrupt events will be ++ * generated. No IRQ_COAL or IRQ_DLY, and not even an ++ * IRQ_ERR. To avoid stalling, we schedule a delayed work ++ * when there is a potential risk of that happening. The work ++ * will call this function, and thus re-schedule itself until ++ * enough buffers are available again. ++ */ ++ if (ll_temac_recv_buffers_available(lp) < lp->coalesce_count_rx) ++ schedule_delayed_work(&lp->restart_work, HZ / 1000); ++ ++ /* Allocate new buffers for those buffer descriptors that were ++ * passed to network stack. Note that GFP_ATOMIC allocations ++ * can fail (e.g. when a larger burst of GFP_ATOMIC ++ * allocations occurs), so while we try to allocate all ++ * buffers in the same interrupt where they were processed, we ++ * continue with what we could get in case of allocation ++ * failure. Allocation of remaining buffers will be retried ++ * in following calls. ++ */ ++ while (1) { ++ struct sk_buff *skb; ++ struct cdmac_bd *bd; ++ dma_addr_t skb_dma_addr; ++ ++ rx_bd = lp->rx_bd_tail + 1; ++ if (rx_bd >= RX_BD_NUM) ++ rx_bd = 0; ++ bd = &lp->rx_bd_v[rx_bd]; ++ ++ if (bd->phys) ++ break; /* All skb's allocated */ ++ ++ skb = netdev_alloc_skb_ip_align(ndev, XTE_MAX_JUMBO_FRAME_SIZE); ++ if (!skb) { ++ dev_warn(&ndev->dev, "skb alloc failed\n"); ++ break; + } + +- cur_p->app0 = cpu_to_be32(STS_CTRL_APP0_IRQONEND); +- skb_dma_addr = dma_map_single(ndev->dev.parent, new_skb->data, ++ skb_dma_addr = dma_map_single(ndev->dev.parent, skb->data, + XTE_MAX_JUMBO_FRAME_SIZE, + DMA_FROM_DEVICE); +- cur_p->phys = cpu_to_be32(skb_dma_addr); +- cur_p->len = cpu_to_be32(XTE_MAX_JUMBO_FRAME_SIZE); +- lp->rx_skb[lp->rx_bd_ci] = new_skb; ++ if (WARN_ON_ONCE(dma_mapping_error(ndev->dev.parent, ++ skb_dma_addr))) { ++ dev_kfree_skb_any(skb); ++ break; ++ } + +- lp->rx_bd_ci++; +- if (lp->rx_bd_ci >= RX_BD_NUM) +- lp->rx_bd_ci = 0; ++ bd->phys = cpu_to_be32(skb_dma_addr); ++ bd->len = cpu_to_be32(XTE_MAX_JUMBO_FRAME_SIZE); ++ bd->app0 = cpu_to_be32(STS_CTRL_APP0_IRQONEND); ++ lp->rx_skb[rx_bd] = skb; + +- cur_p = &lp->rx_bd_v[lp->rx_bd_ci]; +- bdstat = be32_to_cpu(cur_p->app0); ++ lp->rx_bd_tail = rx_bd; ++ update_tail = true; ++ } ++ ++ /* Move tail pointer when buffers have been allocated */ ++ if (update_tail) { ++ lp->dma_out(lp, RX_TAILDESC_PTR, ++ lp->rx_bd_p + sizeof(*lp->rx_bd_v) * lp->rx_bd_tail); + } +- lp->dma_out(lp, RX_TAILDESC_PTR, tail_p); + + spin_unlock_irqrestore(&lp->rx_lock, flags); + } + ++/* Function scheduled to ensure a restart in case of DMA halt ++ * condition caused by running out of buffer descriptors. ++ */ ++static void ll_temac_restart_work_func(struct work_struct *work) ++{ ++ struct temac_local *lp = container_of(work, struct temac_local, ++ restart_work.work); ++ struct net_device *ndev = lp->ndev; ++ ++ ll_temac_recv(ndev); ++} ++ + static irqreturn_t ll_temac_tx_irq(int irq, void *_ndev) + { + struct net_device *ndev = _ndev; +@@ -1052,6 +1178,8 @@ static int temac_stop(struct net_device *ndev) + + dev_dbg(&ndev->dev, "temac_close()\n"); + ++ cancel_delayed_work_sync(&lp->restart_work); ++ + free_irq(lp->tx_irq, ndev); + free_irq(lp->rx_irq, ndev); + +@@ -1184,6 +1312,7 @@ static int temac_probe(struct platform_device *pdev) + lp->dev = &pdev->dev; + lp->options = XTE_OPTION_DEFAULTS; + spin_lock_init(&lp->rx_lock); ++ INIT_DELAYED_WORK(&lp->restart_work, ll_temac_restart_work_func); + + /* Setup mutex for synchronization of indirect register access */ + if (pdata) { +@@ -1290,6 +1419,7 @@ static int temac_probe(struct platform_device *pdev) + */ + lp->tx_chnl_ctrl = 0x10220000; + lp->rx_chnl_ctrl = 0xff070000; ++ lp->coalesce_count_rx = 0x07; + + /* Finished with the DMA node; drop the reference */ + of_node_put(dma_np); +@@ -1321,11 +1451,14 @@ static int temac_probe(struct platform_device *pdev) + (pdata->tx_irq_count << 16); + else + lp->tx_chnl_ctrl = 0x10220000; +- if (pdata->rx_irq_timeout || pdata->rx_irq_count) ++ if (pdata->rx_irq_timeout || pdata->rx_irq_count) { + lp->rx_chnl_ctrl = (pdata->rx_irq_timeout << 24) | + (pdata->rx_irq_count << 16); +- else ++ lp->coalesce_count_rx = pdata->rx_irq_count; ++ } else { + lp->rx_chnl_ctrl = 0xff070000; ++ lp->coalesce_count_rx = 0x07; ++ } + } + + /* Error handle returned DMA RX and TX interrupts */ +diff --git a/drivers/net/phy/mscc.c b/drivers/net/phy/mscc.c +index 7ada1fd9ca71..2339b9381d21 100644 +--- a/drivers/net/phy/mscc.c ++++ b/drivers/net/phy/mscc.c +@@ -302,11 +302,11 @@ enum rgmii_rx_clock_delay { + BIT(VSC8531_FORCE_LED_OFF) | \ + BIT(VSC8531_FORCE_LED_ON)) + +-#define MSCC_VSC8584_REVB_INT8051_FW "mscc_vsc8584_revb_int8051_fb48.bin" ++#define MSCC_VSC8584_REVB_INT8051_FW "microchip/mscc_vsc8584_revb_int8051_fb48.bin" + #define MSCC_VSC8584_REVB_INT8051_FW_START_ADDR 0xe800 + #define MSCC_VSC8584_REVB_INT8051_FW_CRC 0xfb48 + +-#define MSCC_VSC8574_REVB_INT8051_FW "mscc_vsc8574_revb_int8051_29e8.bin" ++#define MSCC_VSC8574_REVB_INT8051_FW "microchip/mscc_vsc8574_revb_int8051_29e8.bin" + #define MSCC_VSC8574_REVB_INT8051_FW_START_ADDR 0x4000 + #define MSCC_VSC8574_REVB_INT8051_FW_CRC 0x29e8 + +diff --git a/drivers/net/slip/slip.c b/drivers/net/slip/slip.c +index 61d7e0d1d77d..8e56a41dd758 100644 +--- a/drivers/net/slip/slip.c ++++ b/drivers/net/slip/slip.c +@@ -863,7 +863,10 @@ err_free_chan: + tty->disc_data = NULL; + clear_bit(SLF_INUSE, &sl->flags); + sl_free_netdev(sl->dev); ++ /* do not call free_netdev before rtnl_unlock */ ++ rtnl_unlock(); + free_netdev(sl->dev); ++ return err; + + err_exit: + rtnl_unlock(); +diff --git a/drivers/net/usb/qmi_wwan.c b/drivers/net/usb/qmi_wwan.c +index 3b7a3b8a5e06..5754bb6ca0ee 100644 +--- a/drivers/net/usb/qmi_wwan.c ++++ b/drivers/net/usb/qmi_wwan.c +@@ -337,6 +337,9 @@ static void qmi_wwan_netdev_setup(struct net_device *net) + netdev_dbg(net, "mode: raw IP\n"); + } else if (!net->header_ops) { /* don't bother if already set */ + ether_setup(net); ++ /* Restoring min/max mtu values set originally by usbnet */ ++ net->min_mtu = 0; ++ net->max_mtu = ETH_MAX_MTU; + clear_bit(EVENT_NO_IP_ALIGN, &dev->flags); + netdev_dbg(net, "mode: Ethernet\n"); + } +diff --git a/drivers/scsi/libfc/fc_disc.c b/drivers/scsi/libfc/fc_disc.c +index 9c5f7c9178c6..2b865c6423e2 100644 +--- a/drivers/scsi/libfc/fc_disc.c ++++ b/drivers/scsi/libfc/fc_disc.c +@@ -628,6 +628,8 @@ redisc: + } + out: + kref_put(&rdata->kref, fc_rport_destroy); ++ if (!IS_ERR(fp)) ++ fc_frame_free(fp); + } + + /** +diff --git a/drivers/watchdog/wdat_wdt.c b/drivers/watchdog/wdat_wdt.c +index 1ce39de917f0..88c5e6361aa0 100644 +--- a/drivers/watchdog/wdat_wdt.c ++++ b/drivers/watchdog/wdat_wdt.c +@@ -54,6 +54,13 @@ module_param(nowayout, bool, 0); + MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started (default=" + __MODULE_STRING(WATCHDOG_NOWAYOUT) ")"); + ++#define WDAT_DEFAULT_TIMEOUT 30 ++ ++static int timeout = WDAT_DEFAULT_TIMEOUT; ++module_param(timeout, int, 0); ++MODULE_PARM_DESC(timeout, "Watchdog timeout in seconds (default=" ++ __MODULE_STRING(WDAT_DEFAULT_TIMEOUT) ")"); ++ + static int wdat_wdt_read(struct wdat_wdt *wdat, + const struct wdat_instruction *instr, u32 *value) + { +@@ -438,6 +445,22 @@ static int wdat_wdt_probe(struct platform_device *pdev) + + platform_set_drvdata(pdev, wdat); + ++ /* ++ * Set initial timeout so that userspace has time to configure the ++ * watchdog properly after it has opened the device. In some cases ++ * the BIOS default is too short and causes immediate reboot. ++ */ ++ if (timeout * 1000 < wdat->wdd.min_hw_heartbeat_ms || ++ timeout * 1000 > wdat->wdd.max_hw_heartbeat_ms) { ++ dev_warn(dev, "Invalid timeout %d given, using %d\n", ++ timeout, WDAT_DEFAULT_TIMEOUT); ++ timeout = WDAT_DEFAULT_TIMEOUT; ++ } ++ ++ ret = wdat_wdt_set_timeout(&wdat->wdd, timeout); ++ if (ret) ++ return ret; ++ + watchdog_set_nowayout(&wdat->wdd, nowayout); + return devm_watchdog_register_device(dev, &wdat->wdd); + } +diff --git a/fs/jbd2/transaction.c b/fs/jbd2/transaction.c +index b17f05ae6011..de992a70ddfe 100644 +--- a/fs/jbd2/transaction.c ++++ b/fs/jbd2/transaction.c +@@ -1079,8 +1079,8 @@ static bool jbd2_write_access_granted(handle_t *handle, struct buffer_head *bh, + /* For undo access buffer must have data copied */ + if (undo && !jh->b_committed_data) + goto out; +- if (jh->b_transaction != handle->h_transaction && +- jh->b_next_transaction != handle->h_transaction) ++ if (READ_ONCE(jh->b_transaction) != handle->h_transaction && ++ READ_ONCE(jh->b_next_transaction) != handle->h_transaction) + goto out; + /* + * There are two reasons for the barrier here: +@@ -2535,8 +2535,8 @@ void __jbd2_journal_refile_buffer(struct journal_head *jh) + * our jh reference and thus __jbd2_journal_file_buffer() must not + * take a new one. + */ +- jh->b_transaction = jh->b_next_transaction; +- jh->b_next_transaction = NULL; ++ WRITE_ONCE(jh->b_transaction, jh->b_next_transaction); ++ WRITE_ONCE(jh->b_next_transaction, NULL); + if (buffer_freed(bh)) + jlist = BJ_Forget; + else if (jh->b_modified) +diff --git a/kernel/signal.c b/kernel/signal.c +index bcd46f547db3..eea748174ade 100644 +--- a/kernel/signal.c ++++ b/kernel/signal.c +@@ -413,27 +413,32 @@ __sigqueue_alloc(int sig, struct task_struct *t, gfp_t flags, int override_rlimi + { + struct sigqueue *q = NULL; + struct user_struct *user; ++ int sigpending; + + /* + * Protect access to @t credentials. This can go away when all + * callers hold rcu read lock. ++ * ++ * NOTE! A pending signal will hold on to the user refcount, ++ * and we get/put the refcount only when the sigpending count ++ * changes from/to zero. + */ + rcu_read_lock(); +- user = get_uid(__task_cred(t)->user); +- atomic_inc(&user->sigpending); ++ user = __task_cred(t)->user; ++ sigpending = atomic_inc_return(&user->sigpending); ++ if (sigpending == 1) ++ get_uid(user); + rcu_read_unlock(); + +- if (override_rlimit || +- atomic_read(&user->sigpending) <= +- task_rlimit(t, RLIMIT_SIGPENDING)) { ++ if (override_rlimit || likely(sigpending <= task_rlimit(t, RLIMIT_SIGPENDING))) { + q = kmem_cache_alloc(sigqueue_cachep, flags); + } else { + print_dropped_signal(sig); + } + + if (unlikely(q == NULL)) { +- atomic_dec(&user->sigpending); +- free_uid(user); ++ if (atomic_dec_and_test(&user->sigpending)) ++ free_uid(user); + } else { + INIT_LIST_HEAD(&q->list); + q->flags = 0; +@@ -447,8 +452,8 @@ static void __sigqueue_free(struct sigqueue *q) + { + if (q->flags & SIGQUEUE_PREALLOC) + return; +- atomic_dec(&q->user->sigpending); +- free_uid(q->user); ++ if (atomic_dec_and_test(&q->user->sigpending)) ++ free_uid(q->user); + kmem_cache_free(sigqueue_cachep, q); + } + +diff --git a/kernel/trace/trace_events_hist.c b/kernel/trace/trace_events_hist.c +index a31be3fce3e8..6495800fb92a 100644 +--- a/kernel/trace/trace_events_hist.c ++++ b/kernel/trace/trace_events_hist.c +@@ -811,6 +811,29 @@ static const char *synth_field_fmt(char *type) + return fmt; + } + ++static void print_synth_event_num_val(struct trace_seq *s, ++ char *print_fmt, char *name, ++ int size, u64 val, char *space) ++{ ++ switch (size) { ++ case 1: ++ trace_seq_printf(s, print_fmt, name, (u8)val, space); ++ break; ++ ++ case 2: ++ trace_seq_printf(s, print_fmt, name, (u16)val, space); ++ break; ++ ++ case 4: ++ trace_seq_printf(s, print_fmt, name, (u32)val, space); ++ break; ++ ++ default: ++ trace_seq_printf(s, print_fmt, name, val, space); ++ break; ++ } ++} ++ + static enum print_line_t print_synth_event(struct trace_iterator *iter, + int flags, + struct trace_event *event) +@@ -849,10 +872,13 @@ static enum print_line_t print_synth_event(struct trace_iterator *iter, + } else { + struct trace_print_flags __flags[] = { + __def_gfpflag_names, {-1, NULL} }; ++ char *space = (i == se->n_fields - 1 ? "" : " "); + +- trace_seq_printf(s, print_fmt, se->fields[i]->name, +- entry->fields[n_u64], +- i == se->n_fields - 1 ? "" : " "); ++ print_synth_event_num_val(s, print_fmt, ++ se->fields[i]->name, ++ se->fields[i]->size, ++ entry->fields[n_u64], ++ space); + + if (strcmp(se->fields[i]->type, "gfp_t") == 0) { + trace_seq_puts(s, " ("); +diff --git a/mm/slub.c b/mm/slub.c +index 20d72cb20515..3ca4a223f44c 100644 +--- a/mm/slub.c ++++ b/mm/slub.c +@@ -3154,6 +3154,15 @@ int kmem_cache_alloc_bulk(struct kmem_cache *s, gfp_t flags, size_t size, + void *object = c->freelist; + + if (unlikely(!object)) { ++ /* ++ * We may have removed an object from c->freelist using ++ * the fastpath in the previous iteration; in that case, ++ * c->tid has not been bumped yet. ++ * Since ___slab_alloc() may reenable interrupts while ++ * allocating memory, we should bump c->tid now. ++ */ ++ c->tid = next_tid(c->tid); ++ + /* + * Invoking slow path likely have side-effect + * of re-populating per CPU c->freelist +diff --git a/net/ipv4/cipso_ipv4.c b/net/ipv4/cipso_ipv4.c +index 376882215919..0bd10a1f477f 100644 +--- a/net/ipv4/cipso_ipv4.c ++++ b/net/ipv4/cipso_ipv4.c +@@ -1724,6 +1724,7 @@ void cipso_v4_error(struct sk_buff *skb, int error, u32 gateway) + { + unsigned char optbuf[sizeof(struct ip_options) + 40]; + struct ip_options *opt = (struct ip_options *)optbuf; ++ int res; + + if (ip_hdr(skb)->protocol == IPPROTO_ICMP || error != -EACCES) + return; +@@ -1735,7 +1736,11 @@ void cipso_v4_error(struct sk_buff *skb, int error, u32 gateway) + + memset(opt, 0, sizeof(struct ip_options)); + opt->optlen = ip_hdr(skb)->ihl*4 - sizeof(struct iphdr); +- if (__ip_options_compile(dev_net(skb->dev), opt, skb, NULL)) ++ rcu_read_lock(); ++ res = __ip_options_compile(dev_net(skb->dev), opt, skb, NULL); ++ rcu_read_unlock(); ++ ++ if (res) + return; + + if (gateway) +diff --git a/net/mac80211/rx.c b/net/mac80211/rx.c +index 0e05ff037672..0ba98ad9bc85 100644 +--- a/net/mac80211/rx.c ++++ b/net/mac80211/rx.c +@@ -4114,7 +4114,7 @@ void __ieee80211_check_fast_rx_iface(struct ieee80211_sub_if_data *sdata) + + lockdep_assert_held(&local->sta_mtx); + +- list_for_each_entry_rcu(sta, &local->sta_list, list) { ++ list_for_each_entry(sta, &local->sta_list, list) { + if (sdata != sta->sdata && + (!sta->sdata->bss || sta->sdata->bss != sdata->bss)) + continue; +diff --git a/net/netfilter/xt_hashlimit.c b/net/netfilter/xt_hashlimit.c +index 1b68a131083c..8c835ad63729 100644 +--- a/net/netfilter/xt_hashlimit.c ++++ b/net/netfilter/xt_hashlimit.c +@@ -358,21 +358,7 @@ static int htable_create(struct net *net, struct hashlimit_cfg3 *cfg, + return 0; + } + +-static bool select_all(const struct xt_hashlimit_htable *ht, +- const struct dsthash_ent *he) +-{ +- return true; +-} +- +-static bool select_gc(const struct xt_hashlimit_htable *ht, +- const struct dsthash_ent *he) +-{ +- return time_after_eq(jiffies, he->expires); +-} +- +-static void htable_selective_cleanup(struct xt_hashlimit_htable *ht, +- bool (*select)(const struct xt_hashlimit_htable *ht, +- const struct dsthash_ent *he)) ++static void htable_selective_cleanup(struct xt_hashlimit_htable *ht, bool select_all) + { + unsigned int i; + +@@ -382,7 +368,7 @@ static void htable_selective_cleanup(struct xt_hashlimit_htable *ht, + + spin_lock_bh(&ht->lock); + hlist_for_each_entry_safe(dh, n, &ht->hash[i], node) { +- if ((*select)(ht, dh)) ++ if (time_after_eq(jiffies, dh->expires) || select_all) + dsthash_free(ht, dh); + } + spin_unlock_bh(&ht->lock); +@@ -396,7 +382,7 @@ static void htable_gc(struct work_struct *work) + + ht = container_of(work, struct xt_hashlimit_htable, gc_work.work); + +- htable_selective_cleanup(ht, select_gc); ++ htable_selective_cleanup(ht, false); + + queue_delayed_work(system_power_efficient_wq, + &ht->gc_work, msecs_to_jiffies(ht->cfg.gc_interval)); +@@ -416,15 +402,6 @@ static void htable_remove_proc_entry(struct xt_hashlimit_htable *hinfo) + remove_proc_entry(hinfo->name, parent); + } + +-static void htable_destroy(struct xt_hashlimit_htable *hinfo) +-{ +- cancel_delayed_work_sync(&hinfo->gc_work); +- htable_remove_proc_entry(hinfo); +- htable_selective_cleanup(hinfo, select_all); +- kfree(hinfo->name); +- vfree(hinfo); +-} +- + static struct xt_hashlimit_htable *htable_find_get(struct net *net, + const char *name, + u_int8_t family) +@@ -446,8 +423,13 @@ static void htable_put(struct xt_hashlimit_htable *hinfo) + { + if (refcount_dec_and_mutex_lock(&hinfo->use, &hashlimit_mutex)) { + hlist_del(&hinfo->node); ++ htable_remove_proc_entry(hinfo); + mutex_unlock(&hashlimit_mutex); +- htable_destroy(hinfo); ++ ++ cancel_delayed_work_sync(&hinfo->gc_work); ++ htable_selective_cleanup(hinfo, true); ++ kfree(hinfo->name); ++ vfree(hinfo); + } + } + +diff --git a/net/qrtr/qrtr.c b/net/qrtr/qrtr.c +index 88f98f27ad88..3d24d45be5f4 100644 +--- a/net/qrtr/qrtr.c ++++ b/net/qrtr/qrtr.c +@@ -196,7 +196,7 @@ static int qrtr_node_enqueue(struct qrtr_node *node, struct sk_buff *skb, + hdr->size = cpu_to_le32(len); + hdr->confirm_rx = 0; + +- skb_put_padto(skb, ALIGN(len, 4)); ++ skb_put_padto(skb, ALIGN(len, 4) + sizeof(*hdr)); + + mutex_lock(&node->ep_lock); + if (node->ep) +diff --git a/net/wireless/reg.c b/net/wireless/reg.c +index fff9a74891fc..1a8218f1bbe0 100644 +--- a/net/wireless/reg.c ++++ b/net/wireless/reg.c +@@ -2276,7 +2276,7 @@ static void handle_channel_custom(struct wiphy *wiphy, + break; + } + +- if (IS_ERR(reg_rule)) { ++ if (IS_ERR_OR_NULL(reg_rule)) { + pr_debug("Disabling freq %d MHz as custom regd has no rule that fits it\n", + chan->center_freq); + if (wiphy->regulatory_flags & REGULATORY_WIPHY_SELF_MANAGED) { +diff --git a/tools/testing/selftests/rseq/Makefile b/tools/testing/selftests/rseq/Makefile +index f1053630bb6f..2af9d39a9716 100644 +--- a/tools/testing/selftests/rseq/Makefile ++++ b/tools/testing/selftests/rseq/Makefile +@@ -4,7 +4,7 @@ ifneq ($(shell $(CC) --version 2>&1 | head -n 1 | grep clang),) + CLANG_FLAGS += -no-integrated-as + endif + +-CFLAGS += -O2 -Wall -g -I./ -I../../../../usr/include/ -L./ -Wl,-rpath=./ \ ++CFLAGS += -O2 -Wall -g -I./ -I../../../../usr/include/ -L$(OUTPUT) -Wl,-rpath=./ \ + $(CLANG_FLAGS) + LDLIBS += -lpthread +
