diff --git a/examples/rt-for-vmware.yml b/examples/rt-for-vmware.yml index 66f8beae9..821e0dd69 100644 --- a/examples/rt-for-vmware.yml +++ b/examples/rt-for-vmware.yml @@ -1,5 +1,5 @@ kernel: - image: linuxkit/kernel:4.14.87-rt + image: linuxkit/kernel:4.19.25-rt cmdline: "console=tty0" init: - linuxkit/init:005807f5c6a74e23f485a6d1657818bdccb70cd0 diff --git a/kernel/Makefile b/kernel/Makefile index 004a0b69b..fbad2680d 100644 --- a/kernel/Makefile +++ b/kernel/Makefile @@ -263,14 +263,14 @@ $(eval $(call kernel,4.20.13,4.20.x,$(EXTRA),$(DEBUG))) $(eval $(call kernel,4.19.26,4.19.x,$(EXTRA),$(DEBUG))) $(eval $(call kernel,4.14.104,4.14.x,$(EXTRA),$(DEBUG))) $(eval $(call kernel,4.14.104,4.14.x,,-dbg)) -$(eval $(call kernel,4.14.87,4.14.x,-rt,)) +$(eval $(call kernel,4.19.25,4.19.x,-rt,)) $(eval $(call kernel,4.9.161,4.9.x,$(EXTRA),$(DEBUG))) else ifeq ($(ARCH),aarch64) $(eval $(call kernel,4.20.13,4.20.x,$(EXTRA),$(DEBUG))) $(eval $(call kernel,4.19.26,4.19.x,$(EXTRA),$(DEBUG))) $(eval $(call kernel,4.14.104,4.14.x,$(EXTRA),$(DEBUG))) -$(eval $(call kernel,4.14.87,4.14.x,-rt,)) +$(eval $(call kernel,4.19.25,4.19.x,-rt,)) else ifeq ($(ARCH),s390x) $(eval $(call kernel,4.20.13,4.20.x,$(EXTRA),$(DEBUG))) diff --git a/kernel/config-4.14.x-aarch64-rt b/kernel/config-4.19.x-aarch64-rt similarity index 100% rename from kernel/config-4.14.x-aarch64-rt rename to kernel/config-4.19.x-aarch64-rt diff --git a/kernel/config-4.14.x-x86_64-rt b/kernel/config-4.19.x-x86_64-rt similarity index 100% rename from kernel/config-4.14.x-x86_64-rt rename to kernel/config-4.19.x-x86_64-rt diff --git a/kernel/patches-4.14.x-rt/0001-rtmutex-Make-rt_mutex_futex_unlock-safe-for-irq-off-.patch b/kernel/patches-4.14.x-rt/0001-rtmutex-Make-rt_mutex_futex_unlock-safe-for-irq-off-.patch deleted file mode 100644 index e826aea5f..000000000 --- a/kernel/patches-4.14.x-rt/0001-rtmutex-Make-rt_mutex_futex_unlock-safe-for-irq-off-.patch +++ /dev/null @@ -1,127 +0,0 @@ -From cf77772195405adc1a0cd2bc304ed810e6420c73 Mon Sep 17 00:00:00 2001 -From: Boqun Feng -Date: Fri, 9 Mar 2018 14:56:28 +0800 -Subject: [PATCH 001/450] rtmutex: Make rt_mutex_futex_unlock() safe for - irq-off callsites - -Upstream commit 6b0ef92fee2a3189eba6d6b827b247cb4f6da7e9 - -When running rcutorture with TREE03 config, CONFIG_PROVE_LOCKING=y, and -kernel cmdline argument "rcutorture.gp_exp=1", lockdep reports a -HARDIRQ-safe->HARDIRQ-unsafe deadlock: - - ================================ - WARNING: inconsistent lock state - 4.16.0-rc4+ #1 Not tainted - -------------------------------- - inconsistent {IN-HARDIRQ-W} -> {HARDIRQ-ON-W} usage. - takes: - __schedule+0xbe/0xaf0 - {IN-HARDIRQ-W} state was registered at: - _raw_spin_lock+0x2a/0x40 - scheduler_tick+0x47/0xf0 -... - other info that might help us debug this: - Possible unsafe locking scenario: - CPU0 - ---- - lock(&rq->lock); - - lock(&rq->lock); - *** DEADLOCK *** - 1 lock held by rcu_torture_rea/724: - rcu_torture_read_lock+0x0/0x70 - stack backtrace: - CPU: 2 PID: 724 Comm: rcu_torture_rea Not tainted 4.16.0-rc4+ #1 - Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS 1.11.0-20171110_100015-anatol 04/01/2014 - Call Trace: - lock_acquire+0x90/0x200 - ? __schedule+0xbe/0xaf0 - _raw_spin_lock+0x2a/0x40 - ? __schedule+0xbe/0xaf0 - __schedule+0xbe/0xaf0 - preempt_schedule_irq+0x2f/0x60 - retint_kernel+0x1b/0x2d - RIP: 0010:rcu_read_unlock_special+0x0/0x680 - ? rcu_torture_read_unlock+0x60/0x60 - __rcu_read_unlock+0x64/0x70 - rcu_torture_read_unlock+0x17/0x60 - rcu_torture_reader+0x275/0x450 - ? rcutorture_booster_init+0x110/0x110 - ? rcu_torture_stall+0x230/0x230 - ? kthread+0x10e/0x130 - kthread+0x10e/0x130 - ? kthread_create_worker_on_cpu+0x70/0x70 - ? call_usermodehelper_exec_async+0x11a/0x150 - ret_from_fork+0x3a/0x50 - -This happens with the following even sequence: - - preempt_schedule_irq(); - local_irq_enable(); - __schedule(): - local_irq_disable(); // irq off - ... - rcu_note_context_switch(): - rcu_note_preempt_context_switch(): - rcu_read_unlock_special(): - local_irq_save(flags); - ... - raw_spin_unlock_irqrestore(...,flags); // irq remains off - rt_mutex_futex_unlock(): - raw_spin_lock_irq(); - ... - raw_spin_unlock_irq(); // accidentally set irq on - - - rq_lock(): - raw_spin_lock(); // acquiring rq->lock with irq on - -which means rq->lock becomes a HARDIRQ-unsafe lock, which can cause -deadlocks in scheduler code. - -This problem was introduced by commit 02a7c234e540 ("rcu: Suppress -lockdep false-positive ->boost_mtx complaints"). That brought the user -of rt_mutex_futex_unlock() with irq off. - -To fix this, replace the *lock_irq() in rt_mutex_futex_unlock() with -*lock_irq{save,restore}() to make it safe to call rt_mutex_futex_unlock() -with irq off. - -Fixes: 02a7c234e540 ("rcu: Suppress lockdep false-positive ->boost_mtx complaints") -Signed-off-by: Boqun Feng -Signed-off-by: Thomas Gleixner -Cc: Peter Zijlstra -Cc: Lai Jiangshan -Cc: Steven Rostedt -Cc: Josh Triplett -Cc: Mathieu Desnoyers -Cc: "Paul E . McKenney" -Link: https://lkml.kernel.org/r/20180309065630.8283-1-boqun.feng@gmail.com -Signed-off-by: Sebastian Andrzej Siewior ---- - kernel/locking/rtmutex.c | 5 +++-- - 1 file changed, 3 insertions(+), 2 deletions(-) - -diff --git a/kernel/locking/rtmutex.c b/kernel/locking/rtmutex.c -index 4ad35718f123..456750bf9c95 100644 ---- a/kernel/locking/rtmutex.c -+++ b/kernel/locking/rtmutex.c -@@ -1637,11 +1637,12 @@ bool __sched __rt_mutex_futex_unlock(struct rt_mutex *lock, - void __sched rt_mutex_futex_unlock(struct rt_mutex *lock) - { - DEFINE_WAKE_Q(wake_q); -+ unsigned long flags; - bool postunlock; - -- raw_spin_lock_irq(&lock->wait_lock); -+ raw_spin_lock_irqsave(&lock->wait_lock, flags); - postunlock = __rt_mutex_futex_unlock(lock, &wake_q); -- raw_spin_unlock_irq(&lock->wait_lock); -+ raw_spin_unlock_irqrestore(&lock->wait_lock, flags); - - if (postunlock) - rt_mutex_postunlock(&wake_q); --- -2.19.2 - diff --git a/kernel/patches-4.14.x-rt/0002-rcu-Suppress-lockdep-false-positive-boost_mtx-compla.patch b/kernel/patches-4.14.x-rt/0002-rcu-Suppress-lockdep-false-positive-boost_mtx-compla.patch deleted file mode 100644 index c51bcde27..000000000 --- a/kernel/patches-4.14.x-rt/0002-rcu-Suppress-lockdep-false-positive-boost_mtx-compla.patch +++ /dev/null @@ -1,56 +0,0 @@ -From 80b97a7398475268f38b59179b7798da7576593b Mon Sep 17 00:00:00 2001 -From: "Paul E. McKenney" -Date: Tue, 19 Sep 2017 15:36:42 -0700 -Subject: [PATCH 002/450] rcu: Suppress lockdep false-positive ->boost_mtx - complaints - -Upstream commit bcda31a2659497df39d6bedfbdf17498b4f4ac89 - -RCU priority boosting uses rt_mutex_init_proxy_locked() to initialize an -rt_mutex structure in locked state held by some other task. When that -other task releases it, lockdep complains (quite accurately, but a bit -uselessly) that the other task never acquired it. This complaint can -suppress other, more helpful, lockdep complaints, and in any case it is -a false positive. - -This commit therefore switches from rt_mutex_unlock() to -rt_mutex_futex_unlock(), thereby avoiding the lockdep annotations. -Of course, if lockdep ever learns about rt_mutex_init_proxy_locked(), -addtional adjustments will be required. - -Suggested-by: Peter Zijlstra -Signed-off-by: Paul E. McKenney -Signed-off-by: Sebastian Andrzej Siewior ---- - kernel/rcu/tree_plugin.h | 5 ++--- - 1 file changed, 2 insertions(+), 3 deletions(-) - -diff --git a/kernel/rcu/tree_plugin.h b/kernel/rcu/tree_plugin.h -index 8b3102d22823..181e2487c8b8 100644 ---- a/kernel/rcu/tree_plugin.h -+++ b/kernel/rcu/tree_plugin.h -@@ -31,11 +31,10 @@ - #include - #include - #include "../time/tick-internal.h" -+#include "../locking/rtmutex_common.h" - - #ifdef CONFIG_RCU_BOOST - --#include "../locking/rtmutex_common.h" -- - /* - * Control variables for per-CPU and per-rcu_node kthreads. These - * handle all flavors of RCU. -@@ -530,7 +529,7 @@ void rcu_read_unlock_special(struct task_struct *t) - - /* Unboost if we were boosted. */ - if (IS_ENABLED(CONFIG_RCU_BOOST) && drop_boost_mutex) -- rt_mutex_unlock(&rnp->boost_mtx); -+ rt_mutex_futex_unlock(&rnp->boost_mtx); - - /* - * If this was the last task on the expedited lists, --- -2.19.2 - diff --git a/kernel/patches-4.14.x-rt/0003-brd-remove-unused-brd_mutex.patch b/kernel/patches-4.14.x-rt/0003-brd-remove-unused-brd_mutex.patch deleted file mode 100644 index 6bddcad08..000000000 --- a/kernel/patches-4.14.x-rt/0003-brd-remove-unused-brd_mutex.patch +++ /dev/null @@ -1,32 +0,0 @@ -From 88e1236f4d0412babbf59bdf44516d4d2326d093 Mon Sep 17 00:00:00 2001 -From: Mikulas Patocka -Date: Fri, 10 Nov 2017 12:29:34 -0500 -Subject: [PATCH 003/450] brd: remove unused brd_mutex - -Upstream commit 15f7b41f70ddcca3b555bd0fdc7c8da7466b517e - -Remove unused mutex brd_mutex. It is unused since the commit ff26956875c2 -("brd: remove support for BLKFLSBUF"). - -Signed-off-by: Mikulas Patocka -Signed-off-by: Jens Axboe -Signed-off-by: Sebastian Andrzej Siewior ---- - drivers/block/brd.c | 1 - - 1 file changed, 1 deletion(-) - -diff --git a/drivers/block/brd.c b/drivers/block/brd.c -index 2d7178f7754e..c1cf87718c2e 100644 ---- a/drivers/block/brd.c -+++ b/drivers/block/brd.c -@@ -60,7 +60,6 @@ struct brd_device { - /* - * Look up and return a brd's page for a given sector. - */ --static DEFINE_MUTEX(brd_mutex); - static struct page *brd_lookup_page(struct brd_device *brd, sector_t sector) - { - pgoff_t idx; --- -2.19.2 - diff --git a/kernel/patches-4.14.x-rt/0004-KVM-arm-arm64-Remove-redundant-preemptible-checks.patch b/kernel/patches-4.14.x-rt/0004-KVM-arm-arm64-Remove-redundant-preemptible-checks.patch deleted file mode 100644 index 0e54658b0..000000000 --- a/kernel/patches-4.14.x-rt/0004-KVM-arm-arm64-Remove-redundant-preemptible-checks.patch +++ /dev/null @@ -1,44 +0,0 @@ -From caadf195c1da52ea6db6e657346eeac26afb68f3 Mon Sep 17 00:00:00 2001 -From: Christoffer Dall -Date: Fri, 8 Sep 2017 07:07:13 -0700 -Subject: [PATCH 004/450] KVM: arm/arm64: Remove redundant preemptible checks - -Upstream commit 5a24575032971c5a9a4580417a791c427ebdb8e5 - -The __this_cpu_read() and __this_cpu_write() functions already implement -checks for the required preemption levels when using -CONFIG_DEBUG_PREEMPT which gives you nice error messages and such. -Therefore there is no need to explicitly check this using a BUG_ON() in -the code (which we don't do for other uses of per cpu variables either). - -Acked-by: Marc Zyngier -Reviewed-by: Andre Przywara -Signed-off-by: Christoffer Dall -Signed-off-by: Sebastian Andrzej Siewior ---- - virt/kvm/arm/arm.c | 2 -- - 1 file changed, 2 deletions(-) - -diff --git a/virt/kvm/arm/arm.c b/virt/kvm/arm/arm.c -index ed42b8cf6f5b..045aa39b14c1 100644 ---- a/virt/kvm/arm/arm.c -+++ b/virt/kvm/arm/arm.c -@@ -69,7 +69,6 @@ static DEFINE_PER_CPU(unsigned char, kvm_arm_hardware_enabled); - - static void kvm_arm_set_running_vcpu(struct kvm_vcpu *vcpu) - { -- BUG_ON(preemptible()); - __this_cpu_write(kvm_arm_running_vcpu, vcpu); - } - -@@ -79,7 +78,6 @@ static void kvm_arm_set_running_vcpu(struct kvm_vcpu *vcpu) - */ - struct kvm_vcpu *kvm_arm_get_running_vcpu(void) - { -- BUG_ON(preemptible()); - return __this_cpu_read(kvm_arm_running_vcpu); - } - --- -2.19.2 - diff --git a/kernel/patches-4.14.x-rt/0005-iommu-amd-Use-raw-locks-on-atomic-context-paths.patch b/kernel/patches-4.14.x-rt/0005-iommu-amd-Use-raw-locks-on-atomic-context-paths.patch deleted file mode 100644 index 345295048..000000000 --- a/kernel/patches-4.14.x-rt/0005-iommu-amd-Use-raw-locks-on-atomic-context-paths.patch +++ /dev/null @@ -1,180 +0,0 @@ -From 0f961ceb5f56e333087f3ff78ba3f897f31a6113 Mon Sep 17 00:00:00 2001 -From: Scott Wood -Date: Sun, 21 Jan 2018 03:28:54 -0600 -Subject: [PATCH 005/450] iommu/amd: Use raw locks on atomic context paths - -Upstream commit 27790398c2aed917828dc3c6f81240d57f1584c9 - -Several functions in this driver are called from atomic context, -and thus raw locks must be used in order to be safe on PREEMPT_RT. - -This includes paths that must wait for command completion, which is -a potential PREEMPT_RT latency concern but not easily avoidable. - -Signed-off-by: Scott Wood -Signed-off-by: Joerg Roedel ---- - drivers/iommu/amd_iommu.c | 30 +++++++++++++++--------------- - drivers/iommu/amd_iommu_init.c | 2 +- - drivers/iommu/amd_iommu_types.h | 4 ++-- - 3 files changed, 18 insertions(+), 18 deletions(-) - -diff --git a/drivers/iommu/amd_iommu.c b/drivers/iommu/amd_iommu.c -index efa6cd2500b9..131a881d033d 100644 ---- a/drivers/iommu/amd_iommu.c -+++ b/drivers/iommu/amd_iommu.c -@@ -1062,9 +1062,9 @@ static int iommu_queue_command_sync(struct amd_iommu *iommu, - unsigned long flags; - int ret; - -- spin_lock_irqsave(&iommu->lock, flags); -+ raw_spin_lock_irqsave(&iommu->lock, flags); - ret = __iommu_queue_command_sync(iommu, cmd, sync); -- spin_unlock_irqrestore(&iommu->lock, flags); -+ raw_spin_unlock_irqrestore(&iommu->lock, flags); - - return ret; - } -@@ -1090,7 +1090,7 @@ static int iommu_completion_wait(struct amd_iommu *iommu) - - build_completion_wait(&cmd, (u64)&iommu->cmd_sem); - -- spin_lock_irqsave(&iommu->lock, flags); -+ raw_spin_lock_irqsave(&iommu->lock, flags); - - iommu->cmd_sem = 0; - -@@ -1101,7 +1101,7 @@ static int iommu_completion_wait(struct amd_iommu *iommu) - ret = wait_on_sem(&iommu->cmd_sem); - - out_unlock: -- spin_unlock_irqrestore(&iommu->lock, flags); -+ raw_spin_unlock_irqrestore(&iommu->lock, flags); - - return ret; - } -@@ -3626,7 +3626,7 @@ static struct irq_remap_table *get_irq_table(u16 devid, bool ioapic) - goto out_unlock; - - /* Initialize table spin-lock */ -- spin_lock_init(&table->lock); -+ raw_spin_lock_init(&table->lock); - - if (ioapic) - /* Keep the first 32 indexes free for IOAPIC interrupts */ -@@ -3685,7 +3685,7 @@ static int alloc_irq_index(u16 devid, int count) - if (!table) - return -ENODEV; - -- spin_lock_irqsave(&table->lock, flags); -+ raw_spin_lock_irqsave(&table->lock, flags); - - /* Scan table for free entries */ - for (c = 0, index = table->min_index; -@@ -3708,7 +3708,7 @@ static int alloc_irq_index(u16 devid, int count) - index = -ENOSPC; - - out: -- spin_unlock_irqrestore(&table->lock, flags); -+ raw_spin_unlock_irqrestore(&table->lock, flags); - - return index; - } -@@ -3729,7 +3729,7 @@ static int modify_irte_ga(u16 devid, int index, struct irte_ga *irte, - if (!table) - return -ENOMEM; - -- spin_lock_irqsave(&table->lock, flags); -+ raw_spin_lock_irqsave(&table->lock, flags); - - entry = (struct irte_ga *)table->table; - entry = &entry[index]; -@@ -3740,7 +3740,7 @@ static int modify_irte_ga(u16 devid, int index, struct irte_ga *irte, - if (data) - data->ref = entry; - -- spin_unlock_irqrestore(&table->lock, flags); -+ raw_spin_unlock_irqrestore(&table->lock, flags); - - iommu_flush_irt(iommu, devid); - iommu_completion_wait(iommu); -@@ -3762,9 +3762,9 @@ static int modify_irte(u16 devid, int index, union irte *irte) - if (!table) - return -ENOMEM; - -- spin_lock_irqsave(&table->lock, flags); -+ raw_spin_lock_irqsave(&table->lock, flags); - table->table[index] = irte->val; -- spin_unlock_irqrestore(&table->lock, flags); -+ raw_spin_unlock_irqrestore(&table->lock, flags); - - iommu_flush_irt(iommu, devid); - iommu_completion_wait(iommu); -@@ -3786,9 +3786,9 @@ static void free_irte(u16 devid, int index) - if (!table) - return; - -- spin_lock_irqsave(&table->lock, flags); -+ raw_spin_lock_irqsave(&table->lock, flags); - iommu->irte_ops->clear_allocated(table, index); -- spin_unlock_irqrestore(&table->lock, flags); -+ raw_spin_unlock_irqrestore(&table->lock, flags); - - iommu_flush_irt(iommu, devid); - iommu_completion_wait(iommu); -@@ -4367,7 +4367,7 @@ int amd_iommu_update_ga(int cpu, bool is_run, void *data) - if (!irt) - return -ENODEV; - -- spin_lock_irqsave(&irt->lock, flags); -+ raw_spin_lock_irqsave(&irt->lock, flags); - - if (ref->lo.fields_vapic.guest_mode) { - if (cpu >= 0) -@@ -4376,7 +4376,7 @@ int amd_iommu_update_ga(int cpu, bool is_run, void *data) - barrier(); - } - -- spin_unlock_irqrestore(&irt->lock, flags); -+ raw_spin_unlock_irqrestore(&irt->lock, flags); - - iommu_flush_irt(iommu, devid); - iommu_completion_wait(iommu); -diff --git a/drivers/iommu/amd_iommu_init.c b/drivers/iommu/amd_iommu_init.c -index 6fe2d0346073..e3cd81b32a33 100644 ---- a/drivers/iommu/amd_iommu_init.c -+++ b/drivers/iommu/amd_iommu_init.c -@@ -1474,7 +1474,7 @@ static int __init init_iommu_one(struct amd_iommu *iommu, struct ivhd_header *h) - { - int ret; - -- spin_lock_init(&iommu->lock); -+ raw_spin_lock_init(&iommu->lock); - - /* Add IOMMU to internal data structures */ - list_add_tail(&iommu->list, &amd_iommu_list); -diff --git a/drivers/iommu/amd_iommu_types.h b/drivers/iommu/amd_iommu_types.h -index f6b24c7d8b70..7521745dc2a5 100644 ---- a/drivers/iommu/amd_iommu_types.h -+++ b/drivers/iommu/amd_iommu_types.h -@@ -406,7 +406,7 @@ extern bool amd_iommu_iotlb_sup; - #define IRQ_TABLE_ALIGNMENT 128 - - struct irq_remap_table { -- spinlock_t lock; -+ raw_spinlock_t lock; - unsigned min_index; - u32 *table; - }; -@@ -488,7 +488,7 @@ struct amd_iommu { - int index; - - /* locks the accesses to the hardware */ -- spinlock_t lock; -+ raw_spinlock_t lock; - - /* Pointer to PCI device of this IOMMU */ - struct pci_dev *dev; --- -2.19.2 - diff --git a/kernel/patches-4.14.x-rt/0006-iommu-amd-Don-t-use-dev_data-in-irte_ga_set_affinity.patch b/kernel/patches-4.14.x-rt/0006-iommu-amd-Don-t-use-dev_data-in-irte_ga_set_affinity.patch deleted file mode 100644 index 998abc021..000000000 --- a/kernel/patches-4.14.x-rt/0006-iommu-amd-Don-t-use-dev_data-in-irte_ga_set_affinity.patch +++ /dev/null @@ -1,38 +0,0 @@ -From f60d301f66278292bb819375e579980f52d01679 Mon Sep 17 00:00:00 2001 -From: Scott Wood -Date: Sun, 28 Jan 2018 14:22:19 -0600 -Subject: [PATCH 006/450] iommu/amd: Don't use dev_data in - irte_ga_set_affinity() - -Upstream commit 01ee04badefd296eb7a4430497373be9b7b16783 - -search_dev_data() acquires a non-raw lock, which can't be done -from atomic context on PREEMPT_RT. There is no need to look at -dev_data because guest_mode should never be set if use_vapic is -not set. - -Signed-off-by: Scott Wood -Signed-off-by: Joerg Roedel ---- - drivers/iommu/amd_iommu.c | 4 +--- - 1 file changed, 1 insertion(+), 3 deletions(-) - -diff --git a/drivers/iommu/amd_iommu.c b/drivers/iommu/amd_iommu.c -index 131a881d033d..24fc8ea4909a 100644 ---- a/drivers/iommu/amd_iommu.c -+++ b/drivers/iommu/amd_iommu.c -@@ -3869,10 +3869,8 @@ static void irte_ga_set_affinity(void *entry, u16 devid, u16 index, - u8 vector, u32 dest_apicid) - { - struct irte_ga *irte = (struct irte_ga *) entry; -- struct iommu_dev_data *dev_data = search_dev_data(devid); - -- if (!dev_data || !dev_data->use_vapic || -- !irte->lo.fields_remap.guest_mode) { -+ if (!irte->lo.fields_remap.guest_mode) { - irte->hi.fields.vector = vector; - irte->lo.fields_remap.destination = dest_apicid; - modify_irte_ga(devid, index, irte, NULL); --- -2.19.2 - diff --git a/kernel/patches-4.14.x-rt/0007-iommu-amd-Avoid-locking-get_irq_table-from-atomic-co.patch b/kernel/patches-4.14.x-rt/0007-iommu-amd-Avoid-locking-get_irq_table-from-atomic-co.patch deleted file mode 100644 index 70bd379f2..000000000 --- a/kernel/patches-4.14.x-rt/0007-iommu-amd-Avoid-locking-get_irq_table-from-atomic-co.patch +++ /dev/null @@ -1,122 +0,0 @@ -From 75e9886d998becd42de359a6795f19d8aba1eeea Mon Sep 17 00:00:00 2001 -From: Scott Wood -Date: Wed, 14 Feb 2018 17:36:28 -0600 -Subject: [PATCH 007/450] iommu/amd: Avoid locking get_irq_table() from atomic - context - -Upstream commit df42a04b15f19a842393dc98a84cbc52b1f8ed49 - -get_irq_table() previously acquired amd_iommu_devtable_lock which is not -a raw lock, and thus cannot be acquired from atomic context on -PREEMPT_RT. Many calls to modify_irte*() come from atomic context due to -the IRQ desc->lock, as does amd_iommu_update_ga() due to the preemption -disabling in vcpu_load/put(). - -The only difference between calling get_irq_table() and reading from -irq_lookup_table[] directly, other than the lock acquisition and -amd_iommu_rlookup_table[] check, is if the table entry is unpopulated, -which should never happen when looking up a devid that came from an -irq_2_irte struct, as get_irq_table() would have already been called on -that devid during irq_remapping_alloc(). - -The lock acquisition is not needed in these cases because entries in -irq_lookup_table[] never change once non-NULL -- nor would the -amd_iommu_devtable_lock usage in get_irq_table() provide meaningful -protection if they did, since it's released before using the looked up -table in the get_irq_table() caller. - -Rename the old get_irq_table() to alloc_irq_table(), and create a new -lockless get_irq_table() to be used in non-allocating contexts that WARNs -if it doesn't find what it's looking for. - -Signed-off-by: Scott Wood -Signed-off-by: Joerg Roedel ---- - drivers/iommu/amd_iommu.c | 29 ++++++++++++++++++++++------- - 1 file changed, 22 insertions(+), 7 deletions(-) - -diff --git a/drivers/iommu/amd_iommu.c b/drivers/iommu/amd_iommu.c -index 24fc8ea4909a..57c873ff05fa 100644 ---- a/drivers/iommu/amd_iommu.c -+++ b/drivers/iommu/amd_iommu.c -@@ -3594,7 +3594,22 @@ static void set_dte_irq_entry(u16 devid, struct irq_remap_table *table) - amd_iommu_dev_table[devid].data[2] = dte; - } - --static struct irq_remap_table *get_irq_table(u16 devid, bool ioapic) -+static struct irq_remap_table *get_irq_table(u16 devid) -+{ -+ struct irq_remap_table *table; -+ -+ if (WARN_ONCE(!amd_iommu_rlookup_table[devid], -+ "%s: no iommu for devid %x\n", __func__, devid)) -+ return NULL; -+ -+ table = irq_lookup_table[devid]; -+ if (WARN_ONCE(!table, "%s: no table for devid %x\n", __func__, devid)) -+ return NULL; -+ -+ return table; -+} -+ -+static struct irq_remap_table *alloc_irq_table(u16 devid, bool ioapic) - { - struct irq_remap_table *table = NULL; - struct amd_iommu *iommu; -@@ -3681,7 +3696,7 @@ static int alloc_irq_index(u16 devid, int count) - if (!iommu) - return -ENODEV; - -- table = get_irq_table(devid, false); -+ table = alloc_irq_table(devid, false); - if (!table) - return -ENODEV; - -@@ -3725,7 +3740,7 @@ static int modify_irte_ga(u16 devid, int index, struct irte_ga *irte, - if (iommu == NULL) - return -EINVAL; - -- table = get_irq_table(devid, false); -+ table = get_irq_table(devid); - if (!table) - return -ENOMEM; - -@@ -3758,7 +3773,7 @@ static int modify_irte(u16 devid, int index, union irte *irte) - if (iommu == NULL) - return -EINVAL; - -- table = get_irq_table(devid, false); -+ table = get_irq_table(devid); - if (!table) - return -ENOMEM; - -@@ -3782,7 +3797,7 @@ static void free_irte(u16 devid, int index) - if (iommu == NULL) - return; - -- table = get_irq_table(devid, false); -+ table = get_irq_table(devid); - if (!table) - return; - -@@ -4100,7 +4115,7 @@ static int irq_remapping_alloc(struct irq_domain *domain, unsigned int virq, - return ret; - - if (info->type == X86_IRQ_ALLOC_TYPE_IOAPIC) { -- if (get_irq_table(devid, true)) -+ if (alloc_irq_table(devid, true)) - index = info->ioapic_pin; - else - ret = -ENOMEM; -@@ -4361,7 +4376,7 @@ int amd_iommu_update_ga(int cpu, bool is_run, void *data) - if (!iommu) - return -ENODEV; - -- irt = get_irq_table(devid, false); -+ irt = get_irq_table(devid); - if (!irt) - return -ENODEV; - --- -2.19.2 - diff --git a/kernel/patches-4.14.x-rt/0008-iommu-amd-Turn-dev_data_list-into-a-lock-less-list.patch b/kernel/patches-4.14.x-rt/0008-iommu-amd-Turn-dev_data_list-into-a-lock-less-list.patch deleted file mode 100644 index 76eef5ae9..000000000 --- a/kernel/patches-4.14.x-rt/0008-iommu-amd-Turn-dev_data_list-into-a-lock-less-list.patch +++ /dev/null @@ -1,105 +0,0 @@ -From ece88076b665589976cb6fc1e2fc07cc6e7c1ec4 Mon Sep 17 00:00:00 2001 -From: Sebastian Andrzej Siewior -Date: Thu, 22 Mar 2018 16:22:34 +0100 -Subject: [PATCH 008/450] iommu/amd: Turn dev_data_list into a lock less list - -Upstream commit 779da73273fc4c4c6f41579a95e4fb7880a1720e - -alloc_dev_data() adds new items to dev_data_list and search_dev_data() -is searching for items in this list. Both protect the access to the list -with a spinlock. -There is no need to navigate forth and back within the list and there is -also no deleting of a specific item. This qualifies the list to become a -lock less list and as part of this, the spinlock can be removed. -With this change the ordering of those items within the list is changed: -before the change new items were added to the end of the list, now they -are added to the front. I don't think it matters but wanted to mention -it. - -Signed-off-by: Sebastian Andrzej Siewior -Signed-off-by: Joerg Roedel ---- - drivers/iommu/amd_iommu.c | 28 ++++++++++------------------ - drivers/iommu/amd_iommu_types.h | 2 +- - 2 files changed, 11 insertions(+), 19 deletions(-) - -diff --git a/drivers/iommu/amd_iommu.c b/drivers/iommu/amd_iommu.c -index 57c873ff05fa..50b6cab604aa 100644 ---- a/drivers/iommu/amd_iommu.c -+++ b/drivers/iommu/amd_iommu.c -@@ -84,8 +84,7 @@ - static DEFINE_RWLOCK(amd_iommu_devtable_lock); - - /* List of all available dev_data structures */ --static LIST_HEAD(dev_data_list); --static DEFINE_SPINLOCK(dev_data_list_lock); -+static LLIST_HEAD(dev_data_list); - - LIST_HEAD(ioapic_map); - LIST_HEAD(hpet_map); -@@ -204,40 +203,33 @@ static struct dma_ops_domain* to_dma_ops_domain(struct protection_domain *domain - static struct iommu_dev_data *alloc_dev_data(u16 devid) - { - struct iommu_dev_data *dev_data; -- unsigned long flags; - - dev_data = kzalloc(sizeof(*dev_data), GFP_KERNEL); - if (!dev_data) - return NULL; - - dev_data->devid = devid; -- -- spin_lock_irqsave(&dev_data_list_lock, flags); -- list_add_tail(&dev_data->dev_data_list, &dev_data_list); -- spin_unlock_irqrestore(&dev_data_list_lock, flags); -- - ratelimit_default_init(&dev_data->rs); - -+ llist_add(&dev_data->dev_data_list, &dev_data_list); - return dev_data; - } - - static struct iommu_dev_data *search_dev_data(u16 devid) - { - struct iommu_dev_data *dev_data; -- unsigned long flags; -+ struct llist_node *node; -+ -+ if (llist_empty(&dev_data_list)) -+ return NULL; - -- spin_lock_irqsave(&dev_data_list_lock, flags); -- list_for_each_entry(dev_data, &dev_data_list, dev_data_list) { -+ node = dev_data_list.first; -+ llist_for_each_entry(dev_data, node, dev_data_list) { - if (dev_data->devid == devid) -- goto out_unlock; -+ return dev_data; - } - -- dev_data = NULL; -- --out_unlock: -- spin_unlock_irqrestore(&dev_data_list_lock, flags); -- -- return dev_data; -+ return NULL; - } - - static int __last_alias(struct pci_dev *pdev, u16 alias, void *data) -diff --git a/drivers/iommu/amd_iommu_types.h b/drivers/iommu/amd_iommu_types.h -index 7521745dc2a5..16b1404da58c 100644 ---- a/drivers/iommu/amd_iommu_types.h -+++ b/drivers/iommu/amd_iommu_types.h -@@ -625,7 +625,7 @@ struct devid_map { - */ - struct iommu_dev_data { - struct list_head list; /* For domain->dev_list */ -- struct list_head dev_data_list; /* For global dev_data_list */ -+ struct llist_node dev_data_list; /* For global dev_data_list */ - struct protection_domain *domain; /* Domain the device is bound to */ - u16 devid; /* PCI Device ID */ - u16 alias; /* Alias Device ID */ --- -2.19.2 - diff --git a/kernel/patches-4.14.x-rt/0009-iommu-amd-Split-domain-id-out-of-amd_iommu_devtable_.patch b/kernel/patches-4.14.x-rt/0009-iommu-amd-Split-domain-id-out-of-amd_iommu_devtable_.patch deleted file mode 100644 index 11b16e2e5..000000000 --- a/kernel/patches-4.14.x-rt/0009-iommu-amd-Split-domain-id-out-of-amd_iommu_devtable_.patch +++ /dev/null @@ -1,68 +0,0 @@ -From 5ef7777092fe740f67d1e304019e3bea28eb8fce Mon Sep 17 00:00:00 2001 -From: Sebastian Andrzej Siewior -Date: Thu, 22 Mar 2018 16:22:35 +0100 -Subject: [PATCH 009/450] iommu/amd: Split domain id out of - amd_iommu_devtable_lock - -Upstream commit 2bc00180890427dcc092b2f2b0d03c904bcade29 - -domain_id_alloc() and domain_id_free() is used for id management. Those -two function share a bitmap (amd_iommu_pd_alloc_bitmap) and set/clear -bits based on id allocation. There is no need to share this with -amd_iommu_devtable_lock, it can use its own lock for this operation. - -Signed-off-by: Sebastian Andrzej Siewior -Signed-off-by: Joerg Roedel ---- - drivers/iommu/amd_iommu.c | 12 +++++------- - 1 file changed, 5 insertions(+), 7 deletions(-) - -diff --git a/drivers/iommu/amd_iommu.c b/drivers/iommu/amd_iommu.c -index 50b6cab604aa..ccf9d1d08983 100644 ---- a/drivers/iommu/amd_iommu.c -+++ b/drivers/iommu/amd_iommu.c -@@ -82,6 +82,7 @@ - #define AMD_IOMMU_PGSIZES ((~0xFFFUL) & ~(2ULL << 38)) - - static DEFINE_RWLOCK(amd_iommu_devtable_lock); -+static DEFINE_SPINLOCK(pd_bitmap_lock); - - /* List of all available dev_data structures */ - static LLIST_HEAD(dev_data_list); -@@ -1602,29 +1603,26 @@ static void del_domain_from_list(struct protection_domain *domain) - - static u16 domain_id_alloc(void) - { -- unsigned long flags; - int id; - -- write_lock_irqsave(&amd_iommu_devtable_lock, flags); -+ spin_lock(&pd_bitmap_lock); - id = find_first_zero_bit(amd_iommu_pd_alloc_bitmap, MAX_DOMAIN_ID); - BUG_ON(id == 0); - if (id > 0 && id < MAX_DOMAIN_ID) - __set_bit(id, amd_iommu_pd_alloc_bitmap); - else - id = 0; -- write_unlock_irqrestore(&amd_iommu_devtable_lock, flags); -+ spin_unlock(&pd_bitmap_lock); - - return id; - } - - static void domain_id_free(int id) - { -- unsigned long flags; -- -- write_lock_irqsave(&amd_iommu_devtable_lock, flags); -+ spin_lock(&pd_bitmap_lock); - if (id > 0 && id < MAX_DOMAIN_ID) - __clear_bit(id, amd_iommu_pd_alloc_bitmap); -- write_unlock_irqrestore(&amd_iommu_devtable_lock, flags); -+ spin_unlock(&pd_bitmap_lock); - } - - #define DEFINE_FREE_PT_FN(LVL, FN) \ --- -2.19.2 - diff --git a/kernel/patches-4.14.x-rt/0010-iommu-amd-Split-irq_lookup_table-out-of-the-amd_iomm.patch b/kernel/patches-4.14.x-rt/0010-iommu-amd-Split-irq_lookup_table-out-of-the-amd_iomm.patch deleted file mode 100644 index 7df44d809..000000000 --- a/kernel/patches-4.14.x-rt/0010-iommu-amd-Split-irq_lookup_table-out-of-the-amd_iomm.patch +++ /dev/null @@ -1,56 +0,0 @@ -From 5003ff93cc34975cd85c14248483548cd0635dc6 Mon Sep 17 00:00:00 2001 -From: Sebastian Andrzej Siewior -Date: Thu, 22 Mar 2018 16:22:36 +0100 -Subject: [PATCH 010/450] iommu/amd: Split irq_lookup_table out of the - amd_iommu_devtable_lock - -Upstream commit ea6166f4b83e9cfba1c18f46a764d50045682fe5 - -The function get_irq_table() reads/writes irq_lookup_table while holding -the amd_iommu_devtable_lock. It also modifies -amd_iommu_dev_table[].data[2]. -set_dte_entry() is using amd_iommu_dev_table[].data[0|1] (under the -domain->lock) so it should be okay. The access to the iommu is -serialized with its own (iommu's) lock. - -So split out get_irq_table() out of amd_iommu_devtable_lock's lock. - -Signed-off-by: Sebastian Andrzej Siewior -Signed-off-by: Joerg Roedel ---- - drivers/iommu/amd_iommu.c | 5 +++-- - 1 file changed, 3 insertions(+), 2 deletions(-) - -diff --git a/drivers/iommu/amd_iommu.c b/drivers/iommu/amd_iommu.c -index ccf9d1d08983..1bb09f1e5cd1 100644 ---- a/drivers/iommu/amd_iommu.c -+++ b/drivers/iommu/amd_iommu.c -@@ -83,6 +83,7 @@ - - static DEFINE_RWLOCK(amd_iommu_devtable_lock); - static DEFINE_SPINLOCK(pd_bitmap_lock); -+static DEFINE_SPINLOCK(iommu_table_lock); - - /* List of all available dev_data structures */ - static LLIST_HEAD(dev_data_list); -@@ -3606,7 +3607,7 @@ static struct irq_remap_table *alloc_irq_table(u16 devid, bool ioapic) - unsigned long flags; - u16 alias; - -- write_lock_irqsave(&amd_iommu_devtable_lock, flags); -+ spin_lock_irqsave(&iommu_table_lock, flags); - - iommu = amd_iommu_rlookup_table[devid]; - if (!iommu) -@@ -3671,7 +3672,7 @@ static struct irq_remap_table *alloc_irq_table(u16 devid, bool ioapic) - iommu_completion_wait(iommu); - - out_unlock: -- write_unlock_irqrestore(&amd_iommu_devtable_lock, flags); -+ spin_unlock_irqrestore(&iommu_table_lock, flags); - - return table; - } --- -2.19.2 - diff --git a/kernel/patches-4.14.x-rt/0011-iommu-amd-Remove-the-special-case-from-alloc_irq_tab.patch b/kernel/patches-4.14.x-rt/0011-iommu-amd-Remove-the-special-case-from-alloc_irq_tab.patch deleted file mode 100644 index 047a71ef6..000000000 --- a/kernel/patches-4.14.x-rt/0011-iommu-amd-Remove-the-special-case-from-alloc_irq_tab.patch +++ /dev/null @@ -1,100 +0,0 @@ -From a3bd03fcc63c2806bee9b1b4da5d55a40a7d1c6c Mon Sep 17 00:00:00 2001 -From: Sebastian Andrzej Siewior -Date: Thu, 22 Mar 2018 16:22:37 +0100 -Subject: [PATCH 011/450] iommu/amd: Remove the special case from - alloc_irq_table() - -Upstream commit fde65dd3d3096e8f6ecc7bbe544eb91f4220772c - -alloc_irq_table() has a special ioapic argument. If set then it will -pre-allocate / reserve the first 32 indexes. The argument is only once -true and it would make alloc_irq_table() a little simpler if we would -extract the special bits to the caller. -The caller of irq_remapping_alloc() is holding irq_domain_mutex so the -initialization of iommu->irte_ops->set_allocated() should not race -against other user. - -Signed-off-by: Sebastian Andrzej Siewior -Signed-off-by: Joerg Roedel ---- - drivers/iommu/amd_iommu.c | 34 ++++++++++++++++++++-------------- - 1 file changed, 20 insertions(+), 14 deletions(-) - -diff --git a/drivers/iommu/amd_iommu.c b/drivers/iommu/amd_iommu.c -index 1bb09f1e5cd1..f1017cf37eb3 100644 ---- a/drivers/iommu/amd_iommu.c -+++ b/drivers/iommu/amd_iommu.c -@@ -3600,7 +3600,7 @@ static struct irq_remap_table *get_irq_table(u16 devid) - return table; - } - --static struct irq_remap_table *alloc_irq_table(u16 devid, bool ioapic) -+static struct irq_remap_table *alloc_irq_table(u16 devid) - { - struct irq_remap_table *table = NULL; - struct amd_iommu *iommu; -@@ -3634,10 +3634,6 @@ static struct irq_remap_table *alloc_irq_table(u16 devid, bool ioapic) - /* Initialize table spin-lock */ - raw_spin_lock_init(&table->lock); - -- if (ioapic) -- /* Keep the first 32 indexes free for IOAPIC interrupts */ -- table->min_index = 32; -- - table->table = kmem_cache_alloc(amd_iommu_irq_cache, GFP_ATOMIC); - if (!table->table) { - kfree(table); -@@ -3652,12 +3648,6 @@ static struct irq_remap_table *alloc_irq_table(u16 devid, bool ioapic) - memset(table->table, 0, - (MAX_IRQS_PER_TABLE * (sizeof(u64) * 2))); - -- if (ioapic) { -- int i; -- -- for (i = 0; i < 32; ++i) -- iommu->irte_ops->set_allocated(table, i); -- } - - irq_lookup_table[devid] = table; - set_dte_irq_entry(devid, table); -@@ -3687,7 +3677,7 @@ static int alloc_irq_index(u16 devid, int count) - if (!iommu) - return -ENODEV; - -- table = alloc_irq_table(devid, false); -+ table = alloc_irq_table(devid); - if (!table) - return -ENODEV; - -@@ -4106,10 +4096,26 @@ static int irq_remapping_alloc(struct irq_domain *domain, unsigned int virq, - return ret; - - if (info->type == X86_IRQ_ALLOC_TYPE_IOAPIC) { -- if (alloc_irq_table(devid, true)) -+ struct irq_remap_table *table; -+ struct amd_iommu *iommu; -+ -+ table = alloc_irq_table(devid); -+ if (table) { -+ if (!table->min_index) { -+ /* -+ * Keep the first 32 indexes free for IOAPIC -+ * interrupts. -+ */ -+ table->min_index = 32; -+ iommu = amd_iommu_rlookup_table[devid]; -+ for (i = 0; i < 32; ++i) -+ iommu->irte_ops->set_allocated(table, i); -+ } -+ WARN_ON(table->min_index != 32); - index = info->ioapic_pin; -- else -+ } else { - ret = -ENOMEM; -+ } - } else { - index = alloc_irq_index(devid, nr_irqs); - } --- -2.19.2 - diff --git a/kernel/patches-4.14.x-rt/0012-iommu-amd-Use-table-instead-irt-as-variable-name-in-.patch b/kernel/patches-4.14.x-rt/0012-iommu-amd-Use-table-instead-irt-as-variable-name-in-.patch deleted file mode 100644 index e91dc919a..000000000 --- a/kernel/patches-4.14.x-rt/0012-iommu-amd-Use-table-instead-irt-as-variable-name-in-.patch +++ /dev/null @@ -1,58 +0,0 @@ -From 340f3a55c46a7bf11cee5431d73ebbd1fa9081c0 Mon Sep 17 00:00:00 2001 -From: Sebastian Andrzej Siewior -Date: Thu, 22 Mar 2018 16:22:38 +0100 -Subject: [PATCH 012/450] iommu/amd: Use `table' instead `irt' as variable name - in amd_iommu_update_ga() - -Upstream commit 4fde541c9dc114c5b448ad34b0286fe8b7c550f1 - -The variable of type struct irq_remap_table is always named `table' -except in amd_iommu_update_ga() where it is called `irt'. Make it -consistent and name it also `table'. - -Signed-off-by: Sebastian Andrzej Siewior -Signed-off-by: Joerg Roedel ---- - drivers/iommu/amd_iommu.c | 10 +++++----- - 1 file changed, 5 insertions(+), 5 deletions(-) - -diff --git a/drivers/iommu/amd_iommu.c b/drivers/iommu/amd_iommu.c -index f1017cf37eb3..561664b0e609 100644 ---- a/drivers/iommu/amd_iommu.c -+++ b/drivers/iommu/amd_iommu.c -@@ -4359,7 +4359,7 @@ int amd_iommu_update_ga(int cpu, bool is_run, void *data) - { - unsigned long flags; - struct amd_iommu *iommu; -- struct irq_remap_table *irt; -+ struct irq_remap_table *table; - struct amd_ir_data *ir_data = (struct amd_ir_data *)data; - int devid = ir_data->irq_2_irte.devid; - struct irte_ga *entry = (struct irte_ga *) ir_data->entry; -@@ -4373,11 +4373,11 @@ int amd_iommu_update_ga(int cpu, bool is_run, void *data) - if (!iommu) - return -ENODEV; - -- irt = get_irq_table(devid); -- if (!irt) -+ table = get_irq_table(devid); -+ if (!table) - return -ENODEV; - -- raw_spin_lock_irqsave(&irt->lock, flags); -+ raw_spin_lock_irqsave(&table->lock, flags); - - if (ref->lo.fields_vapic.guest_mode) { - if (cpu >= 0) -@@ -4386,7 +4386,7 @@ int amd_iommu_update_ga(int cpu, bool is_run, void *data) - barrier(); - } - -- raw_spin_unlock_irqrestore(&irt->lock, flags); -+ raw_spin_unlock_irqrestore(&table->lock, flags); - - iommu_flush_irt(iommu, devid); - iommu_completion_wait(iommu); --- -2.19.2 - diff --git a/kernel/patches-4.14.x-rt/0013-iommu-amd-Factor-out-setting-the-remap-table-for-a-d.patch b/kernel/patches-4.14.x-rt/0013-iommu-amd-Factor-out-setting-the-remap-table-for-a-d.patch deleted file mode 100644 index efa7626e3..000000000 --- a/kernel/patches-4.14.x-rt/0013-iommu-amd-Factor-out-setting-the-remap-table-for-a-d.patch +++ /dev/null @@ -1,72 +0,0 @@ -From 78b50efad4c03293a63d9b482f5c33f8186bfc9f Mon Sep 17 00:00:00 2001 -From: Sebastian Andrzej Siewior -Date: Thu, 22 Mar 2018 16:22:39 +0100 -Subject: [PATCH 013/450] iommu/amd: Factor out setting the remap table for a - devid - -Upstream commit 2fcc1e8ac4a8514c64f946178fc36c2e30e56a41 - -Setting the IRQ remap table for a specific devid (or its alias devid) -includes three steps. Those three steps are always repeated each time -this is done. -Introduce a new helper function, move those steps there and use that -function instead. The compiler can still decide if it is worth to -inline. - -Signed-off-by: Sebastian Andrzej Siewior -Signed-off-by: Joerg Roedel ---- - drivers/iommu/amd_iommu.c | 23 ++++++++++++----------- - 1 file changed, 12 insertions(+), 11 deletions(-) - -diff --git a/drivers/iommu/amd_iommu.c b/drivers/iommu/amd_iommu.c -index 561664b0e609..473ec78ba50c 100644 ---- a/drivers/iommu/amd_iommu.c -+++ b/drivers/iommu/amd_iommu.c -@@ -3600,6 +3600,14 @@ static struct irq_remap_table *get_irq_table(u16 devid) - return table; - } - -+static void set_remap_table_entry(struct amd_iommu *iommu, u16 devid, -+ struct irq_remap_table *table) -+{ -+ irq_lookup_table[devid] = table; -+ set_dte_irq_entry(devid, table); -+ iommu_flush_dte(iommu, devid); -+} -+ - static struct irq_remap_table *alloc_irq_table(u16 devid) - { - struct irq_remap_table *table = NULL; -@@ -3620,9 +3628,7 @@ static struct irq_remap_table *alloc_irq_table(u16 devid) - alias = amd_iommu_alias_table[devid]; - table = irq_lookup_table[alias]; - if (table) { -- irq_lookup_table[devid] = table; -- set_dte_irq_entry(devid, table); -- iommu_flush_dte(iommu, devid); -+ set_remap_table_entry(iommu, devid, table); - goto out; - } - -@@ -3649,14 +3655,9 @@ static struct irq_remap_table *alloc_irq_table(u16 devid) - (MAX_IRQS_PER_TABLE * (sizeof(u64) * 2))); - - -- irq_lookup_table[devid] = table; -- set_dte_irq_entry(devid, table); -- iommu_flush_dte(iommu, devid); -- if (devid != alias) { -- irq_lookup_table[alias] = table; -- set_dte_irq_entry(alias, table); -- iommu_flush_dte(iommu, alias); -- } -+ set_remap_table_entry(iommu, devid, table); -+ if (devid != alias) -+ set_remap_table_entry(iommu, alias, table); - - out: - iommu_completion_wait(iommu); --- -2.19.2 - diff --git a/kernel/patches-4.14.x-rt/0014-iommu-amd-Drop-the-lock-while-allocating-new-irq-rem.patch b/kernel/patches-4.14.x-rt/0014-iommu-amd-Drop-the-lock-while-allocating-new-irq-rem.patch deleted file mode 100644 index df8132afb..000000000 --- a/kernel/patches-4.14.x-rt/0014-iommu-amd-Drop-the-lock-while-allocating-new-irq-rem.patch +++ /dev/null @@ -1,137 +0,0 @@ -From 0ef3ebf9be599ebc17441c220f837622a2ddeb79 Mon Sep 17 00:00:00 2001 -From: Sebastian Andrzej Siewior -Date: Thu, 22 Mar 2018 16:22:40 +0100 -Subject: [PATCH 014/450] iommu/amd: Drop the lock while allocating new irq - remap table - -Upstream commit 993ca6e063a69a0c65ca42ed449b6bc1b3844151 - -The irq_remap_table is allocated while the iommu_table_lock is held with -interrupts disabled. ->From looking at the call sites, all callers are in the early device -initialisation (apic_bsp_setup(), pci_enable_device(), -pci_enable_msi()) so make sense to drop the lock which also enables -interrupts and try to allocate that memory with GFP_KERNEL instead -GFP_ATOMIC. - -Since during the allocation the iommu_table_lock is dropped, we need to -recheck if table exists after the lock has been reacquired. I *think* -that it is impossible that the "devid" entry appears in irq_lookup_table -while the lock is dropped since the same device can only be probed once. -However I check for both cases, just to be sure. - -Signed-off-by: Sebastian Andrzej Siewior -Signed-off-by: Joerg Roedel ---- - drivers/iommu/amd_iommu.c | 63 ++++++++++++++++++++++++++++----------- - 1 file changed, 45 insertions(+), 18 deletions(-) - -diff --git a/drivers/iommu/amd_iommu.c b/drivers/iommu/amd_iommu.c -index 473ec78ba50c..c9e703260324 100644 ---- a/drivers/iommu/amd_iommu.c -+++ b/drivers/iommu/amd_iommu.c -@@ -3600,6 +3600,30 @@ static struct irq_remap_table *get_irq_table(u16 devid) - return table; - } - -+static struct irq_remap_table *__alloc_irq_table(void) -+{ -+ struct irq_remap_table *table; -+ -+ table = kzalloc(sizeof(*table), GFP_KERNEL); -+ if (!table) -+ return NULL; -+ -+ table->table = kmem_cache_alloc(amd_iommu_irq_cache, GFP_KERNEL); -+ if (!table->table) { -+ kfree(table); -+ return NULL; -+ } -+ raw_spin_lock_init(&table->lock); -+ -+ if (!AMD_IOMMU_GUEST_IR_GA(amd_iommu_guest_ir)) -+ memset(table->table, 0, -+ MAX_IRQS_PER_TABLE * sizeof(u32)); -+ else -+ memset(table->table, 0, -+ (MAX_IRQS_PER_TABLE * (sizeof(u64) * 2))); -+ return table; -+} -+ - static void set_remap_table_entry(struct amd_iommu *iommu, u16 devid, - struct irq_remap_table *table) - { -@@ -3611,6 +3635,7 @@ static void set_remap_table_entry(struct amd_iommu *iommu, u16 devid, - static struct irq_remap_table *alloc_irq_table(u16 devid) - { - struct irq_remap_table *table = NULL; -+ struct irq_remap_table *new_table = NULL; - struct amd_iommu *iommu; - unsigned long flags; - u16 alias; -@@ -3629,42 +3654,44 @@ static struct irq_remap_table *alloc_irq_table(u16 devid) - table = irq_lookup_table[alias]; - if (table) { - set_remap_table_entry(iommu, devid, table); -- goto out; -+ goto out_wait; - } -+ spin_unlock_irqrestore(&iommu_table_lock, flags); - - /* Nothing there yet, allocate new irq remapping table */ -- table = kzalloc(sizeof(*table), GFP_ATOMIC); -- if (!table) -- goto out_unlock; -+ new_table = __alloc_irq_table(); -+ if (!new_table) -+ return NULL; - -- /* Initialize table spin-lock */ -- raw_spin_lock_init(&table->lock); -+ spin_lock_irqsave(&iommu_table_lock, flags); - -- table->table = kmem_cache_alloc(amd_iommu_irq_cache, GFP_ATOMIC); -- if (!table->table) { -- kfree(table); -- table = NULL; -+ table = irq_lookup_table[devid]; -+ if (table) - goto out_unlock; -- } - -- if (!AMD_IOMMU_GUEST_IR_GA(amd_iommu_guest_ir)) -- memset(table->table, 0, -- MAX_IRQS_PER_TABLE * sizeof(u32)); -- else -- memset(table->table, 0, -- (MAX_IRQS_PER_TABLE * (sizeof(u64) * 2))); -+ table = irq_lookup_table[alias]; -+ if (table) { -+ set_remap_table_entry(iommu, devid, table); -+ goto out_wait; -+ } - -+ table = new_table; -+ new_table = NULL; - - set_remap_table_entry(iommu, devid, table); - if (devid != alias) - set_remap_table_entry(iommu, alias, table); - --out: -+out_wait: - iommu_completion_wait(iommu); - - out_unlock: - spin_unlock_irqrestore(&iommu_table_lock, flags); - -+ if (new_table) { -+ kmem_cache_free(amd_iommu_irq_cache, new_table->table); -+ kfree(new_table); -+ } - return table; - } - --- -2.19.2 - diff --git a/kernel/patches-4.14.x-rt/0015-iommu-amd-Make-amd_iommu_devtable_lock-a-spin_lock.patch b/kernel/patches-4.14.x-rt/0015-iommu-amd-Make-amd_iommu_devtable_lock-a-spin_lock.patch deleted file mode 100644 index d8a8ecce6..000000000 --- a/kernel/patches-4.14.x-rt/0015-iommu-amd-Make-amd_iommu_devtable_lock-a-spin_lock.patch +++ /dev/null @@ -1,79 +0,0 @@ -From 7febe26307d9a7f74f5e1509961b682017caaa31 Mon Sep 17 00:00:00 2001 -From: Sebastian Andrzej Siewior -Date: Thu, 22 Mar 2018 16:22:41 +0100 -Subject: [PATCH 015/450] iommu/amd: Make amd_iommu_devtable_lock a spin_lock - -Upstream commit 2cd1083d79a0a8c223af430ca97884c28a1e2fc0 - -Before commit 0bb6e243d7fb ("iommu/amd: Support IOMMU_DOMAIN_DMA type -allocation") amd_iommu_devtable_lock had a read_lock() user but now -there are none. In fact, after the mentioned commit we had only -write_lock() user of the lock. Since there is no reason to keep it as -writer lock, change its type to a spin_lock. -I *think* that we might even be able to remove the lock because all its -current user seem to have their own protection. - -Signed-off-by: Sebastian Andrzej Siewior -Signed-off-by: Joerg Roedel ---- - drivers/iommu/amd_iommu.c | 14 +++++++------- - 1 file changed, 7 insertions(+), 7 deletions(-) - -diff --git a/drivers/iommu/amd_iommu.c b/drivers/iommu/amd_iommu.c -index c9e703260324..67008031537a 100644 ---- a/drivers/iommu/amd_iommu.c -+++ b/drivers/iommu/amd_iommu.c -@@ -81,7 +81,7 @@ - */ - #define AMD_IOMMU_PGSIZES ((~0xFFFUL) & ~(2ULL << 38)) - --static DEFINE_RWLOCK(amd_iommu_devtable_lock); -+static DEFINE_SPINLOCK(amd_iommu_devtable_lock); - static DEFINE_SPINLOCK(pd_bitmap_lock); - static DEFINE_SPINLOCK(iommu_table_lock); - -@@ -2092,9 +2092,9 @@ static int attach_device(struct device *dev, - } - - skip_ats_check: -- write_lock_irqsave(&amd_iommu_devtable_lock, flags); -+ spin_lock_irqsave(&amd_iommu_devtable_lock, flags); - ret = __attach_device(dev_data, domain); -- write_unlock_irqrestore(&amd_iommu_devtable_lock, flags); -+ spin_unlock_irqrestore(&amd_iommu_devtable_lock, flags); - - /* - * We might boot into a crash-kernel here. The crashed kernel -@@ -2144,9 +2144,9 @@ static void detach_device(struct device *dev) - domain = dev_data->domain; - - /* lock device table */ -- write_lock_irqsave(&amd_iommu_devtable_lock, flags); -+ spin_lock_irqsave(&amd_iommu_devtable_lock, flags); - __detach_device(dev_data); -- write_unlock_irqrestore(&amd_iommu_devtable_lock, flags); -+ spin_unlock_irqrestore(&amd_iommu_devtable_lock, flags); - - if (!dev_is_pci(dev)) - return; -@@ -2810,7 +2810,7 @@ static void cleanup_domain(struct protection_domain *domain) - struct iommu_dev_data *entry; - unsigned long flags; - -- write_lock_irqsave(&amd_iommu_devtable_lock, flags); -+ spin_lock_irqsave(&amd_iommu_devtable_lock, flags); - - while (!list_empty(&domain->dev_list)) { - entry = list_first_entry(&domain->dev_list, -@@ -2818,7 +2818,7 @@ static void cleanup_domain(struct protection_domain *domain) - __detach_device(entry); - } - -- write_unlock_irqrestore(&amd_iommu_devtable_lock, flags); -+ spin_unlock_irqrestore(&amd_iommu_devtable_lock, flags); - } - - static void protection_domain_free(struct protection_domain *domain) --- -2.19.2 - diff --git a/kernel/patches-4.14.x-rt/0016-iommu-amd-Return-proper-error-code-in-irq_remapping_.patch b/kernel/patches-4.14.x-rt/0016-iommu-amd-Return-proper-error-code-in-irq_remapping_.patch deleted file mode 100644 index b966ec81b..000000000 --- a/kernel/patches-4.14.x-rt/0016-iommu-amd-Return-proper-error-code-in-irq_remapping_.patch +++ /dev/null @@ -1,46 +0,0 @@ -From 274e123364bc15e0fce26d4bc5f98793e6db18d8 Mon Sep 17 00:00:00 2001 -From: Sebastian Andrzej Siewior -Date: Thu, 22 Mar 2018 16:22:42 +0100 -Subject: [PATCH 016/450] iommu/amd: Return proper error code in - irq_remapping_alloc() - -Upstream commit 29d049be9438278c47253a74cf8d0ddf36bd5d68 - -In the unlikely case when alloc_irq_table() is not able to return a -remap table then "ret" will be assigned with an error code. Later, the -code checks `index' and if it is negative (which it is because it is -initialized with `-1') and then then function properly aborts but -returns `-1' instead `-ENOMEM' what was intended. -In order to correct this, I assign -ENOMEM to index. - -Signed-off-by: Sebastian Andrzej Siewior -Signed-off-by: Joerg Roedel ---- - drivers/iommu/amd_iommu.c | 4 ++-- - 1 file changed, 2 insertions(+), 2 deletions(-) - -diff --git a/drivers/iommu/amd_iommu.c b/drivers/iommu/amd_iommu.c -index 67008031537a..876947fcb4c6 100644 ---- a/drivers/iommu/amd_iommu.c -+++ b/drivers/iommu/amd_iommu.c -@@ -4100,7 +4100,7 @@ static int irq_remapping_alloc(struct irq_domain *domain, unsigned int virq, - struct amd_ir_data *data = NULL; - struct irq_cfg *cfg; - int i, ret, devid; -- int index = -1; -+ int index; - - if (!info) - return -EINVAL; -@@ -4142,7 +4142,7 @@ static int irq_remapping_alloc(struct irq_domain *domain, unsigned int virq, - WARN_ON(table->min_index != 32); - index = info->ioapic_pin; - } else { -- ret = -ENOMEM; -+ index = -ENOMEM; - } - } else { - index = alloc_irq_index(devid, nr_irqs); --- -2.19.2 - diff --git a/kernel/patches-4.14.x-rt/0017-timers-Use-static-keys-for-migrate_enable-nohz_activ.patch b/kernel/patches-4.14.x-rt/0017-timers-Use-static-keys-for-migrate_enable-nohz_activ.patch deleted file mode 100644 index 89bf063ef..000000000 --- a/kernel/patches-4.14.x-rt/0017-timers-Use-static-keys-for-migrate_enable-nohz_activ.patch +++ /dev/null @@ -1,287 +0,0 @@ -From 7d3e8471f6d634b971ed483bf0fe0e3f426a799c Mon Sep 17 00:00:00 2001 -From: Thomas Gleixner -Date: Wed, 20 Dec 2017 17:12:50 +0100 -Subject: [PATCH 017/450] timers: Use static keys for - migrate_enable/nohz_active - -The members migrate_enable and nohz_active in the timer/hrtimer per CPU -bases have been introduced to avoid accessing global variables for these -decisions. - -Still that results in a (cache hot) load and conditional branch, which can -be avoided by using static keys. - -Implement it with static keys and optimize for the most critical case of -high performance networking which tends to disable the timer migration -functionality. - -Signed-off-by: Thomas Gleixner -Signed-off-by: Anna-Maria Gleixner -Signed-off-by: Sebastian Andrzej Siewior ---- - include/linux/hrtimer.h | 4 -- - kernel/time/hrtimer.c | 17 +++----- - kernel/time/tick-internal.h | 19 +++++---- - kernel/time/tick-sched.c | 2 +- - kernel/time/timer.c | 83 +++++++++++++++++++------------------ - 5 files changed, 61 insertions(+), 64 deletions(-) - -diff --git a/include/linux/hrtimer.h b/include/linux/hrtimer.h -index 012c37fdb688..79b2a8d29d8c 100644 ---- a/include/linux/hrtimer.h -+++ b/include/linux/hrtimer.h -@@ -153,8 +153,6 @@ enum hrtimer_base_type { - * @cpu: cpu number - * @active_bases: Bitfield to mark bases with active timers - * @clock_was_set_seq: Sequence counter of clock was set events -- * @migration_enabled: The migration of hrtimers to other cpus is enabled -- * @nohz_active: The nohz functionality is enabled - * @expires_next: absolute time of the next event which was scheduled - * via clock_set_next_event() - * @next_timer: Pointer to the first expiring timer -@@ -178,8 +176,6 @@ struct hrtimer_cpu_base { - unsigned int cpu; - unsigned int active_bases; - unsigned int clock_was_set_seq; -- bool migration_enabled; -- bool nohz_active; - #ifdef CONFIG_HIGH_RES_TIMERS - unsigned int in_hrtirq : 1, - hres_active : 1, -diff --git a/kernel/time/hrtimer.c b/kernel/time/hrtimer.c -index d00e85ac10d6..883fef2926e9 100644 ---- a/kernel/time/hrtimer.c -+++ b/kernel/time/hrtimer.c -@@ -178,23 +178,16 @@ hrtimer_check_target(struct hrtimer *timer, struct hrtimer_clock_base *new_base) - #endif - } - --#ifdef CONFIG_NO_HZ_COMMON --static inline --struct hrtimer_cpu_base *get_target_base(struct hrtimer_cpu_base *base, -- int pinned) --{ -- if (pinned || !base->migration_enabled) -- return base; -- return &per_cpu(hrtimer_bases, get_nohz_timer_target()); --} --#else - static inline - struct hrtimer_cpu_base *get_target_base(struct hrtimer_cpu_base *base, - int pinned) - { -+#if defined(CONFIG_SMP) && defined(CONFIG_NO_HZ_COMMON) -+ if (static_branch_unlikely(&timers_migration_enabled) && !pinned) -+ return &per_cpu(hrtimer_bases, get_nohz_timer_target()); -+#endif - return base; - } --#endif - - /* - * We switch the timer base to a power-optimized selected CPU target, -@@ -973,7 +966,7 @@ void hrtimer_start_range_ns(struct hrtimer *timer, ktime_t tim, - * Kick to reschedule the next tick to handle the new timer - * on dynticks target. - */ -- if (new_base->cpu_base->nohz_active) -+ if (is_timers_nohz_active()) - wake_up_nohz_cpu(new_base->cpu_base->cpu); - } else { - hrtimer_reprogram(timer, new_base); -diff --git a/kernel/time/tick-internal.h b/kernel/time/tick-internal.h -index f8e1845aa464..4ac74dff59f0 100644 ---- a/kernel/time/tick-internal.h -+++ b/kernel/time/tick-internal.h -@@ -150,14 +150,19 @@ static inline void tick_nohz_init(void) { } - - #ifdef CONFIG_NO_HZ_COMMON - extern unsigned long tick_nohz_active; --#else -+extern void timers_update_nohz(void); -+extern struct static_key_false timers_nohz_active; -+static inline bool is_timers_nohz_active(void) -+{ -+ return static_branch_unlikely(&timers_nohz_active); -+} -+# ifdef CONFIG_SMP -+extern struct static_key_false timers_migration_enabled; -+# endif -+#else /* CONFIG_NO_HZ_COMMON */ -+static inline void timers_update_nohz(void) { } - #define tick_nohz_active (0) --#endif -- --#if defined(CONFIG_SMP) && defined(CONFIG_NO_HZ_COMMON) --extern void timers_update_migration(bool update_nohz); --#else --static inline void timers_update_migration(bool update_nohz) { } -+static inline bool is_timers_nohz_active(void) { return false; } - #endif - - DECLARE_PER_CPU(struct hrtimer_cpu_base, hrtimer_bases); -diff --git a/kernel/time/tick-sched.c b/kernel/time/tick-sched.c -index a8fa0a896b78..67e2b79b6a9b 100644 ---- a/kernel/time/tick-sched.c -+++ b/kernel/time/tick-sched.c -@@ -1132,7 +1132,7 @@ static inline void tick_nohz_activate(struct tick_sched *ts, int mode) - ts->nohz_mode = mode; - /* One update is enough */ - if (!test_and_set_bit(0, &tick_nohz_active)) -- timers_update_migration(true); -+ timers_update_nohz(); - } - - /** -diff --git a/kernel/time/timer.c b/kernel/time/timer.c -index f17c76a1a05f..9b644e70b660 100644 ---- a/kernel/time/timer.c -+++ b/kernel/time/timer.c -@@ -200,8 +200,6 @@ struct timer_base { - unsigned long clk; - unsigned long next_expiry; - unsigned int cpu; -- bool migration_enabled; -- bool nohz_active; - bool is_idle; - bool must_forward_clk; - DECLARE_BITMAP(pending_map, WHEEL_SIZE); -@@ -210,45 +208,59 @@ struct timer_base { - - static DEFINE_PER_CPU(struct timer_base, timer_bases[NR_BASES]); - --#if defined(CONFIG_SMP) && defined(CONFIG_NO_HZ_COMMON) -+#ifdef CONFIG_NO_HZ_COMMON -+ -+DEFINE_STATIC_KEY_FALSE(timers_nohz_active); -+static DEFINE_MUTEX(timer_keys_mutex); -+ -+static void timer_update_keys(struct work_struct *work); -+static DECLARE_WORK(timer_update_work, timer_update_keys); -+ -+#ifdef CONFIG_SMP - unsigned int sysctl_timer_migration = 1; - --void timers_update_migration(bool update_nohz) -+DEFINE_STATIC_KEY_FALSE(timers_migration_enabled); -+ -+static void timers_update_migration(void) - { - bool on = sysctl_timer_migration && tick_nohz_active; -- unsigned int cpu; - -- /* Avoid the loop, if nothing to update */ -- if (this_cpu_read(timer_bases[BASE_STD].migration_enabled) == on) -- return; -+ if (on) -+ static_branch_enable(&timers_migration_enabled); -+ else -+ static_branch_disable(&timers_migration_enabled); -+} -+#else -+static inline void timers_update_migration(void) { } -+#endif /* !CONFIG_SMP */ - -- for_each_possible_cpu(cpu) { -- per_cpu(timer_bases[BASE_STD].migration_enabled, cpu) = on; -- per_cpu(timer_bases[BASE_DEF].migration_enabled, cpu) = on; -- per_cpu(hrtimer_bases.migration_enabled, cpu) = on; -- if (!update_nohz) -- continue; -- per_cpu(timer_bases[BASE_STD].nohz_active, cpu) = true; -- per_cpu(timer_bases[BASE_DEF].nohz_active, cpu) = true; -- per_cpu(hrtimer_bases.nohz_active, cpu) = true; -- } -+static void timer_update_keys(struct work_struct *work) -+{ -+ mutex_lock(&timer_keys_mutex); -+ timers_update_migration(); -+ static_branch_enable(&timers_nohz_active); -+ mutex_unlock(&timer_keys_mutex); -+} -+ -+void timers_update_nohz(void) -+{ -+ schedule_work(&timer_update_work); - } - - int timer_migration_handler(struct ctl_table *table, int write, - void __user *buffer, size_t *lenp, - loff_t *ppos) - { -- static DEFINE_MUTEX(mutex); - int ret; - -- mutex_lock(&mutex); -+ mutex_lock(&timer_keys_mutex); - ret = proc_dointvec_minmax(table, write, buffer, lenp, ppos); - if (!ret && write) -- timers_update_migration(false); -- mutex_unlock(&mutex); -+ timers_update_migration(); -+ mutex_unlock(&timer_keys_mutex); - return ret; - } --#endif -+#endif /* NO_HZ_COMMON */ - - static unsigned long round_jiffies_common(unsigned long j, int cpu, - bool force_up) -@@ -534,7 +546,7 @@ __internal_add_timer(struct timer_base *base, struct timer_list *timer) - static void - trigger_dyntick_cpu(struct timer_base *base, struct timer_list *timer) - { -- if (!IS_ENABLED(CONFIG_NO_HZ_COMMON) || !base->nohz_active) -+ if (!is_timers_nohz_active()) - return; - - /* -@@ -840,21 +852,20 @@ static inline struct timer_base *get_timer_base(u32 tflags) - return get_timer_cpu_base(tflags, tflags & TIMER_CPUMASK); - } - --#ifdef CONFIG_NO_HZ_COMMON - static inline struct timer_base * - get_target_base(struct timer_base *base, unsigned tflags) - { --#ifdef CONFIG_SMP -- if ((tflags & TIMER_PINNED) || !base->migration_enabled) -- return get_timer_this_cpu_base(tflags); -- return get_timer_cpu_base(tflags, get_nohz_timer_target()); --#else -- return get_timer_this_cpu_base(tflags); -+#if defined(CONFIG_SMP) && defined(CONFIG_NO_HZ_COMMON) -+ if (static_branch_unlikely(&timers_migration_enabled) && -+ !(tflags & TIMER_PINNED)) -+ return get_timer_cpu_base(tflags, get_nohz_timer_target()); - #endif -+ return get_timer_this_cpu_base(tflags); - } - - static inline void forward_timer_base(struct timer_base *base) - { -+#ifdef CONFIG_NO_HZ_COMMON - unsigned long jnow; - - /* -@@ -878,16 +889,8 @@ static inline void forward_timer_base(struct timer_base *base) - base->clk = jnow; - else - base->clk = base->next_expiry; --} --#else --static inline struct timer_base * --get_target_base(struct timer_base *base, unsigned tflags) --{ -- return get_timer_this_cpu_base(tflags); --} -- --static inline void forward_timer_base(struct timer_base *base) { } - #endif -+} - - - /* --- -2.19.2 - diff --git a/kernel/patches-4.14.x-rt/0018-hrtimer-Correct-blantanly-wrong-comment.patch b/kernel/patches-4.14.x-rt/0018-hrtimer-Correct-blantanly-wrong-comment.patch deleted file mode 100644 index 4e90b7615..000000000 --- a/kernel/patches-4.14.x-rt/0018-hrtimer-Correct-blantanly-wrong-comment.patch +++ /dev/null @@ -1,42 +0,0 @@ -From 0032a44f1d407ce2c142b3493bb6f2bb60158896 Mon Sep 17 00:00:00 2001 -From: Thomas Gleixner -Date: Wed, 20 Dec 2017 17:12:51 +0100 -Subject: [PATCH 018/450] hrtimer: Correct blantanly wrong comment - -The protection of a hrtimer which runs its callback against migration to a -different CPU has nothing to do with hard interrupt context. - -The protection against migration of a hrtimer running the expiry callback -is the pointer in the cpu_base which holds a pointer to the currently -running timer. This pointer is evaluated in the code which potentially -switches the timer base and makes sure it's kept on the CPU on which the -callback is running. - -Reported-by: Anna-Maria Gleixner -Signed-off-by: Thomas Gleixner -Signed-off-by: Anna-Maria Gleixner -Signed-off-by: Sebastian Andrzej Siewior ---- - kernel/time/hrtimer.c | 6 +++--- - 1 file changed, 3 insertions(+), 3 deletions(-) - -diff --git a/kernel/time/hrtimer.c b/kernel/time/hrtimer.c -index 883fef2926e9..65543d31af32 100644 ---- a/kernel/time/hrtimer.c -+++ b/kernel/time/hrtimer.c -@@ -1204,9 +1204,9 @@ static void __run_hrtimer(struct hrtimer_cpu_base *cpu_base, - timer->is_rel = false; - - /* -- * Because we run timers from hardirq context, there is no chance -- * they get migrated to another cpu, therefore its safe to unlock -- * the timer base. -+ * The timer is marked as running in the cpu base, so it is -+ * protected against migration to a different CPU even if the lock -+ * is dropped. - */ - raw_spin_unlock(&cpu_base->lock); - trace_hrtimer_expire_entry(timer, now); --- -2.19.2 - diff --git a/kernel/patches-4.14.x-rt/0019-hrtimer-Fix-kerneldoc-for-struct-hrtimer_cpu_base.patch b/kernel/patches-4.14.x-rt/0019-hrtimer-Fix-kerneldoc-for-struct-hrtimer_cpu_base.patch deleted file mode 100644 index 151f6d4b9..000000000 --- a/kernel/patches-4.14.x-rt/0019-hrtimer-Fix-kerneldoc-for-struct-hrtimer_cpu_base.patch +++ /dev/null @@ -1,48 +0,0 @@ -From 514d5cebbbc72530f555551b1edbf7908bb3bf2d Mon Sep 17 00:00:00 2001 -From: Anna-Maria Gleixner -Date: Wed, 20 Dec 2017 17:12:52 +0100 -Subject: [PATCH 019/450] hrtimer: Fix kerneldoc for struct hrtimer_cpu_base - -The sequence '/**' marks the start of a struct description. Add the -missing second asterisk. While at it adapt the ordering of the struct -members to the struct definition and document the purpose of -expires_next more precisely. - -Signed-off-by: Anna-Maria Gleixner -Signed-off-by: Sebastian Andrzej Siewior ---- - include/linux/hrtimer.h | 8 ++++---- - 1 file changed, 4 insertions(+), 4 deletions(-) - -diff --git a/include/linux/hrtimer.h b/include/linux/hrtimer.h -index 79b2a8d29d8c..b3a382be8db0 100644 ---- a/include/linux/hrtimer.h -+++ b/include/linux/hrtimer.h -@@ -144,7 +144,7 @@ enum hrtimer_base_type { - HRTIMER_MAX_CLOCK_BASES, - }; - --/* -+/** - * struct hrtimer_cpu_base - the per cpu clock bases - * @lock: lock protecting the base and associated clock bases - * and timers -@@ -153,12 +153,12 @@ enum hrtimer_base_type { - * @cpu: cpu number - * @active_bases: Bitfield to mark bases with active timers - * @clock_was_set_seq: Sequence counter of clock was set events -- * @expires_next: absolute time of the next event which was scheduled -- * via clock_set_next_event() -- * @next_timer: Pointer to the first expiring timer - * @in_hrtirq: hrtimer_interrupt() is currently executing - * @hres_active: State of high resolution mode - * @hang_detected: The last hrtimer interrupt detected a hang -+ * @expires_next: absolute time of the next event, is required for remote -+ * hrtimer enqueue -+ * @next_timer: Pointer to the first expiring timer - * @nr_events: Total number of hrtimer interrupt events - * @nr_retries: Total number of hrtimer interrupt retries - * @nr_hangs: Total number of hrtimer interrupt hangs --- -2.19.2 - diff --git a/kernel/patches-4.14.x-rt/0020-hrtimer-Cleanup-clock-argument-in-schedule_hrtimeout.patch b/kernel/patches-4.14.x-rt/0020-hrtimer-Cleanup-clock-argument-in-schedule_hrtimeout.patch deleted file mode 100644 index 03ebba941..000000000 --- a/kernel/patches-4.14.x-rt/0020-hrtimer-Cleanup-clock-argument-in-schedule_hrtimeout.patch +++ /dev/null @@ -1,88 +0,0 @@ -From 88f3615b960b07d71c6fb2c6a14075be7e9099b4 Mon Sep 17 00:00:00 2001 -From: Anna-Maria Gleixner -Date: Wed, 20 Dec 2017 17:12:53 +0100 -Subject: [PATCH 020/450] hrtimer: Cleanup clock argument in - schedule_hrtimeout_range_clock() - -schedule_hrtimeout_range_clock() uses an integer for the clock id -instead of the predefined type "clockid_t". The ID of the clock is -indicated in hrtimer code as clock_id. Therefore change the name of -the variable as well to make it consistent. - -While at it, clean up the description for the function parameters clock_id -and mode. The clock modes and the clock ids are not restricted as the -comment suggests. Fix the mode description as well for the callers of -schedule_hrtimeout_range_clock(). - -No functional change. - -Signed-off-by: Anna-Maria Gleixner -Signed-off-by: Sebastian Andrzej Siewior ---- - include/linux/hrtimer.h | 2 +- - kernel/time/hrtimer.c | 12 ++++++------ - 2 files changed, 7 insertions(+), 7 deletions(-) - -diff --git a/include/linux/hrtimer.h b/include/linux/hrtimer.h -index b3a382be8db0..931ce9c89c93 100644 ---- a/include/linux/hrtimer.h -+++ b/include/linux/hrtimer.h -@@ -462,7 +462,7 @@ extern int schedule_hrtimeout_range(ktime_t *expires, u64 delta, - extern int schedule_hrtimeout_range_clock(ktime_t *expires, - u64 delta, - const enum hrtimer_mode mode, -- int clock); -+ clockid_t clock_id); - extern int schedule_hrtimeout(ktime_t *expires, const enum hrtimer_mode mode); - - /* Soft interrupt function to run the hrtimer queues: */ -diff --git a/kernel/time/hrtimer.c b/kernel/time/hrtimer.c -index 65543d31af32..790841b59433 100644 ---- a/kernel/time/hrtimer.c -+++ b/kernel/time/hrtimer.c -@@ -1672,12 +1672,12 @@ void __init hrtimers_init(void) - * schedule_hrtimeout_range_clock - sleep until timeout - * @expires: timeout value (ktime_t) - * @delta: slack in expires timeout (ktime_t) -- * @mode: timer mode, HRTIMER_MODE_ABS or HRTIMER_MODE_REL -- * @clock: timer clock, CLOCK_MONOTONIC or CLOCK_REALTIME -+ * @mode: timer mode -+ * @clock_id: timer clock to be used - */ - int __sched - schedule_hrtimeout_range_clock(ktime_t *expires, u64 delta, -- const enum hrtimer_mode mode, int clock) -+ const enum hrtimer_mode mode, clockid_t clock_id) - { - struct hrtimer_sleeper t; - -@@ -1698,7 +1698,7 @@ schedule_hrtimeout_range_clock(ktime_t *expires, u64 delta, - return -EINTR; - } - -- hrtimer_init_on_stack(&t.timer, clock, mode); -+ hrtimer_init_on_stack(&t.timer, clock_id, mode); - hrtimer_set_expires_range_ns(&t.timer, *expires, delta); - - hrtimer_init_sleeper(&t, current); -@@ -1720,7 +1720,7 @@ schedule_hrtimeout_range_clock(ktime_t *expires, u64 delta, - * schedule_hrtimeout_range - sleep until timeout - * @expires: timeout value (ktime_t) - * @delta: slack in expires timeout (ktime_t) -- * @mode: timer mode, HRTIMER_MODE_ABS or HRTIMER_MODE_REL -+ * @mode: timer mode - * - * Make the current task sleep until the given expiry time has - * elapsed. The routine will return immediately unless -@@ -1759,7 +1759,7 @@ EXPORT_SYMBOL_GPL(schedule_hrtimeout_range); - /** - * schedule_hrtimeout - sleep until timeout - * @expires: timeout value (ktime_t) -- * @mode: timer mode, HRTIMER_MODE_ABS or HRTIMER_MODE_REL -+ * @mode: timer mode - * - * Make the current task sleep until the given expiry time has - * elapsed. The routine will return immediately unless --- -2.19.2 - diff --git a/kernel/patches-4.14.x-rt/0021-hrtimer-Fix-hrtimer-function-description.patch b/kernel/patches-4.14.x-rt/0021-hrtimer-Fix-hrtimer-function-description.patch deleted file mode 100644 index 295997db6..000000000 --- a/kernel/patches-4.14.x-rt/0021-hrtimer-Fix-hrtimer-function-description.patch +++ /dev/null @@ -1,68 +0,0 @@ -From 0a6e7eb400a68467d21993bd9ec87b43fc871411 Mon Sep 17 00:00:00 2001 -From: Anna-Maria Gleixner -Date: Wed, 20 Dec 2017 17:12:54 +0100 -Subject: [PATCH 021/450] hrtimer: Fix hrtimer function description - -The hrtimer_start[_range_ns]() starts a timer reliable on this CPU only -when HRTIMER_MODE_PINNED is set. Furthermore the HRTIMER_MODE_PINNED mode -is not considered, when a hrtimer is initialized. - -Signed-off-by: Anna-Maria Gleixner -Signed-off-by: Sebastian Andrzej Siewior ---- - include/linux/hrtimer.h | 6 +++--- - kernel/time/hrtimer.c | 9 +++++---- - 2 files changed, 8 insertions(+), 7 deletions(-) - -diff --git a/include/linux/hrtimer.h b/include/linux/hrtimer.h -index 931ce9c89c93..4e6a8841dcbe 100644 ---- a/include/linux/hrtimer.h -+++ b/include/linux/hrtimer.h -@@ -361,11 +361,11 @@ extern void hrtimer_start_range_ns(struct hrtimer *timer, ktime_t tim, - u64 range_ns, const enum hrtimer_mode mode); - - /** -- * hrtimer_start - (re)start an hrtimer on the current CPU -+ * hrtimer_start - (re)start an hrtimer - * @timer: the timer to be added - * @tim: expiry time -- * @mode: expiry mode: absolute (HRTIMER_MODE_ABS) or -- * relative (HRTIMER_MODE_REL) -+ * @mode: timer mode: absolute (HRTIMER_MODE_ABS) or -+ * relative (HRTIMER_MODE_REL), and pinned (HRTIMER_MODE_PINNED) - */ - static inline void hrtimer_start(struct hrtimer *timer, ktime_t tim, - const enum hrtimer_mode mode) -diff --git a/kernel/time/hrtimer.c b/kernel/time/hrtimer.c -index 790841b59433..6460aa2d9b25 100644 ---- a/kernel/time/hrtimer.c -+++ b/kernel/time/hrtimer.c -@@ -928,12 +928,12 @@ static inline ktime_t hrtimer_update_lowres(struct hrtimer *timer, ktime_t tim, - } - - /** -- * hrtimer_start_range_ns - (re)start an hrtimer on the current CPU -+ * hrtimer_start_range_ns - (re)start an hrtimer - * @timer: the timer to be added - * @tim: expiry time - * @delta_ns: "slack" range for the timer -- * @mode: expiry mode: absolute (HRTIMER_MODE_ABS) or -- * relative (HRTIMER_MODE_REL) -+ * @mode: timer mode: absolute (HRTIMER_MODE_ABS) or -+ * relative (HRTIMER_MODE_REL), and pinned (HRTIMER_MODE_PINNED) - */ - void hrtimer_start_range_ns(struct hrtimer *timer, ktime_t tim, - u64 delta_ns, const enum hrtimer_mode mode) -@@ -1116,7 +1116,8 @@ static void __hrtimer_init(struct hrtimer *timer, clockid_t clock_id, - * hrtimer_init - initialize a timer to the given clock - * @timer: the timer to be initialized - * @clock_id: the clock to be used -- * @mode: timer mode abs/rel -+ * @mode: timer mode: absolute (HRTIMER_MODE_ABS) or -+ * relative (HRTIMER_MODE_REL); pinned is not considered here! - */ - void hrtimer_init(struct hrtimer *timer, clockid_t clock_id, - enum hrtimer_mode mode) --- -2.19.2 - diff --git a/kernel/patches-4.14.x-rt/0022-hrtimer-Cleanup-hrtimer_mode-enum.patch b/kernel/patches-4.14.x-rt/0022-hrtimer-Cleanup-hrtimer_mode-enum.patch deleted file mode 100644 index 69c169e99..000000000 --- a/kernel/patches-4.14.x-rt/0022-hrtimer-Cleanup-hrtimer_mode-enum.patch +++ /dev/null @@ -1,51 +0,0 @@ -From c70a78a159599bbc711e49f8d1d44a978d7fd6da Mon Sep 17 00:00:00 2001 -From: Anna-Maria Gleixner -Date: Wed, 20 Dec 2017 17:12:56 +0100 -Subject: [PATCH 022/450] hrtimer: Cleanup hrtimer_mode enum - -It's not obvious that the HRTIMER_MODE variants are bit combinations -because all modes are hard coded constants. - -Change it so the bit meanings are clear and use the symbols for creating -modes which combine bits. - -While at it get rid of the ugly tail comments. - -Signed-off-by: Anna-Maria Gleixner -Signed-off-by: Sebastian Andrzej Siewior ---- - include/linux/hrtimer.h | 16 +++++++++++----- - 1 file changed, 11 insertions(+), 5 deletions(-) - -diff --git a/include/linux/hrtimer.h b/include/linux/hrtimer.h -index 4e6a8841dcbe..28f267cf2851 100644 ---- a/include/linux/hrtimer.h -+++ b/include/linux/hrtimer.h -@@ -28,13 +28,19 @@ struct hrtimer_cpu_base; - - /* - * Mode arguments of xxx_hrtimer functions: -+ * -+ * HRTIMER_MODE_ABS - Time value is absolute -+ * HRTIMER_MODE_REL - Time value is relative to now -+ * HRTIMER_MODE_PINNED - Timer is bound to CPU (is only considered -+ * when starting the timer) - */ - enum hrtimer_mode { -- HRTIMER_MODE_ABS = 0x0, /* Time value is absolute */ -- HRTIMER_MODE_REL = 0x1, /* Time value is relative to now */ -- HRTIMER_MODE_PINNED = 0x02, /* Timer is bound to CPU */ -- HRTIMER_MODE_ABS_PINNED = 0x02, -- HRTIMER_MODE_REL_PINNED = 0x03, -+ HRTIMER_MODE_ABS = 0x00, -+ HRTIMER_MODE_REL = 0x01, -+ HRTIMER_MODE_PINNED = 0x02, -+ -+ HRTIMER_MODE_ABS_PINNED = HRTIMER_MODE_ABS | HRTIMER_MODE_PINNED, -+ HRTIMER_MODE_REL_PINNED = HRTIMER_MODE_REL | HRTIMER_MODE_PINNED, - }; - - /* --- -2.19.2 - diff --git a/kernel/patches-4.14.x-rt/0023-tracing-hrtimer-Print-hrtimer-mode-in-hrtimer_start-.patch b/kernel/patches-4.14.x-rt/0023-tracing-hrtimer-Print-hrtimer-mode-in-hrtimer_start-.patch deleted file mode 100644 index 2c69f182d..000000000 --- a/kernel/patches-4.14.x-rt/0023-tracing-hrtimer-Print-hrtimer-mode-in-hrtimer_start-.patch +++ /dev/null @@ -1,121 +0,0 @@ -From 539a7faf8c0ee647ec65c88ab187f9200c8878cf Mon Sep 17 00:00:00 2001 -From: Anna-Maria Gleixner -Date: Wed, 20 Dec 2017 17:12:58 +0100 -Subject: [PATCH 023/450] tracing/hrtimer: Print hrtimer mode in hrtimer_start - tracepoint - -The hrtimer_start tracepoint lacks the mode information. The mode is -important because consecutive starts can switch from ABS to REL or from -PINNED to non PINNED. - -Add the mode information. - -Signed-off-by: Anna-Maria Gleixner -Signed-off-by: Sebastian Andrzej Siewior ---- - include/trace/events/timer.h | 13 ++++++++----- - kernel/time/hrtimer.c | 16 +++++++++------- - 2 files changed, 17 insertions(+), 12 deletions(-) - -diff --git a/include/trace/events/timer.h b/include/trace/events/timer.h -index c6f728037c53..744b4310b24b 100644 ---- a/include/trace/events/timer.h -+++ b/include/trace/events/timer.h -@@ -186,15 +186,16 @@ TRACE_EVENT(hrtimer_init, - */ - TRACE_EVENT(hrtimer_start, - -- TP_PROTO(struct hrtimer *hrtimer), -+ TP_PROTO(struct hrtimer *hrtimer, enum hrtimer_mode mode), - -- TP_ARGS(hrtimer), -+ TP_ARGS(hrtimer, mode), - - TP_STRUCT__entry( - __field( void *, hrtimer ) - __field( void *, function ) - __field( s64, expires ) - __field( s64, softexpires ) -+ __field( enum hrtimer_mode, mode ) - ), - - TP_fast_assign( -@@ -202,12 +203,14 @@ TRACE_EVENT(hrtimer_start, - __entry->function = hrtimer->function; - __entry->expires = hrtimer_get_expires(hrtimer); - __entry->softexpires = hrtimer_get_softexpires(hrtimer); -+ __entry->mode = mode; - ), - -- TP_printk("hrtimer=%p function=%pf expires=%llu softexpires=%llu", -- __entry->hrtimer, __entry->function, -+ TP_printk("hrtimer=%p function=%pf expires=%llu softexpires=%llu " -+ "mode=%s", __entry->hrtimer, __entry->function, - (unsigned long long) __entry->expires, -- (unsigned long long) __entry->softexpires) -+ (unsigned long long) __entry->softexpires, -+ decode_hrtimer_mode(__entry->mode)) - ); - - /** -diff --git a/kernel/time/hrtimer.c b/kernel/time/hrtimer.c -index 6460aa2d9b25..476fe683e8ed 100644 ---- a/kernel/time/hrtimer.c -+++ b/kernel/time/hrtimer.c -@@ -435,10 +435,11 @@ debug_init(struct hrtimer *timer, clockid_t clockid, - trace_hrtimer_init(timer, clockid, mode); - } - --static inline void debug_activate(struct hrtimer *timer) -+static inline void debug_activate(struct hrtimer *timer, -+ enum hrtimer_mode mode) - { - debug_hrtimer_activate(timer); -- trace_hrtimer_start(timer); -+ trace_hrtimer_start(timer, mode); - } - - static inline void debug_deactivate(struct hrtimer *timer) -@@ -832,9 +833,10 @@ EXPORT_SYMBOL_GPL(hrtimer_forward); - * Returns 1 when the new timer is the leftmost timer in the tree. - */ - static int enqueue_hrtimer(struct hrtimer *timer, -- struct hrtimer_clock_base *base) -+ struct hrtimer_clock_base *base, -+ enum hrtimer_mode mode) - { -- debug_activate(timer); -+ debug_activate(timer, mode); - - base->cpu_base->active_bases |= 1 << base->index; - -@@ -957,7 +959,7 @@ void hrtimer_start_range_ns(struct hrtimer *timer, ktime_t tim, - /* Switch the timer base, if necessary: */ - new_base = switch_hrtimer_base(timer, base, mode & HRTIMER_MODE_PINNED); - -- leftmost = enqueue_hrtimer(timer, new_base); -+ leftmost = enqueue_hrtimer(timer, new_base, mode); - if (!leftmost) - goto unlock; - -@@ -1226,7 +1228,7 @@ static void __run_hrtimer(struct hrtimer_cpu_base *cpu_base, - */ - if (restart != HRTIMER_NORESTART && - !(timer->state & HRTIMER_STATE_ENQUEUED)) -- enqueue_hrtimer(timer, base); -+ enqueue_hrtimer(timer, base, HRTIMER_MODE_ABS); - - /* - * Separate the ->running assignment from the ->state assignment. -@@ -1626,7 +1628,7 @@ static void migrate_hrtimer_list(struct hrtimer_clock_base *old_base, - * sort out already expired timers and reprogram the - * event device. - */ -- enqueue_hrtimer(timer, new_base); -+ enqueue_hrtimer(timer, new_base, HRTIMER_MODE_ABS); - } - } - --- -2.19.2 - diff --git a/kernel/patches-4.14.x-rt/0024-hrtimer-Switch-for-loop-to-_ffs-evaluation.patch b/kernel/patches-4.14.x-rt/0024-hrtimer-Switch-for-loop-to-_ffs-evaluation.patch deleted file mode 100644 index dc73367d9..000000000 --- a/kernel/patches-4.14.x-rt/0024-hrtimer-Switch-for-loop-to-_ffs-evaluation.patch +++ /dev/null @@ -1,90 +0,0 @@ -From bb3a1b059ac7a6e2ada2d4045a8a18a125627e65 Mon Sep 17 00:00:00 2001 -From: Anna-Maria Gleixner -Date: Wed, 20 Dec 2017 17:12:59 +0100 -Subject: [PATCH 024/450] hrtimer: Switch for loop to _ffs() evaluation - -Looping over all clock bases to find active bits is suboptimal if not all -bases are active. - -Avoid this by converting it to a __ffs() evaluation. The functionallity is -outsourced into an own function and is called via a macro as suggested by -Peter Zijlstra. - -Suggested-by: Peter Zijlstra -Signed-off-by: Anna-Maria Gleixner -Signed-off-by: Sebastian Andrzej Siewior ---- - kernel/time/hrtimer.c | 31 +++++++++++++++++++++---------- - 1 file changed, 21 insertions(+), 10 deletions(-) - -diff --git a/kernel/time/hrtimer.c b/kernel/time/hrtimer.c -index 476fe683e8ed..85f9335d0d60 100644 ---- a/kernel/time/hrtimer.c -+++ b/kernel/time/hrtimer.c -@@ -448,6 +448,23 @@ static inline void debug_deactivate(struct hrtimer *timer) - trace_hrtimer_cancel(timer); - } - -+static struct hrtimer_clock_base * -+__next_base(struct hrtimer_cpu_base *cpu_base, unsigned int *active) -+{ -+ unsigned int idx; -+ -+ if (!*active) -+ return NULL; -+ -+ idx = __ffs(*active); -+ *active &= ~(1U << idx); -+ -+ return &cpu_base->clock_base[idx]; -+} -+ -+#define for_each_active_base(base, cpu_base, active) \ -+ while ((base = __next_base((cpu_base), &(active)))) -+ - #if defined(CONFIG_NO_HZ_COMMON) || defined(CONFIG_HIGH_RES_TIMERS) - static inline void hrtimer_update_next_timer(struct hrtimer_cpu_base *cpu_base, - struct hrtimer *timer) -@@ -459,18 +476,15 @@ static inline void hrtimer_update_next_timer(struct hrtimer_cpu_base *cpu_base, - - static ktime_t __hrtimer_get_next_event(struct hrtimer_cpu_base *cpu_base) - { -- struct hrtimer_clock_base *base = cpu_base->clock_base; -+ struct hrtimer_clock_base *base; - unsigned int active = cpu_base->active_bases; - ktime_t expires, expires_next = KTIME_MAX; - - hrtimer_update_next_timer(cpu_base, NULL); -- for (; active; base++, active >>= 1) { -+ for_each_active_base(base, cpu_base, active) { - struct timerqueue_node *next; - struct hrtimer *timer; - -- if (!(active & 0x01)) -- continue; -- - next = timerqueue_getnext(&base->active); - timer = container_of(next, struct hrtimer, node); - expires = ktime_sub(hrtimer_get_expires(timer), base->offset); -@@ -1245,16 +1259,13 @@ static void __run_hrtimer(struct hrtimer_cpu_base *cpu_base, - - static void __hrtimer_run_queues(struct hrtimer_cpu_base *cpu_base, ktime_t now) - { -- struct hrtimer_clock_base *base = cpu_base->clock_base; -+ struct hrtimer_clock_base *base; - unsigned int active = cpu_base->active_bases; - -- for (; active; base++, active >>= 1) { -+ for_each_active_base(base, cpu_base, active) { - struct timerqueue_node *node; - ktime_t basenow; - -- if (!(active & 0x01)) -- continue; -- - basenow = ktime_add(now, base->offset); - - while ((node = timerqueue_getnext(&base->active))) { --- -2.19.2 - diff --git a/kernel/patches-4.14.x-rt/0025-hrtimer-Store-running-timer-in-hrtimer_clock_base.patch b/kernel/patches-4.14.x-rt/0025-hrtimer-Store-running-timer-in-hrtimer_clock_base.patch deleted file mode 100644 index 120b06d7e..000000000 --- a/kernel/patches-4.14.x-rt/0025-hrtimer-Store-running-timer-in-hrtimer_clock_base.patch +++ /dev/null @@ -1,199 +0,0 @@ -From 06c6f558d3e8182d49a68dd3cafa56d771e0aa30 Mon Sep 17 00:00:00 2001 -From: Anna-Maria Gleixner -Date: Wed, 20 Dec 2017 17:13:00 +0100 -Subject: [PATCH 025/450] hrtimer: Store running timer in hrtimer_clock_base - -The pointer to the currently running timer is stored in hrtimer_cpu_base -before the base lock is dropped and the callback is invoked. - -This results in two levels of indirections and the upcoming support for -softirq based hrtimer requires splitting the "running" storage into soft -and hard irq context expiry. - -Storing both in the cpu base would require conditionals in all code paths -accessing that information. - -It's possible to have a per clock base sequence count and running pointer -without changing the semantics of the related mechanisms because the timer -base pointer cannot be changed while a timer is running the callback. - -Unfortunately this makes cpu_clock base larger than 32 bytes on 32bit -kernels. Instead of having huge gaps due to alignment, remove the alignment -and let the compiler pack cpu base for 32bit. The resulting cache access -patterns are fortunately not really different from the current -behaviour. On 64bit kernels the 64byte alignment stays and the behaviour is -unchanged. This was determined by analyzing the resulting layout and -looking at the number of cache lines involved for the frequently used -clocks. - -Signed-off-by: Anna-Maria Gleixner -Signed-off-by: Sebastian Andrzej Siewior ---- - include/linux/hrtimer.h | 20 +++++++++----------- - kernel/time/hrtimer.c | 28 +++++++++++++--------------- - 2 files changed, 22 insertions(+), 26 deletions(-) - -diff --git a/include/linux/hrtimer.h b/include/linux/hrtimer.h -index 28f267cf2851..1bae7b9f071d 100644 ---- a/include/linux/hrtimer.h -+++ b/include/linux/hrtimer.h -@@ -118,9 +118,9 @@ struct hrtimer_sleeper { - }; - - #ifdef CONFIG_64BIT --# define HRTIMER_CLOCK_BASE_ALIGN 64 -+# define __hrtimer_clock_base_align ____cacheline_aligned - #else --# define HRTIMER_CLOCK_BASE_ALIGN 32 -+# define __hrtimer_clock_base_align - #endif - - /** -@@ -129,18 +129,22 @@ struct hrtimer_sleeper { - * @index: clock type index for per_cpu support when moving a - * timer to a base on another cpu. - * @clockid: clock id for per_cpu support -+ * @seq: seqcount around __run_hrtimer -+ * @running: pointer to the currently running hrtimer - * @active: red black tree root node for the active timers - * @get_time: function to retrieve the current time of the clock - * @offset: offset of this clock to the monotonic base - */ - struct hrtimer_clock_base { - struct hrtimer_cpu_base *cpu_base; -- int index; -+ unsigned int index; - clockid_t clockid; -+ seqcount_t seq; -+ struct hrtimer *running; - struct timerqueue_head active; - ktime_t (*get_time)(void); - ktime_t offset; --} __attribute__((__aligned__(HRTIMER_CLOCK_BASE_ALIGN))); -+} __hrtimer_clock_base_align; - - enum hrtimer_base_type { - HRTIMER_BASE_MONOTONIC, -@@ -154,8 +158,6 @@ enum hrtimer_base_type { - * struct hrtimer_cpu_base - the per cpu clock bases - * @lock: lock protecting the base and associated clock bases - * and timers -- * @seq: seqcount around __run_hrtimer -- * @running: pointer to the currently running hrtimer - * @cpu: cpu number - * @active_bases: Bitfield to mark bases with active timers - * @clock_was_set_seq: Sequence counter of clock was set events -@@ -177,8 +179,6 @@ enum hrtimer_base_type { - */ - struct hrtimer_cpu_base { - raw_spinlock_t lock; -- seqcount_t seq; -- struct hrtimer *running; - unsigned int cpu; - unsigned int active_bases; - unsigned int clock_was_set_seq; -@@ -198,8 +198,6 @@ struct hrtimer_cpu_base { - - static inline void hrtimer_set_expires(struct hrtimer *timer, ktime_t time) - { -- BUILD_BUG_ON(sizeof(struct hrtimer_clock_base) > HRTIMER_CLOCK_BASE_ALIGN); -- - timer->node.expires = time; - timer->_softexpires = time; - } -@@ -424,7 +422,7 @@ static inline int hrtimer_is_queued(struct hrtimer *timer) - */ - static inline int hrtimer_callback_running(struct hrtimer *timer) - { -- return timer->base->cpu_base->running == timer; -+ return timer->base->running == timer; - } - - /* Forward a hrtimer so it expires after now: */ -diff --git a/kernel/time/hrtimer.c b/kernel/time/hrtimer.c -index 85f9335d0d60..bedfc2865901 100644 ---- a/kernel/time/hrtimer.c -+++ b/kernel/time/hrtimer.c -@@ -70,7 +70,6 @@ - DEFINE_PER_CPU(struct hrtimer_cpu_base, hrtimer_bases) = - { - .lock = __RAW_SPIN_LOCK_UNLOCKED(hrtimer_bases.lock), -- .seq = SEQCNT_ZERO(hrtimer_bases.seq), - .clock_base = - { - { -@@ -118,7 +117,6 @@ static const int hrtimer_clock_to_base_table[MAX_CLOCKS] = { - * timer->base->cpu_base - */ - static struct hrtimer_cpu_base migration_cpu_base = { -- .seq = SEQCNT_ZERO(migration_cpu_base), - .clock_base = { { .cpu_base = &migration_cpu_base, }, }, - }; - -@@ -1152,19 +1150,19 @@ EXPORT_SYMBOL_GPL(hrtimer_init); - */ - bool hrtimer_active(const struct hrtimer *timer) - { -- struct hrtimer_cpu_base *cpu_base; -+ struct hrtimer_clock_base *base; - unsigned int seq; - - do { -- cpu_base = READ_ONCE(timer->base->cpu_base); -- seq = raw_read_seqcount_begin(&cpu_base->seq); -+ base = READ_ONCE(timer->base); -+ seq = raw_read_seqcount_begin(&base->seq); - - if (timer->state != HRTIMER_STATE_INACTIVE || -- cpu_base->running == timer) -+ base->running == timer) - return true; - -- } while (read_seqcount_retry(&cpu_base->seq, seq) || -- cpu_base != READ_ONCE(timer->base->cpu_base)); -+ } while (read_seqcount_retry(&base->seq, seq) || -+ base != READ_ONCE(timer->base)); - - return false; - } -@@ -1198,16 +1196,16 @@ static void __run_hrtimer(struct hrtimer_cpu_base *cpu_base, - lockdep_assert_held(&cpu_base->lock); - - debug_deactivate(timer); -- cpu_base->running = timer; -+ base->running = timer; - - /* - * Separate the ->running assignment from the ->state assignment. - * - * As with a regular write barrier, this ensures the read side in -- * hrtimer_active() cannot observe cpu_base->running == NULL && -+ * hrtimer_active() cannot observe base->running == NULL && - * timer->state == INACTIVE. - */ -- raw_write_seqcount_barrier(&cpu_base->seq); -+ raw_write_seqcount_barrier(&base->seq); - - __remove_hrtimer(timer, base, HRTIMER_STATE_INACTIVE, 0); - fn = timer->function; -@@ -1248,13 +1246,13 @@ static void __run_hrtimer(struct hrtimer_cpu_base *cpu_base, - * Separate the ->running assignment from the ->state assignment. - * - * As with a regular write barrier, this ensures the read side in -- * hrtimer_active() cannot observe cpu_base->running == NULL && -+ * hrtimer_active() cannot observe base->running.timer == NULL && - * timer->state == INACTIVE. - */ -- raw_write_seqcount_barrier(&cpu_base->seq); -+ raw_write_seqcount_barrier(&base->seq); - -- WARN_ON_ONCE(cpu_base->running != timer); -- cpu_base->running = NULL; -+ WARN_ON_ONCE(base->running != timer); -+ base->running = NULL; - } - - static void __hrtimer_run_queues(struct hrtimer_cpu_base *cpu_base, ktime_t now) --- -2.19.2 - diff --git a/kernel/patches-4.14.x-rt/0026-hrtimer-Make-room-in-struct-hrtimer_cpu_base.patch b/kernel/patches-4.14.x-rt/0026-hrtimer-Make-room-in-struct-hrtimer_cpu_base.patch deleted file mode 100644 index d4dae8d3c..000000000 --- a/kernel/patches-4.14.x-rt/0026-hrtimer-Make-room-in-struct-hrtimer_cpu_base.patch +++ /dev/null @@ -1,39 +0,0 @@ -From 848a963465a750a46dd6554f18ff5593d8b9cbda Mon Sep 17 00:00:00 2001 -From: Anna-Maria Gleixner -Date: Wed, 20 Dec 2017 17:13:01 +0100 -Subject: [PATCH 026/450] hrtimer: Make room in struct hrtimer_cpu_base - -The upcoming softirq based hrtimers support requires an additional field in -the hrtimer_cpu_base struct, which would grow the struct size beyond a -cache line. - -The struct members nr_retries and nr_hangs of hrtimer_cpu_base are solely -used for diagnostic output and have no requirement to be unsigned int. - -Make them unsigned short to create room for the new struct member. No -functional change. - -Signed-off-by: Anna-Maria Gleixner -Signed-off-by: Sebastian Andrzej Siewior ---- - include/linux/hrtimer.h | 4 ++-- - 1 file changed, 2 insertions(+), 2 deletions(-) - -diff --git a/include/linux/hrtimer.h b/include/linux/hrtimer.h -index 1bae7b9f071d..56e56bcb6f0f 100644 ---- a/include/linux/hrtimer.h -+++ b/include/linux/hrtimer.h -@@ -189,8 +189,8 @@ struct hrtimer_cpu_base { - ktime_t expires_next; - struct hrtimer *next_timer; - unsigned int nr_events; -- unsigned int nr_retries; -- unsigned int nr_hangs; -+ unsigned short nr_retries; -+ unsigned short nr_hangs; - unsigned int max_hang_time; - #endif - struct hrtimer_clock_base clock_base[HRTIMER_MAX_CLOCK_BASES]; --- -2.19.2 - diff --git a/kernel/patches-4.14.x-rt/0027-hrtimer-Reduce-conditional-code-hres_active.patch b/kernel/patches-4.14.x-rt/0027-hrtimer-Reduce-conditional-code-hres_active.patch deleted file mode 100644 index b23d7814a..000000000 --- a/kernel/patches-4.14.x-rt/0027-hrtimer-Reduce-conditional-code-hres_active.patch +++ /dev/null @@ -1,157 +0,0 @@ -From ae9cbcb83bcfc4a83965378438eca2a1ca78afc9 Mon Sep 17 00:00:00 2001 -From: Anna-Maria Gleixner -Date: Wed, 20 Dec 2017 17:13:02 +0100 -Subject: [PATCH 027/450] hrtimer: Reduce conditional code (hres_active) - -The hrtimer_cpu_base struct has the CONFIG_HIGH_RES_TIMERS conditional -struct member hres_active. All related functions to this member are -conditional as well. - -There is no functional change, when the hres_active member is -unconditional with all related functions and is set to zero during -initialization. - -The conditional code sections can be avoided by adding IS_ENABLED(HIGHRES) -conditionals into common functions, which ensures dead code elimination. - -Suggested-by: Thomas Gleixner -Signed-off-by: Anna-Maria Gleixner -Signed-off-by: Sebastian Andrzej Siewior ---- - include/linux/hrtimer.h | 20 ++++++++------------ - kernel/time/hrtimer.c | 31 +++++++++++++++---------------- - 2 files changed, 23 insertions(+), 28 deletions(-) - -diff --git a/include/linux/hrtimer.h b/include/linux/hrtimer.h -index 56e56bcb6f0f..22627b3a33fe 100644 ---- a/include/linux/hrtimer.h -+++ b/include/linux/hrtimer.h -@@ -161,8 +161,8 @@ enum hrtimer_base_type { - * @cpu: cpu number - * @active_bases: Bitfield to mark bases with active timers - * @clock_was_set_seq: Sequence counter of clock was set events -- * @in_hrtirq: hrtimer_interrupt() is currently executing - * @hres_active: State of high resolution mode -+ * @in_hrtirq: hrtimer_interrupt() is currently executing - * @hang_detected: The last hrtimer interrupt detected a hang - * @expires_next: absolute time of the next event, is required for remote - * hrtimer enqueue -@@ -182,9 +182,9 @@ struct hrtimer_cpu_base { - unsigned int cpu; - unsigned int active_bases; - unsigned int clock_was_set_seq; -+ unsigned int hres_active : 1; - #ifdef CONFIG_HIGH_RES_TIMERS - unsigned int in_hrtirq : 1, -- hres_active : 1, - hang_detected : 1; - ktime_t expires_next; - struct hrtimer *next_timer; -@@ -266,16 +266,17 @@ static inline ktime_t hrtimer_cb_get_time(struct hrtimer *timer) - return timer->base->get_time(); - } - -+static inline int hrtimer_is_hres_active(struct hrtimer *timer) -+{ -+ return IS_ENABLED(CONFIG_HIGH_RES_TIMERS) ? -+ timer->base->cpu_base->hres_active : 0; -+} -+ - #ifdef CONFIG_HIGH_RES_TIMERS - struct clock_event_device; - - extern void hrtimer_interrupt(struct clock_event_device *dev); - --static inline int hrtimer_is_hres_active(struct hrtimer *timer) --{ -- return timer->base->cpu_base->hres_active; --} -- - /* - * The resolution of the clocks. The resolution value is returned in - * the clock_getres() system call to give application programmers an -@@ -298,11 +299,6 @@ extern unsigned int hrtimer_resolution; - - #define hrtimer_resolution (unsigned int)LOW_RES_NSEC - --static inline int hrtimer_is_hres_active(struct hrtimer *timer) --{ -- return 0; --} -- - static inline void clock_was_set_delayed(void) { } - - #endif -diff --git a/kernel/time/hrtimer.c b/kernel/time/hrtimer.c -index bedfc2865901..7e0490143275 100644 ---- a/kernel/time/hrtimer.c -+++ b/kernel/time/hrtimer.c -@@ -512,6 +512,20 @@ static inline ktime_t hrtimer_update_base(struct hrtimer_cpu_base *base) - offs_real, offs_boot, offs_tai); - } - -+/* -+ * Is the high resolution mode active ? -+ */ -+static inline int __hrtimer_hres_active(struct hrtimer_cpu_base *cpu_base) -+{ -+ return IS_ENABLED(CONFIG_HIGH_RES_TIMERS) ? -+ cpu_base->hres_active : 0; -+} -+ -+static inline int hrtimer_hres_active(void) -+{ -+ return __hrtimer_hres_active(this_cpu_ptr(&hrtimer_bases)); -+} -+ - /* High resolution timer related functions */ - #ifdef CONFIG_HIGH_RES_TIMERS - -@@ -540,19 +554,6 @@ static inline int hrtimer_is_hres_enabled(void) - return hrtimer_hres_enabled; - } - --/* -- * Is the high resolution mode active ? -- */ --static inline int __hrtimer_hres_active(struct hrtimer_cpu_base *cpu_base) --{ -- return cpu_base->hres_active; --} -- --static inline int hrtimer_hres_active(void) --{ -- return __hrtimer_hres_active(this_cpu_ptr(&hrtimer_bases)); --} -- - /* - * Reprogram the event source with checking both queues for the - * next event -@@ -662,7 +663,6 @@ static inline void hrtimer_init_hres(struct hrtimer_cpu_base *base) - { - base->expires_next = KTIME_MAX; - base->hang_detected = 0; -- base->hres_active = 0; - base->next_timer = NULL; - } - -@@ -722,8 +722,6 @@ void clock_was_set_delayed(void) - - #else - --static inline int __hrtimer_hres_active(struct hrtimer_cpu_base *b) { return 0; } --static inline int hrtimer_hres_active(void) { return 0; } - static inline int hrtimer_is_hres_enabled(void) { return 0; } - static inline void hrtimer_switch_to_hres(void) { } - static inline void -@@ -1605,6 +1603,7 @@ int hrtimers_prepare_cpu(unsigned int cpu) - - cpu_base->active_bases = 0; - cpu_base->cpu = cpu; -+ cpu_base->hres_active = 0; - hrtimer_init_hres(cpu_base); - return 0; - } --- -2.19.2 - diff --git a/kernel/patches-4.14.x-rt/0028-hrtimer-Use-accesor-functions-instead-of-direct-acce.patch b/kernel/patches-4.14.x-rt/0028-hrtimer-Use-accesor-functions-instead-of-direct-acce.patch deleted file mode 100644 index afae85d0d..000000000 --- a/kernel/patches-4.14.x-rt/0028-hrtimer-Use-accesor-functions-instead-of-direct-acce.patch +++ /dev/null @@ -1,42 +0,0 @@ -From b978729a14b5b64461840a95d386fe545dae0924 Mon Sep 17 00:00:00 2001 -From: Anna-Maria Gleixner -Date: Wed, 20 Dec 2017 17:13:03 +0100 -Subject: [PATCH 028/450] hrtimer: Use accesor functions instead of direct - access - -__hrtimer_hres_active() is now available unconditionally. Replace the -direct access to hrtimer_cpu_base.hres_active. - -No functional change. - -Signed-off-by: Anna-Maria Gleixner -Signed-off-by: Sebastian Andrzej Siewior ---- - kernel/time/hrtimer.c | 4 ++-- - 1 file changed, 2 insertions(+), 2 deletions(-) - -diff --git a/kernel/time/hrtimer.c b/kernel/time/hrtimer.c -index 7e0490143275..85882d5da523 100644 ---- a/kernel/time/hrtimer.c -+++ b/kernel/time/hrtimer.c -@@ -564,7 +564,7 @@ hrtimer_force_reprogram(struct hrtimer_cpu_base *cpu_base, int skip_equal) - { - ktime_t expires_next; - -- if (!cpu_base->hres_active) -+ if (!__hrtimer_hres_active(cpu_base)) - return; - - expires_next = __hrtimer_get_next_event(cpu_base); -@@ -675,7 +675,7 @@ static void retrigger_next_event(void *arg) - { - struct hrtimer_cpu_base *base = this_cpu_ptr(&hrtimer_bases); - -- if (!base->hres_active) -+ if (!__hrtimer_hres_active(base)) - return; - - raw_spin_lock(&base->lock); --- -2.19.2 - diff --git a/kernel/patches-4.14.x-rt/0029-hrtimer-Make-the-remote-enqueue-check-unconditional.patch b/kernel/patches-4.14.x-rt/0029-hrtimer-Make-the-remote-enqueue-check-unconditional.patch deleted file mode 100644 index 763baf6e3..000000000 --- a/kernel/patches-4.14.x-rt/0029-hrtimer-Make-the-remote-enqueue-check-unconditional.patch +++ /dev/null @@ -1,144 +0,0 @@ -From b5cd9c9539b8a050c5c9806e54aa9b295215ba00 Mon Sep 17 00:00:00 2001 -From: Anna-Maria Gleixner -Date: Wed, 20 Dec 2017 17:13:04 +0100 -Subject: [PATCH 029/450] hrtimer: Make the remote enqueue check unconditional - -hrtimer_cpu_base.expires_next is used to cache the next event armed in the -timer hardware. The value is used to check whether an hrtimer can be -enqueued remotely. If the new hrtimer is expiring before expires_next, then -remote enqueue is not possible as the remote hrtimer hardware cannot be -accessed for reprogramming to an earlier expiry time. - -The remote enqueue check is currently conditional on -CONFIG_HIGH_RES_TIMERS=y and hrtimer_cpu_base.hres_active. There is no -compelling reason to make this conditional. - -Move hrtimer_cpu_base.expires_next out of the CONFIG_HIGH_RES_TIMERS=y -guarded area and remove the conditionals in hrtimer_check_target(). - -The check is currently a NOOP for the CONFIG_HIGH_RES_TIMERS=n and the -!hrtimer_cpu_base.hres_active case because in these cases nothing updates -hrtimer_cpu_base.expires_next yet. This will be changed with later patches -which further reduce the #ifdef zoo in this code. - -Signed-off-by: Anna-Maria Gleixner -Signed-off-by: Sebastian Andrzej Siewior ---- - include/linux/hrtimer.h | 6 +++--- - kernel/time/hrtimer.c | 32 +++++++++----------------------- - 2 files changed, 12 insertions(+), 26 deletions(-) - -diff --git a/include/linux/hrtimer.h b/include/linux/hrtimer.h -index 22627b3a33fe..bb7270e8bc37 100644 ---- a/include/linux/hrtimer.h -+++ b/include/linux/hrtimer.h -@@ -164,13 +164,13 @@ enum hrtimer_base_type { - * @hres_active: State of high resolution mode - * @in_hrtirq: hrtimer_interrupt() is currently executing - * @hang_detected: The last hrtimer interrupt detected a hang -- * @expires_next: absolute time of the next event, is required for remote -- * hrtimer enqueue - * @next_timer: Pointer to the first expiring timer - * @nr_events: Total number of hrtimer interrupt events - * @nr_retries: Total number of hrtimer interrupt retries - * @nr_hangs: Total number of hrtimer interrupt hangs - * @max_hang_time: Maximum time spent in hrtimer_interrupt -+ * @expires_next: absolute time of the next event, is required for remote -+ * hrtimer enqueue - * @clock_base: array of clock bases for this cpu - * - * Note: next_timer is just an optimization for __remove_hrtimer(). -@@ -186,13 +186,13 @@ struct hrtimer_cpu_base { - #ifdef CONFIG_HIGH_RES_TIMERS - unsigned int in_hrtirq : 1, - hang_detected : 1; -- ktime_t expires_next; - struct hrtimer *next_timer; - unsigned int nr_events; - unsigned short nr_retries; - unsigned short nr_hangs; - unsigned int max_hang_time; - #endif -+ ktime_t expires_next; - struct hrtimer_clock_base clock_base[HRTIMER_MAX_CLOCK_BASES]; - } ____cacheline_aligned; - -diff --git a/kernel/time/hrtimer.c b/kernel/time/hrtimer.c -index 85882d5da523..b1016aabc73a 100644 ---- a/kernel/time/hrtimer.c -+++ b/kernel/time/hrtimer.c -@@ -154,26 +154,21 @@ struct hrtimer_clock_base *lock_hrtimer_base(const struct hrtimer *timer, - } - - /* -- * With HIGHRES=y we do not migrate the timer when it is expiring -- * before the next event on the target cpu because we cannot reprogram -- * the target cpu hardware and we would cause it to fire late. -+ * We do not migrate the timer when it is expiring before the next -+ * event on the target cpu. When high resolution is enabled, we cannot -+ * reprogram the target cpu hardware and we would cause it to fire -+ * late. To keep it simple, we handle the high resolution enabled and -+ * disabled case similar. - * - * Called with cpu_base->lock of target cpu held. - */ - static int - hrtimer_check_target(struct hrtimer *timer, struct hrtimer_clock_base *new_base) - { --#ifdef CONFIG_HIGH_RES_TIMERS - ktime_t expires; - -- if (!new_base->cpu_base->hres_active) -- return 0; -- - expires = ktime_sub(hrtimer_get_expires(timer), new_base->offset); - return expires <= new_base->cpu_base->expires_next; --#else -- return 0; --#endif - } - - static inline -@@ -656,16 +651,6 @@ static void hrtimer_reprogram(struct hrtimer *timer, - tick_program_event(expires, 1); - } - --/* -- * Initialize the high resolution related parts of cpu_base -- */ --static inline void hrtimer_init_hres(struct hrtimer_cpu_base *base) --{ -- base->expires_next = KTIME_MAX; -- base->hang_detected = 0; -- base->next_timer = NULL; --} -- - /* - * Retrigger next event is called after clock was set - * -@@ -731,7 +716,6 @@ static inline int hrtimer_reprogram(struct hrtimer *timer, - { - return 0; - } --static inline void hrtimer_init_hres(struct hrtimer_cpu_base *base) { } - static inline void retrigger_next_event(void *arg) { } - - #endif /* CONFIG_HIGH_RES_TIMERS */ -@@ -1601,10 +1585,12 @@ int hrtimers_prepare_cpu(unsigned int cpu) - timerqueue_init_head(&cpu_base->clock_base[i].active); - } - -- cpu_base->active_bases = 0; - cpu_base->cpu = cpu; -+ cpu_base->active_bases = 0; - cpu_base->hres_active = 0; -- hrtimer_init_hres(cpu_base); -+ cpu_base->hang_detected = 0; -+ cpu_base->next_timer = NULL; -+ cpu_base->expires_next = KTIME_MAX; - return 0; - } - --- -2.19.2 - diff --git a/kernel/patches-4.14.x-rt/0030-hrtimer-Make-hrtimer_cpu_base.next_timer-handling-un.patch b/kernel/patches-4.14.x-rt/0030-hrtimer-Make-hrtimer_cpu_base.next_timer-handling-un.patch deleted file mode 100644 index 96bff3be8..000000000 --- a/kernel/patches-4.14.x-rt/0030-hrtimer-Make-hrtimer_cpu_base.next_timer-handling-un.patch +++ /dev/null @@ -1,105 +0,0 @@ -From 63efcc991a5d6b098605ccdb9a2223f6afbd8602 Mon Sep 17 00:00:00 2001 -From: Anna-Maria Gleixner -Date: Wed, 20 Dec 2017 17:13:05 +0100 -Subject: [PATCH 030/450] hrtimer: Make hrtimer_cpu_base.next_timer handling - unconditional - -hrtimer_cpu_base.next_timer stores the pointer to the next expiring timer -in a cpu base. - -This pointer cannot be dereferenced and is solely used to check whether a -hrtimer which is removed is the hrtimer which is the first to expire in the -CPU base. If this is the case, then the timer hardware needs to be -reprogrammed to avoid an extra interrupt for nothing. - -Again, this is conditional functionality, but there is no compelling reason -to make this conditional. As a preparation, hrtimer_cpu_base.next_timer -needs to be available unconditonal. Aside of that the upcoming support for -softirq based hrtimers requires access to this pointer unconditionally. - -Make the update of hrtimer_cpu_base.next_timer unconditional and remove the -ifdef cruft. The impact on CONFIG_HIGH_RES_TIMERS=n && CONFIG_NOHZ=n is -marginal as it's just a store on an already dirtied cacheline. - -No functional change. - -Signed-off-by: Anna-Maria Gleixner -Signed-off-by: Sebastian Andrzej Siewior ---- - include/linux/hrtimer.h | 4 ++-- - kernel/time/hrtimer.c | 12 ++---------- - 2 files changed, 4 insertions(+), 12 deletions(-) - -diff --git a/include/linux/hrtimer.h b/include/linux/hrtimer.h -index bb7270e8bc37..2d3e1d678a4d 100644 ---- a/include/linux/hrtimer.h -+++ b/include/linux/hrtimer.h -@@ -164,13 +164,13 @@ enum hrtimer_base_type { - * @hres_active: State of high resolution mode - * @in_hrtirq: hrtimer_interrupt() is currently executing - * @hang_detected: The last hrtimer interrupt detected a hang -- * @next_timer: Pointer to the first expiring timer - * @nr_events: Total number of hrtimer interrupt events - * @nr_retries: Total number of hrtimer interrupt retries - * @nr_hangs: Total number of hrtimer interrupt hangs - * @max_hang_time: Maximum time spent in hrtimer_interrupt - * @expires_next: absolute time of the next event, is required for remote - * hrtimer enqueue -+ * @next_timer: Pointer to the first expiring timer - * @clock_base: array of clock bases for this cpu - * - * Note: next_timer is just an optimization for __remove_hrtimer(). -@@ -186,13 +186,13 @@ struct hrtimer_cpu_base { - #ifdef CONFIG_HIGH_RES_TIMERS - unsigned int in_hrtirq : 1, - hang_detected : 1; -- struct hrtimer *next_timer; - unsigned int nr_events; - unsigned short nr_retries; - unsigned short nr_hangs; - unsigned int max_hang_time; - #endif - ktime_t expires_next; -+ struct hrtimer *next_timer; - struct hrtimer_clock_base clock_base[HRTIMER_MAX_CLOCK_BASES]; - } ____cacheline_aligned; - -diff --git a/kernel/time/hrtimer.c b/kernel/time/hrtimer.c -index b1016aabc73a..e01c2e78c032 100644 ---- a/kernel/time/hrtimer.c -+++ b/kernel/time/hrtimer.c -@@ -459,21 +459,13 @@ __next_base(struct hrtimer_cpu_base *cpu_base, unsigned int *active) - while ((base = __next_base((cpu_base), &(active)))) - - #if defined(CONFIG_NO_HZ_COMMON) || defined(CONFIG_HIGH_RES_TIMERS) --static inline void hrtimer_update_next_timer(struct hrtimer_cpu_base *cpu_base, -- struct hrtimer *timer) --{ --#ifdef CONFIG_HIGH_RES_TIMERS -- cpu_base->next_timer = timer; --#endif --} -- - static ktime_t __hrtimer_get_next_event(struct hrtimer_cpu_base *cpu_base) - { - struct hrtimer_clock_base *base; - unsigned int active = cpu_base->active_bases; - ktime_t expires, expires_next = KTIME_MAX; - -- hrtimer_update_next_timer(cpu_base, NULL); -+ cpu_base->next_timer = NULL; - for_each_active_base(base, cpu_base, active) { - struct timerqueue_node *next; - struct hrtimer *timer; -@@ -483,7 +475,7 @@ static ktime_t __hrtimer_get_next_event(struct hrtimer_cpu_base *cpu_base) - expires = ktime_sub(hrtimer_get_expires(timer), base->offset); - if (expires < expires_next) { - expires_next = expires; -- hrtimer_update_next_timer(cpu_base, timer); -+ cpu_base->next_timer = timer; - } - } - /* --- -2.19.2 - diff --git a/kernel/patches-4.14.x-rt/0031-hrtimer-Make-hrtimer_reprogramm-unconditional.patch b/kernel/patches-4.14.x-rt/0031-hrtimer-Make-hrtimer_reprogramm-unconditional.patch deleted file mode 100644 index c248c8f08..000000000 --- a/kernel/patches-4.14.x-rt/0031-hrtimer-Make-hrtimer_reprogramm-unconditional.patch +++ /dev/null @@ -1,193 +0,0 @@ -From 259346e29614e27a84c4e3cbcbe6a26e61ad56eb Mon Sep 17 00:00:00 2001 -From: Anna-Maria Gleixner -Date: Wed, 20 Dec 2017 17:13:06 +0100 -Subject: [PATCH 031/450] hrtimer: Make hrtimer_reprogramm() unconditional - -hrtimer_reprogram() needs to be available unconditionally for softirq based -hrtimers. Move the function and all required struct members out of the -CONFIG_HIGH_RES_TIMERS #ifdef. - -There is no functional change because hrtimer_reprogram() is only invoked -when hrtimer_cpu_base.hres_active is true. Making it unconditional -increases the text size for the CONFIG_HIGH_RES_TIMERS=n case, but avoids -replication of that code for the upcoming softirq based hrtimers support. - -Signed-off-by: Anna-Maria Gleixner -Signed-off-by: Sebastian Andrzej Siewior ---- - include/linux/hrtimer.h | 6 +- - kernel/time/hrtimer.c | 129 +++++++++++++++++++--------------------- - 2 files changed, 65 insertions(+), 70 deletions(-) - -diff --git a/include/linux/hrtimer.h b/include/linux/hrtimer.h -index 2d3e1d678a4d..98ed35767ac5 100644 ---- a/include/linux/hrtimer.h -+++ b/include/linux/hrtimer.h -@@ -182,10 +182,10 @@ struct hrtimer_cpu_base { - unsigned int cpu; - unsigned int active_bases; - unsigned int clock_was_set_seq; -- unsigned int hres_active : 1; --#ifdef CONFIG_HIGH_RES_TIMERS -- unsigned int in_hrtirq : 1, -+ unsigned int hres_active : 1, -+ in_hrtirq : 1, - hang_detected : 1; -+#ifdef CONFIG_HIGH_RES_TIMERS - unsigned int nr_events; - unsigned short nr_retries; - unsigned short nr_hangs; -diff --git a/kernel/time/hrtimer.c b/kernel/time/hrtimer.c -index e01c2e78c032..37085a13f19a 100644 ---- a/kernel/time/hrtimer.c -+++ b/kernel/time/hrtimer.c -@@ -581,68 +581,6 @@ hrtimer_force_reprogram(struct hrtimer_cpu_base *cpu_base, int skip_equal) - tick_program_event(cpu_base->expires_next, 1); - } - --/* -- * When a timer is enqueued and expires earlier than the already enqueued -- * timers, we have to check, whether it expires earlier than the timer for -- * which the clock event device was armed. -- * -- * Called with interrupts disabled and base->cpu_base.lock held -- */ --static void hrtimer_reprogram(struct hrtimer *timer, -- struct hrtimer_clock_base *base) --{ -- struct hrtimer_cpu_base *cpu_base = this_cpu_ptr(&hrtimer_bases); -- ktime_t expires = ktime_sub(hrtimer_get_expires(timer), base->offset); -- -- WARN_ON_ONCE(hrtimer_get_expires_tv64(timer) < 0); -- -- /* -- * If the timer is not on the current cpu, we cannot reprogram -- * the other cpus clock event device. -- */ -- if (base->cpu_base != cpu_base) -- return; -- -- /* -- * If the hrtimer interrupt is running, then it will -- * reevaluate the clock bases and reprogram the clock event -- * device. The callbacks are always executed in hard interrupt -- * context so we don't need an extra check for a running -- * callback. -- */ -- if (cpu_base->in_hrtirq) -- return; -- -- /* -- * CLOCK_REALTIME timer might be requested with an absolute -- * expiry time which is less than base->offset. Set it to 0. -- */ -- if (expires < 0) -- expires = 0; -- -- if (expires >= cpu_base->expires_next) -- return; -- -- /* Update the pointer to the next expiring timer */ -- cpu_base->next_timer = timer; -- -- /* -- * If a hang was detected in the last timer interrupt then we -- * do not schedule a timer which is earlier than the expiry -- * which we enforced in the hang detection. We want the system -- * to make progress. -- */ -- if (cpu_base->hang_detected) -- return; -- -- /* -- * Program the timer hardware. We enforce the expiry for -- * events which are already in the past. -- */ -- cpu_base->expires_next = expires; -- tick_program_event(expires, 1); --} -- - /* - * Retrigger next event is called after clock was set - * -@@ -703,15 +641,72 @@ static inline int hrtimer_is_hres_enabled(void) { return 0; } - static inline void hrtimer_switch_to_hres(void) { } - static inline void - hrtimer_force_reprogram(struct hrtimer_cpu_base *base, int skip_equal) { } --static inline int hrtimer_reprogram(struct hrtimer *timer, -- struct hrtimer_clock_base *base) --{ -- return 0; --} - static inline void retrigger_next_event(void *arg) { } - - #endif /* CONFIG_HIGH_RES_TIMERS */ - -+/* -+ * When a timer is enqueued and expires earlier than the already enqueued -+ * timers, we have to check, whether it expires earlier than the timer for -+ * which the clock event device was armed. -+ * -+ * Called with interrupts disabled and base->cpu_base.lock held -+ */ -+static void hrtimer_reprogram(struct hrtimer *timer, -+ struct hrtimer_clock_base *base) -+{ -+ struct hrtimer_cpu_base *cpu_base = this_cpu_ptr(&hrtimer_bases); -+ ktime_t expires = ktime_sub(hrtimer_get_expires(timer), base->offset); -+ -+ WARN_ON_ONCE(hrtimer_get_expires_tv64(timer) < 0); -+ -+ /* -+ * If the timer is not on the current cpu, we cannot reprogram -+ * the other cpus clock event device. -+ */ -+ if (base->cpu_base != cpu_base) -+ return; -+ -+ /* -+ * If the hrtimer interrupt is running, then it will -+ * reevaluate the clock bases and reprogram the clock event -+ * device. The callbacks are always executed in hard interrupt -+ * context so we don't need an extra check for a running -+ * callback. -+ */ -+ if (cpu_base->in_hrtirq) -+ return; -+ -+ /* -+ * CLOCK_REALTIME timer might be requested with an absolute -+ * expiry time which is less than base->offset. Set it to 0. -+ */ -+ if (expires < 0) -+ expires = 0; -+ -+ if (expires >= cpu_base->expires_next) -+ return; -+ -+ /* Update the pointer to the next expiring timer */ -+ cpu_base->next_timer = timer; -+ -+ /* -+ * If a hang was detected in the last timer interrupt then we -+ * do not schedule a timer which is earlier than the expiry -+ * which we enforced in the hang detection. We want the system -+ * to make progress. -+ */ -+ if (cpu_base->hang_detected) -+ return; -+ -+ /* -+ * Program the timer hardware. We enforce the expiry for -+ * events which are already in the past. -+ */ -+ cpu_base->expires_next = expires; -+ tick_program_event(expires, 1); -+} -+ - /* - * Clock realtime was set - * --- -2.19.2 - diff --git a/kernel/patches-4.14.x-rt/0032-hrtimer-Make-hrtimer_force_reprogramm-unconditionall.patch b/kernel/patches-4.14.x-rt/0032-hrtimer-Make-hrtimer_force_reprogramm-unconditionall.patch deleted file mode 100644 index 5e521b1df..000000000 --- a/kernel/patches-4.14.x-rt/0032-hrtimer-Make-hrtimer_force_reprogramm-unconditionall.patch +++ /dev/null @@ -1,111 +0,0 @@ -From 24cd3845de20fd8fe195d0e9cc51e64669d39f1f Mon Sep 17 00:00:00 2001 -From: Anna-Maria Gleixner -Date: Wed, 20 Dec 2017 17:13:07 +0100 -Subject: [PATCH 032/450] hrtimer: Make hrtimer_force_reprogramm() - unconditionally available - -hrtimer_force_reprogram() needs to be available unconditionally for softirq -based hrtimers. Move the function and all required struct members out of -the CONFIG_HIGH_RES_TIMERS #ifdef. - -There is no functional change because hrtimer_force_reprogram() is only -invoked when hrtimer_cpu_base.hres_active is true and -CONFIG_HIGH_RES_TIMERS=y. - -Making it unconditional increases the text size for the -CONFIG_HIGH_RES_TIMERS=n case slightly, but avoids replication of that code -for the upcoming softirq based hrtimers support. Most of the code gets -eliminated in the CONFIG_HIGH_RES_TIMERS=n case by the compiler. - -Signed-off-by: Anna-Maria Gleixner -Signed-off-by: Sebastian Andrzej Siewior ---- - kernel/time/hrtimer.c | 58 +++++++++++++++++++++---------------------- - 1 file changed, 28 insertions(+), 30 deletions(-) - -diff --git a/kernel/time/hrtimer.c b/kernel/time/hrtimer.c -index 37085a13f19a..5fd669dd46be 100644 ---- a/kernel/time/hrtimer.c -+++ b/kernel/time/hrtimer.c -@@ -513,34 +513,6 @@ static inline int hrtimer_hres_active(void) - return __hrtimer_hres_active(this_cpu_ptr(&hrtimer_bases)); - } - --/* High resolution timer related functions */ --#ifdef CONFIG_HIGH_RES_TIMERS -- --/* -- * High resolution timer enabled ? -- */ --static bool hrtimer_hres_enabled __read_mostly = true; --unsigned int hrtimer_resolution __read_mostly = LOW_RES_NSEC; --EXPORT_SYMBOL_GPL(hrtimer_resolution); -- --/* -- * Enable / Disable high resolution mode -- */ --static int __init setup_hrtimer_hres(char *str) --{ -- return (kstrtobool(str, &hrtimer_hres_enabled) == 0); --} -- --__setup("highres=", setup_hrtimer_hres); -- --/* -- * hrtimer_high_res_enabled - query, if the highres mode is enabled -- */ --static inline int hrtimer_is_hres_enabled(void) --{ -- return hrtimer_hres_enabled; --} -- - /* - * Reprogram the event source with checking both queues for the - * next event -@@ -581,6 +553,34 @@ hrtimer_force_reprogram(struct hrtimer_cpu_base *cpu_base, int skip_equal) - tick_program_event(cpu_base->expires_next, 1); - } - -+/* High resolution timer related functions */ -+#ifdef CONFIG_HIGH_RES_TIMERS -+ -+/* -+ * High resolution timer enabled ? -+ */ -+static bool hrtimer_hres_enabled __read_mostly = true; -+unsigned int hrtimer_resolution __read_mostly = LOW_RES_NSEC; -+EXPORT_SYMBOL_GPL(hrtimer_resolution); -+ -+/* -+ * Enable / Disable high resolution mode -+ */ -+static int __init setup_hrtimer_hres(char *str) -+{ -+ return (kstrtobool(str, &hrtimer_hres_enabled) == 0); -+} -+ -+__setup("highres=", setup_hrtimer_hres); -+ -+/* -+ * hrtimer_high_res_enabled - query, if the highres mode is enabled -+ */ -+static inline int hrtimer_is_hres_enabled(void) -+{ -+ return hrtimer_hres_enabled; -+} -+ - /* - * Retrigger next event is called after clock was set - * -@@ -639,8 +639,6 @@ void clock_was_set_delayed(void) - - static inline int hrtimer_is_hres_enabled(void) { return 0; } - static inline void hrtimer_switch_to_hres(void) { } --static inline void --hrtimer_force_reprogram(struct hrtimer_cpu_base *base, int skip_equal) { } - static inline void retrigger_next_event(void *arg) { } - - #endif /* CONFIG_HIGH_RES_TIMERS */ --- -2.19.2 - diff --git a/kernel/patches-4.14.x-rt/0033-hrtimer-Unify-handling-of-hrtimer-remove.patch b/kernel/patches-4.14.x-rt/0033-hrtimer-Unify-handling-of-hrtimer-remove.patch deleted file mode 100644 index 1107b55f9..000000000 --- a/kernel/patches-4.14.x-rt/0033-hrtimer-Unify-handling-of-hrtimer-remove.patch +++ /dev/null @@ -1,94 +0,0 @@ -From e74c0793383b70b53c785a36f9dcdc7c8d3f6940 Mon Sep 17 00:00:00 2001 -From: Anna-Maria Gleixner -Date: Wed, 20 Dec 2017 17:13:08 +0100 -Subject: [PATCH 033/450] hrtimer: Unify handling of hrtimer remove - -When the first hrtimer on the current CPU is removed, -hrtimer_force_reprogram() is invoked but only when -CONFIG_HIGH_RES_TIMERS=y and hrtimer_cpu_base.hres_active is set. - -hrtimer_force_reprogram() updates hrtimer_cpu_base.expires_next and -reprograms the clock event device. When CONFIG_HIGH_RES_TIMERS=y and -hrtimer_cpu_base.hres_active is set, a pointless hrtimer interrupt can be -prevented. - -hrtimer_check_target() makes the 'can remote enqueue' decision. As soon as -hrtimer_check_target() is unconditionally available and -hrtimer_cpu_base.expires_next is updated by hrtimer_reprogram(), -hrtimer_force_reprogram() needs to be available unconditionally as well to -prevent the following scenario with CONFIG_HIGH_RES_TIMERS=n: - -- the first hrtimer on this CPU is removed and hrtimer_force_reprogram() is - not executed - -- CPU goes idle (next timer is calculated and hrtimers are taken into - account) - -- a hrtimer is enqueued remote on the idle CPU: hrtimer_check_target() - compares expiry value and hrtimer_cpu_base.expires_next. The expiry value - is after expires_next, so the hrtimer is enqueued. This timer will fire - late, if it expires before the effective first hrtimer on this CPU and - the comparison was with an outdated expires_next value. - -To prevent this scenario, make hrtimer_force_reprogram() unconditional -except the effective reprogramming part, which gets eliminated by the -compiler in the CONFIG_HIGH_RES_TIMERS=n case. - -Signed-off-by: Anna-Maria Gleixner -Signed-off-by: Sebastian Andrzej Siewior ---- - kernel/time/hrtimer.c | 10 ++++------ - 1 file changed, 4 insertions(+), 6 deletions(-) - -diff --git a/kernel/time/hrtimer.c b/kernel/time/hrtimer.c -index 5fd669dd46be..ce9a3ef7a796 100644 ---- a/kernel/time/hrtimer.c -+++ b/kernel/time/hrtimer.c -@@ -523,9 +523,6 @@ hrtimer_force_reprogram(struct hrtimer_cpu_base *cpu_base, int skip_equal) - { - ktime_t expires_next; - -- if (!__hrtimer_hres_active(cpu_base)) -- return; -- - expires_next = __hrtimer_get_next_event(cpu_base); - - if (skip_equal && expires_next == cpu_base->expires_next) -@@ -534,6 +531,9 @@ hrtimer_force_reprogram(struct hrtimer_cpu_base *cpu_base, int skip_equal) - cpu_base->expires_next = expires_next; - - /* -+ * If hres is not active, hardware does not have to be -+ * reprogrammed yet. -+ * - * If a hang was detected in the last timer interrupt then we - * leave the hang delay active in the hardware. We want the - * system to make progress. That also prevents the following -@@ -547,7 +547,7 @@ hrtimer_force_reprogram(struct hrtimer_cpu_base *cpu_base, int skip_equal) - * set. So we'd effectivly block all timers until the T2 event - * fires. - */ -- if (cpu_base->hang_detected) -+ if (!__hrtimer_hres_active(cpu_base) || cpu_base->hang_detected) - return; - - tick_program_event(cpu_base->expires_next, 1); -@@ -848,7 +848,6 @@ static void __remove_hrtimer(struct hrtimer *timer, - if (!timerqueue_del(&base->active, &timer->node)) - cpu_base->active_bases &= ~(1 << base->index); - --#ifdef CONFIG_HIGH_RES_TIMERS - /* - * Note: If reprogram is false we do not update - * cpu_base->next_timer. This happens when we remove the first -@@ -859,7 +858,6 @@ static void __remove_hrtimer(struct hrtimer *timer, - */ - if (reprogram && timer == cpu_base->next_timer) - hrtimer_force_reprogram(cpu_base, 1); --#endif - } - - /* --- -2.19.2 - diff --git a/kernel/patches-4.14.x-rt/0034-hrtimer-Unify-handling-of-remote-enqueue.patch b/kernel/patches-4.14.x-rt/0034-hrtimer-Unify-handling-of-remote-enqueue.patch deleted file mode 100644 index e542b1744..000000000 --- a/kernel/patches-4.14.x-rt/0034-hrtimer-Unify-handling-of-remote-enqueue.patch +++ /dev/null @@ -1,158 +0,0 @@ -From 8fb098ddff5d47a14a9a5843032b8e206c83ff7a Mon Sep 17 00:00:00 2001 -From: Anna-Maria Gleixner -Date: Wed, 20 Dec 2017 17:13:09 +0100 -Subject: [PATCH 034/450] hrtimer: Unify handling of remote enqueue - -hrtimer_reprogram() is conditionally invoked from hrtimer_start_range_ns() -when hrtimer_cpu_base.hres_active is true. - -In the !hres_active case there is a special condition for the nohz_active -case: - - If the newly enqueued timer expires before the first expiring timer on a - remote CPU then the remote CPU needs to be notified and woken up from a - NOHZ idle sleep to take the new first expiring timer into account. - -Previous changes have already established the prerequisites to make the -remote enqueue behaviour the same whether high resolution mode is active or -not: - - If the to be enqueued timer expires before the first expiring timer on a - remote CPU, then it cannot be enqueued there. - -This was done for the high resolution mode because there is no way to -access the remote CPU timer hardware. The same is true for NOHZ, but was -handled differently by unconditionally enqueuing the timer and waking up -the remote CPU so it can reprogram its timer. Again there is no compelling -reason for this difference. - -hrtimer_check_target(), which makes the 'can remote enqueue' decision is -already unconditional, but not yet functional because nothing updates -hrtimer_cpu_base.expires_next in the !hres_active case. - -To unify this the following changes are required: - - 1) Make the store of the new first expiry time unconditonal in - hrtimer_reprogram() and check __hrtimer_hres_active() before proceeding - to the actual hardware access. This check also lets the compiler - eliminate the rest of the function in case of CONFIG_HIGH_RES_TIMERS=n. - - 2) Invoke hrtimer_reprogram() unconditionally from - hrtimer_start_range_ns() - - 3) Remove the remote wakeup special case for the !high_res && nohz_active - case. - -Confine the timers_nohz_active static key to timer.c which is the only user -now. - -Signed-off-by: Anna-Maria Gleixner -Signed-off-by: Sebastian Andrzej Siewior ---- - kernel/time/hrtimer.c | 18 ++++++------------ - kernel/time/tick-internal.h | 6 ------ - kernel/time/timer.c | 9 ++++++++- - 3 files changed, 14 insertions(+), 19 deletions(-) - -diff --git a/kernel/time/hrtimer.c b/kernel/time/hrtimer.c -index ce9a3ef7a796..35d7d0c8c3d6 100644 ---- a/kernel/time/hrtimer.c -+++ b/kernel/time/hrtimer.c -@@ -687,21 +687,24 @@ static void hrtimer_reprogram(struct hrtimer *timer, - - /* Update the pointer to the next expiring timer */ - cpu_base->next_timer = timer; -+ cpu_base->expires_next = expires; - - /* -+ * If hres is not active, hardware does not have to be -+ * programmed yet. -+ * - * If a hang was detected in the last timer interrupt then we - * do not schedule a timer which is earlier than the expiry - * which we enforced in the hang detection. We want the system - * to make progress. - */ -- if (cpu_base->hang_detected) -+ if (!__hrtimer_hres_active(cpu_base) || cpu_base->hang_detected) - return; - - /* - * Program the timer hardware. We enforce the expiry for - * events which are already in the past. - */ -- cpu_base->expires_next = expires; - tick_program_event(expires, 1); - } - -@@ -940,16 +943,7 @@ void hrtimer_start_range_ns(struct hrtimer *timer, ktime_t tim, - if (!leftmost) - goto unlock; - -- if (!hrtimer_is_hres_active(timer)) { -- /* -- * Kick to reschedule the next tick to handle the new timer -- * on dynticks target. -- */ -- if (is_timers_nohz_active()) -- wake_up_nohz_cpu(new_base->cpu_base->cpu); -- } else { -- hrtimer_reprogram(timer, new_base); -- } -+ hrtimer_reprogram(timer, new_base); - unlock: - unlock_hrtimer_base(timer, &flags); - } -diff --git a/kernel/time/tick-internal.h b/kernel/time/tick-internal.h -index 4ac74dff59f0..e277284c2831 100644 ---- a/kernel/time/tick-internal.h -+++ b/kernel/time/tick-internal.h -@@ -151,18 +151,12 @@ static inline void tick_nohz_init(void) { } - #ifdef CONFIG_NO_HZ_COMMON - extern unsigned long tick_nohz_active; - extern void timers_update_nohz(void); --extern struct static_key_false timers_nohz_active; --static inline bool is_timers_nohz_active(void) --{ -- return static_branch_unlikely(&timers_nohz_active); --} - # ifdef CONFIG_SMP - extern struct static_key_false timers_migration_enabled; - # endif - #else /* CONFIG_NO_HZ_COMMON */ - static inline void timers_update_nohz(void) { } - #define tick_nohz_active (0) --static inline bool is_timers_nohz_active(void) { return false; } - #endif - - DECLARE_PER_CPU(struct hrtimer_cpu_base, hrtimer_bases); -diff --git a/kernel/time/timer.c b/kernel/time/timer.c -index 9b644e70b660..3b6c7e287f23 100644 ---- a/kernel/time/timer.c -+++ b/kernel/time/timer.c -@@ -210,7 +210,7 @@ static DEFINE_PER_CPU(struct timer_base, timer_bases[NR_BASES]); - - #ifdef CONFIG_NO_HZ_COMMON - --DEFINE_STATIC_KEY_FALSE(timers_nohz_active); -+static DEFINE_STATIC_KEY_FALSE(timers_nohz_active); - static DEFINE_MUTEX(timer_keys_mutex); - - static void timer_update_keys(struct work_struct *work); -@@ -260,6 +260,13 @@ int timer_migration_handler(struct ctl_table *table, int write, - mutex_unlock(&timer_keys_mutex); - return ret; - } -+ -+static inline bool is_timers_nohz_active(void) -+{ -+ return static_branch_unlikely(&timers_nohz_active); -+} -+#else -+static inline bool is_timers_nohz_active(void) { return false; } - #endif /* NO_HZ_COMMON */ - - static unsigned long round_jiffies_common(unsigned long j, int cpu, --- -2.19.2 - diff --git a/kernel/patches-4.14.x-rt/0035-hrtimer-Make-remote-enqueue-decision-less-restrictiv.patch b/kernel/patches-4.14.x-rt/0035-hrtimer-Make-remote-enqueue-decision-less-restrictiv.patch deleted file mode 100644 index 69dd3104b..000000000 --- a/kernel/patches-4.14.x-rt/0035-hrtimer-Make-remote-enqueue-decision-less-restrictiv.patch +++ /dev/null @@ -1,38 +0,0 @@ -From 13b3625a91c6df2a63dfc4ac26db33008d63a7e2 Mon Sep 17 00:00:00 2001 -From: Anna-Maria Gleixner -Date: Wed, 20 Dec 2017 17:13:10 +0100 -Subject: [PATCH 035/450] hrtimer: Make remote enqueue decision less - restrictive - -The current decision whether a timer can be queued on a remote CPU checks -for timer->expiry <= remote_cpu_base.expires_next. - -This is too restrictive because a timer with the same expiry time as an -existing timer will be enqueued on right-hand size of the existing timer -inside the rbtree, i.e. behind the first expiring timer. - -So its safe to allow enqueuing timers with the same expiry time as the -first expiring timer on a remote CPU base. - -Signed-off-by: Anna-Maria Gleixner -Signed-off-by: Sebastian Andrzej Siewior ---- - kernel/time/hrtimer.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/kernel/time/hrtimer.c b/kernel/time/hrtimer.c -index 35d7d0c8c3d6..1b2866645c83 100644 ---- a/kernel/time/hrtimer.c -+++ b/kernel/time/hrtimer.c -@@ -168,7 +168,7 @@ hrtimer_check_target(struct hrtimer *timer, struct hrtimer_clock_base *new_base) - ktime_t expires; - - expires = ktime_sub(hrtimer_get_expires(timer), new_base->offset); -- return expires <= new_base->cpu_base->expires_next; -+ return expires < new_base->cpu_base->expires_next; - } - - static inline --- -2.19.2 - diff --git a/kernel/patches-4.14.x-rt/0036-hrtimer-Remove-base-argument-from-hrtimer_reprogram.patch b/kernel/patches-4.14.x-rt/0036-hrtimer-Remove-base-argument-from-hrtimer_reprogram.patch deleted file mode 100644 index 420291b7c..000000000 --- a/kernel/patches-4.14.x-rt/0036-hrtimer-Remove-base-argument-from-hrtimer_reprogram.patch +++ /dev/null @@ -1,56 +0,0 @@ -From 0cf40556907398391a02e49acbb93e2be5f0be98 Mon Sep 17 00:00:00 2001 -From: Anna-Maria Gleixner -Date: Wed, 20 Dec 2017 17:13:11 +0100 -Subject: [PATCH 036/450] hrtimer: Remove base argument from - hrtimer_reprogram() - -hrtimer_reprogram() must have access to the hrtimer_clock_base of the new -first expiring timer to access hrtimer_clock_base.offset for adjusting the -expiry time to CLOCK_MONOTONIC. This is required to evaluate whether the -new left most timer in the hrtimer_clock_base is the first expiring timer -of all clock bases in a hrtimer_cpu_base. - -The only user of hrtimer_reprogram() is hrtimer_start_range_ns(), which has -a pointer to hrtimer_clock_base already and hands it in as an argument. But -hrtimer_start_range_ns() will be split for the upcoming support for softirq -based hrtimers to avoid code duplication and will lose the direct access to -the clock base pointer. - -Instead of handing in timer and timer->base as an argument remove the base -argument from hrtimer_reprogram() and retrieve the clock base internally. - -Signed-off-by: Anna-Maria Gleixner -Signed-off-by: Sebastian Andrzej Siewior ---- - kernel/time/hrtimer.c | 6 +++--- - 1 file changed, 3 insertions(+), 3 deletions(-) - -diff --git a/kernel/time/hrtimer.c b/kernel/time/hrtimer.c -index 1b2866645c83..9030dcb3ef14 100644 ---- a/kernel/time/hrtimer.c -+++ b/kernel/time/hrtimer.c -@@ -650,10 +650,10 @@ static inline void retrigger_next_event(void *arg) { } - * - * Called with interrupts disabled and base->cpu_base.lock held - */ --static void hrtimer_reprogram(struct hrtimer *timer, -- struct hrtimer_clock_base *base) -+static void hrtimer_reprogram(struct hrtimer *timer) - { - struct hrtimer_cpu_base *cpu_base = this_cpu_ptr(&hrtimer_bases); -+ struct hrtimer_clock_base *base = timer->base; - ktime_t expires = ktime_sub(hrtimer_get_expires(timer), base->offset); - - WARN_ON_ONCE(hrtimer_get_expires_tv64(timer) < 0); -@@ -943,7 +943,7 @@ void hrtimer_start_range_ns(struct hrtimer *timer, ktime_t tim, - if (!leftmost) - goto unlock; - -- hrtimer_reprogram(timer, new_base); -+ hrtimer_reprogram(timer); - unlock: - unlock_hrtimer_base(timer, &flags); - } --- -2.19.2 - diff --git a/kernel/patches-4.14.x-rt/0037-hrtimer-Split-hrtimer_start_range_ns.patch b/kernel/patches-4.14.x-rt/0037-hrtimer-Split-hrtimer_start_range_ns.patch deleted file mode 100644 index d92263dbd..000000000 --- a/kernel/patches-4.14.x-rt/0037-hrtimer-Split-hrtimer_start_range_ns.patch +++ /dev/null @@ -1,81 +0,0 @@ -From e884985cb8d91c0547a8d1cdda126bf7e0019c1c Mon Sep 17 00:00:00 2001 -From: Anna-Maria Gleixner -Date: Wed, 20 Dec 2017 17:13:12 +0100 -Subject: [PATCH 037/450] hrtimer: Split hrtimer_start_range_ns() - -Preparatory patch for softirq based hrtimers to avoid code duplication. No -functional change. - -Signed-off-by: Anna-Maria Gleixner -Signed-off-by: Sebastian Andrzej Siewior ---- - kernel/time/hrtimer.c | 44 +++++++++++++++++++++++-------------------- - 1 file changed, 24 insertions(+), 20 deletions(-) - -diff --git a/kernel/time/hrtimer.c b/kernel/time/hrtimer.c -index 9030dcb3ef14..687a8d903a18 100644 ---- a/kernel/time/hrtimer.c -+++ b/kernel/time/hrtimer.c -@@ -909,22 +909,11 @@ static inline ktime_t hrtimer_update_lowres(struct hrtimer *timer, ktime_t tim, - return tim; - } - --/** -- * hrtimer_start_range_ns - (re)start an hrtimer -- * @timer: the timer to be added -- * @tim: expiry time -- * @delta_ns: "slack" range for the timer -- * @mode: timer mode: absolute (HRTIMER_MODE_ABS) or -- * relative (HRTIMER_MODE_REL), and pinned (HRTIMER_MODE_PINNED) -- */ --void hrtimer_start_range_ns(struct hrtimer *timer, ktime_t tim, -- u64 delta_ns, const enum hrtimer_mode mode) -+static int __hrtimer_start_range_ns(struct hrtimer *timer, ktime_t tim, -+ u64 delta_ns, const enum hrtimer_mode mode, -+ struct hrtimer_clock_base *base) - { -- struct hrtimer_clock_base *base, *new_base; -- unsigned long flags; -- int leftmost; -- -- base = lock_hrtimer_base(timer, &flags); -+ struct hrtimer_clock_base *new_base; - - /* Remove an active timer from the queue: */ - remove_hrtimer(timer, base, true); -@@ -939,12 +928,27 @@ void hrtimer_start_range_ns(struct hrtimer *timer, ktime_t tim, - /* Switch the timer base, if necessary: */ - new_base = switch_hrtimer_base(timer, base, mode & HRTIMER_MODE_PINNED); - -- leftmost = enqueue_hrtimer(timer, new_base, mode); -- if (!leftmost) -- goto unlock; -+ return enqueue_hrtimer(timer, new_base, mode); -+} -+/** -+ * hrtimer_start_range_ns - (re)start an hrtimer -+ * @timer: the timer to be added -+ * @tim: expiry time -+ * @delta_ns: "slack" range for the timer -+ * @mode: timer mode: absolute (HRTIMER_MODE_ABS) or -+ * relative (HRTIMER_MODE_REL), and pinned (HRTIMER_MODE_PINNED) -+ */ -+void hrtimer_start_range_ns(struct hrtimer *timer, ktime_t tim, -+ u64 delta_ns, const enum hrtimer_mode mode) -+{ -+ struct hrtimer_clock_base *base; -+ unsigned long flags; -+ -+ base = lock_hrtimer_base(timer, &flags); -+ -+ if (__hrtimer_start_range_ns(timer, tim, delta_ns, mode, base)) -+ hrtimer_reprogram(timer); - -- hrtimer_reprogram(timer); --unlock: - unlock_hrtimer_base(timer, &flags); - } - EXPORT_SYMBOL_GPL(hrtimer_start_range_ns); --- -2.19.2 - diff --git a/kernel/patches-4.14.x-rt/0038-hrtimer-Split-__hrtimer_get_next_event.patch b/kernel/patches-4.14.x-rt/0038-hrtimer-Split-__hrtimer_get_next_event.patch deleted file mode 100644 index 8dee26f32..000000000 --- a/kernel/patches-4.14.x-rt/0038-hrtimer-Split-__hrtimer_get_next_event.patch +++ /dev/null @@ -1,58 +0,0 @@ -From 4317f172bc6903167e82cc24d11bea7e21148440 Mon Sep 17 00:00:00 2001 -From: Anna-Maria Gleixner -Date: Wed, 20 Dec 2017 17:13:13 +0100 -Subject: [PATCH 038/450] hrtimer: Split __hrtimer_get_next_event() - -Preparatory patch for softirq based hrtimers to avoid code duplication. No -functional change. - -Signed-off-by: Anna-Maria Gleixner -Signed-off-by: Sebastian Andrzej Siewior ---- - kernel/time/hrtimer.c | 20 ++++++++++++++++---- - 1 file changed, 16 insertions(+), 4 deletions(-) - -diff --git a/kernel/time/hrtimer.c b/kernel/time/hrtimer.c -index 687a8d903a18..2382bc5d8e4d 100644 ---- a/kernel/time/hrtimer.c -+++ b/kernel/time/hrtimer.c -@@ -459,13 +459,13 @@ __next_base(struct hrtimer_cpu_base *cpu_base, unsigned int *active) - while ((base = __next_base((cpu_base), &(active)))) - - #if defined(CONFIG_NO_HZ_COMMON) || defined(CONFIG_HIGH_RES_TIMERS) --static ktime_t __hrtimer_get_next_event(struct hrtimer_cpu_base *cpu_base) -+static ktime_t __hrtimer_next_event_base(struct hrtimer_cpu_base *cpu_base, -+ unsigned int active, -+ ktime_t expires_next) - { - struct hrtimer_clock_base *base; -- unsigned int active = cpu_base->active_bases; -- ktime_t expires, expires_next = KTIME_MAX; -+ ktime_t expires; - -- cpu_base->next_timer = NULL; - for_each_active_base(base, cpu_base, active) { - struct timerqueue_node *next; - struct hrtimer *timer; -@@ -487,6 +487,18 @@ static ktime_t __hrtimer_get_next_event(struct hrtimer_cpu_base *cpu_base) - expires_next = 0; - return expires_next; - } -+ -+static ktime_t __hrtimer_get_next_event(struct hrtimer_cpu_base *cpu_base) -+{ -+ unsigned int active = cpu_base->active_bases; -+ ktime_t expires_next = KTIME_MAX; -+ -+ cpu_base->next_timer = NULL; -+ -+ expires_next = __hrtimer_next_event_base(cpu_base, active, expires_next); -+ -+ return expires_next; -+} - #endif - - static inline ktime_t hrtimer_update_base(struct hrtimer_cpu_base *base) --- -2.19.2 - diff --git a/kernel/patches-4.14.x-rt/0039-hrtimer-Use-irqsave-irqrestore-around-__run_hrtimer.patch b/kernel/patches-4.14.x-rt/0039-hrtimer-Use-irqsave-irqrestore-around-__run_hrtimer.patch deleted file mode 100644 index 4704530a1..000000000 --- a/kernel/patches-4.14.x-rt/0039-hrtimer-Use-irqsave-irqrestore-around-__run_hrtimer.patch +++ /dev/null @@ -1,151 +0,0 @@ -From b7ccaa85f3ae93369f44be697f5db72c1c3f5c10 Mon Sep 17 00:00:00 2001 -From: Anna-Maria Gleixner -Date: Wed, 20 Dec 2017 17:13:14 +0100 -Subject: [PATCH 039/450] hrtimer: Use irqsave/irqrestore around - __run_hrtimer() - -__run_hrtimer() is called with the hrtimer_cpu_base.lock held and -interrupts disabled. Before invoking the timer callback the base lock is -dropped, but interrupts stay disabled. - -The upcoming support for softirq based hrtimers requires that interrupts -are enabled before the timer callback is invoked. - -To avoid code duplication, take hrtimer_cpu_base.lock with -raw_spin_lock_irqsave(flags) at the call site and hand in the flags as -argument. So raw_spin_unlock_irqrestore() before the callback invocation -will either keep interrupts disabled in interrupt context or restore to -interrupt enabled state when called from softirq context. - -Suggested-by: Peter Zijlstra -Signed-off-by: Anna-Maria Gleixner -Signed-off-by: Sebastian Andrzej Siewior ---- - kernel/time/hrtimer.c | 31 ++++++++++++++++++------------- - 1 file changed, 18 insertions(+), 13 deletions(-) - -diff --git a/kernel/time/hrtimer.c b/kernel/time/hrtimer.c -index 2382bc5d8e4d..86cdc9a76911 100644 ---- a/kernel/time/hrtimer.c -+++ b/kernel/time/hrtimer.c -@@ -1163,7 +1163,8 @@ EXPORT_SYMBOL_GPL(hrtimer_active); - - static void __run_hrtimer(struct hrtimer_cpu_base *cpu_base, - struct hrtimer_clock_base *base, -- struct hrtimer *timer, ktime_t *now) -+ struct hrtimer *timer, ktime_t *now, -+ unsigned long flags) - { - enum hrtimer_restart (*fn)(struct hrtimer *); - int restart; -@@ -1198,11 +1199,11 @@ static void __run_hrtimer(struct hrtimer_cpu_base *cpu_base, - * protected against migration to a different CPU even if the lock - * is dropped. - */ -- raw_spin_unlock(&cpu_base->lock); -+ raw_spin_unlock_irqrestore(&cpu_base->lock, flags); - trace_hrtimer_expire_entry(timer, now); - restart = fn(timer); - trace_hrtimer_expire_exit(timer); -- raw_spin_lock(&cpu_base->lock); -+ raw_spin_lock_irq(&cpu_base->lock); - - /* - * Note: We clear the running state after enqueue_hrtimer and -@@ -1230,7 +1231,8 @@ static void __run_hrtimer(struct hrtimer_cpu_base *cpu_base, - base->running = NULL; - } - --static void __hrtimer_run_queues(struct hrtimer_cpu_base *cpu_base, ktime_t now) -+static void __hrtimer_run_queues(struct hrtimer_cpu_base *cpu_base, ktime_t now, -+ unsigned long flags) - { - struct hrtimer_clock_base *base; - unsigned int active = cpu_base->active_bases; -@@ -1261,7 +1263,7 @@ static void __hrtimer_run_queues(struct hrtimer_cpu_base *cpu_base, ktime_t now) - if (basenow < hrtimer_get_softexpires_tv64(timer)) - break; - -- __run_hrtimer(cpu_base, base, timer, &basenow); -+ __run_hrtimer(cpu_base, base, timer, &basenow, flags); - } - } - } -@@ -1276,13 +1278,14 @@ void hrtimer_interrupt(struct clock_event_device *dev) - { - struct hrtimer_cpu_base *cpu_base = this_cpu_ptr(&hrtimer_bases); - ktime_t expires_next, now, entry_time, delta; -+ unsigned long flags; - int retries = 0; - - BUG_ON(!cpu_base->hres_active); - cpu_base->nr_events++; - dev->next_event = KTIME_MAX; - -- raw_spin_lock(&cpu_base->lock); -+ raw_spin_lock_irqsave(&cpu_base->lock, flags); - entry_time = now = hrtimer_update_base(cpu_base); - retry: - cpu_base->in_hrtirq = 1; -@@ -1295,7 +1298,7 @@ void hrtimer_interrupt(struct clock_event_device *dev) - */ - cpu_base->expires_next = KTIME_MAX; - -- __hrtimer_run_queues(cpu_base, now); -+ __hrtimer_run_queues(cpu_base, now, flags); - - /* Reevaluate the clock bases for the next expiry */ - expires_next = __hrtimer_get_next_event(cpu_base); -@@ -1305,7 +1308,7 @@ void hrtimer_interrupt(struct clock_event_device *dev) - */ - cpu_base->expires_next = expires_next; - cpu_base->in_hrtirq = 0; -- raw_spin_unlock(&cpu_base->lock); -+ raw_spin_unlock_irqrestore(&cpu_base->lock, flags); - - /* Reprogramming necessary ? */ - if (!tick_program_event(expires_next, 0)) { -@@ -1326,7 +1329,7 @@ void hrtimer_interrupt(struct clock_event_device *dev) - * Acquire base lock for updating the offsets and retrieving - * the current time. - */ -- raw_spin_lock(&cpu_base->lock); -+ raw_spin_lock_irqsave(&cpu_base->lock, flags); - now = hrtimer_update_base(cpu_base); - cpu_base->nr_retries++; - if (++retries < 3) -@@ -1339,7 +1342,8 @@ void hrtimer_interrupt(struct clock_event_device *dev) - */ - cpu_base->nr_hangs++; - cpu_base->hang_detected = 1; -- raw_spin_unlock(&cpu_base->lock); -+ raw_spin_unlock_irqrestore(&cpu_base->lock, flags); -+ - delta = ktime_sub(now, entry_time); - if ((unsigned int)delta > cpu_base->max_hang_time) - cpu_base->max_hang_time = (unsigned int) delta; -@@ -1381,6 +1385,7 @@ static inline void __hrtimer_peek_ahead_timers(void) { } - void hrtimer_run_queues(void) - { - struct hrtimer_cpu_base *cpu_base = this_cpu_ptr(&hrtimer_bases); -+ unsigned long flags; - ktime_t now; - - if (__hrtimer_hres_active(cpu_base)) -@@ -1398,10 +1403,10 @@ void hrtimer_run_queues(void) - return; - } - -- raw_spin_lock(&cpu_base->lock); -+ raw_spin_lock_irqsave(&cpu_base->lock, flags); - now = hrtimer_update_base(cpu_base); -- __hrtimer_run_queues(cpu_base, now); -- raw_spin_unlock(&cpu_base->lock); -+ __hrtimer_run_queues(cpu_base, now, flags); -+ raw_spin_unlock_irqrestore(&cpu_base->lock, flags); - } - - /* --- -2.19.2 - diff --git a/kernel/patches-4.14.x-rt/0040-hrtimer-Add-clock-bases-and-hrtimer-mode-for-soft-ir.patch b/kernel/patches-4.14.x-rt/0040-hrtimer-Add-clock-bases-and-hrtimer-mode-for-soft-ir.patch deleted file mode 100644 index d2c4aa4b6..000000000 --- a/kernel/patches-4.14.x-rt/0040-hrtimer-Add-clock-bases-and-hrtimer-mode-for-soft-ir.patch +++ /dev/null @@ -1,118 +0,0 @@ -From ca683556d23c0f7dd07d63f56d9becd628db4386 Mon Sep 17 00:00:00 2001 -From: Anna-Maria Gleixner -Date: Wed, 20 Dec 2017 17:13:15 +0100 -Subject: [PATCH 040/450] hrtimer: Add clock bases and hrtimer mode for soft - irq context - -hrtimer callback functions are always executed in hard interrupt -context. Users of hrtimer which need their timer function to be executed -in soft interrupt context, make use of tasklets to get the proper context. - -Add additional hrtimer clock bases for timers which must expire in softirq -context, so the detour via the tasklet can be avoided. This is also -required for RT, where the majority of hrtimer is moved into softirq -hrtimer context. - -The selection of the expiry mode happens via a mode bit. Introduce -HRTIMER_MODE_SOFT and the matching combinations with the ABS/REL/PINNED -bits and update the decoding of hrtimer_mode in tracepoints. - -Signed-off-by: Anna-Maria Gleixner -Signed-off-by: Sebastian Andrzej Siewior ---- - include/linux/hrtimer.h | 14 ++++++++++++++ - include/trace/events/timer.h | 6 +++++- - kernel/time/hrtimer.c | 20 ++++++++++++++++++++ - 3 files changed, 39 insertions(+), 1 deletion(-) - -diff --git a/include/linux/hrtimer.h b/include/linux/hrtimer.h -index 98ed35767ac5..26ae8a868ea8 100644 ---- a/include/linux/hrtimer.h -+++ b/include/linux/hrtimer.h -@@ -33,14 +33,24 @@ struct hrtimer_cpu_base; - * HRTIMER_MODE_REL - Time value is relative to now - * HRTIMER_MODE_PINNED - Timer is bound to CPU (is only considered - * when starting the timer) -+ * HRTIMER_MODE_SOFT - Timer callback function will be executed in -+ * soft irq context - */ - enum hrtimer_mode { - HRTIMER_MODE_ABS = 0x00, - HRTIMER_MODE_REL = 0x01, - HRTIMER_MODE_PINNED = 0x02, -+ HRTIMER_MODE_SOFT = 0x04, - - HRTIMER_MODE_ABS_PINNED = HRTIMER_MODE_ABS | HRTIMER_MODE_PINNED, - HRTIMER_MODE_REL_PINNED = HRTIMER_MODE_REL | HRTIMER_MODE_PINNED, -+ -+ HRTIMER_MODE_ABS_SOFT = HRTIMER_MODE_ABS | HRTIMER_MODE_SOFT, -+ HRTIMER_MODE_REL_SOFT = HRTIMER_MODE_REL | HRTIMER_MODE_SOFT, -+ -+ HRTIMER_MODE_ABS_PINNED_SOFT = HRTIMER_MODE_ABS_PINNED | HRTIMER_MODE_SOFT, -+ HRTIMER_MODE_REL_PINNED_SOFT = HRTIMER_MODE_REL_PINNED | HRTIMER_MODE_SOFT, -+ - }; - - /* -@@ -151,6 +161,10 @@ enum hrtimer_base_type { - HRTIMER_BASE_REALTIME, - HRTIMER_BASE_BOOTTIME, - HRTIMER_BASE_TAI, -+ HRTIMER_BASE_MONOTONIC_SOFT, -+ HRTIMER_BASE_REALTIME_SOFT, -+ HRTIMER_BASE_BOOTTIME_SOFT, -+ HRTIMER_BASE_TAI_SOFT, - HRTIMER_MAX_CLOCK_BASES, - }; - -diff --git a/include/trace/events/timer.h b/include/trace/events/timer.h -index 744b4310b24b..a57e4ee989d6 100644 ---- a/include/trace/events/timer.h -+++ b/include/trace/events/timer.h -@@ -148,7 +148,11 @@ DEFINE_EVENT(timer_class, timer_cancel, - { HRTIMER_MODE_ABS, "ABS" }, \ - { HRTIMER_MODE_REL, "REL" }, \ - { HRTIMER_MODE_ABS_PINNED, "ABS|PINNED" }, \ -- { HRTIMER_MODE_REL_PINNED, "REL|PINNED" }) -+ { HRTIMER_MODE_REL_PINNED, "REL|PINNED" }, \ -+ { HRTIMER_MODE_ABS_SOFT, "ABS|SOFT" }, \ -+ { HRTIMER_MODE_REL_SOFT, "REL|SOFT" }, \ -+ { HRTIMER_MODE_ABS_PINNED_SOFT, "ABS|PINNED|SOFT" }, \ -+ { HRTIMER_MODE_REL_PINNED_SOFT, "REL|PINNED|SOFT" }) - - /** - * hrtimer_init - called when the hrtimer is initialized -diff --git a/kernel/time/hrtimer.c b/kernel/time/hrtimer.c -index 86cdc9a76911..b5121845d12c 100644 ---- a/kernel/time/hrtimer.c -+++ b/kernel/time/hrtimer.c -@@ -92,6 +92,26 @@ DEFINE_PER_CPU(struct hrtimer_cpu_base, hrtimer_bases) = - .clockid = CLOCK_TAI, - .get_time = &ktime_get_clocktai, - }, -+ { -+ .index = HRTIMER_BASE_MONOTONIC_SOFT, -+ .clockid = CLOCK_MONOTONIC, -+ .get_time = &ktime_get, -+ }, -+ { -+ .index = HRTIMER_BASE_REALTIME_SOFT, -+ .clockid = CLOCK_REALTIME, -+ .get_time = &ktime_get_real, -+ }, -+ { -+ .index = HRTIMER_BASE_BOOTTIME_SOFT, -+ .clockid = CLOCK_BOOTTIME, -+ .get_time = &ktime_get_boottime, -+ }, -+ { -+ .index = HRTIMER_BASE_TAI_SOFT, -+ .clockid = CLOCK_TAI, -+ .get_time = &ktime_get_clocktai, -+ }, - } - }; - --- -2.19.2 - diff --git a/kernel/patches-4.14.x-rt/0041-hrtimer-Prepare-handling-of-hard-and-softirq-based-h.patch b/kernel/patches-4.14.x-rt/0041-hrtimer-Prepare-handling-of-hard-and-softirq-based-h.patch deleted file mode 100644 index 40b8342dc..000000000 --- a/kernel/patches-4.14.x-rt/0041-hrtimer-Prepare-handling-of-hard-and-softirq-based-h.patch +++ /dev/null @@ -1,122 +0,0 @@ -From cae6bc5fa3632fb13d559189b382b8935b165be1 Mon Sep 17 00:00:00 2001 -From: Anna-Maria Gleixner -Date: Wed, 20 Dec 2017 17:13:16 +0100 -Subject: [PATCH 041/450] hrtimer: Prepare handling of hard and softirq based - hrtimers - -The softirq based hrtimer can utilize most of the existing hrtimers -functions, but need to operate on a different data set. - -Add an active_mask argument to various functions so the hard and soft bases -can be selected. Fixup the existing callers and hand in the ACTIVE_HARD -mask. - -Signed-off-by: Anna-Maria Gleixner -Signed-off-by: Sebastian Andrzej Siewior ---- - kernel/time/hrtimer.c | 38 +++++++++++++++++++++++++++++--------- - 1 file changed, 29 insertions(+), 9 deletions(-) - -diff --git a/kernel/time/hrtimer.c b/kernel/time/hrtimer.c -index b5121845d12c..9a1f2b00c847 100644 ---- a/kernel/time/hrtimer.c -+++ b/kernel/time/hrtimer.c -@@ -59,6 +59,15 @@ - - #include "tick-internal.h" - -+/* -+ * Masks for selecting the soft and hard context timers from -+ * cpu_base->active -+ */ -+#define MASK_SHIFT (HRTIMER_BASE_MONOTONIC_SOFT) -+#define HRTIMER_ACTIVE_HARD ((1U << MASK_SHIFT) - 1) -+#define HRTIMER_ACTIVE_SOFT (HRTIMER_ACTIVE_HARD << MASK_SHIFT) -+#define HRTIMER_ACTIVE_ALL (HRTIMER_ACTIVE_SOFT | HRTIMER_ACTIVE_HARD) -+ - /* - * The timer bases: - * -@@ -508,13 +517,24 @@ static ktime_t __hrtimer_next_event_base(struct hrtimer_cpu_base *cpu_base, - return expires_next; - } - --static ktime_t __hrtimer_get_next_event(struct hrtimer_cpu_base *cpu_base) -+/* -+ * Recomputes cpu_base::*next_timer and returns the earliest expires_next but -+ * does not set cpu_base::*expires_next, that is done by hrtimer_reprogram. -+ * -+ * @active_mask must be one of: -+ * - HRTIMER_ACTIVE, -+ * - HRTIMER_ACTIVE_SOFT, or -+ * - HRTIMER_ACTIVE_HARD. -+ */ -+static ktime_t __hrtimer_get_next_event(struct hrtimer_cpu_base *cpu_base, -+ unsigned int active_mask) - { -- unsigned int active = cpu_base->active_bases; -+ unsigned int active; - ktime_t expires_next = KTIME_MAX; - - cpu_base->next_timer = NULL; - -+ active = cpu_base->active_bases & active_mask; - expires_next = __hrtimer_next_event_base(cpu_base, active, expires_next); - - return expires_next; -@@ -555,7 +575,7 @@ hrtimer_force_reprogram(struct hrtimer_cpu_base *cpu_base, int skip_equal) - { - ktime_t expires_next; - -- expires_next = __hrtimer_get_next_event(cpu_base); -+ expires_next = __hrtimer_get_next_event(cpu_base, HRTIMER_ACTIVE_HARD); - - if (skip_equal && expires_next == cpu_base->expires_next) - return; -@@ -1078,7 +1098,7 @@ u64 hrtimer_get_next_event(void) - raw_spin_lock_irqsave(&cpu_base->lock, flags); - - if (!__hrtimer_hres_active(cpu_base)) -- expires = __hrtimer_get_next_event(cpu_base); -+ expires = __hrtimer_get_next_event(cpu_base, HRTIMER_ACTIVE_HARD); - - raw_spin_unlock_irqrestore(&cpu_base->lock, flags); - -@@ -1252,10 +1272,10 @@ static void __run_hrtimer(struct hrtimer_cpu_base *cpu_base, - } - - static void __hrtimer_run_queues(struct hrtimer_cpu_base *cpu_base, ktime_t now, -- unsigned long flags) -+ unsigned long flags, unsigned int active_mask) - { - struct hrtimer_clock_base *base; -- unsigned int active = cpu_base->active_bases; -+ unsigned int active = cpu_base->active_bases & active_mask; - - for_each_active_base(base, cpu_base, active) { - struct timerqueue_node *node; -@@ -1318,10 +1338,10 @@ void hrtimer_interrupt(struct clock_event_device *dev) - */ - cpu_base->expires_next = KTIME_MAX; - -- __hrtimer_run_queues(cpu_base, now, flags); -+ __hrtimer_run_queues(cpu_base, now, flags, HRTIMER_ACTIVE_HARD); - - /* Reevaluate the clock bases for the next expiry */ -- expires_next = __hrtimer_get_next_event(cpu_base); -+ expires_next = __hrtimer_get_next_event(cpu_base, HRTIMER_ACTIVE_HARD); - /* - * Store the new expiry value so the migration code can verify - * against it. -@@ -1425,7 +1445,7 @@ void hrtimer_run_queues(void) - - raw_spin_lock_irqsave(&cpu_base->lock, flags); - now = hrtimer_update_base(cpu_base); -- __hrtimer_run_queues(cpu_base, now, flags); -+ __hrtimer_run_queues(cpu_base, now, flags, HRTIMER_ACTIVE_HARD); - raw_spin_unlock_irqrestore(&cpu_base->lock, flags); - } - --- -2.19.2 - diff --git a/kernel/patches-4.14.x-rt/0042-hrtimer-Implement-support-for-softirq-based-hrtimers.patch b/kernel/patches-4.14.x-rt/0042-hrtimer-Implement-support-for-softirq-based-hrtimers.patch deleted file mode 100644 index d37e2ca90..000000000 --- a/kernel/patches-4.14.x-rt/0042-hrtimer-Implement-support-for-softirq-based-hrtimers.patch +++ /dev/null @@ -1,506 +0,0 @@ -From 478a104cc093e2bd50b75791abc57f3a7957e566 Mon Sep 17 00:00:00 2001 -From: Anna-Maria Gleixner -Date: Wed, 20 Dec 2017 17:13:17 +0100 -Subject: [PATCH 042/450] hrtimer: Implement support for softirq based hrtimers - -hrtimer callbacks are always invoked in hard interrupt context. Several -users in tree require soft interrupt context for their callbacks and -achieve this by combining a hrtimer with a tasklet. The hrtimer schedules -the tasklet in hard interrupt context and the tasklet callback gets invoked -in softirq context later. - -That's suboptimal and aside of that the real-time patch moves most of the -hrtimers into softirq context. So adding native support for hrtimers -expiring in softirq context is a valuable extension for both mainline and -the RT patch set. - -Each valid hrtimer clock id has two associated hrtimer clock bases: one for -timers expiring in hardirq context and one for timers expiring in softirq -context. - -Implement the functionality to associate a hrtimer with the hard or softirq -related clock bases and update the relevant functions to take them into -account when the next expiry time needs to be evaluated. - -Add a check into the hard interrupt context handler functions to check -whether the first expiring softirq based timer has expired. If it's expired -the softirq is raised and the accounting of softirq based timers to -evaluate the next expiry time for programming the timer hardware is skipped -until the softirq processing has finished. At the end of the softirq -processing the regular processing is resumed. - -Suggested-by: Thomas Gleixner -Suggested-by: Peter Zijlstra -Signed-off-by: Anna-Maria Gleixner -Signed-off-by: Sebastian Andrzej Siewior ---- - include/linux/hrtimer.h | 21 ++++- - kernel/time/hrtimer.c | 199 ++++++++++++++++++++++++++++++++++------ - 2 files changed, 189 insertions(+), 31 deletions(-) - -diff --git a/include/linux/hrtimer.h b/include/linux/hrtimer.h -index 26ae8a868ea8..c7902ca7c9f4 100644 ---- a/include/linux/hrtimer.h -+++ b/include/linux/hrtimer.h -@@ -103,6 +103,7 @@ enum hrtimer_restart { - * @base: pointer to the timer base (per cpu and per clock) - * @state: state information (See bit values above) - * @is_rel: Set if the timer was armed relative -+ * @is_soft: Set if hrtimer will be expired in soft interrupt context. - * - * The hrtimer structure must be initialized by hrtimer_init() - */ -@@ -113,6 +114,7 @@ struct hrtimer { - struct hrtimer_clock_base *base; - u8 state; - u8 is_rel; -+ u8 is_soft; - }; - - /** -@@ -178,13 +180,18 @@ enum hrtimer_base_type { - * @hres_active: State of high resolution mode - * @in_hrtirq: hrtimer_interrupt() is currently executing - * @hang_detected: The last hrtimer interrupt detected a hang -+ * @softirq_activated: displays, if the softirq is raised - update of softirq -+ * related settings is not required then. - * @nr_events: Total number of hrtimer interrupt events - * @nr_retries: Total number of hrtimer interrupt retries - * @nr_hangs: Total number of hrtimer interrupt hangs - * @max_hang_time: Maximum time spent in hrtimer_interrupt - * @expires_next: absolute time of the next event, is required for remote -- * hrtimer enqueue -+ * hrtimer enqueue; it is the total first expiry time (hard -+ * and soft hrtimer are taken into account) - * @next_timer: Pointer to the first expiring timer -+ * @softirq_expires_next: Time to check, if soft queues needs also to be expired -+ * @softirq_next_timer: Pointer to the first expiring softirq based timer - * @clock_base: array of clock bases for this cpu - * - * Note: next_timer is just an optimization for __remove_hrtimer(). -@@ -196,9 +203,10 @@ struct hrtimer_cpu_base { - unsigned int cpu; - unsigned int active_bases; - unsigned int clock_was_set_seq; -- unsigned int hres_active : 1, -- in_hrtirq : 1, -- hang_detected : 1; -+ unsigned int hres_active : 1, -+ in_hrtirq : 1, -+ hang_detected : 1, -+ softirq_activated : 1; - #ifdef CONFIG_HIGH_RES_TIMERS - unsigned int nr_events; - unsigned short nr_retries; -@@ -207,6 +215,8 @@ struct hrtimer_cpu_base { - #endif - ktime_t expires_next; - struct hrtimer *next_timer; -+ ktime_t softirq_expires_next; -+ struct hrtimer *softirq_next_timer; - struct hrtimer_clock_base clock_base[HRTIMER_MAX_CLOCK_BASES]; - } ____cacheline_aligned; - -@@ -379,7 +389,8 @@ extern void hrtimer_start_range_ns(struct hrtimer *timer, ktime_t tim, - * @timer: the timer to be added - * @tim: expiry time - * @mode: timer mode: absolute (HRTIMER_MODE_ABS) or -- * relative (HRTIMER_MODE_REL), and pinned (HRTIMER_MODE_PINNED) -+ * relative (HRTIMER_MODE_REL), and pinned (HRTIMER_MODE_PINNED); -+ * softirq based mode is considered for debug purpose only! - */ - static inline void hrtimer_start(struct hrtimer *timer, ktime_t tim, - const enum hrtimer_mode mode) -diff --git a/kernel/time/hrtimer.c b/kernel/time/hrtimer.c -index 9a1f2b00c847..66d7a12d7256 100644 ---- a/kernel/time/hrtimer.c -+++ b/kernel/time/hrtimer.c -@@ -411,7 +411,8 @@ static inline void debug_hrtimer_init(struct hrtimer *timer) - debug_object_init(timer, &hrtimer_debug_descr); - } - --static inline void debug_hrtimer_activate(struct hrtimer *timer) -+static inline void debug_hrtimer_activate(struct hrtimer *timer, -+ enum hrtimer_mode mode) - { - debug_object_activate(timer, &hrtimer_debug_descr); - } -@@ -444,8 +445,10 @@ void destroy_hrtimer_on_stack(struct hrtimer *timer) - EXPORT_SYMBOL_GPL(destroy_hrtimer_on_stack); - - #else -+ - static inline void debug_hrtimer_init(struct hrtimer *timer) { } --static inline void debug_hrtimer_activate(struct hrtimer *timer) { } -+static inline void debug_hrtimer_activate(struct hrtimer *timer, -+ enum hrtimer_mode mode) { } - static inline void debug_hrtimer_deactivate(struct hrtimer *timer) { } - #endif - -@@ -460,7 +463,7 @@ debug_init(struct hrtimer *timer, clockid_t clockid, - static inline void debug_activate(struct hrtimer *timer, - enum hrtimer_mode mode) - { -- debug_hrtimer_activate(timer); -+ debug_hrtimer_activate(timer, mode); - trace_hrtimer_start(timer, mode); - } - -@@ -487,7 +490,6 @@ __next_base(struct hrtimer_cpu_base *cpu_base, unsigned int *active) - #define for_each_active_base(base, cpu_base, active) \ - while ((base = __next_base((cpu_base), &(active)))) - --#if defined(CONFIG_NO_HZ_COMMON) || defined(CONFIG_HIGH_RES_TIMERS) - static ktime_t __hrtimer_next_event_base(struct hrtimer_cpu_base *cpu_base, - unsigned int active, - ktime_t expires_next) -@@ -504,7 +506,10 @@ static ktime_t __hrtimer_next_event_base(struct hrtimer_cpu_base *cpu_base, - expires = ktime_sub(hrtimer_get_expires(timer), base->offset); - if (expires < expires_next) { - expires_next = expires; -- cpu_base->next_timer = timer; -+ if (timer->is_soft) -+ cpu_base->softirq_next_timer = timer; -+ else -+ cpu_base->next_timer = timer; - } - } - /* -@@ -521,25 +526,42 @@ static ktime_t __hrtimer_next_event_base(struct hrtimer_cpu_base *cpu_base, - * Recomputes cpu_base::*next_timer and returns the earliest expires_next but - * does not set cpu_base::*expires_next, that is done by hrtimer_reprogram. - * -+ * When a softirq is pending, we can ignore the HRTIMER_ACTIVE_SOFT bases, -+ * those timers will get run whenever the softirq gets handled, at the end of -+ * hrtimer_run_softirq(), hrtimer_update_softirq_timer() will re-add these bases. -+ * -+ * Therefore softirq values are those from the HRTIMER_ACTIVE_SOFT clock bases. -+ * The !softirq values are the minima across HRTIMER_ACTIVE_ALL, unless an actual -+ * softirq is pending, in which case they're the minima of HRTIMER_ACTIVE_HARD. -+ * - * @active_mask must be one of: -- * - HRTIMER_ACTIVE, -+ * - HRTIMER_ACTIVE_ALL, - * - HRTIMER_ACTIVE_SOFT, or - * - HRTIMER_ACTIVE_HARD. - */ --static ktime_t __hrtimer_get_next_event(struct hrtimer_cpu_base *cpu_base, -- unsigned int active_mask) -+static ktime_t -+__hrtimer_get_next_event(struct hrtimer_cpu_base *cpu_base, unsigned int active_mask) - { - unsigned int active; -+ struct hrtimer *next_timer = NULL; - ktime_t expires_next = KTIME_MAX; - -- cpu_base->next_timer = NULL; -+ if (!cpu_base->softirq_activated && (active_mask & HRTIMER_ACTIVE_SOFT)) { -+ active = cpu_base->active_bases & HRTIMER_ACTIVE_SOFT; -+ cpu_base->softirq_next_timer = NULL; -+ expires_next = __hrtimer_next_event_base(cpu_base, active, KTIME_MAX); -+ -+ next_timer = cpu_base->softirq_next_timer; -+ } - -- active = cpu_base->active_bases & active_mask; -- expires_next = __hrtimer_next_event_base(cpu_base, active, expires_next); -+ if (active_mask & HRTIMER_ACTIVE_HARD) { -+ active = cpu_base->active_bases & HRTIMER_ACTIVE_HARD; -+ cpu_base->next_timer = next_timer; -+ expires_next = __hrtimer_next_event_base(cpu_base, active, expires_next); -+ } - - return expires_next; - } --#endif - - static inline ktime_t hrtimer_update_base(struct hrtimer_cpu_base *base) - { -@@ -547,8 +569,14 @@ static inline ktime_t hrtimer_update_base(struct hrtimer_cpu_base *base) - ktime_t *offs_boot = &base->clock_base[HRTIMER_BASE_BOOTTIME].offset; - ktime_t *offs_tai = &base->clock_base[HRTIMER_BASE_TAI].offset; - -- return ktime_get_update_offsets_now(&base->clock_was_set_seq, -+ ktime_t now = ktime_get_update_offsets_now(&base->clock_was_set_seq, - offs_real, offs_boot, offs_tai); -+ -+ base->clock_base[HRTIMER_BASE_REALTIME_SOFT].offset = *offs_real; -+ base->clock_base[HRTIMER_BASE_BOOTTIME_SOFT].offset = *offs_boot; -+ base->clock_base[HRTIMER_BASE_TAI_SOFT].offset = *offs_tai; -+ -+ return now; - } - - /* -@@ -575,7 +603,23 @@ hrtimer_force_reprogram(struct hrtimer_cpu_base *cpu_base, int skip_equal) - { - ktime_t expires_next; - -- expires_next = __hrtimer_get_next_event(cpu_base, HRTIMER_ACTIVE_HARD); -+ /* -+ * Find the current next expiration time. -+ */ -+ expires_next = __hrtimer_get_next_event(cpu_base, HRTIMER_ACTIVE_ALL); -+ -+ if (cpu_base->next_timer && cpu_base->next_timer->is_soft) { -+ /* -+ * When the softirq is activated, hrtimer has to be -+ * programmed with the first hard hrtimer because soft -+ * timer interrupt could occur too late. -+ */ -+ if (cpu_base->softirq_activated) -+ expires_next = __hrtimer_get_next_event(cpu_base, -+ HRTIMER_ACTIVE_HARD); -+ else -+ cpu_base->softirq_expires_next = expires_next; -+ } - - if (skip_equal && expires_next == cpu_base->expires_next) - return; -@@ -702,7 +746,7 @@ static inline void retrigger_next_event(void *arg) { } - * - * Called with interrupts disabled and base->cpu_base.lock held - */ --static void hrtimer_reprogram(struct hrtimer *timer) -+static void hrtimer_reprogram(struct hrtimer *timer, bool reprogram) - { - struct hrtimer_cpu_base *cpu_base = this_cpu_ptr(&hrtimer_bases); - struct hrtimer_clock_base *base = timer->base; -@@ -710,6 +754,37 @@ static void hrtimer_reprogram(struct hrtimer *timer) - - WARN_ON_ONCE(hrtimer_get_expires_tv64(timer) < 0); - -+ /* -+ * CLOCK_REALTIME timer might be requested with an absolute -+ * expiry time which is less than base->offset. Set it to 0. -+ */ -+ if (expires < 0) -+ expires = 0; -+ -+ if (timer->is_soft) { -+ /* -+ * soft hrtimer could be started on a remote CPU. In this -+ * case softirq_expires_next needs to be updated on the -+ * remote CPU. The soft hrtimer will not expire before the -+ * first hard hrtimer on the remote CPU - -+ * hrtimer_check_target() prevents this case. -+ */ -+ struct hrtimer_cpu_base *timer_cpu_base = base->cpu_base; -+ -+ if (timer_cpu_base->softirq_activated) -+ return; -+ -+ if (!ktime_before(expires, timer_cpu_base->softirq_expires_next)) -+ return; -+ -+ timer_cpu_base->softirq_next_timer = timer; -+ timer_cpu_base->softirq_expires_next = expires; -+ -+ if (!ktime_before(expires, timer_cpu_base->expires_next) || -+ !reprogram) -+ return; -+ } -+ - /* - * If the timer is not on the current cpu, we cannot reprogram - * the other cpus clock event device. -@@ -727,13 +802,6 @@ static void hrtimer_reprogram(struct hrtimer *timer) - if (cpu_base->in_hrtirq) - return; - -- /* -- * CLOCK_REALTIME timer might be requested with an absolute -- * expiry time which is less than base->offset. Set it to 0. -- */ -- if (expires < 0) -- expires = 0; -- - if (expires >= cpu_base->expires_next) - return; - -@@ -961,6 +1029,31 @@ static inline ktime_t hrtimer_update_lowres(struct hrtimer *timer, ktime_t tim, - return tim; - } - -+static void -+hrtimer_update_softirq_timer(struct hrtimer_cpu_base *cpu_base, bool reprogram) -+{ -+ ktime_t expires; -+ -+ /* -+ * Find the next SOFT expiration. -+ */ -+ expires = __hrtimer_get_next_event(cpu_base, HRTIMER_ACTIVE_SOFT); -+ -+ /* -+ * reprogramming needs to be triggered, even if the next soft -+ * hrtimer expires at the same time than the next hard -+ * hrtimer. cpu_base->softirq_expires_next needs to be updated! -+ */ -+ if (expires == KTIME_MAX) -+ return; -+ -+ /* -+ * cpu_base->*next_timer is recomputed by __hrtimer_get_next_event() -+ * cpu_base->*expires_next is only set by hrtimer_reprogram() -+ */ -+ hrtimer_reprogram(cpu_base->softirq_next_timer, reprogram); -+} -+ - static int __hrtimer_start_range_ns(struct hrtimer *timer, ktime_t tim, - u64 delta_ns, const enum hrtimer_mode mode, - struct hrtimer_clock_base *base) -@@ -982,13 +1075,15 @@ static int __hrtimer_start_range_ns(struct hrtimer *timer, ktime_t tim, - - return enqueue_hrtimer(timer, new_base, mode); - } -+ - /** - * hrtimer_start_range_ns - (re)start an hrtimer - * @timer: the timer to be added - * @tim: expiry time - * @delta_ns: "slack" range for the timer - * @mode: timer mode: absolute (HRTIMER_MODE_ABS) or -- * relative (HRTIMER_MODE_REL), and pinned (HRTIMER_MODE_PINNED) -+ * relative (HRTIMER_MODE_REL), and pinned (HRTIMER_MODE_PINNED); -+ * softirq based mode is considered for debug purpose only! - */ - void hrtimer_start_range_ns(struct hrtimer *timer, ktime_t tim, - u64 delta_ns, const enum hrtimer_mode mode) -@@ -996,10 +1091,16 @@ void hrtimer_start_range_ns(struct hrtimer *timer, ktime_t tim, - struct hrtimer_clock_base *base; - unsigned long flags; - -+ /* -+ * Check whether the HRTIMER_MODE_SOFT bit and hrtimer.is_soft -+ * match. -+ */ -+ WARN_ON_ONCE(!(mode & HRTIMER_MODE_SOFT) ^ !timer->is_soft); -+ - base = lock_hrtimer_base(timer, &flags); - - if (__hrtimer_start_range_ns(timer, tim, delta_ns, mode, base)) -- hrtimer_reprogram(timer); -+ hrtimer_reprogram(timer, true); - - unlock_hrtimer_base(timer, &flags); - } -@@ -1098,7 +1199,7 @@ u64 hrtimer_get_next_event(void) - raw_spin_lock_irqsave(&cpu_base->lock, flags); - - if (!__hrtimer_hres_active(cpu_base)) -- expires = __hrtimer_get_next_event(cpu_base, HRTIMER_ACTIVE_HARD); -+ expires = __hrtimer_get_next_event(cpu_base, HRTIMER_ACTIVE_ALL); - - raw_spin_unlock_irqrestore(&cpu_base->lock, flags); - -@@ -1308,6 +1409,23 @@ static void __hrtimer_run_queues(struct hrtimer_cpu_base *cpu_base, ktime_t now, - } - } - -+static __latent_entropy void hrtimer_run_softirq(struct softirq_action *h) -+{ -+ struct hrtimer_cpu_base *cpu_base = this_cpu_ptr(&hrtimer_bases); -+ unsigned long flags; -+ ktime_t now; -+ -+ raw_spin_lock_irqsave(&cpu_base->lock, flags); -+ -+ now = hrtimer_update_base(cpu_base); -+ __hrtimer_run_queues(cpu_base, now, flags, HRTIMER_ACTIVE_SOFT); -+ -+ cpu_base->softirq_activated = 0; -+ hrtimer_update_softirq_timer(cpu_base, true); -+ -+ raw_spin_unlock_irqrestore(&cpu_base->lock, flags); -+} -+ - #ifdef CONFIG_HIGH_RES_TIMERS - - /* -@@ -1338,10 +1456,16 @@ void hrtimer_interrupt(struct clock_event_device *dev) - */ - cpu_base->expires_next = KTIME_MAX; - -+ if (!ktime_before(now, cpu_base->softirq_expires_next)) { -+ cpu_base->softirq_expires_next = KTIME_MAX; -+ cpu_base->softirq_activated = 1; -+ raise_softirq_irqoff(HRTIMER_SOFTIRQ); -+ } -+ - __hrtimer_run_queues(cpu_base, now, flags, HRTIMER_ACTIVE_HARD); - - /* Reevaluate the clock bases for the next expiry */ -- expires_next = __hrtimer_get_next_event(cpu_base, HRTIMER_ACTIVE_HARD); -+ expires_next = __hrtimer_get_next_event(cpu_base, HRTIMER_ACTIVE_ALL); - /* - * Store the new expiry value so the migration code can verify - * against it. -@@ -1445,6 +1569,13 @@ void hrtimer_run_queues(void) - - raw_spin_lock_irqsave(&cpu_base->lock, flags); - now = hrtimer_update_base(cpu_base); -+ -+ if (!ktime_before(now, cpu_base->softirq_expires_next)) { -+ cpu_base->softirq_expires_next = KTIME_MAX; -+ cpu_base->softirq_activated = 1; -+ raise_softirq_irqoff(HRTIMER_SOFTIRQ); -+ } -+ - __hrtimer_run_queues(cpu_base, now, flags, HRTIMER_ACTIVE_HARD); - raw_spin_unlock_irqrestore(&cpu_base->lock, flags); - } -@@ -1628,7 +1759,9 @@ int hrtimers_prepare_cpu(unsigned int cpu) - cpu_base->hres_active = 0; - cpu_base->hang_detected = 0; - cpu_base->next_timer = NULL; -+ cpu_base->softirq_next_timer = NULL; - cpu_base->expires_next = KTIME_MAX; -+ cpu_base->softirq_expires_next = KTIME_MAX; - return 0; - } - -@@ -1672,6 +1805,12 @@ int hrtimers_dead_cpu(unsigned int scpu) - BUG_ON(cpu_online(scpu)); - tick_cancel_sched_timer(scpu); - -+ /* -+ * this BH disable ensures that raise_softirq_irqoff() does -+ * not wakeup ksoftirqd (and acquire the pi-lock) while -+ * holding the cpu_base lock -+ */ -+ local_bh_disable(); - local_irq_disable(); - old_base = &per_cpu(hrtimer_bases, scpu); - new_base = this_cpu_ptr(&hrtimer_bases); -@@ -1687,12 +1826,19 @@ int hrtimers_dead_cpu(unsigned int scpu) - &new_base->clock_base[i]); - } - -+ /* -+ * The migration might have changed the first expiring softirq -+ * timer on this CPU. Update it. -+ */ -+ hrtimer_update_softirq_timer(new_base, false); -+ - raw_spin_unlock(&old_base->lock); - raw_spin_unlock(&new_base->lock); - - /* Check, if we got expired work to do */ - __hrtimer_peek_ahead_timers(); - local_irq_enable(); -+ local_bh_enable(); - return 0; - } - -@@ -1701,6 +1847,7 @@ int hrtimers_dead_cpu(unsigned int scpu) - void __init hrtimers_init(void) - { - hrtimers_prepare_cpu(smp_processor_id()); -+ open_softirq(HRTIMER_SOFTIRQ, hrtimer_run_softirq); - } - - /** --- -2.19.2 - diff --git a/kernel/patches-4.14.x-rt/0043-hrtimer-Implement-SOFT-HARD-clock-base-selection.patch b/kernel/patches-4.14.x-rt/0043-hrtimer-Implement-SOFT-HARD-clock-base-selection.patch deleted file mode 100644 index 7c1d6d7a3..000000000 --- a/kernel/patches-4.14.x-rt/0043-hrtimer-Implement-SOFT-HARD-clock-base-selection.patch +++ /dev/null @@ -1,61 +0,0 @@ -From 236c74d642c5fb89d4733b97b4f85ba6d1f98fde Mon Sep 17 00:00:00 2001 -From: Anna-Maria Gleixner -Date: Wed, 20 Dec 2017 17:13:18 +0100 -Subject: [PATCH 043/450] hrtimer: Implement SOFT/HARD clock base selection - -All prerequisites to handle hrtimers for expiry in either hard or soft -interrupt context are in place. - -Add the missing bit in hrtimer_init() which associates the timer to the -hard or the soft irq clock base. - -Signed-off-by: Anna-Maria Gleixner -Signed-off-by: Sebastian Andrzej Siewior ---- - kernel/time/hrtimer.c | 15 +++++++++++---- - 1 file changed, 11 insertions(+), 4 deletions(-) - -diff --git a/kernel/time/hrtimer.c b/kernel/time/hrtimer.c -index 66d7a12d7256..9947480ad731 100644 ---- a/kernel/time/hrtimer.c -+++ b/kernel/time/hrtimer.c -@@ -1222,8 +1222,9 @@ static inline int hrtimer_clockid_to_base(clockid_t clock_id) - static void __hrtimer_init(struct hrtimer *timer, clockid_t clock_id, - enum hrtimer_mode mode) - { -+ bool softtimer = !!(mode & HRTIMER_MODE_SOFT); -+ int base = softtimer ? HRTIMER_MAX_CLOCK_BASES / 2 : 0; - struct hrtimer_cpu_base *cpu_base; -- int base; - - memset(timer, 0, sizeof(struct hrtimer)); - -@@ -1237,7 +1238,8 @@ static void __hrtimer_init(struct hrtimer *timer, clockid_t clock_id, - if (clock_id == CLOCK_REALTIME && mode & HRTIMER_MODE_REL) - clock_id = CLOCK_MONOTONIC; - -- base = hrtimer_clockid_to_base(clock_id); -+ base += hrtimer_clockid_to_base(clock_id); -+ timer->is_soft = softtimer; - timer->base = &cpu_base->clock_base[base]; - timerqueue_init(&timer->node); - } -@@ -1246,8 +1248,13 @@ static void __hrtimer_init(struct hrtimer *timer, clockid_t clock_id, - * hrtimer_init - initialize a timer to the given clock - * @timer: the timer to be initialized - * @clock_id: the clock to be used -- * @mode: timer mode: absolute (HRTIMER_MODE_ABS) or -- * relative (HRTIMER_MODE_REL); pinned is not considered here! -+ * @mode: The modes which are relevant for intitialization: -+ * HRTIMER_MODE_ABS, HRTIMER_MODE_REL, HRTIMER_MODE_ABS_SOFT, -+ * HRTIMER_MODE_REL_SOFT -+ * -+ * The PINNED variants of the above can be handed in, -+ * but the PINNED bit is ignored as pinning happens -+ * when the hrtimer is started - */ - void hrtimer_init(struct hrtimer *timer, clockid_t clock_id, - enum hrtimer_mode mode) --- -2.19.2 - diff --git a/kernel/patches-4.14.x-rt/0044-can-bcm-Replace-hrtimer_tasklet-with-softirq-based-h.patch b/kernel/patches-4.14.x-rt/0044-can-bcm-Replace-hrtimer_tasklet-with-softirq-based-h.patch deleted file mode 100644 index 8f9b679c5..000000000 --- a/kernel/patches-4.14.x-rt/0044-can-bcm-Replace-hrtimer_tasklet-with-softirq-based-h.patch +++ /dev/null @@ -1,321 +0,0 @@ -From 53707523d5193b8dd4a0fb417bf4a09edc811c6c Mon Sep 17 00:00:00 2001 -From: Thomas Gleixner -Date: Thu, 23 Nov 2017 16:39:11 +0100 -Subject: [PATCH 044/450] can/bcm: Replace hrtimer_tasklet with softirq based - hrtimer - -Switch the timer to HRTIMER_MODE_SOFT, which executed the timer -callback in softirq context and remove the hrtimer_tasklet. - -Signed-off-by: Thomas Gleixner -Signed-off-by: Anna-Maria Gleixner -Signed-off-by: Thomas Gleixner -Cc: Oliver Hartkopp -Cc: Marc Kleine-Budde -Cc: linux-can@vger.kernel.org -Signed-off-by: Sebastian Andrzej Siewior ---- - net/can/bcm.c | 156 +++++++++++++++++--------------------------------- - 1 file changed, 52 insertions(+), 104 deletions(-) - -diff --git a/net/can/bcm.c b/net/can/bcm.c -index 13690334efa3..9cc67ac257f1 100644 ---- a/net/can/bcm.c -+++ b/net/can/bcm.c -@@ -102,7 +102,6 @@ struct bcm_op { - unsigned long frames_abs, frames_filtered; - struct bcm_timeval ival1, ival2; - struct hrtimer timer, thrtimer; -- struct tasklet_struct tsklet, thrtsklet; - ktime_t rx_stamp, kt_ival1, kt_ival2, kt_lastmsg; - int rx_ifindex; - int cfsiz; -@@ -364,25 +363,34 @@ static void bcm_send_to_user(struct bcm_op *op, struct bcm_msg_head *head, - } - } - --static void bcm_tx_start_timer(struct bcm_op *op) -+static bool bcm_tx_set_expiry(struct bcm_op *op, struct hrtimer *hrt) - { -+ ktime_t ival; -+ - if (op->kt_ival1 && op->count) -- hrtimer_start(&op->timer, -- ktime_add(ktime_get(), op->kt_ival1), -- HRTIMER_MODE_ABS); -+ ival = op->kt_ival1; - else if (op->kt_ival2) -- hrtimer_start(&op->timer, -- ktime_add(ktime_get(), op->kt_ival2), -- HRTIMER_MODE_ABS); -+ ival = op->kt_ival2; -+ else -+ return false; -+ -+ hrtimer_set_expires(hrt, ktime_add(ktime_get(), ival)); -+ return true; - } - --static void bcm_tx_timeout_tsklet(unsigned long data) -+static void bcm_tx_start_timer(struct bcm_op *op) - { -- struct bcm_op *op = (struct bcm_op *)data; -+ if (bcm_tx_set_expiry(op, &op->timer)) -+ hrtimer_start_expires(&op->timer, HRTIMER_MODE_ABS_SOFT); -+} -+ -+/* bcm_tx_timeout_handler - performs cyclic CAN frame transmissions */ -+static enum hrtimer_restart bcm_tx_timeout_handler(struct hrtimer *hrtimer) -+{ -+ struct bcm_op *op = container_of(hrtimer, struct bcm_op, timer); - struct bcm_msg_head msg_head; - - if (op->kt_ival1 && (op->count > 0)) { -- - op->count--; - if (!op->count && (op->flags & TX_COUNTEVT)) { - -@@ -399,22 +407,12 @@ static void bcm_tx_timeout_tsklet(unsigned long data) - } - bcm_can_tx(op); - -- } else if (op->kt_ival2) -+ } else if (op->kt_ival2) { - bcm_can_tx(op); -+ } - -- bcm_tx_start_timer(op); --} -- --/* -- * bcm_tx_timeout_handler - performs cyclic CAN frame transmissions -- */ --static enum hrtimer_restart bcm_tx_timeout_handler(struct hrtimer *hrtimer) --{ -- struct bcm_op *op = container_of(hrtimer, struct bcm_op, timer); -- -- tasklet_schedule(&op->tsklet); -- -- return HRTIMER_NORESTART; -+ return bcm_tx_set_expiry(op, &op->timer) ? -+ HRTIMER_RESTART : HRTIMER_NORESTART; - } - - /* -@@ -480,7 +478,7 @@ static void bcm_rx_update_and_send(struct bcm_op *op, - /* do not send the saved data - only start throttle timer */ - hrtimer_start(&op->thrtimer, - ktime_add(op->kt_lastmsg, op->kt_ival2), -- HRTIMER_MODE_ABS); -+ HRTIMER_MODE_ABS_SOFT); - return; - } - -@@ -539,14 +537,21 @@ static void bcm_rx_starttimer(struct bcm_op *op) - return; - - if (op->kt_ival1) -- hrtimer_start(&op->timer, op->kt_ival1, HRTIMER_MODE_REL); -+ hrtimer_start(&op->timer, op->kt_ival1, HRTIMER_MODE_REL_SOFT); - } - --static void bcm_rx_timeout_tsklet(unsigned long data) -+/* bcm_rx_timeout_handler - when the (cyclic) CAN frame reception timed out */ -+static enum hrtimer_restart bcm_rx_timeout_handler(struct hrtimer *hrtimer) - { -- struct bcm_op *op = (struct bcm_op *)data; -+ struct bcm_op *op = container_of(hrtimer, struct bcm_op, timer); - struct bcm_msg_head msg_head; - -+ /* if user wants to be informed, when cyclic CAN-Messages come back */ -+ if ((op->flags & RX_ANNOUNCE_RESUME) && op->last_frames) { -+ /* clear received CAN frames to indicate 'nothing received' */ -+ memset(op->last_frames, 0, op->nframes * op->cfsiz); -+ } -+ - /* create notification to user */ - msg_head.opcode = RX_TIMEOUT; - msg_head.flags = op->flags; -@@ -557,25 +562,6 @@ static void bcm_rx_timeout_tsklet(unsigned long data) - msg_head.nframes = 0; - - bcm_send_to_user(op, &msg_head, NULL, 0); --} -- --/* -- * bcm_rx_timeout_handler - when the (cyclic) CAN frame reception timed out -- */ --static enum hrtimer_restart bcm_rx_timeout_handler(struct hrtimer *hrtimer) --{ -- struct bcm_op *op = container_of(hrtimer, struct bcm_op, timer); -- -- /* schedule before NET_RX_SOFTIRQ */ -- tasklet_hi_schedule(&op->tsklet); -- -- /* no restart of the timer is done here! */ -- -- /* if user wants to be informed, when cyclic CAN-Messages come back */ -- if ((op->flags & RX_ANNOUNCE_RESUME) && op->last_frames) { -- /* clear received CAN frames to indicate 'nothing received' */ -- memset(op->last_frames, 0, op->nframes * op->cfsiz); -- } - - return HRTIMER_NORESTART; - } -@@ -583,14 +569,12 @@ static enum hrtimer_restart bcm_rx_timeout_handler(struct hrtimer *hrtimer) - /* - * bcm_rx_do_flush - helper for bcm_rx_thr_flush - */ --static inline int bcm_rx_do_flush(struct bcm_op *op, int update, -- unsigned int index) -+static inline int bcm_rx_do_flush(struct bcm_op *op, unsigned int index) - { - struct canfd_frame *lcf = op->last_frames + op->cfsiz * index; - - if ((op->last_frames) && (lcf->flags & RX_THR)) { -- if (update) -- bcm_rx_changed(op, lcf); -+ bcm_rx_changed(op, lcf); - return 1; - } - return 0; -@@ -598,11 +582,8 @@ static inline int bcm_rx_do_flush(struct bcm_op *op, int update, - - /* - * bcm_rx_thr_flush - Check for throttled data and send it to the userspace -- * -- * update == 0 : just check if throttled data is available (any irq context) -- * update == 1 : check and send throttled data to userspace (soft_irq context) - */ --static int bcm_rx_thr_flush(struct bcm_op *op, int update) -+static int bcm_rx_thr_flush(struct bcm_op *op) - { - int updated = 0; - -@@ -611,24 +592,16 @@ static int bcm_rx_thr_flush(struct bcm_op *op, int update) - - /* for MUX filter we start at index 1 */ - for (i = 1; i < op->nframes; i++) -- updated += bcm_rx_do_flush(op, update, i); -+ updated += bcm_rx_do_flush(op, i); - - } else { - /* for RX_FILTER_ID and simple filter */ -- updated += bcm_rx_do_flush(op, update, 0); -+ updated += bcm_rx_do_flush(op, 0); - } - - return updated; - } - --static void bcm_rx_thr_tsklet(unsigned long data) --{ -- struct bcm_op *op = (struct bcm_op *)data; -- -- /* push the changed data to the userspace */ -- bcm_rx_thr_flush(op, 1); --} -- - /* - * bcm_rx_thr_handler - the time for blocked content updates is over now: - * Check for throttled data and send it to the userspace -@@ -637,9 +610,7 @@ static enum hrtimer_restart bcm_rx_thr_handler(struct hrtimer *hrtimer) - { - struct bcm_op *op = container_of(hrtimer, struct bcm_op, thrtimer); - -- tasklet_schedule(&op->thrtsklet); -- -- if (bcm_rx_thr_flush(op, 0)) { -+ if (bcm_rx_thr_flush(op)) { - hrtimer_forward(hrtimer, ktime_get(), op->kt_ival2); - return HRTIMER_RESTART; - } else { -@@ -735,23 +706,8 @@ static struct bcm_op *bcm_find_op(struct list_head *ops, - - static void bcm_remove_op(struct bcm_op *op) - { -- if (op->tsklet.func) { -- while (test_bit(TASKLET_STATE_SCHED, &op->tsklet.state) || -- test_bit(TASKLET_STATE_RUN, &op->tsklet.state) || -- hrtimer_active(&op->timer)) { -- hrtimer_cancel(&op->timer); -- tasklet_kill(&op->tsklet); -- } -- } -- -- if (op->thrtsklet.func) { -- while (test_bit(TASKLET_STATE_SCHED, &op->thrtsklet.state) || -- test_bit(TASKLET_STATE_RUN, &op->thrtsklet.state) || -- hrtimer_active(&op->thrtimer)) { -- hrtimer_cancel(&op->thrtimer); -- tasklet_kill(&op->thrtsklet); -- } -- } -+ hrtimer_cancel(&op->timer); -+ hrtimer_cancel(&op->thrtimer); - - if ((op->frames) && (op->frames != &op->sframe)) - kfree(op->frames); -@@ -979,15 +935,13 @@ static int bcm_tx_setup(struct bcm_msg_head *msg_head, struct msghdr *msg, - op->ifindex = ifindex; - - /* initialize uninitialized (kzalloc) structure */ -- hrtimer_init(&op->timer, CLOCK_MONOTONIC, HRTIMER_MODE_REL); -+ hrtimer_init(&op->timer, CLOCK_MONOTONIC, -+ HRTIMER_MODE_REL_SOFT); - op->timer.function = bcm_tx_timeout_handler; - -- /* initialize tasklet for tx countevent notification */ -- tasklet_init(&op->tsklet, bcm_tx_timeout_tsklet, -- (unsigned long) op); -- - /* currently unused in tx_ops */ -- hrtimer_init(&op->thrtimer, CLOCK_MONOTONIC, HRTIMER_MODE_REL); -+ hrtimer_init(&op->thrtimer, CLOCK_MONOTONIC, -+ HRTIMER_MODE_REL_SOFT); - - /* add this bcm_op to the list of the tx_ops */ - list_add(&op->list, &bo->tx_ops); -@@ -1150,20 +1104,14 @@ static int bcm_rx_setup(struct bcm_msg_head *msg_head, struct msghdr *msg, - op->rx_ifindex = ifindex; - - /* initialize uninitialized (kzalloc) structure */ -- hrtimer_init(&op->timer, CLOCK_MONOTONIC, HRTIMER_MODE_REL); -+ hrtimer_init(&op->timer, CLOCK_MONOTONIC, -+ HRTIMER_MODE_REL_SOFT); - op->timer.function = bcm_rx_timeout_handler; - -- /* initialize tasklet for rx timeout notification */ -- tasklet_init(&op->tsklet, bcm_rx_timeout_tsklet, -- (unsigned long) op); -- -- hrtimer_init(&op->thrtimer, CLOCK_MONOTONIC, HRTIMER_MODE_REL); -+ hrtimer_init(&op->thrtimer, CLOCK_MONOTONIC, -+ HRTIMER_MODE_REL_SOFT); - op->thrtimer.function = bcm_rx_thr_handler; - -- /* initialize tasklet for rx throttle handling */ -- tasklet_init(&op->thrtsklet, bcm_rx_thr_tsklet, -- (unsigned long) op); -- - /* add this bcm_op to the list of the rx_ops */ - list_add(&op->list, &bo->rx_ops); - -@@ -1209,12 +1157,12 @@ static int bcm_rx_setup(struct bcm_msg_head *msg_head, struct msghdr *msg, - */ - op->kt_lastmsg = 0; - hrtimer_cancel(&op->thrtimer); -- bcm_rx_thr_flush(op, 1); -+ bcm_rx_thr_flush(op); - } - - if ((op->flags & STARTTIMER) && op->kt_ival1) - hrtimer_start(&op->timer, op->kt_ival1, -- HRTIMER_MODE_REL); -+ HRTIMER_MODE_REL_SOFT); - } - - /* now we can register for can_ids, if we added a new bcm_op */ --- -2.19.2 - diff --git a/kernel/patches-4.14.x-rt/0045-mac80211_hwsim-Replace-hrtimer-tasklet-with-softirq-.patch b/kernel/patches-4.14.x-rt/0045-mac80211_hwsim-Replace-hrtimer-tasklet-with-softirq-.patch deleted file mode 100644 index 6fccd53af..000000000 --- a/kernel/patches-4.14.x-rt/0045-mac80211_hwsim-Replace-hrtimer-tasklet-with-softirq-.patch +++ /dev/null @@ -1,141 +0,0 @@ -From 342c4c04e0060c8e398dad26f9ca0abe9f9985b8 Mon Sep 17 00:00:00 2001 -From: Thomas Gleixner -Date: Thu, 23 Nov 2017 16:39:12 +0100 -Subject: [PATCH 045/450] mac80211_hwsim: Replace hrtimer tasklet with softirq - hrtimer - -Switch the timer to HRTIMER_MODE_SOFT, which executed the timer -callback in softirq context and remove the hrtimer_tasklet. - -Signed-off-by: Thomas Gleixner -Signed-off-by: Anna-Maria Gleixner -Cc: linux-wireless@vger.kernel.org -Cc: Johannes Berg -Cc: Kalle Valo -Signed-off-by: Sebastian Andrzej Siewior ---- - drivers/net/wireless/mac80211_hwsim.c | 44 ++++++++++++--------------- - 1 file changed, 20 insertions(+), 24 deletions(-) - -diff --git a/drivers/net/wireless/mac80211_hwsim.c b/drivers/net/wireless/mac80211_hwsim.c -index 477f9f2f6626..06dff45037fe 100644 ---- a/drivers/net/wireless/mac80211_hwsim.c -+++ b/drivers/net/wireless/mac80211_hwsim.c -@@ -537,7 +537,7 @@ struct mac80211_hwsim_data { - unsigned int rx_filter; - bool started, idle, scanning; - struct mutex mutex; -- struct tasklet_hrtimer beacon_timer; -+ struct hrtimer beacon_timer; - enum ps_mode { - PS_DISABLED, PS_ENABLED, PS_AUTO_POLL, PS_MANUAL_POLL - } ps; -@@ -1423,7 +1423,7 @@ static void mac80211_hwsim_stop(struct ieee80211_hw *hw) - { - struct mac80211_hwsim_data *data = hw->priv; - data->started = false; -- tasklet_hrtimer_cancel(&data->beacon_timer); -+ hrtimer_cancel(&data->beacon_timer); - wiphy_debug(hw->wiphy, "%s\n", __func__); - } - -@@ -1546,14 +1546,12 @@ static enum hrtimer_restart - mac80211_hwsim_beacon(struct hrtimer *timer) - { - struct mac80211_hwsim_data *data = -- container_of(timer, struct mac80211_hwsim_data, -- beacon_timer.timer); -+ container_of(timer, struct mac80211_hwsim_data, beacon_timer); - struct ieee80211_hw *hw = data->hw; - u64 bcn_int = data->beacon_int; -- ktime_t next_bcn; - - if (!data->started) -- goto out; -+ return HRTIMER_NORESTART; - - ieee80211_iterate_active_interfaces_atomic( - hw, IEEE80211_IFACE_ITER_NORMAL, -@@ -1565,11 +1563,9 @@ mac80211_hwsim_beacon(struct hrtimer *timer) - data->bcn_delta = 0; - } - -- next_bcn = ktime_add(hrtimer_get_expires(timer), -- ns_to_ktime(bcn_int * 1000)); -- tasklet_hrtimer_start(&data->beacon_timer, next_bcn, HRTIMER_MODE_ABS); --out: -- return HRTIMER_NORESTART; -+ hrtimer_forward(&data->beacon_timer, hrtimer_get_expires(timer), -+ ns_to_ktime(bcn_int * NSEC_PER_USEC)); -+ return HRTIMER_RESTART; - } - - static const char * const hwsim_chanwidths[] = { -@@ -1643,15 +1639,15 @@ static int mac80211_hwsim_config(struct ieee80211_hw *hw, u32 changed) - mutex_unlock(&data->mutex); - - if (!data->started || !data->beacon_int) -- tasklet_hrtimer_cancel(&data->beacon_timer); -- else if (!hrtimer_is_queued(&data->beacon_timer.timer)) { -+ hrtimer_cancel(&data->beacon_timer); -+ else if (!hrtimer_is_queued(&data->beacon_timer)) { - u64 tsf = mac80211_hwsim_get_tsf(hw, NULL); - u32 bcn_int = data->beacon_int; - u64 until_tbtt = bcn_int - do_div(tsf, bcn_int); - -- tasklet_hrtimer_start(&data->beacon_timer, -- ns_to_ktime(until_tbtt * 1000), -- HRTIMER_MODE_REL); -+ hrtimer_start(&data->beacon_timer, -+ ns_to_ktime(until_tbtt * 1000), -+ HRTIMER_MODE_REL_SOFT); - } - - return 0; -@@ -1714,7 +1710,7 @@ static void mac80211_hwsim_bss_info_changed(struct ieee80211_hw *hw, - info->enable_beacon, info->beacon_int); - vp->bcn_en = info->enable_beacon; - if (data->started && -- !hrtimer_is_queued(&data->beacon_timer.timer) && -+ !hrtimer_is_queued(&data->beacon_timer) && - info->enable_beacon) { - u64 tsf, until_tbtt; - u32 bcn_int; -@@ -1722,9 +1718,9 @@ static void mac80211_hwsim_bss_info_changed(struct ieee80211_hw *hw, - tsf = mac80211_hwsim_get_tsf(hw, vif); - bcn_int = data->beacon_int; - until_tbtt = bcn_int - do_div(tsf, bcn_int); -- tasklet_hrtimer_start(&data->beacon_timer, -- ns_to_ktime(until_tbtt * 1000), -- HRTIMER_MODE_REL); -+ hrtimer_start(&data->beacon_timer, -+ ns_to_ktime(until_tbtt * 1000), -+ HRTIMER_MODE_REL_SOFT); - } else if (!info->enable_beacon) { - unsigned int count = 0; - ieee80211_iterate_active_interfaces_atomic( -@@ -1733,7 +1729,7 @@ static void mac80211_hwsim_bss_info_changed(struct ieee80211_hw *hw, - wiphy_debug(hw->wiphy, " beaconing vifs remaining: %u", - count); - if (count == 0) { -- tasklet_hrtimer_cancel(&data->beacon_timer); -+ hrtimer_cancel(&data->beacon_timer); - data->beacon_int = 0; - } - } -@@ -2722,9 +2718,9 @@ static int mac80211_hwsim_new_radio(struct genl_info *info, - data->debugfs, - data, &hwsim_simulate_radar); - -- tasklet_hrtimer_init(&data->beacon_timer, -- mac80211_hwsim_beacon, -- CLOCK_MONOTONIC, HRTIMER_MODE_ABS); -+ hrtimer_init(&data->beacon_timer, CLOCK_MONOTONIC, -+ HRTIMER_MODE_ABS_SOFT); -+ data->beacon_timer.function = mac80211_hwsim_beacon; - - spin_lock_bh(&hwsim_radio_lock); - list_add_tail(&data->list, &hwsim_radios); --- -2.19.2 - diff --git a/kernel/patches-4.14.x-rt/0046-xfrm-Replace-hrtimer-tasklet-with-softirq-hrtimer.patch b/kernel/patches-4.14.x-rt/0046-xfrm-Replace-hrtimer-tasklet-with-softirq-hrtimer.patch deleted file mode 100644 index 3b0893c62..000000000 --- a/kernel/patches-4.14.x-rt/0046-xfrm-Replace-hrtimer-tasklet-with-softirq-hrtimer.patch +++ /dev/null @@ -1,140 +0,0 @@ -From a18cdb53cd5213258d37db709c0af9feb3e68341 Mon Sep 17 00:00:00 2001 -From: Thomas Gleixner -Date: Thu, 23 Nov 2017 16:39:13 +0100 -Subject: [PATCH 046/450] xfrm: Replace hrtimer tasklet with softirq hrtimer - -Switch the timer to HRTIMER_MODE_SOFT, which executed the timer -callback in softirq context and remove the hrtimer_tasklet. - -Signed-off-by: Thomas Gleixner -Signed-off-by: Anna-Maria Gleixner -Cc: Steffen Klassert -Cc: netdev@vger.kernel.org -Cc: Herbert Xu -Cc: "David S. Miller" -Signed-off-by: Sebastian Andrzej Siewior ---- - include/net/xfrm.h | 2 +- - net/xfrm/xfrm_state.c | 30 ++++++++++++++++++------------ - 2 files changed, 19 insertions(+), 13 deletions(-) - -diff --git a/include/net/xfrm.h b/include/net/xfrm.h -index db99efb2d1d0..a7b95ffbbf8b 100644 ---- a/include/net/xfrm.h -+++ b/include/net/xfrm.h -@@ -217,7 +217,7 @@ struct xfrm_state { - struct xfrm_stats stats; - - struct xfrm_lifetime_cur curlft; -- struct tasklet_hrtimer mtimer; -+ struct hrtimer mtimer; - - struct xfrm_state_offload xso; - -diff --git a/net/xfrm/xfrm_state.c b/net/xfrm/xfrm_state.c -index 6c4ec69e11a0..77f52dc790ec 100644 ---- a/net/xfrm/xfrm_state.c -+++ b/net/xfrm/xfrm_state.c -@@ -427,7 +427,7 @@ static void xfrm_put_mode(struct xfrm_mode *mode) - - static void xfrm_state_gc_destroy(struct xfrm_state *x) - { -- tasklet_hrtimer_cancel(&x->mtimer); -+ hrtimer_cancel(&x->mtimer); - del_timer_sync(&x->rtimer); - kfree(x->aead); - kfree(x->aalg); -@@ -472,8 +472,8 @@ static void xfrm_state_gc_task(struct work_struct *work) - - static enum hrtimer_restart xfrm_timer_handler(struct hrtimer *me) - { -- struct tasklet_hrtimer *thr = container_of(me, struct tasklet_hrtimer, timer); -- struct xfrm_state *x = container_of(thr, struct xfrm_state, mtimer); -+ struct xfrm_state *x = container_of(me, struct xfrm_state, mtimer); -+ enum hrtimer_restart ret = HRTIMER_NORESTART; - unsigned long now = get_seconds(); - long next = LONG_MAX; - int warn = 0; -@@ -537,7 +537,8 @@ static enum hrtimer_restart xfrm_timer_handler(struct hrtimer *me) - km_state_expired(x, 0, 0); - resched: - if (next != LONG_MAX) { -- tasklet_hrtimer_start(&x->mtimer, ktime_set(next, 0), HRTIMER_MODE_REL); -+ hrtimer_forward_now(&x->mtimer, ktime_set(next, 0)); -+ ret = HRTIMER_RESTART; - } - - goto out; -@@ -554,7 +555,7 @@ static enum hrtimer_restart xfrm_timer_handler(struct hrtimer *me) - - out: - spin_unlock(&x->lock); -- return HRTIMER_NORESTART; -+ return ret; - } - - static void xfrm_replay_timer_handler(unsigned long data); -@@ -573,8 +574,8 @@ struct xfrm_state *xfrm_state_alloc(struct net *net) - INIT_HLIST_NODE(&x->bydst); - INIT_HLIST_NODE(&x->bysrc); - INIT_HLIST_NODE(&x->byspi); -- tasklet_hrtimer_init(&x->mtimer, xfrm_timer_handler, -- CLOCK_BOOTTIME, HRTIMER_MODE_ABS); -+ hrtimer_init(&x->mtimer, CLOCK_BOOTTIME, HRTIMER_MODE_ABS_SOFT); -+ x->mtimer.function = xfrm_timer_handler; - setup_timer(&x->rtimer, xfrm_replay_timer_handler, - (unsigned long)x); - x->curlft.add_time = get_seconds(); -@@ -1031,7 +1032,9 @@ xfrm_state_find(const xfrm_address_t *daddr, const xfrm_address_t *saddr, - hlist_add_head_rcu(&x->byspi, net->xfrm.state_byspi + h); - } - x->lft.hard_add_expires_seconds = net->xfrm.sysctl_acq_expires; -- tasklet_hrtimer_start(&x->mtimer, ktime_set(net->xfrm.sysctl_acq_expires, 0), HRTIMER_MODE_REL); -+ hrtimer_start(&x->mtimer, -+ ktime_set(net->xfrm.sysctl_acq_expires, 0), -+ HRTIMER_MODE_REL_SOFT); - net->xfrm.state_num++; - xfrm_hash_grow_check(net, x->bydst.next != NULL); - spin_unlock_bh(&net->xfrm.xfrm_state_lock); -@@ -1142,7 +1145,7 @@ static void __xfrm_state_insert(struct xfrm_state *x) - hlist_add_head_rcu(&x->byspi, net->xfrm.state_byspi + h); - } - -- tasklet_hrtimer_start(&x->mtimer, ktime_set(1, 0), HRTIMER_MODE_REL); -+ hrtimer_start(&x->mtimer, ktime_set(1, 0), HRTIMER_MODE_REL_SOFT); - if (x->replay_maxage) - mod_timer(&x->rtimer, jiffies + x->replay_maxage); - -@@ -1246,7 +1249,9 @@ static struct xfrm_state *__find_acq_core(struct net *net, - x->mark.m = m->m; - x->lft.hard_add_expires_seconds = net->xfrm.sysctl_acq_expires; - xfrm_state_hold(x); -- tasklet_hrtimer_start(&x->mtimer, ktime_set(net->xfrm.sysctl_acq_expires, 0), HRTIMER_MODE_REL); -+ hrtimer_start(&x->mtimer, -+ ktime_set(net->xfrm.sysctl_acq_expires, 0), -+ HRTIMER_MODE_REL_SOFT); - list_add(&x->km.all, &net->xfrm.state_all); - hlist_add_head_rcu(&x->bydst, net->xfrm.state_bydst + h); - h = xfrm_src_hash(net, daddr, saddr, family); -@@ -1546,7 +1551,8 @@ int xfrm_state_update(struct xfrm_state *x) - memcpy(&x1->lft, &x->lft, sizeof(x1->lft)); - x1->km.dying = 0; - -- tasklet_hrtimer_start(&x1->mtimer, ktime_set(1, 0), HRTIMER_MODE_REL); -+ hrtimer_start(&x1->mtimer, ktime_set(1, 0), -+ HRTIMER_MODE_REL_SOFT); - if (x1->curlft.use_time) - xfrm_state_check_expire(x1); - -@@ -1570,7 +1576,7 @@ int xfrm_state_check_expire(struct xfrm_state *x) - if (x->curlft.bytes >= x->lft.hard_byte_limit || - x->curlft.packets >= x->lft.hard_packet_limit) { - x->km.state = XFRM_STATE_EXPIRED; -- tasklet_hrtimer_start(&x->mtimer, 0, HRTIMER_MODE_REL); -+ hrtimer_start(&x->mtimer, 0, HRTIMER_MODE_REL_SOFT); - return -EINVAL; - } - --- -2.19.2 - diff --git a/kernel/patches-4.14.x-rt/0047-softirq-Remove-tasklet_hrtimer.patch b/kernel/patches-4.14.x-rt/0047-softirq-Remove-tasklet_hrtimer.patch deleted file mode 100644 index fcd8bdfa5..000000000 --- a/kernel/patches-4.14.x-rt/0047-softirq-Remove-tasklet_hrtimer.patch +++ /dev/null @@ -1,117 +0,0 @@ -From 7e36685a07adb7a6bb5e1c8ca09b359dad8ba444 Mon Sep 17 00:00:00 2001 -From: Thomas Gleixner -Date: Thu, 23 Nov 2017 16:39:14 +0100 -Subject: [PATCH 047/450] softirq: Remove tasklet_hrtimer - -There are no more tasklet_hrtimer users of this interface. -Remove it. - -Signed-off-by: Thomas Gleixner -Signed-off-by: Anna-Maria Gleixner -Signed-off-by: Sebastian Andrzej Siewior ---- - include/linux/interrupt.h | 25 ------------------- - kernel/softirq.c | 51 --------------------------------------- - 2 files changed, 76 deletions(-) - -diff --git a/include/linux/interrupt.h b/include/linux/interrupt.h -index 69c238210325..af15bfd89598 100644 ---- a/include/linux/interrupt.h -+++ b/include/linux/interrupt.h -@@ -618,31 +618,6 @@ extern void tasklet_kill_immediate(struct tasklet_struct *t, unsigned int cpu); - extern void tasklet_init(struct tasklet_struct *t, - void (*func)(unsigned long), unsigned long data); - --struct tasklet_hrtimer { -- struct hrtimer timer; -- struct tasklet_struct tasklet; -- enum hrtimer_restart (*function)(struct hrtimer *); --}; -- --extern void --tasklet_hrtimer_init(struct tasklet_hrtimer *ttimer, -- enum hrtimer_restart (*function)(struct hrtimer *), -- clockid_t which_clock, enum hrtimer_mode mode); -- --static inline --void tasklet_hrtimer_start(struct tasklet_hrtimer *ttimer, ktime_t time, -- const enum hrtimer_mode mode) --{ -- hrtimer_start(&ttimer->timer, time, mode); --} -- --static inline --void tasklet_hrtimer_cancel(struct tasklet_hrtimer *ttimer) --{ -- hrtimer_cancel(&ttimer->timer); -- tasklet_kill(&ttimer->tasklet); --} -- - /* - * Autoprobing for irqs: - * -diff --git a/kernel/softirq.c b/kernel/softirq.c -index a4c87cf27f9d..1a5dfc8dcf49 100644 ---- a/kernel/softirq.c -+++ b/kernel/softirq.c -@@ -588,57 +588,6 @@ void tasklet_kill(struct tasklet_struct *t) - } - EXPORT_SYMBOL(tasklet_kill); - --/* -- * tasklet_hrtimer -- */ -- --/* -- * The trampoline is called when the hrtimer expires. It schedules a tasklet -- * to run __tasklet_hrtimer_trampoline() which in turn will call the intended -- * hrtimer callback, but from softirq context. -- */ --static enum hrtimer_restart __hrtimer_tasklet_trampoline(struct hrtimer *timer) --{ -- struct tasklet_hrtimer *ttimer = -- container_of(timer, struct tasklet_hrtimer, timer); -- -- tasklet_hi_schedule(&ttimer->tasklet); -- return HRTIMER_NORESTART; --} -- --/* -- * Helper function which calls the hrtimer callback from -- * tasklet/softirq context -- */ --static void __tasklet_hrtimer_trampoline(unsigned long data) --{ -- struct tasklet_hrtimer *ttimer = (void *)data; -- enum hrtimer_restart restart; -- -- restart = ttimer->function(&ttimer->timer); -- if (restart != HRTIMER_NORESTART) -- hrtimer_restart(&ttimer->timer); --} -- --/** -- * tasklet_hrtimer_init - Init a tasklet/hrtimer combo for softirq callbacks -- * @ttimer: tasklet_hrtimer which is initialized -- * @function: hrtimer callback function which gets called from softirq context -- * @which_clock: clock id (CLOCK_MONOTONIC/CLOCK_REALTIME) -- * @mode: hrtimer mode (HRTIMER_MODE_ABS/HRTIMER_MODE_REL) -- */ --void tasklet_hrtimer_init(struct tasklet_hrtimer *ttimer, -- enum hrtimer_restart (*function)(struct hrtimer *), -- clockid_t which_clock, enum hrtimer_mode mode) --{ -- hrtimer_init(&ttimer->timer, which_clock, mode); -- ttimer->timer.function = __hrtimer_tasklet_trampoline; -- tasklet_init(&ttimer->tasklet, __tasklet_hrtimer_trampoline, -- (unsigned long)ttimer); -- ttimer->function = function; --} --EXPORT_SYMBOL_GPL(tasklet_hrtimer_init); -- - void __init softirq_init(void) - { - int cpu; --- -2.19.2 - diff --git a/kernel/patches-4.14.x-rt/0048-ALSA-dummy-Replace-tasklet-with-softirq-hrtimer.patch b/kernel/patches-4.14.x-rt/0048-ALSA-dummy-Replace-tasklet-with-softirq-hrtimer.patch deleted file mode 100644 index 6bd8e2651..000000000 --- a/kernel/patches-4.14.x-rt/0048-ALSA-dummy-Replace-tasklet-with-softirq-hrtimer.patch +++ /dev/null @@ -1,105 +0,0 @@ -From 3ebe79e022f917a7461c7785d2882e578c34f094 Mon Sep 17 00:00:00 2001 -From: Thomas Gleixner -Date: Thu, 23 Nov 2017 16:39:15 +0100 -Subject: [PATCH 048/450] ALSA/dummy: Replace tasklet with softirq hrtimer - -The tasklet is used to defer the execution of snd_pcm_period_elapsed() to -the softirq context. Using the HRTIMER_MODE_SOFT mode invokes the timer -callback in softirq context as well which renders the tasklet useless. - -[o-takashi: avoid stall due to a call of hrtimer_cancel() on a callback - of hrtimer] - -Signed-off-by: Thomas Gleixner -Signed-off-by: Anna-Maria Gleixner -Cc: alsa-devel@alsa-project.org -Cc: Takashi Sakamoto -Cc: Takashi Iwai -Cc: Jaroslav Kysela -Link: http://lkml.kernel.org/r/20170905161820.jtysvxtfleunbbmf@breakpoint.cc -Signed-off-by: Sebastian Andrzej Siewior ---- - sound/drivers/dummy.c | 27 ++++++++++++--------------- - 1 file changed, 12 insertions(+), 15 deletions(-) - -diff --git a/sound/drivers/dummy.c b/sound/drivers/dummy.c -index c0939a0164a6..549e014ecc0d 100644 ---- a/sound/drivers/dummy.c -+++ b/sound/drivers/dummy.c -@@ -376,17 +376,9 @@ struct dummy_hrtimer_pcm { - ktime_t period_time; - atomic_t running; - struct hrtimer timer; -- struct tasklet_struct tasklet; - struct snd_pcm_substream *substream; - }; - --static void dummy_hrtimer_pcm_elapsed(unsigned long priv) --{ -- struct dummy_hrtimer_pcm *dpcm = (struct dummy_hrtimer_pcm *)priv; -- if (atomic_read(&dpcm->running)) -- snd_pcm_period_elapsed(dpcm->substream); --} -- - static enum hrtimer_restart dummy_hrtimer_callback(struct hrtimer *timer) - { - struct dummy_hrtimer_pcm *dpcm; -@@ -394,7 +386,14 @@ static enum hrtimer_restart dummy_hrtimer_callback(struct hrtimer *timer) - dpcm = container_of(timer, struct dummy_hrtimer_pcm, timer); - if (!atomic_read(&dpcm->running)) - return HRTIMER_NORESTART; -- tasklet_schedule(&dpcm->tasklet); -+ /* -+ * In cases of XRUN and draining, this calls .trigger to stop PCM -+ * substream. -+ */ -+ snd_pcm_period_elapsed(dpcm->substream); -+ if (!atomic_read(&dpcm->running)) -+ return HRTIMER_NORESTART; -+ - hrtimer_forward_now(timer, dpcm->period_time); - return HRTIMER_RESTART; - } -@@ -404,7 +403,7 @@ static int dummy_hrtimer_start(struct snd_pcm_substream *substream) - struct dummy_hrtimer_pcm *dpcm = substream->runtime->private_data; - - dpcm->base_time = hrtimer_cb_get_time(&dpcm->timer); -- hrtimer_start(&dpcm->timer, dpcm->period_time, HRTIMER_MODE_REL); -+ hrtimer_start(&dpcm->timer, dpcm->period_time, HRTIMER_MODE_REL_SOFT); - atomic_set(&dpcm->running, 1); - return 0; - } -@@ -414,14 +413,14 @@ static int dummy_hrtimer_stop(struct snd_pcm_substream *substream) - struct dummy_hrtimer_pcm *dpcm = substream->runtime->private_data; - - atomic_set(&dpcm->running, 0); -- hrtimer_cancel(&dpcm->timer); -+ if (!hrtimer_callback_running(&dpcm->timer)) -+ hrtimer_cancel(&dpcm->timer); - return 0; - } - - static inline void dummy_hrtimer_sync(struct dummy_hrtimer_pcm *dpcm) - { - hrtimer_cancel(&dpcm->timer); -- tasklet_kill(&dpcm->tasklet); - } - - static snd_pcm_uframes_t -@@ -466,12 +465,10 @@ static int dummy_hrtimer_create(struct snd_pcm_substream *substream) - if (!dpcm) - return -ENOMEM; - substream->runtime->private_data = dpcm; -- hrtimer_init(&dpcm->timer, CLOCK_MONOTONIC, HRTIMER_MODE_REL); -+ hrtimer_init(&dpcm->timer, CLOCK_MONOTONIC, HRTIMER_MODE_REL_SOFT); - dpcm->timer.function = dummy_hrtimer_callback; - dpcm->substream = substream; - atomic_set(&dpcm->running, 0); -- tasklet_init(&dpcm->tasklet, dummy_hrtimer_pcm_elapsed, -- (unsigned long)dpcm); - return 0; - } - --- -2.19.2 - diff --git a/kernel/patches-4.14.x-rt/0049-usb-gadget-NCM-Replace-tasklet-with-softirq-hrtimer.patch b/kernel/patches-4.14.x-rt/0049-usb-gadget-NCM-Replace-tasklet-with-softirq-hrtimer.patch deleted file mode 100644 index d8c1d2136..000000000 --- a/kernel/patches-4.14.x-rt/0049-usb-gadget-NCM-Replace-tasklet-with-softirq-hrtimer.patch +++ /dev/null @@ -1,102 +0,0 @@ -From 9e2909d68eb94cf781688f66472b85e95a8aebde Mon Sep 17 00:00:00 2001 -From: Thomas Gleixner -Date: Thu, 23 Nov 2017 16:39:16 +0100 -Subject: [PATCH 049/450] usb/gadget/NCM: Replace tasklet with softirq hrtimer - -The tx_tasklet tasklet is used in invoke the hrtimer (task_timer) in -softirq context. This can be also achieved without the tasklet but -with HRTIMER_MODE_SOFT as hrtimer mode. - -Signed-off-by: Thomas Gleixner -Signed-off-by: Anna-Maria Gleixner -Cc: Felipe Balbi -Cc: linux-usb@vger.kernel.org -Signed-off-by: Sebastian Andrzej Siewior ---- - drivers/usb/gadget/function/f_ncm.c | 30 +++++++---------------------- - 1 file changed, 7 insertions(+), 23 deletions(-) - -diff --git a/drivers/usb/gadget/function/f_ncm.c b/drivers/usb/gadget/function/f_ncm.c -index 45b334ceaf2e..5f24e6d3b6eb 100644 ---- a/drivers/usb/gadget/function/f_ncm.c -+++ b/drivers/usb/gadget/function/f_ncm.c -@@ -77,9 +77,7 @@ struct f_ncm { - struct sk_buff *skb_tx_ndp; - u16 ndp_dgram_count; - bool timer_force_tx; -- struct tasklet_struct tx_tasklet; - struct hrtimer task_timer; -- - bool timer_stopping; - }; - -@@ -1108,7 +1106,7 @@ static struct sk_buff *ncm_wrap_ntb(struct gether *port, - - /* Delay the timer. */ - hrtimer_start(&ncm->task_timer, TX_TIMEOUT_NSECS, -- HRTIMER_MODE_REL); -+ HRTIMER_MODE_REL_SOFT); - - /* Add the datagram position entries */ - ntb_ndp = skb_put_zero(ncm->skb_tx_ndp, dgram_idx_len); -@@ -1152,17 +1150,15 @@ static struct sk_buff *ncm_wrap_ntb(struct gether *port, - } - - /* -- * This transmits the NTB if there are frames waiting. -+ * The transmit should only be run if no skb data has been sent -+ * for a certain duration. - */ --static void ncm_tx_tasklet(unsigned long data) -+static enum hrtimer_restart ncm_tx_timeout(struct hrtimer *data) - { -- struct f_ncm *ncm = (void *)data; -- -- if (ncm->timer_stopping) -- return; -+ struct f_ncm *ncm = container_of(data, struct f_ncm, task_timer); - - /* Only send if data is available. */ -- if (ncm->skb_tx_data) { -+ if (!ncm->timer_stopping && ncm->skb_tx_data) { - ncm->timer_force_tx = true; - - /* XXX This allowance of a NULL skb argument to ndo_start_xmit -@@ -1175,16 +1171,6 @@ static void ncm_tx_tasklet(unsigned long data) - - ncm->timer_force_tx = false; - } --} -- --/* -- * The transmit should only be run if no skb data has been sent -- * for a certain duration. -- */ --static enum hrtimer_restart ncm_tx_timeout(struct hrtimer *data) --{ -- struct f_ncm *ncm = container_of(data, struct f_ncm, task_timer); -- tasklet_schedule(&ncm->tx_tasklet); - return HRTIMER_NORESTART; - } - -@@ -1517,8 +1503,7 @@ static int ncm_bind(struct usb_configuration *c, struct usb_function *f) - ncm->port.open = ncm_open; - ncm->port.close = ncm_close; - -- tasklet_init(&ncm->tx_tasklet, ncm_tx_tasklet, (unsigned long) ncm); -- hrtimer_init(&ncm->task_timer, CLOCK_MONOTONIC, HRTIMER_MODE_REL); -+ hrtimer_init(&ncm->task_timer, CLOCK_MONOTONIC, HRTIMER_MODE_REL_SOFT); - ncm->task_timer.function = ncm_tx_timeout; - - DBG(cdev, "CDC Network: %s speed IN/%s OUT/%s NOTIFY/%s\n", -@@ -1627,7 +1612,6 @@ static void ncm_unbind(struct usb_configuration *c, struct usb_function *f) - DBG(c->cdev, "ncm unbind\n"); - - hrtimer_cancel(&ncm->task_timer); -- tasklet_kill(&ncm->tx_tasklet); - - ncm_string_defs[0].id = 0; - usb_free_all_descriptors(f); --- -2.19.2 - diff --git a/kernel/patches-4.14.x-rt/0050-net-mvpp2-Replace-tasklet-with-softirq-hrtimer.patch b/kernel/patches-4.14.x-rt/0050-net-mvpp2-Replace-tasklet-with-softirq-hrtimer.patch deleted file mode 100644 index a544cada4..000000000 --- a/kernel/patches-4.14.x-rt/0050-net-mvpp2-Replace-tasklet-with-softirq-hrtimer.patch +++ /dev/null @@ -1,138 +0,0 @@ -From 5f46919e7892edef70b9289e2c8418e4f9ffe804 Mon Sep 17 00:00:00 2001 -From: Thomas Gleixner -Date: Thu, 23 Nov 2017 16:39:17 +0100 -Subject: [PATCH 050/450] net/mvpp2: Replace tasklet with softirq hrtimer - -The tx_done_tasklet tasklet is used in invoke the hrtimer -(mvpp2_hr_timer_cb) in softirq context. This can be also achieved without -the tasklet but with HRTIMER_MODE_SOFT as hrtimer mode. - -Signed-off-by: Thomas Gleixner -Signed-off-by: Anna-Maria Gleixner -Cc: Thomas Petazzoni -Cc: netdev@vger.kernel.org -Cc: "David S. Miller" -Signed-off-by: Sebastian Andrzej Siewior ---- - drivers/net/ethernet/marvell/mvpp2.c | 62 +++++++++++----------------- - 1 file changed, 25 insertions(+), 37 deletions(-) - -diff --git a/drivers/net/ethernet/marvell/mvpp2.c b/drivers/net/ethernet/marvell/mvpp2.c -index 00e6f1d155a6..9c69ab2c5b07 100644 ---- a/drivers/net/ethernet/marvell/mvpp2.c -+++ b/drivers/net/ethernet/marvell/mvpp2.c -@@ -831,9 +831,8 @@ struct mvpp2_pcpu_stats { - /* Per-CPU port control */ - struct mvpp2_port_pcpu { - struct hrtimer tx_done_timer; -+ struct net_device *dev; - bool timer_scheduled; -- /* Tasklet for egress finalization */ -- struct tasklet_struct tx_done_tasklet; - }; - - struct mvpp2_queue_vector { -@@ -5955,46 +5954,34 @@ static void mvpp2_link_event(struct net_device *dev) - } - } - --static void mvpp2_timer_set(struct mvpp2_port_pcpu *port_pcpu) --{ -- ktime_t interval; -- -- if (!port_pcpu->timer_scheduled) { -- port_pcpu->timer_scheduled = true; -- interval = MVPP2_TXDONE_HRTIMER_PERIOD_NS; -- hrtimer_start(&port_pcpu->tx_done_timer, interval, -- HRTIMER_MODE_REL_PINNED); -- } --} -- --static void mvpp2_tx_proc_cb(unsigned long data) -+static enum hrtimer_restart mvpp2_hr_timer_cb(struct hrtimer *timer) - { -- struct net_device *dev = (struct net_device *)data; -- struct mvpp2_port *port = netdev_priv(dev); -- struct mvpp2_port_pcpu *port_pcpu = this_cpu_ptr(port->pcpu); -+ struct net_device *dev; -+ struct mvpp2_port *port; -+ struct mvpp2_port_pcpu *port_pcpu; - unsigned int tx_todo, cause; - -+ port_pcpu = container_of(timer, struct mvpp2_port_pcpu, tx_done_timer); -+ dev = port_pcpu->dev; -+ - if (!netif_running(dev)) -- return; -+ return HRTIMER_NORESTART; -+ - port_pcpu->timer_scheduled = false; -+ port = netdev_priv(dev); - - /* Process all the Tx queues */ - cause = (1 << port->ntxqs) - 1; - tx_todo = mvpp2_tx_done(port, cause, smp_processor_id()); - - /* Set the timer in case not all the packets were processed */ -- if (tx_todo) -- mvpp2_timer_set(port_pcpu); --} -- --static enum hrtimer_restart mvpp2_hr_timer_cb(struct hrtimer *timer) --{ -- struct mvpp2_port_pcpu *port_pcpu = container_of(timer, -- struct mvpp2_port_pcpu, -- tx_done_timer); -- -- tasklet_schedule(&port_pcpu->tx_done_tasklet); -+ if (tx_todo && !port_pcpu->timer_scheduled) { -+ port_pcpu->timer_scheduled = true; -+ hrtimer_forward_now(&port_pcpu->tx_done_timer, -+ MVPP2_TXDONE_HRTIMER_PERIOD_NS); - -+ return HRTIMER_RESTART; -+ } - return HRTIMER_NORESTART; - } - -@@ -6484,7 +6471,12 @@ static int mvpp2_tx(struct sk_buff *skb, struct net_device *dev) - txq_pcpu->count > 0) { - struct mvpp2_port_pcpu *port_pcpu = this_cpu_ptr(port->pcpu); - -- mvpp2_timer_set(port_pcpu); -+ if (!port_pcpu->timer_scheduled) { -+ port_pcpu->timer_scheduled = true; -+ hrtimer_start(&port_pcpu->tx_done_timer, -+ MVPP2_TXDONE_HRTIMER_PERIOD_NS, -+ HRTIMER_MODE_REL_PINNED_SOFT); -+ } - } - - return NETDEV_TX_OK; -@@ -6875,7 +6867,6 @@ static int mvpp2_stop(struct net_device *dev) - - hrtimer_cancel(&port_pcpu->tx_done_timer); - port_pcpu->timer_scheduled = false; -- tasklet_kill(&port_pcpu->tx_done_tasklet); - } - } - mvpp2_cleanup_rxqs(port); -@@ -7648,13 +7639,10 @@ static int mvpp2_port_probe(struct platform_device *pdev, - port_pcpu = per_cpu_ptr(port->pcpu, cpu); - - hrtimer_init(&port_pcpu->tx_done_timer, CLOCK_MONOTONIC, -- HRTIMER_MODE_REL_PINNED); -+ HRTIMER_MODE_REL_PINNED_SOFT); - port_pcpu->tx_done_timer.function = mvpp2_hr_timer_cb; - port_pcpu->timer_scheduled = false; -- -- tasklet_init(&port_pcpu->tx_done_tasklet, -- mvpp2_tx_proc_cb, -- (unsigned long)dev); -+ port_pcpu->dev = dev; - } - } - --- -2.19.2 - diff --git a/kernel/patches-4.14.x-rt/0052-ARM-smp-Move-clear_tasks_mm_cpumask-call-to-__cpu_di.patch b/kernel/patches-4.14.x-rt/0052-ARM-smp-Move-clear_tasks_mm_cpumask-call-to-__cpu_di.patch deleted file mode 100644 index 4b36b7cd9..000000000 --- a/kernel/patches-4.14.x-rt/0052-ARM-smp-Move-clear_tasks_mm_cpumask-call-to-__cpu_di.patch +++ /dev/null @@ -1,91 +0,0 @@ -From 507ef937323c7aeb59dad74c200aaaa9f16e6150 Mon Sep 17 00:00:00 2001 -From: Grygorii Strashko -Date: Fri, 11 Sep 2015 21:21:23 +0300 -Subject: [PATCH 052/450] ARM: smp: Move clear_tasks_mm_cpumask() call to - __cpu_die() - -When running with the RT-kernel (4.1.5-rt5) on TI OMAP dra7-evm and trying -to do Suspend to RAM, the following backtrace occurs: - - Disabling non-boot CPUs ... - PM: noirq suspend of devices complete after 7.295 msecs - Disabling non-boot CPUs ... - BUG: sleeping function called from invalid context at kernel/locking/rtmutex.c:917 - in_atomic(): 1, irqs_disabled(): 128, pid: 18, name: migration/1 - INFO: lockdep is turned off. - irq event stamp: 122 - hardirqs last enabled at (121): [] _raw_spin_unlock_irqrestore+0x88/0x90 - hardirqs last disabled at (122): [] _raw_spin_lock_irq+0x28/0x5c - softirqs last enabled at (0): [] copy_process.part.52+0x410/0x19d8 - softirqs last disabled at (0): [< (null)>] (null) - Preemption disabled at:[< (null)>] (null) - CPU: 1 PID: 18 Comm: migration/1 Tainted: G W 4.1.4-rt3-01046-g96ac8da #204 - Hardware name: Generic DRA74X (Flattened Device Tree) - [] (unwind_backtrace) from [] (show_stack+0x20/0x24) - [] (show_stack) from [] (dump_stack+0x88/0xdc) - [] (dump_stack) from [] (___might_sleep+0x198/0x2a8) - [] (___might_sleep) from [] (rt_spin_lock+0x30/0x70) - [] (rt_spin_lock) from [] (find_lock_task_mm+0x9c/0x174) - [] (find_lock_task_mm) from [] (clear_tasks_mm_cpumask+0xb4/0x1ac) - [] (clear_tasks_mm_cpumask) from [] (__cpu_disable+0x98/0xbc) - [] (__cpu_disable) from [] (take_cpu_down+0x1c/0x50) - [] (take_cpu_down) from [] (multi_cpu_stop+0x11c/0x158) - [] (multi_cpu_stop) from [] (cpu_stopper_thread+0xc4/0x184) - [] (cpu_stopper_thread) from [] (smpboot_thread_fn+0x18c/0x324) - [] (smpboot_thread_fn) from [] (kthread+0xe8/0x104) - [] (kthread) from [] (ret_from_fork+0x14/0x3c) - CPU1: shutdown - PM: Calling sched_clock_suspend+0x0/0x40 - PM: Calling timekeeping_suspend+0x0/0x2e0 - PM: Calling irq_gc_suspend+0x0/0x68 - PM: Calling fw_suspend+0x0/0x2c - PM: Calling cpu_pm_suspend+0x0/0x28 - -Also, sometimes system stucks right after displaying "Disabling non-boot -CPUs ...". The root cause of above backtrace is task_lock() which takes -a sleeping lock on -RT. - -To fix the issue, move clear_tasks_mm_cpumask() call from __cpu_disable() -to __cpu_die() which is called on the thread which is asking for a target -CPU to be shutdown. In addition, this change restores CPUhotplug functionality -on TI OMAP dra7-evm and CPU1 can be unplugged/plugged many times. - -Signed-off-by: Grygorii Strashko -Cc: Steven Rostedt -Cc: -Cc: Sekhar Nori -Cc: Austin Schuh -Cc: -Cc: Russell King -Cc: -Cc: stable-rt@vger.kernel.org -Link: http://lkml.kernel.org/r/1441995683-30817-1-git-send-email-grygorii.strashko@ti.com -Signed-off-by: Thomas Gleixner ---- - arch/arm/kernel/smp.c | 3 +-- - 1 file changed, 1 insertion(+), 2 deletions(-) - -diff --git a/arch/arm/kernel/smp.c b/arch/arm/kernel/smp.c -index e61af0600133..d8f2e77d5651 100644 ---- a/arch/arm/kernel/smp.c -+++ b/arch/arm/kernel/smp.c -@@ -237,8 +237,6 @@ int __cpu_disable(void) - flush_cache_louis(); - local_flush_tlb_all(); - -- clear_tasks_mm_cpumask(cpu); -- - return 0; - } - -@@ -256,6 +254,7 @@ void __cpu_die(unsigned int cpu) - } - pr_debug("CPU%u: shutdown\n", cpu); - -+ clear_tasks_mm_cpumask(cpu); - /* - * platform_cpu_kill() is generally expected to do the powering off - * and/or cutting of clocks to the dying CPU. Optionally, this may --- -2.19.2 - diff --git a/kernel/patches-4.14.x-rt/0053-rtmutex-Handle-non-enqueued-waiters-gracefully.patch b/kernel/patches-4.14.x-rt/0053-rtmutex-Handle-non-enqueued-waiters-gracefully.patch deleted file mode 100644 index ebf6de77c..000000000 --- a/kernel/patches-4.14.x-rt/0053-rtmutex-Handle-non-enqueued-waiters-gracefully.patch +++ /dev/null @@ -1,37 +0,0 @@ -From 04d4c6f31743974003d211da27cfe093f8cb724d Mon Sep 17 00:00:00 2001 -From: Thomas Gleixner -Date: Fri, 6 Nov 2015 18:51:03 +0100 -Subject: [PATCH 053/450] rtmutex: Handle non enqueued waiters gracefully - -Yimin debugged that in case of a PI wakeup in progress when -rt_mutex_start_proxy_lock() calls task_blocks_on_rt_mutex() the latter -returns -EAGAIN and in consequence the remove_waiter() call runs into -a BUG_ON() because there is nothing to remove. - -Guard it with rt_mutex_has_waiters(). This is a quick fix which is -easy to backport. The proper fix is to have a central check in -remove_waiter() so we can call it unconditionally. - -Reported-and-debugged-by: Yimin Deng -Signed-off-by: Thomas Gleixner -Cc: stable-rt@vger.kernel.org ---- - kernel/locking/rtmutex.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/kernel/locking/rtmutex.c b/kernel/locking/rtmutex.c -index 456750bf9c95..a8119deef92e 100644 ---- a/kernel/locking/rtmutex.c -+++ b/kernel/locking/rtmutex.c -@@ -1750,7 +1750,7 @@ int __rt_mutex_start_proxy_lock(struct rt_mutex *lock, - ret = 0; - } - -- if (unlikely(ret)) -+ if (ret && rt_mutex_has_waiters(lock)) - remove_waiter(lock, waiter); - - debug_rt_mutex_print_deadlock(waiter); --- -2.19.2 - diff --git a/kernel/patches-4.14.x-rt/0054-rbtree-include-rcu.h-because-we-use-it.patch b/kernel/patches-4.14.x-rt/0054-rbtree-include-rcu.h-because-we-use-it.patch deleted file mode 100644 index 7bd729947..000000000 --- a/kernel/patches-4.14.x-rt/0054-rbtree-include-rcu.h-because-we-use-it.patch +++ /dev/null @@ -1,43 +0,0 @@ -From 3152ba2bf24f52a147556852a29522b67cb6ceb0 Mon Sep 17 00:00:00 2001 -From: Sebastian Andrzej Siewior -Date: Wed, 14 Sep 2016 11:52:17 +0200 -Subject: [PATCH 054/450] rbtree: include rcu.h because we use it - -Since commit c1adf20052d8 ("Introduce rb_replace_node_rcu()") -rbtree_augmented.h uses RCU related data structures but does not include -them. It works as long as gets somehow included before that and fails -otherwise. - -Signed-off-by: Sebastian Andrzej Siewior ---- - include/linux/rbtree_augmented.h | 1 + - include/linux/rbtree_latch.h | 1 + - 2 files changed, 2 insertions(+) - -diff --git a/include/linux/rbtree_augmented.h b/include/linux/rbtree_augmented.h -index 6bfd2b581f75..af8a61be2d8d 100644 ---- a/include/linux/rbtree_augmented.h -+++ b/include/linux/rbtree_augmented.h -@@ -26,6 +26,7 @@ - - #include - #include -+#include - - /* - * Please note - only struct rb_augment_callbacks and the prototypes for -diff --git a/include/linux/rbtree_latch.h b/include/linux/rbtree_latch.h -index ece43e882b56..7d012faa509a 100644 ---- a/include/linux/rbtree_latch.h -+++ b/include/linux/rbtree_latch.h -@@ -35,6 +35,7 @@ - - #include - #include -+#include - - struct latch_tree_node { - struct rb_node node[2]; --- -2.19.2 - diff --git a/kernel/patches-4.14.x-rt/0055-rxrpc-remove-unused-static-variables.patch b/kernel/patches-4.14.x-rt/0055-rxrpc-remove-unused-static-variables.patch deleted file mode 100644 index d8b9be98e..000000000 --- a/kernel/patches-4.14.x-rt/0055-rxrpc-remove-unused-static-variables.patch +++ /dev/null @@ -1,32 +0,0 @@ -From 0327ee53081aa5cda616879003e4817ee6d231d3 Mon Sep 17 00:00:00 2001 -From: Sebastian Andrzej Siewior -Date: Fri, 21 Oct 2016 10:54:50 +0200 -Subject: [PATCH 055/450] rxrpc: remove unused static variables - -The rxrpc_security_methods and rxrpc_security_sem user has been removed -in 648af7fca159 ("rxrpc: Absorb the rxkad security module"). This was -noticed by kbuild test robot for the -RT tree but is also true for !RT. - -Reported-by: kbuild test robot -Signed-off-by: Sebastian Andrzej Siewior ---- - net/rxrpc/security.c | 3 --- - 1 file changed, 3 deletions(-) - -diff --git a/net/rxrpc/security.c b/net/rxrpc/security.c -index e9f428351293..c4479afe8ae7 100644 ---- a/net/rxrpc/security.c -+++ b/net/rxrpc/security.c -@@ -19,9 +19,6 @@ - #include - #include "ar-internal.h" - --static LIST_HEAD(rxrpc_security_methods); --static DECLARE_RWSEM(rxrpc_security_sem); -- - static const struct rxrpc_security *rxrpc_security_types[] = { - [RXRPC_SECURITY_NONE] = &rxrpc_no_security, - #ifdef CONFIG_RXKAD --- -2.19.2 - diff --git a/kernel/patches-4.14.x-rt/0056-mfd-syscon-atmel-smc-include-string.h.patch b/kernel/patches-4.14.x-rt/0056-mfd-syscon-atmel-smc-include-string.h.patch deleted file mode 100644 index 6eb3a88df..000000000 --- a/kernel/patches-4.14.x-rt/0056-mfd-syscon-atmel-smc-include-string.h.patch +++ /dev/null @@ -1,28 +0,0 @@ -From fa6ce1fa81dfde47d57ea111931de106e2977ebc Mon Sep 17 00:00:00 2001 -From: Sebastian Andrzej Siewior -Date: Wed, 4 Oct 2017 09:55:58 +0200 -Subject: [PATCH 056/450] mfd: syscon: atmel-smc: include string.h - -The string.h header file is needed for the memset() definition. The RT -build fails because it is not pulled in via other header files. - -Signed-off-by: Sebastian Andrzej Siewior ---- - drivers/mfd/atmel-smc.c | 1 + - 1 file changed, 1 insertion(+) - -diff --git a/drivers/mfd/atmel-smc.c b/drivers/mfd/atmel-smc.c -index 7d77948567d7..0adbd2e796fe 100644 ---- a/drivers/mfd/atmel-smc.c -+++ b/drivers/mfd/atmel-smc.c -@@ -12,6 +12,7 @@ - */ - - #include -+#include - - /** - * atmel_smc_cs_conf_init - initialize a SMC CS conf --- -2.19.2 - diff --git a/kernel/patches-4.14.x-rt/0057-sched-swait-include-wait.h.patch b/kernel/patches-4.14.x-rt/0057-sched-swait-include-wait.h.patch deleted file mode 100644 index c2008fb58..000000000 --- a/kernel/patches-4.14.x-rt/0057-sched-swait-include-wait.h.patch +++ /dev/null @@ -1,41 +0,0 @@ -From 307536cbf7b07eeaf5582bf169c3a2b235720280 Mon Sep 17 00:00:00 2001 -From: Sebastian Andrzej Siewior -Date: Mon, 4 Dec 2017 13:11:10 +0100 -Subject: [PATCH 057/450] sched/swait: include wait.h - -kbuild bot reported against an intermediate RT patch that the build -fails with: - -> In file included from include/linux/completion.h:12:0, -> from include/linux/rcupdate_wait.h:10, -> from kernel/rcu/srcutiny.c:27: -> kernel/rcu/srcutiny.c: In function 'srcu_drive_gp': -> >> include/linux/swait.h:172:7: error: implicit declaration of function '___wait_is_interruptible'; did you mean '__swait_event_interruptible'? -> if (___wait_is_interruptible(state) && __int) { \ - -That error vanishes a few patches later (in the RT queue) because wait.h -is then pulled in by other means. It does not seem to surface on !RT. -I think that swait should include a header file for a function/macro -(___wait_is_interruptible()) it is using. - -Reported-by: kbuild test robot -Signed-off-by: Sebastian Andrzej Siewior ---- - include/linux/swait.h | 1 + - 1 file changed, 1 insertion(+) - -diff --git a/include/linux/swait.h b/include/linux/swait.h -index c98aaf677466..84f9745365ff 100644 ---- a/include/linux/swait.h -+++ b/include/linux/swait.h -@@ -5,6 +5,7 @@ - #include - #include - #include -+#include - #include - - /* --- -2.19.2 - diff --git a/kernel/patches-4.14.x-rt/0059-Bluetooth-avoid-recursive-locking-in-hci_send_to_cha.patch b/kernel/patches-4.14.x-rt/0059-Bluetooth-avoid-recursive-locking-in-hci_send_to_cha.patch deleted file mode 100644 index 2fe3f49ef..000000000 --- a/kernel/patches-4.14.x-rt/0059-Bluetooth-avoid-recursive-locking-in-hci_send_to_cha.patch +++ /dev/null @@ -1,76 +0,0 @@ -From 993ed674f91546159ccd72fcfccb05b7179df734 Mon Sep 17 00:00:00 2001 -From: Sebastian Andrzej Siewior -Date: Thu, 21 Sep 2017 15:35:57 +0200 -Subject: [PATCH 059/450] Bluetooth: avoid recursive locking in - hci_send_to_channel() - -Mart reported a deadlock in -RT in the call path: - hci_send_monitor_ctrl_event() -> hci_send_to_channel() - -because both functions acquire the same read lock hci_sk_list.lock. This -is also a mainline issue because the qrwlock implementation is writer -fair (the traditional rwlock implementation is reader biased). - -To avoid the deadlock there is now __hci_send_to_channel() which expects -the readlock to be held. - -Cc: Marcel Holtmann -Cc: Johan Hedberg -Cc: stable-rt@vger.kernel.org -Fixes: 38ceaa00d02d ("Bluetooth: Add support for sending MGMT commands and events to monitor") -Reported-by: Mart van de Wege -Signed-off-by: Sebastian Andrzej Siewior ---- - net/bluetooth/hci_sock.c | 17 +++++++++++------ - 1 file changed, 11 insertions(+), 6 deletions(-) - -diff --git a/net/bluetooth/hci_sock.c b/net/bluetooth/hci_sock.c -index 65d734c165bd..923e9a271872 100644 ---- a/net/bluetooth/hci_sock.c -+++ b/net/bluetooth/hci_sock.c -@@ -251,15 +251,13 @@ void hci_send_to_sock(struct hci_dev *hdev, struct sk_buff *skb) - } - - /* Send frame to sockets with specific channel */ --void hci_send_to_channel(unsigned short channel, struct sk_buff *skb, -- int flag, struct sock *skip_sk) -+static void __hci_send_to_channel(unsigned short channel, struct sk_buff *skb, -+ int flag, struct sock *skip_sk) - { - struct sock *sk; - - BT_DBG("channel %u len %d", channel, skb->len); - -- read_lock(&hci_sk_list.lock); -- - sk_for_each(sk, &hci_sk_list.head) { - struct sk_buff *nskb; - -@@ -285,6 +283,13 @@ void hci_send_to_channel(unsigned short channel, struct sk_buff *skb, - kfree_skb(nskb); - } - -+} -+ -+void hci_send_to_channel(unsigned short channel, struct sk_buff *skb, -+ int flag, struct sock *skip_sk) -+{ -+ read_lock(&hci_sk_list.lock); -+ __hci_send_to_channel(channel, skb, flag, skip_sk); - read_unlock(&hci_sk_list.lock); - } - -@@ -388,8 +393,8 @@ void hci_send_monitor_ctrl_event(struct hci_dev *hdev, u16 event, - hdr->index = index; - hdr->len = cpu_to_le16(skb->len - HCI_MON_HDR_SIZE); - -- hci_send_to_channel(HCI_CHANNEL_MONITOR, skb, -- HCI_SOCK_TRUSTED, NULL); -+ __hci_send_to_channel(HCI_CHANNEL_MONITOR, skb, -+ HCI_SOCK_TRUSTED, NULL); - kfree_skb(skb); - } - --- -2.19.2 - diff --git a/kernel/patches-4.14.x-rt/0060-iommu-iova-Use-raw_cpu_ptr-instead-of-get_cpu_ptr-fo.patch b/kernel/patches-4.14.x-rt/0060-iommu-iova-Use-raw_cpu_ptr-instead-of-get_cpu_ptr-fo.patch deleted file mode 100644 index 1d2d3868c..000000000 --- a/kernel/patches-4.14.x-rt/0060-iommu-iova-Use-raw_cpu_ptr-instead-of-get_cpu_ptr-fo.patch +++ /dev/null @@ -1,48 +0,0 @@ -From fdbd8254ab62179f7aee6033e4ff8353b4ade395 Mon Sep 17 00:00:00 2001 -From: Sebastian Andrzej Siewior -Date: Thu, 21 Sep 2017 17:21:40 +0200 -Subject: [PATCH 060/450] iommu/iova: Use raw_cpu_ptr() instead of - get_cpu_ptr() for ->fq - -get_cpu_ptr() disabled preemption and returns the ->fq object of the -current CPU. raw_cpu_ptr() does the same except that it not disable -preemption which means the scheduler can move it to another CPU after it -obtained the per-CPU object. -In this case this is not bad because the data structure itself is -protected with a spin_lock. This change shouldn't matter however on RT -it does because the sleeping lock can't be accessed with disabled -preemption. - -Cc: Joerg Roedel -Cc: iommu@lists.linux-foundation.org -Reported-by: vinadhy@gmail.com -Signed-off-by: Sebastian Andrzej Siewior ---- - drivers/iommu/iova.c | 4 +--- - 1 file changed, 1 insertion(+), 3 deletions(-) - -diff --git a/drivers/iommu/iova.c b/drivers/iommu/iova.c -index 33edfa794ae9..b30900025c62 100644 ---- a/drivers/iommu/iova.c -+++ b/drivers/iommu/iova.c -@@ -570,7 +570,7 @@ void queue_iova(struct iova_domain *iovad, - unsigned long pfn, unsigned long pages, - unsigned long data) - { -- struct iova_fq *fq = get_cpu_ptr(iovad->fq); -+ struct iova_fq *fq = raw_cpu_ptr(iovad->fq); - unsigned long flags; - unsigned idx; - -@@ -600,8 +600,6 @@ void queue_iova(struct iova_domain *iovad, - if (atomic_cmpxchg(&iovad->fq_timer_on, 0, 1) == 0) - mod_timer(&iovad->fq_timer, - jiffies + msecs_to_jiffies(IOVA_FQ_TIMEOUT)); -- -- put_cpu_ptr(iovad->fq); - } - EXPORT_SYMBOL_GPL(queue_iova); - --- -2.19.2 - diff --git a/kernel/patches-4.14.x-rt/0061-greybus-audio-don-t-inclide-rwlock.h-directly.patch b/kernel/patches-4.14.x-rt/0061-greybus-audio-don-t-inclide-rwlock.h-directly.patch deleted file mode 100644 index 4c2f8d1ec..000000000 --- a/kernel/patches-4.14.x-rt/0061-greybus-audio-don-t-inclide-rwlock.h-directly.patch +++ /dev/null @@ -1,36 +0,0 @@ -From fbcbb30ee0869c20e0058364661c2bb612c48bbf Mon Sep 17 00:00:00 2001 -From: Sebastian Andrzej Siewior -Date: Thu, 5 Oct 2017 14:38:52 +0200 -Subject: [PATCH 061/450] greybus: audio: don't inclide rwlock.h directly. - -rwlock.h should not be included directly. Instead linux/splinlock.h -should be included. One thing it does is to break the RT build. - -Cc: Vaibhav Agarwal -Cc: Mark Greer -Cc: Johan Hovold -Cc: Alex Elder -Cc: Greg Kroah-Hartman -Cc: greybus-dev@lists.linaro.org -Cc: devel@driverdev.osuosl.org -Signed-off-by: Sebastian Andrzej Siewior ---- - drivers/staging/greybus/audio_manager.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/drivers/staging/greybus/audio_manager.c b/drivers/staging/greybus/audio_manager.c -index aa6508b44fab..045696ce85c7 100644 ---- a/drivers/staging/greybus/audio_manager.c -+++ b/drivers/staging/greybus/audio_manager.c -@@ -10,7 +10,7 @@ - #include - #include - #include --#include -+#include - #include - - #include "audio_manager.h" --- -2.19.2 - diff --git a/kernel/patches-4.14.x-rt/0062-xen-9pfs-don-t-inclide-rwlock.h-directly.patch b/kernel/patches-4.14.x-rt/0062-xen-9pfs-don-t-inclide-rwlock.h-directly.patch deleted file mode 100644 index 25a2a456e..000000000 --- a/kernel/patches-4.14.x-rt/0062-xen-9pfs-don-t-inclide-rwlock.h-directly.patch +++ /dev/null @@ -1,34 +0,0 @@ -From 53e8aad4871bacbe9ca9dae684d61821f520300d Mon Sep 17 00:00:00 2001 -From: Sebastian Andrzej Siewior -Date: Thu, 5 Oct 2017 14:38:52 +0200 -Subject: [PATCH 062/450] xen/9pfs: don't inclide rwlock.h directly. - -rwlock.h should not be included directly. Instead linux/splinlock.h -should be included. One thing it does is to break the RT build. - -Cc: Eric Van Hensbergen -Cc: Ron Minnich -Cc: Latchesar Ionkov -Cc: "David S. Miller" -Cc: v9fs-developer@lists.sourceforge.net -Cc: netdev@vger.kernel.org -Signed-off-by: Sebastian Andrzej Siewior ---- - net/9p/trans_xen.c | 1 - - 1 file changed, 1 deletion(-) - -diff --git a/net/9p/trans_xen.c b/net/9p/trans_xen.c -index c10bdf63eae7..84a49f2bcfbc 100644 ---- a/net/9p/trans_xen.c -+++ b/net/9p/trans_xen.c -@@ -38,7 +38,6 @@ - - #include - #include --#include - #include - #include - #include --- -2.19.2 - diff --git a/kernel/patches-4.14.x-rt/0063-drm-i915-properly-init-lockdep-class.patch b/kernel/patches-4.14.x-rt/0063-drm-i915-properly-init-lockdep-class.patch deleted file mode 100644 index c085277f1..000000000 --- a/kernel/patches-4.14.x-rt/0063-drm-i915-properly-init-lockdep-class.patch +++ /dev/null @@ -1,37 +0,0 @@ -From 0d3d9c5f072e910b2f184bfac6c15b9690a779e9 Mon Sep 17 00:00:00 2001 -From: Sebastian Andrzej Siewior -Date: Thu, 30 Nov 2017 16:06:13 +0100 -Subject: [PATCH 063/450] drm/i915: properly init lockdep class - -The code has an ifdef and uses two functions to either init the bare -spinlock or init it and set a lock-class. It is possible to do the same -thing without an ifdef. -With this patch (in debug case) we first use the "default" lock class -which is later overwritten to the supplied one. Without lockdep the set -name/class function vanishes. - -Signed-off-by: Sebastian Andrzej Siewior ---- - drivers/gpu/drm/i915/i915_gem_timeline.c | 5 +---- - 1 file changed, 1 insertion(+), 4 deletions(-) - -diff --git a/drivers/gpu/drm/i915/i915_gem_timeline.c b/drivers/gpu/drm/i915/i915_gem_timeline.c -index c597ce277a04..c1108d3921f8 100644 ---- a/drivers/gpu/drm/i915/i915_gem_timeline.c -+++ b/drivers/gpu/drm/i915/i915_gem_timeline.c -@@ -33,11 +33,8 @@ static void __intel_timeline_init(struct intel_timeline *tl, - { - tl->fence_context = context; - tl->common = parent; --#ifdef CONFIG_DEBUG_SPINLOCK -- __raw_spin_lock_init(&tl->lock.rlock, lockname, lockclass); --#else - spin_lock_init(&tl->lock); --#endif -+ lockdep_set_class_and_name(&tl->lock, lockclass, lockname); - init_request_active(&tl->last_request, NULL); - INIT_LIST_HEAD(&tl->requests); - i915_syncmap_init(&tl->sync); --- -2.19.2 - diff --git a/kernel/patches-4.14.x-rt/0064-timerqueue-Document-return-values-of-timerqueue_add-.patch b/kernel/patches-4.14.x-rt/0064-timerqueue-Document-return-values-of-timerqueue_add-.patch deleted file mode 100644 index 0b6d7da4e..000000000 --- a/kernel/patches-4.14.x-rt/0064-timerqueue-Document-return-values-of-timerqueue_add-.patch +++ /dev/null @@ -1,45 +0,0 @@ -From 74826a26ced7740701c5d18e2678b2771ef4b9f1 Mon Sep 17 00:00:00 2001 -From: Thomas Gleixner -Date: Fri, 22 Dec 2017 15:51:15 +0100 -Subject: [PATCH 064/450] timerqueue: Document return values of - timerqueue_add/del() - -The return values of timerqueue_add/del() are not documented in the kernel doc -comment. Add proper documentation. - -Signed-off-by: Thomas Gleixner -Cc: rt@linutronix.de -Signed-off-by: Sebastian Andrzej Siewior ---- - lib/timerqueue.c | 8 +++++--- - 1 file changed, 5 insertions(+), 3 deletions(-) - -diff --git a/lib/timerqueue.c b/lib/timerqueue.c -index 4a720ed4fdaf..0d54bcbc8170 100644 ---- a/lib/timerqueue.c -+++ b/lib/timerqueue.c -@@ -33,8 +33,9 @@ - * @head: head of timerqueue - * @node: timer node to be added - * -- * Adds the timer node to the timerqueue, sorted by the -- * node's expires value. -+ * Adds the timer node to the timerqueue, sorted by the node's expires -+ * value. Returns true if the newly added timer is the first expiring timer in -+ * the queue. - */ - bool timerqueue_add(struct timerqueue_head *head, struct timerqueue_node *node) - { -@@ -70,7 +71,8 @@ EXPORT_SYMBOL_GPL(timerqueue_add); - * @head: head of timerqueue - * @node: timer node to be removed - * -- * Removes the timer node from the timerqueue. -+ * Removes the timer node from the timerqueue. Returns true if the queue is -+ * not empty after the remove. - */ - bool timerqueue_del(struct timerqueue_head *head, struct timerqueue_node *node) - { --- -2.19.2 - diff --git a/kernel/patches-4.14.x-rt/0065-sparc64-use-generic-rwsem-spinlocks-rt.patch b/kernel/patches-4.14.x-rt/0065-sparc64-use-generic-rwsem-spinlocks-rt.patch deleted file mode 100644 index 465513203..000000000 --- a/kernel/patches-4.14.x-rt/0065-sparc64-use-generic-rwsem-spinlocks-rt.patch +++ /dev/null @@ -1,33 +0,0 @@ -From 5692af55627acc4af517136fd0ea965581b5bba8 Mon Sep 17 00:00:00 2001 -From: Allen Pais -Date: Fri, 13 Dec 2013 09:44:41 +0530 -Subject: [PATCH 065/450] sparc64: use generic rwsem spinlocks rt - -Signed-off-by: Allen Pais -Signed-off-by: Sebastian Andrzej Siewior ---- - arch/sparc/Kconfig | 6 ++---- - 1 file changed, 2 insertions(+), 4 deletions(-) - -diff --git a/arch/sparc/Kconfig b/arch/sparc/Kconfig -index 4e83f950713e..7f9d71523763 100644 ---- a/arch/sparc/Kconfig -+++ b/arch/sparc/Kconfig -@@ -206,12 +206,10 @@ config NR_CPUS - source kernel/Kconfig.hz - - config RWSEM_GENERIC_SPINLOCK -- bool -- default y if SPARC32 -+ def_bool PREEMPT_RT_FULL - - config RWSEM_XCHGADD_ALGORITHM -- bool -- default y if SPARC64 -+ def_bool !RWSEM_GENERIC_SPINLOCK && !PREEMPT_RT_FULL - - config GENERIC_HWEIGHT - bool --- -2.19.2 - diff --git a/kernel/patches-4.14.x-rt/0066-kernel-SRCU-provide-a-static-initializer.patch b/kernel/patches-4.14.x-rt/0066-kernel-SRCU-provide-a-static-initializer.patch deleted file mode 100644 index e200a578c..000000000 --- a/kernel/patches-4.14.x-rt/0066-kernel-SRCU-provide-a-static-initializer.patch +++ /dev/null @@ -1,165 +0,0 @@ -From 04c244882b9bf3a257292ac6b3cfba56121b3628 Mon Sep 17 00:00:00 2001 -From: Sebastian Andrzej Siewior -Date: Tue, 19 Mar 2013 14:44:30 +0100 -Subject: [PATCH 066/450] kernel/SRCU: provide a static initializer - -There are macros for static initializer for the three out of four -possible notifier types, that are: - ATOMIC_NOTIFIER_HEAD() - BLOCKING_NOTIFIER_HEAD() - RAW_NOTIFIER_HEAD() - -This patch provides a static initilizer for the forth type to make it -complete. - -Signed-off-by: Sebastian Andrzej Siewior ---- - include/linux/notifier.h | 42 +++++++++++++++++++++++++++++++--------- - include/linux/srcutiny.h | 6 +++--- - include/linux/srcutree.h | 6 +++--- - 3 files changed, 39 insertions(+), 15 deletions(-) - -diff --git a/include/linux/notifier.h b/include/linux/notifier.h -index 6d731110e0db..e758627da14d 100644 ---- a/include/linux/notifier.h -+++ b/include/linux/notifier.h -@@ -7,7 +7,7 @@ - * - * Alan Cox - */ -- -+ - #ifndef _LINUX_NOTIFIER_H - #define _LINUX_NOTIFIER_H - #include -@@ -43,9 +43,7 @@ - * in srcu_notifier_call_chain(): no cache bounces and no memory barriers. - * As compensation, srcu_notifier_chain_unregister() is rather expensive. - * SRCU notifier chains should be used when the chain will be called very -- * often but notifier_blocks will seldom be removed. Also, SRCU notifier -- * chains are slightly more difficult to use because they require special -- * runtime initialization. -+ * often but notifier_blocks will seldom be removed. - */ - - struct notifier_block; -@@ -91,7 +89,7 @@ struct srcu_notifier_head { - (name)->head = NULL; \ - } while (0) - --/* srcu_notifier_heads must be initialized and cleaned up dynamically */ -+/* srcu_notifier_heads must be cleaned up dynamically */ - extern void srcu_init_notifier_head(struct srcu_notifier_head *nh); - #define srcu_cleanup_notifier_head(name) \ - cleanup_srcu_struct(&(name)->srcu); -@@ -104,7 +102,13 @@ extern void srcu_init_notifier_head(struct srcu_notifier_head *nh); - .head = NULL } - #define RAW_NOTIFIER_INIT(name) { \ - .head = NULL } --/* srcu_notifier_heads cannot be initialized statically */ -+ -+#define SRCU_NOTIFIER_INIT(name, pcpu) \ -+ { \ -+ .mutex = __MUTEX_INITIALIZER(name.mutex), \ -+ .head = NULL, \ -+ .srcu = __SRCU_STRUCT_INIT(name.srcu, pcpu), \ -+ } - - #define ATOMIC_NOTIFIER_HEAD(name) \ - struct atomic_notifier_head name = \ -@@ -116,6 +120,26 @@ extern void srcu_init_notifier_head(struct srcu_notifier_head *nh); - struct raw_notifier_head name = \ - RAW_NOTIFIER_INIT(name) - -+#ifdef CONFIG_TREE_SRCU -+#define _SRCU_NOTIFIER_HEAD(name, mod) \ -+ static DEFINE_PER_CPU(struct srcu_data, \ -+ name##_head_srcu_data); \ -+ mod struct srcu_notifier_head name = \ -+ SRCU_NOTIFIER_INIT(name, name##_head_srcu_data) -+ -+#else -+#define _SRCU_NOTIFIER_HEAD(name, mod) \ -+ mod struct srcu_notifier_head name = \ -+ SRCU_NOTIFIER_INIT(name, name) -+ -+#endif -+ -+#define SRCU_NOTIFIER_HEAD(name) \ -+ _SRCU_NOTIFIER_HEAD(name, ) -+ -+#define SRCU_NOTIFIER_HEAD_STATIC(name) \ -+ _SRCU_NOTIFIER_HEAD(name, static) -+ - #ifdef __KERNEL__ - - extern int atomic_notifier_chain_register(struct atomic_notifier_head *nh, -@@ -185,12 +209,12 @@ static inline int notifier_to_errno(int ret) - - /* - * Declared notifiers so far. I can imagine quite a few more chains -- * over time (eg laptop power reset chains, reboot chain (to clean -+ * over time (eg laptop power reset chains, reboot chain (to clean - * device units up), device [un]mount chain, module load/unload chain, -- * low memory chain, screenblank chain (for plug in modular screenblankers) -+ * low memory chain, screenblank chain (for plug in modular screenblankers) - * VC switch chains (for loadable kernel svgalib VC switch helpers) etc... - */ -- -+ - /* CPU notfiers are defined in include/linux/cpu.h. */ - - /* netdevice notifiers are defined in include/linux/netdevice.h */ -diff --git a/include/linux/srcutiny.h b/include/linux/srcutiny.h -index 261471f407a5..f41d2fb09f87 100644 ---- a/include/linux/srcutiny.h -+++ b/include/linux/srcutiny.h -@@ -43,7 +43,7 @@ struct srcu_struct { - - void srcu_drive_gp(struct work_struct *wp); - --#define __SRCU_STRUCT_INIT(name) \ -+#define __SRCU_STRUCT_INIT(name, __ignored) \ - { \ - .srcu_wq = __SWAIT_QUEUE_HEAD_INITIALIZER(name.srcu_wq), \ - .srcu_cb_tail = &name.srcu_cb_head, \ -@@ -56,9 +56,9 @@ void srcu_drive_gp(struct work_struct *wp); - * Tree SRCU, which needs some per-CPU data. - */ - #define DEFINE_SRCU(name) \ -- struct srcu_struct name = __SRCU_STRUCT_INIT(name) -+ struct srcu_struct name = __SRCU_STRUCT_INIT(name, name) - #define DEFINE_STATIC_SRCU(name) \ -- static struct srcu_struct name = __SRCU_STRUCT_INIT(name) -+ static struct srcu_struct name = __SRCU_STRUCT_INIT(name, name) - - void synchronize_srcu(struct srcu_struct *sp); - -diff --git a/include/linux/srcutree.h b/include/linux/srcutree.h -index a949f4f9e4d7..85ae8c0dddb4 100644 ---- a/include/linux/srcutree.h -+++ b/include/linux/srcutree.h -@@ -104,9 +104,9 @@ struct srcu_struct { - #define SRCU_STATE_SCAN1 1 - #define SRCU_STATE_SCAN2 2 - --#define __SRCU_STRUCT_INIT(name) \ -+#define __SRCU_STRUCT_INIT(name, pcpu_name) \ - { \ -- .sda = &name##_srcu_data, \ -+ .sda = &pcpu_name, \ - .lock = __RAW_SPIN_LOCK_UNLOCKED(name.lock), \ - .srcu_gp_seq_needed = 0 - 1, \ - __SRCU_DEP_MAP_INIT(name) \ -@@ -133,7 +133,7 @@ struct srcu_struct { - */ - #define __DEFINE_SRCU(name, is_static) \ - static DEFINE_PER_CPU(struct srcu_data, name##_srcu_data);\ -- is_static struct srcu_struct name = __SRCU_STRUCT_INIT(name) -+ is_static struct srcu_struct name = __SRCU_STRUCT_INIT(name, name##_srcu_data) - #define DEFINE_SRCU(name) __DEFINE_SRCU(name, /* not static */) - #define DEFINE_STATIC_SRCU(name) __DEFINE_SRCU(name, static) - --- -2.19.2 - diff --git a/kernel/patches-4.14.x-rt/0067-target-drop-spin_lock_assert-irqs_disabled-combo-che.patch b/kernel/patches-4.14.x-rt/0067-target-drop-spin_lock_assert-irqs_disabled-combo-che.patch deleted file mode 100644 index 9f406662e..000000000 --- a/kernel/patches-4.14.x-rt/0067-target-drop-spin_lock_assert-irqs_disabled-combo-che.patch +++ /dev/null @@ -1,68 +0,0 @@ -From 23624e1d8e58efec7e18f61451c2feb4f37238ab Mon Sep 17 00:00:00 2001 -From: "bigeasy@linutronix.de" -Date: Fri, 23 Mar 2018 18:17:36 +0100 -Subject: [PATCH 067/450] target: drop spin_lock_assert() + irqs_disabled() - combo checks - -There are a few functions which check for if the lock is held -(spin_lock_assert()) and the interrupts are disabled (irqs_disabled()). ->From looking at the code, each function is static, the caller is near by -and does spin_lock_irq|safe(). As Linus puts it: - -|It's not like this is some function that is exported to random users, -|and we should check that the calling convention is right. -| -|This looks like "it may have been useful during coding to document -|things, but it's not useful long-term". - -Remove those checks. - -Reviewed-by: Bart Van Assche -Reported-by: Arnaldo Carvalho de Melo -Suggested-by: Linus Torvalds -Signed-off-by: Sebastian Andrzej Siewior ---- - drivers/target/target_core_tmr.c | 2 -- - drivers/target/target_core_transport.c | 6 ------ - 2 files changed, 8 deletions(-) - -diff --git a/drivers/target/target_core_tmr.c b/drivers/target/target_core_tmr.c -index 9c7bc1ca341a..3d35dad1de2c 100644 ---- a/drivers/target/target_core_tmr.c -+++ b/drivers/target/target_core_tmr.c -@@ -114,8 +114,6 @@ static bool __target_check_io_state(struct se_cmd *se_cmd, - { - struct se_session *sess = se_cmd->se_sess; - -- assert_spin_locked(&sess->sess_cmd_lock); -- WARN_ON_ONCE(!irqs_disabled()); - /* - * If command already reached CMD_T_COMPLETE state within - * target_complete_cmd() or CMD_T_FABRIC_STOP due to shutdown, -diff --git a/drivers/target/target_core_transport.c b/drivers/target/target_core_transport.c -index 0d0be7d8b9d6..f652e58e2988 100644 ---- a/drivers/target/target_core_transport.c -+++ b/drivers/target/target_core_transport.c -@@ -2967,9 +2967,6 @@ __transport_wait_for_tasks(struct se_cmd *cmd, bool fabric_stop, - __acquires(&cmd->t_state_lock) - { - -- assert_spin_locked(&cmd->t_state_lock); -- WARN_ON_ONCE(!irqs_disabled()); -- - if (fabric_stop) - cmd->transport_state |= CMD_T_FABRIC_STOP; - -@@ -3239,9 +3236,6 @@ static int __transport_check_aborted_status(struct se_cmd *cmd, int send_status) - { - int ret; - -- assert_spin_locked(&cmd->t_state_lock); -- WARN_ON_ONCE(!irqs_disabled()); -- - if (!(cmd->transport_state & CMD_T_ABORTED)) - return 0; - /* --- -2.19.2 - diff --git a/kernel/patches-4.14.x-rt/0070-tracing-Reverse-the-order-of-trace_types_lock-and-ev.patch b/kernel/patches-4.14.x-rt/0070-tracing-Reverse-the-order-of-trace_types_lock-and-ev.patch deleted file mode 100644 index fc6c0832d..000000000 --- a/kernel/patches-4.14.x-rt/0070-tracing-Reverse-the-order-of-trace_types_lock-and-ev.patch +++ /dev/null @@ -1,199 +0,0 @@ -From 5949dd1e7ccd5b129d4f1fd30c9090bcc1ee8620 Mon Sep 17 00:00:00 2001 -From: "Steven Rostedt (VMware)" -Date: Thu, 21 Sep 2017 16:22:49 -0400 -Subject: [PATCH 070/450] tracing: Reverse the order of trace_types_lock and - event_mutex - -In order to make future changes where we need to call -tracing_set_clock() from within an event command, the order of -trace_types_lock and event_mutex must be reversed, as the event command -will hold event_mutex and the trace_types_lock is taken from within -tracing_set_clock(). - -Link: http://lkml.kernel.org/r/20170921162249.0dde3dca@gandalf.local.home - -Requested-by: Tom Zanussi -Signed-off-by: Steven Rostedt (VMware) -(cherry picked from commit 12ecef0cb12102d8c034770173d2d1363cb97d52) -Signed-off-by: Sebastian Andrzej Siewior ---- - kernel/trace/trace.c | 5 +++++ - kernel/trace/trace_events.c | 31 +++++++++++++++---------------- - 2 files changed, 20 insertions(+), 16 deletions(-) - -diff --git a/kernel/trace/trace.c b/kernel/trace/trace.c -index e9cbb96cd99e..ee24e0bfc391 100644 ---- a/kernel/trace/trace.c -+++ b/kernel/trace/trace.c -@@ -7684,6 +7684,7 @@ static int instance_mkdir(const char *name) - struct trace_array *tr; - int ret; - -+ mutex_lock(&event_mutex); - mutex_lock(&trace_types_lock); - - ret = -EEXIST; -@@ -7739,6 +7740,7 @@ static int instance_mkdir(const char *name) - list_add(&tr->list, &ftrace_trace_arrays); - - mutex_unlock(&trace_types_lock); -+ mutex_unlock(&event_mutex); - - return 0; - -@@ -7750,6 +7752,7 @@ static int instance_mkdir(const char *name) - - out_unlock: - mutex_unlock(&trace_types_lock); -+ mutex_unlock(&event_mutex); - - return ret; - -@@ -7762,6 +7765,7 @@ static int instance_rmdir(const char *name) - int ret; - int i; - -+ mutex_lock(&event_mutex); - mutex_lock(&trace_types_lock); - - ret = -ENODEV; -@@ -7807,6 +7811,7 @@ static int instance_rmdir(const char *name) - - out_unlock: - mutex_unlock(&trace_types_lock); -+ mutex_unlock(&event_mutex); - - return ret; - } -diff --git a/kernel/trace/trace_events.c b/kernel/trace/trace_events.c -index d53268a4e167..1b87157edbff 100644 ---- a/kernel/trace/trace_events.c -+++ b/kernel/trace/trace_events.c -@@ -1406,8 +1406,8 @@ static int subsystem_open(struct inode *inode, struct file *filp) - return -ENODEV; - - /* Make sure the system still exists */ -- mutex_lock(&trace_types_lock); - mutex_lock(&event_mutex); -+ mutex_lock(&trace_types_lock); - list_for_each_entry(tr, &ftrace_trace_arrays, list) { - list_for_each_entry(dir, &tr->systems, list) { - if (dir == inode->i_private) { -@@ -1421,8 +1421,8 @@ static int subsystem_open(struct inode *inode, struct file *filp) - } - } - exit_loop: -- mutex_unlock(&event_mutex); - mutex_unlock(&trace_types_lock); -+ mutex_unlock(&event_mutex); - - if (!system) - return -ENODEV; -@@ -2308,15 +2308,15 @@ static void __add_event_to_tracers(struct trace_event_call *call); - int trace_add_event_call(struct trace_event_call *call) - { - int ret; -- mutex_lock(&trace_types_lock); - mutex_lock(&event_mutex); -+ mutex_lock(&trace_types_lock); - - ret = __register_event(call, NULL); - if (ret >= 0) - __add_event_to_tracers(call); - -- mutex_unlock(&event_mutex); - mutex_unlock(&trace_types_lock); -+ mutex_unlock(&event_mutex); - return ret; - } - -@@ -2370,13 +2370,13 @@ int trace_remove_event_call(struct trace_event_call *call) - { - int ret; - -- mutex_lock(&trace_types_lock); - mutex_lock(&event_mutex); -+ mutex_lock(&trace_types_lock); - down_write(&trace_event_sem); - ret = probe_remove_event_call(call); - up_write(&trace_event_sem); -- mutex_unlock(&event_mutex); - mutex_unlock(&trace_types_lock); -+ mutex_unlock(&event_mutex); - - return ret; - } -@@ -2438,8 +2438,8 @@ static int trace_module_notify(struct notifier_block *self, - { - struct module *mod = data; - -- mutex_lock(&trace_types_lock); - mutex_lock(&event_mutex); -+ mutex_lock(&trace_types_lock); - switch (val) { - case MODULE_STATE_COMING: - trace_module_add_events(mod); -@@ -2448,8 +2448,8 @@ static int trace_module_notify(struct notifier_block *self, - trace_module_remove_events(mod); - break; - } -- mutex_unlock(&event_mutex); - mutex_unlock(&trace_types_lock); -+ mutex_unlock(&event_mutex); - - return 0; - } -@@ -2964,24 +2964,24 @@ create_event_toplevel_files(struct dentry *parent, struct trace_array *tr) - * creates the event hierachry in the @parent/events directory. - * - * Returns 0 on success. -+ * -+ * Must be called with event_mutex held. - */ - int event_trace_add_tracer(struct dentry *parent, struct trace_array *tr) - { - int ret; - -- mutex_lock(&event_mutex); -+ lockdep_assert_held(&event_mutex); - - ret = create_event_toplevel_files(parent, tr); - if (ret) -- goto out_unlock; -+ goto out; - - down_write(&trace_event_sem); - __trace_add_event_dirs(tr); - up_write(&trace_event_sem); - -- out_unlock: -- mutex_unlock(&event_mutex); -- -+ out: - return ret; - } - -@@ -3010,9 +3010,10 @@ early_event_add_tracer(struct dentry *parent, struct trace_array *tr) - return ret; - } - -+/* Must be called with event_mutex held */ - int event_trace_del_tracer(struct trace_array *tr) - { -- mutex_lock(&event_mutex); -+ lockdep_assert_held(&event_mutex); - - /* Disable any event triggers and associated soft-disabled events */ - clear_event_triggers(tr); -@@ -3033,8 +3034,6 @@ int event_trace_del_tracer(struct trace_array *tr) - - tr->event_dir = NULL; - -- mutex_unlock(&event_mutex); -- - return 0; - } - --- -2.19.2 - diff --git a/kernel/patches-4.14.x-rt/0071-ring-buffer-Rewrite-trace_recursive_-un-lock-to-be-s.patch b/kernel/patches-4.14.x-rt/0071-ring-buffer-Rewrite-trace_recursive_-un-lock-to-be-s.patch deleted file mode 100644 index 2af414f68..000000000 --- a/kernel/patches-4.14.x-rt/0071-ring-buffer-Rewrite-trace_recursive_-un-lock-to-be-s.patch +++ /dev/null @@ -1,123 +0,0 @@ -From 2b1f41ec5ffa792926f78d9561c67ec7bfc7a215 Mon Sep 17 00:00:00 2001 -From: "Steven Rostedt (VMware)" -Date: Fri, 22 Sep 2017 16:59:02 -0400 -Subject: [PATCH 071/450] ring-buffer: Rewrite trace_recursive_(un)lock() to be - simpler - -The current method to prevent the ring buffer from entering into a recursize -loop is to use a bitmask and set the bit that maps to the current context -(normal, softirq, irq or NMI), and if that bit was already set, it is -considered a recursive loop. - -New code is being added that may require the ring buffer to be entered a -second time in the current context. The recursive locking prevents that from -happening. Instead of mapping a bitmask to the current context, just allow 4 -levels of nesting in the ring buffer. This matches the 4 context levels that -it can already nest. It is highly unlikely to have more than two levels, -thus it should be fine when we add the second entry into the ring buffer. If -that proves to be a problem, we can always up the number to 8. - -An added benefit is that reading preempt_count() to get the current level -adds a very slight but noticeable overhead. This removes that need. - -Signed-off-by: Steven Rostedt (VMware) -(cherry picked from commit 1a149d7d3f45d311da1f63473736c05f30ae8a75) -Signed-off-by: Sebastian Andrzej Siewior ---- - kernel/trace/ring_buffer.c | 64 ++++++++++---------------------------- - 1 file changed, 17 insertions(+), 47 deletions(-) - -diff --git a/kernel/trace/ring_buffer.c b/kernel/trace/ring_buffer.c -index a1d5e0949dcf..ade8493cb69f 100644 ---- a/kernel/trace/ring_buffer.c -+++ b/kernel/trace/ring_buffer.c -@@ -2547,61 +2547,29 @@ rb_wakeups(struct ring_buffer *buffer, struct ring_buffer_per_cpu *cpu_buffer) - * The lock and unlock are done within a preempt disable section. - * The current_context per_cpu variable can only be modified - * by the current task between lock and unlock. But it can -- * be modified more than once via an interrupt. To pass this -- * information from the lock to the unlock without having to -- * access the 'in_interrupt()' functions again (which do show -- * a bit of overhead in something as critical as function tracing, -- * we use a bitmask trick. -+ * be modified more than once via an interrupt. There are four -+ * different contexts that we need to consider. - * -- * bit 0 = NMI context -- * bit 1 = IRQ context -- * bit 2 = SoftIRQ context -- * bit 3 = normal context. -+ * Normal context. -+ * SoftIRQ context -+ * IRQ context -+ * NMI context - * -- * This works because this is the order of contexts that can -- * preempt other contexts. A SoftIRQ never preempts an IRQ -- * context. -- * -- * When the context is determined, the corresponding bit is -- * checked and set (if it was set, then a recursion of that context -- * happened). -- * -- * On unlock, we need to clear this bit. To do so, just subtract -- * 1 from the current_context and AND it to itself. -- * -- * (binary) -- * 101 - 1 = 100 -- * 101 & 100 = 100 (clearing bit zero) -- * -- * 1010 - 1 = 1001 -- * 1010 & 1001 = 1000 (clearing bit 1) -- * -- * The least significant bit can be cleared this way, and it -- * just so happens that it is the same bit corresponding to -- * the current context. -+ * If for some reason the ring buffer starts to recurse, we -+ * only allow that to happen at most 4 times (one for each -+ * context). If it happens 5 times, then we consider this a -+ * recusive loop and do not let it go further. - */ - - static __always_inline int - trace_recursive_lock(struct ring_buffer_per_cpu *cpu_buffer) - { -- unsigned int val = cpu_buffer->current_context; -- int bit; -- -- if (in_interrupt()) { -- if (in_nmi()) -- bit = RB_CTX_NMI; -- else if (in_irq()) -- bit = RB_CTX_IRQ; -- else -- bit = RB_CTX_SOFTIRQ; -- } else -- bit = RB_CTX_NORMAL; -- -- if (unlikely(val & (1 << bit))) -+ if (cpu_buffer->current_context >= 4) - return 1; - -- val |= (1 << bit); -- cpu_buffer->current_context = val; -+ cpu_buffer->current_context++; -+ /* Interrupts must see this update */ -+ barrier(); - - return 0; - } -@@ -2609,7 +2577,9 @@ trace_recursive_lock(struct ring_buffer_per_cpu *cpu_buffer) - static __always_inline void - trace_recursive_unlock(struct ring_buffer_per_cpu *cpu_buffer) - { -- cpu_buffer->current_context &= cpu_buffer->current_context - 1; -+ /* Don't let the dec leak out */ -+ barrier(); -+ cpu_buffer->current_context--; - } - - /** --- -2.19.2 - diff --git a/kernel/patches-4.14.x-rt/0072-tracing-Remove-lookups-from-tracing_map-hitcount.patch b/kernel/patches-4.14.x-rt/0072-tracing-Remove-lookups-from-tracing_map-hitcount.patch deleted file mode 100644 index 8cd0a1c55..000000000 --- a/kernel/patches-4.14.x-rt/0072-tracing-Remove-lookups-from-tracing_map-hitcount.patch +++ /dev/null @@ -1,36 +0,0 @@ -From 6c8db16c6d06bad6ad65df740972283acaf82297 Mon Sep 17 00:00:00 2001 -From: Tom Zanussi -Date: Fri, 22 Sep 2017 14:58:18 -0500 -Subject: [PATCH 072/450] tracing: Remove lookups from tracing_map hitcount - -Lookups inflate the hitcount, making it essentially useless. Only -inserts and updates should really affect the hitcount anyway, so -explicitly filter lookups out. - -Link: http://lkml.kernel.org/r/c8d9dc39d269a8abf88bf4102d0dfc65deb0fc7f.1506105045.git.tom.zanussi@linux.intel.com - -Signed-off-by: Tom Zanussi -Signed-off-by: Steven Rostedt (VMware) -(cherry picked from commit 83c07ecc4203728e85fc4a2ce6fdf25d16ea118e) -Signed-off-by: Sebastian Andrzej Siewior ---- - kernel/trace/tracing_map.c | 3 ++- - 1 file changed, 2 insertions(+), 1 deletion(-) - -diff --git a/kernel/trace/tracing_map.c b/kernel/trace/tracing_map.c -index 305039b122fa..07e75344725b 100644 ---- a/kernel/trace/tracing_map.c -+++ b/kernel/trace/tracing_map.c -@@ -428,7 +428,8 @@ __tracing_map_insert(struct tracing_map *map, void *key, bool lookup_only) - - if (test_key && test_key == key_hash && entry->val && - keys_match(key, entry->val->key, map->key_size)) { -- atomic64_inc(&map->hits); -+ if (!lookup_only) -+ atomic64_inc(&map->hits); - return entry->val; - } - --- -2.19.2 - diff --git a/kernel/patches-4.14.x-rt/0073-tracing-Increase-tracing-map-KEYS_MAX-size.patch b/kernel/patches-4.14.x-rt/0073-tracing-Increase-tracing-map-KEYS_MAX-size.patch deleted file mode 100644 index dbcd14d3e..000000000 --- a/kernel/patches-4.14.x-rt/0073-tracing-Increase-tracing-map-KEYS_MAX-size.patch +++ /dev/null @@ -1,34 +0,0 @@ -From 45d6041465d780691c7c498eb7f7458bb5192ded Mon Sep 17 00:00:00 2001 -From: Tom Zanussi -Date: Fri, 22 Sep 2017 14:58:19 -0500 -Subject: [PATCH 073/450] tracing: Increase tracing map KEYS_MAX size - -The current default for the number of subkeys in a compound key is 2, -which is too restrictive. Increase it to a more realistic value of 3. - -Link: http://lkml.kernel.org/r/b6952cca06d1f912eba33804a6fd6069b3847d44.1506105045.git.tom.zanussi@linux.intel.com - -Signed-off-by: Tom Zanussi -Signed-off-by: Steven Rostedt (VMware) -(cherry picked from commit 4f36c2d85cedea60ad424d44534121ab0458069e) -Signed-off-by: Sebastian Andrzej Siewior ---- - kernel/trace/tracing_map.h | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/kernel/trace/tracing_map.h b/kernel/trace/tracing_map.h -index ab0ca77331d0..5b5bbf8ae550 100644 ---- a/kernel/trace/tracing_map.h -+++ b/kernel/trace/tracing_map.h -@@ -6,7 +6,7 @@ - #define TRACING_MAP_BITS_MAX 17 - #define TRACING_MAP_BITS_MIN 7 - --#define TRACING_MAP_KEYS_MAX 2 -+#define TRACING_MAP_KEYS_MAX 3 - #define TRACING_MAP_VALS_MAX 3 - #define TRACING_MAP_FIELDS_MAX (TRACING_MAP_KEYS_MAX + \ - TRACING_MAP_VALS_MAX) --- -2.19.2 - diff --git a/kernel/patches-4.14.x-rt/0074-tracing-Make-traceprobe-parsing-code-reusable.patch b/kernel/patches-4.14.x-rt/0074-tracing-Make-traceprobe-parsing-code-reusable.patch deleted file mode 100644 index c53c373f5..000000000 --- a/kernel/patches-4.14.x-rt/0074-tracing-Make-traceprobe-parsing-code-reusable.patch +++ /dev/null @@ -1,337 +0,0 @@ -From f8a450144ee205d29baae926ec23478a12f25476 Mon Sep 17 00:00:00 2001 -From: Tom Zanussi -Date: Fri, 22 Sep 2017 14:58:20 -0500 -Subject: [PATCH 074/450] tracing: Make traceprobe parsing code reusable - -traceprobe_probes_write() and traceprobe_command() actually contain -nothing that ties them to kprobes - the code is generically useful for -similar types of parsing elsewhere, so separate it out and move it to -trace.c/trace.h. - -Other than moving it, the only change is in naming: -traceprobe_probes_write() becomes trace_parse_run_command() and -traceprobe_command() becomes trace_run_command(). - -Link: http://lkml.kernel.org/r/ae5c26ea40c196a8986854d921eb6e713ede7e3f.1506105045.git.tom.zanussi@linux.intel.com - -Signed-off-by: Tom Zanussi -Signed-off-by: Steven Rostedt (VMware) -(cherry picked from commit 7e465baa80293ed5f87fdf6405391d6f02110d4e) -Signed-off-by: Sebastian Andrzej Siewior ---- - kernel/trace/trace.c | 86 +++++++++++++++++++++++++++++++++++++ - kernel/trace/trace.h | 7 +++ - kernel/trace/trace_kprobe.c | 18 ++++---- - kernel/trace/trace_probe.c | 86 ------------------------------------- - kernel/trace/trace_probe.h | 7 --- - kernel/trace/trace_uprobe.c | 2 +- - 6 files changed, 103 insertions(+), 103 deletions(-) - -diff --git a/kernel/trace/trace.c b/kernel/trace/trace.c -index ee24e0bfc391..f3d7c259e424 100644 ---- a/kernel/trace/trace.c -+++ b/kernel/trace/trace.c -@@ -8280,6 +8280,92 @@ void ftrace_dump(enum ftrace_dump_mode oops_dump_mode) - } - EXPORT_SYMBOL_GPL(ftrace_dump); - -+int trace_run_command(const char *buf, int (*createfn)(int, char **)) -+{ -+ char **argv; -+ int argc, ret; -+ -+ argc = 0; -+ ret = 0; -+ argv = argv_split(GFP_KERNEL, buf, &argc); -+ if (!argv) -+ return -ENOMEM; -+ -+ if (argc) -+ ret = createfn(argc, argv); -+ -+ argv_free(argv); -+ -+ return ret; -+} -+ -+#define WRITE_BUFSIZE 4096 -+ -+ssize_t trace_parse_run_command(struct file *file, const char __user *buffer, -+ size_t count, loff_t *ppos, -+ int (*createfn)(int, char **)) -+{ -+ char *kbuf, *buf, *tmp; -+ int ret = 0; -+ size_t done = 0; -+ size_t size; -+ -+ kbuf = kmalloc(WRITE_BUFSIZE, GFP_KERNEL); -+ if (!kbuf) -+ return -ENOMEM; -+ -+ while (done < count) { -+ size = count - done; -+ -+ if (size >= WRITE_BUFSIZE) -+ size = WRITE_BUFSIZE - 1; -+ -+ if (copy_from_user(kbuf, buffer + done, size)) { -+ ret = -EFAULT; -+ goto out; -+ } -+ kbuf[size] = '\0'; -+ buf = kbuf; -+ do { -+ tmp = strchr(buf, '\n'); -+ if (tmp) { -+ *tmp = '\0'; -+ size = tmp - buf + 1; -+ } else { -+ size = strlen(buf); -+ if (done + size < count) { -+ if (buf != kbuf) -+ break; -+ /* This can accept WRITE_BUFSIZE - 2 ('\n' + '\0') */ -+ pr_warn("Line length is too long: Should be less than %d\n", -+ WRITE_BUFSIZE - 2); -+ ret = -EINVAL; -+ goto out; -+ } -+ } -+ done += size; -+ -+ /* Remove comments */ -+ tmp = strchr(buf, '#'); -+ -+ if (tmp) -+ *tmp = '\0'; -+ -+ ret = trace_run_command(buf, createfn); -+ if (ret) -+ goto out; -+ buf += size; -+ -+ } while (done < count); -+ } -+ ret = done; -+ -+out: -+ kfree(kbuf); -+ -+ return ret; -+} -+ - __init static int tracer_alloc_buffers(void) - { - int ring_buf_size; -diff --git a/kernel/trace/trace.h b/kernel/trace/trace.h -index 851cd1605085..221591636530 100644 ---- a/kernel/trace/trace.h -+++ b/kernel/trace/trace.h -@@ -1755,6 +1755,13 @@ void trace_printk_start_comm(void); - int trace_keep_overwrite(struct tracer *tracer, u32 mask, int set); - int set_tracer_flag(struct trace_array *tr, unsigned int mask, int enabled); - -+#define MAX_EVENT_NAME_LEN 64 -+ -+extern int trace_run_command(const char *buf, int (*createfn)(int, char**)); -+extern ssize_t trace_parse_run_command(struct file *file, -+ const char __user *buffer, size_t count, loff_t *ppos, -+ int (*createfn)(int, char**)); -+ - /* - * Normal trace_printk() and friends allocates special buffers - * to do the manipulation, as well as saves the print formats -diff --git a/kernel/trace/trace_kprobe.c b/kernel/trace/trace_kprobe.c -index ea20274a105a..3c40d4174052 100644 ---- a/kernel/trace/trace_kprobe.c -+++ b/kernel/trace/trace_kprobe.c -@@ -918,8 +918,8 @@ static int probes_open(struct inode *inode, struct file *file) - static ssize_t probes_write(struct file *file, const char __user *buffer, - size_t count, loff_t *ppos) - { -- return traceprobe_probes_write(file, buffer, count, ppos, -- create_trace_kprobe); -+ return trace_parse_run_command(file, buffer, count, ppos, -+ create_trace_kprobe); - } - - static const struct file_operations kprobe_events_ops = { -@@ -1444,9 +1444,9 @@ static __init int kprobe_trace_self_tests_init(void) - - pr_info("Testing kprobe tracing: "); - -- ret = traceprobe_command("p:testprobe kprobe_trace_selftest_target " -- "$stack $stack0 +0($stack)", -- create_trace_kprobe); -+ ret = trace_run_command("p:testprobe kprobe_trace_selftest_target " -+ "$stack $stack0 +0($stack)", -+ create_trace_kprobe); - if (WARN_ON_ONCE(ret)) { - pr_warn("error on probing function entry.\n"); - warn++; -@@ -1466,8 +1466,8 @@ static __init int kprobe_trace_self_tests_init(void) - } - } - -- ret = traceprobe_command("r:testprobe2 kprobe_trace_selftest_target " -- "$retval", create_trace_kprobe); -+ ret = trace_run_command("r:testprobe2 kprobe_trace_selftest_target " -+ "$retval", create_trace_kprobe); - if (WARN_ON_ONCE(ret)) { - pr_warn("error on probing function return.\n"); - warn++; -@@ -1537,13 +1537,13 @@ static __init int kprobe_trace_self_tests_init(void) - disable_trace_kprobe(tk, file); - } - -- ret = traceprobe_command("-:testprobe", create_trace_kprobe); -+ ret = trace_run_command("-:testprobe", create_trace_kprobe); - if (WARN_ON_ONCE(ret)) { - pr_warn("error on deleting a probe.\n"); - warn++; - } - -- ret = traceprobe_command("-:testprobe2", create_trace_kprobe); -+ ret = trace_run_command("-:testprobe2", create_trace_kprobe); - if (WARN_ON_ONCE(ret)) { - pr_warn("error on deleting a probe.\n"); - warn++; -diff --git a/kernel/trace/trace_probe.c b/kernel/trace/trace_probe.c -index fe4513330412..daf54bda4dc8 100644 ---- a/kernel/trace/trace_probe.c -+++ b/kernel/trace/trace_probe.c -@@ -621,92 +621,6 @@ void traceprobe_free_probe_arg(struct probe_arg *arg) - kfree(arg->comm); - } - --int traceprobe_command(const char *buf, int (*createfn)(int, char **)) --{ -- char **argv; -- int argc, ret; -- -- argc = 0; -- ret = 0; -- argv = argv_split(GFP_KERNEL, buf, &argc); -- if (!argv) -- return -ENOMEM; -- -- if (argc) -- ret = createfn(argc, argv); -- -- argv_free(argv); -- -- return ret; --} -- --#define WRITE_BUFSIZE 4096 -- --ssize_t traceprobe_probes_write(struct file *file, const char __user *buffer, -- size_t count, loff_t *ppos, -- int (*createfn)(int, char **)) --{ -- char *kbuf, *buf, *tmp; -- int ret = 0; -- size_t done = 0; -- size_t size; -- -- kbuf = kmalloc(WRITE_BUFSIZE, GFP_KERNEL); -- if (!kbuf) -- return -ENOMEM; -- -- while (done < count) { -- size = count - done; -- -- if (size >= WRITE_BUFSIZE) -- size = WRITE_BUFSIZE - 1; -- -- if (copy_from_user(kbuf, buffer + done, size)) { -- ret = -EFAULT; -- goto out; -- } -- kbuf[size] = '\0'; -- buf = kbuf; -- do { -- tmp = strchr(buf, '\n'); -- if (tmp) { -- *tmp = '\0'; -- size = tmp - buf + 1; -- } else { -- size = strlen(buf); -- if (done + size < count) { -- if (buf != kbuf) -- break; -- /* This can accept WRITE_BUFSIZE - 2 ('\n' + '\0') */ -- pr_warn("Line length is too long: Should be less than %d\n", -- WRITE_BUFSIZE - 2); -- ret = -EINVAL; -- goto out; -- } -- } -- done += size; -- -- /* Remove comments */ -- tmp = strchr(buf, '#'); -- -- if (tmp) -- *tmp = '\0'; -- -- ret = traceprobe_command(buf, createfn); -- if (ret) -- goto out; -- buf += size; -- -- } while (done < count); -- } -- ret = done; -- --out: -- kfree(kbuf); -- -- return ret; --} -- - static int __set_print_fmt(struct trace_probe *tp, char *buf, int len, - bool is_return) - { -diff --git a/kernel/trace/trace_probe.h b/kernel/trace/trace_probe.h -index dc39472ca9e4..a0d750e3d17c 100644 ---- a/kernel/trace/trace_probe.h -+++ b/kernel/trace/trace_probe.h -@@ -42,7 +42,6 @@ - - #define MAX_TRACE_ARGS 128 - #define MAX_ARGSTR_LEN 63 --#define MAX_EVENT_NAME_LEN 64 - #define MAX_STRING_SIZE PATH_MAX - - /* Reserved field names */ -@@ -356,12 +355,6 @@ extern void traceprobe_free_probe_arg(struct probe_arg *arg); - - extern int traceprobe_split_symbol_offset(char *symbol, long *offset); - --extern ssize_t traceprobe_probes_write(struct file *file, -- const char __user *buffer, size_t count, loff_t *ppos, -- int (*createfn)(int, char**)); -- --extern int traceprobe_command(const char *buf, int (*createfn)(int, char**)); -- - /* Sum up total data length for dynamic arraies (strings) */ - static nokprobe_inline int - __get_data_size(struct trace_probe *tp, struct pt_regs *regs) -diff --git a/kernel/trace/trace_uprobe.c b/kernel/trace/trace_uprobe.c -index ea0d90a31fc9..2ccfbb8efeb2 100644 ---- a/kernel/trace/trace_uprobe.c -+++ b/kernel/trace/trace_uprobe.c -@@ -647,7 +647,7 @@ static int probes_open(struct inode *inode, struct file *file) - static ssize_t probes_write(struct file *file, const char __user *buffer, - size_t count, loff_t *ppos) - { -- return traceprobe_probes_write(file, buffer, count, ppos, create_trace_uprobe); -+ return trace_parse_run_command(file, buffer, count, ppos, create_trace_uprobe); - } - - static const struct file_operations uprobe_events_ops = { --- -2.19.2 - diff --git a/kernel/patches-4.14.x-rt/0075-tracing-Clean-up-hist_field_flags-enum.patch b/kernel/patches-4.14.x-rt/0075-tracing-Clean-up-hist_field_flags-enum.patch deleted file mode 100644 index 3c225db6a..000000000 --- a/kernel/patches-4.14.x-rt/0075-tracing-Clean-up-hist_field_flags-enum.patch +++ /dev/null @@ -1,53 +0,0 @@ -From a10939ad451478d0da11c0b2fb7e77219a7fbd8f Mon Sep 17 00:00:00 2001 -From: Tom Zanussi -Date: Fri, 22 Sep 2017 14:58:21 -0500 -Subject: [PATCH 075/450] tracing: Clean up hist_field_flags enum - -As we add more flags, specifying explicit integers for the flag values -becomes more unwieldy and error-prone - switch them over to left-shift -values. - -Link: http://lkml.kernel.org/r/e644e4fb7665aec015f4a2d84a2f990d3dd5b8a1.1506105045.git.tom.zanussi@linux.intel.com - -Signed-off-by: Tom Zanussi -Signed-off-by: Steven Rostedt (VMware) -(cherry picked from commit 0d7a8325bf3326c92da2d21b4496a9ddde896d4f) -Signed-off-by: Sebastian Andrzej Siewior ---- - kernel/trace/trace_events_hist.c | 20 ++++++++++---------- - 1 file changed, 10 insertions(+), 10 deletions(-) - -diff --git a/kernel/trace/trace_events_hist.c b/kernel/trace/trace_events_hist.c -index 7eb975a2d0e1..4f6b6406d6ec 100644 ---- a/kernel/trace/trace_events_hist.c -+++ b/kernel/trace/trace_events_hist.c -@@ -110,16 +110,16 @@ DEFINE_HIST_FIELD_FN(u8); - #define HIST_KEY_SIZE_MAX (MAX_FILTER_STR_VAL + HIST_STACKTRACE_SIZE) - - enum hist_field_flags { -- HIST_FIELD_FL_HITCOUNT = 1, -- HIST_FIELD_FL_KEY = 2, -- HIST_FIELD_FL_STRING = 4, -- HIST_FIELD_FL_HEX = 8, -- HIST_FIELD_FL_SYM = 16, -- HIST_FIELD_FL_SYM_OFFSET = 32, -- HIST_FIELD_FL_EXECNAME = 64, -- HIST_FIELD_FL_SYSCALL = 128, -- HIST_FIELD_FL_STACKTRACE = 256, -- HIST_FIELD_FL_LOG2 = 512, -+ HIST_FIELD_FL_HITCOUNT = 1 << 0, -+ HIST_FIELD_FL_KEY = 1 << 1, -+ HIST_FIELD_FL_STRING = 1 << 2, -+ HIST_FIELD_FL_HEX = 1 << 3, -+ HIST_FIELD_FL_SYM = 1 << 4, -+ HIST_FIELD_FL_SYM_OFFSET = 1 << 5, -+ HIST_FIELD_FL_EXECNAME = 1 << 6, -+ HIST_FIELD_FL_SYSCALL = 1 << 7, -+ HIST_FIELD_FL_STACKTRACE = 1 << 8, -+ HIST_FIELD_FL_LOG2 = 1 << 9, - }; - - struct hist_trigger_attrs { --- -2.19.2 - diff --git a/kernel/patches-4.14.x-rt/0076-tracing-Add-hist_field_name-accessor.patch b/kernel/patches-4.14.x-rt/0076-tracing-Add-hist_field_name-accessor.patch deleted file mode 100644 index 34eee537f..000000000 --- a/kernel/patches-4.14.x-rt/0076-tracing-Add-hist_field_name-accessor.patch +++ /dev/null @@ -1,184 +0,0 @@ -From 5268e6c1c89091d12ad6e4f39733c0523498f42a Mon Sep 17 00:00:00 2001 -From: Tom Zanussi -Date: Fri, 22 Sep 2017 14:58:22 -0500 -Subject: [PATCH 076/450] tracing: Add hist_field_name() accessor - -In preparation for hist_fields that won't be strictly based on -trace_event_fields, add a new hist_field_name() accessor to allow that -flexibility and update associated users. - -Link: http://lkml.kernel.org/r/5b5a2d36dde067cbbe2434b10f06daac27b7dbd5.1506105045.git.tom.zanussi@linux.intel.com - -Signed-off-by: Tom Zanussi -Signed-off-by: Steven Rostedt (VMware) -(cherry picked from commit 85013256cf01629f72a327674c5d007b4a4b40da) -Signed-off-by: Sebastian Andrzej Siewior ---- - kernel/trace/trace_events_hist.c | 67 +++++++++++++++++++++----------- - 1 file changed, 45 insertions(+), 22 deletions(-) - -diff --git a/kernel/trace/trace_events_hist.c b/kernel/trace/trace_events_hist.c -index 4f6b6406d6ec..4dc39e3efb21 100644 ---- a/kernel/trace/trace_events_hist.c -+++ b/kernel/trace/trace_events_hist.c -@@ -146,6 +146,23 @@ struct hist_trigger_data { - struct tracing_map *map; - }; - -+static const char *hist_field_name(struct hist_field *field, -+ unsigned int level) -+{ -+ const char *field_name = ""; -+ -+ if (level > 1) -+ return field_name; -+ -+ if (field->field) -+ field_name = field->field->name; -+ -+ if (field_name == NULL) -+ field_name = ""; -+ -+ return field_name; -+} -+ - static hist_field_fn_t select_value_fn(int field_size, int field_is_signed) - { - hist_field_fn_t fn = NULL; -@@ -653,7 +670,6 @@ static int is_descending(const char *str) - static int create_sort_keys(struct hist_trigger_data *hist_data) - { - char *fields_str = hist_data->attrs->sort_key_str; -- struct ftrace_event_field *field = NULL; - struct tracing_map_sort_key *sort_key; - int descending, ret = 0; - unsigned int i, j; -@@ -670,7 +686,9 @@ static int create_sort_keys(struct hist_trigger_data *hist_data) - } - - for (i = 0; i < TRACING_MAP_SORT_KEYS_MAX; i++) { -+ struct hist_field *hist_field; - char *field_str, *field_name; -+ const char *test_name; - - sort_key = &hist_data->sort_keys[i]; - -@@ -703,8 +721,10 @@ static int create_sort_keys(struct hist_trigger_data *hist_data) - } - - for (j = 1; j < hist_data->n_fields; j++) { -- field = hist_data->fields[j]->field; -- if (field && (strcmp(field_name, field->name) == 0)) { -+ hist_field = hist_data->fields[j]; -+ test_name = hist_field_name(hist_field, 0); -+ -+ if (strcmp(field_name, test_name) == 0) { - sort_key->field_idx = j; - descending = is_descending(field_str); - if (descending < 0) { -@@ -952,6 +972,7 @@ hist_trigger_entry_print(struct seq_file *m, - struct hist_field *key_field; - char str[KSYM_SYMBOL_LEN]; - bool multiline = false; -+ const char *field_name; - unsigned int i; - u64 uval; - -@@ -963,26 +984,27 @@ hist_trigger_entry_print(struct seq_file *m, - if (i > hist_data->n_vals) - seq_puts(m, ", "); - -+ field_name = hist_field_name(key_field, 0); -+ - if (key_field->flags & HIST_FIELD_FL_HEX) { - uval = *(u64 *)(key + key_field->offset); -- seq_printf(m, "%s: %llx", -- key_field->field->name, uval); -+ seq_printf(m, "%s: %llx", field_name, uval); - } else if (key_field->flags & HIST_FIELD_FL_SYM) { - uval = *(u64 *)(key + key_field->offset); - sprint_symbol_no_offset(str, uval); -- seq_printf(m, "%s: [%llx] %-45s", -- key_field->field->name, uval, str); -+ seq_printf(m, "%s: [%llx] %-45s", field_name, -+ uval, str); - } else if (key_field->flags & HIST_FIELD_FL_SYM_OFFSET) { - uval = *(u64 *)(key + key_field->offset); - sprint_symbol(str, uval); -- seq_printf(m, "%s: [%llx] %-55s", -- key_field->field->name, uval, str); -+ seq_printf(m, "%s: [%llx] %-55s", field_name, -+ uval, str); - } else if (key_field->flags & HIST_FIELD_FL_EXECNAME) { - char *comm = elt->private_data; - - uval = *(u64 *)(key + key_field->offset); -- seq_printf(m, "%s: %-16s[%10llu]", -- key_field->field->name, comm, uval); -+ seq_printf(m, "%s: %-16s[%10llu]", field_name, -+ comm, uval); - } else if (key_field->flags & HIST_FIELD_FL_SYSCALL) { - const char *syscall_name; - -@@ -991,8 +1013,8 @@ hist_trigger_entry_print(struct seq_file *m, - if (!syscall_name) - syscall_name = "unknown_syscall"; - -- seq_printf(m, "%s: %-30s[%3llu]", -- key_field->field->name, syscall_name, uval); -+ seq_printf(m, "%s: %-30s[%3llu]", field_name, -+ syscall_name, uval); - } else if (key_field->flags & HIST_FIELD_FL_STACKTRACE) { - seq_puts(m, "stacktrace:\n"); - hist_trigger_stacktrace_print(m, -@@ -1000,15 +1022,14 @@ hist_trigger_entry_print(struct seq_file *m, - HIST_STACKTRACE_DEPTH); - multiline = true; - } else if (key_field->flags & HIST_FIELD_FL_LOG2) { -- seq_printf(m, "%s: ~ 2^%-2llu", key_field->field->name, -+ seq_printf(m, "%s: ~ 2^%-2llu", field_name, - *(u64 *)(key + key_field->offset)); - } else if (key_field->flags & HIST_FIELD_FL_STRING) { -- seq_printf(m, "%s: %-50s", key_field->field->name, -+ seq_printf(m, "%s: %-50s", field_name, - (char *)(key + key_field->offset)); - } else { - uval = *(u64 *)(key + key_field->offset); -- seq_printf(m, "%s: %10llu", key_field->field->name, -- uval); -+ seq_printf(m, "%s: %10llu", field_name, uval); - } - } - -@@ -1021,13 +1042,13 @@ hist_trigger_entry_print(struct seq_file *m, - tracing_map_read_sum(elt, HITCOUNT_IDX)); - - for (i = 1; i < hist_data->n_vals; i++) { -+ field_name = hist_field_name(hist_data->fields[i], 0); -+ - if (hist_data->fields[i]->flags & HIST_FIELD_FL_HEX) { -- seq_printf(m, " %s: %10llx", -- hist_data->fields[i]->field->name, -+ seq_printf(m, " %s: %10llx", field_name, - tracing_map_read_sum(elt, i)); - } else { -- seq_printf(m, " %s: %10llu", -- hist_data->fields[i]->field->name, -+ seq_printf(m, " %s: %10llu", field_name, - tracing_map_read_sum(elt, i)); - } - } -@@ -1142,7 +1163,9 @@ static const char *get_hist_field_flags(struct hist_field *hist_field) - - static void hist_field_print(struct seq_file *m, struct hist_field *hist_field) - { -- seq_printf(m, "%s", hist_field->field->name); -+ const char *field_name = hist_field_name(hist_field, 0); -+ -+ seq_printf(m, "%s", field_name); - if (hist_field->flags) { - const char *flags_str = get_hist_field_flags(hist_field); - --- -2.19.2 - diff --git a/kernel/patches-4.14.x-rt/0077-tracing-Reimplement-log2.patch b/kernel/patches-4.14.x-rt/0077-tracing-Reimplement-log2.patch deleted file mode 100644 index a30574af8..000000000 --- a/kernel/patches-4.14.x-rt/0077-tracing-Reimplement-log2.patch +++ /dev/null @@ -1,124 +0,0 @@ -From a26cd096a9541d39014f28705c6cdb351212b3c3 Mon Sep 17 00:00:00 2001 -From: Tom Zanussi -Date: Fri, 22 Sep 2017 14:58:23 -0500 -Subject: [PATCH 077/450] tracing: Reimplement log2 - -log2 as currently implemented applies only to u64 trace_event_field -derived fields, and assumes that anything it's applied to is a u64 -field. - -To prepare for synthetic fields like latencies, log2 should be -applicable to those as well, so take the opportunity now to fix the -current problems as well as expand to more general uses. - -log2 should be thought of as a chaining function rather than a field -type. To enable this as well as possible future function -implementations, add a hist_field operand array into the hist_field -definition for this purpose, and make use of it to implement the log2 -'function'. - -Link: http://lkml.kernel.org/r/b47f93fc0b87b36eccf716b0c018f3a71e1f1111.1506105045.git.tom.zanussi@linux.intel.com - -Signed-off-by: Tom Zanussi -Signed-off-by: Steven Rostedt (VMware) -(cherry picked from commit 5819eaddf35b24d628ddfa4fbb5f8d4026e44b96) -Signed-off-by: Sebastian Andrzej Siewior ---- - kernel/trace/trace_events_hist.c | 31 +++++++++++++++++++++++++++---- - 1 file changed, 27 insertions(+), 4 deletions(-) - -diff --git a/kernel/trace/trace_events_hist.c b/kernel/trace/trace_events_hist.c -index 4dc39e3efb21..4eddc1933079 100644 ---- a/kernel/trace/trace_events_hist.c -+++ b/kernel/trace/trace_events_hist.c -@@ -28,12 +28,16 @@ struct hist_field; - - typedef u64 (*hist_field_fn_t) (struct hist_field *field, void *event); - -+#define HIST_FIELD_OPERANDS_MAX 2 -+ - struct hist_field { - struct ftrace_event_field *field; - unsigned long flags; - hist_field_fn_t fn; - unsigned int size; - unsigned int offset; -+ unsigned int is_signed; -+ struct hist_field *operands[HIST_FIELD_OPERANDS_MAX]; - }; - - static u64 hist_field_none(struct hist_field *field, void *event) -@@ -71,7 +75,9 @@ static u64 hist_field_pstring(struct hist_field *hist_field, void *event) - - static u64 hist_field_log2(struct hist_field *hist_field, void *event) - { -- u64 val = *(u64 *)(event + hist_field->field->offset); -+ struct hist_field *operand = hist_field->operands[0]; -+ -+ u64 val = operand->fn(operand, event); - - return (u64) ilog2(roundup_pow_of_two(val)); - } -@@ -156,6 +162,8 @@ static const char *hist_field_name(struct hist_field *field, - - if (field->field) - field_name = field->field->name; -+ else if (field->flags & HIST_FIELD_FL_LOG2) -+ field_name = hist_field_name(field->operands[0], ++level); - - if (field_name == NULL) - field_name = ""; -@@ -357,8 +365,20 @@ static const struct tracing_map_ops hist_trigger_elt_comm_ops = { - .elt_init = hist_trigger_elt_comm_init, - }; - --static void destroy_hist_field(struct hist_field *hist_field) -+static void destroy_hist_field(struct hist_field *hist_field, -+ unsigned int level) - { -+ unsigned int i; -+ -+ if (level > 2) -+ return; -+ -+ if (!hist_field) -+ return; -+ -+ for (i = 0; i < HIST_FIELD_OPERANDS_MAX; i++) -+ destroy_hist_field(hist_field->operands[i], level + 1); -+ - kfree(hist_field); - } - -@@ -385,7 +405,10 @@ static struct hist_field *create_hist_field(struct ftrace_event_field *field, - } - - if (flags & HIST_FIELD_FL_LOG2) { -+ unsigned long fl = flags & ~HIST_FIELD_FL_LOG2; - hist_field->fn = hist_field_log2; -+ hist_field->operands[0] = create_hist_field(field, fl); -+ hist_field->size = hist_field->operands[0]->size; - goto out; - } - -@@ -405,7 +428,7 @@ static struct hist_field *create_hist_field(struct ftrace_event_field *field, - hist_field->fn = select_value_fn(field->size, - field->is_signed); - if (!hist_field->fn) { -- destroy_hist_field(hist_field); -+ destroy_hist_field(hist_field, 0); - return NULL; - } - } -@@ -422,7 +445,7 @@ static void destroy_hist_fields(struct hist_trigger_data *hist_data) - - for (i = 0; i < TRACING_MAP_FIELDS_MAX; i++) { - if (hist_data->fields[i]) { -- destroy_hist_field(hist_data->fields[i]); -+ destroy_hist_field(hist_data->fields[i], 0); - hist_data->fields[i] = NULL; - } - } --- -2.19.2 - diff --git a/kernel/patches-4.14.x-rt/0078-tracing-Move-hist-trigger-Documentation-to-histogram.patch b/kernel/patches-4.14.x-rt/0078-tracing-Move-hist-trigger-Documentation-to-histogram.patch deleted file mode 100644 index b932f1a59..000000000 --- a/kernel/patches-4.14.x-rt/0078-tracing-Move-hist-trigger-Documentation-to-histogram.patch +++ /dev/null @@ -1,3154 +0,0 @@ -From 63731b6eb06799763c7f72a36954341fffc9d003 Mon Sep 17 00:00:00 2001 -From: Tom Zanussi -Date: Mon, 15 Jan 2018 20:51:35 -0600 -Subject: [PATCH 078/450] tracing: Move hist trigger Documentation to - histogram.txt - -The hist trigger Documentation takes up a large part of events.txt - -since it will be getting even larger, move it to a separate file. - -Link: http://lkml.kernel.org/r/92761155ea4f529e590821b1e02207fe8619f248.1516069914.git.tom.zanussi@linux.intel.com - -Signed-off-by: Tom Zanussi -Signed-off-by: Steven Rostedt (VMware) -(cherry picked from commit 995f87b4d6ddb6bbb40309c08c3ca2a1f9f9db80) -Signed-off-by: Sebastian Andrzej Siewior ---- - Documentation/trace/events.txt | 1548 +--------------------------- - Documentation/trace/histogram.txt | 1568 +++++++++++++++++++++++++++++ - 2 files changed, 1569 insertions(+), 1547 deletions(-) - create mode 100644 Documentation/trace/histogram.txt - -diff --git a/Documentation/trace/events.txt b/Documentation/trace/events.txt -index 2cc08d4a326e..e28f7f29f2b3 100644 ---- a/Documentation/trace/events.txt -+++ b/Documentation/trace/events.txt -@@ -517,1550 +517,4 @@ The following commands are supported: - totals derived from one or more trace event format fields and/or - event counts (hitcount). - -- The format of a hist trigger is as follows: -- -- hist:keys=[:values=] -- [:sort=][:size=#entries][:pause][:continue] -- [:clear][:name=histname1] [if ] -- -- When a matching event is hit, an entry is added to a hash table -- using the key(s) and value(s) named. Keys and values correspond to -- fields in the event's format description. Values must correspond to -- numeric fields - on an event hit, the value(s) will be added to a -- sum kept for that field. The special string 'hitcount' can be used -- in place of an explicit value field - this is simply a count of -- event hits. If 'values' isn't specified, an implicit 'hitcount' -- value will be automatically created and used as the only value. -- Keys can be any field, or the special string 'stacktrace', which -- will use the event's kernel stacktrace as the key. The keywords -- 'keys' or 'key' can be used to specify keys, and the keywords -- 'values', 'vals', or 'val' can be used to specify values. Compound -- keys consisting of up to two fields can be specified by the 'keys' -- keyword. Hashing a compound key produces a unique entry in the -- table for each unique combination of component keys, and can be -- useful for providing more fine-grained summaries of event data. -- Additionally, sort keys consisting of up to two fields can be -- specified by the 'sort' keyword. If more than one field is -- specified, the result will be a 'sort within a sort': the first key -- is taken to be the primary sort key and the second the secondary -- key. If a hist trigger is given a name using the 'name' parameter, -- its histogram data will be shared with other triggers of the same -- name, and trigger hits will update this common data. Only triggers -- with 'compatible' fields can be combined in this way; triggers are -- 'compatible' if the fields named in the trigger share the same -- number and type of fields and those fields also have the same names. -- Note that any two events always share the compatible 'hitcount' and -- 'stacktrace' fields and can therefore be combined using those -- fields, however pointless that may be. -- -- 'hist' triggers add a 'hist' file to each event's subdirectory. -- Reading the 'hist' file for the event will dump the hash table in -- its entirety to stdout. If there are multiple hist triggers -- attached to an event, there will be a table for each trigger in the -- output. The table displayed for a named trigger will be the same as -- any other instance having the same name. Each printed hash table -- entry is a simple list of the keys and values comprising the entry; -- keys are printed first and are delineated by curly braces, and are -- followed by the set of value fields for the entry. By default, -- numeric fields are displayed as base-10 integers. This can be -- modified by appending any of the following modifiers to the field -- name: -- -- .hex display a number as a hex value -- .sym display an address as a symbol -- .sym-offset display an address as a symbol and offset -- .syscall display a syscall id as a system call name -- .execname display a common_pid as a program name -- -- Note that in general the semantics of a given field aren't -- interpreted when applying a modifier to it, but there are some -- restrictions to be aware of in this regard: -- -- - only the 'hex' modifier can be used for values (because values -- are essentially sums, and the other modifiers don't make sense -- in that context). -- - the 'execname' modifier can only be used on a 'common_pid'. The -- reason for this is that the execname is simply the 'comm' value -- saved for the 'current' process when an event was triggered, -- which is the same as the common_pid value saved by the event -- tracing code. Trying to apply that comm value to other pid -- values wouldn't be correct, and typically events that care save -- pid-specific comm fields in the event itself. -- -- A typical usage scenario would be the following to enable a hist -- trigger, read its current contents, and then turn it off: -- -- # echo 'hist:keys=skbaddr.hex:vals=len' > \ -- /sys/kernel/debug/tracing/events/net/netif_rx/trigger -- -- # cat /sys/kernel/debug/tracing/events/net/netif_rx/hist -- -- # echo '!hist:keys=skbaddr.hex:vals=len' > \ -- /sys/kernel/debug/tracing/events/net/netif_rx/trigger -- -- The trigger file itself can be read to show the details of the -- currently attached hist trigger. This information is also displayed -- at the top of the 'hist' file when read. -- -- By default, the size of the hash table is 2048 entries. The 'size' -- parameter can be used to specify more or fewer than that. The units -- are in terms of hashtable entries - if a run uses more entries than -- specified, the results will show the number of 'drops', the number -- of hits that were ignored. The size should be a power of 2 between -- 128 and 131072 (any non- power-of-2 number specified will be rounded -- up). -- -- The 'sort' parameter can be used to specify a value field to sort -- on. The default if unspecified is 'hitcount' and the default sort -- order is 'ascending'. To sort in the opposite direction, append -- .descending' to the sort key. -- -- The 'pause' parameter can be used to pause an existing hist trigger -- or to start a hist trigger but not log any events until told to do -- so. 'continue' or 'cont' can be used to start or restart a paused -- hist trigger. -- -- The 'clear' parameter will clear the contents of a running hist -- trigger and leave its current paused/active state. -- -- Note that the 'pause', 'cont', and 'clear' parameters should be -- applied using 'append' shell operator ('>>') if applied to an -- existing trigger, rather than via the '>' operator, which will cause -- the trigger to be removed through truncation. -- --- enable_hist/disable_hist -- -- The enable_hist and disable_hist triggers can be used to have one -- event conditionally start and stop another event's already-attached -- hist trigger. Any number of enable_hist and disable_hist triggers -- can be attached to a given event, allowing that event to kick off -- and stop aggregations on a host of other events. -- -- The format is very similar to the enable/disable_event triggers: -- -- enable_hist::[:count] -- disable_hist::[:count] -- -- Instead of enabling or disabling the tracing of the target event -- into the trace buffer as the enable/disable_event triggers do, the -- enable/disable_hist triggers enable or disable the aggregation of -- the target event into a hash table. -- -- A typical usage scenario for the enable_hist/disable_hist triggers -- would be to first set up a paused hist trigger on some event, -- followed by an enable_hist/disable_hist pair that turns the hist -- aggregation on and off when conditions of interest are hit: -- -- # echo 'hist:keys=skbaddr.hex:vals=len:pause' > \ -- /sys/kernel/debug/tracing/events/net/netif_receive_skb/trigger -- -- # echo 'enable_hist:net:netif_receive_skb if filename==/usr/bin/wget' > \ -- /sys/kernel/debug/tracing/events/sched/sched_process_exec/trigger -- -- # echo 'disable_hist:net:netif_receive_skb if comm==wget' > \ -- /sys/kernel/debug/tracing/events/sched/sched_process_exit/trigger -- -- The above sets up an initially paused hist trigger which is unpaused -- and starts aggregating events when a given program is executed, and -- which stops aggregating when the process exits and the hist trigger -- is paused again. -- -- The examples below provide a more concrete illustration of the -- concepts and typical usage patterns discussed above. -- -- --6.2 'hist' trigger examples ----------------------------- -- -- The first set of examples creates aggregations using the kmalloc -- event. The fields that can be used for the hist trigger are listed -- in the kmalloc event's format file: -- -- # cat /sys/kernel/debug/tracing/events/kmem/kmalloc/format -- name: kmalloc -- ID: 374 -- format: -- field:unsigned short common_type; offset:0; size:2; signed:0; -- field:unsigned char common_flags; offset:2; size:1; signed:0; -- field:unsigned char common_preempt_count; offset:3; size:1; signed:0; -- field:int common_pid; offset:4; size:4; signed:1; -- -- field:unsigned long call_site; offset:8; size:8; signed:0; -- field:const void * ptr; offset:16; size:8; signed:0; -- field:size_t bytes_req; offset:24; size:8; signed:0; -- field:size_t bytes_alloc; offset:32; size:8; signed:0; -- field:gfp_t gfp_flags; offset:40; size:4; signed:0; -- -- We'll start by creating a hist trigger that generates a simple table -- that lists the total number of bytes requested for each function in -- the kernel that made one or more calls to kmalloc: -- -- # echo 'hist:key=call_site:val=bytes_req' > \ -- /sys/kernel/debug/tracing/events/kmem/kmalloc/trigger -- -- This tells the tracing system to create a 'hist' trigger using the -- call_site field of the kmalloc event as the key for the table, which -- just means that each unique call_site address will have an entry -- created for it in the table. The 'val=bytes_req' parameter tells -- the hist trigger that for each unique entry (call_site) in the -- table, it should keep a running total of the number of bytes -- requested by that call_site. -- -- We'll let it run for awhile and then dump the contents of the 'hist' -- file in the kmalloc event's subdirectory (for readability, a number -- of entries have been omitted): -- -- # cat /sys/kernel/debug/tracing/events/kmem/kmalloc/hist -- # trigger info: hist:keys=call_site:vals=bytes_req:sort=hitcount:size=2048 [active] -- -- { call_site: 18446744072106379007 } hitcount: 1 bytes_req: 176 -- { call_site: 18446744071579557049 } hitcount: 1 bytes_req: 1024 -- { call_site: 18446744071580608289 } hitcount: 1 bytes_req: 16384 -- { call_site: 18446744071581827654 } hitcount: 1 bytes_req: 24 -- { call_site: 18446744071580700980 } hitcount: 1 bytes_req: 8 -- { call_site: 18446744071579359876 } hitcount: 1 bytes_req: 152 -- { call_site: 18446744071580795365 } hitcount: 3 bytes_req: 144 -- { call_site: 18446744071581303129 } hitcount: 3 bytes_req: 144 -- { call_site: 18446744071580713234 } hitcount: 4 bytes_req: 2560 -- { call_site: 18446744071580933750 } hitcount: 4 bytes_req: 736 -- . -- . -- . -- { call_site: 18446744072106047046 } hitcount: 69 bytes_req: 5576 -- { call_site: 18446744071582116407 } hitcount: 73 bytes_req: 2336 -- { call_site: 18446744072106054684 } hitcount: 136 bytes_req: 140504 -- { call_site: 18446744072106224230 } hitcount: 136 bytes_req: 19584 -- { call_site: 18446744072106078074 } hitcount: 153 bytes_req: 2448 -- { call_site: 18446744072106062406 } hitcount: 153 bytes_req: 36720 -- { call_site: 18446744071582507929 } hitcount: 153 bytes_req: 37088 -- { call_site: 18446744072102520590 } hitcount: 273 bytes_req: 10920 -- { call_site: 18446744071582143559 } hitcount: 358 bytes_req: 716 -- { call_site: 18446744072106465852 } hitcount: 417 bytes_req: 56712 -- { call_site: 18446744072102523378 } hitcount: 485 bytes_req: 27160 -- { call_site: 18446744072099568646 } hitcount: 1676 bytes_req: 33520 -- -- Totals: -- Hits: 4610 -- Entries: 45 -- Dropped: 0 -- -- The output displays a line for each entry, beginning with the key -- specified in the trigger, followed by the value(s) also specified in -- the trigger. At the beginning of the output is a line that displays -- the trigger info, which can also be displayed by reading the -- 'trigger' file: -- -- # cat /sys/kernel/debug/tracing/events/kmem/kmalloc/trigger -- hist:keys=call_site:vals=bytes_req:sort=hitcount:size=2048 [active] -- -- At the end of the output are a few lines that display the overall -- totals for the run. The 'Hits' field shows the total number of -- times the event trigger was hit, the 'Entries' field shows the total -- number of used entries in the hash table, and the 'Dropped' field -- shows the number of hits that were dropped because the number of -- used entries for the run exceeded the maximum number of entries -- allowed for the table (normally 0, but if not a hint that you may -- want to increase the size of the table using the 'size' parameter). -- -- Notice in the above output that there's an extra field, 'hitcount', -- which wasn't specified in the trigger. Also notice that in the -- trigger info output, there's a parameter, 'sort=hitcount', which -- wasn't specified in the trigger either. The reason for that is that -- every trigger implicitly keeps a count of the total number of hits -- attributed to a given entry, called the 'hitcount'. That hitcount -- information is explicitly displayed in the output, and in the -- absence of a user-specified sort parameter, is used as the default -- sort field. -- -- The value 'hitcount' can be used in place of an explicit value in -- the 'values' parameter if you don't really need to have any -- particular field summed and are mainly interested in hit -- frequencies. -- -- To turn the hist trigger off, simply call up the trigger in the -- command history and re-execute it with a '!' prepended: -- -- # echo '!hist:key=call_site:val=bytes_req' > \ -- /sys/kernel/debug/tracing/events/kmem/kmalloc/trigger -- -- Finally, notice that the call_site as displayed in the output above -- isn't really very useful. It's an address, but normally addresses -- are displayed in hex. To have a numeric field displayed as a hex -- value, simply append '.hex' to the field name in the trigger: -- -- # echo 'hist:key=call_site.hex:val=bytes_req' > \ -- /sys/kernel/debug/tracing/events/kmem/kmalloc/trigger -- -- # cat /sys/kernel/debug/tracing/events/kmem/kmalloc/hist -- # trigger info: hist:keys=call_site.hex:vals=bytes_req:sort=hitcount:size=2048 [active] -- -- { call_site: ffffffffa026b291 } hitcount: 1 bytes_req: 433 -- { call_site: ffffffffa07186ff } hitcount: 1 bytes_req: 176 -- { call_site: ffffffff811ae721 } hitcount: 1 bytes_req: 16384 -- { call_site: ffffffff811c5134 } hitcount: 1 bytes_req: 8 -- { call_site: ffffffffa04a9ebb } hitcount: 1 bytes_req: 511 -- { call_site: ffffffff8122e0a6 } hitcount: 1 bytes_req: 12 -- { call_site: ffffffff8107da84 } hitcount: 1 bytes_req: 152 -- { call_site: ffffffff812d8246 } hitcount: 1 bytes_req: 24 -- { call_site: ffffffff811dc1e5 } hitcount: 3 bytes_req: 144 -- { call_site: ffffffffa02515e8 } hitcount: 3 bytes_req: 648 -- { call_site: ffffffff81258159 } hitcount: 3 bytes_req: 144 -- { call_site: ffffffff811c80f4 } hitcount: 4 bytes_req: 544 -- . -- . -- . -- { call_site: ffffffffa06c7646 } hitcount: 106 bytes_req: 8024 -- { call_site: ffffffffa06cb246 } hitcount: 132 bytes_req: 31680 -- { call_site: ffffffffa06cef7a } hitcount: 132 bytes_req: 2112 -- { call_site: ffffffff8137e399 } hitcount: 132 bytes_req: 23232 -- { call_site: ffffffffa06c941c } hitcount: 185 bytes_req: 171360 -- { call_site: ffffffffa06f2a66 } hitcount: 185 bytes_req: 26640 -- { call_site: ffffffffa036a70e } hitcount: 265 bytes_req: 10600 -- { call_site: ffffffff81325447 } hitcount: 292 bytes_req: 584 -- { call_site: ffffffffa072da3c } hitcount: 446 bytes_req: 60656 -- { call_site: ffffffffa036b1f2 } hitcount: 526 bytes_req: 29456 -- { call_site: ffffffffa0099c06 } hitcount: 1780 bytes_req: 35600 -- -- Totals: -- Hits: 4775 -- Entries: 46 -- Dropped: 0 -- -- Even that's only marginally more useful - while hex values do look -- more like addresses, what users are typically more interested in -- when looking at text addresses are the corresponding symbols -- instead. To have an address displayed as symbolic value instead, -- simply append '.sym' or '.sym-offset' to the field name in the -- trigger: -- -- # echo 'hist:key=call_site.sym:val=bytes_req' > \ -- /sys/kernel/debug/tracing/events/kmem/kmalloc/trigger -- -- # cat /sys/kernel/debug/tracing/events/kmem/kmalloc/hist -- # trigger info: hist:keys=call_site.sym:vals=bytes_req:sort=hitcount:size=2048 [active] -- -- { call_site: [ffffffff810adcb9] syslog_print_all } hitcount: 1 bytes_req: 1024 -- { call_site: [ffffffff8154bc62] usb_control_msg } hitcount: 1 bytes_req: 8 -- { call_site: [ffffffffa00bf6fe] hidraw_send_report [hid] } hitcount: 1 bytes_req: 7 -- { call_site: [ffffffff8154acbe] usb_alloc_urb } hitcount: 1 bytes_req: 192 -- { call_site: [ffffffffa00bf1ca] hidraw_report_event [hid] } hitcount: 1 bytes_req: 7 -- { call_site: [ffffffff811e3a25] __seq_open_private } hitcount: 1 bytes_req: 40 -- { call_site: [ffffffff8109524a] alloc_fair_sched_group } hitcount: 2 bytes_req: 128 -- { call_site: [ffffffff811febd5] fsnotify_alloc_group } hitcount: 2 bytes_req: 528 -- { call_site: [ffffffff81440f58] __tty_buffer_request_room } hitcount: 2 bytes_req: 2624 -- { call_site: [ffffffff81200ba6] inotify_new_group } hitcount: 2 bytes_req: 96 -- { call_site: [ffffffffa05e19af] ieee80211_start_tx_ba_session [mac80211] } hitcount: 2 bytes_req: 464 -- { call_site: [ffffffff81672406] tcp_get_metrics } hitcount: 2 bytes_req: 304 -- { call_site: [ffffffff81097ec2] alloc_rt_sched_group } hitcount: 2 bytes_req: 128 -- { call_site: [ffffffff81089b05] sched_create_group } hitcount: 2 bytes_req: 1424 -- . -- . -- . -- { call_site: [ffffffffa04a580c] intel_crtc_page_flip [i915] } hitcount: 1185 bytes_req: 123240 -- { call_site: [ffffffffa0287592] drm_mode_page_flip_ioctl [drm] } hitcount: 1185 bytes_req: 104280 -- { call_site: [ffffffffa04c4a3c] intel_plane_duplicate_state [i915] } hitcount: 1402 bytes_req: 190672 -- { call_site: [ffffffff812891ca] ext4_find_extent } hitcount: 1518 bytes_req: 146208 -- { call_site: [ffffffffa029070e] drm_vma_node_allow [drm] } hitcount: 1746 bytes_req: 69840 -- { call_site: [ffffffffa045e7c4] i915_gem_do_execbuffer.isra.23 [i915] } hitcount: 2021 bytes_req: 792312 -- { call_site: [ffffffffa02911f2] drm_modeset_lock_crtc [drm] } hitcount: 2592 bytes_req: 145152 -- { call_site: [ffffffffa0489a66] intel_ring_begin [i915] } hitcount: 2629 bytes_req: 378576 -- { call_site: [ffffffffa046041c] i915_gem_execbuffer2 [i915] } hitcount: 2629 bytes_req: 3783248 -- { call_site: [ffffffff81325607] apparmor_file_alloc_security } hitcount: 5192 bytes_req: 10384 -- { call_site: [ffffffffa00b7c06] hid_report_raw_event [hid] } hitcount: 5529 bytes_req: 110584 -- { call_site: [ffffffff8131ebf7] aa_alloc_task_context } hitcount: 21943 bytes_req: 702176 -- { call_site: [ffffffff8125847d] ext4_htree_store_dirent } hitcount: 55759 bytes_req: 5074265 -- -- Totals: -- Hits: 109928 -- Entries: 71 -- Dropped: 0 -- -- Because the default sort key above is 'hitcount', the above shows a -- the list of call_sites by increasing hitcount, so that at the bottom -- we see the functions that made the most kmalloc calls during the -- run. If instead we we wanted to see the top kmalloc callers in -- terms of the number of bytes requested rather than the number of -- calls, and we wanted the top caller to appear at the top, we can use -- the 'sort' parameter, along with the 'descending' modifier: -- -- # echo 'hist:key=call_site.sym:val=bytes_req:sort=bytes_req.descending' > \ -- /sys/kernel/debug/tracing/events/kmem/kmalloc/trigger -- -- # cat /sys/kernel/debug/tracing/events/kmem/kmalloc/hist -- # trigger info: hist:keys=call_site.sym:vals=bytes_req:sort=bytes_req.descending:size=2048 [active] -- -- { call_site: [ffffffffa046041c] i915_gem_execbuffer2 [i915] } hitcount: 2186 bytes_req: 3397464 -- { call_site: [ffffffffa045e7c4] i915_gem_do_execbuffer.isra.23 [i915] } hitcount: 1790 bytes_req: 712176 -- { call_site: [ffffffff8125847d] ext4_htree_store_dirent } hitcount: 8132 bytes_req: 513135 -- { call_site: [ffffffff811e2a1b] seq_buf_alloc } hitcount: 106 bytes_req: 440128 -- { call_site: [ffffffffa0489a66] intel_ring_begin [i915] } hitcount: 2186 bytes_req: 314784 -- { call_site: [ffffffff812891ca] ext4_find_extent } hitcount: 2174 bytes_req: 208992 -- { call_site: [ffffffff811ae8e1] __kmalloc } hitcount: 8 bytes_req: 131072 -- { call_site: [ffffffffa04c4a3c] intel_plane_duplicate_state [i915] } hitcount: 859 bytes_req: 116824 -- { call_site: [ffffffffa02911f2] drm_modeset_lock_crtc [drm] } hitcount: 1834 bytes_req: 102704 -- { call_site: [ffffffffa04a580c] intel_crtc_page_flip [i915] } hitcount: 972 bytes_req: 101088 -- { call_site: [ffffffffa0287592] drm_mode_page_flip_ioctl [drm] } hitcount: 972 bytes_req: 85536 -- { call_site: [ffffffffa00b7c06] hid_report_raw_event [hid] } hitcount: 3333 bytes_req: 66664 -- { call_site: [ffffffff8137e559] sg_kmalloc } hitcount: 209 bytes_req: 61632 -- . -- . -- . -- { call_site: [ffffffff81095225] alloc_fair_sched_group } hitcount: 2 bytes_req: 128 -- { call_site: [ffffffff81097ec2] alloc_rt_sched_group } hitcount: 2 bytes_req: 128 -- { call_site: [ffffffff812d8406] copy_semundo } hitcount: 2 bytes_req: 48 -- { call_site: [ffffffff81200ba6] inotify_new_group } hitcount: 1 bytes_req: 48 -- { call_site: [ffffffffa027121a] drm_getmagic [drm] } hitcount: 1 bytes_req: 48 -- { call_site: [ffffffff811e3a25] __seq_open_private } hitcount: 1 bytes_req: 40 -- { call_site: [ffffffff811c52f4] bprm_change_interp } hitcount: 2 bytes_req: 16 -- { call_site: [ffffffff8154bc62] usb_control_msg } hitcount: 1 bytes_req: 8 -- { call_site: [ffffffffa00bf1ca] hidraw_report_event [hid] } hitcount: 1 bytes_req: 7 -- { call_site: [ffffffffa00bf6fe] hidraw_send_report [hid] } hitcount: 1 bytes_req: 7 -- -- Totals: -- Hits: 32133 -- Entries: 81 -- Dropped: 0 -- -- To display the offset and size information in addition to the symbol -- name, just use 'sym-offset' instead: -- -- # echo 'hist:key=call_site.sym-offset:val=bytes_req:sort=bytes_req.descending' > \ -- /sys/kernel/debug/tracing/events/kmem/kmalloc/trigger -- -- # cat /sys/kernel/debug/tracing/events/kmem/kmalloc/hist -- # trigger info: hist:keys=call_site.sym-offset:vals=bytes_req:sort=bytes_req.descending:size=2048 [active] -- -- { call_site: [ffffffffa046041c] i915_gem_execbuffer2+0x6c/0x2c0 [i915] } hitcount: 4569 bytes_req: 3163720 -- { call_site: [ffffffffa0489a66] intel_ring_begin+0xc6/0x1f0 [i915] } hitcount: 4569 bytes_req: 657936 -- { call_site: [ffffffffa045e7c4] i915_gem_do_execbuffer.isra.23+0x694/0x1020 [i915] } hitcount: 1519 bytes_req: 472936 -- { call_site: [ffffffffa045e646] i915_gem_do_execbuffer.isra.23+0x516/0x1020 [i915] } hitcount: 3050 bytes_req: 211832 -- { call_site: [ffffffff811e2a1b] seq_buf_alloc+0x1b/0x50 } hitcount: 34 bytes_req: 148384 -- { call_site: [ffffffffa04a580c] intel_crtc_page_flip+0xbc/0x870 [i915] } hitcount: 1385 bytes_req: 144040 -- { call_site: [ffffffff811ae8e1] __kmalloc+0x191/0x1b0 } hitcount: 8 bytes_req: 131072 -- { call_site: [ffffffffa0287592] drm_mode_page_flip_ioctl+0x282/0x360 [drm] } hitcount: 1385 bytes_req: 121880 -- { call_site: [ffffffffa02911f2] drm_modeset_lock_crtc+0x32/0x100 [drm] } hitcount: 1848 bytes_req: 103488 -- { call_site: [ffffffffa04c4a3c] intel_plane_duplicate_state+0x2c/0xa0 [i915] } hitcount: 461 bytes_req: 62696 -- { call_site: [ffffffffa029070e] drm_vma_node_allow+0x2e/0xd0 [drm] } hitcount: 1541 bytes_req: 61640 -- { call_site: [ffffffff815f8d7b] sk_prot_alloc+0xcb/0x1b0 } hitcount: 57 bytes_req: 57456 -- . -- . -- . -- { call_site: [ffffffff8109524a] alloc_fair_sched_group+0x5a/0x1a0 } hitcount: 2 bytes_req: 128 -- { call_site: [ffffffffa027b921] drm_vm_open_locked+0x31/0xa0 [drm] } hitcount: 3 bytes_req: 96 -- { call_site: [ffffffff8122e266] proc_self_follow_link+0x76/0xb0 } hitcount: 8 bytes_req: 96 -- { call_site: [ffffffff81213e80] load_elf_binary+0x240/0x1650 } hitcount: 3 bytes_req: 84 -- { call_site: [ffffffff8154bc62] usb_control_msg+0x42/0x110 } hitcount: 1 bytes_req: 8 -- { call_site: [ffffffffa00bf6fe] hidraw_send_report+0x7e/0x1a0 [hid] } hitcount: 1 bytes_req: 7 -- { call_site: [ffffffffa00bf1ca] hidraw_report_event+0x8a/0x120 [hid] } hitcount: 1 bytes_req: 7 -- -- Totals: -- Hits: 26098 -- Entries: 64 -- Dropped: 0 -- -- We can also add multiple fields to the 'values' parameter. For -- example, we might want to see the total number of bytes allocated -- alongside bytes requested, and display the result sorted by bytes -- allocated in a descending order: -- -- # echo 'hist:keys=call_site.sym:values=bytes_req,bytes_alloc:sort=bytes_alloc.descending' > \ -- /sys/kernel/debug/tracing/events/kmem/kmalloc/trigger -- -- # cat /sys/kernel/debug/tracing/events/kmem/kmalloc/hist -- # trigger info: hist:keys=call_site.sym:vals=bytes_req,bytes_alloc:sort=bytes_alloc.descending:size=2048 [active] -- -- { call_site: [ffffffffa046041c] i915_gem_execbuffer2 [i915] } hitcount: 7403 bytes_req: 4084360 bytes_alloc: 5958016 -- { call_site: [ffffffff811e2a1b] seq_buf_alloc } hitcount: 541 bytes_req: 2213968 bytes_alloc: 2228224 -- { call_site: [ffffffffa0489a66] intel_ring_begin [i915] } hitcount: 7404 bytes_req: 1066176 bytes_alloc: 1421568 -- { call_site: [ffffffffa045e7c4] i915_gem_do_execbuffer.isra.23 [i915] } hitcount: 1565 bytes_req: 557368 bytes_alloc: 1037760 -- { call_site: [ffffffff8125847d] ext4_htree_store_dirent } hitcount: 9557 bytes_req: 595778 bytes_alloc: 695744 -- { call_site: [ffffffffa045e646] i915_gem_do_execbuffer.isra.23 [i915] } hitcount: 5839 bytes_req: 430680 bytes_alloc: 470400 -- { call_site: [ffffffffa04c4a3c] intel_plane_duplicate_state [i915] } hitcount: 2388 bytes_req: 324768 bytes_alloc: 458496 -- { call_site: [ffffffffa02911f2] drm_modeset_lock_crtc [drm] } hitcount: 3911 bytes_req: 219016 bytes_alloc: 250304 -- { call_site: [ffffffff815f8d7b] sk_prot_alloc } hitcount: 235 bytes_req: 236880 bytes_alloc: 240640 -- { call_site: [ffffffff8137e559] sg_kmalloc } hitcount: 557 bytes_req: 169024 bytes_alloc: 221760 -- { call_site: [ffffffffa00b7c06] hid_report_raw_event [hid] } hitcount: 9378 bytes_req: 187548 bytes_alloc: 206312 -- { call_site: [ffffffffa04a580c] intel_crtc_page_flip [i915] } hitcount: 1519 bytes_req: 157976 bytes_alloc: 194432 -- . -- . -- . -- { call_site: [ffffffff8109bd3b] sched_autogroup_create_attach } hitcount: 2 bytes_req: 144 bytes_alloc: 192 -- { call_site: [ffffffff81097ee8] alloc_rt_sched_group } hitcount: 2 bytes_req: 128 bytes_alloc: 128 -- { call_site: [ffffffff8109524a] alloc_fair_sched_group } hitcount: 2 bytes_req: 128 bytes_alloc: 128 -- { call_site: [ffffffff81095225] alloc_fair_sched_group } hitcount: 2 bytes_req: 128 bytes_alloc: 128 -- { call_site: [ffffffff81097ec2] alloc_rt_sched_group } hitcount: 2 bytes_req: 128 bytes_alloc: 128 -- { call_site: [ffffffff81213e80] load_elf_binary } hitcount: 3 bytes_req: 84 bytes_alloc: 96 -- { call_site: [ffffffff81079a2e] kthread_create_on_node } hitcount: 1 bytes_req: 56 bytes_alloc: 64 -- { call_site: [ffffffffa00bf6fe] hidraw_send_report [hid] } hitcount: 1 bytes_req: 7 bytes_alloc: 8 -- { call_site: [ffffffff8154bc62] usb_control_msg } hitcount: 1 bytes_req: 8 bytes_alloc: 8 -- { call_site: [ffffffffa00bf1ca] hidraw_report_event [hid] } hitcount: 1 bytes_req: 7 bytes_alloc: 8 -- -- Totals: -- Hits: 66598 -- Entries: 65 -- Dropped: 0 -- -- Finally, to finish off our kmalloc example, instead of simply having -- the hist trigger display symbolic call_sites, we can have the hist -- trigger additionally display the complete set of kernel stack traces -- that led to each call_site. To do that, we simply use the special -- value 'stacktrace' for the key parameter: -- -- # echo 'hist:keys=stacktrace:values=bytes_req,bytes_alloc:sort=bytes_alloc' > \ -- /sys/kernel/debug/tracing/events/kmem/kmalloc/trigger -- -- The above trigger will use the kernel stack trace in effect when an -- event is triggered as the key for the hash table. This allows the -- enumeration of every kernel callpath that led up to a particular -- event, along with a running total of any of the event fields for -- that event. Here we tally bytes requested and bytes allocated for -- every callpath in the system that led up to a kmalloc (in this case -- every callpath to a kmalloc for a kernel compile): -- -- # cat /sys/kernel/debug/tracing/events/kmem/kmalloc/hist -- # trigger info: hist:keys=stacktrace:vals=bytes_req,bytes_alloc:sort=bytes_alloc:size=2048 [active] -- -- { stacktrace: -- __kmalloc_track_caller+0x10b/0x1a0 -- kmemdup+0x20/0x50 -- hidraw_report_event+0x8a/0x120 [hid] -- hid_report_raw_event+0x3ea/0x440 [hid] -- hid_input_report+0x112/0x190 [hid] -- hid_irq_in+0xc2/0x260 [usbhid] -- __usb_hcd_giveback_urb+0x72/0x120 -- usb_giveback_urb_bh+0x9e/0xe0 -- tasklet_hi_action+0xf8/0x100 -- __do_softirq+0x114/0x2c0 -- irq_exit+0xa5/0xb0 -- do_IRQ+0x5a/0xf0 -- ret_from_intr+0x0/0x30 -- cpuidle_enter+0x17/0x20 -- cpu_startup_entry+0x315/0x3e0 -- rest_init+0x7c/0x80 -- } hitcount: 3 bytes_req: 21 bytes_alloc: 24 -- { stacktrace: -- __kmalloc_track_caller+0x10b/0x1a0 -- kmemdup+0x20/0x50 -- hidraw_report_event+0x8a/0x120 [hid] -- hid_report_raw_event+0x3ea/0x440 [hid] -- hid_input_report+0x112/0x190 [hid] -- hid_irq_in+0xc2/0x260 [usbhid] -- __usb_hcd_giveback_urb+0x72/0x120 -- usb_giveback_urb_bh+0x9e/0xe0 -- tasklet_hi_action+0xf8/0x100 -- __do_softirq+0x114/0x2c0 -- irq_exit+0xa5/0xb0 -- do_IRQ+0x5a/0xf0 -- ret_from_intr+0x0/0x30 -- } hitcount: 3 bytes_req: 21 bytes_alloc: 24 -- { stacktrace: -- kmem_cache_alloc_trace+0xeb/0x150 -- aa_alloc_task_context+0x27/0x40 -- apparmor_cred_prepare+0x1f/0x50 -- security_prepare_creds+0x16/0x20 -- prepare_creds+0xdf/0x1a0 -- SyS_capset+0xb5/0x200 -- system_call_fastpath+0x12/0x6a -- } hitcount: 1 bytes_req: 32 bytes_alloc: 32 -- . -- . -- . -- { stacktrace: -- __kmalloc+0x11b/0x1b0 -- i915_gem_execbuffer2+0x6c/0x2c0 [i915] -- drm_ioctl+0x349/0x670 [drm] -- do_vfs_ioctl+0x2f0/0x4f0 -- SyS_ioctl+0x81/0xa0 -- system_call_fastpath+0x12/0x6a -- } hitcount: 17726 bytes_req: 13944120 bytes_alloc: 19593808 -- { stacktrace: -- __kmalloc+0x11b/0x1b0 -- load_elf_phdrs+0x76/0xa0 -- load_elf_binary+0x102/0x1650 -- search_binary_handler+0x97/0x1d0 -- do_execveat_common.isra.34+0x551/0x6e0 -- SyS_execve+0x3a/0x50 -- return_from_execve+0x0/0x23 -- } hitcount: 33348 bytes_req: 17152128 bytes_alloc: 20226048 -- { stacktrace: -- kmem_cache_alloc_trace+0xeb/0x150 -- apparmor_file_alloc_security+0x27/0x40 -- security_file_alloc+0x16/0x20 -- get_empty_filp+0x93/0x1c0 -- path_openat+0x31/0x5f0 -- do_filp_open+0x3a/0x90 -- do_sys_open+0x128/0x220 -- SyS_open+0x1e/0x20 -- system_call_fastpath+0x12/0x6a -- } hitcount: 4766422 bytes_req: 9532844 bytes_alloc: 38131376 -- { stacktrace: -- __kmalloc+0x11b/0x1b0 -- seq_buf_alloc+0x1b/0x50 -- seq_read+0x2cc/0x370 -- proc_reg_read+0x3d/0x80 -- __vfs_read+0x28/0xe0 -- vfs_read+0x86/0x140 -- SyS_read+0x46/0xb0 -- system_call_fastpath+0x12/0x6a -- } hitcount: 19133 bytes_req: 78368768 bytes_alloc: 78368768 -- -- Totals: -- Hits: 6085872 -- Entries: 253 -- Dropped: 0 -- -- If you key a hist trigger on common_pid, in order for example to -- gather and display sorted totals for each process, you can use the -- special .execname modifier to display the executable names for the -- processes in the table rather than raw pids. The example below -- keeps a per-process sum of total bytes read: -- -- # echo 'hist:key=common_pid.execname:val=count:sort=count.descending' > \ -- /sys/kernel/debug/tracing/events/syscalls/sys_enter_read/trigger -- -- # cat /sys/kernel/debug/tracing/events/syscalls/sys_enter_read/hist -- # trigger info: hist:keys=common_pid.execname:vals=count:sort=count.descending:size=2048 [active] -- -- { common_pid: gnome-terminal [ 3196] } hitcount: 280 count: 1093512 -- { common_pid: Xorg [ 1309] } hitcount: 525 count: 256640 -- { common_pid: compiz [ 2889] } hitcount: 59 count: 254400 -- { common_pid: bash [ 8710] } hitcount: 3 count: 66369 -- { common_pid: dbus-daemon-lau [ 8703] } hitcount: 49 count: 47739 -- { common_pid: irqbalance [ 1252] } hitcount: 27 count: 27648 -- { common_pid: 01ifupdown [ 8705] } hitcount: 3 count: 17216 -- { common_pid: dbus-daemon [ 772] } hitcount: 10 count: 12396 -- { common_pid: Socket Thread [ 8342] } hitcount: 11 count: 11264 -- { common_pid: nm-dhcp-client. [ 8701] } hitcount: 6 count: 7424 -- { common_pid: gmain [ 1315] } hitcount: 18 count: 6336 -- . -- . -- . -- { common_pid: postgres [ 1892] } hitcount: 2 count: 32 -- { common_pid: postgres [ 1891] } hitcount: 2 count: 32 -- { common_pid: gmain [ 8704] } hitcount: 2 count: 32 -- { common_pid: upstart-dbus-br [ 2740] } hitcount: 21 count: 21 -- { common_pid: nm-dispatcher.a [ 8696] } hitcount: 1 count: 16 -- { common_pid: indicator-datet [ 2904] } hitcount: 1 count: 16 -- { common_pid: gdbus [ 2998] } hitcount: 1 count: 16 -- { common_pid: rtkit-daemon [ 2052] } hitcount: 1 count: 8 -- { common_pid: init [ 1] } hitcount: 2 count: 2 -- -- Totals: -- Hits: 2116 -- Entries: 51 -- Dropped: 0 -- -- Similarly, if you key a hist trigger on syscall id, for example to -- gather and display a list of systemwide syscall hits, you can use -- the special .syscall modifier to display the syscall names rather -- than raw ids. The example below keeps a running total of syscall -- counts for the system during the run: -- -- # echo 'hist:key=id.syscall:val=hitcount' > \ -- /sys/kernel/debug/tracing/events/raw_syscalls/sys_enter/trigger -- -- # cat /sys/kernel/debug/tracing/events/raw_syscalls/sys_enter/hist -- # trigger info: hist:keys=id.syscall:vals=hitcount:sort=hitcount:size=2048 [active] -- -- { id: sys_fsync [ 74] } hitcount: 1 -- { id: sys_newuname [ 63] } hitcount: 1 -- { id: sys_prctl [157] } hitcount: 1 -- { id: sys_statfs [137] } hitcount: 1 -- { id: sys_symlink [ 88] } hitcount: 1 -- { id: sys_sendmmsg [307] } hitcount: 1 -- { id: sys_semctl [ 66] } hitcount: 1 -- { id: sys_readlink [ 89] } hitcount: 3 -- { id: sys_bind [ 49] } hitcount: 3 -- { id: sys_getsockname [ 51] } hitcount: 3 -- { id: sys_unlink [ 87] } hitcount: 3 -- { id: sys_rename [ 82] } hitcount: 4 -- { id: unknown_syscall [ 58] } hitcount: 4 -- { id: sys_connect [ 42] } hitcount: 4 -- { id: sys_getpid [ 39] } hitcount: 4 -- . -- . -- . -- { id: sys_rt_sigprocmask [ 14] } hitcount: 952 -- { id: sys_futex [202] } hitcount: 1534 -- { id: sys_write [ 1] } hitcount: 2689 -- { id: sys_setitimer [ 38] } hitcount: 2797 -- { id: sys_read [ 0] } hitcount: 3202 -- { id: sys_select [ 23] } hitcount: 3773 -- { id: sys_writev [ 20] } hitcount: 4531 -- { id: sys_poll [ 7] } hitcount: 8314 -- { id: sys_recvmsg [ 47] } hitcount: 13738 -- { id: sys_ioctl [ 16] } hitcount: 21843 -- -- Totals: -- Hits: 67612 -- Entries: 72 -- Dropped: 0 -- -- The syscall counts above provide a rough overall picture of system -- call activity on the system; we can see for example that the most -- popular system call on this system was the 'sys_ioctl' system call. -- -- We can use 'compound' keys to refine that number and provide some -- further insight as to which processes exactly contribute to the -- overall ioctl count. -- -- The command below keeps a hitcount for every unique combination of -- system call id and pid - the end result is essentially a table -- that keeps a per-pid sum of system call hits. The results are -- sorted using the system call id as the primary key, and the -- hitcount sum as the secondary key: -- -- # echo 'hist:key=id.syscall,common_pid.execname:val=hitcount:sort=id,hitcount' > \ -- /sys/kernel/debug/tracing/events/raw_syscalls/sys_enter/trigger -- -- # cat /sys/kernel/debug/tracing/events/raw_syscalls/sys_enter/hist -- # trigger info: hist:keys=id.syscall,common_pid.execname:vals=hitcount:sort=id.syscall,hitcount:size=2048 [active] -- -- { id: sys_read [ 0], common_pid: rtkit-daemon [ 1877] } hitcount: 1 -- { id: sys_read [ 0], common_pid: gdbus [ 2976] } hitcount: 1 -- { id: sys_read [ 0], common_pid: console-kit-dae [ 3400] } hitcount: 1 -- { id: sys_read [ 0], common_pid: postgres [ 1865] } hitcount: 1 -- { id: sys_read [ 0], common_pid: deja-dup-monito [ 3543] } hitcount: 2 -- { id: sys_read [ 0], common_pid: NetworkManager [ 890] } hitcount: 2 -- { id: sys_read [ 0], common_pid: evolution-calen [ 3048] } hitcount: 2 -- { id: sys_read [ 0], common_pid: postgres [ 1864] } hitcount: 2 -- { id: sys_read [ 0], common_pid: nm-applet [ 3022] } hitcount: 2 -- { id: sys_read [ 0], common_pid: whoopsie [ 1212] } hitcount: 2 -- . -- . -- . -- { id: sys_ioctl [ 16], common_pid: bash [ 8479] } hitcount: 1 -- { id: sys_ioctl [ 16], common_pid: bash [ 3472] } hitcount: 12 -- { id: sys_ioctl [ 16], common_pid: gnome-terminal [ 3199] } hitcount: 16 -- { id: sys_ioctl [ 16], common_pid: Xorg [ 1267] } hitcount: 1808 -- { id: sys_ioctl [ 16], common_pid: compiz [ 2994] } hitcount: 5580 -- . -- . -- . -- { id: sys_waitid [247], common_pid: upstart-dbus-br [ 2690] } hitcount: 3 -- { id: sys_waitid [247], common_pid: upstart-dbus-br [ 2688] } hitcount: 16 -- { id: sys_inotify_add_watch [254], common_pid: gmain [ 975] } hitcount: 2 -- { id: sys_inotify_add_watch [254], common_pid: gmain [ 3204] } hitcount: 4 -- { id: sys_inotify_add_watch [254], common_pid: gmain [ 2888] } hitcount: 4 -- { id: sys_inotify_add_watch [254], common_pid: gmain [ 3003] } hitcount: 4 -- { id: sys_inotify_add_watch [254], common_pid: gmain [ 2873] } hitcount: 4 -- { id: sys_inotify_add_watch [254], common_pid: gmain [ 3196] } hitcount: 6 -- { id: sys_openat [257], common_pid: java [ 2623] } hitcount: 2 -- { id: sys_eventfd2 [290], common_pid: ibus-ui-gtk3 [ 2760] } hitcount: 4 -- { id: sys_eventfd2 [290], common_pid: compiz [ 2994] } hitcount: 6 -- -- Totals: -- Hits: 31536 -- Entries: 323 -- Dropped: 0 -- -- The above list does give us a breakdown of the ioctl syscall by -- pid, but it also gives us quite a bit more than that, which we -- don't really care about at the moment. Since we know the syscall -- id for sys_ioctl (16, displayed next to the sys_ioctl name), we -- can use that to filter out all the other syscalls: -- -- # echo 'hist:key=id.syscall,common_pid.execname:val=hitcount:sort=id,hitcount if id == 16' > \ -- /sys/kernel/debug/tracing/events/raw_syscalls/sys_enter/trigger -- -- # cat /sys/kernel/debug/tracing/events/raw_syscalls/sys_enter/hist -- # trigger info: hist:keys=id.syscall,common_pid.execname:vals=hitcount:sort=id.syscall,hitcount:size=2048 if id == 16 [active] -- -- { id: sys_ioctl [ 16], common_pid: gmain [ 2769] } hitcount: 1 -- { id: sys_ioctl [ 16], common_pid: evolution-addre [ 8571] } hitcount: 1 -- { id: sys_ioctl [ 16], common_pid: gmain [ 3003] } hitcount: 1 -- { id: sys_ioctl [ 16], common_pid: gmain [ 2781] } hitcount: 1 -- { id: sys_ioctl [ 16], common_pid: gmain [ 2829] } hitcount: 1 -- { id: sys_ioctl [ 16], common_pid: bash [ 8726] } hitcount: 1 -- { id: sys_ioctl [ 16], common_pid: bash [ 8508] } hitcount: 1 -- { id: sys_ioctl [ 16], common_pid: gmain [ 2970] } hitcount: 1 -- { id: sys_ioctl [ 16], common_pid: gmain [ 2768] } hitcount: 1 -- . -- . -- . -- { id: sys_ioctl [ 16], common_pid: pool [ 8559] } hitcount: 45 -- { id: sys_ioctl [ 16], common_pid: pool [ 8555] } hitcount: 48 -- { id: sys_ioctl [ 16], common_pid: pool [ 8551] } hitcount: 48 -- { id: sys_ioctl [ 16], common_pid: avahi-daemon [ 896] } hitcount: 66 -- { id: sys_ioctl [ 16], common_pid: Xorg [ 1267] } hitcount: 26674 -- { id: sys_ioctl [ 16], common_pid: compiz [ 2994] } hitcount: 73443 -- -- Totals: -- Hits: 101162 -- Entries: 103 -- Dropped: 0 -- -- The above output shows that 'compiz' and 'Xorg' are far and away -- the heaviest ioctl callers (which might lead to questions about -- whether they really need to be making all those calls and to -- possible avenues for further investigation.) -- -- The compound key examples used a key and a sum value (hitcount) to -- sort the output, but we can just as easily use two keys instead. -- Here's an example where we use a compound key composed of the the -- common_pid and size event fields. Sorting with pid as the primary -- key and 'size' as the secondary key allows us to display an -- ordered summary of the recvfrom sizes, with counts, received by -- each process: -- -- # echo 'hist:key=common_pid.execname,size:val=hitcount:sort=common_pid,size' > \ -- /sys/kernel/debug/tracing/events/syscalls/sys_enter_recvfrom/trigger -- -- # cat /sys/kernel/debug/tracing/events/syscalls/sys_enter_recvfrom/hist -- # trigger info: hist:keys=common_pid.execname,size:vals=hitcount:sort=common_pid.execname,size:size=2048 [active] -- -- { common_pid: smbd [ 784], size: 4 } hitcount: 1 -- { common_pid: dnsmasq [ 1412], size: 4096 } hitcount: 672 -- { common_pid: postgres [ 1796], size: 1000 } hitcount: 6 -- { common_pid: postgres [ 1867], size: 1000 } hitcount: 10 -- { common_pid: bamfdaemon [ 2787], size: 28 } hitcount: 2 -- { common_pid: bamfdaemon [ 2787], size: 14360 } hitcount: 1 -- { common_pid: compiz [ 2994], size: 8 } hitcount: 1 -- { common_pid: compiz [ 2994], size: 20 } hitcount: 11 -- { common_pid: gnome-terminal [ 3199], size: 4 } hitcount: 2 -- { common_pid: firefox [ 8817], size: 4 } hitcount: 1 -- { common_pid: firefox [ 8817], size: 8 } hitcount: 5 -- { common_pid: firefox [ 8817], size: 588 } hitcount: 2 -- { common_pid: firefox [ 8817], size: 628 } hitcount: 1 -- { common_pid: firefox [ 8817], size: 6944 } hitcount: 1 -- { common_pid: firefox [ 8817], size: 408880 } hitcount: 2 -- { common_pid: firefox [ 8822], size: 8 } hitcount: 2 -- { common_pid: firefox [ 8822], size: 160 } hitcount: 2 -- { common_pid: firefox [ 8822], size: 320 } hitcount: 2 -- { common_pid: firefox [ 8822], size: 352 } hitcount: 1 -- . -- . -- . -- { common_pid: pool [ 8923], size: 1960 } hitcount: 10 -- { common_pid: pool [ 8923], size: 2048 } hitcount: 10 -- { common_pid: pool [ 8924], size: 1960 } hitcount: 10 -- { common_pid: pool [ 8924], size: 2048 } hitcount: 10 -- { common_pid: pool [ 8928], size: 1964 } hitcount: 4 -- { common_pid: pool [ 8928], size: 1965 } hitcount: 2 -- { common_pid: pool [ 8928], size: 2048 } hitcount: 6 -- { common_pid: pool [ 8929], size: 1982 } hitcount: 1 -- { common_pid: pool [ 8929], size: 2048 } hitcount: 1 -- -- Totals: -- Hits: 2016 -- Entries: 224 -- Dropped: 0 -- -- The above example also illustrates the fact that although a compound -- key is treated as a single entity for hashing purposes, the sub-keys -- it's composed of can be accessed independently. -- -- The next example uses a string field as the hash key and -- demonstrates how you can manually pause and continue a hist trigger. -- In this example, we'll aggregate fork counts and don't expect a -- large number of entries in the hash table, so we'll drop it to a -- much smaller number, say 256: -- -- # echo 'hist:key=child_comm:val=hitcount:size=256' > \ -- /sys/kernel/debug/tracing/events/sched/sched_process_fork/trigger -- -- # cat /sys/kernel/debug/tracing/events/sched/sched_process_fork/hist -- # trigger info: hist:keys=child_comm:vals=hitcount:sort=hitcount:size=256 [active] -- -- { child_comm: dconf worker } hitcount: 1 -- { child_comm: ibus-daemon } hitcount: 1 -- { child_comm: whoopsie } hitcount: 1 -- { child_comm: smbd } hitcount: 1 -- { child_comm: gdbus } hitcount: 1 -- { child_comm: kthreadd } hitcount: 1 -- { child_comm: dconf worker } hitcount: 1 -- { child_comm: evolution-alarm } hitcount: 2 -- { child_comm: Socket Thread } hitcount: 2 -- { child_comm: postgres } hitcount: 2 -- { child_comm: bash } hitcount: 3 -- { child_comm: compiz } hitcount: 3 -- { child_comm: evolution-sourc } hitcount: 4 -- { child_comm: dhclient } hitcount: 4 -- { child_comm: pool } hitcount: 5 -- { child_comm: nm-dispatcher.a } hitcount: 8 -- { child_comm: firefox } hitcount: 8 -- { child_comm: dbus-daemon } hitcount: 8 -- { child_comm: glib-pacrunner } hitcount: 10 -- { child_comm: evolution } hitcount: 23 -- -- Totals: -- Hits: 89 -- Entries: 20 -- Dropped: 0 -- -- If we want to pause the hist trigger, we can simply append :pause to -- the command that started the trigger. Notice that the trigger info -- displays as [paused]: -- -- # echo 'hist:key=child_comm:val=hitcount:size=256:pause' >> \ -- /sys/kernel/debug/tracing/events/sched/sched_process_fork/trigger -- -- # cat /sys/kernel/debug/tracing/events/sched/sched_process_fork/hist -- # trigger info: hist:keys=child_comm:vals=hitcount:sort=hitcount:size=256 [paused] -- -- { child_comm: dconf worker } hitcount: 1 -- { child_comm: kthreadd } hitcount: 1 -- { child_comm: dconf worker } hitcount: 1 -- { child_comm: gdbus } hitcount: 1 -- { child_comm: ibus-daemon } hitcount: 1 -- { child_comm: Socket Thread } hitcount: 2 -- { child_comm: evolution-alarm } hitcount: 2 -- { child_comm: smbd } hitcount: 2 -- { child_comm: bash } hitcount: 3 -- { child_comm: whoopsie } hitcount: 3 -- { child_comm: compiz } hitcount: 3 -- { child_comm: evolution-sourc } hitcount: 4 -- { child_comm: pool } hitcount: 5 -- { child_comm: postgres } hitcount: 6 -- { child_comm: firefox } hitcount: 8 -- { child_comm: dhclient } hitcount: 10 -- { child_comm: emacs } hitcount: 12 -- { child_comm: dbus-daemon } hitcount: 20 -- { child_comm: nm-dispatcher.a } hitcount: 20 -- { child_comm: evolution } hitcount: 35 -- { child_comm: glib-pacrunner } hitcount: 59 -- -- Totals: -- Hits: 199 -- Entries: 21 -- Dropped: 0 -- -- To manually continue having the trigger aggregate events, append -- :cont instead. Notice that the trigger info displays as [active] -- again, and the data has changed: -- -- # echo 'hist:key=child_comm:val=hitcount:size=256:cont' >> \ -- /sys/kernel/debug/tracing/events/sched/sched_process_fork/trigger -- -- # cat /sys/kernel/debug/tracing/events/sched/sched_process_fork/hist -- # trigger info: hist:keys=child_comm:vals=hitcount:sort=hitcount:size=256 [active] -- -- { child_comm: dconf worker } hitcount: 1 -- { child_comm: dconf worker } hitcount: 1 -- { child_comm: kthreadd } hitcount: 1 -- { child_comm: gdbus } hitcount: 1 -- { child_comm: ibus-daemon } hitcount: 1 -- { child_comm: Socket Thread } hitcount: 2 -- { child_comm: evolution-alarm } hitcount: 2 -- { child_comm: smbd } hitcount: 2 -- { child_comm: whoopsie } hitcount: 3 -- { child_comm: compiz } hitcount: 3 -- { child_comm: evolution-sourc } hitcount: 4 -- { child_comm: bash } hitcount: 5 -- { child_comm: pool } hitcount: 5 -- { child_comm: postgres } hitcount: 6 -- { child_comm: firefox } hitcount: 8 -- { child_comm: dhclient } hitcount: 11 -- { child_comm: emacs } hitcount: 12 -- { child_comm: dbus-daemon } hitcount: 22 -- { child_comm: nm-dispatcher.a } hitcount: 22 -- { child_comm: evolution } hitcount: 35 -- { child_comm: glib-pacrunner } hitcount: 59 -- -- Totals: -- Hits: 206 -- Entries: 21 -- Dropped: 0 -- -- The previous example showed how to start and stop a hist trigger by -- appending 'pause' and 'continue' to the hist trigger command. A -- hist trigger can also be started in a paused state by initially -- starting the trigger with ':pause' appended. This allows you to -- start the trigger only when you're ready to start collecting data -- and not before. For example, you could start the trigger in a -- paused state, then unpause it and do something you want to measure, -- then pause the trigger again when done. -- -- Of course, doing this manually can be difficult and error-prone, but -- it is possible to automatically start and stop a hist trigger based -- on some condition, via the enable_hist and disable_hist triggers. -- -- For example, suppose we wanted to take a look at the relative -- weights in terms of skb length for each callpath that leads to a -- netif_receieve_skb event when downloading a decent-sized file using -- wget. -- -- First we set up an initially paused stacktrace trigger on the -- netif_receive_skb event: -- -- # echo 'hist:key=stacktrace:vals=len:pause' > \ -- /sys/kernel/debug/tracing/events/net/netif_receive_skb/trigger -- -- Next, we set up an 'enable_hist' trigger on the sched_process_exec -- event, with an 'if filename==/usr/bin/wget' filter. The effect of -- this new trigger is that it will 'unpause' the hist trigger we just -- set up on netif_receive_skb if and only if it sees a -- sched_process_exec event with a filename of '/usr/bin/wget'. When -- that happens, all netif_receive_skb events are aggregated into a -- hash table keyed on stacktrace: -- -- # echo 'enable_hist:net:netif_receive_skb if filename==/usr/bin/wget' > \ -- /sys/kernel/debug/tracing/events/sched/sched_process_exec/trigger -- -- The aggregation continues until the netif_receive_skb is paused -- again, which is what the following disable_hist event does by -- creating a similar setup on the sched_process_exit event, using the -- filter 'comm==wget': -- -- # echo 'disable_hist:net:netif_receive_skb if comm==wget' > \ -- /sys/kernel/debug/tracing/events/sched/sched_process_exit/trigger -- -- Whenever a process exits and the comm field of the disable_hist -- trigger filter matches 'comm==wget', the netif_receive_skb hist -- trigger is disabled. -- -- The overall effect is that netif_receive_skb events are aggregated -- into the hash table for only the duration of the wget. Executing a -- wget command and then listing the 'hist' file will display the -- output generated by the wget command: -- -- $ wget https://www.kernel.org/pub/linux/kernel/v3.x/patch-3.19.xz -- -- # cat /sys/kernel/debug/tracing/events/net/netif_receive_skb/hist -- # trigger info: hist:keys=stacktrace:vals=len:sort=hitcount:size=2048 [paused] -- -- { stacktrace: -- __netif_receive_skb_core+0x46d/0x990 -- __netif_receive_skb+0x18/0x60 -- netif_receive_skb_internal+0x23/0x90 -- napi_gro_receive+0xc8/0x100 -- ieee80211_deliver_skb+0xd6/0x270 [mac80211] -- ieee80211_rx_handlers+0xccf/0x22f0 [mac80211] -- ieee80211_prepare_and_rx_handle+0x4e7/0xc40 [mac80211] -- ieee80211_rx+0x31d/0x900 [mac80211] -- iwlagn_rx_reply_rx+0x3db/0x6f0 [iwldvm] -- iwl_rx_dispatch+0x8e/0xf0 [iwldvm] -- iwl_pcie_irq_handler+0xe3c/0x12f0 [iwlwifi] -- irq_thread_fn+0x20/0x50 -- irq_thread+0x11f/0x150 -- kthread+0xd2/0xf0 -- ret_from_fork+0x42/0x70 -- } hitcount: 85 len: 28884 -- { stacktrace: -- __netif_receive_skb_core+0x46d/0x990 -- __netif_receive_skb+0x18/0x60 -- netif_receive_skb_internal+0x23/0x90 -- napi_gro_complete+0xa4/0xe0 -- dev_gro_receive+0x23a/0x360 -- napi_gro_receive+0x30/0x100 -- ieee80211_deliver_skb+0xd6/0x270 [mac80211] -- ieee80211_rx_handlers+0xccf/0x22f0 [mac80211] -- ieee80211_prepare_and_rx_handle+0x4e7/0xc40 [mac80211] -- ieee80211_rx+0x31d/0x900 [mac80211] -- iwlagn_rx_reply_rx+0x3db/0x6f0 [iwldvm] -- iwl_rx_dispatch+0x8e/0xf0 [iwldvm] -- iwl_pcie_irq_handler+0xe3c/0x12f0 [iwlwifi] -- irq_thread_fn+0x20/0x50 -- irq_thread+0x11f/0x150 -- kthread+0xd2/0xf0 -- } hitcount: 98 len: 664329 -- { stacktrace: -- __netif_receive_skb_core+0x46d/0x990 -- __netif_receive_skb+0x18/0x60 -- process_backlog+0xa8/0x150 -- net_rx_action+0x15d/0x340 -- __do_softirq+0x114/0x2c0 -- do_softirq_own_stack+0x1c/0x30 -- do_softirq+0x65/0x70 -- __local_bh_enable_ip+0xb5/0xc0 -- ip_finish_output+0x1f4/0x840 -- ip_output+0x6b/0xc0 -- ip_local_out_sk+0x31/0x40 -- ip_send_skb+0x1a/0x50 -- udp_send_skb+0x173/0x2a0 -- udp_sendmsg+0x2bf/0x9f0 -- inet_sendmsg+0x64/0xa0 -- sock_sendmsg+0x3d/0x50 -- } hitcount: 115 len: 13030 -- { stacktrace: -- __netif_receive_skb_core+0x46d/0x990 -- __netif_receive_skb+0x18/0x60 -- netif_receive_skb_internal+0x23/0x90 -- napi_gro_complete+0xa4/0xe0 -- napi_gro_flush+0x6d/0x90 -- iwl_pcie_irq_handler+0x92a/0x12f0 [iwlwifi] -- irq_thread_fn+0x20/0x50 -- irq_thread+0x11f/0x150 -- kthread+0xd2/0xf0 -- ret_from_fork+0x42/0x70 -- } hitcount: 934 len: 5512212 -- -- Totals: -- Hits: 1232 -- Entries: 4 -- Dropped: 0 -- -- The above shows all the netif_receive_skb callpaths and their total -- lengths for the duration of the wget command. -- -- The 'clear' hist trigger param can be used to clear the hash table. -- Suppose we wanted to try another run of the previous example but -- this time also wanted to see the complete list of events that went -- into the histogram. In order to avoid having to set everything up -- again, we can just clear the histogram first: -- -- # echo 'hist:key=stacktrace:vals=len:clear' >> \ -- /sys/kernel/debug/tracing/events/net/netif_receive_skb/trigger -- -- Just to verify that it is in fact cleared, here's what we now see in -- the hist file: -- -- # cat /sys/kernel/debug/tracing/events/net/netif_receive_skb/hist -- # trigger info: hist:keys=stacktrace:vals=len:sort=hitcount:size=2048 [paused] -- -- Totals: -- Hits: 0 -- Entries: 0 -- Dropped: 0 -- -- Since we want to see the detailed list of every netif_receive_skb -- event occurring during the new run, which are in fact the same -- events being aggregated into the hash table, we add some additional -- 'enable_event' events to the triggering sched_process_exec and -- sched_process_exit events as such: -- -- # echo 'enable_event:net:netif_receive_skb if filename==/usr/bin/wget' > \ -- /sys/kernel/debug/tracing/events/sched/sched_process_exec/trigger -- -- # echo 'disable_event:net:netif_receive_skb if comm==wget' > \ -- /sys/kernel/debug/tracing/events/sched/sched_process_exit/trigger -- -- If you read the trigger files for the sched_process_exec and -- sched_process_exit triggers, you should see two triggers for each: -- one enabling/disabling the hist aggregation and the other -- enabling/disabling the logging of events: -- -- # cat /sys/kernel/debug/tracing/events/sched/sched_process_exec/trigger -- enable_event:net:netif_receive_skb:unlimited if filename==/usr/bin/wget -- enable_hist:net:netif_receive_skb:unlimited if filename==/usr/bin/wget -- -- # cat /sys/kernel/debug/tracing/events/sched/sched_process_exit/trigger -- enable_event:net:netif_receive_skb:unlimited if comm==wget -- disable_hist:net:netif_receive_skb:unlimited if comm==wget -- -- In other words, whenever either of the sched_process_exec or -- sched_process_exit events is hit and matches 'wget', it enables or -- disables both the histogram and the event log, and what you end up -- with is a hash table and set of events just covering the specified -- duration. Run the wget command again: -- -- $ wget https://www.kernel.org/pub/linux/kernel/v3.x/patch-3.19.xz -- -- Displaying the 'hist' file should show something similar to what you -- saw in the last run, but this time you should also see the -- individual events in the trace file: -- -- # cat /sys/kernel/debug/tracing/trace -- -- # tracer: nop -- # -- # entries-in-buffer/entries-written: 183/1426 #P:4 -- # -- # _-----=> irqs-off -- # / _----=> need-resched -- # | / _---=> hardirq/softirq -- # || / _--=> preempt-depth -- # ||| / delay -- # TASK-PID CPU# |||| TIMESTAMP FUNCTION -- # | | | |||| | | -- wget-15108 [000] ..s1 31769.606929: netif_receive_skb: dev=lo skbaddr=ffff88009c353100 len=60 -- wget-15108 [000] ..s1 31769.606999: netif_receive_skb: dev=lo skbaddr=ffff88009c353200 len=60 -- dnsmasq-1382 [000] ..s1 31769.677652: netif_receive_skb: dev=lo skbaddr=ffff88009c352b00 len=130 -- dnsmasq-1382 [000] ..s1 31769.685917: netif_receive_skb: dev=lo skbaddr=ffff88009c352200 len=138 -- ##### CPU 2 buffer started #### -- irq/29-iwlwifi-559 [002] ..s. 31772.031529: netif_receive_skb: dev=wlan0 skbaddr=ffff88009d433d00 len=2948 -- irq/29-iwlwifi-559 [002] ..s. 31772.031572: netif_receive_skb: dev=wlan0 skbaddr=ffff88009d432200 len=1500 -- irq/29-iwlwifi-559 [002] ..s. 31772.032196: netif_receive_skb: dev=wlan0 skbaddr=ffff88009d433100 len=2948 -- irq/29-iwlwifi-559 [002] ..s. 31772.032761: netif_receive_skb: dev=wlan0 skbaddr=ffff88009d433000 len=2948 -- irq/29-iwlwifi-559 [002] ..s. 31772.033220: netif_receive_skb: dev=wlan0 skbaddr=ffff88009d432e00 len=1500 -- . -- . -- . -- -- The following example demonstrates how multiple hist triggers can be -- attached to a given event. This capability can be useful for -- creating a set of different summaries derived from the same set of -- events, or for comparing the effects of different filters, among -- other things. -- -- # echo 'hist:keys=skbaddr.hex:vals=len if len < 0' >> \ -- /sys/kernel/debug/tracing/events/net/netif_receive_skb/trigger -- # echo 'hist:keys=skbaddr.hex:vals=len if len > 4096' >> \ -- /sys/kernel/debug/tracing/events/net/netif_receive_skb/trigger -- # echo 'hist:keys=skbaddr.hex:vals=len if len == 256' >> \ -- /sys/kernel/debug/tracing/events/net/netif_receive_skb/trigger -- # echo 'hist:keys=skbaddr.hex:vals=len' >> \ -- /sys/kernel/debug/tracing/events/net/netif_receive_skb/trigger -- # echo 'hist:keys=len:vals=common_preempt_count' >> \ -- /sys/kernel/debug/tracing/events/net/netif_receive_skb/trigger -- -- The above set of commands create four triggers differing only in -- their filters, along with a completely different though fairly -- nonsensical trigger. Note that in order to append multiple hist -- triggers to the same file, you should use the '>>' operator to -- append them ('>' will also add the new hist trigger, but will remove -- any existing hist triggers beforehand). -- -- Displaying the contents of the 'hist' file for the event shows the -- contents of all five histograms: -- -- # cat /sys/kernel/debug/tracing/events/net/netif_receive_skb/hist -- -- # event histogram -- # -- # trigger info: hist:keys=len:vals=hitcount,common_preempt_count:sort=hitcount:size=2048 [active] -- # -- -- { len: 176 } hitcount: 1 common_preempt_count: 0 -- { len: 223 } hitcount: 1 common_preempt_count: 0 -- { len: 4854 } hitcount: 1 common_preempt_count: 0 -- { len: 395 } hitcount: 1 common_preempt_count: 0 -- { len: 177 } hitcount: 1 common_preempt_count: 0 -- { len: 446 } hitcount: 1 common_preempt_count: 0 -- { len: 1601 } hitcount: 1 common_preempt_count: 0 -- . -- . -- . -- { len: 1280 } hitcount: 66 common_preempt_count: 0 -- { len: 116 } hitcount: 81 common_preempt_count: 40 -- { len: 708 } hitcount: 112 common_preempt_count: 0 -- { len: 46 } hitcount: 221 common_preempt_count: 0 -- { len: 1264 } hitcount: 458 common_preempt_count: 0 -- -- Totals: -- Hits: 1428 -- Entries: 147 -- Dropped: 0 -- -- -- # event histogram -- # -- # trigger info: hist:keys=skbaddr.hex:vals=hitcount,len:sort=hitcount:size=2048 [active] -- # -- -- { skbaddr: ffff8800baee5e00 } hitcount: 1 len: 130 -- { skbaddr: ffff88005f3d5600 } hitcount: 1 len: 1280 -- { skbaddr: ffff88005f3d4900 } hitcount: 1 len: 1280 -- { skbaddr: ffff88009fed6300 } hitcount: 1 len: 115 -- { skbaddr: ffff88009fe0ad00 } hitcount: 1 len: 115 -- { skbaddr: ffff88008cdb1900 } hitcount: 1 len: 46 -- { skbaddr: ffff880064b5ef00 } hitcount: 1 len: 118 -- { skbaddr: ffff880044e3c700 } hitcount: 1 len: 60 -- { skbaddr: ffff880100065900 } hitcount: 1 len: 46 -- { skbaddr: ffff8800d46bd500 } hitcount: 1 len: 116 -- { skbaddr: ffff88005f3d5f00 } hitcount: 1 len: 1280 -- { skbaddr: ffff880100064700 } hitcount: 1 len: 365 -- { skbaddr: ffff8800badb6f00 } hitcount: 1 len: 60 -- . -- . -- . -- { skbaddr: ffff88009fe0be00 } hitcount: 27 len: 24677 -- { skbaddr: ffff88009fe0a400 } hitcount: 27 len: 23052 -- { skbaddr: ffff88009fe0b700 } hitcount: 31 len: 25589 -- { skbaddr: ffff88009fe0b600 } hitcount: 32 len: 27326 -- { skbaddr: ffff88006a462800 } hitcount: 68 len: 71678 -- { skbaddr: ffff88006a463700 } hitcount: 70 len: 72678 -- { skbaddr: ffff88006a462b00 } hitcount: 71 len: 77589 -- { skbaddr: ffff88006a463600 } hitcount: 73 len: 71307 -- { skbaddr: ffff88006a462200 } hitcount: 81 len: 81032 -- -- Totals: -- Hits: 1451 -- Entries: 318 -- Dropped: 0 -- -- -- # event histogram -- # -- # trigger info: hist:keys=skbaddr.hex:vals=hitcount,len:sort=hitcount:size=2048 if len == 256 [active] -- # -- -- -- Totals: -- Hits: 0 -- Entries: 0 -- Dropped: 0 -- -- -- # event histogram -- # -- # trigger info: hist:keys=skbaddr.hex:vals=hitcount,len:sort=hitcount:size=2048 if len > 4096 [active] -- # -- -- { skbaddr: ffff88009fd2c300 } hitcount: 1 len: 7212 -- { skbaddr: ffff8800d2bcce00 } hitcount: 1 len: 7212 -- { skbaddr: ffff8800d2bcd700 } hitcount: 1 len: 7212 -- { skbaddr: ffff8800d2bcda00 } hitcount: 1 len: 21492 -- { skbaddr: ffff8800ae2e2d00 } hitcount: 1 len: 7212 -- { skbaddr: ffff8800d2bcdb00 } hitcount: 1 len: 7212 -- { skbaddr: ffff88006a4df500 } hitcount: 1 len: 4854 -- { skbaddr: ffff88008ce47b00 } hitcount: 1 len: 18636 -- { skbaddr: ffff8800ae2e2200 } hitcount: 1 len: 12924 -- { skbaddr: ffff88005f3e1000 } hitcount: 1 len: 4356 -- { skbaddr: ffff8800d2bcdc00 } hitcount: 2 len: 24420 -- { skbaddr: ffff8800d2bcc200 } hitcount: 2 len: 12996 -- -- Totals: -- Hits: 14 -- Entries: 12 -- Dropped: 0 -- -- -- # event histogram -- # -- # trigger info: hist:keys=skbaddr.hex:vals=hitcount,len:sort=hitcount:size=2048 if len < 0 [active] -- # -- -- -- Totals: -- Hits: 0 -- Entries: 0 -- Dropped: 0 -- -- Named triggers can be used to have triggers share a common set of -- histogram data. This capability is mostly useful for combining the -- output of events generated by tracepoints contained inside inline -- functions, but names can be used in a hist trigger on any event. -- For example, these two triggers when hit will update the same 'len' -- field in the shared 'foo' histogram data: -- -- # echo 'hist:name=foo:keys=skbaddr.hex:vals=len' > \ -- /sys/kernel/debug/tracing/events/net/netif_receive_skb/trigger -- # echo 'hist:name=foo:keys=skbaddr.hex:vals=len' > \ -- /sys/kernel/debug/tracing/events/net/netif_rx/trigger -- -- You can see that they're updating common histogram data by reading -- each event's hist files at the same time: -- -- # cat /sys/kernel/debug/tracing/events/net/netif_receive_skb/hist; -- cat /sys/kernel/debug/tracing/events/net/netif_rx/hist -- -- # event histogram -- # -- # trigger info: hist:name=foo:keys=skbaddr.hex:vals=hitcount,len:sort=hitcount:size=2048 [active] -- # -- -- { skbaddr: ffff88000ad53500 } hitcount: 1 len: 46 -- { skbaddr: ffff8800af5a1500 } hitcount: 1 len: 76 -- { skbaddr: ffff8800d62a1900 } hitcount: 1 len: 46 -- { skbaddr: ffff8800d2bccb00 } hitcount: 1 len: 468 -- { skbaddr: ffff8800d3c69900 } hitcount: 1 len: 46 -- { skbaddr: ffff88009ff09100 } hitcount: 1 len: 52 -- { skbaddr: ffff88010f13ab00 } hitcount: 1 len: 168 -- { skbaddr: ffff88006a54f400 } hitcount: 1 len: 46 -- { skbaddr: ffff8800d2bcc500 } hitcount: 1 len: 260 -- { skbaddr: ffff880064505000 } hitcount: 1 len: 46 -- { skbaddr: ffff8800baf24e00 } hitcount: 1 len: 32 -- { skbaddr: ffff88009fe0ad00 } hitcount: 1 len: 46 -- { skbaddr: ffff8800d3edff00 } hitcount: 1 len: 44 -- { skbaddr: ffff88009fe0b400 } hitcount: 1 len: 168 -- { skbaddr: ffff8800a1c55a00 } hitcount: 1 len: 40 -- { skbaddr: ffff8800d2bcd100 } hitcount: 1 len: 40 -- { skbaddr: ffff880064505f00 } hitcount: 1 len: 174 -- { skbaddr: ffff8800a8bff200 } hitcount: 1 len: 160 -- { skbaddr: ffff880044e3cc00 } hitcount: 1 len: 76 -- { skbaddr: ffff8800a8bfe700 } hitcount: 1 len: 46 -- { skbaddr: ffff8800d2bcdc00 } hitcount: 1 len: 32 -- { skbaddr: ffff8800a1f64800 } hitcount: 1 len: 46 -- { skbaddr: ffff8800d2bcde00 } hitcount: 1 len: 988 -- { skbaddr: ffff88006a5dea00 } hitcount: 1 len: 46 -- { skbaddr: ffff88002e37a200 } hitcount: 1 len: 44 -- { skbaddr: ffff8800a1f32c00 } hitcount: 2 len: 676 -- { skbaddr: ffff88000ad52600 } hitcount: 2 len: 107 -- { skbaddr: ffff8800a1f91e00 } hitcount: 2 len: 92 -- { skbaddr: ffff8800af5a0200 } hitcount: 2 len: 142 -- { skbaddr: ffff8800d2bcc600 } hitcount: 2 len: 220 -- { skbaddr: ffff8800ba36f500 } hitcount: 2 len: 92 -- { skbaddr: ffff8800d021f800 } hitcount: 2 len: 92 -- { skbaddr: ffff8800a1f33600 } hitcount: 2 len: 675 -- { skbaddr: ffff8800a8bfff00 } hitcount: 3 len: 138 -- { skbaddr: ffff8800d62a1300 } hitcount: 3 len: 138 -- { skbaddr: ffff88002e37a100 } hitcount: 4 len: 184 -- { skbaddr: ffff880064504400 } hitcount: 4 len: 184 -- { skbaddr: ffff8800a8bfec00 } hitcount: 4 len: 184 -- { skbaddr: ffff88000ad53700 } hitcount: 5 len: 230 -- { skbaddr: ffff8800d2bcdb00 } hitcount: 5 len: 196 -- { skbaddr: ffff8800a1f90000 } hitcount: 6 len: 276 -- { skbaddr: ffff88006a54f900 } hitcount: 6 len: 276 -- -- Totals: -- Hits: 81 -- Entries: 42 -- Dropped: 0 -- # event histogram -- # -- # trigger info: hist:name=foo:keys=skbaddr.hex:vals=hitcount,len:sort=hitcount:size=2048 [active] -- # -- -- { skbaddr: ffff88000ad53500 } hitcount: 1 len: 46 -- { skbaddr: ffff8800af5a1500 } hitcount: 1 len: 76 -- { skbaddr: ffff8800d62a1900 } hitcount: 1 len: 46 -- { skbaddr: ffff8800d2bccb00 } hitcount: 1 len: 468 -- { skbaddr: ffff8800d3c69900 } hitcount: 1 len: 46 -- { skbaddr: ffff88009ff09100 } hitcount: 1 len: 52 -- { skbaddr: ffff88010f13ab00 } hitcount: 1 len: 168 -- { skbaddr: ffff88006a54f400 } hitcount: 1 len: 46 -- { skbaddr: ffff8800d2bcc500 } hitcount: 1 len: 260 -- { skbaddr: ffff880064505000 } hitcount: 1 len: 46 -- { skbaddr: ffff8800baf24e00 } hitcount: 1 len: 32 -- { skbaddr: ffff88009fe0ad00 } hitcount: 1 len: 46 -- { skbaddr: ffff8800d3edff00 } hitcount: 1 len: 44 -- { skbaddr: ffff88009fe0b400 } hitcount: 1 len: 168 -- { skbaddr: ffff8800a1c55a00 } hitcount: 1 len: 40 -- { skbaddr: ffff8800d2bcd100 } hitcount: 1 len: 40 -- { skbaddr: ffff880064505f00 } hitcount: 1 len: 174 -- { skbaddr: ffff8800a8bff200 } hitcount: 1 len: 160 -- { skbaddr: ffff880044e3cc00 } hitcount: 1 len: 76 -- { skbaddr: ffff8800a8bfe700 } hitcount: 1 len: 46 -- { skbaddr: ffff8800d2bcdc00 } hitcount: 1 len: 32 -- { skbaddr: ffff8800a1f64800 } hitcount: 1 len: 46 -- { skbaddr: ffff8800d2bcde00 } hitcount: 1 len: 988 -- { skbaddr: ffff88006a5dea00 } hitcount: 1 len: 46 -- { skbaddr: ffff88002e37a200 } hitcount: 1 len: 44 -- { skbaddr: ffff8800a1f32c00 } hitcount: 2 len: 676 -- { skbaddr: ffff88000ad52600 } hitcount: 2 len: 107 -- { skbaddr: ffff8800a1f91e00 } hitcount: 2 len: 92 -- { skbaddr: ffff8800af5a0200 } hitcount: 2 len: 142 -- { skbaddr: ffff8800d2bcc600 } hitcount: 2 len: 220 -- { skbaddr: ffff8800ba36f500 } hitcount: 2 len: 92 -- { skbaddr: ffff8800d021f800 } hitcount: 2 len: 92 -- { skbaddr: ffff8800a1f33600 } hitcount: 2 len: 675 -- { skbaddr: ffff8800a8bfff00 } hitcount: 3 len: 138 -- { skbaddr: ffff8800d62a1300 } hitcount: 3 len: 138 -- { skbaddr: ffff88002e37a100 } hitcount: 4 len: 184 -- { skbaddr: ffff880064504400 } hitcount: 4 len: 184 -- { skbaddr: ffff8800a8bfec00 } hitcount: 4 len: 184 -- { skbaddr: ffff88000ad53700 } hitcount: 5 len: 230 -- { skbaddr: ffff8800d2bcdb00 } hitcount: 5 len: 196 -- { skbaddr: ffff8800a1f90000 } hitcount: 6 len: 276 -- { skbaddr: ffff88006a54f900 } hitcount: 6 len: 276 -- -- Totals: -- Hits: 81 -- Entries: 42 -- Dropped: 0 -- -- And here's an example that shows how to combine histogram data from -- any two events even if they don't share any 'compatible' fields -- other than 'hitcount' and 'stacktrace'. These commands create a -- couple of triggers named 'bar' using those fields: -- -- # echo 'hist:name=bar:key=stacktrace:val=hitcount' > \ -- /sys/kernel/debug/tracing/events/sched/sched_process_fork/trigger -- # echo 'hist:name=bar:key=stacktrace:val=hitcount' > \ -- /sys/kernel/debug/tracing/events/net/netif_rx/trigger -- -- And displaying the output of either shows some interesting if -- somewhat confusing output: -- -- # cat /sys/kernel/debug/tracing/events/sched/sched_process_fork/hist -- # cat /sys/kernel/debug/tracing/events/net/netif_rx/hist -- -- # event histogram -- # -- # trigger info: hist:name=bar:keys=stacktrace:vals=hitcount:sort=hitcount:size=2048 [active] -- # -- -- { stacktrace: -- _do_fork+0x18e/0x330 -- kernel_thread+0x29/0x30 -- kthreadd+0x154/0x1b0 -- ret_from_fork+0x3f/0x70 -- } hitcount: 1 -- { stacktrace: -- netif_rx_internal+0xb2/0xd0 -- netif_rx_ni+0x20/0x70 -- dev_loopback_xmit+0xaa/0xd0 -- ip_mc_output+0x126/0x240 -- ip_local_out_sk+0x31/0x40 -- igmp_send_report+0x1e9/0x230 -- igmp_timer_expire+0xe9/0x120 -- call_timer_fn+0x39/0xf0 -- run_timer_softirq+0x1e1/0x290 -- __do_softirq+0xfd/0x290 -- irq_exit+0x98/0xb0 -- smp_apic_timer_interrupt+0x4a/0x60 -- apic_timer_interrupt+0x6d/0x80 -- cpuidle_enter+0x17/0x20 -- call_cpuidle+0x3b/0x60 -- cpu_startup_entry+0x22d/0x310 -- } hitcount: 1 -- { stacktrace: -- netif_rx_internal+0xb2/0xd0 -- netif_rx_ni+0x20/0x70 -- dev_loopback_xmit+0xaa/0xd0 -- ip_mc_output+0x17f/0x240 -- ip_local_out_sk+0x31/0x40 -- ip_send_skb+0x1a/0x50 -- udp_send_skb+0x13e/0x270 -- udp_sendmsg+0x2bf/0x980 -- inet_sendmsg+0x67/0xa0 -- sock_sendmsg+0x38/0x50 -- SYSC_sendto+0xef/0x170 -- SyS_sendto+0xe/0x10 -- entry_SYSCALL_64_fastpath+0x12/0x6a -- } hitcount: 2 -- { stacktrace: -- netif_rx_internal+0xb2/0xd0 -- netif_rx+0x1c/0x60 -- loopback_xmit+0x6c/0xb0 -- dev_hard_start_xmit+0x219/0x3a0 -- __dev_queue_xmit+0x415/0x4f0 -- dev_queue_xmit_sk+0x13/0x20 -- ip_finish_output2+0x237/0x340 -- ip_finish_output+0x113/0x1d0 -- ip_output+0x66/0xc0 -- ip_local_out_sk+0x31/0x40 -- ip_send_skb+0x1a/0x50 -- udp_send_skb+0x16d/0x270 -- udp_sendmsg+0x2bf/0x980 -- inet_sendmsg+0x67/0xa0 -- sock_sendmsg+0x38/0x50 -- ___sys_sendmsg+0x14e/0x270 -- } hitcount: 76 -- { stacktrace: -- netif_rx_internal+0xb2/0xd0 -- netif_rx+0x1c/0x60 -- loopback_xmit+0x6c/0xb0 -- dev_hard_start_xmit+0x219/0x3a0 -- __dev_queue_xmit+0x415/0x4f0 -- dev_queue_xmit_sk+0x13/0x20 -- ip_finish_output2+0x237/0x340 -- ip_finish_output+0x113/0x1d0 -- ip_output+0x66/0xc0 -- ip_local_out_sk+0x31/0x40 -- ip_send_skb+0x1a/0x50 -- udp_send_skb+0x16d/0x270 -- udp_sendmsg+0x2bf/0x980 -- inet_sendmsg+0x67/0xa0 -- sock_sendmsg+0x38/0x50 -- ___sys_sendmsg+0x269/0x270 -- } hitcount: 77 -- { stacktrace: -- netif_rx_internal+0xb2/0xd0 -- netif_rx+0x1c/0x60 -- loopback_xmit+0x6c/0xb0 -- dev_hard_start_xmit+0x219/0x3a0 -- __dev_queue_xmit+0x415/0x4f0 -- dev_queue_xmit_sk+0x13/0x20 -- ip_finish_output2+0x237/0x340 -- ip_finish_output+0x113/0x1d0 -- ip_output+0x66/0xc0 -- ip_local_out_sk+0x31/0x40 -- ip_send_skb+0x1a/0x50 -- udp_send_skb+0x16d/0x270 -- udp_sendmsg+0x2bf/0x980 -- inet_sendmsg+0x67/0xa0 -- sock_sendmsg+0x38/0x50 -- SYSC_sendto+0xef/0x170 -- } hitcount: 88 -- { stacktrace: -- _do_fork+0x18e/0x330 -- SyS_clone+0x19/0x20 -- entry_SYSCALL_64_fastpath+0x12/0x6a -- } hitcount: 244 -- -- Totals: -- Hits: 489 -- Entries: 7 -- Dropped: 0 -+ See Documentation/trace/histogram.txt for details and examples. -diff --git a/Documentation/trace/histogram.txt b/Documentation/trace/histogram.txt -new file mode 100644 -index 000000000000..b2145f44b190 ---- /dev/null -+++ b/Documentation/trace/histogram.txt -@@ -0,0 +1,1568 @@ -+ Event Histograms -+ -+ Documentation written by Tom Zanussi -+ -+1. Introduction -+=============== -+ -+ Histogram triggers are special event triggers that can be used to -+ aggregate trace event data into histograms. For information on -+ trace events and event triggers, see Documentation/trace/events.txt. -+ -+ -+2. Histogram Trigger Command -+============================ -+ -+ A histogram trigger command is an event trigger command that -+ aggregates event hits into a hash table keyed on one or more trace -+ event format fields (or stacktrace) and a set of running totals -+ derived from one or more trace event format fields and/or event -+ counts (hitcount). -+ -+ The format of a hist trigger is as follows: -+ -+ hist:keys=[:values=] -+ [:sort=][:size=#entries][:pause][:continue] -+ [:clear][:name=histname1] [if ] -+ -+ When a matching event is hit, an entry is added to a hash table -+ using the key(s) and value(s) named. Keys and values correspond to -+ fields in the event's format description. Values must correspond to -+ numeric fields - on an event hit, the value(s) will be added to a -+ sum kept for that field. The special string 'hitcount' can be used -+ in place of an explicit value field - this is simply a count of -+ event hits. If 'values' isn't specified, an implicit 'hitcount' -+ value will be automatically created and used as the only value. -+ Keys can be any field, or the special string 'stacktrace', which -+ will use the event's kernel stacktrace as the key. The keywords -+ 'keys' or 'key' can be used to specify keys, and the keywords -+ 'values', 'vals', or 'val' can be used to specify values. Compound -+ keys consisting of up to two fields can be specified by the 'keys' -+ keyword. Hashing a compound key produces a unique entry in the -+ table for each unique combination of component keys, and can be -+ useful for providing more fine-grained summaries of event data. -+ Additionally, sort keys consisting of up to two fields can be -+ specified by the 'sort' keyword. If more than one field is -+ specified, the result will be a 'sort within a sort': the first key -+ is taken to be the primary sort key and the second the secondary -+ key. If a hist trigger is given a name using the 'name' parameter, -+ its histogram data will be shared with other triggers of the same -+ name, and trigger hits will update this common data. Only triggers -+ with 'compatible' fields can be combined in this way; triggers are -+ 'compatible' if the fields named in the trigger share the same -+ number and type of fields and those fields also have the same names. -+ Note that any two events always share the compatible 'hitcount' and -+ 'stacktrace' fields and can therefore be combined using those -+ fields, however pointless that may be. -+ -+ 'hist' triggers add a 'hist' file to each event's subdirectory. -+ Reading the 'hist' file for the event will dump the hash table in -+ its entirety to stdout. If there are multiple hist triggers -+ attached to an event, there will be a table for each trigger in the -+ output. The table displayed for a named trigger will be the same as -+ any other instance having the same name. Each printed hash table -+ entry is a simple list of the keys and values comprising the entry; -+ keys are printed first and are delineated by curly braces, and are -+ followed by the set of value fields for the entry. By default, -+ numeric fields are displayed as base-10 integers. This can be -+ modified by appending any of the following modifiers to the field -+ name: -+ -+ .hex display a number as a hex value -+ .sym display an address as a symbol -+ .sym-offset display an address as a symbol and offset -+ .syscall display a syscall id as a system call name -+ .execname display a common_pid as a program name -+ -+ Note that in general the semantics of a given field aren't -+ interpreted when applying a modifier to it, but there are some -+ restrictions to be aware of in this regard: -+ -+ - only the 'hex' modifier can be used for values (because values -+ are essentially sums, and the other modifiers don't make sense -+ in that context). -+ - the 'execname' modifier can only be used on a 'common_pid'. The -+ reason for this is that the execname is simply the 'comm' value -+ saved for the 'current' process when an event was triggered, -+ which is the same as the common_pid value saved by the event -+ tracing code. Trying to apply that comm value to other pid -+ values wouldn't be correct, and typically events that care save -+ pid-specific comm fields in the event itself. -+ -+ A typical usage scenario would be the following to enable a hist -+ trigger, read its current contents, and then turn it off: -+ -+ # echo 'hist:keys=skbaddr.hex:vals=len' > \ -+ /sys/kernel/debug/tracing/events/net/netif_rx/trigger -+ -+ # cat /sys/kernel/debug/tracing/events/net/netif_rx/hist -+ -+ # echo '!hist:keys=skbaddr.hex:vals=len' > \ -+ /sys/kernel/debug/tracing/events/net/netif_rx/trigger -+ -+ The trigger file itself can be read to show the details of the -+ currently attached hist trigger. This information is also displayed -+ at the top of the 'hist' file when read. -+ -+ By default, the size of the hash table is 2048 entries. The 'size' -+ parameter can be used to specify more or fewer than that. The units -+ are in terms of hashtable entries - if a run uses more entries than -+ specified, the results will show the number of 'drops', the number -+ of hits that were ignored. The size should be a power of 2 between -+ 128 and 131072 (any non- power-of-2 number specified will be rounded -+ up). -+ -+ The 'sort' parameter can be used to specify a value field to sort -+ on. The default if unspecified is 'hitcount' and the default sort -+ order is 'ascending'. To sort in the opposite direction, append -+ .descending' to the sort key. -+ -+ The 'pause' parameter can be used to pause an existing hist trigger -+ or to start a hist trigger but not log any events until told to do -+ so. 'continue' or 'cont' can be used to start or restart a paused -+ hist trigger. -+ -+ The 'clear' parameter will clear the contents of a running hist -+ trigger and leave its current paused/active state. -+ -+ Note that the 'pause', 'cont', and 'clear' parameters should be -+ applied using 'append' shell operator ('>>') if applied to an -+ existing trigger, rather than via the '>' operator, which will cause -+ the trigger to be removed through truncation. -+ -+- enable_hist/disable_hist -+ -+ The enable_hist and disable_hist triggers can be used to have one -+ event conditionally start and stop another event's already-attached -+ hist trigger. Any number of enable_hist and disable_hist triggers -+ can be attached to a given event, allowing that event to kick off -+ and stop aggregations on a host of other events. -+ -+ The format is very similar to the enable/disable_event triggers: -+ -+ enable_hist::[:count] -+ disable_hist::[:count] -+ -+ Instead of enabling or disabling the tracing of the target event -+ into the trace buffer as the enable/disable_event triggers do, the -+ enable/disable_hist triggers enable or disable the aggregation of -+ the target event into a hash table. -+ -+ A typical usage scenario for the enable_hist/disable_hist triggers -+ would be to first set up a paused hist trigger on some event, -+ followed by an enable_hist/disable_hist pair that turns the hist -+ aggregation on and off when conditions of interest are hit: -+ -+ # echo 'hist:keys=skbaddr.hex:vals=len:pause' > \ -+ /sys/kernel/debug/tracing/events/net/netif_receive_skb/trigger -+ -+ # echo 'enable_hist:net:netif_receive_skb if filename==/usr/bin/wget' > \ -+ /sys/kernel/debug/tracing/events/sched/sched_process_exec/trigger -+ -+ # echo 'disable_hist:net:netif_receive_skb if comm==wget' > \ -+ /sys/kernel/debug/tracing/events/sched/sched_process_exit/trigger -+ -+ The above sets up an initially paused hist trigger which is unpaused -+ and starts aggregating events when a given program is executed, and -+ which stops aggregating when the process exits and the hist trigger -+ is paused again. -+ -+ The examples below provide a more concrete illustration of the -+ concepts and typical usage patterns discussed above. -+ -+ -+6.2 'hist' trigger examples -+--------------------------- -+ -+ The first set of examples creates aggregations using the kmalloc -+ event. The fields that can be used for the hist trigger are listed -+ in the kmalloc event's format file: -+ -+ # cat /sys/kernel/debug/tracing/events/kmem/kmalloc/format -+ name: kmalloc -+ ID: 374 -+ format: -+ field:unsigned short common_type; offset:0; size:2; signed:0; -+ field:unsigned char common_flags; offset:2; size:1; signed:0; -+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0; -+ field:int common_pid; offset:4; size:4; signed:1; -+ -+ field:unsigned long call_site; offset:8; size:8; signed:0; -+ field:const void * ptr; offset:16; size:8; signed:0; -+ field:size_t bytes_req; offset:24; size:8; signed:0; -+ field:size_t bytes_alloc; offset:32; size:8; signed:0; -+ field:gfp_t gfp_flags; offset:40; size:4; signed:0; -+ -+ We'll start by creating a hist trigger that generates a simple table -+ that lists the total number of bytes requested for each function in -+ the kernel that made one or more calls to kmalloc: -+ -+ # echo 'hist:key=call_site:val=bytes_req' > \ -+ /sys/kernel/debug/tracing/events/kmem/kmalloc/trigger -+ -+ This tells the tracing system to create a 'hist' trigger using the -+ call_site field of the kmalloc event as the key for the table, which -+ just means that each unique call_site address will have an entry -+ created for it in the table. The 'val=bytes_req' parameter tells -+ the hist trigger that for each unique entry (call_site) in the -+ table, it should keep a running total of the number of bytes -+ requested by that call_site. -+ -+ We'll let it run for awhile and then dump the contents of the 'hist' -+ file in the kmalloc event's subdirectory (for readability, a number -+ of entries have been omitted): -+ -+ # cat /sys/kernel/debug/tracing/events/kmem/kmalloc/hist -+ # trigger info: hist:keys=call_site:vals=bytes_req:sort=hitcount:size=2048 [active] -+ -+ { call_site: 18446744072106379007 } hitcount: 1 bytes_req: 176 -+ { call_site: 18446744071579557049 } hitcount: 1 bytes_req: 1024 -+ { call_site: 18446744071580608289 } hitcount: 1 bytes_req: 16384 -+ { call_site: 18446744071581827654 } hitcount: 1 bytes_req: 24 -+ { call_site: 18446744071580700980 } hitcount: 1 bytes_req: 8 -+ { call_site: 18446744071579359876 } hitcount: 1 bytes_req: 152 -+ { call_site: 18446744071580795365 } hitcount: 3 bytes_req: 144 -+ { call_site: 18446744071581303129 } hitcount: 3 bytes_req: 144 -+ { call_site: 18446744071580713234 } hitcount: 4 bytes_req: 2560 -+ { call_site: 18446744071580933750 } hitcount: 4 bytes_req: 736 -+ . -+ . -+ . -+ { call_site: 18446744072106047046 } hitcount: 69 bytes_req: 5576 -+ { call_site: 18446744071582116407 } hitcount: 73 bytes_req: 2336 -+ { call_site: 18446744072106054684 } hitcount: 136 bytes_req: 140504 -+ { call_site: 18446744072106224230 } hitcount: 136 bytes_req: 19584 -+ { call_site: 18446744072106078074 } hitcount: 153 bytes_req: 2448 -+ { call_site: 18446744072106062406 } hitcount: 153 bytes_req: 36720 -+ { call_site: 18446744071582507929 } hitcount: 153 bytes_req: 37088 -+ { call_site: 18446744072102520590 } hitcount: 273 bytes_req: 10920 -+ { call_site: 18446744071582143559 } hitcount: 358 bytes_req: 716 -+ { call_site: 18446744072106465852 } hitcount: 417 bytes_req: 56712 -+ { call_site: 18446744072102523378 } hitcount: 485 bytes_req: 27160 -+ { call_site: 18446744072099568646 } hitcount: 1676 bytes_req: 33520 -+ -+ Totals: -+ Hits: 4610 -+ Entries: 45 -+ Dropped: 0 -+ -+ The output displays a line for each entry, beginning with the key -+ specified in the trigger, followed by the value(s) also specified in -+ the trigger. At the beginning of the output is a line that displays -+ the trigger info, which can also be displayed by reading the -+ 'trigger' file: -+ -+ # cat /sys/kernel/debug/tracing/events/kmem/kmalloc/trigger -+ hist:keys=call_site:vals=bytes_req:sort=hitcount:size=2048 [active] -+ -+ At the end of the output are a few lines that display the overall -+ totals for the run. The 'Hits' field shows the total number of -+ times the event trigger was hit, the 'Entries' field shows the total -+ number of used entries in the hash table, and the 'Dropped' field -+ shows the number of hits that were dropped because the number of -+ used entries for the run exceeded the maximum number of entries -+ allowed for the table (normally 0, but if not a hint that you may -+ want to increase the size of the table using the 'size' parameter). -+ -+ Notice in the above output that there's an extra field, 'hitcount', -+ which wasn't specified in the trigger. Also notice that in the -+ trigger info output, there's a parameter, 'sort=hitcount', which -+ wasn't specified in the trigger either. The reason for that is that -+ every trigger implicitly keeps a count of the total number of hits -+ attributed to a given entry, called the 'hitcount'. That hitcount -+ information is explicitly displayed in the output, and in the -+ absence of a user-specified sort parameter, is used as the default -+ sort field. -+ -+ The value 'hitcount' can be used in place of an explicit value in -+ the 'values' parameter if you don't really need to have any -+ particular field summed and are mainly interested in hit -+ frequencies. -+ -+ To turn the hist trigger off, simply call up the trigger in the -+ command history and re-execute it with a '!' prepended: -+ -+ # echo '!hist:key=call_site:val=bytes_req' > \ -+ /sys/kernel/debug/tracing/events/kmem/kmalloc/trigger -+ -+ Finally, notice that the call_site as displayed in the output above -+ isn't really very useful. It's an address, but normally addresses -+ are displayed in hex. To have a numeric field displayed as a hex -+ value, simply append '.hex' to the field name in the trigger: -+ -+ # echo 'hist:key=call_site.hex:val=bytes_req' > \ -+ /sys/kernel/debug/tracing/events/kmem/kmalloc/trigger -+ -+ # cat /sys/kernel/debug/tracing/events/kmem/kmalloc/hist -+ # trigger info: hist:keys=call_site.hex:vals=bytes_req:sort=hitcount:size=2048 [active] -+ -+ { call_site: ffffffffa026b291 } hitcount: 1 bytes_req: 433 -+ { call_site: ffffffffa07186ff } hitcount: 1 bytes_req: 176 -+ { call_site: ffffffff811ae721 } hitcount: 1 bytes_req: 16384 -+ { call_site: ffffffff811c5134 } hitcount: 1 bytes_req: 8 -+ { call_site: ffffffffa04a9ebb } hitcount: 1 bytes_req: 511 -+ { call_site: ffffffff8122e0a6 } hitcount: 1 bytes_req: 12 -+ { call_site: ffffffff8107da84 } hitcount: 1 bytes_req: 152 -+ { call_site: ffffffff812d8246 } hitcount: 1 bytes_req: 24 -+ { call_site: ffffffff811dc1e5 } hitcount: 3 bytes_req: 144 -+ { call_site: ffffffffa02515e8 } hitcount: 3 bytes_req: 648 -+ { call_site: ffffffff81258159 } hitcount: 3 bytes_req: 144 -+ { call_site: ffffffff811c80f4 } hitcount: 4 bytes_req: 544 -+ . -+ . -+ . -+ { call_site: ffffffffa06c7646 } hitcount: 106 bytes_req: 8024 -+ { call_site: ffffffffa06cb246 } hitcount: 132 bytes_req: 31680 -+ { call_site: ffffffffa06cef7a } hitcount: 132 bytes_req: 2112 -+ { call_site: ffffffff8137e399 } hitcount: 132 bytes_req: 23232 -+ { call_site: ffffffffa06c941c } hitcount: 185 bytes_req: 171360 -+ { call_site: ffffffffa06f2a66 } hitcount: 185 bytes_req: 26640 -+ { call_site: ffffffffa036a70e } hitcount: 265 bytes_req: 10600 -+ { call_site: ffffffff81325447 } hitcount: 292 bytes_req: 584 -+ { call_site: ffffffffa072da3c } hitcount: 446 bytes_req: 60656 -+ { call_site: ffffffffa036b1f2 } hitcount: 526 bytes_req: 29456 -+ { call_site: ffffffffa0099c06 } hitcount: 1780 bytes_req: 35600 -+ -+ Totals: -+ Hits: 4775 -+ Entries: 46 -+ Dropped: 0 -+ -+ Even that's only marginally more useful - while hex values do look -+ more like addresses, what users are typically more interested in -+ when looking at text addresses are the corresponding symbols -+ instead. To have an address displayed as symbolic value instead, -+ simply append '.sym' or '.sym-offset' to the field name in the -+ trigger: -+ -+ # echo 'hist:key=call_site.sym:val=bytes_req' > \ -+ /sys/kernel/debug/tracing/events/kmem/kmalloc/trigger -+ -+ # cat /sys/kernel/debug/tracing/events/kmem/kmalloc/hist -+ # trigger info: hist:keys=call_site.sym:vals=bytes_req:sort=hitcount:size=2048 [active] -+ -+ { call_site: [ffffffff810adcb9] syslog_print_all } hitcount: 1 bytes_req: 1024 -+ { call_site: [ffffffff8154bc62] usb_control_msg } hitcount: 1 bytes_req: 8 -+ { call_site: [ffffffffa00bf6fe] hidraw_send_report [hid] } hitcount: 1 bytes_req: 7 -+ { call_site: [ffffffff8154acbe] usb_alloc_urb } hitcount: 1 bytes_req: 192 -+ { call_site: [ffffffffa00bf1ca] hidraw_report_event [hid] } hitcount: 1 bytes_req: 7 -+ { call_site: [ffffffff811e3a25] __seq_open_private } hitcount: 1 bytes_req: 40 -+ { call_site: [ffffffff8109524a] alloc_fair_sched_group } hitcount: 2 bytes_req: 128 -+ { call_site: [ffffffff811febd5] fsnotify_alloc_group } hitcount: 2 bytes_req: 528 -+ { call_site: [ffffffff81440f58] __tty_buffer_request_room } hitcount: 2 bytes_req: 2624 -+ { call_site: [ffffffff81200ba6] inotify_new_group } hitcount: 2 bytes_req: 96 -+ { call_site: [ffffffffa05e19af] ieee80211_start_tx_ba_session [mac80211] } hitcount: 2 bytes_req: 464 -+ { call_site: [ffffffff81672406] tcp_get_metrics } hitcount: 2 bytes_req: 304 -+ { call_site: [ffffffff81097ec2] alloc_rt_sched_group } hitcount: 2 bytes_req: 128 -+ { call_site: [ffffffff81089b05] sched_create_group } hitcount: 2 bytes_req: 1424 -+ . -+ . -+ . -+ { call_site: [ffffffffa04a580c] intel_crtc_page_flip [i915] } hitcount: 1185 bytes_req: 123240 -+ { call_site: [ffffffffa0287592] drm_mode_page_flip_ioctl [drm] } hitcount: 1185 bytes_req: 104280 -+ { call_site: [ffffffffa04c4a3c] intel_plane_duplicate_state [i915] } hitcount: 1402 bytes_req: 190672 -+ { call_site: [ffffffff812891ca] ext4_find_extent } hitcount: 1518 bytes_req: 146208 -+ { call_site: [ffffffffa029070e] drm_vma_node_allow [drm] } hitcount: 1746 bytes_req: 69840 -+ { call_site: [ffffffffa045e7c4] i915_gem_do_execbuffer.isra.23 [i915] } hitcount: 2021 bytes_req: 792312 -+ { call_site: [ffffffffa02911f2] drm_modeset_lock_crtc [drm] } hitcount: 2592 bytes_req: 145152 -+ { call_site: [ffffffffa0489a66] intel_ring_begin [i915] } hitcount: 2629 bytes_req: 378576 -+ { call_site: [ffffffffa046041c] i915_gem_execbuffer2 [i915] } hitcount: 2629 bytes_req: 3783248 -+ { call_site: [ffffffff81325607] apparmor_file_alloc_security } hitcount: 5192 bytes_req: 10384 -+ { call_site: [ffffffffa00b7c06] hid_report_raw_event [hid] } hitcount: 5529 bytes_req: 110584 -+ { call_site: [ffffffff8131ebf7] aa_alloc_task_context } hitcount: 21943 bytes_req: 702176 -+ { call_site: [ffffffff8125847d] ext4_htree_store_dirent } hitcount: 55759 bytes_req: 5074265 -+ -+ Totals: -+ Hits: 109928 -+ Entries: 71 -+ Dropped: 0 -+ -+ Because the default sort key above is 'hitcount', the above shows a -+ the list of call_sites by increasing hitcount, so that at the bottom -+ we see the functions that made the most kmalloc calls during the -+ run. If instead we we wanted to see the top kmalloc callers in -+ terms of the number of bytes requested rather than the number of -+ calls, and we wanted the top caller to appear at the top, we can use -+ the 'sort' parameter, along with the 'descending' modifier: -+ -+ # echo 'hist:key=call_site.sym:val=bytes_req:sort=bytes_req.descending' > \ -+ /sys/kernel/debug/tracing/events/kmem/kmalloc/trigger -+ -+ # cat /sys/kernel/debug/tracing/events/kmem/kmalloc/hist -+ # trigger info: hist:keys=call_site.sym:vals=bytes_req:sort=bytes_req.descending:size=2048 [active] -+ -+ { call_site: [ffffffffa046041c] i915_gem_execbuffer2 [i915] } hitcount: 2186 bytes_req: 3397464 -+ { call_site: [ffffffffa045e7c4] i915_gem_do_execbuffer.isra.23 [i915] } hitcount: 1790 bytes_req: 712176 -+ { call_site: [ffffffff8125847d] ext4_htree_store_dirent } hitcount: 8132 bytes_req: 513135 -+ { call_site: [ffffffff811e2a1b] seq_buf_alloc } hitcount: 106 bytes_req: 440128 -+ { call_site: [ffffffffa0489a66] intel_ring_begin [i915] } hitcount: 2186 bytes_req: 314784 -+ { call_site: [ffffffff812891ca] ext4_find_extent } hitcount: 2174 bytes_req: 208992 -+ { call_site: [ffffffff811ae8e1] __kmalloc } hitcount: 8 bytes_req: 131072 -+ { call_site: [ffffffffa04c4a3c] intel_plane_duplicate_state [i915] } hitcount: 859 bytes_req: 116824 -+ { call_site: [ffffffffa02911f2] drm_modeset_lock_crtc [drm] } hitcount: 1834 bytes_req: 102704 -+ { call_site: [ffffffffa04a580c] intel_crtc_page_flip [i915] } hitcount: 972 bytes_req: 101088 -+ { call_site: [ffffffffa0287592] drm_mode_page_flip_ioctl [drm] } hitcount: 972 bytes_req: 85536 -+ { call_site: [ffffffffa00b7c06] hid_report_raw_event [hid] } hitcount: 3333 bytes_req: 66664 -+ { call_site: [ffffffff8137e559] sg_kmalloc } hitcount: 209 bytes_req: 61632 -+ . -+ . -+ . -+ { call_site: [ffffffff81095225] alloc_fair_sched_group } hitcount: 2 bytes_req: 128 -+ { call_site: [ffffffff81097ec2] alloc_rt_sched_group } hitcount: 2 bytes_req: 128 -+ { call_site: [ffffffff812d8406] copy_semundo } hitcount: 2 bytes_req: 48 -+ { call_site: [ffffffff81200ba6] inotify_new_group } hitcount: 1 bytes_req: 48 -+ { call_site: [ffffffffa027121a] drm_getmagic [drm] } hitcount: 1 bytes_req: 48 -+ { call_site: [ffffffff811e3a25] __seq_open_private } hitcount: 1 bytes_req: 40 -+ { call_site: [ffffffff811c52f4] bprm_change_interp } hitcount: 2 bytes_req: 16 -+ { call_site: [ffffffff8154bc62] usb_control_msg } hitcount: 1 bytes_req: 8 -+ { call_site: [ffffffffa00bf1ca] hidraw_report_event [hid] } hitcount: 1 bytes_req: 7 -+ { call_site: [ffffffffa00bf6fe] hidraw_send_report [hid] } hitcount: 1 bytes_req: 7 -+ -+ Totals: -+ Hits: 32133 -+ Entries: 81 -+ Dropped: 0 -+ -+ To display the offset and size information in addition to the symbol -+ name, just use 'sym-offset' instead: -+ -+ # echo 'hist:key=call_site.sym-offset:val=bytes_req:sort=bytes_req.descending' > \ -+ /sys/kernel/debug/tracing/events/kmem/kmalloc/trigger -+ -+ # cat /sys/kernel/debug/tracing/events/kmem/kmalloc/hist -+ # trigger info: hist:keys=call_site.sym-offset:vals=bytes_req:sort=bytes_req.descending:size=2048 [active] -+ -+ { call_site: [ffffffffa046041c] i915_gem_execbuffer2+0x6c/0x2c0 [i915] } hitcount: 4569 bytes_req: 3163720 -+ { call_site: [ffffffffa0489a66] intel_ring_begin+0xc6/0x1f0 [i915] } hitcount: 4569 bytes_req: 657936 -+ { call_site: [ffffffffa045e7c4] i915_gem_do_execbuffer.isra.23+0x694/0x1020 [i915] } hitcount: 1519 bytes_req: 472936 -+ { call_site: [ffffffffa045e646] i915_gem_do_execbuffer.isra.23+0x516/0x1020 [i915] } hitcount: 3050 bytes_req: 211832 -+ { call_site: [ffffffff811e2a1b] seq_buf_alloc+0x1b/0x50 } hitcount: 34 bytes_req: 148384 -+ { call_site: [ffffffffa04a580c] intel_crtc_page_flip+0xbc/0x870 [i915] } hitcount: 1385 bytes_req: 144040 -+ { call_site: [ffffffff811ae8e1] __kmalloc+0x191/0x1b0 } hitcount: 8 bytes_req: 131072 -+ { call_site: [ffffffffa0287592] drm_mode_page_flip_ioctl+0x282/0x360 [drm] } hitcount: 1385 bytes_req: 121880 -+ { call_site: [ffffffffa02911f2] drm_modeset_lock_crtc+0x32/0x100 [drm] } hitcount: 1848 bytes_req: 103488 -+ { call_site: [ffffffffa04c4a3c] intel_plane_duplicate_state+0x2c/0xa0 [i915] } hitcount: 461 bytes_req: 62696 -+ { call_site: [ffffffffa029070e] drm_vma_node_allow+0x2e/0xd0 [drm] } hitcount: 1541 bytes_req: 61640 -+ { call_site: [ffffffff815f8d7b] sk_prot_alloc+0xcb/0x1b0 } hitcount: 57 bytes_req: 57456 -+ . -+ . -+ . -+ { call_site: [ffffffff8109524a] alloc_fair_sched_group+0x5a/0x1a0 } hitcount: 2 bytes_req: 128 -+ { call_site: [ffffffffa027b921] drm_vm_open_locked+0x31/0xa0 [drm] } hitcount: 3 bytes_req: 96 -+ { call_site: [ffffffff8122e266] proc_self_follow_link+0x76/0xb0 } hitcount: 8 bytes_req: 96 -+ { call_site: [ffffffff81213e80] load_elf_binary+0x240/0x1650 } hitcount: 3 bytes_req: 84 -+ { call_site: [ffffffff8154bc62] usb_control_msg+0x42/0x110 } hitcount: 1 bytes_req: 8 -+ { call_site: [ffffffffa00bf6fe] hidraw_send_report+0x7e/0x1a0 [hid] } hitcount: 1 bytes_req: 7 -+ { call_site: [ffffffffa00bf1ca] hidraw_report_event+0x8a/0x120 [hid] } hitcount: 1 bytes_req: 7 -+ -+ Totals: -+ Hits: 26098 -+ Entries: 64 -+ Dropped: 0 -+ -+ We can also add multiple fields to the 'values' parameter. For -+ example, we might want to see the total number of bytes allocated -+ alongside bytes requested, and display the result sorted by bytes -+ allocated in a descending order: -+ -+ # echo 'hist:keys=call_site.sym:values=bytes_req,bytes_alloc:sort=bytes_alloc.descending' > \ -+ /sys/kernel/debug/tracing/events/kmem/kmalloc/trigger -+ -+ # cat /sys/kernel/debug/tracing/events/kmem/kmalloc/hist -+ # trigger info: hist:keys=call_site.sym:vals=bytes_req,bytes_alloc:sort=bytes_alloc.descending:size=2048 [active] -+ -+ { call_site: [ffffffffa046041c] i915_gem_execbuffer2 [i915] } hitcount: 7403 bytes_req: 4084360 bytes_alloc: 5958016 -+ { call_site: [ffffffff811e2a1b] seq_buf_alloc } hitcount: 541 bytes_req: 2213968 bytes_alloc: 2228224 -+ { call_site: [ffffffffa0489a66] intel_ring_begin [i915] } hitcount: 7404 bytes_req: 1066176 bytes_alloc: 1421568 -+ { call_site: [ffffffffa045e7c4] i915_gem_do_execbuffer.isra.23 [i915] } hitcount: 1565 bytes_req: 557368 bytes_alloc: 1037760 -+ { call_site: [ffffffff8125847d] ext4_htree_store_dirent } hitcount: 9557 bytes_req: 595778 bytes_alloc: 695744 -+ { call_site: [ffffffffa045e646] i915_gem_do_execbuffer.isra.23 [i915] } hitcount: 5839 bytes_req: 430680 bytes_alloc: 470400 -+ { call_site: [ffffffffa04c4a3c] intel_plane_duplicate_state [i915] } hitcount: 2388 bytes_req: 324768 bytes_alloc: 458496 -+ { call_site: [ffffffffa02911f2] drm_modeset_lock_crtc [drm] } hitcount: 3911 bytes_req: 219016 bytes_alloc: 250304 -+ { call_site: [ffffffff815f8d7b] sk_prot_alloc } hitcount: 235 bytes_req: 236880 bytes_alloc: 240640 -+ { call_site: [ffffffff8137e559] sg_kmalloc } hitcount: 557 bytes_req: 169024 bytes_alloc: 221760 -+ { call_site: [ffffffffa00b7c06] hid_report_raw_event [hid] } hitcount: 9378 bytes_req: 187548 bytes_alloc: 206312 -+ { call_site: [ffffffffa04a580c] intel_crtc_page_flip [i915] } hitcount: 1519 bytes_req: 157976 bytes_alloc: 194432 -+ . -+ . -+ . -+ { call_site: [ffffffff8109bd3b] sched_autogroup_create_attach } hitcount: 2 bytes_req: 144 bytes_alloc: 192 -+ { call_site: [ffffffff81097ee8] alloc_rt_sched_group } hitcount: 2 bytes_req: 128 bytes_alloc: 128 -+ { call_site: [ffffffff8109524a] alloc_fair_sched_group } hitcount: 2 bytes_req: 128 bytes_alloc: 128 -+ { call_site: [ffffffff81095225] alloc_fair_sched_group } hitcount: 2 bytes_req: 128 bytes_alloc: 128 -+ { call_site: [ffffffff81097ec2] alloc_rt_sched_group } hitcount: 2 bytes_req: 128 bytes_alloc: 128 -+ { call_site: [ffffffff81213e80] load_elf_binary } hitcount: 3 bytes_req: 84 bytes_alloc: 96 -+ { call_site: [ffffffff81079a2e] kthread_create_on_node } hitcount: 1 bytes_req: 56 bytes_alloc: 64 -+ { call_site: [ffffffffa00bf6fe] hidraw_send_report [hid] } hitcount: 1 bytes_req: 7 bytes_alloc: 8 -+ { call_site: [ffffffff8154bc62] usb_control_msg } hitcount: 1 bytes_req: 8 bytes_alloc: 8 -+ { call_site: [ffffffffa00bf1ca] hidraw_report_event [hid] } hitcount: 1 bytes_req: 7 bytes_alloc: 8 -+ -+ Totals: -+ Hits: 66598 -+ Entries: 65 -+ Dropped: 0 -+ -+ Finally, to finish off our kmalloc example, instead of simply having -+ the hist trigger display symbolic call_sites, we can have the hist -+ trigger additionally display the complete set of kernel stack traces -+ that led to each call_site. To do that, we simply use the special -+ value 'stacktrace' for the key parameter: -+ -+ # echo 'hist:keys=stacktrace:values=bytes_req,bytes_alloc:sort=bytes_alloc' > \ -+ /sys/kernel/debug/tracing/events/kmem/kmalloc/trigger -+ -+ The above trigger will use the kernel stack trace in effect when an -+ event is triggered as the key for the hash table. This allows the -+ enumeration of every kernel callpath that led up to a particular -+ event, along with a running total of any of the event fields for -+ that event. Here we tally bytes requested and bytes allocated for -+ every callpath in the system that led up to a kmalloc (in this case -+ every callpath to a kmalloc for a kernel compile): -+ -+ # cat /sys/kernel/debug/tracing/events/kmem/kmalloc/hist -+ # trigger info: hist:keys=stacktrace:vals=bytes_req,bytes_alloc:sort=bytes_alloc:size=2048 [active] -+ -+ { stacktrace: -+ __kmalloc_track_caller+0x10b/0x1a0 -+ kmemdup+0x20/0x50 -+ hidraw_report_event+0x8a/0x120 [hid] -+ hid_report_raw_event+0x3ea/0x440 [hid] -+ hid_input_report+0x112/0x190 [hid] -+ hid_irq_in+0xc2/0x260 [usbhid] -+ __usb_hcd_giveback_urb+0x72/0x120 -+ usb_giveback_urb_bh+0x9e/0xe0 -+ tasklet_hi_action+0xf8/0x100 -+ __do_softirq+0x114/0x2c0 -+ irq_exit+0xa5/0xb0 -+ do_IRQ+0x5a/0xf0 -+ ret_from_intr+0x0/0x30 -+ cpuidle_enter+0x17/0x20 -+ cpu_startup_entry+0x315/0x3e0 -+ rest_init+0x7c/0x80 -+ } hitcount: 3 bytes_req: 21 bytes_alloc: 24 -+ { stacktrace: -+ __kmalloc_track_caller+0x10b/0x1a0 -+ kmemdup+0x20/0x50 -+ hidraw_report_event+0x8a/0x120 [hid] -+ hid_report_raw_event+0x3ea/0x440 [hid] -+ hid_input_report+0x112/0x190 [hid] -+ hid_irq_in+0xc2/0x260 [usbhid] -+ __usb_hcd_giveback_urb+0x72/0x120 -+ usb_giveback_urb_bh+0x9e/0xe0 -+ tasklet_hi_action+0xf8/0x100 -+ __do_softirq+0x114/0x2c0 -+ irq_exit+0xa5/0xb0 -+ do_IRQ+0x5a/0xf0 -+ ret_from_intr+0x0/0x30 -+ } hitcount: 3 bytes_req: 21 bytes_alloc: 24 -+ { stacktrace: -+ kmem_cache_alloc_trace+0xeb/0x150 -+ aa_alloc_task_context+0x27/0x40 -+ apparmor_cred_prepare+0x1f/0x50 -+ security_prepare_creds+0x16/0x20 -+ prepare_creds+0xdf/0x1a0 -+ SyS_capset+0xb5/0x200 -+ system_call_fastpath+0x12/0x6a -+ } hitcount: 1 bytes_req: 32 bytes_alloc: 32 -+ . -+ . -+ . -+ { stacktrace: -+ __kmalloc+0x11b/0x1b0 -+ i915_gem_execbuffer2+0x6c/0x2c0 [i915] -+ drm_ioctl+0x349/0x670 [drm] -+ do_vfs_ioctl+0x2f0/0x4f0 -+ SyS_ioctl+0x81/0xa0 -+ system_call_fastpath+0x12/0x6a -+ } hitcount: 17726 bytes_req: 13944120 bytes_alloc: 19593808 -+ { stacktrace: -+ __kmalloc+0x11b/0x1b0 -+ load_elf_phdrs+0x76/0xa0 -+ load_elf_binary+0x102/0x1650 -+ search_binary_handler+0x97/0x1d0 -+ do_execveat_common.isra.34+0x551/0x6e0 -+ SyS_execve+0x3a/0x50 -+ return_from_execve+0x0/0x23 -+ } hitcount: 33348 bytes_req: 17152128 bytes_alloc: 20226048 -+ { stacktrace: -+ kmem_cache_alloc_trace+0xeb/0x150 -+ apparmor_file_alloc_security+0x27/0x40 -+ security_file_alloc+0x16/0x20 -+ get_empty_filp+0x93/0x1c0 -+ path_openat+0x31/0x5f0 -+ do_filp_open+0x3a/0x90 -+ do_sys_open+0x128/0x220 -+ SyS_open+0x1e/0x20 -+ system_call_fastpath+0x12/0x6a -+ } hitcount: 4766422 bytes_req: 9532844 bytes_alloc: 38131376 -+ { stacktrace: -+ __kmalloc+0x11b/0x1b0 -+ seq_buf_alloc+0x1b/0x50 -+ seq_read+0x2cc/0x370 -+ proc_reg_read+0x3d/0x80 -+ __vfs_read+0x28/0xe0 -+ vfs_read+0x86/0x140 -+ SyS_read+0x46/0xb0 -+ system_call_fastpath+0x12/0x6a -+ } hitcount: 19133 bytes_req: 78368768 bytes_alloc: 78368768 -+ -+ Totals: -+ Hits: 6085872 -+ Entries: 253 -+ Dropped: 0 -+ -+ If you key a hist trigger on common_pid, in order for example to -+ gather and display sorted totals for each process, you can use the -+ special .execname modifier to display the executable names for the -+ processes in the table rather than raw pids. The example below -+ keeps a per-process sum of total bytes read: -+ -+ # echo 'hist:key=common_pid.execname:val=count:sort=count.descending' > \ -+ /sys/kernel/debug/tracing/events/syscalls/sys_enter_read/trigger -+ -+ # cat /sys/kernel/debug/tracing/events/syscalls/sys_enter_read/hist -+ # trigger info: hist:keys=common_pid.execname:vals=count:sort=count.descending:size=2048 [active] -+ -+ { common_pid: gnome-terminal [ 3196] } hitcount: 280 count: 1093512 -+ { common_pid: Xorg [ 1309] } hitcount: 525 count: 256640 -+ { common_pid: compiz [ 2889] } hitcount: 59 count: 254400 -+ { common_pid: bash [ 8710] } hitcount: 3 count: 66369 -+ { common_pid: dbus-daemon-lau [ 8703] } hitcount: 49 count: 47739 -+ { common_pid: irqbalance [ 1252] } hitcount: 27 count: 27648 -+ { common_pid: 01ifupdown [ 8705] } hitcount: 3 count: 17216 -+ { common_pid: dbus-daemon [ 772] } hitcount: 10 count: 12396 -+ { common_pid: Socket Thread [ 8342] } hitcount: 11 count: 11264 -+ { common_pid: nm-dhcp-client. [ 8701] } hitcount: 6 count: 7424 -+ { common_pid: gmain [ 1315] } hitcount: 18 count: 6336 -+ . -+ . -+ . -+ { common_pid: postgres [ 1892] } hitcount: 2 count: 32 -+ { common_pid: postgres [ 1891] } hitcount: 2 count: 32 -+ { common_pid: gmain [ 8704] } hitcount: 2 count: 32 -+ { common_pid: upstart-dbus-br [ 2740] } hitcount: 21 count: 21 -+ { common_pid: nm-dispatcher.a [ 8696] } hitcount: 1 count: 16 -+ { common_pid: indicator-datet [ 2904] } hitcount: 1 count: 16 -+ { common_pid: gdbus [ 2998] } hitcount: 1 count: 16 -+ { common_pid: rtkit-daemon [ 2052] } hitcount: 1 count: 8 -+ { common_pid: init [ 1] } hitcount: 2 count: 2 -+ -+ Totals: -+ Hits: 2116 -+ Entries: 51 -+ Dropped: 0 -+ -+ Similarly, if you key a hist trigger on syscall id, for example to -+ gather and display a list of systemwide syscall hits, you can use -+ the special .syscall modifier to display the syscall names rather -+ than raw ids. The example below keeps a running total of syscall -+ counts for the system during the run: -+ -+ # echo 'hist:key=id.syscall:val=hitcount' > \ -+ /sys/kernel/debug/tracing/events/raw_syscalls/sys_enter/trigger -+ -+ # cat /sys/kernel/debug/tracing/events/raw_syscalls/sys_enter/hist -+ # trigger info: hist:keys=id.syscall:vals=hitcount:sort=hitcount:size=2048 [active] -+ -+ { id: sys_fsync [ 74] } hitcount: 1 -+ { id: sys_newuname [ 63] } hitcount: 1 -+ { id: sys_prctl [157] } hitcount: 1 -+ { id: sys_statfs [137] } hitcount: 1 -+ { id: sys_symlink [ 88] } hitcount: 1 -+ { id: sys_sendmmsg [307] } hitcount: 1 -+ { id: sys_semctl [ 66] } hitcount: 1 -+ { id: sys_readlink [ 89] } hitcount: 3 -+ { id: sys_bind [ 49] } hitcount: 3 -+ { id: sys_getsockname [ 51] } hitcount: 3 -+ { id: sys_unlink [ 87] } hitcount: 3 -+ { id: sys_rename [ 82] } hitcount: 4 -+ { id: unknown_syscall [ 58] } hitcount: 4 -+ { id: sys_connect [ 42] } hitcount: 4 -+ { id: sys_getpid [ 39] } hitcount: 4 -+ . -+ . -+ . -+ { id: sys_rt_sigprocmask [ 14] } hitcount: 952 -+ { id: sys_futex [202] } hitcount: 1534 -+ { id: sys_write [ 1] } hitcount: 2689 -+ { id: sys_setitimer [ 38] } hitcount: 2797 -+ { id: sys_read [ 0] } hitcount: 3202 -+ { id: sys_select [ 23] } hitcount: 3773 -+ { id: sys_writev [ 20] } hitcount: 4531 -+ { id: sys_poll [ 7] } hitcount: 8314 -+ { id: sys_recvmsg [ 47] } hitcount: 13738 -+ { id: sys_ioctl [ 16] } hitcount: 21843 -+ -+ Totals: -+ Hits: 67612 -+ Entries: 72 -+ Dropped: 0 -+ -+ The syscall counts above provide a rough overall picture of system -+ call activity on the system; we can see for example that the most -+ popular system call on this system was the 'sys_ioctl' system call. -+ -+ We can use 'compound' keys to refine that number and provide some -+ further insight as to which processes exactly contribute to the -+ overall ioctl count. -+ -+ The command below keeps a hitcount for every unique combination of -+ system call id and pid - the end result is essentially a table -+ that keeps a per-pid sum of system call hits. The results are -+ sorted using the system call id as the primary key, and the -+ hitcount sum as the secondary key: -+ -+ # echo 'hist:key=id.syscall,common_pid.execname:val=hitcount:sort=id,hitcount' > \ -+ /sys/kernel/debug/tracing/events/raw_syscalls/sys_enter/trigger -+ -+ # cat /sys/kernel/debug/tracing/events/raw_syscalls/sys_enter/hist -+ # trigger info: hist:keys=id.syscall,common_pid.execname:vals=hitcount:sort=id.syscall,hitcount:size=2048 [active] -+ -+ { id: sys_read [ 0], common_pid: rtkit-daemon [ 1877] } hitcount: 1 -+ { id: sys_read [ 0], common_pid: gdbus [ 2976] } hitcount: 1 -+ { id: sys_read [ 0], common_pid: console-kit-dae [ 3400] } hitcount: 1 -+ { id: sys_read [ 0], common_pid: postgres [ 1865] } hitcount: 1 -+ { id: sys_read [ 0], common_pid: deja-dup-monito [ 3543] } hitcount: 2 -+ { id: sys_read [ 0], common_pid: NetworkManager [ 890] } hitcount: 2 -+ { id: sys_read [ 0], common_pid: evolution-calen [ 3048] } hitcount: 2 -+ { id: sys_read [ 0], common_pid: postgres [ 1864] } hitcount: 2 -+ { id: sys_read [ 0], common_pid: nm-applet [ 3022] } hitcount: 2 -+ { id: sys_read [ 0], common_pid: whoopsie [ 1212] } hitcount: 2 -+ . -+ . -+ . -+ { id: sys_ioctl [ 16], common_pid: bash [ 8479] } hitcount: 1 -+ { id: sys_ioctl [ 16], common_pid: bash [ 3472] } hitcount: 12 -+ { id: sys_ioctl [ 16], common_pid: gnome-terminal [ 3199] } hitcount: 16 -+ { id: sys_ioctl [ 16], common_pid: Xorg [ 1267] } hitcount: 1808 -+ { id: sys_ioctl [ 16], common_pid: compiz [ 2994] } hitcount: 5580 -+ . -+ . -+ . -+ { id: sys_waitid [247], common_pid: upstart-dbus-br [ 2690] } hitcount: 3 -+ { id: sys_waitid [247], common_pid: upstart-dbus-br [ 2688] } hitcount: 16 -+ { id: sys_inotify_add_watch [254], common_pid: gmain [ 975] } hitcount: 2 -+ { id: sys_inotify_add_watch [254], common_pid: gmain [ 3204] } hitcount: 4 -+ { id: sys_inotify_add_watch [254], common_pid: gmain [ 2888] } hitcount: 4 -+ { id: sys_inotify_add_watch [254], common_pid: gmain [ 3003] } hitcount: 4 -+ { id: sys_inotify_add_watch [254], common_pid: gmain [ 2873] } hitcount: 4 -+ { id: sys_inotify_add_watch [254], common_pid: gmain [ 3196] } hitcount: 6 -+ { id: sys_openat [257], common_pid: java [ 2623] } hitcount: 2 -+ { id: sys_eventfd2 [290], common_pid: ibus-ui-gtk3 [ 2760] } hitcount: 4 -+ { id: sys_eventfd2 [290], common_pid: compiz [ 2994] } hitcount: 6 -+ -+ Totals: -+ Hits: 31536 -+ Entries: 323 -+ Dropped: 0 -+ -+ The above list does give us a breakdown of the ioctl syscall by -+ pid, but it also gives us quite a bit more than that, which we -+ don't really care about at the moment. Since we know the syscall -+ id for sys_ioctl (16, displayed next to the sys_ioctl name), we -+ can use that to filter out all the other syscalls: -+ -+ # echo 'hist:key=id.syscall,common_pid.execname:val=hitcount:sort=id,hitcount if id == 16' > \ -+ /sys/kernel/debug/tracing/events/raw_syscalls/sys_enter/trigger -+ -+ # cat /sys/kernel/debug/tracing/events/raw_syscalls/sys_enter/hist -+ # trigger info: hist:keys=id.syscall,common_pid.execname:vals=hitcount:sort=id.syscall,hitcount:size=2048 if id == 16 [active] -+ -+ { id: sys_ioctl [ 16], common_pid: gmain [ 2769] } hitcount: 1 -+ { id: sys_ioctl [ 16], common_pid: evolution-addre [ 8571] } hitcount: 1 -+ { id: sys_ioctl [ 16], common_pid: gmain [ 3003] } hitcount: 1 -+ { id: sys_ioctl [ 16], common_pid: gmain [ 2781] } hitcount: 1 -+ { id: sys_ioctl [ 16], common_pid: gmain [ 2829] } hitcount: 1 -+ { id: sys_ioctl [ 16], common_pid: bash [ 8726] } hitcount: 1 -+ { id: sys_ioctl [ 16], common_pid: bash [ 8508] } hitcount: 1 -+ { id: sys_ioctl [ 16], common_pid: gmain [ 2970] } hitcount: 1 -+ { id: sys_ioctl [ 16], common_pid: gmain [ 2768] } hitcount: 1 -+ . -+ . -+ . -+ { id: sys_ioctl [ 16], common_pid: pool [ 8559] } hitcount: 45 -+ { id: sys_ioctl [ 16], common_pid: pool [ 8555] } hitcount: 48 -+ { id: sys_ioctl [ 16], common_pid: pool [ 8551] } hitcount: 48 -+ { id: sys_ioctl [ 16], common_pid: avahi-daemon [ 896] } hitcount: 66 -+ { id: sys_ioctl [ 16], common_pid: Xorg [ 1267] } hitcount: 26674 -+ { id: sys_ioctl [ 16], common_pid: compiz [ 2994] } hitcount: 73443 -+ -+ Totals: -+ Hits: 101162 -+ Entries: 103 -+ Dropped: 0 -+ -+ The above output shows that 'compiz' and 'Xorg' are far and away -+ the heaviest ioctl callers (which might lead to questions about -+ whether they really need to be making all those calls and to -+ possible avenues for further investigation.) -+ -+ The compound key examples used a key and a sum value (hitcount) to -+ sort the output, but we can just as easily use two keys instead. -+ Here's an example where we use a compound key composed of the the -+ common_pid and size event fields. Sorting with pid as the primary -+ key and 'size' as the secondary key allows us to display an -+ ordered summary of the recvfrom sizes, with counts, received by -+ each process: -+ -+ # echo 'hist:key=common_pid.execname,size:val=hitcount:sort=common_pid,size' > \ -+ /sys/kernel/debug/tracing/events/syscalls/sys_enter_recvfrom/trigger -+ -+ # cat /sys/kernel/debug/tracing/events/syscalls/sys_enter_recvfrom/hist -+ # trigger info: hist:keys=common_pid.execname,size:vals=hitcount:sort=common_pid.execname,size:size=2048 [active] -+ -+ { common_pid: smbd [ 784], size: 4 } hitcount: 1 -+ { common_pid: dnsmasq [ 1412], size: 4096 } hitcount: 672 -+ { common_pid: postgres [ 1796], size: 1000 } hitcount: 6 -+ { common_pid: postgres [ 1867], size: 1000 } hitcount: 10 -+ { common_pid: bamfdaemon [ 2787], size: 28 } hitcount: 2 -+ { common_pid: bamfdaemon [ 2787], size: 14360 } hitcount: 1 -+ { common_pid: compiz [ 2994], size: 8 } hitcount: 1 -+ { common_pid: compiz [ 2994], size: 20 } hitcount: 11 -+ { common_pid: gnome-terminal [ 3199], size: 4 } hitcount: 2 -+ { common_pid: firefox [ 8817], size: 4 } hitcount: 1 -+ { common_pid: firefox [ 8817], size: 8 } hitcount: 5 -+ { common_pid: firefox [ 8817], size: 588 } hitcount: 2 -+ { common_pid: firefox [ 8817], size: 628 } hitcount: 1 -+ { common_pid: firefox [ 8817], size: 6944 } hitcount: 1 -+ { common_pid: firefox [ 8817], size: 408880 } hitcount: 2 -+ { common_pid: firefox [ 8822], size: 8 } hitcount: 2 -+ { common_pid: firefox [ 8822], size: 160 } hitcount: 2 -+ { common_pid: firefox [ 8822], size: 320 } hitcount: 2 -+ { common_pid: firefox [ 8822], size: 352 } hitcount: 1 -+ . -+ . -+ . -+ { common_pid: pool [ 8923], size: 1960 } hitcount: 10 -+ { common_pid: pool [ 8923], size: 2048 } hitcount: 10 -+ { common_pid: pool [ 8924], size: 1960 } hitcount: 10 -+ { common_pid: pool [ 8924], size: 2048 } hitcount: 10 -+ { common_pid: pool [ 8928], size: 1964 } hitcount: 4 -+ { common_pid: pool [ 8928], size: 1965 } hitcount: 2 -+ { common_pid: pool [ 8928], size: 2048 } hitcount: 6 -+ { common_pid: pool [ 8929], size: 1982 } hitcount: 1 -+ { common_pid: pool [ 8929], size: 2048 } hitcount: 1 -+ -+ Totals: -+ Hits: 2016 -+ Entries: 224 -+ Dropped: 0 -+ -+ The above example also illustrates the fact that although a compound -+ key is treated as a single entity for hashing purposes, the sub-keys -+ it's composed of can be accessed independently. -+ -+ The next example uses a string field as the hash key and -+ demonstrates how you can manually pause and continue a hist trigger. -+ In this example, we'll aggregate fork counts and don't expect a -+ large number of entries in the hash table, so we'll drop it to a -+ much smaller number, say 256: -+ -+ # echo 'hist:key=child_comm:val=hitcount:size=256' > \ -+ /sys/kernel/debug/tracing/events/sched/sched_process_fork/trigger -+ -+ # cat /sys/kernel/debug/tracing/events/sched/sched_process_fork/hist -+ # trigger info: hist:keys=child_comm:vals=hitcount:sort=hitcount:size=256 [active] -+ -+ { child_comm: dconf worker } hitcount: 1 -+ { child_comm: ibus-daemon } hitcount: 1 -+ { child_comm: whoopsie } hitcount: 1 -+ { child_comm: smbd } hitcount: 1 -+ { child_comm: gdbus } hitcount: 1 -+ { child_comm: kthreadd } hitcount: 1 -+ { child_comm: dconf worker } hitcount: 1 -+ { child_comm: evolution-alarm } hitcount: 2 -+ { child_comm: Socket Thread } hitcount: 2 -+ { child_comm: postgres } hitcount: 2 -+ { child_comm: bash } hitcount: 3 -+ { child_comm: compiz } hitcount: 3 -+ { child_comm: evolution-sourc } hitcount: 4 -+ { child_comm: dhclient } hitcount: 4 -+ { child_comm: pool } hitcount: 5 -+ { child_comm: nm-dispatcher.a } hitcount: 8 -+ { child_comm: firefox } hitcount: 8 -+ { child_comm: dbus-daemon } hitcount: 8 -+ { child_comm: glib-pacrunner } hitcount: 10 -+ { child_comm: evolution } hitcount: 23 -+ -+ Totals: -+ Hits: 89 -+ Entries: 20 -+ Dropped: 0 -+ -+ If we want to pause the hist trigger, we can simply append :pause to -+ the command that started the trigger. Notice that the trigger info -+ displays as [paused]: -+ -+ # echo 'hist:key=child_comm:val=hitcount:size=256:pause' >> \ -+ /sys/kernel/debug/tracing/events/sched/sched_process_fork/trigger -+ -+ # cat /sys/kernel/debug/tracing/events/sched/sched_process_fork/hist -+ # trigger info: hist:keys=child_comm:vals=hitcount:sort=hitcount:size=256 [paused] -+ -+ { child_comm: dconf worker } hitcount: 1 -+ { child_comm: kthreadd } hitcount: 1 -+ { child_comm: dconf worker } hitcount: 1 -+ { child_comm: gdbus } hitcount: 1 -+ { child_comm: ibus-daemon } hitcount: 1 -+ { child_comm: Socket Thread } hitcount: 2 -+ { child_comm: evolution-alarm } hitcount: 2 -+ { child_comm: smbd } hitcount: 2 -+ { child_comm: bash } hitcount: 3 -+ { child_comm: whoopsie } hitcount: 3 -+ { child_comm: compiz } hitcount: 3 -+ { child_comm: evolution-sourc } hitcount: 4 -+ { child_comm: pool } hitcount: 5 -+ { child_comm: postgres } hitcount: 6 -+ { child_comm: firefox } hitcount: 8 -+ { child_comm: dhclient } hitcount: 10 -+ { child_comm: emacs } hitcount: 12 -+ { child_comm: dbus-daemon } hitcount: 20 -+ { child_comm: nm-dispatcher.a } hitcount: 20 -+ { child_comm: evolution } hitcount: 35 -+ { child_comm: glib-pacrunner } hitcount: 59 -+ -+ Totals: -+ Hits: 199 -+ Entries: 21 -+ Dropped: 0 -+ -+ To manually continue having the trigger aggregate events, append -+ :cont instead. Notice that the trigger info displays as [active] -+ again, and the data has changed: -+ -+ # echo 'hist:key=child_comm:val=hitcount:size=256:cont' >> \ -+ /sys/kernel/debug/tracing/events/sched/sched_process_fork/trigger -+ -+ # cat /sys/kernel/debug/tracing/events/sched/sched_process_fork/hist -+ # trigger info: hist:keys=child_comm:vals=hitcount:sort=hitcount:size=256 [active] -+ -+ { child_comm: dconf worker } hitcount: 1 -+ { child_comm: dconf worker } hitcount: 1 -+ { child_comm: kthreadd } hitcount: 1 -+ { child_comm: gdbus } hitcount: 1 -+ { child_comm: ibus-daemon } hitcount: 1 -+ { child_comm: Socket Thread } hitcount: 2 -+ { child_comm: evolution-alarm } hitcount: 2 -+ { child_comm: smbd } hitcount: 2 -+ { child_comm: whoopsie } hitcount: 3 -+ { child_comm: compiz } hitcount: 3 -+ { child_comm: evolution-sourc } hitcount: 4 -+ { child_comm: bash } hitcount: 5 -+ { child_comm: pool } hitcount: 5 -+ { child_comm: postgres } hitcount: 6 -+ { child_comm: firefox } hitcount: 8 -+ { child_comm: dhclient } hitcount: 11 -+ { child_comm: emacs } hitcount: 12 -+ { child_comm: dbus-daemon } hitcount: 22 -+ { child_comm: nm-dispatcher.a } hitcount: 22 -+ { child_comm: evolution } hitcount: 35 -+ { child_comm: glib-pacrunner } hitcount: 59 -+ -+ Totals: -+ Hits: 206 -+ Entries: 21 -+ Dropped: 0 -+ -+ The previous example showed how to start and stop a hist trigger by -+ appending 'pause' and 'continue' to the hist trigger command. A -+ hist trigger can also be started in a paused state by initially -+ starting the trigger with ':pause' appended. This allows you to -+ start the trigger only when you're ready to start collecting data -+ and not before. For example, you could start the trigger in a -+ paused state, then unpause it and do something you want to measure, -+ then pause the trigger again when done. -+ -+ Of course, doing this manually can be difficult and error-prone, but -+ it is possible to automatically start and stop a hist trigger based -+ on some condition, via the enable_hist and disable_hist triggers. -+ -+ For example, suppose we wanted to take a look at the relative -+ weights in terms of skb length for each callpath that leads to a -+ netif_receieve_skb event when downloading a decent-sized file using -+ wget. -+ -+ First we set up an initially paused stacktrace trigger on the -+ netif_receive_skb event: -+ -+ # echo 'hist:key=stacktrace:vals=len:pause' > \ -+ /sys/kernel/debug/tracing/events/net/netif_receive_skb/trigger -+ -+ Next, we set up an 'enable_hist' trigger on the sched_process_exec -+ event, with an 'if filename==/usr/bin/wget' filter. The effect of -+ this new trigger is that it will 'unpause' the hist trigger we just -+ set up on netif_receive_skb if and only if it sees a -+ sched_process_exec event with a filename of '/usr/bin/wget'. When -+ that happens, all netif_receive_skb events are aggregated into a -+ hash table keyed on stacktrace: -+ -+ # echo 'enable_hist:net:netif_receive_skb if filename==/usr/bin/wget' > \ -+ /sys/kernel/debug/tracing/events/sched/sched_process_exec/trigger -+ -+ The aggregation continues until the netif_receive_skb is paused -+ again, which is what the following disable_hist event does by -+ creating a similar setup on the sched_process_exit event, using the -+ filter 'comm==wget': -+ -+ # echo 'disable_hist:net:netif_receive_skb if comm==wget' > \ -+ /sys/kernel/debug/tracing/events/sched/sched_process_exit/trigger -+ -+ Whenever a process exits and the comm field of the disable_hist -+ trigger filter matches 'comm==wget', the netif_receive_skb hist -+ trigger is disabled. -+ -+ The overall effect is that netif_receive_skb events are aggregated -+ into the hash table for only the duration of the wget. Executing a -+ wget command and then listing the 'hist' file will display the -+ output generated by the wget command: -+ -+ $ wget https://www.kernel.org/pub/linux/kernel/v3.x/patch-3.19.xz -+ -+ # cat /sys/kernel/debug/tracing/events/net/netif_receive_skb/hist -+ # trigger info: hist:keys=stacktrace:vals=len:sort=hitcount:size=2048 [paused] -+ -+ { stacktrace: -+ __netif_receive_skb_core+0x46d/0x990 -+ __netif_receive_skb+0x18/0x60 -+ netif_receive_skb_internal+0x23/0x90 -+ napi_gro_receive+0xc8/0x100 -+ ieee80211_deliver_skb+0xd6/0x270 [mac80211] -+ ieee80211_rx_handlers+0xccf/0x22f0 [mac80211] -+ ieee80211_prepare_and_rx_handle+0x4e7/0xc40 [mac80211] -+ ieee80211_rx+0x31d/0x900 [mac80211] -+ iwlagn_rx_reply_rx+0x3db/0x6f0 [iwldvm] -+ iwl_rx_dispatch+0x8e/0xf0 [iwldvm] -+ iwl_pcie_irq_handler+0xe3c/0x12f0 [iwlwifi] -+ irq_thread_fn+0x20/0x50 -+ irq_thread+0x11f/0x150 -+ kthread+0xd2/0xf0 -+ ret_from_fork+0x42/0x70 -+ } hitcount: 85 len: 28884 -+ { stacktrace: -+ __netif_receive_skb_core+0x46d/0x990 -+ __netif_receive_skb+0x18/0x60 -+ netif_receive_skb_internal+0x23/0x90 -+ napi_gro_complete+0xa4/0xe0 -+ dev_gro_receive+0x23a/0x360 -+ napi_gro_receive+0x30/0x100 -+ ieee80211_deliver_skb+0xd6/0x270 [mac80211] -+ ieee80211_rx_handlers+0xccf/0x22f0 [mac80211] -+ ieee80211_prepare_and_rx_handle+0x4e7/0xc40 [mac80211] -+ ieee80211_rx+0x31d/0x900 [mac80211] -+ iwlagn_rx_reply_rx+0x3db/0x6f0 [iwldvm] -+ iwl_rx_dispatch+0x8e/0xf0 [iwldvm] -+ iwl_pcie_irq_handler+0xe3c/0x12f0 [iwlwifi] -+ irq_thread_fn+0x20/0x50 -+ irq_thread+0x11f/0x150 -+ kthread+0xd2/0xf0 -+ } hitcount: 98 len: 664329 -+ { stacktrace: -+ __netif_receive_skb_core+0x46d/0x990 -+ __netif_receive_skb+0x18/0x60 -+ process_backlog+0xa8/0x150 -+ net_rx_action+0x15d/0x340 -+ __do_softirq+0x114/0x2c0 -+ do_softirq_own_stack+0x1c/0x30 -+ do_softirq+0x65/0x70 -+ __local_bh_enable_ip+0xb5/0xc0 -+ ip_finish_output+0x1f4/0x840 -+ ip_output+0x6b/0xc0 -+ ip_local_out_sk+0x31/0x40 -+ ip_send_skb+0x1a/0x50 -+ udp_send_skb+0x173/0x2a0 -+ udp_sendmsg+0x2bf/0x9f0 -+ inet_sendmsg+0x64/0xa0 -+ sock_sendmsg+0x3d/0x50 -+ } hitcount: 115 len: 13030 -+ { stacktrace: -+ __netif_receive_skb_core+0x46d/0x990 -+ __netif_receive_skb+0x18/0x60 -+ netif_receive_skb_internal+0x23/0x90 -+ napi_gro_complete+0xa4/0xe0 -+ napi_gro_flush+0x6d/0x90 -+ iwl_pcie_irq_handler+0x92a/0x12f0 [iwlwifi] -+ irq_thread_fn+0x20/0x50 -+ irq_thread+0x11f/0x150 -+ kthread+0xd2/0xf0 -+ ret_from_fork+0x42/0x70 -+ } hitcount: 934 len: 5512212 -+ -+ Totals: -+ Hits: 1232 -+ Entries: 4 -+ Dropped: 0 -+ -+ The above shows all the netif_receive_skb callpaths and their total -+ lengths for the duration of the wget command. -+ -+ The 'clear' hist trigger param can be used to clear the hash table. -+ Suppose we wanted to try another run of the previous example but -+ this time also wanted to see the complete list of events that went -+ into the histogram. In order to avoid having to set everything up -+ again, we can just clear the histogram first: -+ -+ # echo 'hist:key=stacktrace:vals=len:clear' >> \ -+ /sys/kernel/debug/tracing/events/net/netif_receive_skb/trigger -+ -+ Just to verify that it is in fact cleared, here's what we now see in -+ the hist file: -+ -+ # cat /sys/kernel/debug/tracing/events/net/netif_receive_skb/hist -+ # trigger info: hist:keys=stacktrace:vals=len:sort=hitcount:size=2048 [paused] -+ -+ Totals: -+ Hits: 0 -+ Entries: 0 -+ Dropped: 0 -+ -+ Since we want to see the detailed list of every netif_receive_skb -+ event occurring during the new run, which are in fact the same -+ events being aggregated into the hash table, we add some additional -+ 'enable_event' events to the triggering sched_process_exec and -+ sched_process_exit events as such: -+ -+ # echo 'enable_event:net:netif_receive_skb if filename==/usr/bin/wget' > \ -+ /sys/kernel/debug/tracing/events/sched/sched_process_exec/trigger -+ -+ # echo 'disable_event:net:netif_receive_skb if comm==wget' > \ -+ /sys/kernel/debug/tracing/events/sched/sched_process_exit/trigger -+ -+ If you read the trigger files for the sched_process_exec and -+ sched_process_exit triggers, you should see two triggers for each: -+ one enabling/disabling the hist aggregation and the other -+ enabling/disabling the logging of events: -+ -+ # cat /sys/kernel/debug/tracing/events/sched/sched_process_exec/trigger -+ enable_event:net:netif_receive_skb:unlimited if filename==/usr/bin/wget -+ enable_hist:net:netif_receive_skb:unlimited if filename==/usr/bin/wget -+ -+ # cat /sys/kernel/debug/tracing/events/sched/sched_process_exit/trigger -+ enable_event:net:netif_receive_skb:unlimited if comm==wget -+ disable_hist:net:netif_receive_skb:unlimited if comm==wget -+ -+ In other words, whenever either of the sched_process_exec or -+ sched_process_exit events is hit and matches 'wget', it enables or -+ disables both the histogram and the event log, and what you end up -+ with is a hash table and set of events just covering the specified -+ duration. Run the wget command again: -+ -+ $ wget https://www.kernel.org/pub/linux/kernel/v3.x/patch-3.19.xz -+ -+ Displaying the 'hist' file should show something similar to what you -+ saw in the last run, but this time you should also see the -+ individual events in the trace file: -+ -+ # cat /sys/kernel/debug/tracing/trace -+ -+ # tracer: nop -+ # -+ # entries-in-buffer/entries-written: 183/1426 #P:4 -+ # -+ # _-----=> irqs-off -+ # / _----=> need-resched -+ # | / _---=> hardirq/softirq -+ # || / _--=> preempt-depth -+ # ||| / delay -+ # TASK-PID CPU# |||| TIMESTAMP FUNCTION -+ # | | | |||| | | -+ wget-15108 [000] ..s1 31769.606929: netif_receive_skb: dev=lo skbaddr=ffff88009c353100 len=60 -+ wget-15108 [000] ..s1 31769.606999: netif_receive_skb: dev=lo skbaddr=ffff88009c353200 len=60 -+ dnsmasq-1382 [000] ..s1 31769.677652: netif_receive_skb: dev=lo skbaddr=ffff88009c352b00 len=130 -+ dnsmasq-1382 [000] ..s1 31769.685917: netif_receive_skb: dev=lo skbaddr=ffff88009c352200 len=138 -+ ##### CPU 2 buffer started #### -+ irq/29-iwlwifi-559 [002] ..s. 31772.031529: netif_receive_skb: dev=wlan0 skbaddr=ffff88009d433d00 len=2948 -+ irq/29-iwlwifi-559 [002] ..s. 31772.031572: netif_receive_skb: dev=wlan0 skbaddr=ffff88009d432200 len=1500 -+ irq/29-iwlwifi-559 [002] ..s. 31772.032196: netif_receive_skb: dev=wlan0 skbaddr=ffff88009d433100 len=2948 -+ irq/29-iwlwifi-559 [002] ..s. 31772.032761: netif_receive_skb: dev=wlan0 skbaddr=ffff88009d433000 len=2948 -+ irq/29-iwlwifi-559 [002] ..s. 31772.033220: netif_receive_skb: dev=wlan0 skbaddr=ffff88009d432e00 len=1500 -+ . -+ . -+ . -+ -+ The following example demonstrates how multiple hist triggers can be -+ attached to a given event. This capability can be useful for -+ creating a set of different summaries derived from the same set of -+ events, or for comparing the effects of different filters, among -+ other things. -+ -+ # echo 'hist:keys=skbaddr.hex:vals=len if len < 0' >> \ -+ /sys/kernel/debug/tracing/events/net/netif_receive_skb/trigger -+ # echo 'hist:keys=skbaddr.hex:vals=len if len > 4096' >> \ -+ /sys/kernel/debug/tracing/events/net/netif_receive_skb/trigger -+ # echo 'hist:keys=skbaddr.hex:vals=len if len == 256' >> \ -+ /sys/kernel/debug/tracing/events/net/netif_receive_skb/trigger -+ # echo 'hist:keys=skbaddr.hex:vals=len' >> \ -+ /sys/kernel/debug/tracing/events/net/netif_receive_skb/trigger -+ # echo 'hist:keys=len:vals=common_preempt_count' >> \ -+ /sys/kernel/debug/tracing/events/net/netif_receive_skb/trigger -+ -+ The above set of commands create four triggers differing only in -+ their filters, along with a completely different though fairly -+ nonsensical trigger. Note that in order to append multiple hist -+ triggers to the same file, you should use the '>>' operator to -+ append them ('>' will also add the new hist trigger, but will remove -+ any existing hist triggers beforehand). -+ -+ Displaying the contents of the 'hist' file for the event shows the -+ contents of all five histograms: -+ -+ # cat /sys/kernel/debug/tracing/events/net/netif_receive_skb/hist -+ -+ # event histogram -+ # -+ # trigger info: hist:keys=len:vals=hitcount,common_preempt_count:sort=hitcount:size=2048 [active] -+ # -+ -+ { len: 176 } hitcount: 1 common_preempt_count: 0 -+ { len: 223 } hitcount: 1 common_preempt_count: 0 -+ { len: 4854 } hitcount: 1 common_preempt_count: 0 -+ { len: 395 } hitcount: 1 common_preempt_count: 0 -+ { len: 177 } hitcount: 1 common_preempt_count: 0 -+ { len: 446 } hitcount: 1 common_preempt_count: 0 -+ { len: 1601 } hitcount: 1 common_preempt_count: 0 -+ . -+ . -+ . -+ { len: 1280 } hitcount: 66 common_preempt_count: 0 -+ { len: 116 } hitcount: 81 common_preempt_count: 40 -+ { len: 708 } hitcount: 112 common_preempt_count: 0 -+ { len: 46 } hitcount: 221 common_preempt_count: 0 -+ { len: 1264 } hitcount: 458 common_preempt_count: 0 -+ -+ Totals: -+ Hits: 1428 -+ Entries: 147 -+ Dropped: 0 -+ -+ -+ # event histogram -+ # -+ # trigger info: hist:keys=skbaddr.hex:vals=hitcount,len:sort=hitcount:size=2048 [active] -+ # -+ -+ { skbaddr: ffff8800baee5e00 } hitcount: 1 len: 130 -+ { skbaddr: ffff88005f3d5600 } hitcount: 1 len: 1280 -+ { skbaddr: ffff88005f3d4900 } hitcount: 1 len: 1280 -+ { skbaddr: ffff88009fed6300 } hitcount: 1 len: 115 -+ { skbaddr: ffff88009fe0ad00 } hitcount: 1 len: 115 -+ { skbaddr: ffff88008cdb1900 } hitcount: 1 len: 46 -+ { skbaddr: ffff880064b5ef00 } hitcount: 1 len: 118 -+ { skbaddr: ffff880044e3c700 } hitcount: 1 len: 60 -+ { skbaddr: ffff880100065900 } hitcount: 1 len: 46 -+ { skbaddr: ffff8800d46bd500 } hitcount: 1 len: 116 -+ { skbaddr: ffff88005f3d5f00 } hitcount: 1 len: 1280 -+ { skbaddr: ffff880100064700 } hitcount: 1 len: 365 -+ { skbaddr: ffff8800badb6f00 } hitcount: 1 len: 60 -+ . -+ . -+ . -+ { skbaddr: ffff88009fe0be00 } hitcount: 27 len: 24677 -+ { skbaddr: ffff88009fe0a400 } hitcount: 27 len: 23052 -+ { skbaddr: ffff88009fe0b700 } hitcount: 31 len: 25589 -+ { skbaddr: ffff88009fe0b600 } hitcount: 32 len: 27326 -+ { skbaddr: ffff88006a462800 } hitcount: 68 len: 71678 -+ { skbaddr: ffff88006a463700 } hitcount: 70 len: 72678 -+ { skbaddr: ffff88006a462b00 } hitcount: 71 len: 77589 -+ { skbaddr: ffff88006a463600 } hitcount: 73 len: 71307 -+ { skbaddr: ffff88006a462200 } hitcount: 81 len: 81032 -+ -+ Totals: -+ Hits: 1451 -+ Entries: 318 -+ Dropped: 0 -+ -+ -+ # event histogram -+ # -+ # trigger info: hist:keys=skbaddr.hex:vals=hitcount,len:sort=hitcount:size=2048 if len == 256 [active] -+ # -+ -+ -+ Totals: -+ Hits: 0 -+ Entries: 0 -+ Dropped: 0 -+ -+ -+ # event histogram -+ # -+ # trigger info: hist:keys=skbaddr.hex:vals=hitcount,len:sort=hitcount:size=2048 if len > 4096 [active] -+ # -+ -+ { skbaddr: ffff88009fd2c300 } hitcount: 1 len: 7212 -+ { skbaddr: ffff8800d2bcce00 } hitcount: 1 len: 7212 -+ { skbaddr: ffff8800d2bcd700 } hitcount: 1 len: 7212 -+ { skbaddr: ffff8800d2bcda00 } hitcount: 1 len: 21492 -+ { skbaddr: ffff8800ae2e2d00 } hitcount: 1 len: 7212 -+ { skbaddr: ffff8800d2bcdb00 } hitcount: 1 len: 7212 -+ { skbaddr: ffff88006a4df500 } hitcount: 1 len: 4854 -+ { skbaddr: ffff88008ce47b00 } hitcount: 1 len: 18636 -+ { skbaddr: ffff8800ae2e2200 } hitcount: 1 len: 12924 -+ { skbaddr: ffff88005f3e1000 } hitcount: 1 len: 4356 -+ { skbaddr: ffff8800d2bcdc00 } hitcount: 2 len: 24420 -+ { skbaddr: ffff8800d2bcc200 } hitcount: 2 len: 12996 -+ -+ Totals: -+ Hits: 14 -+ Entries: 12 -+ Dropped: 0 -+ -+ -+ # event histogram -+ # -+ # trigger info: hist:keys=skbaddr.hex:vals=hitcount,len:sort=hitcount:size=2048 if len < 0 [active] -+ # -+ -+ -+ Totals: -+ Hits: 0 -+ Entries: 0 -+ Dropped: 0 -+ -+ Named triggers can be used to have triggers share a common set of -+ histogram data. This capability is mostly useful for combining the -+ output of events generated by tracepoints contained inside inline -+ functions, but names can be used in a hist trigger on any event. -+ For example, these two triggers when hit will update the same 'len' -+ field in the shared 'foo' histogram data: -+ -+ # echo 'hist:name=foo:keys=skbaddr.hex:vals=len' > \ -+ /sys/kernel/debug/tracing/events/net/netif_receive_skb/trigger -+ # echo 'hist:name=foo:keys=skbaddr.hex:vals=len' > \ -+ /sys/kernel/debug/tracing/events/net/netif_rx/trigger -+ -+ You can see that they're updating common histogram data by reading -+ each event's hist files at the same time: -+ -+ # cat /sys/kernel/debug/tracing/events/net/netif_receive_skb/hist; -+ cat /sys/kernel/debug/tracing/events/net/netif_rx/hist -+ -+ # event histogram -+ # -+ # trigger info: hist:name=foo:keys=skbaddr.hex:vals=hitcount,len:sort=hitcount:size=2048 [active] -+ # -+ -+ { skbaddr: ffff88000ad53500 } hitcount: 1 len: 46 -+ { skbaddr: ffff8800af5a1500 } hitcount: 1 len: 76 -+ { skbaddr: ffff8800d62a1900 } hitcount: 1 len: 46 -+ { skbaddr: ffff8800d2bccb00 } hitcount: 1 len: 468 -+ { skbaddr: ffff8800d3c69900 } hitcount: 1 len: 46 -+ { skbaddr: ffff88009ff09100 } hitcount: 1 len: 52 -+ { skbaddr: ffff88010f13ab00 } hitcount: 1 len: 168 -+ { skbaddr: ffff88006a54f400 } hitcount: 1 len: 46 -+ { skbaddr: ffff8800d2bcc500 } hitcount: 1 len: 260 -+ { skbaddr: ffff880064505000 } hitcount: 1 len: 46 -+ { skbaddr: ffff8800baf24e00 } hitcount: 1 len: 32 -+ { skbaddr: ffff88009fe0ad00 } hitcount: 1 len: 46 -+ { skbaddr: ffff8800d3edff00 } hitcount: 1 len: 44 -+ { skbaddr: ffff88009fe0b400 } hitcount: 1 len: 168 -+ { skbaddr: ffff8800a1c55a00 } hitcount: 1 len: 40 -+ { skbaddr: ffff8800d2bcd100 } hitcount: 1 len: 40 -+ { skbaddr: ffff880064505f00 } hitcount: 1 len: 174 -+ { skbaddr: ffff8800a8bff200 } hitcount: 1 len: 160 -+ { skbaddr: ffff880044e3cc00 } hitcount: 1 len: 76 -+ { skbaddr: ffff8800a8bfe700 } hitcount: 1 len: 46 -+ { skbaddr: ffff8800d2bcdc00 } hitcount: 1 len: 32 -+ { skbaddr: ffff8800a1f64800 } hitcount: 1 len: 46 -+ { skbaddr: ffff8800d2bcde00 } hitcount: 1 len: 988 -+ { skbaddr: ffff88006a5dea00 } hitcount: 1 len: 46 -+ { skbaddr: ffff88002e37a200 } hitcount: 1 len: 44 -+ { skbaddr: ffff8800a1f32c00 } hitcount: 2 len: 676 -+ { skbaddr: ffff88000ad52600 } hitcount: 2 len: 107 -+ { skbaddr: ffff8800a1f91e00 } hitcount: 2 len: 92 -+ { skbaddr: ffff8800af5a0200 } hitcount: 2 len: 142 -+ { skbaddr: ffff8800d2bcc600 } hitcount: 2 len: 220 -+ { skbaddr: ffff8800ba36f500 } hitcount: 2 len: 92 -+ { skbaddr: ffff8800d021f800 } hitcount: 2 len: 92 -+ { skbaddr: ffff8800a1f33600 } hitcount: 2 len: 675 -+ { skbaddr: ffff8800a8bfff00 } hitcount: 3 len: 138 -+ { skbaddr: ffff8800d62a1300 } hitcount: 3 len: 138 -+ { skbaddr: ffff88002e37a100 } hitcount: 4 len: 184 -+ { skbaddr: ffff880064504400 } hitcount: 4 len: 184 -+ { skbaddr: ffff8800a8bfec00 } hitcount: 4 len: 184 -+ { skbaddr: ffff88000ad53700 } hitcount: 5 len: 230 -+ { skbaddr: ffff8800d2bcdb00 } hitcount: 5 len: 196 -+ { skbaddr: ffff8800a1f90000 } hitcount: 6 len: 276 -+ { skbaddr: ffff88006a54f900 } hitcount: 6 len: 276 -+ -+ Totals: -+ Hits: 81 -+ Entries: 42 -+ Dropped: 0 -+ # event histogram -+ # -+ # trigger info: hist:name=foo:keys=skbaddr.hex:vals=hitcount,len:sort=hitcount:size=2048 [active] -+ # -+ -+ { skbaddr: ffff88000ad53500 } hitcount: 1 len: 46 -+ { skbaddr: ffff8800af5a1500 } hitcount: 1 len: 76 -+ { skbaddr: ffff8800d62a1900 } hitcount: 1 len: 46 -+ { skbaddr: ffff8800d2bccb00 } hitcount: 1 len: 468 -+ { skbaddr: ffff8800d3c69900 } hitcount: 1 len: 46 -+ { skbaddr: ffff88009ff09100 } hitcount: 1 len: 52 -+ { skbaddr: ffff88010f13ab00 } hitcount: 1 len: 168 -+ { skbaddr: ffff88006a54f400 } hitcount: 1 len: 46 -+ { skbaddr: ffff8800d2bcc500 } hitcount: 1 len: 260 -+ { skbaddr: ffff880064505000 } hitcount: 1 len: 46 -+ { skbaddr: ffff8800baf24e00 } hitcount: 1 len: 32 -+ { skbaddr: ffff88009fe0ad00 } hitcount: 1 len: 46 -+ { skbaddr: ffff8800d3edff00 } hitcount: 1 len: 44 -+ { skbaddr: ffff88009fe0b400 } hitcount: 1 len: 168 -+ { skbaddr: ffff8800a1c55a00 } hitcount: 1 len: 40 -+ { skbaddr: ffff8800d2bcd100 } hitcount: 1 len: 40 -+ { skbaddr: ffff880064505f00 } hitcount: 1 len: 174 -+ { skbaddr: ffff8800a8bff200 } hitcount: 1 len: 160 -+ { skbaddr: ffff880044e3cc00 } hitcount: 1 len: 76 -+ { skbaddr: ffff8800a8bfe700 } hitcount: 1 len: 46 -+ { skbaddr: ffff8800d2bcdc00 } hitcount: 1 len: 32 -+ { skbaddr: ffff8800a1f64800 } hitcount: 1 len: 46 -+ { skbaddr: ffff8800d2bcde00 } hitcount: 1 len: 988 -+ { skbaddr: ffff88006a5dea00 } hitcount: 1 len: 46 -+ { skbaddr: ffff88002e37a200 } hitcount: 1 len: 44 -+ { skbaddr: ffff8800a1f32c00 } hitcount: 2 len: 676 -+ { skbaddr: ffff88000ad52600 } hitcount: 2 len: 107 -+ { skbaddr: ffff8800a1f91e00 } hitcount: 2 len: 92 -+ { skbaddr: ffff8800af5a0200 } hitcount: 2 len: 142 -+ { skbaddr: ffff8800d2bcc600 } hitcount: 2 len: 220 -+ { skbaddr: ffff8800ba36f500 } hitcount: 2 len: 92 -+ { skbaddr: ffff8800d021f800 } hitcount: 2 len: 92 -+ { skbaddr: ffff8800a1f33600 } hitcount: 2 len: 675 -+ { skbaddr: ffff8800a8bfff00 } hitcount: 3 len: 138 -+ { skbaddr: ffff8800d62a1300 } hitcount: 3 len: 138 -+ { skbaddr: ffff88002e37a100 } hitcount: 4 len: 184 -+ { skbaddr: ffff880064504400 } hitcount: 4 len: 184 -+ { skbaddr: ffff8800a8bfec00 } hitcount: 4 len: 184 -+ { skbaddr: ffff88000ad53700 } hitcount: 5 len: 230 -+ { skbaddr: ffff8800d2bcdb00 } hitcount: 5 len: 196 -+ { skbaddr: ffff8800a1f90000 } hitcount: 6 len: 276 -+ { skbaddr: ffff88006a54f900 } hitcount: 6 len: 276 -+ -+ Totals: -+ Hits: 81 -+ Entries: 42 -+ Dropped: 0 -+ -+ And here's an example that shows how to combine histogram data from -+ any two events even if they don't share any 'compatible' fields -+ other than 'hitcount' and 'stacktrace'. These commands create a -+ couple of triggers named 'bar' using those fields: -+ -+ # echo 'hist:name=bar:key=stacktrace:val=hitcount' > \ -+ /sys/kernel/debug/tracing/events/sched/sched_process_fork/trigger -+ # echo 'hist:name=bar:key=stacktrace:val=hitcount' > \ -+ /sys/kernel/debug/tracing/events/net/netif_rx/trigger -+ -+ And displaying the output of either shows some interesting if -+ somewhat confusing output: -+ -+ # cat /sys/kernel/debug/tracing/events/sched/sched_process_fork/hist -+ # cat /sys/kernel/debug/tracing/events/net/netif_rx/hist -+ -+ # event histogram -+ # -+ # trigger info: hist:name=bar:keys=stacktrace:vals=hitcount:sort=hitcount:size=2048 [active] -+ # -+ -+ { stacktrace: -+ _do_fork+0x18e/0x330 -+ kernel_thread+0x29/0x30 -+ kthreadd+0x154/0x1b0 -+ ret_from_fork+0x3f/0x70 -+ } hitcount: 1 -+ { stacktrace: -+ netif_rx_internal+0xb2/0xd0 -+ netif_rx_ni+0x20/0x70 -+ dev_loopback_xmit+0xaa/0xd0 -+ ip_mc_output+0x126/0x240 -+ ip_local_out_sk+0x31/0x40 -+ igmp_send_report+0x1e9/0x230 -+ igmp_timer_expire+0xe9/0x120 -+ call_timer_fn+0x39/0xf0 -+ run_timer_softirq+0x1e1/0x290 -+ __do_softirq+0xfd/0x290 -+ irq_exit+0x98/0xb0 -+ smp_apic_timer_interrupt+0x4a/0x60 -+ apic_timer_interrupt+0x6d/0x80 -+ cpuidle_enter+0x17/0x20 -+ call_cpuidle+0x3b/0x60 -+ cpu_startup_entry+0x22d/0x310 -+ } hitcount: 1 -+ { stacktrace: -+ netif_rx_internal+0xb2/0xd0 -+ netif_rx_ni+0x20/0x70 -+ dev_loopback_xmit+0xaa/0xd0 -+ ip_mc_output+0x17f/0x240 -+ ip_local_out_sk+0x31/0x40 -+ ip_send_skb+0x1a/0x50 -+ udp_send_skb+0x13e/0x270 -+ udp_sendmsg+0x2bf/0x980 -+ inet_sendmsg+0x67/0xa0 -+ sock_sendmsg+0x38/0x50 -+ SYSC_sendto+0xef/0x170 -+ SyS_sendto+0xe/0x10 -+ entry_SYSCALL_64_fastpath+0x12/0x6a -+ } hitcount: 2 -+ { stacktrace: -+ netif_rx_internal+0xb2/0xd0 -+ netif_rx+0x1c/0x60 -+ loopback_xmit+0x6c/0xb0 -+ dev_hard_start_xmit+0x219/0x3a0 -+ __dev_queue_xmit+0x415/0x4f0 -+ dev_queue_xmit_sk+0x13/0x20 -+ ip_finish_output2+0x237/0x340 -+ ip_finish_output+0x113/0x1d0 -+ ip_output+0x66/0xc0 -+ ip_local_out_sk+0x31/0x40 -+ ip_send_skb+0x1a/0x50 -+ udp_send_skb+0x16d/0x270 -+ udp_sendmsg+0x2bf/0x980 -+ inet_sendmsg+0x67/0xa0 -+ sock_sendmsg+0x38/0x50 -+ ___sys_sendmsg+0x14e/0x270 -+ } hitcount: 76 -+ { stacktrace: -+ netif_rx_internal+0xb2/0xd0 -+ netif_rx+0x1c/0x60 -+ loopback_xmit+0x6c/0xb0 -+ dev_hard_start_xmit+0x219/0x3a0 -+ __dev_queue_xmit+0x415/0x4f0 -+ dev_queue_xmit_sk+0x13/0x20 -+ ip_finish_output2+0x237/0x340 -+ ip_finish_output+0x113/0x1d0 -+ ip_output+0x66/0xc0 -+ ip_local_out_sk+0x31/0x40 -+ ip_send_skb+0x1a/0x50 -+ udp_send_skb+0x16d/0x270 -+ udp_sendmsg+0x2bf/0x980 -+ inet_sendmsg+0x67/0xa0 -+ sock_sendmsg+0x38/0x50 -+ ___sys_sendmsg+0x269/0x270 -+ } hitcount: 77 -+ { stacktrace: -+ netif_rx_internal+0xb2/0xd0 -+ netif_rx+0x1c/0x60 -+ loopback_xmit+0x6c/0xb0 -+ dev_hard_start_xmit+0x219/0x3a0 -+ __dev_queue_xmit+0x415/0x4f0 -+ dev_queue_xmit_sk+0x13/0x20 -+ ip_finish_output2+0x237/0x340 -+ ip_finish_output+0x113/0x1d0 -+ ip_output+0x66/0xc0 -+ ip_local_out_sk+0x31/0x40 -+ ip_send_skb+0x1a/0x50 -+ udp_send_skb+0x16d/0x270 -+ udp_sendmsg+0x2bf/0x980 -+ inet_sendmsg+0x67/0xa0 -+ sock_sendmsg+0x38/0x50 -+ SYSC_sendto+0xef/0x170 -+ } hitcount: 88 -+ { stacktrace: -+ _do_fork+0x18e/0x330 -+ SyS_clone+0x19/0x20 -+ entry_SYSCALL_64_fastpath+0x12/0x6a -+ } hitcount: 244 -+ -+ Totals: -+ Hits: 489 -+ Entries: 7 -+ Dropped: 0 --- -2.19.2 - diff --git a/kernel/patches-4.14.x-rt/0079-tracing-Add-Documentation-for-log2-modifier.patch b/kernel/patches-4.14.x-rt/0079-tracing-Add-Documentation-for-log2-modifier.patch deleted file mode 100644 index 7ee64c377..000000000 --- a/kernel/patches-4.14.x-rt/0079-tracing-Add-Documentation-for-log2-modifier.patch +++ /dev/null @@ -1,33 +0,0 @@ -From cdc25f0d6e106121a6dd599495ad7f00f766ca49 Mon Sep 17 00:00:00 2001 -From: Tom Zanussi -Date: Mon, 15 Jan 2018 20:51:36 -0600 -Subject: [PATCH 079/450] tracing: Add Documentation for log2 modifier - -Add a line for the log2 modifier, to keep it aligned with -tracing/README. - -Link: http://lkml.kernel.org/r/a419028bccab155749a4b8702d5b97af75f1578f.1516069914.git.tom.zanussi@linux.intel.com - -Signed-off-by: Tom Zanussi -Signed-off-by: Steven Rostedt (VMware) -(cherry picked from commit fcb5b95a2bb931f8e72e2dbd2def67382dd99d42) -Signed-off-by: Sebastian Andrzej Siewior ---- - Documentation/trace/histogram.txt | 1 + - 1 file changed, 1 insertion(+) - -diff --git a/Documentation/trace/histogram.txt b/Documentation/trace/histogram.txt -index b2145f44b190..a4143f04a097 100644 ---- a/Documentation/trace/histogram.txt -+++ b/Documentation/trace/histogram.txt -@@ -73,6 +73,7 @@ - .sym-offset display an address as a symbol and offset - .syscall display a syscall id as a system call name - .execname display a common_pid as a program name -+ .log2 display log2 value rather than raw number - - Note that in general the semantics of a given field aren't - interpreted when applying a modifier to it, but there are some --- -2.19.2 - diff --git a/kernel/patches-4.14.x-rt/0080-tracing-Add-support-to-detect-and-avoid-duplicates.patch b/kernel/patches-4.14.x-rt/0080-tracing-Add-support-to-detect-and-avoid-duplicates.patch deleted file mode 100644 index e72e930b0..000000000 --- a/kernel/patches-4.14.x-rt/0080-tracing-Add-support-to-detect-and-avoid-duplicates.patch +++ /dev/null @@ -1,124 +0,0 @@ -From d8196bc0e2751a637e8eacbbd15ae20322b2b74d Mon Sep 17 00:00:00 2001 -From: Vedang Patel -Date: Mon, 15 Jan 2018 20:51:37 -0600 -Subject: [PATCH 080/450] tracing: Add support to detect and avoid duplicates - -A duplicate in the tracing_map hash table is when 2 different entries -have the same key and, as a result, the key_hash. This is possible due -to a race condition in the algorithm. This race condition is inherent to -the algorithm and not a bug. This was fine because, until now, we were -only interested in the sum of all the values related to a particular -key (the duplicates are dealt with in tracing_map_sort_entries()). But, -with the inclusion of variables[1], we are interested in individual -values. So, it will not be clear what value to choose when -there are duplicates. So, the duplicates need to be removed. - -The duplicates can occur in the code in the following scenarios: - -- A thread is in the process of adding a new element. It has -successfully executed cmpxchg() and inserted the key. But, it is still -not done acquiring the trace_map_elt struct, populating it and storing -the pointer to the struct in the value field of tracing_map hash table. -If another thread comes in at this time and wants to add an element with -the same key, it will not see the current element and add a new one. - -- There are multiple threads trying to execute cmpxchg at the same time, -one of the threads will succeed and the others will fail. The ones which -fail will go ahead increment 'idx' and add a new element there creating -a duplicate. - -This patch detects and avoids the first condition by asking the thread -which detects the duplicate to loop one more time. There is also a -possibility of infinite loop if the thread which is trying to insert -goes to sleep indefinitely and the one which is trying to insert a new -element detects a duplicate. Which is why, the thread loops for -map_size iterations before returning NULL. - -The second scenario is avoided by preventing the threads which failed -cmpxchg() from incrementing idx. This way, they will loop -around and check if the thread which succeeded in executing cmpxchg() -had the same key. - -[1] http://lkml.kernel.org/r/cover.1498510759.git.tom.zanussi@linux.intel.com - -Link: http://lkml.kernel.org/r/e178e89ec399240331d383bd5913d649713110f4.1516069914.git.tom.zanussi@linux.intel.com - -Signed-off-by: Vedang Patel -Signed-off-by: Tom Zanussi -Signed-off-by: Steven Rostedt (VMware) -(cherry picked from commit bd0a7ab135d0d0872296c3ae3c4f816a9a4c3dee) -Signed-off-by: Sebastian Andrzej Siewior ---- - kernel/trace/tracing_map.c | 41 +++++++++++++++++++++++++++++++++----- - 1 file changed, 36 insertions(+), 5 deletions(-) - -diff --git a/kernel/trace/tracing_map.c b/kernel/trace/tracing_map.c -index 07e75344725b..b30f3439f27f 100644 ---- a/kernel/trace/tracing_map.c -+++ b/kernel/trace/tracing_map.c -@@ -414,7 +414,9 @@ static inline struct tracing_map_elt * - __tracing_map_insert(struct tracing_map *map, void *key, bool lookup_only) - { - u32 idx, key_hash, test_key; -+ int dup_try = 0; - struct tracing_map_entry *entry; -+ struct tracing_map_elt *val; - - key_hash = jhash(key, map->key_size, 0); - if (key_hash == 0) -@@ -426,11 +428,33 @@ __tracing_map_insert(struct tracing_map *map, void *key, bool lookup_only) - entry = TRACING_MAP_ENTRY(map->map, idx); - test_key = entry->key; - -- if (test_key && test_key == key_hash && entry->val && -- keys_match(key, entry->val->key, map->key_size)) { -- if (!lookup_only) -- atomic64_inc(&map->hits); -- return entry->val; -+ if (test_key && test_key == key_hash) { -+ val = READ_ONCE(entry->val); -+ if (val && -+ keys_match(key, val->key, map->key_size)) { -+ if (!lookup_only) -+ atomic64_inc(&map->hits); -+ return val; -+ } else if (unlikely(!val)) { -+ /* -+ * The key is present. But, val (pointer to elt -+ * struct) is still NULL. which means some other -+ * thread is in the process of inserting an -+ * element. -+ * -+ * On top of that, it's key_hash is same as the -+ * one being inserted right now. So, it's -+ * possible that the element has the same -+ * key as well. -+ */ -+ -+ dup_try++; -+ if (dup_try > map->map_size) { -+ atomic64_inc(&map->drops); -+ break; -+ } -+ continue; -+ } - } - - if (!test_key) { -@@ -452,6 +476,13 @@ __tracing_map_insert(struct tracing_map *map, void *key, bool lookup_only) - atomic64_inc(&map->hits); - - return entry->val; -+ } else { -+ /* -+ * cmpxchg() failed. Loop around once -+ * more to check what key was inserted. -+ */ -+ dup_try++; -+ continue; - } - } - --- -2.19.2 - diff --git a/kernel/patches-4.14.x-rt/0081-tracing-Remove-code-which-merges-duplicates.patch b/kernel/patches-4.14.x-rt/0081-tracing-Remove-code-which-merges-duplicates.patch deleted file mode 100644 index 128d204a9..000000000 --- a/kernel/patches-4.14.x-rt/0081-tracing-Remove-code-which-merges-duplicates.patch +++ /dev/null @@ -1,202 +0,0 @@ -From 6139f982902cdb12bbbf875895de16575c41abc3 Mon Sep 17 00:00:00 2001 -From: Vedang Patel -Date: Mon, 15 Jan 2018 20:51:38 -0600 -Subject: [PATCH 081/450] tracing: Remove code which merges duplicates - -We now have the logic to detect and remove duplicates in the -tracing_map hash table. The code which merges duplicates in the -histogram is redundant now. So, modify this code just to detect -duplicates. The duplication detection code is still kept to ensure -that any rare race condition which might cause duplicates does not go -unnoticed. - -Link: http://lkml.kernel.org/r/55215cf59e2674391bdaf772fdafc4c393352b03.1516069914.git.tom.zanussi@linux.intel.com - -Signed-off-by: Vedang Patel -Signed-off-by: Tom Zanussi -Signed-off-by: Steven Rostedt (VMware) -(cherry picked from commit 3f7f4cc21fc62ff7da7d34b5ca95a69d73a1f764) -Signed-off-by: Sebastian Andrzej Siewior ---- - kernel/trace/trace_events_hist.c | 11 ----- - kernel/trace/tracing_map.c | 83 +++----------------------------- - kernel/trace/tracing_map.h | 7 --- - 3 files changed, 6 insertions(+), 95 deletions(-) - -diff --git a/kernel/trace/trace_events_hist.c b/kernel/trace/trace_events_hist.c -index 4eddc1933079..c57e5369b0c2 100644 ---- a/kernel/trace/trace_events_hist.c -+++ b/kernel/trace/trace_events_hist.c -@@ -340,16 +340,6 @@ static int hist_trigger_elt_comm_alloc(struct tracing_map_elt *elt) - return 0; - } - --static void hist_trigger_elt_comm_copy(struct tracing_map_elt *to, -- struct tracing_map_elt *from) --{ -- char *comm_from = from->private_data; -- char *comm_to = to->private_data; -- -- if (comm_from) -- memcpy(comm_to, comm_from, TASK_COMM_LEN + 1); --} -- - static void hist_trigger_elt_comm_init(struct tracing_map_elt *elt) - { - char *comm = elt->private_data; -@@ -360,7 +350,6 @@ static void hist_trigger_elt_comm_init(struct tracing_map_elt *elt) - - static const struct tracing_map_ops hist_trigger_elt_comm_ops = { - .elt_alloc = hist_trigger_elt_comm_alloc, -- .elt_copy = hist_trigger_elt_comm_copy, - .elt_free = hist_trigger_elt_comm_free, - .elt_init = hist_trigger_elt_comm_init, - }; -diff --git a/kernel/trace/tracing_map.c b/kernel/trace/tracing_map.c -index b30f3439f27f..f47a4d54bcf0 100644 ---- a/kernel/trace/tracing_map.c -+++ b/kernel/trace/tracing_map.c -@@ -847,67 +847,15 @@ create_sort_entry(void *key, struct tracing_map_elt *elt) - return sort_entry; - } - --static struct tracing_map_elt *copy_elt(struct tracing_map_elt *elt) --{ -- struct tracing_map_elt *dup_elt; -- unsigned int i; -- -- dup_elt = tracing_map_elt_alloc(elt->map); -- if (IS_ERR(dup_elt)) -- return NULL; -- -- if (elt->map->ops && elt->map->ops->elt_copy) -- elt->map->ops->elt_copy(dup_elt, elt); -- -- dup_elt->private_data = elt->private_data; -- memcpy(dup_elt->key, elt->key, elt->map->key_size); -- -- for (i = 0; i < elt->map->n_fields; i++) { -- atomic64_set(&dup_elt->fields[i].sum, -- atomic64_read(&elt->fields[i].sum)); -- dup_elt->fields[i].cmp_fn = elt->fields[i].cmp_fn; -- } -- -- return dup_elt; --} -- --static int merge_dup(struct tracing_map_sort_entry **sort_entries, -- unsigned int target, unsigned int dup) --{ -- struct tracing_map_elt *target_elt, *elt; -- bool first_dup = (target - dup) == 1; -- int i; -- -- if (first_dup) { -- elt = sort_entries[target]->elt; -- target_elt = copy_elt(elt); -- if (!target_elt) -- return -ENOMEM; -- sort_entries[target]->elt = target_elt; -- sort_entries[target]->elt_copied = true; -- } else -- target_elt = sort_entries[target]->elt; -- -- elt = sort_entries[dup]->elt; -- -- for (i = 0; i < elt->map->n_fields; i++) -- atomic64_add(atomic64_read(&elt->fields[i].sum), -- &target_elt->fields[i].sum); -- -- sort_entries[dup]->dup = true; -- -- return 0; --} -- --static int merge_dups(struct tracing_map_sort_entry **sort_entries, -+static void detect_dups(struct tracing_map_sort_entry **sort_entries, - int n_entries, unsigned int key_size) - { - unsigned int dups = 0, total_dups = 0; -- int err, i, j; -+ int i; - void *key; - - if (n_entries < 2) -- return total_dups; -+ return; - - sort(sort_entries, n_entries, sizeof(struct tracing_map_sort_entry *), - (int (*)(const void *, const void *))cmp_entries_dup, NULL); -@@ -916,30 +864,14 @@ static int merge_dups(struct tracing_map_sort_entry **sort_entries, - for (i = 1; i < n_entries; i++) { - if (!memcmp(sort_entries[i]->key, key, key_size)) { - dups++; total_dups++; -- err = merge_dup(sort_entries, i - dups, i); -- if (err) -- return err; - continue; - } - key = sort_entries[i]->key; - dups = 0; - } - -- if (!total_dups) -- return total_dups; -- -- for (i = 0, j = 0; i < n_entries; i++) { -- if (!sort_entries[i]->dup) { -- sort_entries[j] = sort_entries[i]; -- if (j++ != i) -- sort_entries[i] = NULL; -- } else { -- destroy_sort_entry(sort_entries[i]); -- sort_entries[i] = NULL; -- } -- } -- -- return total_dups; -+ WARN_ONCE(total_dups > 0, -+ "Duplicates detected: %d\n", total_dups); - } - - static bool is_key(struct tracing_map *map, unsigned int field_idx) -@@ -1065,10 +997,7 @@ int tracing_map_sort_entries(struct tracing_map *map, - return 1; - } - -- ret = merge_dups(entries, n_entries, map->key_size); -- if (ret < 0) -- goto free; -- n_entries -= ret; -+ detect_dups(entries, n_entries, map->key_size); - - if (is_key(map, sort_keys[0].field_idx)) - cmp_entries_fn = cmp_entries_key; -diff --git a/kernel/trace/tracing_map.h b/kernel/trace/tracing_map.h -index 5b5bbf8ae550..de57887c0670 100644 ---- a/kernel/trace/tracing_map.h -+++ b/kernel/trace/tracing_map.h -@@ -215,11 +215,6 @@ struct tracing_map { - * Element allocation occurs before tracing begins, when the - * tracing_map_init() call is made by client code. - * -- * @elt_copy: At certain points in the lifetime of an element, it may -- * need to be copied. The copy should include a copy of the -- * client-allocated data, which can be copied into the 'to' -- * element from the 'from' element. -- * - * @elt_free: When a tracing_map_elt is freed, this function is called - * and allows client-allocated per-element data to be freed. - * -@@ -233,8 +228,6 @@ struct tracing_map { - */ - struct tracing_map_ops { - int (*elt_alloc)(struct tracing_map_elt *elt); -- void (*elt_copy)(struct tracing_map_elt *to, -- struct tracing_map_elt *from); - void (*elt_free)(struct tracing_map_elt *elt); - void (*elt_clear)(struct tracing_map_elt *elt); - void (*elt_init)(struct tracing_map_elt *elt); --- -2.19.2 - diff --git a/kernel/patches-4.14.x-rt/0082-ring-buffer-Add-interface-for-setting-absolute-time-.patch b/kernel/patches-4.14.x-rt/0082-ring-buffer-Add-interface-for-setting-absolute-time-.patch deleted file mode 100644 index 2e58a2373..000000000 --- a/kernel/patches-4.14.x-rt/0082-ring-buffer-Add-interface-for-setting-absolute-time-.patch +++ /dev/null @@ -1,144 +0,0 @@ -From 582fb702bc2b0544b208b2a5990dadf00da3e486 Mon Sep 17 00:00:00 2001 -From: Tom Zanussi -Date: Mon, 15 Jan 2018 20:51:39 -0600 -Subject: [PATCH 082/450] ring-buffer: Add interface for setting absolute time - stamps - -Define a new function, tracing_set_time_stamp_abs(), which can be used -to enable or disable the use of absolute timestamps rather than time -deltas for a trace array. - -Only the interface is added here; a subsequent patch will add the -underlying implementation. - -Link: http://lkml.kernel.org/r/ce96119de44c7fe0ee44786d15254e9b493040d3.1516069914.git.tom.zanussi@linux.intel.com - -Signed-off-by: Tom Zanussi -Signed-off-by: Baohong Liu -Signed-off-by: Steven Rostedt (VMware) -(cherry picked from commit 22753475c5232cd6f024746d6a6696a4dd2683ab) -Signed-off-by: Sebastian Andrzej Siewior ---- - include/linux/ring_buffer.h | 2 ++ - kernel/trace/ring_buffer.c | 11 +++++++++++ - kernel/trace/trace.c | 33 ++++++++++++++++++++++++++++++++- - kernel/trace/trace.h | 3 +++ - 4 files changed, 48 insertions(+), 1 deletion(-) - -diff --git a/include/linux/ring_buffer.h b/include/linux/ring_buffer.h -index 5caa062a02b2..adffb56bae8f 100644 ---- a/include/linux/ring_buffer.h -+++ b/include/linux/ring_buffer.h -@@ -179,6 +179,8 @@ void ring_buffer_normalize_time_stamp(struct ring_buffer *buffer, - int cpu, u64 *ts); - void ring_buffer_set_clock(struct ring_buffer *buffer, - u64 (*clock)(void)); -+void ring_buffer_set_time_stamp_abs(struct ring_buffer *buffer, bool abs); -+bool ring_buffer_time_stamp_abs(struct ring_buffer *buffer); - - size_t ring_buffer_page_len(void *page); - -diff --git a/kernel/trace/ring_buffer.c b/kernel/trace/ring_buffer.c -index ade8493cb69f..c74b329879ad 100644 ---- a/kernel/trace/ring_buffer.c -+++ b/kernel/trace/ring_buffer.c -@@ -488,6 +488,7 @@ struct ring_buffer { - u64 (*clock)(void); - - struct rb_irq_work irq_work; -+ bool time_stamp_abs; - }; - - struct ring_buffer_iter { -@@ -1387,6 +1388,16 @@ void ring_buffer_set_clock(struct ring_buffer *buffer, - buffer->clock = clock; - } - -+void ring_buffer_set_time_stamp_abs(struct ring_buffer *buffer, bool abs) -+{ -+ buffer->time_stamp_abs = abs; -+} -+ -+bool ring_buffer_time_stamp_abs(struct ring_buffer *buffer) -+{ -+ return buffer->time_stamp_abs; -+} -+ - static void rb_reset_cpu(struct ring_buffer_per_cpu *cpu_buffer); - - static inline unsigned long rb_page_entries(struct buffer_page *bpage) -diff --git a/kernel/trace/trace.c b/kernel/trace/trace.c -index f3d7c259e424..ffb67272b642 100644 ---- a/kernel/trace/trace.c -+++ b/kernel/trace/trace.c -@@ -2275,7 +2275,7 @@ trace_event_buffer_lock_reserve(struct ring_buffer **current_rb, - - *current_rb = trace_file->tr->trace_buffer.buffer; - -- if ((trace_file->flags & -+ if (!ring_buffer_time_stamp_abs(*current_rb) && (trace_file->flags & - (EVENT_FILE_FL_SOFT_DISABLED | EVENT_FILE_FL_FILTERED)) && - (entry = this_cpu_read(trace_buffered_event))) { - /* Try to use the per cpu buffer first */ -@@ -6298,6 +6298,37 @@ static int tracing_clock_open(struct inode *inode, struct file *file) - return ret; - } - -+int tracing_set_time_stamp_abs(struct trace_array *tr, bool abs) -+{ -+ int ret = 0; -+ -+ mutex_lock(&trace_types_lock); -+ -+ if (abs && tr->time_stamp_abs_ref++) -+ goto out; -+ -+ if (!abs) { -+ if (WARN_ON_ONCE(!tr->time_stamp_abs_ref)) { -+ ret = -EINVAL; -+ goto out; -+ } -+ -+ if (--tr->time_stamp_abs_ref) -+ goto out; -+ } -+ -+ ring_buffer_set_time_stamp_abs(tr->trace_buffer.buffer, abs); -+ -+#ifdef CONFIG_TRACER_MAX_TRACE -+ if (tr->max_buffer.buffer) -+ ring_buffer_set_time_stamp_abs(tr->max_buffer.buffer, abs); -+#endif -+ out: -+ mutex_unlock(&trace_types_lock); -+ -+ return ret; -+} -+ - struct ftrace_buffer_info { - struct trace_iterator iter; - void *spare; -diff --git a/kernel/trace/trace.h b/kernel/trace/trace.h -index 221591636530..0506c4cdfeba 100644 ---- a/kernel/trace/trace.h -+++ b/kernel/trace/trace.h -@@ -273,6 +273,7 @@ struct trace_array { - /* function tracing enabled */ - int function_enabled; - #endif -+ int time_stamp_abs_ref; - }; - - enum { -@@ -286,6 +287,8 @@ extern struct mutex trace_types_lock; - extern int trace_array_get(struct trace_array *tr); - extern void trace_array_put(struct trace_array *tr); - -+extern int tracing_set_time_stamp_abs(struct trace_array *tr, bool abs); -+ - /* - * The global tracer (top) should be the first trace array added, - * but we check the flag anyway. --- -2.19.2 - diff --git a/kernel/patches-4.14.x-rt/0083-ring-buffer-Redefine-the-unimplemented-RINGBUF_TYPE_.patch b/kernel/patches-4.14.x-rt/0083-ring-buffer-Redefine-the-unimplemented-RINGBUF_TYPE_.patch deleted file mode 100644 index 50723a5c3..000000000 --- a/kernel/patches-4.14.x-rt/0083-ring-buffer-Redefine-the-unimplemented-RINGBUF_TYPE_.patch +++ /dev/null @@ -1,330 +0,0 @@ -From 64d14090ceefe8b55ecdcb0d3543fec1d830920c Mon Sep 17 00:00:00 2001 -From: Tom Zanussi -Date: Mon, 15 Jan 2018 20:51:40 -0600 -Subject: [PATCH 083/450] ring-buffer: Redefine the unimplemented - RINGBUF_TYPE_TIME_STAMP - -RINGBUF_TYPE_TIME_STAMP is defined but not used, and from what I can -gather was reserved for something like an absolute timestamp feature -for the ring buffer, if not a complete replacement of the current -time_delta scheme. - -This code redefines RINGBUF_TYPE_TIME_STAMP to implement absolute time -stamps. Another way to look at it is that it essentially forces -extended time_deltas for all events. - -The motivation for doing this is to enable time_deltas that aren't -dependent on previous events in the ring buffer, making it feasible to -use the ring_buffer_event timetamps in a more random-access way, for -purposes other than serial event printing. - -To set/reset this mode, use tracing_set_timestamp_abs() from the -previous interface patch. - -Link: http://lkml.kernel.org/r/477b362dba1ce7fab9889a1a8e885a62c472f041.1516069914.git.tom.zanussi@linux.intel.com - -Signed-off-by: Tom Zanussi -Signed-off-by: Steven Rostedt (VMware) -(cherry picked from commit 58c0bd803060b0c0c9de8751382a7af5f507d74d) -Signed-off-by: Sebastian Andrzej Siewior ---- - include/linux/ring_buffer.h | 12 +++-- - kernel/trace/ring_buffer.c | 104 ++++++++++++++++++++++++++---------- - 2 files changed, 83 insertions(+), 33 deletions(-) - -diff --git a/include/linux/ring_buffer.h b/include/linux/ring_buffer.h -index adffb56bae8f..6c2a6b3f3c6d 100644 ---- a/include/linux/ring_buffer.h -+++ b/include/linux/ring_buffer.h -@@ -34,10 +34,12 @@ struct ring_buffer_event { - * array[0] = time delta (28 .. 59) - * size = 8 bytes - * -- * @RINGBUF_TYPE_TIME_STAMP: Sync time stamp with external clock -- * array[0] = tv_nsec -- * array[1..2] = tv_sec -- * size = 16 bytes -+ * @RINGBUF_TYPE_TIME_STAMP: Absolute timestamp -+ * Same format as TIME_EXTEND except that the -+ * value is an absolute timestamp, not a delta -+ * event.time_delta contains bottom 27 bits -+ * array[0] = top (28 .. 59) bits -+ * size = 8 bytes - * - * <= @RINGBUF_TYPE_DATA_TYPE_LEN_MAX: - * Data record -@@ -54,12 +56,12 @@ enum ring_buffer_type { - RINGBUF_TYPE_DATA_TYPE_LEN_MAX = 28, - RINGBUF_TYPE_PADDING, - RINGBUF_TYPE_TIME_EXTEND, -- /* FIXME: RINGBUF_TYPE_TIME_STAMP not implemented */ - RINGBUF_TYPE_TIME_STAMP, - }; - - unsigned ring_buffer_event_length(struct ring_buffer_event *event); - void *ring_buffer_event_data(struct ring_buffer_event *event); -+u64 ring_buffer_event_time_stamp(struct ring_buffer_event *event); - - /* - * ring_buffer_discard_commit will remove an event that has not -diff --git a/kernel/trace/ring_buffer.c b/kernel/trace/ring_buffer.c -index c74b329879ad..197617001c0b 100644 ---- a/kernel/trace/ring_buffer.c -+++ b/kernel/trace/ring_buffer.c -@@ -41,6 +41,8 @@ int ring_buffer_print_entry_header(struct trace_seq *s) - RINGBUF_TYPE_PADDING); - trace_seq_printf(s, "\ttime_extend : type == %d\n", - RINGBUF_TYPE_TIME_EXTEND); -+ trace_seq_printf(s, "\ttime_stamp : type == %d\n", -+ RINGBUF_TYPE_TIME_STAMP); - trace_seq_printf(s, "\tdata max type_len == %d\n", - RINGBUF_TYPE_DATA_TYPE_LEN_MAX); - -@@ -140,12 +142,15 @@ int ring_buffer_print_entry_header(struct trace_seq *s) - - enum { - RB_LEN_TIME_EXTEND = 8, -- RB_LEN_TIME_STAMP = 16, -+ RB_LEN_TIME_STAMP = 8, - }; - - #define skip_time_extend(event) \ - ((struct ring_buffer_event *)((char *)event + RB_LEN_TIME_EXTEND)) - -+#define extended_time(event) \ -+ (event->type_len >= RINGBUF_TYPE_TIME_EXTEND) -+ - static inline int rb_null_event(struct ring_buffer_event *event) - { - return event->type_len == RINGBUF_TYPE_PADDING && !event->time_delta; -@@ -209,7 +214,7 @@ rb_event_ts_length(struct ring_buffer_event *event) - { - unsigned len = 0; - -- if (event->type_len == RINGBUF_TYPE_TIME_EXTEND) { -+ if (extended_time(event)) { - /* time extends include the data event after it */ - len = RB_LEN_TIME_EXTEND; - event = skip_time_extend(event); -@@ -231,7 +236,7 @@ unsigned ring_buffer_event_length(struct ring_buffer_event *event) - { - unsigned length; - -- if (event->type_len == RINGBUF_TYPE_TIME_EXTEND) -+ if (extended_time(event)) - event = skip_time_extend(event); - - length = rb_event_length(event); -@@ -248,7 +253,7 @@ EXPORT_SYMBOL_GPL(ring_buffer_event_length); - static __always_inline void * - rb_event_data(struct ring_buffer_event *event) - { -- if (event->type_len == RINGBUF_TYPE_TIME_EXTEND) -+ if (extended_time(event)) - event = skip_time_extend(event); - BUG_ON(event->type_len > RINGBUF_TYPE_DATA_TYPE_LEN_MAX); - /* If length is in len field, then array[0] has the data */ -@@ -275,6 +280,27 @@ EXPORT_SYMBOL_GPL(ring_buffer_event_data); - #define TS_MASK ((1ULL << TS_SHIFT) - 1) - #define TS_DELTA_TEST (~TS_MASK) - -+/** -+ * ring_buffer_event_time_stamp - return the event's extended timestamp -+ * @event: the event to get the timestamp of -+ * -+ * Returns the extended timestamp associated with a data event. -+ * An extended time_stamp is a 64-bit timestamp represented -+ * internally in a special way that makes the best use of space -+ * contained within a ring buffer event. This function decodes -+ * it and maps it to a straight u64 value. -+ */ -+u64 ring_buffer_event_time_stamp(struct ring_buffer_event *event) -+{ -+ u64 ts; -+ -+ ts = event->array[0]; -+ ts <<= TS_SHIFT; -+ ts += event->time_delta; -+ -+ return ts; -+} -+ - /* Flag when events were overwritten */ - #define RB_MISSED_EVENTS (1 << 31) - /* Missed count stored at end */ -@@ -2230,12 +2256,15 @@ rb_move_tail(struct ring_buffer_per_cpu *cpu_buffer, - - /* Slow path, do not inline */ - static noinline struct ring_buffer_event * --rb_add_time_stamp(struct ring_buffer_event *event, u64 delta) -+rb_add_time_stamp(struct ring_buffer_event *event, u64 delta, bool abs) - { -- event->type_len = RINGBUF_TYPE_TIME_EXTEND; -+ if (abs) -+ event->type_len = RINGBUF_TYPE_TIME_STAMP; -+ else -+ event->type_len = RINGBUF_TYPE_TIME_EXTEND; - -- /* Not the first event on the page? */ -- if (rb_event_index(event)) { -+ /* Not the first event on the page, or not delta? */ -+ if (abs || rb_event_index(event)) { - event->time_delta = delta & TS_MASK; - event->array[0] = delta >> TS_SHIFT; - } else { -@@ -2278,7 +2307,9 @@ rb_update_event(struct ring_buffer_per_cpu *cpu_buffer, - * add it to the start of the resevered space. - */ - if (unlikely(info->add_timestamp)) { -- event = rb_add_time_stamp(event, delta); -+ bool abs = ring_buffer_time_stamp_abs(cpu_buffer->buffer); -+ -+ event = rb_add_time_stamp(event, info->delta, abs); - length -= RB_LEN_TIME_EXTEND; - delta = 0; - } -@@ -2466,7 +2497,7 @@ static __always_inline void rb_end_commit(struct ring_buffer_per_cpu *cpu_buffer - - static inline void rb_event_discard(struct ring_buffer_event *event) - { -- if (event->type_len == RINGBUF_TYPE_TIME_EXTEND) -+ if (extended_time(event)) - event = skip_time_extend(event); - - /* array[0] holds the actual length for the discarded event */ -@@ -2510,10 +2541,11 @@ rb_update_write_stamp(struct ring_buffer_per_cpu *cpu_buffer, - cpu_buffer->write_stamp = - cpu_buffer->commit_page->page->time_stamp; - else if (event->type_len == RINGBUF_TYPE_TIME_EXTEND) { -- delta = event->array[0]; -- delta <<= TS_SHIFT; -- delta += event->time_delta; -+ delta = ring_buffer_event_time_stamp(event); - cpu_buffer->write_stamp += delta; -+ } else if (event->type_len == RINGBUF_TYPE_TIME_STAMP) { -+ delta = ring_buffer_event_time_stamp(event); -+ cpu_buffer->write_stamp = delta; - } else - cpu_buffer->write_stamp += event->time_delta; - } -@@ -2666,7 +2698,7 @@ __rb_reserve_next(struct ring_buffer_per_cpu *cpu_buffer, - * If this is the first commit on the page, then it has the same - * timestamp as the page itself. - */ -- if (!tail) -+ if (!tail && !ring_buffer_time_stamp_abs(cpu_buffer->buffer)) - info->delta = 0; - - /* See if we shot pass the end of this buffer page */ -@@ -2743,8 +2775,11 @@ rb_reserve_next_event(struct ring_buffer *buffer, - /* make sure this diff is calculated here */ - barrier(); - -- /* Did the write stamp get updated already? */ -- if (likely(info.ts >= cpu_buffer->write_stamp)) { -+ if (ring_buffer_time_stamp_abs(buffer)) { -+ info.delta = info.ts; -+ rb_handle_timestamp(cpu_buffer, &info); -+ } else /* Did the write stamp get updated already? */ -+ if (likely(info.ts >= cpu_buffer->write_stamp)) { - info.delta = diff; - if (unlikely(test_time_stamp(info.delta))) - rb_handle_timestamp(cpu_buffer, &info); -@@ -3442,14 +3477,13 @@ rb_update_read_stamp(struct ring_buffer_per_cpu *cpu_buffer, - return; - - case RINGBUF_TYPE_TIME_EXTEND: -- delta = event->array[0]; -- delta <<= TS_SHIFT; -- delta += event->time_delta; -+ delta = ring_buffer_event_time_stamp(event); - cpu_buffer->read_stamp += delta; - return; - - case RINGBUF_TYPE_TIME_STAMP: -- /* FIXME: not implemented */ -+ delta = ring_buffer_event_time_stamp(event); -+ cpu_buffer->read_stamp = delta; - return; - - case RINGBUF_TYPE_DATA: -@@ -3473,14 +3507,13 @@ rb_update_iter_read_stamp(struct ring_buffer_iter *iter, - return; - - case RINGBUF_TYPE_TIME_EXTEND: -- delta = event->array[0]; -- delta <<= TS_SHIFT; -- delta += event->time_delta; -+ delta = ring_buffer_event_time_stamp(event); - iter->read_stamp += delta; - return; - - case RINGBUF_TYPE_TIME_STAMP: -- /* FIXME: not implemented */ -+ delta = ring_buffer_event_time_stamp(event); -+ iter->read_stamp = delta; - return; - - case RINGBUF_TYPE_DATA: -@@ -3704,6 +3737,8 @@ rb_buffer_peek(struct ring_buffer_per_cpu *cpu_buffer, u64 *ts, - struct buffer_page *reader; - int nr_loops = 0; - -+ if (ts) -+ *ts = 0; - again: - /* - * We repeat when a time extend is encountered. -@@ -3740,12 +3775,17 @@ rb_buffer_peek(struct ring_buffer_per_cpu *cpu_buffer, u64 *ts, - goto again; - - case RINGBUF_TYPE_TIME_STAMP: -- /* FIXME: not implemented */ -+ if (ts) { -+ *ts = ring_buffer_event_time_stamp(event); -+ ring_buffer_normalize_time_stamp(cpu_buffer->buffer, -+ cpu_buffer->cpu, ts); -+ } -+ /* Internal data, OK to advance */ - rb_advance_reader(cpu_buffer); - goto again; - - case RINGBUF_TYPE_DATA: -- if (ts) { -+ if (ts && !(*ts)) { - *ts = cpu_buffer->read_stamp + event->time_delta; - ring_buffer_normalize_time_stamp(cpu_buffer->buffer, - cpu_buffer->cpu, ts); -@@ -3770,6 +3810,9 @@ rb_iter_peek(struct ring_buffer_iter *iter, u64 *ts) - struct ring_buffer_event *event; - int nr_loops = 0; - -+ if (ts) -+ *ts = 0; -+ - cpu_buffer = iter->cpu_buffer; - buffer = cpu_buffer->buffer; - -@@ -3822,12 +3865,17 @@ rb_iter_peek(struct ring_buffer_iter *iter, u64 *ts) - goto again; - - case RINGBUF_TYPE_TIME_STAMP: -- /* FIXME: not implemented */ -+ if (ts) { -+ *ts = ring_buffer_event_time_stamp(event); -+ ring_buffer_normalize_time_stamp(cpu_buffer->buffer, -+ cpu_buffer->cpu, ts); -+ } -+ /* Internal data, OK to advance */ - rb_advance_iter(iter); - goto again; - - case RINGBUF_TYPE_DATA: -- if (ts) { -+ if (ts && !(*ts)) { - *ts = iter->read_stamp + event->time_delta; - ring_buffer_normalize_time_stamp(buffer, - cpu_buffer->cpu, ts); --- -2.19.2 - diff --git a/kernel/patches-4.14.x-rt/0084-tracing-Add-timestamp_mode-trace-file.patch b/kernel/patches-4.14.x-rt/0084-tracing-Add-timestamp_mode-trace-file.patch deleted file mode 100644 index a157eecd8..000000000 --- a/kernel/patches-4.14.x-rt/0084-tracing-Add-timestamp_mode-trace-file.patch +++ /dev/null @@ -1,145 +0,0 @@ -From 78df5faab56e9333581a9b048905776dcb52bb99 Mon Sep 17 00:00:00 2001 -From: Tom Zanussi -Date: Mon, 15 Jan 2018 20:51:41 -0600 -Subject: [PATCH 084/450] tracing: Add timestamp_mode trace file - -Add a new option flag indicating whether or not the ring buffer is in -'absolute timestamp' mode. - -Currently this is only set/unset by hist triggers that make use of a -common_timestamp. As such, there's no reason to make this writeable -for users - its purpose is only to allow users to determine -unequivocally whether or not the ring buffer is in that mode (although -absolute timestamps can coexist with the normal delta timestamps, when -the ring buffer is in absolute mode, timestamps written while absolute -mode is in effect take up more space in the buffer, and are not as -efficient). - -Link: http://lkml.kernel.org/r/e8aa7b1cde1cf15014e66545d06ac6ef2ebba456.1516069914.git.tom.zanussi@linux.intel.com - -Signed-off-by: Tom Zanussi -Signed-off-by: Steven Rostedt (VMware) -(cherry picked from commit 0eba34f9bf5b66217355a6a66054b3194aca123d) -Signed-off-by: Sebastian Andrzej Siewior ---- - Documentation/trace/ftrace.txt | 24 +++++++++++++++++ - kernel/trace/trace.c | 47 ++++++++++++++++++++++++++++++++++ - 2 files changed, 71 insertions(+) - -diff --git a/Documentation/trace/ftrace.txt b/Documentation/trace/ftrace.txt -index d4601df6e72e..54213e5c23f6 100644 ---- a/Documentation/trace/ftrace.txt -+++ b/Documentation/trace/ftrace.txt -@@ -539,6 +539,30 @@ of ftrace. Here is a list of some of the key files: - - See events.txt for more information. - -+ timestamp_mode: -+ -+ Certain tracers may change the timestamp mode used when -+ logging trace events into the event buffer. Events with -+ different modes can coexist within a buffer but the mode in -+ effect when an event is logged determines which timestamp mode -+ is used for that event. The default timestamp mode is -+ 'delta'. -+ -+ Usual timestamp modes for tracing: -+ -+ # cat timestamp_mode -+ [delta] absolute -+ -+ The timestamp mode with the square brackets around it is the -+ one in effect. -+ -+ delta: Default timestamp mode - timestamp is a delta against -+ a per-buffer timestamp. -+ -+ absolute: The timestamp is a full timestamp, not a delta -+ against some other value. As such it takes up more -+ space and is less efficient. -+ - hwlat_detector: - - Directory for the Hardware Latency Detector. -diff --git a/kernel/trace/trace.c b/kernel/trace/trace.c -index ffb67272b642..c358cae7461f 100644 ---- a/kernel/trace/trace.c -+++ b/kernel/trace/trace.c -@@ -4531,6 +4531,9 @@ static const char readme_msg[] = - #ifdef CONFIG_X86_64 - " x86-tsc: TSC cycle counter\n" - #endif -+ "\n timestamp_mode\t-view the mode used to timestamp events\n" -+ " delta: Delta difference against a buffer-wide timestamp\n" -+ " absolute: Absolute (standalone) timestamp\n" - "\n trace_marker\t\t- Writes into this file writes into the kernel buffer\n" - "\n trace_marker_raw\t\t- Writes into this file writes binary data into the kernel buffer\n" - " tracing_cpumask\t- Limit which CPUs to trace\n" -@@ -6298,6 +6301,40 @@ static int tracing_clock_open(struct inode *inode, struct file *file) - return ret; - } - -+static int tracing_time_stamp_mode_show(struct seq_file *m, void *v) -+{ -+ struct trace_array *tr = m->private; -+ -+ mutex_lock(&trace_types_lock); -+ -+ if (ring_buffer_time_stamp_abs(tr->trace_buffer.buffer)) -+ seq_puts(m, "delta [absolute]\n"); -+ else -+ seq_puts(m, "[delta] absolute\n"); -+ -+ mutex_unlock(&trace_types_lock); -+ -+ return 0; -+} -+ -+static int tracing_time_stamp_mode_open(struct inode *inode, struct file *file) -+{ -+ struct trace_array *tr = inode->i_private; -+ int ret; -+ -+ if (tracing_disabled) -+ return -ENODEV; -+ -+ if (trace_array_get(tr)) -+ return -ENODEV; -+ -+ ret = single_open(file, tracing_time_stamp_mode_show, inode->i_private); -+ if (ret < 0) -+ trace_array_put(tr); -+ -+ return ret; -+} -+ - int tracing_set_time_stamp_abs(struct trace_array *tr, bool abs) - { - int ret = 0; -@@ -6576,6 +6613,13 @@ static const struct file_operations trace_clock_fops = { - .write = tracing_clock_write, - }; - -+static const struct file_operations trace_time_stamp_mode_fops = { -+ .open = tracing_time_stamp_mode_open, -+ .read = seq_read, -+ .llseek = seq_lseek, -+ .release = tracing_single_release_tr, -+}; -+ - #ifdef CONFIG_TRACER_SNAPSHOT - static const struct file_operations snapshot_fops = { - .open = tracing_snapshot_open, -@@ -7900,6 +7944,9 @@ init_tracer_tracefs(struct trace_array *tr, struct dentry *d_tracer) - trace_create_file("tracing_on", 0644, d_tracer, - tr, &rb_simple_fops); - -+ trace_create_file("timestamp_mode", 0444, d_tracer, tr, -+ &trace_time_stamp_mode_fops); -+ - create_trace_options_dir(tr); - - #if defined(CONFIG_TRACER_MAX_TRACE) || defined(CONFIG_HWLAT_TRACER) --- -2.19.2 - diff --git a/kernel/patches-4.14.x-rt/0085-tracing-Give-event-triggers-access-to-ring_buffer_ev.patch b/kernel/patches-4.14.x-rt/0085-tracing-Give-event-triggers-access-to-ring_buffer_ev.patch deleted file mode 100644 index 27c01dc1b..000000000 --- a/kernel/patches-4.14.x-rt/0085-tracing-Give-event-triggers-access-to-ring_buffer_ev.patch +++ /dev/null @@ -1,316 +0,0 @@ -From 635d753e923c3acd4de41b201ccc450da32e8330 Mon Sep 17 00:00:00 2001 -From: Tom Zanussi -Date: Mon, 15 Jan 2018 20:51:42 -0600 -Subject: [PATCH 085/450] tracing: Give event triggers access to - ring_buffer_event - -The ring_buffer event can provide a timestamp that may be useful to -various triggers - pass it into the handlers for that purpose. - -Link: http://lkml.kernel.org/r/6de592683b59fa70ffa5d43d0109896623fc1367.1516069914.git.tom.zanussi@linux.intel.com - -Signed-off-by: Tom Zanussi -Signed-off-by: Steven Rostedt (VMware) -(cherry picked from commit 373514437a6f75b5cfe890742b590f2c12f6c335) -Signed-off-by: Sebastian Andrzej Siewior ---- - include/linux/trace_events.h | 14 +++++---- - kernel/trace/trace.h | 9 +++--- - kernel/trace/trace_events_hist.c | 11 ++++--- - kernel/trace/trace_events_trigger.c | 47 ++++++++++++++++++----------- - 4 files changed, 49 insertions(+), 32 deletions(-) - -diff --git a/include/linux/trace_events.h b/include/linux/trace_events.h -index 2bcb4dc6df1a..aefc80f2909b 100644 ---- a/include/linux/trace_events.h -+++ b/include/linux/trace_events.h -@@ -402,11 +402,13 @@ enum event_trigger_type { - - extern int filter_match_preds(struct event_filter *filter, void *rec); - --extern enum event_trigger_type event_triggers_call(struct trace_event_file *file, -- void *rec); --extern void event_triggers_post_call(struct trace_event_file *file, -- enum event_trigger_type tt, -- void *rec); -+extern enum event_trigger_type -+event_triggers_call(struct trace_event_file *file, void *rec, -+ struct ring_buffer_event *event); -+extern void -+event_triggers_post_call(struct trace_event_file *file, -+ enum event_trigger_type tt, -+ void *rec, struct ring_buffer_event *event); - - bool trace_event_ignore_this_pid(struct trace_event_file *trace_file); - -@@ -426,7 +428,7 @@ trace_trigger_soft_disabled(struct trace_event_file *file) - - if (!(eflags & EVENT_FILE_FL_TRIGGER_COND)) { - if (eflags & EVENT_FILE_FL_TRIGGER_MODE) -- event_triggers_call(file, NULL); -+ event_triggers_call(file, NULL, NULL); - if (eflags & EVENT_FILE_FL_SOFT_DISABLED) - return true; - if (eflags & EVENT_FILE_FL_PID_FILTER) -diff --git a/kernel/trace/trace.h b/kernel/trace/trace.h -index 0506c4cdfeba..e2e12710d53c 100644 ---- a/kernel/trace/trace.h -+++ b/kernel/trace/trace.h -@@ -1296,7 +1296,7 @@ __event_trigger_test_discard(struct trace_event_file *file, - unsigned long eflags = file->flags; - - if (eflags & EVENT_FILE_FL_TRIGGER_COND) -- *tt = event_triggers_call(file, entry); -+ *tt = event_triggers_call(file, entry, event); - - if (test_bit(EVENT_FILE_FL_SOFT_DISABLED_BIT, &file->flags) || - (unlikely(file->flags & EVENT_FILE_FL_FILTERED) && -@@ -1333,7 +1333,7 @@ event_trigger_unlock_commit(struct trace_event_file *file, - trace_buffer_unlock_commit(file->tr, buffer, event, irq_flags, pc); - - if (tt) -- event_triggers_post_call(file, tt, entry); -+ event_triggers_post_call(file, tt, entry, event); - } - - /** -@@ -1366,7 +1366,7 @@ event_trigger_unlock_commit_regs(struct trace_event_file *file, - irq_flags, pc, regs); - - if (tt) -- event_triggers_post_call(file, tt, entry); -+ event_triggers_post_call(file, tt, entry, event); - } - - #define FILTER_PRED_INVALID ((unsigned short)-1) -@@ -1591,7 +1591,8 @@ extern int register_trigger_hist_enable_disable_cmds(void); - */ - struct event_trigger_ops { - void (*func)(struct event_trigger_data *data, -- void *rec); -+ void *rec, -+ struct ring_buffer_event *rbe); - int (*init)(struct event_trigger_ops *ops, - struct event_trigger_data *data); - void (*free)(struct event_trigger_ops *ops, -diff --git a/kernel/trace/trace_events_hist.c b/kernel/trace/trace_events_hist.c -index c57e5369b0c2..77079c79b6d4 100644 ---- a/kernel/trace/trace_events_hist.c -+++ b/kernel/trace/trace_events_hist.c -@@ -909,7 +909,8 @@ static inline void add_to_key(char *compound_key, void *key, - memcpy(compound_key + key_field->offset, key, size); - } - --static void event_hist_trigger(struct event_trigger_data *data, void *rec) -+static void event_hist_trigger(struct event_trigger_data *data, void *rec, -+ struct ring_buffer_event *event) - { - struct hist_trigger_data *hist_data = data->private_data; - bool use_compound_key = (hist_data->n_keys > 1); -@@ -1660,7 +1661,8 @@ __init int register_trigger_hist_cmd(void) - } - - static void --hist_enable_trigger(struct event_trigger_data *data, void *rec) -+hist_enable_trigger(struct event_trigger_data *data, void *rec, -+ struct ring_buffer_event *event) - { - struct enable_trigger_data *enable_data = data->private_data; - struct event_trigger_data *test; -@@ -1676,7 +1678,8 @@ hist_enable_trigger(struct event_trigger_data *data, void *rec) - } - - static void --hist_enable_count_trigger(struct event_trigger_data *data, void *rec) -+hist_enable_count_trigger(struct event_trigger_data *data, void *rec, -+ struct ring_buffer_event *event) - { - if (!data->count) - return; -@@ -1684,7 +1687,7 @@ hist_enable_count_trigger(struct event_trigger_data *data, void *rec) - if (data->count != -1) - (data->count)--; - -- hist_enable_trigger(data, rec); -+ hist_enable_trigger(data, rec, event); - } - - static struct event_trigger_ops hist_enable_trigger_ops = { -diff --git a/kernel/trace/trace_events_trigger.c b/kernel/trace/trace_events_trigger.c -index 43254c5e7e16..4c269f2e00a4 100644 ---- a/kernel/trace/trace_events_trigger.c -+++ b/kernel/trace/trace_events_trigger.c -@@ -63,7 +63,8 @@ void trigger_data_free(struct event_trigger_data *data) - * any trigger that should be deferred, ETT_NONE if nothing to defer. - */ - enum event_trigger_type --event_triggers_call(struct trace_event_file *file, void *rec) -+event_triggers_call(struct trace_event_file *file, void *rec, -+ struct ring_buffer_event *event) - { - struct event_trigger_data *data; - enum event_trigger_type tt = ETT_NONE; -@@ -76,7 +77,7 @@ event_triggers_call(struct trace_event_file *file, void *rec) - if (data->paused) - continue; - if (!rec) { -- data->ops->func(data, rec); -+ data->ops->func(data, rec, event); - continue; - } - filter = rcu_dereference_sched(data->filter); -@@ -86,7 +87,7 @@ event_triggers_call(struct trace_event_file *file, void *rec) - tt |= data->cmd_ops->trigger_type; - continue; - } -- data->ops->func(data, rec); -+ data->ops->func(data, rec, event); - } - return tt; - } -@@ -108,7 +109,7 @@ EXPORT_SYMBOL_GPL(event_triggers_call); - void - event_triggers_post_call(struct trace_event_file *file, - enum event_trigger_type tt, -- void *rec) -+ void *rec, struct ring_buffer_event *event) - { - struct event_trigger_data *data; - -@@ -116,7 +117,7 @@ event_triggers_post_call(struct trace_event_file *file, - if (data->paused) - continue; - if (data->cmd_ops->trigger_type & tt) -- data->ops->func(data, rec); -+ data->ops->func(data, rec, event); - } - } - EXPORT_SYMBOL_GPL(event_triggers_post_call); -@@ -915,7 +916,8 @@ void set_named_trigger_data(struct event_trigger_data *data, - } - - static void --traceon_trigger(struct event_trigger_data *data, void *rec) -+traceon_trigger(struct event_trigger_data *data, void *rec, -+ struct ring_buffer_event *event) - { - if (tracing_is_on()) - return; -@@ -924,7 +926,8 @@ traceon_trigger(struct event_trigger_data *data, void *rec) - } - - static void --traceon_count_trigger(struct event_trigger_data *data, void *rec) -+traceon_count_trigger(struct event_trigger_data *data, void *rec, -+ struct ring_buffer_event *event) - { - if (tracing_is_on()) - return; -@@ -939,7 +942,8 @@ traceon_count_trigger(struct event_trigger_data *data, void *rec) - } - - static void --traceoff_trigger(struct event_trigger_data *data, void *rec) -+traceoff_trigger(struct event_trigger_data *data, void *rec, -+ struct ring_buffer_event *event) - { - if (!tracing_is_on()) - return; -@@ -948,7 +952,8 @@ traceoff_trigger(struct event_trigger_data *data, void *rec) - } - - static void --traceoff_count_trigger(struct event_trigger_data *data, void *rec) -+traceoff_count_trigger(struct event_trigger_data *data, void *rec, -+ struct ring_buffer_event *event) - { - if (!tracing_is_on()) - return; -@@ -1045,7 +1050,8 @@ static struct event_command trigger_traceoff_cmd = { - - #ifdef CONFIG_TRACER_SNAPSHOT - static void --snapshot_trigger(struct event_trigger_data *data, void *rec) -+snapshot_trigger(struct event_trigger_data *data, void *rec, -+ struct ring_buffer_event *event) - { - struct trace_event_file *file = data->private_data; - -@@ -1056,7 +1062,8 @@ snapshot_trigger(struct event_trigger_data *data, void *rec) - } - - static void --snapshot_count_trigger(struct event_trigger_data *data, void *rec) -+snapshot_count_trigger(struct event_trigger_data *data, void *rec, -+ struct ring_buffer_event *event) - { - if (!data->count) - return; -@@ -1064,7 +1071,7 @@ snapshot_count_trigger(struct event_trigger_data *data, void *rec) - if (data->count != -1) - (data->count)--; - -- snapshot_trigger(data, rec); -+ snapshot_trigger(data, rec, event); - } - - static int -@@ -1143,13 +1150,15 @@ static __init int register_trigger_snapshot_cmd(void) { return 0; } - #define STACK_SKIP 3 - - static void --stacktrace_trigger(struct event_trigger_data *data, void *rec) -+stacktrace_trigger(struct event_trigger_data *data, void *rec, -+ struct ring_buffer_event *event) - { - trace_dump_stack(STACK_SKIP); - } - - static void --stacktrace_count_trigger(struct event_trigger_data *data, void *rec) -+stacktrace_count_trigger(struct event_trigger_data *data, void *rec, -+ struct ring_buffer_event *event) - { - if (!data->count) - return; -@@ -1157,7 +1166,7 @@ stacktrace_count_trigger(struct event_trigger_data *data, void *rec) - if (data->count != -1) - (data->count)--; - -- stacktrace_trigger(data, rec); -+ stacktrace_trigger(data, rec, event); - } - - static int -@@ -1219,7 +1228,8 @@ static __init void unregister_trigger_traceon_traceoff_cmds(void) - } - - static void --event_enable_trigger(struct event_trigger_data *data, void *rec) -+event_enable_trigger(struct event_trigger_data *data, void *rec, -+ struct ring_buffer_event *event) - { - struct enable_trigger_data *enable_data = data->private_data; - -@@ -1230,7 +1240,8 @@ event_enable_trigger(struct event_trigger_data *data, void *rec) - } - - static void --event_enable_count_trigger(struct event_trigger_data *data, void *rec) -+event_enable_count_trigger(struct event_trigger_data *data, void *rec, -+ struct ring_buffer_event *event) - { - struct enable_trigger_data *enable_data = data->private_data; - -@@ -1244,7 +1255,7 @@ event_enable_count_trigger(struct event_trigger_data *data, void *rec) - if (data->count != -1) - (data->count)--; - -- event_enable_trigger(data, rec); -+ event_enable_trigger(data, rec, event); - } - - int event_enable_trigger_print(struct seq_file *m, --- -2.19.2 - diff --git a/kernel/patches-4.14.x-rt/0086-tracing-Add-ring-buffer-event-param-to-hist-field-fu.patch b/kernel/patches-4.14.x-rt/0086-tracing-Add-ring-buffer-event-param-to-hist-field-fu.patch deleted file mode 100644 index 49ae550ed..000000000 --- a/kernel/patches-4.14.x-rt/0086-tracing-Add-ring-buffer-event-param-to-hist-field-fu.patch +++ /dev/null @@ -1,149 +0,0 @@ -From 9bd98ebd9a345d81a789160ce7ab7a0c4be5c61a Mon Sep 17 00:00:00 2001 -From: Tom Zanussi -Date: Mon, 15 Jan 2018 20:51:43 -0600 -Subject: [PATCH 086/450] tracing: Add ring buffer event param to hist field - functions - -Some events such as timestamps require access to a ring_buffer_event -struct; add a param so that hist field functions can access that. - -Link: http://lkml.kernel.org/r/2ff4af18e72b6002eb86b26b2a7f39cef7d1dfe4.1516069914.git.tom.zanussi@linux.intel.com - -Signed-off-by: Tom Zanussi -Signed-off-by: Steven Rostedt (VMware) -(cherry picked from commit df7253a730d0aaef760d45ea234dc087ba7cac88) -Signed-off-by: Sebastian Andrzej Siewior ---- - kernel/trace/trace_events_hist.c | 39 ++++++++++++++++++++------------ - 1 file changed, 24 insertions(+), 15 deletions(-) - -diff --git a/kernel/trace/trace_events_hist.c b/kernel/trace/trace_events_hist.c -index 77079c79b6d4..9126be52ff4d 100644 ---- a/kernel/trace/trace_events_hist.c -+++ b/kernel/trace/trace_events_hist.c -@@ -26,7 +26,8 @@ - - struct hist_field; - --typedef u64 (*hist_field_fn_t) (struct hist_field *field, void *event); -+typedef u64 (*hist_field_fn_t) (struct hist_field *field, void *event, -+ struct ring_buffer_event *rbe); - - #define HIST_FIELD_OPERANDS_MAX 2 - -@@ -40,24 +41,28 @@ struct hist_field { - struct hist_field *operands[HIST_FIELD_OPERANDS_MAX]; - }; - --static u64 hist_field_none(struct hist_field *field, void *event) -+static u64 hist_field_none(struct hist_field *field, void *event, -+ struct ring_buffer_event *rbe) - { - return 0; - } - --static u64 hist_field_counter(struct hist_field *field, void *event) -+static u64 hist_field_counter(struct hist_field *field, void *event, -+ struct ring_buffer_event *rbe) - { - return 1; - } - --static u64 hist_field_string(struct hist_field *hist_field, void *event) -+static u64 hist_field_string(struct hist_field *hist_field, void *event, -+ struct ring_buffer_event *rbe) - { - char *addr = (char *)(event + hist_field->field->offset); - - return (u64)(unsigned long)addr; - } - --static u64 hist_field_dynstring(struct hist_field *hist_field, void *event) -+static u64 hist_field_dynstring(struct hist_field *hist_field, void *event, -+ struct ring_buffer_event *rbe) - { - u32 str_item = *(u32 *)(event + hist_field->field->offset); - int str_loc = str_item & 0xffff; -@@ -66,24 +71,28 @@ static u64 hist_field_dynstring(struct hist_field *hist_field, void *event) - return (u64)(unsigned long)addr; - } - --static u64 hist_field_pstring(struct hist_field *hist_field, void *event) -+static u64 hist_field_pstring(struct hist_field *hist_field, void *event, -+ struct ring_buffer_event *rbe) - { - char **addr = (char **)(event + hist_field->field->offset); - - return (u64)(unsigned long)*addr; - } - --static u64 hist_field_log2(struct hist_field *hist_field, void *event) -+static u64 hist_field_log2(struct hist_field *hist_field, void *event, -+ struct ring_buffer_event *rbe) - { - struct hist_field *operand = hist_field->operands[0]; - -- u64 val = operand->fn(operand, event); -+ u64 val = operand->fn(operand, event, rbe); - - return (u64) ilog2(roundup_pow_of_two(val)); - } - - #define DEFINE_HIST_FIELD_FN(type) \ --static u64 hist_field_##type(struct hist_field *hist_field, void *event)\ -+ static u64 hist_field_##type(struct hist_field *hist_field, \ -+ void *event, \ -+ struct ring_buffer_event *rbe) \ - { \ - type *addr = (type *)(event + hist_field->field->offset); \ - \ -@@ -871,8 +880,8 @@ create_hist_data(unsigned int map_bits, - } - - static void hist_trigger_elt_update(struct hist_trigger_data *hist_data, -- struct tracing_map_elt *elt, -- void *rec) -+ struct tracing_map_elt *elt, void *rec, -+ struct ring_buffer_event *rbe) - { - struct hist_field *hist_field; - unsigned int i; -@@ -880,7 +889,7 @@ static void hist_trigger_elt_update(struct hist_trigger_data *hist_data, - - for_each_hist_val_field(i, hist_data) { - hist_field = hist_data->fields[i]; -- hist_val = hist_field->fn(hist_field, rec); -+ hist_val = hist_field->fn(hist_field, rec, rbe); - tracing_map_update_sum(elt, i, hist_val); - } - } -@@ -910,7 +919,7 @@ static inline void add_to_key(char *compound_key, void *key, - } - - static void event_hist_trigger(struct event_trigger_data *data, void *rec, -- struct ring_buffer_event *event) -+ struct ring_buffer_event *rbe) - { - struct hist_trigger_data *hist_data = data->private_data; - bool use_compound_key = (hist_data->n_keys > 1); -@@ -939,7 +948,7 @@ static void event_hist_trigger(struct event_trigger_data *data, void *rec, - - key = entries; - } else { -- field_contents = key_field->fn(key_field, rec); -+ field_contents = key_field->fn(key_field, rec, rbe); - if (key_field->flags & HIST_FIELD_FL_STRING) { - key = (void *)(unsigned long)field_contents; - use_compound_key = true; -@@ -956,7 +965,7 @@ static void event_hist_trigger(struct event_trigger_data *data, void *rec, - - elt = tracing_map_insert(hist_data->map, key); - if (elt) -- hist_trigger_elt_update(hist_data, elt, rec); -+ hist_trigger_elt_update(hist_data, elt, rec, rbe); - } - - static void hist_trigger_stacktrace_print(struct seq_file *m, --- -2.19.2 - diff --git a/kernel/patches-4.14.x-rt/0087-tracing-Break-out-hist-trigger-assignment-parsing.patch b/kernel/patches-4.14.x-rt/0087-tracing-Break-out-hist-trigger-assignment-parsing.patch deleted file mode 100644 index 29adb81be..000000000 --- a/kernel/patches-4.14.x-rt/0087-tracing-Break-out-hist-trigger-assignment-parsing.patch +++ /dev/null @@ -1,118 +0,0 @@ -From e2bbd29cab8010be36eb88dc22c5e3addc9d7a2c Mon Sep 17 00:00:00 2001 -From: Tom Zanussi -Date: Mon, 15 Jan 2018 20:51:44 -0600 -Subject: [PATCH 087/450] tracing: Break out hist trigger assignment parsing - -This will make it easier to add variables, and makes the parsing code -cleaner regardless. - -Link: http://lkml.kernel.org/r/e574b3291bbe15e35a4dfc87e5395aa715701c98.1516069914.git.tom.zanussi@linux.intel.com - -Signed-off-by: Tom Zanussi -Signed-off-by: Rajvi Jingar -Signed-off-by: Steven Rostedt (VMware) -(cherry picked from commit 3c1e23def1291b21a2057f883ccc0456418dc5ad) -Signed-off-by: Sebastian Andrzej Siewior ---- - kernel/trace/trace_events_hist.c | 72 ++++++++++++++++++++++---------- - 1 file changed, 51 insertions(+), 21 deletions(-) - -diff --git a/kernel/trace/trace_events_hist.c b/kernel/trace/trace_events_hist.c -index 9126be52ff4d..4935290fd1e8 100644 ---- a/kernel/trace/trace_events_hist.c -+++ b/kernel/trace/trace_events_hist.c -@@ -251,6 +251,51 @@ static void destroy_hist_trigger_attrs(struct hist_trigger_attrs *attrs) - kfree(attrs); - } - -+static int parse_assignment(char *str, struct hist_trigger_attrs *attrs) -+{ -+ int ret = 0; -+ -+ if ((strncmp(str, "key=", strlen("key=")) == 0) || -+ (strncmp(str, "keys=", strlen("keys=")) == 0)) { -+ attrs->keys_str = kstrdup(str, GFP_KERNEL); -+ if (!attrs->keys_str) { -+ ret = -ENOMEM; -+ goto out; -+ } -+ } else if ((strncmp(str, "val=", strlen("val=")) == 0) || -+ (strncmp(str, "vals=", strlen("vals=")) == 0) || -+ (strncmp(str, "values=", strlen("values=")) == 0)) { -+ attrs->vals_str = kstrdup(str, GFP_KERNEL); -+ if (!attrs->vals_str) { -+ ret = -ENOMEM; -+ goto out; -+ } -+ } else if (strncmp(str, "sort=", strlen("sort=")) == 0) { -+ attrs->sort_key_str = kstrdup(str, GFP_KERNEL); -+ if (!attrs->sort_key_str) { -+ ret = -ENOMEM; -+ goto out; -+ } -+ } else if (strncmp(str, "name=", strlen("name=")) == 0) { -+ attrs->name = kstrdup(str, GFP_KERNEL); -+ if (!attrs->name) { -+ ret = -ENOMEM; -+ goto out; -+ } -+ } else if (strncmp(str, "size=", strlen("size=")) == 0) { -+ int map_bits = parse_map_size(str); -+ -+ if (map_bits < 0) { -+ ret = map_bits; -+ goto out; -+ } -+ attrs->map_bits = map_bits; -+ } else -+ ret = -EINVAL; -+ out: -+ return ret; -+} -+ - static struct hist_trigger_attrs *parse_hist_trigger_attrs(char *trigger_str) - { - struct hist_trigger_attrs *attrs; -@@ -263,33 +308,18 @@ static struct hist_trigger_attrs *parse_hist_trigger_attrs(char *trigger_str) - while (trigger_str) { - char *str = strsep(&trigger_str, ":"); - -- if ((strncmp(str, "key=", strlen("key=")) == 0) || -- (strncmp(str, "keys=", strlen("keys=")) == 0)) -- attrs->keys_str = kstrdup(str, GFP_KERNEL); -- else if ((strncmp(str, "val=", strlen("val=")) == 0) || -- (strncmp(str, "vals=", strlen("vals=")) == 0) || -- (strncmp(str, "values=", strlen("values=")) == 0)) -- attrs->vals_str = kstrdup(str, GFP_KERNEL); -- else if (strncmp(str, "sort=", strlen("sort=")) == 0) -- attrs->sort_key_str = kstrdup(str, GFP_KERNEL); -- else if (strncmp(str, "name=", strlen("name=")) == 0) -- attrs->name = kstrdup(str, GFP_KERNEL); -- else if (strcmp(str, "pause") == 0) -+ if (strchr(str, '=')) { -+ ret = parse_assignment(str, attrs); -+ if (ret) -+ goto free; -+ } else if (strcmp(str, "pause") == 0) - attrs->pause = true; - else if ((strcmp(str, "cont") == 0) || - (strcmp(str, "continue") == 0)) - attrs->cont = true; - else if (strcmp(str, "clear") == 0) - attrs->clear = true; -- else if (strncmp(str, "size=", strlen("size=")) == 0) { -- int map_bits = parse_map_size(str); -- -- if (map_bits < 0) { -- ret = map_bits; -- goto free; -- } -- attrs->map_bits = map_bits; -- } else { -+ else { - ret = -EINVAL; - goto free; - } --- -2.19.2 - diff --git a/kernel/patches-4.14.x-rt/0088-tracing-Add-hist-trigger-timestamp-support.patch b/kernel/patches-4.14.x-rt/0088-tracing-Add-hist-trigger-timestamp-support.patch deleted file mode 100644 index 67f860cbb..000000000 --- a/kernel/patches-4.14.x-rt/0088-tracing-Add-hist-trigger-timestamp-support.patch +++ /dev/null @@ -1,252 +0,0 @@ -From 67b7fdf52c9a5092aea0a1dd29becd8b5ba7292b Mon Sep 17 00:00:00 2001 -From: Tom Zanussi -Date: Mon, 15 Jan 2018 20:51:45 -0600 -Subject: [PATCH 088/450] tracing: Add hist trigger timestamp support - -Add support for a timestamp event field. This is actually a 'pseudo-' -event field in that it behaves like it's part of the event record, but -is really part of the corresponding ring buffer event. - -To make use of the timestamp field, users can specify -"common_timestamp" as a field name for any histogram. Note that this -doesn't make much sense on its own either as either a key or value, -but needs to be supported even so, since follow-on patches will add -support for making use of this field in time deltas. The -common_timestamp 'field' is not a bona fide event field - so you won't -find it in the event description - but rather it's a synthetic field -that can be used like a real field. - -Note that the use of this field requires the ring buffer be put into -'absolute timestamp' mode, which saves the complete timestamp for each -event rather than an offset. This mode will be enabled if and only if -a histogram makes use of the "common_timestamp" field. - -Link: http://lkml.kernel.org/r/97afbd646ed146e26271f3458b4b33e16d7817c2.1516069914.git.tom.zanussi@linux.intel.com - -Signed-off-by: Tom Zanussi -Signed-off-by: Baohong Liu -[kasan use-after-free fix] -Signed-off-by: Vedang Patel -Signed-off-by: Steven Rostedt (VMware) -(cherry picked from commit 5d9d58b00ff82078deac8557c91359cd13c8959d) -Signed-off-by: Sebastian Andrzej Siewior ---- - kernel/trace/trace_events_hist.c | 94 ++++++++++++++++++++++++-------- - 1 file changed, 71 insertions(+), 23 deletions(-) - -diff --git a/kernel/trace/trace_events_hist.c b/kernel/trace/trace_events_hist.c -index 4935290fd1e8..cd80bca34cec 100644 ---- a/kernel/trace/trace_events_hist.c -+++ b/kernel/trace/trace_events_hist.c -@@ -89,6 +89,12 @@ static u64 hist_field_log2(struct hist_field *hist_field, void *event, - return (u64) ilog2(roundup_pow_of_two(val)); - } - -+static u64 hist_field_timestamp(struct hist_field *hist_field, void *event, -+ struct ring_buffer_event *rbe) -+{ -+ return ring_buffer_event_time_stamp(rbe); -+} -+ - #define DEFINE_HIST_FIELD_FN(type) \ - static u64 hist_field_##type(struct hist_field *hist_field, \ - void *event, \ -@@ -135,6 +141,7 @@ enum hist_field_flags { - HIST_FIELD_FL_SYSCALL = 1 << 7, - HIST_FIELD_FL_STACKTRACE = 1 << 8, - HIST_FIELD_FL_LOG2 = 1 << 9, -+ HIST_FIELD_FL_TIMESTAMP = 1 << 10, - }; - - struct hist_trigger_attrs { -@@ -159,6 +166,7 @@ struct hist_trigger_data { - struct trace_event_file *event_file; - struct hist_trigger_attrs *attrs; - struct tracing_map *map; -+ bool enable_timestamps; - }; - - static const char *hist_field_name(struct hist_field *field, -@@ -173,6 +181,8 @@ static const char *hist_field_name(struct hist_field *field, - field_name = field->field->name; - else if (field->flags & HIST_FIELD_FL_LOG2) - field_name = hist_field_name(field->operands[0], ++level); -+ else if (field->flags & HIST_FIELD_FL_TIMESTAMP) -+ field_name = "common_timestamp"; - - if (field_name == NULL) - field_name = ""; -@@ -440,6 +450,12 @@ static struct hist_field *create_hist_field(struct ftrace_event_field *field, - goto out; - } - -+ if (flags & HIST_FIELD_FL_TIMESTAMP) { -+ hist_field->fn = hist_field_timestamp; -+ hist_field->size = sizeof(u64); -+ goto out; -+ } -+ - if (WARN_ON_ONCE(!field)) - goto out; - -@@ -517,10 +533,15 @@ static int create_val_field(struct hist_trigger_data *hist_data, - } - } - -- field = trace_find_event_field(file->event_call, field_name); -- if (!field || !field->size) { -- ret = -EINVAL; -- goto out; -+ if (strcmp(field_name, "common_timestamp") == 0) { -+ flags |= HIST_FIELD_FL_TIMESTAMP; -+ hist_data->enable_timestamps = true; -+ } else { -+ field = trace_find_event_field(file->event_call, field_name); -+ if (!field || !field->size) { -+ ret = -EINVAL; -+ goto out; -+ } - } - - hist_data->fields[val_idx] = create_hist_field(field, flags); -@@ -615,16 +636,22 @@ static int create_key_field(struct hist_trigger_data *hist_data, - } - } - -- field = trace_find_event_field(file->event_call, field_name); -- if (!field || !field->size) { -- ret = -EINVAL; -- goto out; -- } -+ if (strcmp(field_name, "common_timestamp") == 0) { -+ flags |= HIST_FIELD_FL_TIMESTAMP; -+ hist_data->enable_timestamps = true; -+ key_size = sizeof(u64); -+ } else { -+ field = trace_find_event_field(file->event_call, field_name); -+ if (!field || !field->size) { -+ ret = -EINVAL; -+ goto out; -+ } - -- if (is_string_field(field)) -- key_size = MAX_FILTER_STR_VAL; -- else -- key_size = field->size; -+ if (is_string_field(field)) -+ key_size = MAX_FILTER_STR_VAL; -+ else -+ key_size = field->size; -+ } - } - - hist_data->fields[key_idx] = create_hist_field(field, flags); -@@ -820,6 +847,9 @@ static int create_tracing_map_fields(struct hist_trigger_data *hist_data) - - if (hist_field->flags & HIST_FIELD_FL_STACKTRACE) - cmp_fn = tracing_map_cmp_none; -+ else if (!field) -+ cmp_fn = tracing_map_cmp_num(hist_field->size, -+ hist_field->is_signed); - else if (is_string_field(field)) - cmp_fn = tracing_map_cmp_string; - else -@@ -1217,7 +1247,11 @@ static void hist_field_print(struct seq_file *m, struct hist_field *hist_field) - { - const char *field_name = hist_field_name(hist_field, 0); - -- seq_printf(m, "%s", field_name); -+ if (hist_field->flags & HIST_FIELD_FL_TIMESTAMP) -+ seq_puts(m, "common_timestamp"); -+ else if (field_name) -+ seq_printf(m, "%s", field_name); -+ - if (hist_field->flags) { - const char *flags_str = get_hist_field_flags(hist_field); - -@@ -1268,27 +1302,25 @@ static int event_hist_trigger_print(struct seq_file *m, - - for (i = 0; i < hist_data->n_sort_keys; i++) { - struct tracing_map_sort_key *sort_key; -+ unsigned int idx; - - sort_key = &hist_data->sort_keys[i]; -+ idx = sort_key->field_idx; -+ -+ if (WARN_ON(idx >= TRACING_MAP_FIELDS_MAX)) -+ return -EINVAL; - - if (i > 0) - seq_puts(m, ","); - -- if (sort_key->field_idx == HITCOUNT_IDX) -+ if (idx == HITCOUNT_IDX) - seq_puts(m, "hitcount"); -- else { -- unsigned int idx = sort_key->field_idx; -- -- if (WARN_ON(idx >= TRACING_MAP_FIELDS_MAX)) -- return -EINVAL; -- -+ else - hist_field_print(m, hist_data->fields[idx]); -- } - - if (sort_key->descending) - seq_puts(m, ".descending"); - } -- - seq_printf(m, ":size=%u", (1 << hist_data->map->map_bits)); - - if (data->filter_str) -@@ -1456,6 +1488,10 @@ static bool hist_trigger_match(struct event_trigger_data *data, - return false; - if (key_field->offset != key_field_test->offset) - return false; -+ if (key_field->size != key_field_test->size) -+ return false; -+ if (key_field->is_signed != key_field_test->is_signed) -+ return false; - } - - for (i = 0; i < hist_data->n_sort_keys; i++) { -@@ -1538,6 +1574,9 @@ static int hist_register_trigger(char *glob, struct event_trigger_ops *ops, - - update_cond_flag(file); - -+ if (hist_data->enable_timestamps) -+ tracing_set_time_stamp_abs(file->tr, true); -+ - if (trace_event_trigger_enable_disable(file, 1) < 0) { - list_del_rcu(&data->list); - update_cond_flag(file); -@@ -1572,17 +1611,26 @@ static void hist_unregister_trigger(char *glob, struct event_trigger_ops *ops, - - if (unregistered && test->ops->free) - test->ops->free(test->ops, test); -+ -+ if (hist_data->enable_timestamps) { -+ if (unregistered) -+ tracing_set_time_stamp_abs(file->tr, false); -+ } - } - - static void hist_unreg_all(struct trace_event_file *file) - { - struct event_trigger_data *test, *n; -+ struct hist_trigger_data *hist_data; - - list_for_each_entry_safe(test, n, &file->triggers, list) { - if (test->cmd_ops->trigger_type == ETT_EVENT_HIST) { -+ hist_data = test->private_data; - list_del_rcu(&test->list); - trace_event_trigger_enable_disable(file, 0); - update_cond_flag(file); -+ if (hist_data->enable_timestamps) -+ tracing_set_time_stamp_abs(file->tr, false); - if (test->ops->free) - test->ops->free(test->ops, test); - } --- -2.19.2 - diff --git a/kernel/patches-4.14.x-rt/0089-tracing-Add-per-element-variable-support-to-tracing_.patch b/kernel/patches-4.14.x-rt/0089-tracing-Add-per-element-variable-support-to-tracing_.patch deleted file mode 100644 index 520e258bd..000000000 --- a/kernel/patches-4.14.x-rt/0089-tracing-Add-per-element-variable-support-to-tracing_.patch +++ /dev/null @@ -1,232 +0,0 @@ -From 3c95c215d087d86eb91bda208a6b219eadb556e6 Mon Sep 17 00:00:00 2001 -From: Tom Zanussi -Date: Mon, 15 Jan 2018 20:51:46 -0600 -Subject: [PATCH 089/450] tracing: Add per-element variable support to - tracing_map - -In order to allow information to be passed between trace events, add -support for per-element variables to tracing_map. This provides a -means for histograms to associate a value or values with an entry when -it's saved or updated, and retrieved by a subsequent event occurrences. - -Variables can be set using tracing_map_set_var() and read using -tracing_map_read_var(). tracing_map_var_set() returns true or false -depending on whether or not the variable has been set or not, which is -important for event-matching applications. - -tracing_map_read_var_once() reads the variable and resets it to the -'unset' state, implementing read-once variables, which are also -important for event-matching uses. - -Link: http://lkml.kernel.org/r/7fa001108252556f0c6dd9d63145eabfe3370d1a.1516069914.git.tom.zanussi@linux.intel.com - -Signed-off-by: Tom Zanussi -Signed-off-by: Steven Rostedt (VMware) -(cherry picked from commit 42a38132f9e154e1fa2dd2182dff17f9c0e7ee7e) -Signed-off-by: Sebastian Andrzej Siewior ---- - kernel/trace/tracing_map.c | 108 +++++++++++++++++++++++++++++++++++++ - kernel/trace/tracing_map.h | 11 ++++ - 2 files changed, 119 insertions(+) - -diff --git a/kernel/trace/tracing_map.c b/kernel/trace/tracing_map.c -index f47a4d54bcf0..5cadb1b8b5fe 100644 ---- a/kernel/trace/tracing_map.c -+++ b/kernel/trace/tracing_map.c -@@ -66,6 +66,73 @@ u64 tracing_map_read_sum(struct tracing_map_elt *elt, unsigned int i) - return (u64)atomic64_read(&elt->fields[i].sum); - } - -+/** -+ * tracing_map_set_var - Assign a tracing_map_elt's variable field -+ * @elt: The tracing_map_elt -+ * @i: The index of the given variable associated with the tracing_map_elt -+ * @n: The value to assign -+ * -+ * Assign n to variable i associated with the specified tracing_map_elt -+ * instance. The index i is the index returned by the call to -+ * tracing_map_add_var() when the tracing map was set up. -+ */ -+void tracing_map_set_var(struct tracing_map_elt *elt, unsigned int i, u64 n) -+{ -+ atomic64_set(&elt->vars[i], n); -+ elt->var_set[i] = true; -+} -+ -+/** -+ * tracing_map_var_set - Return whether or not a variable has been set -+ * @elt: The tracing_map_elt -+ * @i: The index of the given variable associated with the tracing_map_elt -+ * -+ * Return true if the variable has been set, false otherwise. The -+ * index i is the index returned by the call to tracing_map_add_var() -+ * when the tracing map was set up. -+ */ -+bool tracing_map_var_set(struct tracing_map_elt *elt, unsigned int i) -+{ -+ return elt->var_set[i]; -+} -+ -+/** -+ * tracing_map_read_var - Return the value of a tracing_map_elt's variable field -+ * @elt: The tracing_map_elt -+ * @i: The index of the given variable associated with the tracing_map_elt -+ * -+ * Retrieve the value of the variable i associated with the specified -+ * tracing_map_elt instance. The index i is the index returned by the -+ * call to tracing_map_add_var() when the tracing map was set -+ * up. -+ * -+ * Return: The variable value associated with field i for elt. -+ */ -+u64 tracing_map_read_var(struct tracing_map_elt *elt, unsigned int i) -+{ -+ return (u64)atomic64_read(&elt->vars[i]); -+} -+ -+/** -+ * tracing_map_read_var_once - Return and reset a tracing_map_elt's variable field -+ * @elt: The tracing_map_elt -+ * @i: The index of the given variable associated with the tracing_map_elt -+ * -+ * Retrieve the value of the variable i associated with the specified -+ * tracing_map_elt instance, and reset the variable to the 'not set' -+ * state. The index i is the index returned by the call to -+ * tracing_map_add_var() when the tracing map was set up. The reset -+ * essentially makes the variable a read-once variable if it's only -+ * accessed using this function. -+ * -+ * Return: The variable value associated with field i for elt. -+ */ -+u64 tracing_map_read_var_once(struct tracing_map_elt *elt, unsigned int i) -+{ -+ elt->var_set[i] = false; -+ return (u64)atomic64_read(&elt->vars[i]); -+} -+ - int tracing_map_cmp_string(void *val_a, void *val_b) - { - char *a = val_a; -@@ -170,6 +237,28 @@ int tracing_map_add_sum_field(struct tracing_map *map) - return tracing_map_add_field(map, tracing_map_cmp_atomic64); - } - -+/** -+ * tracing_map_add_var - Add a field describing a tracing_map var -+ * @map: The tracing_map -+ * -+ * Add a var to the map and return the index identifying it in the map -+ * and associated tracing_map_elts. This is the index used for -+ * instance to update a var for a particular tracing_map_elt using -+ * tracing_map_update_var() or reading it via tracing_map_read_var(). -+ * -+ * Return: The index identifying the var in the map and associated -+ * tracing_map_elts, or -EINVAL on error. -+ */ -+int tracing_map_add_var(struct tracing_map *map) -+{ -+ int ret = -EINVAL; -+ -+ if (map->n_vars < TRACING_MAP_VARS_MAX) -+ ret = map->n_vars++; -+ -+ return ret; -+} -+ - /** - * tracing_map_add_key_field - Add a field describing a tracing_map key - * @map: The tracing_map -@@ -280,6 +369,11 @@ static void tracing_map_elt_clear(struct tracing_map_elt *elt) - if (elt->fields[i].cmp_fn == tracing_map_cmp_atomic64) - atomic64_set(&elt->fields[i].sum, 0); - -+ for (i = 0; i < elt->map->n_vars; i++) { -+ atomic64_set(&elt->vars[i], 0); -+ elt->var_set[i] = false; -+ } -+ - if (elt->map->ops && elt->map->ops->elt_clear) - elt->map->ops->elt_clear(elt); - } -@@ -306,6 +400,8 @@ static void tracing_map_elt_free(struct tracing_map_elt *elt) - if (elt->map->ops && elt->map->ops->elt_free) - elt->map->ops->elt_free(elt); - kfree(elt->fields); -+ kfree(elt->vars); -+ kfree(elt->var_set); - kfree(elt->key); - kfree(elt); - } -@@ -333,6 +429,18 @@ static struct tracing_map_elt *tracing_map_elt_alloc(struct tracing_map *map) - goto free; - } - -+ elt->vars = kcalloc(map->n_vars, sizeof(*elt->vars), GFP_KERNEL); -+ if (!elt->vars) { -+ err = -ENOMEM; -+ goto free; -+ } -+ -+ elt->var_set = kcalloc(map->n_vars, sizeof(*elt->var_set), GFP_KERNEL); -+ if (!elt->var_set) { -+ err = -ENOMEM; -+ goto free; -+ } -+ - tracing_map_elt_init_fields(elt); - - if (map->ops && map->ops->elt_alloc) { -diff --git a/kernel/trace/tracing_map.h b/kernel/trace/tracing_map.h -index de57887c0670..053eb92b2d31 100644 ---- a/kernel/trace/tracing_map.h -+++ b/kernel/trace/tracing_map.h -@@ -10,6 +10,7 @@ - #define TRACING_MAP_VALS_MAX 3 - #define TRACING_MAP_FIELDS_MAX (TRACING_MAP_KEYS_MAX + \ - TRACING_MAP_VALS_MAX) -+#define TRACING_MAP_VARS_MAX 16 - #define TRACING_MAP_SORT_KEYS_MAX 2 - - typedef int (*tracing_map_cmp_fn_t) (void *val_a, void *val_b); -@@ -137,6 +138,8 @@ struct tracing_map_field { - struct tracing_map_elt { - struct tracing_map *map; - struct tracing_map_field *fields; -+ atomic64_t *vars; -+ bool *var_set; - void *key; - void *private_data; - }; -@@ -192,6 +195,7 @@ struct tracing_map { - int key_idx[TRACING_MAP_KEYS_MAX]; - unsigned int n_keys; - struct tracing_map_sort_key sort_key; -+ unsigned int n_vars; - atomic64_t hits; - atomic64_t drops; - }; -@@ -241,6 +245,7 @@ tracing_map_create(unsigned int map_bits, - extern int tracing_map_init(struct tracing_map *map); - - extern int tracing_map_add_sum_field(struct tracing_map *map); -+extern int tracing_map_add_var(struct tracing_map *map); - extern int tracing_map_add_key_field(struct tracing_map *map, - unsigned int offset, - tracing_map_cmp_fn_t cmp_fn); -@@ -260,7 +265,13 @@ extern int tracing_map_cmp_none(void *val_a, void *val_b); - - extern void tracing_map_update_sum(struct tracing_map_elt *elt, - unsigned int i, u64 n); -+extern void tracing_map_set_var(struct tracing_map_elt *elt, -+ unsigned int i, u64 n); -+extern bool tracing_map_var_set(struct tracing_map_elt *elt, unsigned int i); - extern u64 tracing_map_read_sum(struct tracing_map_elt *elt, unsigned int i); -+extern u64 tracing_map_read_var(struct tracing_map_elt *elt, unsigned int i); -+extern u64 tracing_map_read_var_once(struct tracing_map_elt *elt, unsigned int i); -+ - extern void tracing_map_set_field_descr(struct tracing_map *map, - unsigned int i, - unsigned int key_offset, --- -2.19.2 - diff --git a/kernel/patches-4.14.x-rt/0090-tracing-Add-hist_data-member-to-hist_field.patch b/kernel/patches-4.14.x-rt/0090-tracing-Add-hist_data-member-to-hist_field.patch deleted file mode 100644 index 80459ba02..000000000 --- a/kernel/patches-4.14.x-rt/0090-tracing-Add-hist_data-member-to-hist_field.patch +++ /dev/null @@ -1,88 +0,0 @@ -From fa4697e01eb4236a2e0ec5d294ae41bc0d3d8a35 Mon Sep 17 00:00:00 2001 -From: Tom Zanussi -Date: Mon, 15 Jan 2018 20:51:47 -0600 -Subject: [PATCH 090/450] tracing: Add hist_data member to hist_field - -Allow hist_data access via hist_field. Some users of hist_fields -require or will require more access to the associated hist_data. - -Link: http://lkml.kernel.org/r/d04cd0768f5228ebb4ac0ba4a847bc4d14d4826f.1516069914.git.tom.zanussi@linux.intel.com - -Signed-off-by: Tom Zanussi -Signed-off-by: Steven Rostedt (VMware) -(cherry picked from commit 14ab3edac407939009700c04215935576250e969) -Signed-off-by: Sebastian Andrzej Siewior ---- - kernel/trace/trace_events_hist.c | 14 +++++++++----- - 1 file changed, 9 insertions(+), 5 deletions(-) - -diff --git a/kernel/trace/trace_events_hist.c b/kernel/trace/trace_events_hist.c -index cd80bca34cec..ec58902145e9 100644 ---- a/kernel/trace/trace_events_hist.c -+++ b/kernel/trace/trace_events_hist.c -@@ -39,6 +39,7 @@ struct hist_field { - unsigned int offset; - unsigned int is_signed; - struct hist_field *operands[HIST_FIELD_OPERANDS_MAX]; -+ struct hist_trigger_data *hist_data; - }; - - static u64 hist_field_none(struct hist_field *field, void *event, -@@ -420,7 +421,8 @@ static void destroy_hist_field(struct hist_field *hist_field, - kfree(hist_field); - } - --static struct hist_field *create_hist_field(struct ftrace_event_field *field, -+static struct hist_field *create_hist_field(struct hist_trigger_data *hist_data, -+ struct ftrace_event_field *field, - unsigned long flags) - { - struct hist_field *hist_field; -@@ -432,6 +434,8 @@ static struct hist_field *create_hist_field(struct ftrace_event_field *field, - if (!hist_field) - return NULL; - -+ hist_field->hist_data = hist_data; -+ - if (flags & HIST_FIELD_FL_HITCOUNT) { - hist_field->fn = hist_field_counter; - goto out; -@@ -445,7 +449,7 @@ static struct hist_field *create_hist_field(struct ftrace_event_field *field, - if (flags & HIST_FIELD_FL_LOG2) { - unsigned long fl = flags & ~HIST_FIELD_FL_LOG2; - hist_field->fn = hist_field_log2; -- hist_field->operands[0] = create_hist_field(field, fl); -+ hist_field->operands[0] = create_hist_field(hist_data, field, fl); - hist_field->size = hist_field->operands[0]->size; - goto out; - } -@@ -498,7 +502,7 @@ static void destroy_hist_fields(struct hist_trigger_data *hist_data) - static int create_hitcount_val(struct hist_trigger_data *hist_data) - { - hist_data->fields[HITCOUNT_IDX] = -- create_hist_field(NULL, HIST_FIELD_FL_HITCOUNT); -+ create_hist_field(hist_data, NULL, HIST_FIELD_FL_HITCOUNT); - if (!hist_data->fields[HITCOUNT_IDX]) - return -ENOMEM; - -@@ -544,7 +548,7 @@ static int create_val_field(struct hist_trigger_data *hist_data, - } - } - -- hist_data->fields[val_idx] = create_hist_field(field, flags); -+ hist_data->fields[val_idx] = create_hist_field(hist_data, field, flags); - if (!hist_data->fields[val_idx]) { - ret = -ENOMEM; - goto out; -@@ -654,7 +658,7 @@ static int create_key_field(struct hist_trigger_data *hist_data, - } - } - -- hist_data->fields[key_idx] = create_hist_field(field, flags); -+ hist_data->fields[key_idx] = create_hist_field(hist_data, field, flags); - if (!hist_data->fields[key_idx]) { - ret = -ENOMEM; - goto out; --- -2.19.2 - diff --git a/kernel/patches-4.14.x-rt/0091-tracing-Add-usecs-modifier-for-hist-trigger-timestam.patch b/kernel/patches-4.14.x-rt/0091-tracing-Add-usecs-modifier-for-hist-trigger-timestam.patch deleted file mode 100644 index f84b504d9..000000000 --- a/kernel/patches-4.14.x-rt/0091-tracing-Add-usecs-modifier-for-hist-trigger-timestam.patch +++ /dev/null @@ -1,170 +0,0 @@ -From 89f6ad2173cbe3a78397f9a3ed07de978840b30d Mon Sep 17 00:00:00 2001 -From: Tom Zanussi -Date: Mon, 15 Jan 2018 20:51:48 -0600 -Subject: [PATCH 091/450] tracing: Add usecs modifier for hist trigger - timestamps - -Appending .usecs onto a common_timestamp field will cause the -timestamp value to be in microseconds instead of the default -nanoseconds. A typical latency histogram using usecs would look like -this: - - # echo 'hist:keys=pid,prio:ts0=common_timestamp.usecs ... - # echo 'hist:keys=next_pid:wakeup_lat=common_timestamp.usecs-$ts0 ... - -This also adds an external trace_clock_in_ns() to trace.c for the -timestamp conversion. - -Link: http://lkml.kernel.org/r/4e813705a170b3e13e97dc3135047362fb1a39f3.1516069914.git.tom.zanussi@linux.intel.com - -Signed-off-by: Tom Zanussi -Signed-off-by: Steven Rostedt (VMware) -(cherry picked from commit 4fa4fdb0fe5d0e87e05b0c5b443cec2269ec0609) -Signed-off-by: Sebastian Andrzej Siewior ---- - Documentation/trace/histogram.txt | 1 + - kernel/trace/trace.c | 13 +++++++++++-- - kernel/trace/trace.h | 2 ++ - kernel/trace/trace_events_hist.c | 28 ++++++++++++++++++++++------ - 4 files changed, 36 insertions(+), 8 deletions(-) - -diff --git a/Documentation/trace/histogram.txt b/Documentation/trace/histogram.txt -index a4143f04a097..25c94730d3fe 100644 ---- a/Documentation/trace/histogram.txt -+++ b/Documentation/trace/histogram.txt -@@ -74,6 +74,7 @@ - .syscall display a syscall id as a system call name - .execname display a common_pid as a program name - .log2 display log2 value rather than raw number -+ .usecs display a common_timestamp in microseconds - - Note that in general the semantics of a given field aren't - interpreted when applying a modifier to it, but there are some -diff --git a/kernel/trace/trace.c b/kernel/trace/trace.c -index c358cae7461f..1f695da375df 100644 ---- a/kernel/trace/trace.c -+++ b/kernel/trace/trace.c -@@ -1170,6 +1170,14 @@ static struct { - ARCH_TRACE_CLOCKS - }; - -+bool trace_clock_in_ns(struct trace_array *tr) -+{ -+ if (trace_clocks[tr->clock_id].in_ns) -+ return true; -+ -+ return false; -+} -+ - /* - * trace_parser_get_init - gets the buffer for trace parser - */ -@@ -4710,8 +4718,9 @@ static const char readme_msg[] = - "\t .sym display an address as a symbol\n" - "\t .sym-offset display an address as a symbol and offset\n" - "\t .execname display a common_pid as a program name\n" -- "\t .syscall display a syscall id as a syscall name\n\n" -- "\t .log2 display log2 value rather than raw number\n\n" -+ "\t .syscall display a syscall id as a syscall name\n" -+ "\t .log2 display log2 value rather than raw number\n" -+ "\t .usecs display a common_timestamp in microseconds\n\n" - "\t The 'pause' parameter can be used to pause an existing hist\n" - "\t trigger or to start a hist trigger but not log any events\n" - "\t until told to do so. 'continue' can be used to start or\n" -diff --git a/kernel/trace/trace.h b/kernel/trace/trace.h -index e2e12710d53c..92936a6fc29e 100644 ---- a/kernel/trace/trace.h -+++ b/kernel/trace/trace.h -@@ -289,6 +289,8 @@ extern void trace_array_put(struct trace_array *tr); - - extern int tracing_set_time_stamp_abs(struct trace_array *tr, bool abs); - -+extern bool trace_clock_in_ns(struct trace_array *tr); -+ - /* - * The global tracer (top) should be the first trace array added, - * but we check the flag anyway. -diff --git a/kernel/trace/trace_events_hist.c b/kernel/trace/trace_events_hist.c -index ec58902145e9..6d268e25d051 100644 ---- a/kernel/trace/trace_events_hist.c -+++ b/kernel/trace/trace_events_hist.c -@@ -90,12 +90,6 @@ static u64 hist_field_log2(struct hist_field *hist_field, void *event, - return (u64) ilog2(roundup_pow_of_two(val)); - } - --static u64 hist_field_timestamp(struct hist_field *hist_field, void *event, -- struct ring_buffer_event *rbe) --{ -- return ring_buffer_event_time_stamp(rbe); --} -- - #define DEFINE_HIST_FIELD_FN(type) \ - static u64 hist_field_##type(struct hist_field *hist_field, \ - void *event, \ -@@ -143,6 +137,7 @@ enum hist_field_flags { - HIST_FIELD_FL_STACKTRACE = 1 << 8, - HIST_FIELD_FL_LOG2 = 1 << 9, - HIST_FIELD_FL_TIMESTAMP = 1 << 10, -+ HIST_FIELD_FL_TIMESTAMP_USECS = 1 << 11, - }; - - struct hist_trigger_attrs { -@@ -153,6 +148,7 @@ struct hist_trigger_attrs { - bool pause; - bool cont; - bool clear; -+ bool ts_in_usecs; - unsigned int map_bits; - }; - -@@ -170,6 +166,20 @@ struct hist_trigger_data { - bool enable_timestamps; - }; - -+static u64 hist_field_timestamp(struct hist_field *hist_field, void *event, -+ struct ring_buffer_event *rbe) -+{ -+ struct hist_trigger_data *hist_data = hist_field->hist_data; -+ struct trace_array *tr = hist_data->event_file->tr; -+ -+ u64 ts = ring_buffer_event_time_stamp(rbe); -+ -+ if (hist_data->attrs->ts_in_usecs && trace_clock_in_ns(tr)) -+ ts = ns2usecs(ts); -+ -+ return ts; -+} -+ - static const char *hist_field_name(struct hist_field *field, - unsigned int level) - { -@@ -634,6 +644,8 @@ static int create_key_field(struct hist_trigger_data *hist_data, - flags |= HIST_FIELD_FL_SYSCALL; - else if (strcmp(field_str, "log2") == 0) - flags |= HIST_FIELD_FL_LOG2; -+ else if (strcmp(field_str, "usecs") == 0) -+ flags |= HIST_FIELD_FL_TIMESTAMP_USECS; - else { - ret = -EINVAL; - goto out; -@@ -643,6 +655,8 @@ static int create_key_field(struct hist_trigger_data *hist_data, - if (strcmp(field_name, "common_timestamp") == 0) { - flags |= HIST_FIELD_FL_TIMESTAMP; - hist_data->enable_timestamps = true; -+ if (flags & HIST_FIELD_FL_TIMESTAMP_USECS) -+ hist_data->attrs->ts_in_usecs = true; - key_size = sizeof(u64); - } else { - field = trace_find_event_field(file->event_call, field_name); -@@ -1243,6 +1257,8 @@ static const char *get_hist_field_flags(struct hist_field *hist_field) - flags_str = "syscall"; - else if (hist_field->flags & HIST_FIELD_FL_LOG2) - flags_str = "log2"; -+ else if (hist_field->flags & HIST_FIELD_FL_TIMESTAMP_USECS) -+ flags_str = "usecs"; - - return flags_str; - } --- -2.19.2 - diff --git a/kernel/patches-4.14.x-rt/0092-tracing-Add-variable-support-to-hist-triggers.patch b/kernel/patches-4.14.x-rt/0092-tracing-Add-variable-support-to-hist-triggers.patch deleted file mode 100644 index 870b1e700..000000000 --- a/kernel/patches-4.14.x-rt/0092-tracing-Add-variable-support-to-hist-triggers.patch +++ /dev/null @@ -1,788 +0,0 @@ -From 854d042f0bf85296ca85144c48f66475651cdaed Mon Sep 17 00:00:00 2001 -From: Tom Zanussi -Date: Mon, 15 Jan 2018 20:51:49 -0600 -Subject: [PATCH 092/450] tracing: Add variable support to hist triggers - -Add support for saving the value of a current event's event field by -assigning it to a variable that can be read by a subsequent event. - -The basic syntax for saving a variable is to simply prefix a unique -variable name not corresponding to any keyword along with an '=' sign -to any event field. - -Both keys and values can be saved and retrieved in this way: - - # echo 'hist:keys=next_pid:vals=$ts0:ts0=common_timestamp ... - # echo 'hist:timer_pid=common_pid:key=$timer_pid ...' - -If a variable isn't a key variable or prefixed with 'vals=', the -associated event field will be saved in a variable but won't be summed -as a value: - - # echo 'hist:keys=next_pid:ts1=common_timestamp:... - -Multiple variables can be assigned at the same time: - - # echo 'hist:keys=pid:vals=$ts0,$b,field2:ts0=common_timestamp,b=field1 ... - -Multiple (or single) variables can also be assigned at the same time -using separate assignments: - - # echo 'hist:keys=pid:vals=$ts0:ts0=common_timestamp:b=field1:c=field2 ... - -Variables set as above can be used by being referenced from another -event, as described in a subsequent patch. - -Link: http://lkml.kernel.org/r/fc93c4944d9719dbcb1d0067be627d44e98e2adc.1516069914.git.tom.zanussi@linux.intel.com - -Signed-off-by: Tom Zanussi -Signed-off-by: Baohong Liu -Signed-off-by: Steven Rostedt (VMware) -(cherry picked from commit b073711690e3af61965e53f197a56638b3c65a81) -Signed-off-by: Sebastian Andrzej Siewior ---- - kernel/trace/trace_events_hist.c | 370 +++++++++++++++++++++++++++---- - 1 file changed, 331 insertions(+), 39 deletions(-) - -diff --git a/kernel/trace/trace_events_hist.c b/kernel/trace/trace_events_hist.c -index 6d268e25d051..b4301542bb4a 100644 ---- a/kernel/trace/trace_events_hist.c -+++ b/kernel/trace/trace_events_hist.c -@@ -30,6 +30,13 @@ typedef u64 (*hist_field_fn_t) (struct hist_field *field, void *event, - struct ring_buffer_event *rbe); - - #define HIST_FIELD_OPERANDS_MAX 2 -+#define HIST_FIELDS_MAX (TRACING_MAP_FIELDS_MAX + TRACING_MAP_VARS_MAX) -+ -+struct hist_var { -+ char *name; -+ struct hist_trigger_data *hist_data; -+ unsigned int idx; -+}; - - struct hist_field { - struct ftrace_event_field *field; -@@ -40,6 +47,7 @@ struct hist_field { - unsigned int is_signed; - struct hist_field *operands[HIST_FIELD_OPERANDS_MAX]; - struct hist_trigger_data *hist_data; -+ struct hist_var var; - }; - - static u64 hist_field_none(struct hist_field *field, void *event, -@@ -138,6 +146,13 @@ enum hist_field_flags { - HIST_FIELD_FL_LOG2 = 1 << 9, - HIST_FIELD_FL_TIMESTAMP = 1 << 10, - HIST_FIELD_FL_TIMESTAMP_USECS = 1 << 11, -+ HIST_FIELD_FL_VAR = 1 << 12, -+}; -+ -+struct var_defs { -+ unsigned int n_vars; -+ char *name[TRACING_MAP_VARS_MAX]; -+ char *expr[TRACING_MAP_VARS_MAX]; - }; - - struct hist_trigger_attrs { -@@ -150,13 +165,19 @@ struct hist_trigger_attrs { - bool clear; - bool ts_in_usecs; - unsigned int map_bits; -+ -+ char *assignment_str[TRACING_MAP_VARS_MAX]; -+ unsigned int n_assignments; -+ -+ struct var_defs var_defs; - }; - - struct hist_trigger_data { -- struct hist_field *fields[TRACING_MAP_FIELDS_MAX]; -+ struct hist_field *fields[HIST_FIELDS_MAX]; - unsigned int n_vals; - unsigned int n_keys; - unsigned int n_fields; -+ unsigned int n_vars; - unsigned int key_size; - struct tracing_map_sort_key sort_keys[TRACING_MAP_SORT_KEYS_MAX]; - unsigned int n_sort_keys; -@@ -164,6 +185,7 @@ struct hist_trigger_data { - struct hist_trigger_attrs *attrs; - struct tracing_map *map; - bool enable_timestamps; -+ bool remove; - }; - - static u64 hist_field_timestamp(struct hist_field *hist_field, void *event, -@@ -180,6 +202,48 @@ static u64 hist_field_timestamp(struct hist_field *hist_field, void *event, - return ts; - } - -+static struct hist_field *find_var_field(struct hist_trigger_data *hist_data, -+ const char *var_name) -+{ -+ struct hist_field *hist_field, *found = NULL; -+ int i; -+ -+ for_each_hist_field(i, hist_data) { -+ hist_field = hist_data->fields[i]; -+ if (hist_field && hist_field->flags & HIST_FIELD_FL_VAR && -+ strcmp(hist_field->var.name, var_name) == 0) { -+ found = hist_field; -+ break; -+ } -+ } -+ -+ return found; -+} -+ -+static struct hist_field *find_var(struct hist_trigger_data *hist_data, -+ struct trace_event_file *file, -+ const char *var_name) -+{ -+ struct hist_trigger_data *test_data; -+ struct event_trigger_data *test; -+ struct hist_field *hist_field; -+ -+ hist_field = find_var_field(hist_data, var_name); -+ if (hist_field) -+ return hist_field; -+ -+ list_for_each_entry_rcu(test, &file->triggers, list) { -+ if (test->cmd_ops->trigger_type == ETT_EVENT_HIST) { -+ test_data = test->private_data; -+ hist_field = find_var_field(test_data, var_name); -+ if (hist_field) -+ return hist_field; -+ } -+ } -+ -+ return NULL; -+} -+ - static const char *hist_field_name(struct hist_field *field, - unsigned int level) - { -@@ -262,9 +326,14 @@ static int parse_map_size(char *str) - - static void destroy_hist_trigger_attrs(struct hist_trigger_attrs *attrs) - { -+ unsigned int i; -+ - if (!attrs) - return; - -+ for (i = 0; i < attrs->n_assignments; i++) -+ kfree(attrs->assignment_str[i]); -+ - kfree(attrs->name); - kfree(attrs->sort_key_str); - kfree(attrs->keys_str); -@@ -311,8 +380,22 @@ static int parse_assignment(char *str, struct hist_trigger_attrs *attrs) - goto out; - } - attrs->map_bits = map_bits; -- } else -- ret = -EINVAL; -+ } else { -+ char *assignment; -+ -+ if (attrs->n_assignments == TRACING_MAP_VARS_MAX) { -+ ret = -EINVAL; -+ goto out; -+ } -+ -+ assignment = kstrdup(str, GFP_KERNEL); -+ if (!assignment) { -+ ret = -ENOMEM; -+ goto out; -+ } -+ -+ attrs->assignment_str[attrs->n_assignments++] = assignment; -+ } - out: - return ret; - } -@@ -428,12 +511,15 @@ static void destroy_hist_field(struct hist_field *hist_field, - for (i = 0; i < HIST_FIELD_OPERANDS_MAX; i++) - destroy_hist_field(hist_field->operands[i], level + 1); - -+ kfree(hist_field->var.name); -+ - kfree(hist_field); - } - - static struct hist_field *create_hist_field(struct hist_trigger_data *hist_data, - struct ftrace_event_field *field, -- unsigned long flags) -+ unsigned long flags, -+ char *var_name) - { - struct hist_field *hist_field; - -@@ -459,7 +545,7 @@ static struct hist_field *create_hist_field(struct hist_trigger_data *hist_data, - if (flags & HIST_FIELD_FL_LOG2) { - unsigned long fl = flags & ~HIST_FIELD_FL_LOG2; - hist_field->fn = hist_field_log2; -- hist_field->operands[0] = create_hist_field(hist_data, field, fl); -+ hist_field->operands[0] = create_hist_field(hist_data, field, fl, NULL); - hist_field->size = hist_field->operands[0]->size; - goto out; - } -@@ -494,14 +580,23 @@ static struct hist_field *create_hist_field(struct hist_trigger_data *hist_data, - hist_field->field = field; - hist_field->flags = flags; - -+ if (var_name) { -+ hist_field->var.name = kstrdup(var_name, GFP_KERNEL); -+ if (!hist_field->var.name) -+ goto free; -+ } -+ - return hist_field; -+ free: -+ destroy_hist_field(hist_field, 0); -+ return NULL; - } - - static void destroy_hist_fields(struct hist_trigger_data *hist_data) - { - unsigned int i; - -- for (i = 0; i < TRACING_MAP_FIELDS_MAX; i++) { -+ for (i = 0; i < HIST_FIELDS_MAX; i++) { - if (hist_data->fields[i]) { - destroy_hist_field(hist_data->fields[i], 0); - hist_data->fields[i] = NULL; -@@ -512,11 +607,12 @@ static void destroy_hist_fields(struct hist_trigger_data *hist_data) - static int create_hitcount_val(struct hist_trigger_data *hist_data) - { - hist_data->fields[HITCOUNT_IDX] = -- create_hist_field(hist_data, NULL, HIST_FIELD_FL_HITCOUNT); -+ create_hist_field(hist_data, NULL, HIST_FIELD_FL_HITCOUNT, NULL); - if (!hist_data->fields[HITCOUNT_IDX]) - return -ENOMEM; - - hist_data->n_vals++; -+ hist_data->n_fields++; - - if (WARN_ON(hist_data->n_vals > TRACING_MAP_VALS_MAX)) - return -EINVAL; -@@ -524,19 +620,16 @@ static int create_hitcount_val(struct hist_trigger_data *hist_data) - return 0; - } - --static int create_val_field(struct hist_trigger_data *hist_data, -- unsigned int val_idx, -- struct trace_event_file *file, -- char *field_str) -+static int __create_val_field(struct hist_trigger_data *hist_data, -+ unsigned int val_idx, -+ struct trace_event_file *file, -+ char *var_name, char *field_str, -+ unsigned long flags) - { - struct ftrace_event_field *field = NULL; -- unsigned long flags = 0; - char *field_name; - int ret = 0; - -- if (WARN_ON(val_idx >= TRACING_MAP_VALS_MAX)) -- return -EINVAL; -- - field_name = strsep(&field_str, "."); - if (field_str) { - if (strcmp(field_str, "hex") == 0) -@@ -558,25 +651,58 @@ static int create_val_field(struct hist_trigger_data *hist_data, - } - } - -- hist_data->fields[val_idx] = create_hist_field(hist_data, field, flags); -+ hist_data->fields[val_idx] = create_hist_field(hist_data, field, flags, var_name); - if (!hist_data->fields[val_idx]) { - ret = -ENOMEM; - goto out; - } - - ++hist_data->n_vals; -+ ++hist_data->n_fields; - -- if (WARN_ON(hist_data->n_vals > TRACING_MAP_VALS_MAX)) -+ if (WARN_ON(hist_data->n_vals > TRACING_MAP_VALS_MAX + TRACING_MAP_VARS_MAX)) - ret = -EINVAL; - out: - return ret; - } - -+static int create_val_field(struct hist_trigger_data *hist_data, -+ unsigned int val_idx, -+ struct trace_event_file *file, -+ char *field_str) -+{ -+ if (WARN_ON(val_idx >= TRACING_MAP_VALS_MAX)) -+ return -EINVAL; -+ -+ return __create_val_field(hist_data, val_idx, file, NULL, field_str, 0); -+} -+ -+static int create_var_field(struct hist_trigger_data *hist_data, -+ unsigned int val_idx, -+ struct trace_event_file *file, -+ char *var_name, char *expr_str) -+{ -+ unsigned long flags = 0; -+ -+ if (WARN_ON(val_idx >= TRACING_MAP_VALS_MAX + TRACING_MAP_VARS_MAX)) -+ return -EINVAL; -+ if (find_var(hist_data, file, var_name) && !hist_data->remove) { -+ return -EINVAL; -+ } -+ -+ flags |= HIST_FIELD_FL_VAR; -+ hist_data->n_vars++; -+ if (WARN_ON(hist_data->n_vars > TRACING_MAP_VARS_MAX)) -+ return -EINVAL; -+ -+ return __create_val_field(hist_data, val_idx, file, var_name, expr_str, flags); -+} -+ - static int create_val_fields(struct hist_trigger_data *hist_data, - struct trace_event_file *file) - { - char *fields_str, *field_str; -- unsigned int i, j; -+ unsigned int i, j = 1; - int ret; - - ret = create_hitcount_val(hist_data); -@@ -596,12 +722,15 @@ static int create_val_fields(struct hist_trigger_data *hist_data, - field_str = strsep(&fields_str, ","); - if (!field_str) - break; -+ - if (strcmp(field_str, "hitcount") == 0) - continue; -+ - ret = create_val_field(hist_data, j++, file, field_str); - if (ret) - goto out; - } -+ - if (fields_str && (strcmp(fields_str, "hitcount") != 0)) - ret = -EINVAL; - out: -@@ -615,11 +744,12 @@ static int create_key_field(struct hist_trigger_data *hist_data, - char *field_str) - { - struct ftrace_event_field *field = NULL; -+ struct hist_field *hist_field = NULL; - unsigned long flags = 0; - unsigned int key_size; - int ret = 0; - -- if (WARN_ON(key_idx >= TRACING_MAP_FIELDS_MAX)) -+ if (WARN_ON(key_idx >= HIST_FIELDS_MAX)) - return -EINVAL; - - flags |= HIST_FIELD_FL_KEY; -@@ -627,6 +757,7 @@ static int create_key_field(struct hist_trigger_data *hist_data, - if (strcmp(field_str, "stacktrace") == 0) { - flags |= HIST_FIELD_FL_STACKTRACE; - key_size = sizeof(unsigned long) * HIST_STACKTRACE_DEPTH; -+ hist_field = create_hist_field(hist_data, NULL, flags, NULL); - } else { - char *field_name = strsep(&field_str, "."); - -@@ -672,7 +803,7 @@ static int create_key_field(struct hist_trigger_data *hist_data, - } - } - -- hist_data->fields[key_idx] = create_hist_field(hist_data, field, flags); -+ hist_data->fields[key_idx] = create_hist_field(hist_data, field, flags, NULL); - if (!hist_data->fields[key_idx]) { - ret = -ENOMEM; - goto out; -@@ -688,6 +819,7 @@ static int create_key_field(struct hist_trigger_data *hist_data, - } - - hist_data->n_keys++; -+ hist_data->n_fields++; - - if (WARN_ON(hist_data->n_keys > TRACING_MAP_KEYS_MAX)) - return -EINVAL; -@@ -731,21 +863,111 @@ static int create_key_fields(struct hist_trigger_data *hist_data, - return ret; - } - -+static int create_var_fields(struct hist_trigger_data *hist_data, -+ struct trace_event_file *file) -+{ -+ unsigned int i, j = hist_data->n_vals; -+ int ret = 0; -+ -+ unsigned int n_vars = hist_data->attrs->var_defs.n_vars; -+ -+ for (i = 0; i < n_vars; i++) { -+ char *var_name = hist_data->attrs->var_defs.name[i]; -+ char *expr = hist_data->attrs->var_defs.expr[i]; -+ -+ ret = create_var_field(hist_data, j++, file, var_name, expr); -+ if (ret) -+ goto out; -+ } -+ out: -+ return ret; -+} -+ -+static void free_var_defs(struct hist_trigger_data *hist_data) -+{ -+ unsigned int i; -+ -+ for (i = 0; i < hist_data->attrs->var_defs.n_vars; i++) { -+ kfree(hist_data->attrs->var_defs.name[i]); -+ kfree(hist_data->attrs->var_defs.expr[i]); -+ } -+ -+ hist_data->attrs->var_defs.n_vars = 0; -+} -+ -+static int parse_var_defs(struct hist_trigger_data *hist_data) -+{ -+ char *s, *str, *var_name, *field_str; -+ unsigned int i, j, n_vars = 0; -+ int ret = 0; -+ -+ for (i = 0; i < hist_data->attrs->n_assignments; i++) { -+ str = hist_data->attrs->assignment_str[i]; -+ for (j = 0; j < TRACING_MAP_VARS_MAX; j++) { -+ field_str = strsep(&str, ","); -+ if (!field_str) -+ break; -+ -+ var_name = strsep(&field_str, "="); -+ if (!var_name || !field_str) { -+ ret = -EINVAL; -+ goto free; -+ } -+ -+ if (n_vars == TRACING_MAP_VARS_MAX) { -+ ret = -EINVAL; -+ goto free; -+ } -+ -+ s = kstrdup(var_name, GFP_KERNEL); -+ if (!s) { -+ ret = -ENOMEM; -+ goto free; -+ } -+ hist_data->attrs->var_defs.name[n_vars] = s; -+ -+ s = kstrdup(field_str, GFP_KERNEL); -+ if (!s) { -+ kfree(hist_data->attrs->var_defs.name[n_vars]); -+ ret = -ENOMEM; -+ goto free; -+ } -+ hist_data->attrs->var_defs.expr[n_vars++] = s; -+ -+ hist_data->attrs->var_defs.n_vars = n_vars; -+ } -+ } -+ -+ return ret; -+ free: -+ free_var_defs(hist_data); -+ -+ return ret; -+} -+ - static int create_hist_fields(struct hist_trigger_data *hist_data, - struct trace_event_file *file) - { - int ret; - -+ ret = parse_var_defs(hist_data); -+ if (ret) -+ goto out; -+ - ret = create_val_fields(hist_data, file); - if (ret) - goto out; - -- ret = create_key_fields(hist_data, file); -+ ret = create_var_fields(hist_data, file); - if (ret) - goto out; - -- hist_data->n_fields = hist_data->n_vals + hist_data->n_keys; -+ ret = create_key_fields(hist_data, file); -+ if (ret) -+ goto out; - out: -+ free_var_defs(hist_data); -+ - return ret; - } - -@@ -768,7 +990,7 @@ static int create_sort_keys(struct hist_trigger_data *hist_data) - char *fields_str = hist_data->attrs->sort_key_str; - struct tracing_map_sort_key *sort_key; - int descending, ret = 0; -- unsigned int i, j; -+ unsigned int i, j, k; - - hist_data->n_sort_keys = 1; /* we always have at least one, hitcount */ - -@@ -816,12 +1038,19 @@ static int create_sort_keys(struct hist_trigger_data *hist_data) - continue; - } - -- for (j = 1; j < hist_data->n_fields; j++) { -+ for (j = 1, k = 1; j < hist_data->n_fields; j++) { -+ unsigned int idx; -+ - hist_field = hist_data->fields[j]; -+ if (hist_field->flags & HIST_FIELD_FL_VAR) -+ continue; -+ -+ idx = k++; -+ - test_name = hist_field_name(hist_field, 0); - - if (strcmp(field_name, test_name) == 0) { -- sort_key->field_idx = j; -+ sort_key->field_idx = idx; - descending = is_descending(field_str); - if (descending < 0) { - ret = descending; -@@ -836,6 +1065,7 @@ static int create_sort_keys(struct hist_trigger_data *hist_data) - break; - } - } -+ - hist_data->n_sort_keys = i; - out: - return ret; -@@ -876,12 +1106,19 @@ static int create_tracing_map_fields(struct hist_trigger_data *hist_data) - idx = tracing_map_add_key_field(map, - hist_field->offset, - cmp_fn); -- -- } else -+ } else if (!(hist_field->flags & HIST_FIELD_FL_VAR)) - idx = tracing_map_add_sum_field(map); - - if (idx < 0) - return idx; -+ -+ if (hist_field->flags & HIST_FIELD_FL_VAR) { -+ idx = tracing_map_add_var(map); -+ if (idx < 0) -+ return idx; -+ hist_field->var.idx = idx; -+ hist_field->var.hist_data = hist_data; -+ } - } - - return 0; -@@ -905,7 +1142,8 @@ static bool need_tracing_map_ops(struct hist_trigger_data *hist_data) - static struct hist_trigger_data * - create_hist_data(unsigned int map_bits, - struct hist_trigger_attrs *attrs, -- struct trace_event_file *file) -+ struct trace_event_file *file, -+ bool remove) - { - const struct tracing_map_ops *map_ops = NULL; - struct hist_trigger_data *hist_data; -@@ -916,6 +1154,7 @@ create_hist_data(unsigned int map_bits, - return ERR_PTR(-ENOMEM); - - hist_data->attrs = attrs; -+ hist_data->remove = remove; - - ret = create_hist_fields(hist_data, file); - if (ret) -@@ -962,14 +1201,28 @@ static void hist_trigger_elt_update(struct hist_trigger_data *hist_data, - struct ring_buffer_event *rbe) - { - struct hist_field *hist_field; -- unsigned int i; -+ unsigned int i, var_idx; - u64 hist_val; - - for_each_hist_val_field(i, hist_data) { - hist_field = hist_data->fields[i]; - hist_val = hist_field->fn(hist_field, rec, rbe); -+ if (hist_field->flags & HIST_FIELD_FL_VAR) { -+ var_idx = hist_field->var.idx; -+ tracing_map_set_var(elt, var_idx, hist_val); -+ continue; -+ } - tracing_map_update_sum(elt, i, hist_val); - } -+ -+ for_each_hist_key_field(i, hist_data) { -+ hist_field = hist_data->fields[i]; -+ if (hist_field->flags & HIST_FIELD_FL_VAR) { -+ hist_val = hist_field->fn(hist_field, rec, rbe); -+ var_idx = hist_field->var.idx; -+ tracing_map_set_var(elt, var_idx, hist_val); -+ } -+ } - } - - static inline void add_to_key(char *compound_key, void *key, -@@ -1144,6 +1397,9 @@ hist_trigger_entry_print(struct seq_file *m, - for (i = 1; i < hist_data->n_vals; i++) { - field_name = hist_field_name(hist_data->fields[i], 0); - -+ if (hist_data->fields[i]->flags & HIST_FIELD_FL_VAR) -+ continue; -+ - if (hist_data->fields[i]->flags & HIST_FIELD_FL_HEX) { - seq_printf(m, " %s: %10llx", field_name, - tracing_map_read_sum(elt, i)); -@@ -1267,6 +1523,9 @@ static void hist_field_print(struct seq_file *m, struct hist_field *hist_field) - { - const char *field_name = hist_field_name(hist_field, 0); - -+ if (hist_field->var.name) -+ seq_printf(m, "%s=", hist_field->var.name); -+ - if (hist_field->flags & HIST_FIELD_FL_TIMESTAMP) - seq_puts(m, "common_timestamp"); - else if (field_name) -@@ -1285,7 +1544,8 @@ static int event_hist_trigger_print(struct seq_file *m, - struct event_trigger_data *data) - { - struct hist_trigger_data *hist_data = data->private_data; -- struct hist_field *key_field; -+ struct hist_field *field; -+ bool have_var = false; - unsigned int i; - - seq_puts(m, "hist:"); -@@ -1296,25 +1556,47 @@ static int event_hist_trigger_print(struct seq_file *m, - seq_puts(m, "keys="); - - for_each_hist_key_field(i, hist_data) { -- key_field = hist_data->fields[i]; -+ field = hist_data->fields[i]; - - if (i > hist_data->n_vals) - seq_puts(m, ","); - -- if (key_field->flags & HIST_FIELD_FL_STACKTRACE) -+ if (field->flags & HIST_FIELD_FL_STACKTRACE) - seq_puts(m, "stacktrace"); - else -- hist_field_print(m, key_field); -+ hist_field_print(m, field); - } - - seq_puts(m, ":vals="); - - for_each_hist_val_field(i, hist_data) { -+ field = hist_data->fields[i]; -+ if (field->flags & HIST_FIELD_FL_VAR) { -+ have_var = true; -+ continue; -+ } -+ - if (i == HITCOUNT_IDX) - seq_puts(m, "hitcount"); - else { - seq_puts(m, ","); -- hist_field_print(m, hist_data->fields[i]); -+ hist_field_print(m, field); -+ } -+ } -+ -+ if (have_var) { -+ unsigned int n = 0; -+ -+ seq_puts(m, ":"); -+ -+ for_each_hist_val_field(i, hist_data) { -+ field = hist_data->fields[i]; -+ -+ if (field->flags & HIST_FIELD_FL_VAR) { -+ if (n++) -+ seq_puts(m, ","); -+ hist_field_print(m, field); -+ } - } - } - -@@ -1322,7 +1604,10 @@ static int event_hist_trigger_print(struct seq_file *m, - - for (i = 0; i < hist_data->n_sort_keys; i++) { - struct tracing_map_sort_key *sort_key; -- unsigned int idx; -+ unsigned int idx, first_key_idx; -+ -+ /* skip VAR vals */ -+ first_key_idx = hist_data->n_vals - hist_data->n_vars; - - sort_key = &hist_data->sort_keys[i]; - idx = sort_key->field_idx; -@@ -1335,8 +1620,11 @@ static int event_hist_trigger_print(struct seq_file *m, - - if (idx == HITCOUNT_IDX) - seq_puts(m, "hitcount"); -- else -+ else { -+ if (idx >= first_key_idx) -+ idx += hist_data->n_vars; - hist_field_print(m, hist_data->fields[idx]); -+ } - - if (sort_key->descending) - seq_puts(m, ".descending"); -@@ -1633,7 +1921,7 @@ static void hist_unregister_trigger(char *glob, struct event_trigger_ops *ops, - test->ops->free(test->ops, test); - - if (hist_data->enable_timestamps) { -- if (unregistered) -+ if (!hist_data->remove || unregistered) - tracing_set_time_stamp_abs(file->tr, false); - } - } -@@ -1666,12 +1954,16 @@ static int event_hist_trigger_func(struct event_command *cmd_ops, - struct hist_trigger_attrs *attrs; - struct event_trigger_ops *trigger_ops; - struct hist_trigger_data *hist_data; -+ bool remove = false; - char *trigger; - int ret = 0; - - if (!param) - return -EINVAL; - -+ if (glob[0] == '!') -+ remove = true; -+ - /* separate the trigger from the filter (k:v [if filter]) */ - trigger = strsep(¶m, " \t"); - if (!trigger) -@@ -1684,7 +1976,7 @@ static int event_hist_trigger_func(struct event_command *cmd_ops, - if (attrs->map_bits) - hist_trigger_bits = attrs->map_bits; - -- hist_data = create_hist_data(hist_trigger_bits, attrs, file); -+ hist_data = create_hist_data(hist_trigger_bits, attrs, file, remove); - if (IS_ERR(hist_data)) { - destroy_hist_trigger_attrs(attrs); - return PTR_ERR(hist_data); -@@ -1713,7 +2005,7 @@ static int event_hist_trigger_func(struct event_command *cmd_ops, - goto out_free; - } - -- if (glob[0] == '!') { -+ if (remove) { - cmd_ops->unreg(glob+1, trigger_ops, trigger_data, file); - ret = 0; - goto out_free; --- -2.19.2 - diff --git a/kernel/patches-4.14.x-rt/0093-tracing-Account-for-variables-in-named-trigger-compa.patch b/kernel/patches-4.14.x-rt/0093-tracing-Account-for-variables-in-named-trigger-compa.patch deleted file mode 100644 index fbe3d98b2..000000000 --- a/kernel/patches-4.14.x-rt/0093-tracing-Account-for-variables-in-named-trigger-compa.patch +++ /dev/null @@ -1,51 +0,0 @@ -From 3d8b3cac2bd3b3898bb0d37555cf677a1e9d9160 Mon Sep 17 00:00:00 2001 -From: Tom Zanussi -Date: Mon, 15 Jan 2018 20:51:50 -0600 -Subject: [PATCH 093/450] tracing: Account for variables in named trigger - compatibility - -Named triggers must also have the same set of variables in order to be -considered compatible - update the trigger match test to account for -that. - -The reason for this requirement is that named triggers with variables -are meant to allow one or more events to set the same variable. - -Link: http://lkml.kernel.org/r/a17eae6328a99917f9d5c66129c9fcd355279ee9.1516069914.git.tom.zanussi@linux.intel.com - -Signed-off-by: Tom Zanussi -Signed-off-by: Steven Rostedt (VMware) -(cherry picked from commit f94add7df3d72bc8e659f9491e25d91c9dae1b44) -Signed-off-by: Sebastian Andrzej Siewior ---- - kernel/trace/trace_events_hist.c | 7 ++++++- - 1 file changed, 6 insertions(+), 1 deletion(-) - -diff --git a/kernel/trace/trace_events_hist.c b/kernel/trace/trace_events_hist.c -index b4301542bb4a..68ff2491edd0 100644 ---- a/kernel/trace/trace_events_hist.c -+++ b/kernel/trace/trace_events_hist.c -@@ -1612,7 +1612,7 @@ static int event_hist_trigger_print(struct seq_file *m, - sort_key = &hist_data->sort_keys[i]; - idx = sort_key->field_idx; - -- if (WARN_ON(idx >= TRACING_MAP_FIELDS_MAX)) -+ if (WARN_ON(idx >= HIST_FIELDS_MAX)) - return -EINVAL; - - if (i > 0) -@@ -1800,6 +1800,11 @@ static bool hist_trigger_match(struct event_trigger_data *data, - return false; - if (key_field->is_signed != key_field_test->is_signed) - return false; -+ if (!!key_field->var.name != !!key_field_test->var.name) -+ return false; -+ if (key_field->var.name && -+ strcmp(key_field->var.name, key_field_test->var.name) != 0) -+ return false; - } - - for (i = 0; i < hist_data->n_sort_keys; i++) { --- -2.19.2 - diff --git a/kernel/patches-4.14.x-rt/0094-tracing-Move-get_hist_field_flags.patch b/kernel/patches-4.14.x-rt/0094-tracing-Move-get_hist_field_flags.patch deleted file mode 100644 index 8d39aa048..000000000 --- a/kernel/patches-4.14.x-rt/0094-tracing-Move-get_hist_field_flags.patch +++ /dev/null @@ -1,83 +0,0 @@ -From 01d1a46a1261ddc3dd9342e975f4ec39a2da543d Mon Sep 17 00:00:00 2001 -From: Tom Zanussi -Date: Mon, 15 Jan 2018 20:51:51 -0600 -Subject: [PATCH 094/450] tracing: Move get_hist_field_flags() - -Move get_hist_field_flags() to make it more easily accessible for new -code (and keep the move separate from new functionality). - -Link: http://lkml.kernel.org/r/32470f0a7047ec7a6e84ba5ec89d6142cc6ede7d.1516069914.git.tom.zanussi@linux.intel.com - -Signed-off-by: Tom Zanussi -Signed-off-by: Steven Rostedt (VMware) -(cherry picked from commit fde3bce553d359c01beb9a6fce4013b65076aff3) -Signed-off-by: Sebastian Andrzej Siewior ---- - kernel/trace/trace_events_hist.c | 44 ++++++++++++++++---------------- - 1 file changed, 22 insertions(+), 22 deletions(-) - -diff --git a/kernel/trace/trace_events_hist.c b/kernel/trace/trace_events_hist.c -index 68ff2491edd0..c6c24d6d2be8 100644 ---- a/kernel/trace/trace_events_hist.c -+++ b/kernel/trace/trace_events_hist.c -@@ -497,6 +497,28 @@ static const struct tracing_map_ops hist_trigger_elt_comm_ops = { - .elt_init = hist_trigger_elt_comm_init, - }; - -+static const char *get_hist_field_flags(struct hist_field *hist_field) -+{ -+ const char *flags_str = NULL; -+ -+ if (hist_field->flags & HIST_FIELD_FL_HEX) -+ flags_str = "hex"; -+ else if (hist_field->flags & HIST_FIELD_FL_SYM) -+ flags_str = "sym"; -+ else if (hist_field->flags & HIST_FIELD_FL_SYM_OFFSET) -+ flags_str = "sym-offset"; -+ else if (hist_field->flags & HIST_FIELD_FL_EXECNAME) -+ flags_str = "execname"; -+ else if (hist_field->flags & HIST_FIELD_FL_SYSCALL) -+ flags_str = "syscall"; -+ else if (hist_field->flags & HIST_FIELD_FL_LOG2) -+ flags_str = "log2"; -+ else if (hist_field->flags & HIST_FIELD_FL_TIMESTAMP_USECS) -+ flags_str = "usecs"; -+ -+ return flags_str; -+} -+ - static void destroy_hist_field(struct hist_field *hist_field, - unsigned int level) - { -@@ -1497,28 +1519,6 @@ const struct file_operations event_hist_fops = { - .release = single_release, - }; - --static const char *get_hist_field_flags(struct hist_field *hist_field) --{ -- const char *flags_str = NULL; -- -- if (hist_field->flags & HIST_FIELD_FL_HEX) -- flags_str = "hex"; -- else if (hist_field->flags & HIST_FIELD_FL_SYM) -- flags_str = "sym"; -- else if (hist_field->flags & HIST_FIELD_FL_SYM_OFFSET) -- flags_str = "sym-offset"; -- else if (hist_field->flags & HIST_FIELD_FL_EXECNAME) -- flags_str = "execname"; -- else if (hist_field->flags & HIST_FIELD_FL_SYSCALL) -- flags_str = "syscall"; -- else if (hist_field->flags & HIST_FIELD_FL_LOG2) -- flags_str = "log2"; -- else if (hist_field->flags & HIST_FIELD_FL_TIMESTAMP_USECS) -- flags_str = "usecs"; -- -- return flags_str; --} -- - static void hist_field_print(struct seq_file *m, struct hist_field *hist_field) - { - const char *field_name = hist_field_name(hist_field, 0); --- -2.19.2 - diff --git a/kernel/patches-4.14.x-rt/0095-tracing-Add-simple-expression-support-to-hist-trigge.patch b/kernel/patches-4.14.x-rt/0095-tracing-Add-simple-expression-support-to-hist-trigge.patch deleted file mode 100644 index 878f68471..000000000 --- a/kernel/patches-4.14.x-rt/0095-tracing-Add-simple-expression-support-to-hist-trigge.patch +++ /dev/null @@ -1,634 +0,0 @@ -From f7d4aeb6cc78f11fa4826c0d18b2807c976f4aee Mon Sep 17 00:00:00 2001 -From: Tom Zanussi -Date: Mon, 15 Jan 2018 20:51:52 -0600 -Subject: [PATCH 095/450] tracing: Add simple expression support to hist - triggers - -Add support for simple addition, subtraction, and unary expressions -(-(expr) and expr, where expr = b-a, a+b, a+b+c) to hist triggers, in -order to support a minimal set of useful inter-event calculations. - -These operations are needed for calculating latencies between events -(timestamp1-timestamp0) and for combined latencies (latencies over 3 -or more events). - -In the process, factor out some common code from key and value -parsing. - -Link: http://lkml.kernel.org/r/9a9308ead4fe32a433d9c7e95921fb798394f6b2.1516069914.git.tom.zanussi@linux.intel.com - -Signed-off-by: Tom Zanussi -[kbuild test robot fix, add static to parse_atom()] -Signed-off-by: Fengguang Wu -Signed-off-by: Steven Rostedt (VMware) -(cherry picked from commit 26c5cb5e4790fec96e3eba02c347e78fa72273a8) -Signed-off-by: Sebastian Andrzej Siewior ---- - kernel/trace/trace_events_hist.c | 487 ++++++++++++++++++++++++++----- - 1 file changed, 413 insertions(+), 74 deletions(-) - -diff --git a/kernel/trace/trace_events_hist.c b/kernel/trace/trace_events_hist.c -index c6c24d6d2be8..d2f01f3f26e1 100644 ---- a/kernel/trace/trace_events_hist.c -+++ b/kernel/trace/trace_events_hist.c -@@ -32,6 +32,13 @@ typedef u64 (*hist_field_fn_t) (struct hist_field *field, void *event, - #define HIST_FIELD_OPERANDS_MAX 2 - #define HIST_FIELDS_MAX (TRACING_MAP_FIELDS_MAX + TRACING_MAP_VARS_MAX) - -+enum field_op_id { -+ FIELD_OP_NONE, -+ FIELD_OP_PLUS, -+ FIELD_OP_MINUS, -+ FIELD_OP_UNARY_MINUS, -+}; -+ - struct hist_var { - char *name; - struct hist_trigger_data *hist_data; -@@ -48,6 +55,8 @@ struct hist_field { - struct hist_field *operands[HIST_FIELD_OPERANDS_MAX]; - struct hist_trigger_data *hist_data; - struct hist_var var; -+ enum field_op_id operator; -+ char *name; - }; - - static u64 hist_field_none(struct hist_field *field, void *event, -@@ -98,6 +107,41 @@ static u64 hist_field_log2(struct hist_field *hist_field, void *event, - return (u64) ilog2(roundup_pow_of_two(val)); - } - -+static u64 hist_field_plus(struct hist_field *hist_field, void *event, -+ struct ring_buffer_event *rbe) -+{ -+ struct hist_field *operand1 = hist_field->operands[0]; -+ struct hist_field *operand2 = hist_field->operands[1]; -+ -+ u64 val1 = operand1->fn(operand1, event, rbe); -+ u64 val2 = operand2->fn(operand2, event, rbe); -+ -+ return val1 + val2; -+} -+ -+static u64 hist_field_minus(struct hist_field *hist_field, void *event, -+ struct ring_buffer_event *rbe) -+{ -+ struct hist_field *operand1 = hist_field->operands[0]; -+ struct hist_field *operand2 = hist_field->operands[1]; -+ -+ u64 val1 = operand1->fn(operand1, event, rbe); -+ u64 val2 = operand2->fn(operand2, event, rbe); -+ -+ return val1 - val2; -+} -+ -+static u64 hist_field_unary_minus(struct hist_field *hist_field, void *event, -+ struct ring_buffer_event *rbe) -+{ -+ struct hist_field *operand = hist_field->operands[0]; -+ -+ s64 sval = (s64)operand->fn(operand, event, rbe); -+ u64 val = (u64)-sval; -+ -+ return val; -+} -+ - #define DEFINE_HIST_FIELD_FN(type) \ - static u64 hist_field_##type(struct hist_field *hist_field, \ - void *event, \ -@@ -147,6 +191,7 @@ enum hist_field_flags { - HIST_FIELD_FL_TIMESTAMP = 1 << 10, - HIST_FIELD_FL_TIMESTAMP_USECS = 1 << 11, - HIST_FIELD_FL_VAR = 1 << 12, -+ HIST_FIELD_FL_EXPR = 1 << 13, - }; - - struct var_defs { -@@ -258,6 +303,8 @@ static const char *hist_field_name(struct hist_field *field, - field_name = hist_field_name(field->operands[0], ++level); - else if (field->flags & HIST_FIELD_FL_TIMESTAMP) - field_name = "common_timestamp"; -+ else if (field->flags & HIST_FIELD_FL_EXPR) -+ field_name = field->name; - - if (field_name == NULL) - field_name = ""; -@@ -519,12 +566,104 @@ static const char *get_hist_field_flags(struct hist_field *hist_field) - return flags_str; - } - -+static void expr_field_str(struct hist_field *field, char *expr) -+{ -+ strcat(expr, hist_field_name(field, 0)); -+ -+ if (field->flags) { -+ const char *flags_str = get_hist_field_flags(field); -+ -+ if (flags_str) { -+ strcat(expr, "."); -+ strcat(expr, flags_str); -+ } -+ } -+} -+ -+static char *expr_str(struct hist_field *field, unsigned int level) -+{ -+ char *expr; -+ -+ if (level > 1) -+ return NULL; -+ -+ expr = kzalloc(MAX_FILTER_STR_VAL, GFP_KERNEL); -+ if (!expr) -+ return NULL; -+ -+ if (!field->operands[0]) { -+ expr_field_str(field, expr); -+ return expr; -+ } -+ -+ if (field->operator == FIELD_OP_UNARY_MINUS) { -+ char *subexpr; -+ -+ strcat(expr, "-("); -+ subexpr = expr_str(field->operands[0], ++level); -+ if (!subexpr) { -+ kfree(expr); -+ return NULL; -+ } -+ strcat(expr, subexpr); -+ strcat(expr, ")"); -+ -+ kfree(subexpr); -+ -+ return expr; -+ } -+ -+ expr_field_str(field->operands[0], expr); -+ -+ switch (field->operator) { -+ case FIELD_OP_MINUS: -+ strcat(expr, "-"); -+ break; -+ case FIELD_OP_PLUS: -+ strcat(expr, "+"); -+ break; -+ default: -+ kfree(expr); -+ return NULL; -+ } -+ -+ expr_field_str(field->operands[1], expr); -+ -+ return expr; -+} -+ -+static int contains_operator(char *str) -+{ -+ enum field_op_id field_op = FIELD_OP_NONE; -+ char *op; -+ -+ op = strpbrk(str, "+-"); -+ if (!op) -+ return FIELD_OP_NONE; -+ -+ switch (*op) { -+ case '-': -+ if (*str == '-') -+ field_op = FIELD_OP_UNARY_MINUS; -+ else -+ field_op = FIELD_OP_MINUS; -+ break; -+ case '+': -+ field_op = FIELD_OP_PLUS; -+ break; -+ default: -+ break; -+ } -+ -+ return field_op; -+} -+ - static void destroy_hist_field(struct hist_field *hist_field, - unsigned int level) - { - unsigned int i; - -- if (level > 2) -+ if (level > 3) - return; - - if (!hist_field) -@@ -534,6 +673,7 @@ static void destroy_hist_field(struct hist_field *hist_field, - destroy_hist_field(hist_field->operands[i], level + 1); - - kfree(hist_field->var.name); -+ kfree(hist_field->name); - - kfree(hist_field); - } -@@ -554,6 +694,9 @@ static struct hist_field *create_hist_field(struct hist_trigger_data *hist_data, - - hist_field->hist_data = hist_data; - -+ if (flags & HIST_FIELD_FL_EXPR) -+ goto out; /* caller will populate */ -+ - if (flags & HIST_FIELD_FL_HITCOUNT) { - hist_field->fn = hist_field_counter; - goto out; -@@ -626,6 +769,257 @@ static void destroy_hist_fields(struct hist_trigger_data *hist_data) - } - } - -+static struct ftrace_event_field * -+parse_field(struct hist_trigger_data *hist_data, struct trace_event_file *file, -+ char *field_str, unsigned long *flags) -+{ -+ struct ftrace_event_field *field = NULL; -+ char *field_name, *modifier, *str; -+ -+ modifier = str = kstrdup(field_str, GFP_KERNEL); -+ if (!modifier) -+ return ERR_PTR(-ENOMEM); -+ -+ field_name = strsep(&modifier, "."); -+ if (modifier) { -+ if (strcmp(modifier, "hex") == 0) -+ *flags |= HIST_FIELD_FL_HEX; -+ else if (strcmp(modifier, "sym") == 0) -+ *flags |= HIST_FIELD_FL_SYM; -+ else if (strcmp(modifier, "sym-offset") == 0) -+ *flags |= HIST_FIELD_FL_SYM_OFFSET; -+ else if ((strcmp(modifier, "execname") == 0) && -+ (strcmp(field_name, "common_pid") == 0)) -+ *flags |= HIST_FIELD_FL_EXECNAME; -+ else if (strcmp(modifier, "syscall") == 0) -+ *flags |= HIST_FIELD_FL_SYSCALL; -+ else if (strcmp(modifier, "log2") == 0) -+ *flags |= HIST_FIELD_FL_LOG2; -+ else if (strcmp(modifier, "usecs") == 0) -+ *flags |= HIST_FIELD_FL_TIMESTAMP_USECS; -+ else { -+ field = ERR_PTR(-EINVAL); -+ goto out; -+ } -+ } -+ -+ if (strcmp(field_name, "common_timestamp") == 0) { -+ *flags |= HIST_FIELD_FL_TIMESTAMP; -+ hist_data->enable_timestamps = true; -+ if (*flags & HIST_FIELD_FL_TIMESTAMP_USECS) -+ hist_data->attrs->ts_in_usecs = true; -+ } else { -+ field = trace_find_event_field(file->event_call, field_name); -+ if (!field || !field->size) { -+ field = ERR_PTR(-EINVAL); -+ goto out; -+ } -+ } -+ out: -+ kfree(str); -+ -+ return field; -+} -+ -+static struct hist_field *parse_atom(struct hist_trigger_data *hist_data, -+ struct trace_event_file *file, char *str, -+ unsigned long *flags, char *var_name) -+{ -+ struct ftrace_event_field *field = NULL; -+ struct hist_field *hist_field = NULL; -+ int ret = 0; -+ -+ field = parse_field(hist_data, file, str, flags); -+ if (IS_ERR(field)) { -+ ret = PTR_ERR(field); -+ goto out; -+ } -+ -+ hist_field = create_hist_field(hist_data, field, *flags, var_name); -+ if (!hist_field) { -+ ret = -ENOMEM; -+ goto out; -+ } -+ -+ return hist_field; -+ out: -+ return ERR_PTR(ret); -+} -+ -+static struct hist_field *parse_expr(struct hist_trigger_data *hist_data, -+ struct trace_event_file *file, -+ char *str, unsigned long flags, -+ char *var_name, unsigned int level); -+ -+static struct hist_field *parse_unary(struct hist_trigger_data *hist_data, -+ struct trace_event_file *file, -+ char *str, unsigned long flags, -+ char *var_name, unsigned int level) -+{ -+ struct hist_field *operand1, *expr = NULL; -+ unsigned long operand_flags; -+ int ret = 0; -+ char *s; -+ -+ // we support only -(xxx) i.e. explicit parens required -+ -+ if (level > 3) { -+ ret = -EINVAL; -+ goto free; -+ } -+ -+ str++; // skip leading '-' -+ -+ s = strchr(str, '('); -+ if (s) -+ str++; -+ else { -+ ret = -EINVAL; -+ goto free; -+ } -+ -+ s = strrchr(str, ')'); -+ if (s) -+ *s = '\0'; -+ else { -+ ret = -EINVAL; // no closing ')' -+ goto free; -+ } -+ -+ flags |= HIST_FIELD_FL_EXPR; -+ expr = create_hist_field(hist_data, NULL, flags, var_name); -+ if (!expr) { -+ ret = -ENOMEM; -+ goto free; -+ } -+ -+ operand_flags = 0; -+ operand1 = parse_expr(hist_data, file, str, operand_flags, NULL, ++level); -+ if (IS_ERR(operand1)) { -+ ret = PTR_ERR(operand1); -+ goto free; -+ } -+ -+ expr->flags |= operand1->flags & -+ (HIST_FIELD_FL_TIMESTAMP | HIST_FIELD_FL_TIMESTAMP_USECS); -+ expr->fn = hist_field_unary_minus; -+ expr->operands[0] = operand1; -+ expr->operator = FIELD_OP_UNARY_MINUS; -+ expr->name = expr_str(expr, 0); -+ -+ return expr; -+ free: -+ destroy_hist_field(expr, 0); -+ return ERR_PTR(ret); -+} -+ -+static int check_expr_operands(struct hist_field *operand1, -+ struct hist_field *operand2) -+{ -+ unsigned long operand1_flags = operand1->flags; -+ unsigned long operand2_flags = operand2->flags; -+ -+ if ((operand1_flags & HIST_FIELD_FL_TIMESTAMP_USECS) != -+ (operand2_flags & HIST_FIELD_FL_TIMESTAMP_USECS)) -+ return -EINVAL; -+ -+ return 0; -+} -+ -+static struct hist_field *parse_expr(struct hist_trigger_data *hist_data, -+ struct trace_event_file *file, -+ char *str, unsigned long flags, -+ char *var_name, unsigned int level) -+{ -+ struct hist_field *operand1 = NULL, *operand2 = NULL, *expr = NULL; -+ unsigned long operand_flags; -+ int field_op, ret = -EINVAL; -+ char *sep, *operand1_str; -+ -+ if (level > 3) -+ return ERR_PTR(-EINVAL); -+ -+ field_op = contains_operator(str); -+ -+ if (field_op == FIELD_OP_NONE) -+ return parse_atom(hist_data, file, str, &flags, var_name); -+ -+ if (field_op == FIELD_OP_UNARY_MINUS) -+ return parse_unary(hist_data, file, str, flags, var_name, ++level); -+ -+ switch (field_op) { -+ case FIELD_OP_MINUS: -+ sep = "-"; -+ break; -+ case FIELD_OP_PLUS: -+ sep = "+"; -+ break; -+ default: -+ goto free; -+ } -+ -+ operand1_str = strsep(&str, sep); -+ if (!operand1_str || !str) -+ goto free; -+ -+ operand_flags = 0; -+ operand1 = parse_atom(hist_data, file, operand1_str, -+ &operand_flags, NULL); -+ if (IS_ERR(operand1)) { -+ ret = PTR_ERR(operand1); -+ operand1 = NULL; -+ goto free; -+ } -+ -+ // rest of string could be another expression e.g. b+c in a+b+c -+ operand_flags = 0; -+ operand2 = parse_expr(hist_data, file, str, operand_flags, NULL, ++level); -+ if (IS_ERR(operand2)) { -+ ret = PTR_ERR(operand2); -+ operand2 = NULL; -+ goto free; -+ } -+ -+ ret = check_expr_operands(operand1, operand2); -+ if (ret) -+ goto free; -+ -+ flags |= HIST_FIELD_FL_EXPR; -+ -+ flags |= operand1->flags & -+ (HIST_FIELD_FL_TIMESTAMP | HIST_FIELD_FL_TIMESTAMP_USECS); -+ -+ expr = create_hist_field(hist_data, NULL, flags, var_name); -+ if (!expr) { -+ ret = -ENOMEM; -+ goto free; -+ } -+ -+ expr->operands[0] = operand1; -+ expr->operands[1] = operand2; -+ expr->operator = field_op; -+ expr->name = expr_str(expr, 0); -+ -+ switch (field_op) { -+ case FIELD_OP_MINUS: -+ expr->fn = hist_field_minus; -+ break; -+ case FIELD_OP_PLUS: -+ expr->fn = hist_field_plus; -+ break; -+ default: -+ goto free; -+ } -+ -+ return expr; -+ free: -+ destroy_hist_field(operand1, 0); -+ destroy_hist_field(operand2, 0); -+ destroy_hist_field(expr, 0); -+ -+ return ERR_PTR(ret); -+} -+ - static int create_hitcount_val(struct hist_trigger_data *hist_data) - { - hist_data->fields[HITCOUNT_IDX] = -@@ -648,37 +1042,17 @@ static int __create_val_field(struct hist_trigger_data *hist_data, - char *var_name, char *field_str, - unsigned long flags) - { -- struct ftrace_event_field *field = NULL; -- char *field_name; -+ struct hist_field *hist_field; - int ret = 0; - -- field_name = strsep(&field_str, "."); -- if (field_str) { -- if (strcmp(field_str, "hex") == 0) -- flags |= HIST_FIELD_FL_HEX; -- else { -- ret = -EINVAL; -- goto out; -- } -- } -- -- if (strcmp(field_name, "common_timestamp") == 0) { -- flags |= HIST_FIELD_FL_TIMESTAMP; -- hist_data->enable_timestamps = true; -- } else { -- field = trace_find_event_field(file->event_call, field_name); -- if (!field || !field->size) { -- ret = -EINVAL; -- goto out; -- } -- } -- -- hist_data->fields[val_idx] = create_hist_field(hist_data, field, flags, var_name); -- if (!hist_data->fields[val_idx]) { -- ret = -ENOMEM; -+ hist_field = parse_expr(hist_data, file, field_str, flags, var_name, 0); -+ if (IS_ERR(hist_field)) { -+ ret = PTR_ERR(hist_field); - goto out; - } - -+ hist_data->fields[val_idx] = hist_field; -+ - ++hist_data->n_vals; - ++hist_data->n_fields; - -@@ -765,8 +1139,8 @@ static int create_key_field(struct hist_trigger_data *hist_data, - struct trace_event_file *file, - char *field_str) - { -- struct ftrace_event_field *field = NULL; - struct hist_field *hist_field = NULL; -+ - unsigned long flags = 0; - unsigned int key_size; - int ret = 0; -@@ -781,60 +1155,24 @@ static int create_key_field(struct hist_trigger_data *hist_data, - key_size = sizeof(unsigned long) * HIST_STACKTRACE_DEPTH; - hist_field = create_hist_field(hist_data, NULL, flags, NULL); - } else { -- char *field_name = strsep(&field_str, "."); -- -- if (field_str) { -- if (strcmp(field_str, "hex") == 0) -- flags |= HIST_FIELD_FL_HEX; -- else if (strcmp(field_str, "sym") == 0) -- flags |= HIST_FIELD_FL_SYM; -- else if (strcmp(field_str, "sym-offset") == 0) -- flags |= HIST_FIELD_FL_SYM_OFFSET; -- else if ((strcmp(field_str, "execname") == 0) && -- (strcmp(field_name, "common_pid") == 0)) -- flags |= HIST_FIELD_FL_EXECNAME; -- else if (strcmp(field_str, "syscall") == 0) -- flags |= HIST_FIELD_FL_SYSCALL; -- else if (strcmp(field_str, "log2") == 0) -- flags |= HIST_FIELD_FL_LOG2; -- else if (strcmp(field_str, "usecs") == 0) -- flags |= HIST_FIELD_FL_TIMESTAMP_USECS; -- else { -- ret = -EINVAL; -- goto out; -- } -+ hist_field = parse_expr(hist_data, file, field_str, flags, -+ NULL, 0); -+ if (IS_ERR(hist_field)) { -+ ret = PTR_ERR(hist_field); -+ goto out; - } - -- if (strcmp(field_name, "common_timestamp") == 0) { -- flags |= HIST_FIELD_FL_TIMESTAMP; -- hist_data->enable_timestamps = true; -- if (flags & HIST_FIELD_FL_TIMESTAMP_USECS) -- hist_data->attrs->ts_in_usecs = true; -- key_size = sizeof(u64); -- } else { -- field = trace_find_event_field(file->event_call, field_name); -- if (!field || !field->size) { -- ret = -EINVAL; -- goto out; -- } -- -- if (is_string_field(field)) -- key_size = MAX_FILTER_STR_VAL; -- else -- key_size = field->size; -- } -+ key_size = hist_field->size; - } - -- hist_data->fields[key_idx] = create_hist_field(hist_data, field, flags, NULL); -- if (!hist_data->fields[key_idx]) { -- ret = -ENOMEM; -- goto out; -- } -+ hist_data->fields[key_idx] = hist_field; - - key_size = ALIGN(key_size, sizeof(u64)); - hist_data->fields[key_idx]->size = key_size; - hist_data->fields[key_idx]->offset = key_offset; -+ - hist_data->key_size += key_size; -+ - if (hist_data->key_size > HIST_KEY_SIZE_MAX) { - ret = -EINVAL; - goto out; -@@ -1419,7 +1757,8 @@ hist_trigger_entry_print(struct seq_file *m, - for (i = 1; i < hist_data->n_vals; i++) { - field_name = hist_field_name(hist_data->fields[i], 0); - -- if (hist_data->fields[i]->flags & HIST_FIELD_FL_VAR) -+ if (hist_data->fields[i]->flags & HIST_FIELD_FL_VAR || -+ hist_data->fields[i]->flags & HIST_FIELD_FL_EXPR) - continue; - - if (hist_data->fields[i]->flags & HIST_FIELD_FL_HEX) { --- -2.19.2 - diff --git a/kernel/patches-4.14.x-rt/0096-tracing-Generalize-per-element-hist-trigger-data.patch b/kernel/patches-4.14.x-rt/0096-tracing-Generalize-per-element-hist-trigger-data.patch deleted file mode 100644 index 0c591dae8..000000000 --- a/kernel/patches-4.14.x-rt/0096-tracing-Generalize-per-element-hist-trigger-data.patch +++ /dev/null @@ -1,164 +0,0 @@ -From c3de8611575e0e51050210b128f9340bb006964a Mon Sep 17 00:00:00 2001 -From: Tom Zanussi -Date: Mon, 15 Jan 2018 20:51:53 -0600 -Subject: [PATCH 096/450] tracing: Generalize per-element hist trigger data - -Up until now, hist triggers only needed per-element support for saving -'comm' data, which was saved directly as a private data pointer. - -In anticipation of the need to save other data besides 'comm', add a -new hist_elt_data struct for the purpose, and switch the current -'comm'-related code over to that. - -Link: http://lkml.kernel.org/r/4502c338c965ddf5fc19fb1ec4764391e001ed4b.1516069914.git.tom.zanussi@linux.intel.com - -Signed-off-by: Tom Zanussi -Signed-off-by: Steven Rostedt (VMware) -(cherry picked from commit 8102d0cb859d223564b17afb01e33701f57191d1) -Signed-off-by: Sebastian Andrzej Siewior ---- - kernel/trace/trace_events_hist.c | 76 ++++++++++++++++++-------------- - 1 file changed, 43 insertions(+), 33 deletions(-) - -diff --git a/kernel/trace/trace_events_hist.c b/kernel/trace/trace_events_hist.c -index d2f01f3f26e1..893f65ce31a5 100644 ---- a/kernel/trace/trace_events_hist.c -+++ b/kernel/trace/trace_events_hist.c -@@ -289,6 +289,10 @@ static struct hist_field *find_var(struct hist_trigger_data *hist_data, - return NULL; - } - -+struct hist_elt_data { -+ char *comm; -+}; -+ - static const char *hist_field_name(struct hist_field *field, - unsigned int level) - { -@@ -503,45 +507,61 @@ static inline void save_comm(char *comm, struct task_struct *task) - memcpy(comm, task->comm, TASK_COMM_LEN); - } - --static void hist_trigger_elt_comm_free(struct tracing_map_elt *elt) -+static void hist_elt_data_free(struct hist_elt_data *elt_data) -+{ -+ kfree(elt_data->comm); -+ kfree(elt_data); -+} -+ -+static void hist_trigger_elt_data_free(struct tracing_map_elt *elt) - { -- kfree((char *)elt->private_data); -+ struct hist_elt_data *elt_data = elt->private_data; -+ -+ hist_elt_data_free(elt_data); - } - --static int hist_trigger_elt_comm_alloc(struct tracing_map_elt *elt) -+static int hist_trigger_elt_data_alloc(struct tracing_map_elt *elt) - { - struct hist_trigger_data *hist_data = elt->map->private_data; -+ unsigned int size = TASK_COMM_LEN; -+ struct hist_elt_data *elt_data; - struct hist_field *key_field; - unsigned int i; - -+ elt_data = kzalloc(sizeof(*elt_data), GFP_KERNEL); -+ if (!elt_data) -+ return -ENOMEM; -+ - for_each_hist_key_field(i, hist_data) { - key_field = hist_data->fields[i]; - - if (key_field->flags & HIST_FIELD_FL_EXECNAME) { -- unsigned int size = TASK_COMM_LEN + 1; -- -- elt->private_data = kzalloc(size, GFP_KERNEL); -- if (!elt->private_data) -+ elt_data->comm = kzalloc(size, GFP_KERNEL); -+ if (!elt_data->comm) { -+ kfree(elt_data); - return -ENOMEM; -+ } - break; - } - } - -+ elt->private_data = elt_data; -+ - return 0; - } - --static void hist_trigger_elt_comm_init(struct tracing_map_elt *elt) -+static void hist_trigger_elt_data_init(struct tracing_map_elt *elt) - { -- char *comm = elt->private_data; -+ struct hist_elt_data *elt_data = elt->private_data; - -- if (comm) -- save_comm(comm, current); -+ if (elt_data->comm) -+ save_comm(elt_data->comm, current); - } - --static const struct tracing_map_ops hist_trigger_elt_comm_ops = { -- .elt_alloc = hist_trigger_elt_comm_alloc, -- .elt_free = hist_trigger_elt_comm_free, -- .elt_init = hist_trigger_elt_comm_init, -+static const struct tracing_map_ops hist_trigger_elt_data_ops = { -+ .elt_alloc = hist_trigger_elt_data_alloc, -+ .elt_free = hist_trigger_elt_data_free, -+ .elt_init = hist_trigger_elt_data_init, - }; - - static const char *get_hist_field_flags(struct hist_field *hist_field) -@@ -1484,21 +1504,6 @@ static int create_tracing_map_fields(struct hist_trigger_data *hist_data) - return 0; - } - --static bool need_tracing_map_ops(struct hist_trigger_data *hist_data) --{ -- struct hist_field *key_field; -- unsigned int i; -- -- for_each_hist_key_field(i, hist_data) { -- key_field = hist_data->fields[i]; -- -- if (key_field->flags & HIST_FIELD_FL_EXECNAME) -- return true; -- } -- -- return false; --} -- - static struct hist_trigger_data * - create_hist_data(unsigned int map_bits, - struct hist_trigger_attrs *attrs, -@@ -1524,8 +1529,7 @@ create_hist_data(unsigned int map_bits, - if (ret) - goto free; - -- if (need_tracing_map_ops(hist_data)) -- map_ops = &hist_trigger_elt_comm_ops; -+ map_ops = &hist_trigger_elt_data_ops; - - hist_data->map = tracing_map_create(map_bits, hist_data->key_size, - map_ops, hist_data); -@@ -1713,7 +1717,13 @@ hist_trigger_entry_print(struct seq_file *m, - seq_printf(m, "%s: [%llx] %-55s", field_name, - uval, str); - } else if (key_field->flags & HIST_FIELD_FL_EXECNAME) { -- char *comm = elt->private_data; -+ struct hist_elt_data *elt_data = elt->private_data; -+ char *comm; -+ -+ if (WARN_ON_ONCE(!elt_data)) -+ return; -+ -+ comm = elt_data->comm; - - uval = *(u64 *)(key + key_field->offset); - seq_printf(m, "%s: %-16s[%10llu]", field_name, --- -2.19.2 - diff --git a/kernel/patches-4.14.x-rt/0097-tracing-Pass-tracing_map_elt-to-hist_field-accessor-.patch b/kernel/patches-4.14.x-rt/0097-tracing-Pass-tracing_map_elt-to-hist_field-accessor-.patch deleted file mode 100644 index 36b685d33..000000000 --- a/kernel/patches-4.14.x-rt/0097-tracing-Pass-tracing_map_elt-to-hist_field-accessor-.patch +++ /dev/null @@ -1,231 +0,0 @@ -From d2ce1d4ffafada6db4b9b4f8fe5561f40cb03b76 Mon Sep 17 00:00:00 2001 -From: Tom Zanussi -Date: Mon, 15 Jan 2018 20:51:54 -0600 -Subject: [PATCH 097/450] tracing: Pass tracing_map_elt to hist_field accessor - functions - -Some accessor functions, such as for variable references, require -access to a corrsponding tracing_map_elt. - -Add a tracing_map_elt param to the function signature and update the -accessor functions accordingly. - -Link: http://lkml.kernel.org/r/e0f292b068e9e4948da1d5af21b5ae0efa9b5717.1516069914.git.tom.zanussi@linux.intel.com - -Signed-off-by: Tom Zanussi -Signed-off-by: Steven Rostedt (VMware) -(cherry picked from commit 8405bbbbc9dc0d88ffc92848cb8f0bda2c7a1b30) -Signed-off-by: Sebastian Andrzej Siewior ---- - kernel/trace/trace_events_hist.c | 91 ++++++++++++++++++++------------ - 1 file changed, 57 insertions(+), 34 deletions(-) - -diff --git a/kernel/trace/trace_events_hist.c b/kernel/trace/trace_events_hist.c -index 893f65ce31a5..becf37b2b0da 100644 ---- a/kernel/trace/trace_events_hist.c -+++ b/kernel/trace/trace_events_hist.c -@@ -26,8 +26,10 @@ - - struct hist_field; - --typedef u64 (*hist_field_fn_t) (struct hist_field *field, void *event, -- struct ring_buffer_event *rbe); -+typedef u64 (*hist_field_fn_t) (struct hist_field *field, -+ struct tracing_map_elt *elt, -+ struct ring_buffer_event *rbe, -+ void *event); - - #define HIST_FIELD_OPERANDS_MAX 2 - #define HIST_FIELDS_MAX (TRACING_MAP_FIELDS_MAX + TRACING_MAP_VARS_MAX) -@@ -59,28 +61,36 @@ struct hist_field { - char *name; - }; - --static u64 hist_field_none(struct hist_field *field, void *event, -- struct ring_buffer_event *rbe) -+static u64 hist_field_none(struct hist_field *field, -+ struct tracing_map_elt *elt, -+ struct ring_buffer_event *rbe, -+ void *event) - { - return 0; - } - --static u64 hist_field_counter(struct hist_field *field, void *event, -- struct ring_buffer_event *rbe) -+static u64 hist_field_counter(struct hist_field *field, -+ struct tracing_map_elt *elt, -+ struct ring_buffer_event *rbe, -+ void *event) - { - return 1; - } - --static u64 hist_field_string(struct hist_field *hist_field, void *event, -- struct ring_buffer_event *rbe) -+static u64 hist_field_string(struct hist_field *hist_field, -+ struct tracing_map_elt *elt, -+ struct ring_buffer_event *rbe, -+ void *event) - { - char *addr = (char *)(event + hist_field->field->offset); - - return (u64)(unsigned long)addr; - } - --static u64 hist_field_dynstring(struct hist_field *hist_field, void *event, -- struct ring_buffer_event *rbe) -+static u64 hist_field_dynstring(struct hist_field *hist_field, -+ struct tracing_map_elt *elt, -+ struct ring_buffer_event *rbe, -+ void *event) - { - u32 str_item = *(u32 *)(event + hist_field->field->offset); - int str_loc = str_item & 0xffff; -@@ -89,54 +99,64 @@ static u64 hist_field_dynstring(struct hist_field *hist_field, void *event, - return (u64)(unsigned long)addr; - } - --static u64 hist_field_pstring(struct hist_field *hist_field, void *event, -- struct ring_buffer_event *rbe) -+static u64 hist_field_pstring(struct hist_field *hist_field, -+ struct tracing_map_elt *elt, -+ struct ring_buffer_event *rbe, -+ void *event) - { - char **addr = (char **)(event + hist_field->field->offset); - - return (u64)(unsigned long)*addr; - } - --static u64 hist_field_log2(struct hist_field *hist_field, void *event, -- struct ring_buffer_event *rbe) -+static u64 hist_field_log2(struct hist_field *hist_field, -+ struct tracing_map_elt *elt, -+ struct ring_buffer_event *rbe, -+ void *event) - { - struct hist_field *operand = hist_field->operands[0]; - -- u64 val = operand->fn(operand, event, rbe); -+ u64 val = operand->fn(operand, elt, rbe, event); - - return (u64) ilog2(roundup_pow_of_two(val)); - } - --static u64 hist_field_plus(struct hist_field *hist_field, void *event, -- struct ring_buffer_event *rbe) -+static u64 hist_field_plus(struct hist_field *hist_field, -+ struct tracing_map_elt *elt, -+ struct ring_buffer_event *rbe, -+ void *event) - { - struct hist_field *operand1 = hist_field->operands[0]; - struct hist_field *operand2 = hist_field->operands[1]; - -- u64 val1 = operand1->fn(operand1, event, rbe); -- u64 val2 = operand2->fn(operand2, event, rbe); -+ u64 val1 = operand1->fn(operand1, elt, rbe, event); -+ u64 val2 = operand2->fn(operand2, elt, rbe, event); - - return val1 + val2; - } - --static u64 hist_field_minus(struct hist_field *hist_field, void *event, -- struct ring_buffer_event *rbe) -+static u64 hist_field_minus(struct hist_field *hist_field, -+ struct tracing_map_elt *elt, -+ struct ring_buffer_event *rbe, -+ void *event) - { - struct hist_field *operand1 = hist_field->operands[0]; - struct hist_field *operand2 = hist_field->operands[1]; - -- u64 val1 = operand1->fn(operand1, event, rbe); -- u64 val2 = operand2->fn(operand2, event, rbe); -+ u64 val1 = operand1->fn(operand1, elt, rbe, event); -+ u64 val2 = operand2->fn(operand2, elt, rbe, event); - - return val1 - val2; - } - --static u64 hist_field_unary_minus(struct hist_field *hist_field, void *event, -- struct ring_buffer_event *rbe) -+static u64 hist_field_unary_minus(struct hist_field *hist_field, -+ struct tracing_map_elt *elt, -+ struct ring_buffer_event *rbe, -+ void *event) - { - struct hist_field *operand = hist_field->operands[0]; - -- s64 sval = (s64)operand->fn(operand, event, rbe); -+ s64 sval = (s64)operand->fn(operand, elt, rbe, event); - u64 val = (u64)-sval; - - return val; -@@ -144,8 +164,9 @@ static u64 hist_field_unary_minus(struct hist_field *hist_field, void *event, - - #define DEFINE_HIST_FIELD_FN(type) \ - static u64 hist_field_##type(struct hist_field *hist_field, \ -- void *event, \ -- struct ring_buffer_event *rbe) \ -+ struct tracing_map_elt *elt, \ -+ struct ring_buffer_event *rbe, \ -+ void *event) \ - { \ - type *addr = (type *)(event + hist_field->field->offset); \ - \ -@@ -233,8 +254,10 @@ struct hist_trigger_data { - bool remove; - }; - --static u64 hist_field_timestamp(struct hist_field *hist_field, void *event, -- struct ring_buffer_event *rbe) -+static u64 hist_field_timestamp(struct hist_field *hist_field, -+ struct tracing_map_elt *elt, -+ struct ring_buffer_event *rbe, -+ void *event) - { - struct hist_trigger_data *hist_data = hist_field->hist_data; - struct trace_array *tr = hist_data->event_file->tr; -@@ -1570,7 +1593,7 @@ static void hist_trigger_elt_update(struct hist_trigger_data *hist_data, - - for_each_hist_val_field(i, hist_data) { - hist_field = hist_data->fields[i]; -- hist_val = hist_field->fn(hist_field, rec, rbe); -+ hist_val = hist_field->fn(hist_field, elt, rbe, rec); - if (hist_field->flags & HIST_FIELD_FL_VAR) { - var_idx = hist_field->var.idx; - tracing_map_set_var(elt, var_idx, hist_val); -@@ -1582,7 +1605,7 @@ static void hist_trigger_elt_update(struct hist_trigger_data *hist_data, - for_each_hist_key_field(i, hist_data) { - hist_field = hist_data->fields[i]; - if (hist_field->flags & HIST_FIELD_FL_VAR) { -- hist_val = hist_field->fn(hist_field, rec, rbe); -+ hist_val = hist_field->fn(hist_field, elt, rbe, rec); - var_idx = hist_field->var.idx; - tracing_map_set_var(elt, var_idx, hist_val); - } -@@ -1620,9 +1643,9 @@ static void event_hist_trigger(struct event_trigger_data *data, void *rec, - bool use_compound_key = (hist_data->n_keys > 1); - unsigned long entries[HIST_STACKTRACE_DEPTH]; - char compound_key[HIST_KEY_SIZE_MAX]; -+ struct tracing_map_elt *elt = NULL; - struct stack_trace stacktrace; - struct hist_field *key_field; -- struct tracing_map_elt *elt; - u64 field_contents; - void *key = NULL; - unsigned int i; -@@ -1643,7 +1666,7 @@ static void event_hist_trigger(struct event_trigger_data *data, void *rec, - - key = entries; - } else { -- field_contents = key_field->fn(key_field, rec, rbe); -+ field_contents = key_field->fn(key_field, elt, rbe, rec); - if (key_field->flags & HIST_FIELD_FL_STRING) { - key = (void *)(unsigned long)field_contents; - use_compound_key = true; --- -2.19.2 - diff --git a/kernel/patches-4.14.x-rt/0098-tracing-Add-hist_field-type-field.patch b/kernel/patches-4.14.x-rt/0098-tracing-Add-hist_field-type-field.patch deleted file mode 100644 index 193d4bd7a..000000000 --- a/kernel/patches-4.14.x-rt/0098-tracing-Add-hist_field-type-field.patch +++ /dev/null @@ -1,123 +0,0 @@ -From d333c65c795cde2de88f5759101bc29c36058992 Mon Sep 17 00:00:00 2001 -From: Tom Zanussi -Date: Mon, 15 Jan 2018 20:51:55 -0600 -Subject: [PATCH 098/450] tracing: Add hist_field 'type' field - -Future support for synthetic events requires hist_field 'type' -information, so add a field for that. - -Also, make other hist_field attribute usage consistent (size, -is_signed, etc). - -Link: http://lkml.kernel.org/r/3fd12a2e86316b05151ba0d7c68268e780af2c9d.1516069914.git.tom.zanussi@linux.intel.com - -Signed-off-by: Tom Zanussi -Signed-off-by: Steven Rostedt (VMware) -(cherry picked from commit d544a468f82526e97cc80c18a019708eb203b00a) -Signed-off-by: Sebastian Andrzej Siewior ---- - kernel/trace/trace_events_hist.c | 33 ++++++++++++++++++++++++++++++++ - 1 file changed, 33 insertions(+) - -diff --git a/kernel/trace/trace_events_hist.c b/kernel/trace/trace_events_hist.c -index becf37b2b0da..6e60cb794dcd 100644 ---- a/kernel/trace/trace_events_hist.c -+++ b/kernel/trace/trace_events_hist.c -@@ -54,6 +54,7 @@ struct hist_field { - unsigned int size; - unsigned int offset; - unsigned int is_signed; -+ const char *type; - struct hist_field *operands[HIST_FIELD_OPERANDS_MAX]; - struct hist_trigger_data *hist_data; - struct hist_var var; -@@ -717,6 +718,7 @@ static void destroy_hist_field(struct hist_field *hist_field, - - kfree(hist_field->var.name); - kfree(hist_field->name); -+ kfree(hist_field->type); - - kfree(hist_field); - } -@@ -742,6 +744,10 @@ static struct hist_field *create_hist_field(struct hist_trigger_data *hist_data, - - if (flags & HIST_FIELD_FL_HITCOUNT) { - hist_field->fn = hist_field_counter; -+ hist_field->size = sizeof(u64); -+ hist_field->type = kstrdup("u64", GFP_KERNEL); -+ if (!hist_field->type) -+ goto free; - goto out; - } - -@@ -755,12 +761,18 @@ static struct hist_field *create_hist_field(struct hist_trigger_data *hist_data, - hist_field->fn = hist_field_log2; - hist_field->operands[0] = create_hist_field(hist_data, field, fl, NULL); - hist_field->size = hist_field->operands[0]->size; -+ hist_field->type = kstrdup(hist_field->operands[0]->type, GFP_KERNEL); -+ if (!hist_field->type) -+ goto free; - goto out; - } - - if (flags & HIST_FIELD_FL_TIMESTAMP) { - hist_field->fn = hist_field_timestamp; - hist_field->size = sizeof(u64); -+ hist_field->type = kstrdup("u64", GFP_KERNEL); -+ if (!hist_field->type) -+ goto free; - goto out; - } - -@@ -770,6 +782,11 @@ static struct hist_field *create_hist_field(struct hist_trigger_data *hist_data, - if (is_string_field(field)) { - flags |= HIST_FIELD_FL_STRING; - -+ hist_field->size = MAX_FILTER_STR_VAL; -+ hist_field->type = kstrdup(field->type, GFP_KERNEL); -+ if (!hist_field->type) -+ goto free; -+ - if (field->filter_type == FILTER_STATIC_STRING) - hist_field->fn = hist_field_string; - else if (field->filter_type == FILTER_DYN_STRING) -@@ -777,6 +794,12 @@ static struct hist_field *create_hist_field(struct hist_trigger_data *hist_data, - else - hist_field->fn = hist_field_pstring; - } else { -+ hist_field->size = field->size; -+ hist_field->is_signed = field->is_signed; -+ hist_field->type = kstrdup(field->type, GFP_KERNEL); -+ if (!hist_field->type) -+ goto free; -+ - hist_field->fn = select_value_fn(field->size, - field->is_signed); - if (!hist_field->fn) { -@@ -949,6 +972,11 @@ static struct hist_field *parse_unary(struct hist_trigger_data *hist_data, - expr->operands[0] = operand1; - expr->operator = FIELD_OP_UNARY_MINUS; - expr->name = expr_str(expr, 0); -+ expr->type = kstrdup(operand1->type, GFP_KERNEL); -+ if (!expr->type) { -+ ret = -ENOMEM; -+ goto free; -+ } - - return expr; - free: -@@ -1042,6 +1070,11 @@ static struct hist_field *parse_expr(struct hist_trigger_data *hist_data, - expr->operands[1] = operand2; - expr->operator = field_op; - expr->name = expr_str(expr, 0); -+ expr->type = kstrdup(operand1->type, GFP_KERNEL); -+ if (!expr->type) { -+ ret = -ENOMEM; -+ goto free; -+ } - - switch (field_op) { - case FIELD_OP_MINUS: --- -2.19.2 - diff --git a/kernel/patches-4.14.x-rt/0099-tracing-Add-variable-reference-handling-to-hist-trig.patch b/kernel/patches-4.14.x-rt/0099-tracing-Add-variable-reference-handling-to-hist-trig.patch deleted file mode 100644 index 00af9fdd4..000000000 --- a/kernel/patches-4.14.x-rt/0099-tracing-Add-variable-reference-handling-to-hist-trig.patch +++ /dev/null @@ -1,967 +0,0 @@ -From ba702b3dad3b6d3b50caac695d99bf3e30e34199 Mon Sep 17 00:00:00 2001 -From: Tom Zanussi -Date: Mon, 15 Jan 2018 20:51:56 -0600 -Subject: [PATCH 099/450] tracing: Add variable reference handling to hist - triggers - -Add the necessary infrastructure to allow the variables defined on one -event to be referenced in another. This allows variables set by a -previous event to be referenced and used in expressions combining the -variable values saved by that previous event and the event fields of -the current event. For example, here's how a latency can be -calculated and saved into yet another variable named 'wakeup_lat': - - # echo 'hist:keys=pid,prio:ts0=common_timestamp ... - # echo 'hist:keys=next_pid:wakeup_lat=common_timestamp-$ts0 ... - -In the first event, the event's timetamp is saved into the variable -ts0. In the next line, ts0 is subtracted from the second event's -timestamp to produce the latency. - -Further users of variable references will be described in subsequent -patches, such as for instance how the 'wakeup_lat' variable above can -be displayed in a latency histogram. - -Link: http://lkml.kernel.org/r/b1d3e6975374e34d501ff417c20189c3f9b2c7b8.1516069914.git.tom.zanussi@linux.intel.com - -Signed-off-by: Tom Zanussi -Signed-off-by: Steven Rostedt (VMware) -(cherry picked from commit 434c1d5831194e72e6eb30d46534d75b5a985eb7) -Signed-off-by: Sebastian Andrzej Siewior ---- - kernel/trace/trace.c | 2 + - kernel/trace/trace.h | 3 + - kernel/trace/trace_events_hist.c | 661 +++++++++++++++++++++++++++- - kernel/trace/trace_events_trigger.c | 6 + - 4 files changed, 656 insertions(+), 16 deletions(-) - -diff --git a/kernel/trace/trace.c b/kernel/trace/trace.c -index 1f695da375df..5b35e4257cc5 100644 ---- a/kernel/trace/trace.c -+++ b/kernel/trace/trace.c -@@ -7801,6 +7801,7 @@ static int instance_mkdir(const char *name) - - INIT_LIST_HEAD(&tr->systems); - INIT_LIST_HEAD(&tr->events); -+ INIT_LIST_HEAD(&tr->hist_vars); - - if (allocate_trace_buffers(tr, trace_buf_size) < 0) - goto out_free_tr; -@@ -8553,6 +8554,7 @@ __init static int tracer_alloc_buffers(void) - - INIT_LIST_HEAD(&global_trace.systems); - INIT_LIST_HEAD(&global_trace.events); -+ INIT_LIST_HEAD(&global_trace.hist_vars); - list_add(&global_trace.list, &ftrace_trace_arrays); - - apply_trace_boot_options(); -diff --git a/kernel/trace/trace.h b/kernel/trace/trace.h -index 92936a6fc29e..5975d5f5c4bc 100644 ---- a/kernel/trace/trace.h -+++ b/kernel/trace/trace.h -@@ -274,6 +274,7 @@ struct trace_array { - int function_enabled; - #endif - int time_stamp_abs_ref; -+ struct list_head hist_vars; - }; - - enum { -@@ -1550,6 +1551,8 @@ extern void pause_named_trigger(struct event_trigger_data *data); - extern void unpause_named_trigger(struct event_trigger_data *data); - extern void set_named_trigger_data(struct event_trigger_data *data, - struct event_trigger_data *named_data); -+extern struct event_trigger_data * -+get_named_trigger_data(struct event_trigger_data *data); - extern int register_event_command(struct event_command *cmd); - extern int unregister_event_command(struct event_command *cmd); - extern int register_trigger_hist_enable_disable_cmds(void); -diff --git a/kernel/trace/trace_events_hist.c b/kernel/trace/trace_events_hist.c -index 6e60cb794dcd..2bc1f76915ef 100644 ---- a/kernel/trace/trace_events_hist.c -+++ b/kernel/trace/trace_events_hist.c -@@ -59,7 +59,12 @@ struct hist_field { - struct hist_trigger_data *hist_data; - struct hist_var var; - enum field_op_id operator; -+ char *system; -+ char *event_name; - char *name; -+ unsigned int var_idx; -+ unsigned int var_ref_idx; -+ bool read_once; - }; - - static u64 hist_field_none(struct hist_field *field, -@@ -214,6 +219,7 @@ enum hist_field_flags { - HIST_FIELD_FL_TIMESTAMP_USECS = 1 << 11, - HIST_FIELD_FL_VAR = 1 << 12, - HIST_FIELD_FL_EXPR = 1 << 13, -+ HIST_FIELD_FL_VAR_REF = 1 << 14, - }; - - struct var_defs { -@@ -253,6 +259,8 @@ struct hist_trigger_data { - struct tracing_map *map; - bool enable_timestamps; - bool remove; -+ struct hist_field *var_refs[TRACING_MAP_VARS_MAX]; -+ unsigned int n_var_refs; - }; - - static u64 hist_field_timestamp(struct hist_field *hist_field, -@@ -271,6 +279,214 @@ static u64 hist_field_timestamp(struct hist_field *hist_field, - return ts; - } - -+struct hist_var_data { -+ struct list_head list; -+ struct hist_trigger_data *hist_data; -+}; -+ -+static struct hist_field * -+check_field_for_var_ref(struct hist_field *hist_field, -+ struct hist_trigger_data *var_data, -+ unsigned int var_idx) -+{ -+ struct hist_field *found = NULL; -+ -+ if (hist_field && hist_field->flags & HIST_FIELD_FL_VAR_REF) { -+ if (hist_field->var.idx == var_idx && -+ hist_field->var.hist_data == var_data) { -+ found = hist_field; -+ } -+ } -+ -+ return found; -+} -+ -+static struct hist_field * -+check_field_for_var_refs(struct hist_trigger_data *hist_data, -+ struct hist_field *hist_field, -+ struct hist_trigger_data *var_data, -+ unsigned int var_idx, -+ unsigned int level) -+{ -+ struct hist_field *found = NULL; -+ unsigned int i; -+ -+ if (level > 3) -+ return found; -+ -+ if (!hist_field) -+ return found; -+ -+ found = check_field_for_var_ref(hist_field, var_data, var_idx); -+ if (found) -+ return found; -+ -+ for (i = 0; i < HIST_FIELD_OPERANDS_MAX; i++) { -+ struct hist_field *operand; -+ -+ operand = hist_field->operands[i]; -+ found = check_field_for_var_refs(hist_data, operand, var_data, -+ var_idx, level + 1); -+ if (found) -+ return found; -+ } -+ -+ return found; -+} -+ -+static struct hist_field *find_var_ref(struct hist_trigger_data *hist_data, -+ struct hist_trigger_data *var_data, -+ unsigned int var_idx) -+{ -+ struct hist_field *hist_field, *found = NULL; -+ unsigned int i; -+ -+ for_each_hist_field(i, hist_data) { -+ hist_field = hist_data->fields[i]; -+ found = check_field_for_var_refs(hist_data, hist_field, -+ var_data, var_idx, 0); -+ if (found) -+ return found; -+ } -+ -+ return found; -+} -+ -+static struct hist_field *find_any_var_ref(struct hist_trigger_data *hist_data, -+ unsigned int var_idx) -+{ -+ struct trace_array *tr = hist_data->event_file->tr; -+ struct hist_field *found = NULL; -+ struct hist_var_data *var_data; -+ -+ list_for_each_entry(var_data, &tr->hist_vars, list) { -+ if (var_data->hist_data == hist_data) -+ continue; -+ found = find_var_ref(var_data->hist_data, hist_data, var_idx); -+ if (found) -+ break; -+ } -+ -+ return found; -+} -+ -+static bool check_var_refs(struct hist_trigger_data *hist_data) -+{ -+ struct hist_field *field; -+ bool found = false; -+ int i; -+ -+ for_each_hist_field(i, hist_data) { -+ field = hist_data->fields[i]; -+ if (field && field->flags & HIST_FIELD_FL_VAR) { -+ if (find_any_var_ref(hist_data, field->var.idx)) { -+ found = true; -+ break; -+ } -+ } -+ } -+ -+ return found; -+} -+ -+static struct hist_var_data *find_hist_vars(struct hist_trigger_data *hist_data) -+{ -+ struct trace_array *tr = hist_data->event_file->tr; -+ struct hist_var_data *var_data, *found = NULL; -+ -+ list_for_each_entry(var_data, &tr->hist_vars, list) { -+ if (var_data->hist_data == hist_data) { -+ found = var_data; -+ break; -+ } -+ } -+ -+ return found; -+} -+ -+static bool field_has_hist_vars(struct hist_field *hist_field, -+ unsigned int level) -+{ -+ int i; -+ -+ if (level > 3) -+ return false; -+ -+ if (!hist_field) -+ return false; -+ -+ if (hist_field->flags & HIST_FIELD_FL_VAR || -+ hist_field->flags & HIST_FIELD_FL_VAR_REF) -+ return true; -+ -+ for (i = 0; i < HIST_FIELD_OPERANDS_MAX; i++) { -+ struct hist_field *operand; -+ -+ operand = hist_field->operands[i]; -+ if (field_has_hist_vars(operand, level + 1)) -+ return true; -+ } -+ -+ return false; -+} -+ -+static bool has_hist_vars(struct hist_trigger_data *hist_data) -+{ -+ struct hist_field *hist_field; -+ int i; -+ -+ for_each_hist_field(i, hist_data) { -+ hist_field = hist_data->fields[i]; -+ if (field_has_hist_vars(hist_field, 0)) -+ return true; -+ } -+ -+ return false; -+} -+ -+static int save_hist_vars(struct hist_trigger_data *hist_data) -+{ -+ struct trace_array *tr = hist_data->event_file->tr; -+ struct hist_var_data *var_data; -+ -+ var_data = find_hist_vars(hist_data); -+ if (var_data) -+ return 0; -+ -+ if (trace_array_get(tr) < 0) -+ return -ENODEV; -+ -+ var_data = kzalloc(sizeof(*var_data), GFP_KERNEL); -+ if (!var_data) { -+ trace_array_put(tr); -+ return -ENOMEM; -+ } -+ -+ var_data->hist_data = hist_data; -+ list_add(&var_data->list, &tr->hist_vars); -+ -+ return 0; -+} -+ -+static void remove_hist_vars(struct hist_trigger_data *hist_data) -+{ -+ struct trace_array *tr = hist_data->event_file->tr; -+ struct hist_var_data *var_data; -+ -+ var_data = find_hist_vars(hist_data); -+ if (!var_data) -+ return; -+ -+ if (WARN_ON(check_var_refs(hist_data))) -+ return; -+ -+ list_del(&var_data->list); -+ -+ kfree(var_data); -+ -+ trace_array_put(tr); -+} -+ - static struct hist_field *find_var_field(struct hist_trigger_data *hist_data, - const char *var_name) - { -@@ -313,10 +529,137 @@ static struct hist_field *find_var(struct hist_trigger_data *hist_data, - return NULL; - } - -+static struct trace_event_file *find_var_file(struct trace_array *tr, -+ char *system, -+ char *event_name, -+ char *var_name) -+{ -+ struct hist_trigger_data *var_hist_data; -+ struct hist_var_data *var_data; -+ struct trace_event_file *file, *found = NULL; -+ -+ if (system) -+ return find_event_file(tr, system, event_name); -+ -+ list_for_each_entry(var_data, &tr->hist_vars, list) { -+ var_hist_data = var_data->hist_data; -+ file = var_hist_data->event_file; -+ if (file == found) -+ continue; -+ -+ if (find_var_field(var_hist_data, var_name)) { -+ if (found) -+ return NULL; -+ -+ found = file; -+ } -+ } -+ -+ return found; -+} -+ -+static struct hist_field *find_file_var(struct trace_event_file *file, -+ const char *var_name) -+{ -+ struct hist_trigger_data *test_data; -+ struct event_trigger_data *test; -+ struct hist_field *hist_field; -+ -+ list_for_each_entry_rcu(test, &file->triggers, list) { -+ if (test->cmd_ops->trigger_type == ETT_EVENT_HIST) { -+ test_data = test->private_data; -+ hist_field = find_var_field(test_data, var_name); -+ if (hist_field) -+ return hist_field; -+ } -+ } -+ -+ return NULL; -+} -+ -+static struct hist_field *find_event_var(struct hist_trigger_data *hist_data, -+ char *system, -+ char *event_name, -+ char *var_name) -+{ -+ struct trace_array *tr = hist_data->event_file->tr; -+ struct hist_field *hist_field = NULL; -+ struct trace_event_file *file; -+ -+ file = find_var_file(tr, system, event_name, var_name); -+ if (!file) -+ return NULL; -+ -+ hist_field = find_file_var(file, var_name); -+ -+ return hist_field; -+} -+ - struct hist_elt_data { - char *comm; -+ u64 *var_ref_vals; - }; - -+static u64 hist_field_var_ref(struct hist_field *hist_field, -+ struct tracing_map_elt *elt, -+ struct ring_buffer_event *rbe, -+ void *event) -+{ -+ struct hist_elt_data *elt_data; -+ u64 var_val = 0; -+ -+ elt_data = elt->private_data; -+ var_val = elt_data->var_ref_vals[hist_field->var_ref_idx]; -+ -+ return var_val; -+} -+ -+static bool resolve_var_refs(struct hist_trigger_data *hist_data, void *key, -+ u64 *var_ref_vals, bool self) -+{ -+ struct hist_trigger_data *var_data; -+ struct tracing_map_elt *var_elt; -+ struct hist_field *hist_field; -+ unsigned int i, var_idx; -+ bool resolved = true; -+ u64 var_val = 0; -+ -+ for (i = 0; i < hist_data->n_var_refs; i++) { -+ hist_field = hist_data->var_refs[i]; -+ var_idx = hist_field->var.idx; -+ var_data = hist_field->var.hist_data; -+ -+ if (var_data == NULL) { -+ resolved = false; -+ break; -+ } -+ -+ if ((self && var_data != hist_data) || -+ (!self && var_data == hist_data)) -+ continue; -+ -+ var_elt = tracing_map_lookup(var_data->map, key); -+ if (!var_elt) { -+ resolved = false; -+ break; -+ } -+ -+ if (!tracing_map_var_set(var_elt, var_idx)) { -+ resolved = false; -+ break; -+ } -+ -+ if (self || !hist_field->read_once) -+ var_val = tracing_map_read_var(var_elt, var_idx); -+ else -+ var_val = tracing_map_read_var_once(var_elt, var_idx); -+ -+ var_ref_vals[i] = var_val; -+ } -+ -+ return resolved; -+} -+ - static const char *hist_field_name(struct hist_field *field, - unsigned int level) - { -@@ -331,8 +674,20 @@ static const char *hist_field_name(struct hist_field *field, - field_name = hist_field_name(field->operands[0], ++level); - else if (field->flags & HIST_FIELD_FL_TIMESTAMP) - field_name = "common_timestamp"; -- else if (field->flags & HIST_FIELD_FL_EXPR) -- field_name = field->name; -+ else if (field->flags & HIST_FIELD_FL_EXPR || -+ field->flags & HIST_FIELD_FL_VAR_REF) { -+ if (field->system) { -+ static char full_name[MAX_FILTER_STR_VAL]; -+ -+ strcat(full_name, field->system); -+ strcat(full_name, "."); -+ strcat(full_name, field->event_name); -+ strcat(full_name, "."); -+ strcat(full_name, field->name); -+ field_name = full_name; -+ } else -+ field_name = field->name; -+ } - - if (field_name == NULL) - field_name = ""; -@@ -612,6 +967,9 @@ static const char *get_hist_field_flags(struct hist_field *hist_field) - - static void expr_field_str(struct hist_field *field, char *expr) - { -+ if (field->flags & HIST_FIELD_FL_VAR_REF) -+ strcat(expr, "$"); -+ - strcat(expr, hist_field_name(field, 0)); - - if (field->flags) { -@@ -742,6 +1100,11 @@ static struct hist_field *create_hist_field(struct hist_trigger_data *hist_data, - if (flags & HIST_FIELD_FL_EXPR) - goto out; /* caller will populate */ - -+ if (flags & HIST_FIELD_FL_VAR_REF) { -+ hist_field->fn = hist_field_var_ref; -+ goto out; -+ } -+ - if (flags & HIST_FIELD_FL_HITCOUNT) { - hist_field->fn = hist_field_counter; - hist_field->size = sizeof(u64); -@@ -835,6 +1198,144 @@ static void destroy_hist_fields(struct hist_trigger_data *hist_data) - } - } - -+static int init_var_ref(struct hist_field *ref_field, -+ struct hist_field *var_field, -+ char *system, char *event_name) -+{ -+ int err = 0; -+ -+ ref_field->var.idx = var_field->var.idx; -+ ref_field->var.hist_data = var_field->hist_data; -+ ref_field->size = var_field->size; -+ ref_field->is_signed = var_field->is_signed; -+ ref_field->flags |= var_field->flags & -+ (HIST_FIELD_FL_TIMESTAMP | HIST_FIELD_FL_TIMESTAMP_USECS); -+ -+ if (system) { -+ ref_field->system = kstrdup(system, GFP_KERNEL); -+ if (!ref_field->system) -+ return -ENOMEM; -+ } -+ -+ if (event_name) { -+ ref_field->event_name = kstrdup(event_name, GFP_KERNEL); -+ if (!ref_field->event_name) { -+ err = -ENOMEM; -+ goto free; -+ } -+ } -+ -+ ref_field->name = kstrdup(var_field->var.name, GFP_KERNEL); -+ if (!ref_field->name) { -+ err = -ENOMEM; -+ goto free; -+ } -+ -+ ref_field->type = kstrdup(var_field->type, GFP_KERNEL); -+ if (!ref_field->type) { -+ err = -ENOMEM; -+ goto free; -+ } -+ out: -+ return err; -+ free: -+ kfree(ref_field->system); -+ kfree(ref_field->event_name); -+ kfree(ref_field->name); -+ -+ goto out; -+} -+ -+static struct hist_field *create_var_ref(struct hist_field *var_field, -+ char *system, char *event_name) -+{ -+ unsigned long flags = HIST_FIELD_FL_VAR_REF; -+ struct hist_field *ref_field; -+ -+ ref_field = create_hist_field(var_field->hist_data, NULL, flags, NULL); -+ if (ref_field) { -+ if (init_var_ref(ref_field, var_field, system, event_name)) { -+ destroy_hist_field(ref_field, 0); -+ return NULL; -+ } -+ } -+ -+ return ref_field; -+} -+ -+static bool is_var_ref(char *var_name) -+{ -+ if (!var_name || strlen(var_name) < 2 || var_name[0] != '$') -+ return false; -+ -+ return true; -+} -+ -+static char *field_name_from_var(struct hist_trigger_data *hist_data, -+ char *var_name) -+{ -+ char *name, *field; -+ unsigned int i; -+ -+ for (i = 0; i < hist_data->attrs->var_defs.n_vars; i++) { -+ name = hist_data->attrs->var_defs.name[i]; -+ -+ if (strcmp(var_name, name) == 0) { -+ field = hist_data->attrs->var_defs.expr[i]; -+ if (contains_operator(field) || is_var_ref(field)) -+ continue; -+ return field; -+ } -+ } -+ -+ return NULL; -+} -+ -+static char *local_field_var_ref(struct hist_trigger_data *hist_data, -+ char *system, char *event_name, -+ char *var_name) -+{ -+ struct trace_event_call *call; -+ -+ if (system && event_name) { -+ call = hist_data->event_file->event_call; -+ -+ if (strcmp(system, call->class->system) != 0) -+ return NULL; -+ -+ if (strcmp(event_name, trace_event_name(call)) != 0) -+ return NULL; -+ } -+ -+ if (!!system != !!event_name) -+ return NULL; -+ -+ if (!is_var_ref(var_name)) -+ return NULL; -+ -+ var_name++; -+ -+ return field_name_from_var(hist_data, var_name); -+} -+ -+static struct hist_field *parse_var_ref(struct hist_trigger_data *hist_data, -+ char *system, char *event_name, -+ char *var_name) -+{ -+ struct hist_field *var_field = NULL, *ref_field = NULL; -+ -+ if (!is_var_ref(var_name)) -+ return NULL; -+ -+ var_name++; -+ -+ var_field = find_event_var(hist_data, system, event_name, var_name); -+ if (var_field) -+ ref_field = create_var_ref(var_field, system, event_name); -+ -+ return ref_field; -+} -+ - static struct ftrace_event_field * - parse_field(struct hist_trigger_data *hist_data, struct trace_event_file *file, - char *field_str, unsigned long *flags) -@@ -891,10 +1392,40 @@ static struct hist_field *parse_atom(struct hist_trigger_data *hist_data, - struct trace_event_file *file, char *str, - unsigned long *flags, char *var_name) - { -+ char *s, *ref_system = NULL, *ref_event = NULL, *ref_var = str; - struct ftrace_event_field *field = NULL; - struct hist_field *hist_field = NULL; - int ret = 0; - -+ s = strchr(str, '.'); -+ if (s) { -+ s = strchr(++s, '.'); -+ if (s) { -+ ref_system = strsep(&str, "."); -+ if (!str) { -+ ret = -EINVAL; -+ goto out; -+ } -+ ref_event = strsep(&str, "."); -+ if (!str) { -+ ret = -EINVAL; -+ goto out; -+ } -+ ref_var = str; -+ } -+ } -+ -+ s = local_field_var_ref(hist_data, ref_system, ref_event, ref_var); -+ if (!s) { -+ hist_field = parse_var_ref(hist_data, ref_system, ref_event, ref_var); -+ if (hist_field) { -+ hist_data->var_refs[hist_data->n_var_refs] = hist_field; -+ hist_field->var_ref_idx = hist_data->n_var_refs++; -+ return hist_field; -+ } -+ } else -+ str = s; -+ - field = parse_field(hist_data, file, str, flags); - if (IS_ERR(field)) { - ret = PTR_ERR(field); -@@ -1066,6 +1597,9 @@ static struct hist_field *parse_expr(struct hist_trigger_data *hist_data, - goto free; - } - -+ operand1->read_once = true; -+ operand2->read_once = true; -+ - expr->operands[0] = operand1; - expr->operands[1] = operand2; - expr->operator = field_op; -@@ -1238,6 +1772,12 @@ static int create_key_field(struct hist_trigger_data *hist_data, - goto out; - } - -+ if (hist_field->flags & HIST_FIELD_FL_VAR_REF) { -+ destroy_hist_field(hist_field, 0); -+ ret = -EINVAL; -+ goto out; -+ } -+ - key_size = hist_field->size; - } - -@@ -1576,6 +2116,7 @@ create_hist_data(unsigned int map_bits, - - hist_data->attrs = attrs; - hist_data->remove = remove; -+ hist_data->event_file = file; - - ret = create_hist_fields(hist_data, file); - if (ret) -@@ -1598,12 +2139,6 @@ create_hist_data(unsigned int map_bits, - ret = create_tracing_map_fields(hist_data); - if (ret) - goto free; -- -- ret = tracing_map_init(hist_data->map); -- if (ret) -- goto free; -- -- hist_data->event_file = file; - out: - return hist_data; - free: -@@ -1618,12 +2153,17 @@ create_hist_data(unsigned int map_bits, - - static void hist_trigger_elt_update(struct hist_trigger_data *hist_data, - struct tracing_map_elt *elt, void *rec, -- struct ring_buffer_event *rbe) -+ struct ring_buffer_event *rbe, -+ u64 *var_ref_vals) - { -+ struct hist_elt_data *elt_data; - struct hist_field *hist_field; - unsigned int i, var_idx; - u64 hist_val; - -+ elt_data = elt->private_data; -+ elt_data->var_ref_vals = var_ref_vals; -+ - for_each_hist_val_field(i, hist_data) { - hist_field = hist_data->fields[i]; - hist_val = hist_field->fn(hist_field, elt, rbe, rec); -@@ -1675,6 +2215,7 @@ static void event_hist_trigger(struct event_trigger_data *data, void *rec, - struct hist_trigger_data *hist_data = data->private_data; - bool use_compound_key = (hist_data->n_keys > 1); - unsigned long entries[HIST_STACKTRACE_DEPTH]; -+ u64 var_ref_vals[TRACING_MAP_VARS_MAX]; - char compound_key[HIST_KEY_SIZE_MAX]; - struct tracing_map_elt *elt = NULL; - struct stack_trace stacktrace; -@@ -1714,9 +2255,15 @@ static void event_hist_trigger(struct event_trigger_data *data, void *rec, - if (use_compound_key) - key = compound_key; - -+ if (hist_data->n_var_refs && -+ !resolve_var_refs(hist_data, key, var_ref_vals, false)) -+ return; -+ - elt = tracing_map_insert(hist_data->map, key); -- if (elt) -- hist_trigger_elt_update(hist_data, elt, rec, rbe); -+ if (!elt) -+ return; -+ -+ hist_trigger_elt_update(hist_data, elt, rec, rbe, var_ref_vals); - } - - static void hist_trigger_stacktrace_print(struct seq_file *m, -@@ -1933,8 +2480,11 @@ static void hist_field_print(struct seq_file *m, struct hist_field *hist_field) - - if (hist_field->flags & HIST_FIELD_FL_TIMESTAMP) - seq_puts(m, "common_timestamp"); -- else if (field_name) -+ else if (field_name) { -+ if (hist_field->flags & HIST_FIELD_FL_VAR_REF) -+ seq_putc(m, '$'); - seq_printf(m, "%s", field_name); -+ } - - if (hist_field->flags) { - const char *flags_str = get_hist_field_flags(hist_field); -@@ -2074,7 +2624,11 @@ static void event_hist_trigger_free(struct event_trigger_ops *ops, - if (!data->ref) { - if (data->name) - del_named_trigger(data); -+ - trigger_data_free(data); -+ -+ remove_hist_vars(hist_data); -+ - destroy_hist_data(hist_data); - } - } -@@ -2287,23 +2841,55 @@ static int hist_register_trigger(char *glob, struct event_trigger_ops *ops, - goto out; - } - -- list_add_rcu(&data->list, &file->triggers); - ret++; - -- update_cond_flag(file); -- - if (hist_data->enable_timestamps) - tracing_set_time_stamp_abs(file->tr, true); -+ out: -+ return ret; -+} -+ -+static int hist_trigger_enable(struct event_trigger_data *data, -+ struct trace_event_file *file) -+{ -+ int ret = 0; -+ -+ list_add_tail_rcu(&data->list, &file->triggers); -+ -+ update_cond_flag(file); - - if (trace_event_trigger_enable_disable(file, 1) < 0) { - list_del_rcu(&data->list); - update_cond_flag(file); - ret--; - } -- out: -+ - return ret; - } - -+static bool hist_trigger_check_refs(struct event_trigger_data *data, -+ struct trace_event_file *file) -+{ -+ struct hist_trigger_data *hist_data = data->private_data; -+ struct event_trigger_data *test, *named_data = NULL; -+ -+ if (hist_data->attrs->name) -+ named_data = find_named_trigger(hist_data->attrs->name); -+ -+ list_for_each_entry_rcu(test, &file->triggers, list) { -+ if (test->cmd_ops->trigger_type == ETT_EVENT_HIST) { -+ if (!hist_trigger_match(data, test, named_data, false)) -+ continue; -+ hist_data = test->private_data; -+ if (check_var_refs(hist_data)) -+ return true; -+ break; -+ } -+ } -+ -+ return false; -+} -+ - static void hist_unregister_trigger(char *glob, struct event_trigger_ops *ops, - struct event_trigger_data *data, - struct trace_event_file *file) -@@ -2336,11 +2922,30 @@ static void hist_unregister_trigger(char *glob, struct event_trigger_ops *ops, - } - } - -+static bool hist_file_check_refs(struct trace_event_file *file) -+{ -+ struct hist_trigger_data *hist_data; -+ struct event_trigger_data *test; -+ -+ list_for_each_entry_rcu(test, &file->triggers, list) { -+ if (test->cmd_ops->trigger_type == ETT_EVENT_HIST) { -+ hist_data = test->private_data; -+ if (check_var_refs(hist_data)) -+ return true; -+ } -+ } -+ -+ return false; -+} -+ - static void hist_unreg_all(struct trace_event_file *file) - { - struct event_trigger_data *test, *n; - struct hist_trigger_data *hist_data; - -+ if (hist_file_check_refs(file)) -+ return; -+ - list_for_each_entry_safe(test, n, &file->triggers, list) { - if (test->cmd_ops->trigger_type == ETT_EVENT_HIST) { - hist_data = test->private_data; -@@ -2416,6 +3021,11 @@ static int event_hist_trigger_func(struct event_command *cmd_ops, - } - - if (remove) { -+ if (hist_trigger_check_refs(trigger_data, file)) { -+ ret = -EBUSY; -+ goto out_free; -+ } -+ - cmd_ops->unreg(glob+1, trigger_ops, trigger_data, file); - ret = 0; - goto out_free; -@@ -2433,14 +3043,33 @@ static int event_hist_trigger_func(struct event_command *cmd_ops, - goto out_free; - } else if (ret < 0) - goto out_free; -+ -+ if (get_named_trigger_data(trigger_data)) -+ goto enable; -+ -+ if (has_hist_vars(hist_data)) -+ save_hist_vars(hist_data); -+ -+ ret = tracing_map_init(hist_data->map); -+ if (ret) -+ goto out_unreg; -+enable: -+ ret = hist_trigger_enable(trigger_data, file); -+ if (ret) -+ goto out_unreg; -+ - /* Just return zero, not the number of registered triggers */ - ret = 0; - out: - return ret; -+ out_unreg: -+ cmd_ops->unreg(glob+1, trigger_ops, trigger_data, file); - out_free: - if (cmd_ops->set_filter) - cmd_ops->set_filter(NULL, trigger_data, NULL); - -+ remove_hist_vars(hist_data); -+ - kfree(trigger_data); - - destroy_hist_data(hist_data); -diff --git a/kernel/trace/trace_events_trigger.c b/kernel/trace/trace_events_trigger.c -index 4c269f2e00a4..24d42350d738 100644 ---- a/kernel/trace/trace_events_trigger.c -+++ b/kernel/trace/trace_events_trigger.c -@@ -915,6 +915,12 @@ void set_named_trigger_data(struct event_trigger_data *data, - data->named_data = named_data; - } - -+struct event_trigger_data * -+get_named_trigger_data(struct event_trigger_data *data) -+{ -+ return data->named_data; -+} -+ - static void - traceon_trigger(struct event_trigger_data *data, void *rec, - struct ring_buffer_event *event) --- -2.19.2 - diff --git a/kernel/patches-4.14.x-rt/0100-tracing-Add-hist-trigger-action-hook.patch b/kernel/patches-4.14.x-rt/0100-tracing-Add-hist-trigger-action-hook.patch deleted file mode 100644 index 0eadf404b..000000000 --- a/kernel/patches-4.14.x-rt/0100-tracing-Add-hist-trigger-action-hook.patch +++ /dev/null @@ -1,221 +0,0 @@ -From bc65875eba8adfc360b79baf7cc2772354f4824a Mon Sep 17 00:00:00 2001 -From: Tom Zanussi -Date: Mon, 15 Jan 2018 20:51:57 -0600 -Subject: [PATCH 100/450] tracing: Add hist trigger action hook - -Add a hook for executing extra actions whenever a histogram entry is -added or updated. - -The default 'action' when a hist entry is added to a histogram is to -update the set of values associated with it. Some applications may -want to perform additional actions at that point, such as generate -another event, or compare and save a maximum. - -Add a simple framework for doing that; specific actions will be -implemented on top of it in later patches. - -Link: http://lkml.kernel.org/r/9482ba6a3eaf5ca6e60954314beacd0e25c05b24.1516069914.git.tom.zanussi@linux.intel.com - -Signed-off-by: Tom Zanussi -Signed-off-by: Steven Rostedt (VMware) -(cherry picked from commit b91ae245c2f781e6da0532d8545f51a0f1291cc0) -Signed-off-by: Sebastian Andrzej Siewior ---- - kernel/trace/trace_events_hist.c | 106 ++++++++++++++++++++++++++++++- - 1 file changed, 104 insertions(+), 2 deletions(-) - -diff --git a/kernel/trace/trace_events_hist.c b/kernel/trace/trace_events_hist.c -index 2bc1f76915ef..e5fea3cf60e9 100644 ---- a/kernel/trace/trace_events_hist.c -+++ b/kernel/trace/trace_events_hist.c -@@ -33,6 +33,7 @@ typedef u64 (*hist_field_fn_t) (struct hist_field *field, - - #define HIST_FIELD_OPERANDS_MAX 2 - #define HIST_FIELDS_MAX (TRACING_MAP_FIELDS_MAX + TRACING_MAP_VARS_MAX) -+#define HIST_ACTIONS_MAX 8 - - enum field_op_id { - FIELD_OP_NONE, -@@ -242,6 +243,9 @@ struct hist_trigger_attrs { - char *assignment_str[TRACING_MAP_VARS_MAX]; - unsigned int n_assignments; - -+ char *action_str[HIST_ACTIONS_MAX]; -+ unsigned int n_actions; -+ - struct var_defs var_defs; - }; - -@@ -261,6 +265,21 @@ struct hist_trigger_data { - bool remove; - struct hist_field *var_refs[TRACING_MAP_VARS_MAX]; - unsigned int n_var_refs; -+ -+ struct action_data *actions[HIST_ACTIONS_MAX]; -+ unsigned int n_actions; -+}; -+ -+struct action_data; -+ -+typedef void (*action_fn_t) (struct hist_trigger_data *hist_data, -+ struct tracing_map_elt *elt, void *rec, -+ struct ring_buffer_event *rbe, -+ struct action_data *data, u64 *var_ref_vals); -+ -+struct action_data { -+ action_fn_t fn; -+ unsigned int var_ref_idx; - }; - - static u64 hist_field_timestamp(struct hist_field *hist_field, -@@ -764,6 +783,9 @@ static void destroy_hist_trigger_attrs(struct hist_trigger_attrs *attrs) - for (i = 0; i < attrs->n_assignments; i++) - kfree(attrs->assignment_str[i]); - -+ for (i = 0; i < attrs->n_actions; i++) -+ kfree(attrs->action_str[i]); -+ - kfree(attrs->name); - kfree(attrs->sort_key_str); - kfree(attrs->keys_str); -@@ -771,6 +793,16 @@ static void destroy_hist_trigger_attrs(struct hist_trigger_attrs *attrs) - kfree(attrs); - } - -+static int parse_action(char *str, struct hist_trigger_attrs *attrs) -+{ -+ int ret = 0; -+ -+ if (attrs->n_actions >= HIST_ACTIONS_MAX) -+ return ret; -+ -+ return ret; -+} -+ - static int parse_assignment(char *str, struct hist_trigger_attrs *attrs) - { - int ret = 0; -@@ -854,8 +886,9 @@ static struct hist_trigger_attrs *parse_hist_trigger_attrs(char *trigger_str) - else if (strcmp(str, "clear") == 0) - attrs->clear = true; - else { -- ret = -EINVAL; -- goto free; -+ ret = parse_action(str, attrs); -+ if (ret) -+ goto free; - } - } - -@@ -2047,11 +2080,55 @@ static int create_sort_keys(struct hist_trigger_data *hist_data) - return ret; - } - -+static void destroy_actions(struct hist_trigger_data *hist_data) -+{ -+ unsigned int i; -+ -+ for (i = 0; i < hist_data->n_actions; i++) { -+ struct action_data *data = hist_data->actions[i]; -+ -+ kfree(data); -+ } -+} -+ -+static int parse_actions(struct hist_trigger_data *hist_data) -+{ -+ unsigned int i; -+ int ret = 0; -+ char *str; -+ -+ for (i = 0; i < hist_data->attrs->n_actions; i++) { -+ str = hist_data->attrs->action_str[i]; -+ } -+ -+ return ret; -+} -+ -+static int create_actions(struct hist_trigger_data *hist_data, -+ struct trace_event_file *file) -+{ -+ struct action_data *data; -+ unsigned int i; -+ int ret = 0; -+ -+ for (i = 0; i < hist_data->attrs->n_actions; i++) { -+ data = hist_data->actions[i]; -+ } -+ -+ return ret; -+} -+ - static void destroy_hist_data(struct hist_trigger_data *hist_data) - { -+ if (!hist_data) -+ return; -+ - destroy_hist_trigger_attrs(hist_data->attrs); - destroy_hist_fields(hist_data); - tracing_map_destroy(hist_data->map); -+ -+ destroy_actions(hist_data); -+ - kfree(hist_data); - } - -@@ -2118,6 +2195,10 @@ create_hist_data(unsigned int map_bits, - hist_data->remove = remove; - hist_data->event_file = file; - -+ ret = parse_actions(hist_data); -+ if (ret) -+ goto free; -+ - ret = create_hist_fields(hist_data, file); - if (ret) - goto free; -@@ -2209,6 +2290,20 @@ static inline void add_to_key(char *compound_key, void *key, - memcpy(compound_key + key_field->offset, key, size); - } - -+static void -+hist_trigger_actions(struct hist_trigger_data *hist_data, -+ struct tracing_map_elt *elt, void *rec, -+ struct ring_buffer_event *rbe, u64 *var_ref_vals) -+{ -+ struct action_data *data; -+ unsigned int i; -+ -+ for (i = 0; i < hist_data->n_actions; i++) { -+ data = hist_data->actions[i]; -+ data->fn(hist_data, elt, rec, rbe, data, var_ref_vals); -+ } -+} -+ - static void event_hist_trigger(struct event_trigger_data *data, void *rec, - struct ring_buffer_event *rbe) - { -@@ -2264,6 +2359,9 @@ static void event_hist_trigger(struct event_trigger_data *data, void *rec, - return; - - hist_trigger_elt_update(hist_data, elt, rec, rbe, var_ref_vals); -+ -+ if (resolve_var_refs(hist_data, key, var_ref_vals, true)) -+ hist_trigger_actions(hist_data, elt, rec, rbe, var_ref_vals); - } - - static void hist_trigger_stacktrace_print(struct seq_file *m, -@@ -3050,6 +3148,10 @@ static int event_hist_trigger_func(struct event_command *cmd_ops, - if (has_hist_vars(hist_data)) - save_hist_vars(hist_data); - -+ ret = create_actions(hist_data, file); -+ if (ret) -+ goto out_unreg; -+ - ret = tracing_map_init(hist_data->map); - if (ret) - goto out_unreg; --- -2.19.2 - diff --git a/kernel/patches-4.14.x-rt/0101-tracing-Add-support-for-synthetic-events.patch b/kernel/patches-4.14.x-rt/0101-tracing-Add-support-for-synthetic-events.patch deleted file mode 100644 index 9cf094139..000000000 --- a/kernel/patches-4.14.x-rt/0101-tracing-Add-support-for-synthetic-events.patch +++ /dev/null @@ -1,1047 +0,0 @@ -From 77030dc4867f01af9cd39df8c2a82dd3c4649d44 Mon Sep 17 00:00:00 2001 -From: Tom Zanussi -Date: Mon, 15 Jan 2018 20:51:58 -0600 -Subject: [PATCH 101/450] tracing: Add support for 'synthetic' events - -Synthetic events are user-defined events generated from hist trigger -variables saved from one or more other events. - -To define a synthetic event, the user writes a simple specification -consisting of the name of the new event along with one or more -variables and their type(s), to the tracing/synthetic_events file. - -For instance, the following creates a new event named 'wakeup_latency' -with 3 fields: lat, pid, and prio: - - # echo 'wakeup_latency u64 lat; pid_t pid; int prio' >> \ - /sys/kernel/debug/tracing/synthetic_events - -Reading the tracing/synthetic_events file lists all the -currently-defined synthetic events, in this case the event we defined -above: - - # cat /sys/kernel/debug/tracing/synthetic_events - wakeup_latency u64 lat; pid_t pid; int prio - -At this point, the synthetic event is ready to use, and a histogram -can be defined using it: - - # echo 'hist:keys=pid,prio,lat.log2:sort=pid,lat' >> \ - /sys/kernel/debug/tracing/events/synthetic/wakeup_latency/trigger - -The new event is created under the tracing/events/synthetic/ directory -and looks and behaves just like any other event: - - # ls /sys/kernel/debug/tracing/events/synthetic/wakeup_latency - enable filter format hist id trigger - -Although a histogram can be defined for it, nothing will happen until -an action tracing that event via the trace_synth() function occurs. -The trace_synth() function is very similar to all the other trace_* -invocations spread throughout the kernel, except in this case the -trace_ function and its corresponding tracepoint isn't statically -generated but defined by the user at run-time. - -How this can be automatically hooked up via a hist trigger 'action' is -discussed in a subsequent patch. - -Link: http://lkml.kernel.org/r/c68df2284b7d172669daf9be29db62ad49bbc559.1516069914.git.tom.zanussi@linux.intel.com - -Signed-off-by: Tom Zanussi -[fix noderef.cocci warnings, sizeof pointer for kcalloc of event->fields] -Signed-off-by: Fengguang Wu -Signed-off-by: Steven Rostedt (VMware) -(cherry picked from commit cc9371f8641efd7ce6c8d4e1fd44eae249deadb4) -Signed-off-by: Sebastian Andrzej Siewior ---- - kernel/trace/trace_events_hist.c | 895 ++++++++++++++++++++++++++++++- - 1 file changed, 893 insertions(+), 2 deletions(-) - -diff --git a/kernel/trace/trace_events_hist.c b/kernel/trace/trace_events_hist.c -index e5fea3cf60e9..ababc289835c 100644 ---- a/kernel/trace/trace_events_hist.c -+++ b/kernel/trace/trace_events_hist.c -@@ -20,10 +20,16 @@ - #include - #include - #include -+#include - - #include "tracing_map.h" - #include "trace.h" - -+#define SYNTH_SYSTEM "synthetic" -+#define SYNTH_FIELDS_MAX 16 -+ -+#define STR_VAR_LEN_MAX 32 /* must be multiple of sizeof(u64) */ -+ - struct hist_field; - - typedef u64 (*hist_field_fn_t) (struct hist_field *field, -@@ -270,6 +276,26 @@ struct hist_trigger_data { - unsigned int n_actions; - }; - -+struct synth_field { -+ char *type; -+ char *name; -+ size_t size; -+ bool is_signed; -+ bool is_string; -+}; -+ -+struct synth_event { -+ struct list_head list; -+ int ref; -+ char *name; -+ struct synth_field **fields; -+ unsigned int n_fields; -+ unsigned int n_u64; -+ struct trace_event_class class; -+ struct trace_event_call call; -+ struct tracepoint *tp; -+}; -+ - struct action_data; - - typedef void (*action_fn_t) (struct hist_trigger_data *hist_data, -@@ -282,6 +308,790 @@ struct action_data { - unsigned int var_ref_idx; - }; - -+static LIST_HEAD(synth_event_list); -+static DEFINE_MUTEX(synth_event_mutex); -+ -+struct synth_trace_event { -+ struct trace_entry ent; -+ u64 fields[]; -+}; -+ -+static int synth_event_define_fields(struct trace_event_call *call) -+{ -+ struct synth_trace_event trace; -+ int offset = offsetof(typeof(trace), fields); -+ struct synth_event *event = call->data; -+ unsigned int i, size, n_u64; -+ char *name, *type; -+ bool is_signed; -+ int ret = 0; -+ -+ for (i = 0, n_u64 = 0; i < event->n_fields; i++) { -+ size = event->fields[i]->size; -+ is_signed = event->fields[i]->is_signed; -+ type = event->fields[i]->type; -+ name = event->fields[i]->name; -+ ret = trace_define_field(call, type, name, offset, size, -+ is_signed, FILTER_OTHER); -+ if (ret) -+ break; -+ -+ if (event->fields[i]->is_string) { -+ offset += STR_VAR_LEN_MAX; -+ n_u64 += STR_VAR_LEN_MAX / sizeof(u64); -+ } else { -+ offset += sizeof(u64); -+ n_u64++; -+ } -+ } -+ -+ event->n_u64 = n_u64; -+ -+ return ret; -+} -+ -+static bool synth_field_signed(char *type) -+{ -+ if (strncmp(type, "u", 1) == 0) -+ return false; -+ -+ return true; -+} -+ -+static int synth_field_is_string(char *type) -+{ -+ if (strstr(type, "char[") != NULL) -+ return true; -+ -+ return false; -+} -+ -+static int synth_field_string_size(char *type) -+{ -+ char buf[4], *end, *start; -+ unsigned int len; -+ int size, err; -+ -+ start = strstr(type, "char["); -+ if (start == NULL) -+ return -EINVAL; -+ start += strlen("char["); -+ -+ end = strchr(type, ']'); -+ if (!end || end < start) -+ return -EINVAL; -+ -+ len = end - start; -+ if (len > 3) -+ return -EINVAL; -+ -+ strncpy(buf, start, len); -+ buf[len] = '\0'; -+ -+ err = kstrtouint(buf, 0, &size); -+ if (err) -+ return err; -+ -+ if (size > STR_VAR_LEN_MAX) -+ return -EINVAL; -+ -+ return size; -+} -+ -+static int synth_field_size(char *type) -+{ -+ int size = 0; -+ -+ if (strcmp(type, "s64") == 0) -+ size = sizeof(s64); -+ else if (strcmp(type, "u64") == 0) -+ size = sizeof(u64); -+ else if (strcmp(type, "s32") == 0) -+ size = sizeof(s32); -+ else if (strcmp(type, "u32") == 0) -+ size = sizeof(u32); -+ else if (strcmp(type, "s16") == 0) -+ size = sizeof(s16); -+ else if (strcmp(type, "u16") == 0) -+ size = sizeof(u16); -+ else if (strcmp(type, "s8") == 0) -+ size = sizeof(s8); -+ else if (strcmp(type, "u8") == 0) -+ size = sizeof(u8); -+ else if (strcmp(type, "char") == 0) -+ size = sizeof(char); -+ else if (strcmp(type, "unsigned char") == 0) -+ size = sizeof(unsigned char); -+ else if (strcmp(type, "int") == 0) -+ size = sizeof(int); -+ else if (strcmp(type, "unsigned int") == 0) -+ size = sizeof(unsigned int); -+ else if (strcmp(type, "long") == 0) -+ size = sizeof(long); -+ else if (strcmp(type, "unsigned long") == 0) -+ size = sizeof(unsigned long); -+ else if (strcmp(type, "pid_t") == 0) -+ size = sizeof(pid_t); -+ else if (synth_field_is_string(type)) -+ size = synth_field_string_size(type); -+ -+ return size; -+} -+ -+static const char *synth_field_fmt(char *type) -+{ -+ const char *fmt = "%llu"; -+ -+ if (strcmp(type, "s64") == 0) -+ fmt = "%lld"; -+ else if (strcmp(type, "u64") == 0) -+ fmt = "%llu"; -+ else if (strcmp(type, "s32") == 0) -+ fmt = "%d"; -+ else if (strcmp(type, "u32") == 0) -+ fmt = "%u"; -+ else if (strcmp(type, "s16") == 0) -+ fmt = "%d"; -+ else if (strcmp(type, "u16") == 0) -+ fmt = "%u"; -+ else if (strcmp(type, "s8") == 0) -+ fmt = "%d"; -+ else if (strcmp(type, "u8") == 0) -+ fmt = "%u"; -+ else if (strcmp(type, "char") == 0) -+ fmt = "%d"; -+ else if (strcmp(type, "unsigned char") == 0) -+ fmt = "%u"; -+ else if (strcmp(type, "int") == 0) -+ fmt = "%d"; -+ else if (strcmp(type, "unsigned int") == 0) -+ fmt = "%u"; -+ else if (strcmp(type, "long") == 0) -+ fmt = "%ld"; -+ else if (strcmp(type, "unsigned long") == 0) -+ fmt = "%lu"; -+ else if (strcmp(type, "pid_t") == 0) -+ fmt = "%d"; -+ else if (synth_field_is_string(type)) -+ fmt = "%s"; -+ -+ return fmt; -+} -+ -+static enum print_line_t print_synth_event(struct trace_iterator *iter, -+ int flags, -+ struct trace_event *event) -+{ -+ struct trace_array *tr = iter->tr; -+ struct trace_seq *s = &iter->seq; -+ struct synth_trace_event *entry; -+ struct synth_event *se; -+ unsigned int i, n_u64; -+ char print_fmt[32]; -+ const char *fmt; -+ -+ entry = (struct synth_trace_event *)iter->ent; -+ se = container_of(event, struct synth_event, call.event); -+ -+ trace_seq_printf(s, "%s: ", se->name); -+ -+ for (i = 0, n_u64 = 0; i < se->n_fields; i++) { -+ if (trace_seq_has_overflowed(s)) -+ goto end; -+ -+ fmt = synth_field_fmt(se->fields[i]->type); -+ -+ /* parameter types */ -+ if (tr->trace_flags & TRACE_ITER_VERBOSE) -+ trace_seq_printf(s, "%s ", fmt); -+ -+ snprintf(print_fmt, sizeof(print_fmt), "%%s=%s%%s", fmt); -+ -+ /* parameter values */ -+ if (se->fields[i]->is_string) { -+ trace_seq_printf(s, print_fmt, se->fields[i]->name, -+ (char *)&entry->fields[n_u64], -+ i == se->n_fields - 1 ? "" : " "); -+ n_u64 += STR_VAR_LEN_MAX / sizeof(u64); -+ } else { -+ trace_seq_printf(s, print_fmt, se->fields[i]->name, -+ entry->fields[n_u64], -+ i == se->n_fields - 1 ? "" : " "); -+ n_u64++; -+ } -+ } -+end: -+ trace_seq_putc(s, '\n'); -+ -+ return trace_handle_return(s); -+} -+ -+static struct trace_event_functions synth_event_funcs = { -+ .trace = print_synth_event -+}; -+ -+static notrace void trace_event_raw_event_synth(void *__data, -+ u64 *var_ref_vals, -+ unsigned int var_ref_idx) -+{ -+ struct trace_event_file *trace_file = __data; -+ struct synth_trace_event *entry; -+ struct trace_event_buffer fbuffer; -+ struct synth_event *event; -+ unsigned int i, n_u64; -+ int fields_size = 0; -+ -+ event = trace_file->event_call->data; -+ -+ if (trace_trigger_soft_disabled(trace_file)) -+ return; -+ -+ fields_size = event->n_u64 * sizeof(u64); -+ -+ entry = trace_event_buffer_reserve(&fbuffer, trace_file, -+ sizeof(*entry) + fields_size); -+ if (!entry) -+ return; -+ -+ for (i = 0, n_u64 = 0; i < event->n_fields; i++) { -+ if (event->fields[i]->is_string) { -+ char *str_val = (char *)(long)var_ref_vals[var_ref_idx + i]; -+ char *str_field = (char *)&entry->fields[n_u64]; -+ -+ strncpy(str_field, str_val, STR_VAR_LEN_MAX); -+ n_u64 += STR_VAR_LEN_MAX / sizeof(u64); -+ } else { -+ entry->fields[n_u64] = var_ref_vals[var_ref_idx + i]; -+ n_u64++; -+ } -+ } -+ -+ trace_event_buffer_commit(&fbuffer); -+} -+ -+static void free_synth_event_print_fmt(struct trace_event_call *call) -+{ -+ if (call) { -+ kfree(call->print_fmt); -+ call->print_fmt = NULL; -+ } -+} -+ -+static int __set_synth_event_print_fmt(struct synth_event *event, -+ char *buf, int len) -+{ -+ const char *fmt; -+ int pos = 0; -+ int i; -+ -+ /* When len=0, we just calculate the needed length */ -+#define LEN_OR_ZERO (len ? len - pos : 0) -+ -+ pos += snprintf(buf + pos, LEN_OR_ZERO, "\""); -+ for (i = 0; i < event->n_fields; i++) { -+ fmt = synth_field_fmt(event->fields[i]->type); -+ pos += snprintf(buf + pos, LEN_OR_ZERO, "%s=%s%s", -+ event->fields[i]->name, fmt, -+ i == event->n_fields - 1 ? "" : ", "); -+ } -+ pos += snprintf(buf + pos, LEN_OR_ZERO, "\""); -+ -+ for (i = 0; i < event->n_fields; i++) { -+ pos += snprintf(buf + pos, LEN_OR_ZERO, -+ ", REC->%s", event->fields[i]->name); -+ } -+ -+#undef LEN_OR_ZERO -+ -+ /* return the length of print_fmt */ -+ return pos; -+} -+ -+static int set_synth_event_print_fmt(struct trace_event_call *call) -+{ -+ struct synth_event *event = call->data; -+ char *print_fmt; -+ int len; -+ -+ /* First: called with 0 length to calculate the needed length */ -+ len = __set_synth_event_print_fmt(event, NULL, 0); -+ -+ print_fmt = kmalloc(len + 1, GFP_KERNEL); -+ if (!print_fmt) -+ return -ENOMEM; -+ -+ /* Second: actually write the @print_fmt */ -+ __set_synth_event_print_fmt(event, print_fmt, len + 1); -+ call->print_fmt = print_fmt; -+ -+ return 0; -+} -+ -+static void free_synth_field(struct synth_field *field) -+{ -+ kfree(field->type); -+ kfree(field->name); -+ kfree(field); -+} -+ -+static struct synth_field *parse_synth_field(char *field_type, -+ char *field_name) -+{ -+ struct synth_field *field; -+ int len, ret = 0; -+ char *array; -+ -+ if (field_type[0] == ';') -+ field_type++; -+ -+ len = strlen(field_name); -+ if (field_name[len - 1] == ';') -+ field_name[len - 1] = '\0'; -+ -+ field = kzalloc(sizeof(*field), GFP_KERNEL); -+ if (!field) -+ return ERR_PTR(-ENOMEM); -+ -+ len = strlen(field_type) + 1; -+ array = strchr(field_name, '['); -+ if (array) -+ len += strlen(array); -+ field->type = kzalloc(len, GFP_KERNEL); -+ if (!field->type) { -+ ret = -ENOMEM; -+ goto free; -+ } -+ strcat(field->type, field_type); -+ if (array) { -+ strcat(field->type, array); -+ *array = '\0'; -+ } -+ -+ field->size = synth_field_size(field->type); -+ if (!field->size) { -+ ret = -EINVAL; -+ goto free; -+ } -+ -+ if (synth_field_is_string(field->type)) -+ field->is_string = true; -+ -+ field->is_signed = synth_field_signed(field->type); -+ -+ field->name = kstrdup(field_name, GFP_KERNEL); -+ if (!field->name) { -+ ret = -ENOMEM; -+ goto free; -+ } -+ out: -+ return field; -+ free: -+ free_synth_field(field); -+ field = ERR_PTR(ret); -+ goto out; -+} -+ -+static void free_synth_tracepoint(struct tracepoint *tp) -+{ -+ if (!tp) -+ return; -+ -+ kfree(tp->name); -+ kfree(tp); -+} -+ -+static struct tracepoint *alloc_synth_tracepoint(char *name) -+{ -+ struct tracepoint *tp; -+ -+ tp = kzalloc(sizeof(*tp), GFP_KERNEL); -+ if (!tp) -+ return ERR_PTR(-ENOMEM); -+ -+ tp->name = kstrdup(name, GFP_KERNEL); -+ if (!tp->name) { -+ kfree(tp); -+ return ERR_PTR(-ENOMEM); -+ } -+ -+ return tp; -+} -+ -+typedef void (*synth_probe_func_t) (void *__data, u64 *var_ref_vals, -+ unsigned int var_ref_idx); -+ -+static inline void trace_synth(struct synth_event *event, u64 *var_ref_vals, -+ unsigned int var_ref_idx) -+{ -+ struct tracepoint *tp = event->tp; -+ -+ if (unlikely(atomic_read(&tp->key.enabled) > 0)) { -+ struct tracepoint_func *probe_func_ptr; -+ synth_probe_func_t probe_func; -+ void *__data; -+ -+ if (!(cpu_online(raw_smp_processor_id()))) -+ return; -+ -+ probe_func_ptr = rcu_dereference_sched((tp)->funcs); -+ if (probe_func_ptr) { -+ do { -+ probe_func = probe_func_ptr->func; -+ __data = probe_func_ptr->data; -+ probe_func(__data, var_ref_vals, var_ref_idx); -+ } while ((++probe_func_ptr)->func); -+ } -+ } -+} -+ -+static struct synth_event *find_synth_event(const char *name) -+{ -+ struct synth_event *event; -+ -+ list_for_each_entry(event, &synth_event_list, list) { -+ if (strcmp(event->name, name) == 0) -+ return event; -+ } -+ -+ return NULL; -+} -+ -+static int register_synth_event(struct synth_event *event) -+{ -+ struct trace_event_call *call = &event->call; -+ int ret = 0; -+ -+ event->call.class = &event->class; -+ event->class.system = kstrdup(SYNTH_SYSTEM, GFP_KERNEL); -+ if (!event->class.system) { -+ ret = -ENOMEM; -+ goto out; -+ } -+ -+ event->tp = alloc_synth_tracepoint(event->name); -+ if (IS_ERR(event->tp)) { -+ ret = PTR_ERR(event->tp); -+ event->tp = NULL; -+ goto out; -+ } -+ -+ INIT_LIST_HEAD(&call->class->fields); -+ call->event.funcs = &synth_event_funcs; -+ call->class->define_fields = synth_event_define_fields; -+ -+ ret = register_trace_event(&call->event); -+ if (!ret) { -+ ret = -ENODEV; -+ goto out; -+ } -+ call->flags = TRACE_EVENT_FL_TRACEPOINT; -+ call->class->reg = trace_event_reg; -+ call->class->probe = trace_event_raw_event_synth; -+ call->data = event; -+ call->tp = event->tp; -+ -+ ret = trace_add_event_call(call); -+ if (ret) { -+ pr_warn("Failed to register synthetic event: %s\n", -+ trace_event_name(call)); -+ goto err; -+ } -+ -+ ret = set_synth_event_print_fmt(call); -+ if (ret < 0) { -+ trace_remove_event_call(call); -+ goto err; -+ } -+ out: -+ return ret; -+ err: -+ unregister_trace_event(&call->event); -+ goto out; -+} -+ -+static int unregister_synth_event(struct synth_event *event) -+{ -+ struct trace_event_call *call = &event->call; -+ int ret; -+ -+ ret = trace_remove_event_call(call); -+ -+ return ret; -+} -+ -+static void free_synth_event(struct synth_event *event) -+{ -+ unsigned int i; -+ -+ if (!event) -+ return; -+ -+ for (i = 0; i < event->n_fields; i++) -+ free_synth_field(event->fields[i]); -+ -+ kfree(event->fields); -+ kfree(event->name); -+ kfree(event->class.system); -+ free_synth_tracepoint(event->tp); -+ free_synth_event_print_fmt(&event->call); -+ kfree(event); -+} -+ -+static struct synth_event *alloc_synth_event(char *event_name, int n_fields, -+ struct synth_field **fields) -+{ -+ struct synth_event *event; -+ unsigned int i; -+ -+ event = kzalloc(sizeof(*event), GFP_KERNEL); -+ if (!event) { -+ event = ERR_PTR(-ENOMEM); -+ goto out; -+ } -+ -+ event->name = kstrdup(event_name, GFP_KERNEL); -+ if (!event->name) { -+ kfree(event); -+ event = ERR_PTR(-ENOMEM); -+ goto out; -+ } -+ -+ event->fields = kcalloc(n_fields, sizeof(*event->fields), GFP_KERNEL); -+ if (!event->fields) { -+ free_synth_event(event); -+ event = ERR_PTR(-ENOMEM); -+ goto out; -+ } -+ -+ for (i = 0; i < n_fields; i++) -+ event->fields[i] = fields[i]; -+ -+ event->n_fields = n_fields; -+ out: -+ return event; -+} -+ -+static void add_or_delete_synth_event(struct synth_event *event, int delete) -+{ -+ if (delete) -+ free_synth_event(event); -+ else { -+ mutex_lock(&synth_event_mutex); -+ if (!find_synth_event(event->name)) -+ list_add(&event->list, &synth_event_list); -+ else -+ free_synth_event(event); -+ mutex_unlock(&synth_event_mutex); -+ } -+} -+ -+static int create_synth_event(int argc, char **argv) -+{ -+ struct synth_field *field, *fields[SYNTH_FIELDS_MAX]; -+ struct synth_event *event = NULL; -+ bool delete_event = false; -+ int i, n_fields = 0, ret = 0; -+ char *name; -+ -+ mutex_lock(&synth_event_mutex); -+ -+ /* -+ * Argument syntax: -+ * - Add synthetic event: field[;field] ... -+ * - Remove synthetic event: ! field[;field] ... -+ * where 'field' = type field_name -+ */ -+ if (argc < 1) { -+ ret = -EINVAL; -+ goto out; -+ } -+ -+ name = argv[0]; -+ if (name[0] == '!') { -+ delete_event = true; -+ name++; -+ } -+ -+ event = find_synth_event(name); -+ if (event) { -+ if (delete_event) { -+ if (event->ref) { -+ event = NULL; -+ ret = -EBUSY; -+ goto out; -+ } -+ list_del(&event->list); -+ goto out; -+ } -+ event = NULL; -+ ret = -EEXIST; -+ goto out; -+ } else if (delete_event) -+ goto out; -+ -+ if (argc < 2) { -+ ret = -EINVAL; -+ goto out; -+ } -+ -+ for (i = 1; i < argc - 1; i++) { -+ if (strcmp(argv[i], ";") == 0) -+ continue; -+ if (n_fields == SYNTH_FIELDS_MAX) { -+ ret = -EINVAL; -+ goto err; -+ } -+ -+ field = parse_synth_field(argv[i], argv[i + 1]); -+ if (IS_ERR(field)) { -+ ret = PTR_ERR(field); -+ goto err; -+ } -+ fields[n_fields] = field; -+ i++; n_fields++; -+ } -+ -+ if (i < argc) { -+ ret = -EINVAL; -+ goto err; -+ } -+ -+ event = alloc_synth_event(name, n_fields, fields); -+ if (IS_ERR(event)) { -+ ret = PTR_ERR(event); -+ event = NULL; -+ goto err; -+ } -+ out: -+ mutex_unlock(&synth_event_mutex); -+ -+ if (event) { -+ if (delete_event) { -+ ret = unregister_synth_event(event); -+ add_or_delete_synth_event(event, !ret); -+ } else { -+ ret = register_synth_event(event); -+ add_or_delete_synth_event(event, ret); -+ } -+ } -+ -+ return ret; -+ err: -+ mutex_unlock(&synth_event_mutex); -+ -+ for (i = 0; i < n_fields; i++) -+ free_synth_field(fields[i]); -+ free_synth_event(event); -+ -+ return ret; -+} -+ -+static int release_all_synth_events(void) -+{ -+ struct list_head release_events; -+ struct synth_event *event, *e; -+ int ret = 0; -+ -+ INIT_LIST_HEAD(&release_events); -+ -+ mutex_lock(&synth_event_mutex); -+ -+ list_for_each_entry(event, &synth_event_list, list) { -+ if (event->ref) { -+ mutex_unlock(&synth_event_mutex); -+ return -EBUSY; -+ } -+ } -+ -+ list_splice_init(&event->list, &release_events); -+ -+ mutex_unlock(&synth_event_mutex); -+ -+ list_for_each_entry_safe(event, e, &release_events, list) { -+ list_del(&event->list); -+ -+ ret = unregister_synth_event(event); -+ add_or_delete_synth_event(event, !ret); -+ } -+ -+ return ret; -+} -+ -+ -+static void *synth_events_seq_start(struct seq_file *m, loff_t *pos) -+{ -+ mutex_lock(&synth_event_mutex); -+ -+ return seq_list_start(&synth_event_list, *pos); -+} -+ -+static void *synth_events_seq_next(struct seq_file *m, void *v, loff_t *pos) -+{ -+ return seq_list_next(v, &synth_event_list, pos); -+} -+ -+static void synth_events_seq_stop(struct seq_file *m, void *v) -+{ -+ mutex_unlock(&synth_event_mutex); -+} -+ -+static int synth_events_seq_show(struct seq_file *m, void *v) -+{ -+ struct synth_field *field; -+ struct synth_event *event = v; -+ unsigned int i; -+ -+ seq_printf(m, "%s\t", event->name); -+ -+ for (i = 0; i < event->n_fields; i++) { -+ field = event->fields[i]; -+ -+ /* parameter values */ -+ seq_printf(m, "%s %s%s", field->type, field->name, -+ i == event->n_fields - 1 ? "" : "; "); -+ } -+ -+ seq_putc(m, '\n'); -+ -+ return 0; -+} -+ -+static const struct seq_operations synth_events_seq_op = { -+ .start = synth_events_seq_start, -+ .next = synth_events_seq_next, -+ .stop = synth_events_seq_stop, -+ .show = synth_events_seq_show -+}; -+ -+static int synth_events_open(struct inode *inode, struct file *file) -+{ -+ int ret; -+ -+ if ((file->f_mode & FMODE_WRITE) && (file->f_flags & O_TRUNC)) { -+ ret = release_all_synth_events(); -+ if (ret < 0) -+ return ret; -+ } -+ -+ return seq_open(file, &synth_events_seq_op); -+} -+ -+static ssize_t synth_events_write(struct file *file, -+ const char __user *buffer, -+ size_t count, loff_t *ppos) -+{ -+ return trace_parse_run_command(file, buffer, count, ppos, -+ create_synth_event); -+} -+ -+static const struct file_operations synth_events_fops = { -+ .open = synth_events_open, -+ .write = synth_events_write, -+ .read = seq_read, -+ .llseek = seq_lseek, -+ .release = seq_release, -+}; -+ - static u64 hist_field_timestamp(struct hist_field *hist_field, - struct tracing_map_elt *elt, - struct ring_buffer_event *rbe, -@@ -2965,6 +3775,28 @@ static int hist_trigger_enable(struct event_trigger_data *data, - return ret; - } - -+static bool have_hist_trigger_match(struct event_trigger_data *data, -+ struct trace_event_file *file) -+{ -+ struct hist_trigger_data *hist_data = data->private_data; -+ struct event_trigger_data *test, *named_data = NULL; -+ bool match = false; -+ -+ if (hist_data->attrs->name) -+ named_data = find_named_trigger(hist_data->attrs->name); -+ -+ list_for_each_entry_rcu(test, &file->triggers, list) { -+ if (test->cmd_ops->trigger_type == ETT_EVENT_HIST) { -+ if (hist_trigger_match(data, test, named_data, false)) { -+ match = true; -+ break; -+ } -+ } -+ } -+ -+ return match; -+} -+ - static bool hist_trigger_check_refs(struct event_trigger_data *data, - struct trace_event_file *file) - { -@@ -3040,6 +3872,8 @@ static void hist_unreg_all(struct trace_event_file *file) - { - struct event_trigger_data *test, *n; - struct hist_trigger_data *hist_data; -+ struct synth_event *se; -+ const char *se_name; - - if (hist_file_check_refs(file)) - return; -@@ -3049,6 +3883,14 @@ static void hist_unreg_all(struct trace_event_file *file) - hist_data = test->private_data; - list_del_rcu(&test->list); - trace_event_trigger_enable_disable(file, 0); -+ -+ mutex_lock(&synth_event_mutex); -+ se_name = trace_event_name(file->event_call); -+ se = find_synth_event(se_name); -+ if (se) -+ se->ref--; -+ mutex_unlock(&synth_event_mutex); -+ - update_cond_flag(file); - if (hist_data->enable_timestamps) - tracing_set_time_stamp_abs(file->tr, false); -@@ -3067,6 +3909,8 @@ static int event_hist_trigger_func(struct event_command *cmd_ops, - struct hist_trigger_attrs *attrs; - struct event_trigger_ops *trigger_ops; - struct hist_trigger_data *hist_data; -+ struct synth_event *se; -+ const char *se_name; - bool remove = false; - char *trigger; - int ret = 0; -@@ -3097,10 +3941,11 @@ static int event_hist_trigger_func(struct event_command *cmd_ops, - - trigger_ops = cmd_ops->get_trigger_ops(cmd, trigger); - -- ret = -ENOMEM; - trigger_data = kzalloc(sizeof(*trigger_data), GFP_KERNEL); -- if (!trigger_data) -+ if (!trigger_data) { -+ ret = -ENOMEM; - goto out_free; -+ } - - trigger_data->count = -1; - trigger_data->ops = trigger_ops; -@@ -3119,12 +3964,23 @@ static int event_hist_trigger_func(struct event_command *cmd_ops, - } - - if (remove) { -+ if (!have_hist_trigger_match(trigger_data, file)) -+ goto out_free; -+ - if (hist_trigger_check_refs(trigger_data, file)) { - ret = -EBUSY; - goto out_free; - } - - cmd_ops->unreg(glob+1, trigger_ops, trigger_data, file); -+ -+ mutex_lock(&synth_event_mutex); -+ se_name = trace_event_name(file->event_call); -+ se = find_synth_event(se_name); -+ if (se) -+ se->ref--; -+ mutex_unlock(&synth_event_mutex); -+ - ret = 0; - goto out_free; - } -@@ -3160,6 +4016,13 @@ static int event_hist_trigger_func(struct event_command *cmd_ops, - if (ret) - goto out_unreg; - -+ mutex_lock(&synth_event_mutex); -+ se_name = trace_event_name(file->event_call); -+ se = find_synth_event(se_name); -+ if (se) -+ se->ref++; -+ mutex_unlock(&synth_event_mutex); -+ - /* Just return zero, not the number of registered triggers */ - ret = 0; - out: -@@ -3332,3 +4195,31 @@ __init int register_trigger_hist_enable_disable_cmds(void) - - return ret; - } -+ -+static __init int trace_events_hist_init(void) -+{ -+ struct dentry *entry = NULL; -+ struct dentry *d_tracer; -+ int err = 0; -+ -+ d_tracer = tracing_init_dentry(); -+ if (IS_ERR(d_tracer)) { -+ err = PTR_ERR(d_tracer); -+ goto err; -+ } -+ -+ entry = tracefs_create_file("synthetic_events", 0644, d_tracer, -+ NULL, &synth_events_fops); -+ if (!entry) { -+ err = -ENODEV; -+ goto err; -+ } -+ -+ return err; -+ err: -+ pr_warn("Could not create tracefs 'synthetic_events' entry\n"); -+ -+ return err; -+} -+ -+fs_initcall(trace_events_hist_init); --- -2.19.2 - diff --git a/kernel/patches-4.14.x-rt/0102-tracing-Add-support-for-field-variables.patch b/kernel/patches-4.14.x-rt/0102-tracing-Add-support-for-field-variables.patch deleted file mode 100644 index 89bb447ff..000000000 --- a/kernel/patches-4.14.x-rt/0102-tracing-Add-support-for-field-variables.patch +++ /dev/null @@ -1,672 +0,0 @@ -From 3b2d1998cf77761cff9598925362a9ca0c1b9f93 Mon Sep 17 00:00:00 2001 -From: Tom Zanussi -Date: Mon, 15 Jan 2018 20:51:59 -0600 -Subject: [PATCH 102/450] tracing: Add support for 'field variables' - -Users should be able to directly specify event fields in hist trigger -'actions' rather than being forced to explicitly create a variable for -that purpose. - -Add support allowing fields to be used directly in actions, which -essentially does just that - creates 'invisible' variables for each -bare field specified in an action. If a bare field refers to a field -on another (matching) event, it even creates a special histogram for -the purpose (since variables can't be defined on an existing histogram -after histogram creation). - -Here's a simple example that demonstrates both. Basically the -onmatch() action creates a list of variables corresponding to the -parameters of the synthetic event to be generated, and then uses those -values to generate the event. So for the wakeup_latency synthetic -event 'call' below the first param, $wakeup_lat, is a variable defined -explicitly on sched_switch, where 'next_pid' is just a normal field on -sched_switch, and prio is a normal field on sched_waking. - -Since the mechanism works on variables, those two normal fields just -have 'invisible' variables created internally for them. In the case of -'prio', which is on another event, we actually need to create an -additional hist trigger and define the invisible variable on that, since -once a hist trigger is defined, variables can't be added to it later. - - echo 'wakeup_latency u64 lat; pid_t pid; int prio' >> - /sys/kernel/debug/tracing/synthetic_events - - echo 'hist:keys=pid:ts0=common_timestamp.usecs >> - /sys/kernel/debug/tracing/events/sched/sched_waking/trigger - -echo 'hist:keys=next_pid:wakeup_lat=common_timestamp.usecs-$ts0: - onmatch(sched.sched_waking).wakeup_latency($wakeup_lat,next_pid,prio) - >> /sys/kernel/debug/tracing/events/sched/sched_switch/trigger - -Link: http://lkml.kernel.org/r/8e8dcdac1ea180ed7a3689e1caeeccede9dc42b3.1516069914.git.tom.zanussi@linux.intel.com - -Signed-off-by: Tom Zanussi -Signed-off-by: Steven Rostedt (VMware) -(cherry picked from commit 5fcd8c6efab39371cb3ce51b8b391a43e83a94de) -Signed-off-by: Sebastian Andrzej Siewior ---- - kernel/trace/trace_events_hist.c | 531 ++++++++++++++++++++++++++++++- - 1 file changed, 530 insertions(+), 1 deletion(-) - -diff --git a/kernel/trace/trace_events_hist.c b/kernel/trace/trace_events_hist.c -index ababc289835c..0cf7cc32dee4 100644 ---- a/kernel/trace/trace_events_hist.c -+++ b/kernel/trace/trace_events_hist.c -@@ -255,6 +255,16 @@ struct hist_trigger_attrs { - struct var_defs var_defs; - }; - -+struct field_var { -+ struct hist_field *var; -+ struct hist_field *val; -+}; -+ -+struct field_var_hist { -+ struct hist_trigger_data *hist_data; -+ char *cmd; -+}; -+ - struct hist_trigger_data { - struct hist_field *fields[HIST_FIELDS_MAX]; - unsigned int n_vals; -@@ -274,6 +284,12 @@ struct hist_trigger_data { - - struct action_data *actions[HIST_ACTIONS_MAX]; - unsigned int n_actions; -+ -+ struct field_var *field_vars[SYNTH_FIELDS_MAX]; -+ unsigned int n_field_vars; -+ unsigned int n_field_var_str; -+ struct field_var_hist *field_var_hists[SYNTH_FIELDS_MAX]; -+ unsigned int n_field_var_hists; - }; - - struct synth_field { -@@ -1427,6 +1443,7 @@ static struct hist_field *find_event_var(struct hist_trigger_data *hist_data, - struct hist_elt_data { - char *comm; - u64 *var_ref_vals; -+ char *field_var_str[SYNTH_FIELDS_MAX]; - }; - - static u64 hist_field_var_ref(struct hist_field *hist_field, -@@ -1731,6 +1748,11 @@ static inline void save_comm(char *comm, struct task_struct *task) - - static void hist_elt_data_free(struct hist_elt_data *elt_data) - { -+ unsigned int i; -+ -+ for (i = 0; i < SYNTH_FIELDS_MAX; i++) -+ kfree(elt_data->field_var_str[i]); -+ - kfree(elt_data->comm); - kfree(elt_data); - } -@@ -1748,7 +1770,7 @@ static int hist_trigger_elt_data_alloc(struct tracing_map_elt *elt) - unsigned int size = TASK_COMM_LEN; - struct hist_elt_data *elt_data; - struct hist_field *key_field; -- unsigned int i; -+ unsigned int i, n_str; - - elt_data = kzalloc(sizeof(*elt_data), GFP_KERNEL); - if (!elt_data) -@@ -1767,6 +1789,18 @@ static int hist_trigger_elt_data_alloc(struct tracing_map_elt *elt) - } - } - -+ n_str = hist_data->n_field_var_str; -+ -+ size = STR_VAR_LEN_MAX; -+ -+ for (i = 0; i < n_str; i++) { -+ elt_data->field_var_str[i] = kzalloc(size, GFP_KERNEL); -+ if (!elt_data->field_var_str[i]) { -+ hist_elt_data_free(elt_data); -+ return -ENOMEM; -+ } -+ } -+ - elt->private_data = elt_data; - - return 0; -@@ -2473,6 +2507,470 @@ static struct hist_field *parse_expr(struct hist_trigger_data *hist_data, - return ERR_PTR(ret); - } - -+static char *find_trigger_filter(struct hist_trigger_data *hist_data, -+ struct trace_event_file *file) -+{ -+ struct event_trigger_data *test; -+ -+ list_for_each_entry_rcu(test, &file->triggers, list) { -+ if (test->cmd_ops->trigger_type == ETT_EVENT_HIST) { -+ if (test->private_data == hist_data) -+ return test->filter_str; -+ } -+ } -+ -+ return NULL; -+} -+ -+static struct event_command trigger_hist_cmd; -+static int event_hist_trigger_func(struct event_command *cmd_ops, -+ struct trace_event_file *file, -+ char *glob, char *cmd, char *param); -+ -+static bool compatible_keys(struct hist_trigger_data *target_hist_data, -+ struct hist_trigger_data *hist_data, -+ unsigned int n_keys) -+{ -+ struct hist_field *target_hist_field, *hist_field; -+ unsigned int n, i, j; -+ -+ if (hist_data->n_fields - hist_data->n_vals != n_keys) -+ return false; -+ -+ i = hist_data->n_vals; -+ j = target_hist_data->n_vals; -+ -+ for (n = 0; n < n_keys; n++) { -+ hist_field = hist_data->fields[i + n]; -+ target_hist_field = target_hist_data->fields[j + n]; -+ -+ if (strcmp(hist_field->type, target_hist_field->type) != 0) -+ return false; -+ if (hist_field->size != target_hist_field->size) -+ return false; -+ if (hist_field->is_signed != target_hist_field->is_signed) -+ return false; -+ } -+ -+ return true; -+} -+ -+static struct hist_trigger_data * -+find_compatible_hist(struct hist_trigger_data *target_hist_data, -+ struct trace_event_file *file) -+{ -+ struct hist_trigger_data *hist_data; -+ struct event_trigger_data *test; -+ unsigned int n_keys; -+ -+ n_keys = target_hist_data->n_fields - target_hist_data->n_vals; -+ -+ list_for_each_entry_rcu(test, &file->triggers, list) { -+ if (test->cmd_ops->trigger_type == ETT_EVENT_HIST) { -+ hist_data = test->private_data; -+ -+ if (compatible_keys(target_hist_data, hist_data, n_keys)) -+ return hist_data; -+ } -+ } -+ -+ return NULL; -+} -+ -+static struct trace_event_file *event_file(struct trace_array *tr, -+ char *system, char *event_name) -+{ -+ struct trace_event_file *file; -+ -+ file = find_event_file(tr, system, event_name); -+ if (!file) -+ return ERR_PTR(-EINVAL); -+ -+ return file; -+} -+ -+static struct hist_field * -+find_synthetic_field_var(struct hist_trigger_data *target_hist_data, -+ char *system, char *event_name, char *field_name) -+{ -+ struct hist_field *event_var; -+ char *synthetic_name; -+ -+ synthetic_name = kzalloc(MAX_FILTER_STR_VAL, GFP_KERNEL); -+ if (!synthetic_name) -+ return ERR_PTR(-ENOMEM); -+ -+ strcpy(synthetic_name, "synthetic_"); -+ strcat(synthetic_name, field_name); -+ -+ event_var = find_event_var(target_hist_data, system, event_name, synthetic_name); -+ -+ kfree(synthetic_name); -+ -+ return event_var; -+} -+ -+/** -+ * create_field_var_hist - Automatically create a histogram and var for a field -+ * @target_hist_data: The target hist trigger -+ * @subsys_name: Optional subsystem name -+ * @event_name: Optional event name -+ * @field_name: The name of the field (and the resulting variable) -+ * -+ * Hist trigger actions fetch data from variables, not directly from -+ * events. However, for convenience, users are allowed to directly -+ * specify an event field in an action, which will be automatically -+ * converted into a variable on their behalf. -+ -+ * If a user specifies a field on an event that isn't the event the -+ * histogram currently being defined (the target event histogram), the -+ * only way that can be accomplished is if a new hist trigger is -+ * created and the field variable defined on that. -+ * -+ * This function creates a new histogram compatible with the target -+ * event (meaning a histogram with the same key as the target -+ * histogram), and creates a variable for the specified field, but -+ * with 'synthetic_' prepended to the variable name in order to avoid -+ * collision with normal field variables. -+ * -+ * Return: The variable created for the field. -+ */ -+struct hist_field * -+create_field_var_hist(struct hist_trigger_data *target_hist_data, -+ char *subsys_name, char *event_name, char *field_name) -+{ -+ struct trace_array *tr = target_hist_data->event_file->tr; -+ struct hist_field *event_var = ERR_PTR(-EINVAL); -+ struct hist_trigger_data *hist_data; -+ unsigned int i, n, first = true; -+ struct field_var_hist *var_hist; -+ struct trace_event_file *file; -+ struct hist_field *key_field; -+ char *saved_filter; -+ char *cmd; -+ int ret; -+ -+ if (target_hist_data->n_field_var_hists >= SYNTH_FIELDS_MAX) -+ return ERR_PTR(-EINVAL); -+ -+ file = event_file(tr, subsys_name, event_name); -+ -+ if (IS_ERR(file)) { -+ ret = PTR_ERR(file); -+ return ERR_PTR(ret); -+ } -+ -+ /* -+ * Look for a histogram compatible with target. We'll use the -+ * found histogram specification to create a new matching -+ * histogram with our variable on it. target_hist_data is not -+ * yet a registered histogram so we can't use that. -+ */ -+ hist_data = find_compatible_hist(target_hist_data, file); -+ if (!hist_data) -+ return ERR_PTR(-EINVAL); -+ -+ /* See if a synthetic field variable has already been created */ -+ event_var = find_synthetic_field_var(target_hist_data, subsys_name, -+ event_name, field_name); -+ if (!IS_ERR_OR_NULL(event_var)) -+ return event_var; -+ -+ var_hist = kzalloc(sizeof(*var_hist), GFP_KERNEL); -+ if (!var_hist) -+ return ERR_PTR(-ENOMEM); -+ -+ cmd = kzalloc(MAX_FILTER_STR_VAL, GFP_KERNEL); -+ if (!cmd) { -+ kfree(var_hist); -+ return ERR_PTR(-ENOMEM); -+ } -+ -+ /* Use the same keys as the compatible histogram */ -+ strcat(cmd, "keys="); -+ -+ for_each_hist_key_field(i, hist_data) { -+ key_field = hist_data->fields[i]; -+ if (!first) -+ strcat(cmd, ","); -+ strcat(cmd, key_field->field->name); -+ first = false; -+ } -+ -+ /* Create the synthetic field variable specification */ -+ strcat(cmd, ":synthetic_"); -+ strcat(cmd, field_name); -+ strcat(cmd, "="); -+ strcat(cmd, field_name); -+ -+ /* Use the same filter as the compatible histogram */ -+ saved_filter = find_trigger_filter(hist_data, file); -+ if (saved_filter) { -+ strcat(cmd, " if "); -+ strcat(cmd, saved_filter); -+ } -+ -+ var_hist->cmd = kstrdup(cmd, GFP_KERNEL); -+ if (!var_hist->cmd) { -+ kfree(cmd); -+ kfree(var_hist); -+ return ERR_PTR(-ENOMEM); -+ } -+ -+ /* Save the compatible histogram information */ -+ var_hist->hist_data = hist_data; -+ -+ /* Create the new histogram with our variable */ -+ ret = event_hist_trigger_func(&trigger_hist_cmd, file, -+ "", "hist", cmd); -+ if (ret) { -+ kfree(cmd); -+ kfree(var_hist->cmd); -+ kfree(var_hist); -+ return ERR_PTR(ret); -+ } -+ -+ kfree(cmd); -+ -+ /* If we can't find the variable, something went wrong */ -+ event_var = find_synthetic_field_var(target_hist_data, subsys_name, -+ event_name, field_name); -+ if (IS_ERR_OR_NULL(event_var)) { -+ kfree(var_hist->cmd); -+ kfree(var_hist); -+ return ERR_PTR(-EINVAL); -+ } -+ -+ n = target_hist_data->n_field_var_hists; -+ target_hist_data->field_var_hists[n] = var_hist; -+ target_hist_data->n_field_var_hists++; -+ -+ return event_var; -+} -+ -+struct hist_field * -+find_target_event_var(struct hist_trigger_data *hist_data, -+ char *subsys_name, char *event_name, char *var_name) -+{ -+ struct trace_event_file *file = hist_data->event_file; -+ struct hist_field *hist_field = NULL; -+ -+ if (subsys_name) { -+ struct trace_event_call *call; -+ -+ if (!event_name) -+ return NULL; -+ -+ call = file->event_call; -+ -+ if (strcmp(subsys_name, call->class->system) != 0) -+ return NULL; -+ -+ if (strcmp(event_name, trace_event_name(call)) != 0) -+ return NULL; -+ } -+ -+ hist_field = find_var_field(hist_data, var_name); -+ -+ return hist_field; -+} -+ -+static inline void __update_field_vars(struct tracing_map_elt *elt, -+ struct ring_buffer_event *rbe, -+ void *rec, -+ struct field_var **field_vars, -+ unsigned int n_field_vars, -+ unsigned int field_var_str_start) -+{ -+ struct hist_elt_data *elt_data = elt->private_data; -+ unsigned int i, j, var_idx; -+ u64 var_val; -+ -+ for (i = 0, j = field_var_str_start; i < n_field_vars; i++) { -+ struct field_var *field_var = field_vars[i]; -+ struct hist_field *var = field_var->var; -+ struct hist_field *val = field_var->val; -+ -+ var_val = val->fn(val, elt, rbe, rec); -+ var_idx = var->var.idx; -+ -+ if (val->flags & HIST_FIELD_FL_STRING) { -+ char *str = elt_data->field_var_str[j++]; -+ char *val_str = (char *)(uintptr_t)var_val; -+ -+ strncpy(str, val_str, STR_VAR_LEN_MAX); -+ var_val = (u64)(uintptr_t)str; -+ } -+ tracing_map_set_var(elt, var_idx, var_val); -+ } -+} -+ -+static void update_field_vars(struct hist_trigger_data *hist_data, -+ struct tracing_map_elt *elt, -+ struct ring_buffer_event *rbe, -+ void *rec) -+{ -+ __update_field_vars(elt, rbe, rec, hist_data->field_vars, -+ hist_data->n_field_vars, 0); -+} -+ -+static struct hist_field *create_var(struct hist_trigger_data *hist_data, -+ struct trace_event_file *file, -+ char *name, int size, const char *type) -+{ -+ struct hist_field *var; -+ int idx; -+ -+ if (find_var(hist_data, file, name) && !hist_data->remove) { -+ var = ERR_PTR(-EINVAL); -+ goto out; -+ } -+ -+ var = kzalloc(sizeof(struct hist_field), GFP_KERNEL); -+ if (!var) { -+ var = ERR_PTR(-ENOMEM); -+ goto out; -+ } -+ -+ idx = tracing_map_add_var(hist_data->map); -+ if (idx < 0) { -+ kfree(var); -+ var = ERR_PTR(-EINVAL); -+ goto out; -+ } -+ -+ var->flags = HIST_FIELD_FL_VAR; -+ var->var.idx = idx; -+ var->var.hist_data = var->hist_data = hist_data; -+ var->size = size; -+ var->var.name = kstrdup(name, GFP_KERNEL); -+ var->type = kstrdup(type, GFP_KERNEL); -+ if (!var->var.name || !var->type) { -+ kfree(var->var.name); -+ kfree(var->type); -+ kfree(var); -+ var = ERR_PTR(-ENOMEM); -+ } -+ out: -+ return var; -+} -+ -+static struct field_var *create_field_var(struct hist_trigger_data *hist_data, -+ struct trace_event_file *file, -+ char *field_name) -+{ -+ struct hist_field *val = NULL, *var = NULL; -+ unsigned long flags = HIST_FIELD_FL_VAR; -+ struct field_var *field_var; -+ int ret = 0; -+ -+ if (hist_data->n_field_vars >= SYNTH_FIELDS_MAX) { -+ ret = -EINVAL; -+ goto err; -+ } -+ -+ val = parse_atom(hist_data, file, field_name, &flags, NULL); -+ if (IS_ERR(val)) { -+ ret = PTR_ERR(val); -+ goto err; -+ } -+ -+ var = create_var(hist_data, file, field_name, val->size, val->type); -+ if (IS_ERR(var)) { -+ kfree(val); -+ ret = PTR_ERR(var); -+ goto err; -+ } -+ -+ field_var = kzalloc(sizeof(struct field_var), GFP_KERNEL); -+ if (!field_var) { -+ kfree(val); -+ kfree(var); -+ ret = -ENOMEM; -+ goto err; -+ } -+ -+ field_var->var = var; -+ field_var->val = val; -+ out: -+ return field_var; -+ err: -+ field_var = ERR_PTR(ret); -+ goto out; -+} -+ -+/** -+ * create_target_field_var - Automatically create a variable for a field -+ * @target_hist_data: The target hist trigger -+ * @subsys_name: Optional subsystem name -+ * @event_name: Optional event name -+ * @var_name: The name of the field (and the resulting variable) -+ * -+ * Hist trigger actions fetch data from variables, not directly from -+ * events. However, for convenience, users are allowed to directly -+ * specify an event field in an action, which will be automatically -+ * converted into a variable on their behalf. -+ -+ * This function creates a field variable with the name var_name on -+ * the hist trigger currently being defined on the target event. If -+ * subsys_name and event_name are specified, this function simply -+ * verifies that they do in fact match the target event subsystem and -+ * event name. -+ * -+ * Return: The variable created for the field. -+ */ -+struct field_var * -+create_target_field_var(struct hist_trigger_data *target_hist_data, -+ char *subsys_name, char *event_name, char *var_name) -+{ -+ struct trace_event_file *file = target_hist_data->event_file; -+ -+ if (subsys_name) { -+ struct trace_event_call *call; -+ -+ if (!event_name) -+ return NULL; -+ -+ call = file->event_call; -+ -+ if (strcmp(subsys_name, call->class->system) != 0) -+ return NULL; -+ -+ if (strcmp(event_name, trace_event_name(call)) != 0) -+ return NULL; -+ } -+ -+ return create_field_var(target_hist_data, file, var_name); -+} -+ -+static void destroy_field_var(struct field_var *field_var) -+{ -+ if (!field_var) -+ return; -+ -+ destroy_hist_field(field_var->var, 0); -+ destroy_hist_field(field_var->val, 0); -+ -+ kfree(field_var); -+} -+ -+static void destroy_field_vars(struct hist_trigger_data *hist_data) -+{ -+ unsigned int i; -+ -+ for (i = 0; i < hist_data->n_field_vars; i++) -+ destroy_field_var(hist_data->field_vars[i]); -+} -+ -+void save_field_var(struct hist_trigger_data *hist_data, -+ struct field_var *field_var) -+{ -+ hist_data->field_vars[hist_data->n_field_vars++] = field_var; -+ -+ if (field_var->val->flags & HIST_FIELD_FL_STRING) -+ hist_data->n_field_var_str++; -+} -+ - static int create_hitcount_val(struct hist_trigger_data *hist_data) - { - hist_data->fields[HITCOUNT_IDX] = -@@ -2928,6 +3426,16 @@ static int create_actions(struct hist_trigger_data *hist_data, - return ret; - } - -+static void destroy_field_var_hists(struct hist_trigger_data *hist_data) -+{ -+ unsigned int i; -+ -+ for (i = 0; i < hist_data->n_field_var_hists; i++) { -+ kfree(hist_data->field_var_hists[i]->cmd); -+ kfree(hist_data->field_var_hists[i]); -+ } -+} -+ - static void destroy_hist_data(struct hist_trigger_data *hist_data) - { - if (!hist_data) -@@ -2938,6 +3446,8 @@ static void destroy_hist_data(struct hist_trigger_data *hist_data) - tracing_map_destroy(hist_data->map); - - destroy_actions(hist_data); -+ destroy_field_vars(hist_data); -+ destroy_field_var_hists(hist_data); - - kfree(hist_data); - } -@@ -3074,6 +3584,8 @@ static void hist_trigger_elt_update(struct hist_trigger_data *hist_data, - tracing_map_set_var(elt, var_idx, hist_val); - } - } -+ -+ update_field_vars(hist_data, elt, rbe, rec); - } - - static inline void add_to_key(char *compound_key, void *key, -@@ -3520,6 +4032,21 @@ static int event_hist_trigger_init(struct event_trigger_ops *ops, - return 0; - } - -+static void unregister_field_var_hists(struct hist_trigger_data *hist_data) -+{ -+ struct trace_event_file *file; -+ unsigned int i; -+ char *cmd; -+ int ret; -+ -+ for (i = 0; i < hist_data->n_field_var_hists; i++) { -+ file = hist_data->field_var_hists[i]->hist_data->event_file; -+ cmd = hist_data->field_var_hists[i]->cmd; -+ ret = event_hist_trigger_func(&trigger_hist_cmd, file, -+ "!hist", "hist", cmd); -+ } -+} -+ - static void event_hist_trigger_free(struct event_trigger_ops *ops, - struct event_trigger_data *data) - { -@@ -3537,6 +4064,8 @@ static void event_hist_trigger_free(struct event_trigger_ops *ops, - - remove_hist_vars(hist_data); - -+ unregister_field_var_hists(hist_data); -+ - destroy_hist_data(hist_data); - } - } --- -2.19.2 - diff --git a/kernel/patches-4.14.x-rt/0103-tracing-Add-onmatch-hist-trigger-action-support.patch b/kernel/patches-4.14.x-rt/0103-tracing-Add-onmatch-hist-trigger-action-support.patch deleted file mode 100644 index d4eaac3c4..000000000 --- a/kernel/patches-4.14.x-rt/0103-tracing-Add-onmatch-hist-trigger-action-support.patch +++ /dev/null @@ -1,693 +0,0 @@ -From a4960078e4a0625bb9f468116b19e35061558a33 Mon Sep 17 00:00:00 2001 -From: Tom Zanussi -Date: Mon, 15 Jan 2018 20:52:00 -0600 -Subject: [PATCH 103/450] tracing: Add 'onmatch' hist trigger action support - -Add an 'onmatch(matching.event).(param list)' -hist trigger action which is invoked with the set of variables or -event fields named in the 'param list'. The result is the generation -of a synthetic event that consists of the values contained in those -variables and/or fields at the time the invoking event was hit. - -As an example the below defines a simple synthetic event using a -variable defined on the sched_wakeup_new event, and shows the event -definition with unresolved fields, since the sched_wakeup_new event -with the testpid variable hasn't been defined yet: - - # echo 'wakeup_new_test pid_t pid; int prio' >> \ - /sys/kernel/debug/tracing/synthetic_events - - # cat /sys/kernel/debug/tracing/synthetic_events - wakeup_new_test pid_t pid; int prio - -The following hist trigger both defines a testpid variable and -specifies an onmatch() trace action that uses that variable along with -a non-variable field to generate a wakeup_new_test synthetic event -whenever a sched_wakeup_new event occurs, which because of the 'if -comm == "cyclictest"' filter only happens when the executable is -cyclictest: - - # echo 'hist:testpid=pid:keys=$testpid:\ - onmatch(sched.sched_wakeup_new).wakeup_new_test($testpid, prio) \ - if comm=="cyclictest"' >> \ - /sys/kernel/debug/tracing/events/sched/sched_wakeup_new/trigger - -Creating and displaying a histogram based on those events is now just -a matter of using the fields and new synthetic event in the -tracing/events/synthetic directory, as usual: - - # echo 'hist:keys=pid,prio:sort=pid,prio' >> \ - /sys/kernel/debug/tracing/events/synthetic/wakeup_new_test/trigger - -Link: http://lkml.kernel.org/r/8c2a574bcb7530c876629c901ecd23911b14afe8.1516069914.git.tom.zanussi@linux.intel.com - -Signed-off-by: Tom Zanussi -Signed-off-by: Rajvi Jingar -Signed-off-by: Steven Rostedt (VMware) -(cherry picked from commit ea82307e63ec125d8612d8cedd2618669f674226) -Signed-off-by: Sebastian Andrzej Siewior ---- - kernel/trace/trace_events_hist.c | 488 ++++++++++++++++++++++++++++++- - 1 file changed, 475 insertions(+), 13 deletions(-) - -diff --git a/kernel/trace/trace_events_hist.c b/kernel/trace/trace_events_hist.c -index 0cf7cc32dee4..34be7af7cc1f 100644 ---- a/kernel/trace/trace_events_hist.c -+++ b/kernel/trace/trace_events_hist.c -@@ -285,6 +285,8 @@ struct hist_trigger_data { - struct action_data *actions[HIST_ACTIONS_MAX]; - unsigned int n_actions; - -+ struct hist_field *synth_var_refs[SYNTH_FIELDS_MAX]; -+ unsigned int n_synth_var_refs; - struct field_var *field_vars[SYNTH_FIELDS_MAX]; - unsigned int n_field_vars; - unsigned int n_field_var_str; -@@ -321,7 +323,18 @@ typedef void (*action_fn_t) (struct hist_trigger_data *hist_data, - - struct action_data { - action_fn_t fn; -- unsigned int var_ref_idx; -+ unsigned int n_params; -+ char *params[SYNTH_FIELDS_MAX]; -+ -+ union { -+ struct { -+ unsigned int var_ref_idx; -+ char *match_event; -+ char *match_event_system; -+ char *synth_event_name; -+ struct synth_event *synth_event; -+ } onmatch; -+ }; - }; - - static LIST_HEAD(synth_event_list); -@@ -887,6 +900,21 @@ static struct synth_event *alloc_synth_event(char *event_name, int n_fields, - return event; - } - -+static void action_trace(struct hist_trigger_data *hist_data, -+ struct tracing_map_elt *elt, void *rec, -+ struct ring_buffer_event *rbe, -+ struct action_data *data, u64 *var_ref_vals) -+{ -+ struct synth_event *event = data->onmatch.synth_event; -+ -+ trace_synth(event, var_ref_vals, data->onmatch.var_ref_idx); -+} -+ -+struct hist_var_data { -+ struct list_head list; -+ struct hist_trigger_data *hist_data; -+}; -+ - static void add_or_delete_synth_event(struct synth_event *event, int delete) - { - if (delete) -@@ -1124,11 +1152,6 @@ static u64 hist_field_timestamp(struct hist_field *hist_field, - return ts; - } - --struct hist_var_data { -- struct list_head list; -- struct hist_trigger_data *hist_data; --}; -- - static struct hist_field * - check_field_for_var_ref(struct hist_field *hist_field, - struct hist_trigger_data *var_data, -@@ -1194,6 +1217,14 @@ static struct hist_field *find_var_ref(struct hist_trigger_data *hist_data, - return found; - } - -+ for (i = 0; i < hist_data->n_synth_var_refs; i++) { -+ hist_field = hist_data->synth_var_refs[i]; -+ found = check_field_for_var_refs(hist_data, hist_field, -+ var_data, var_idx, 0); -+ if (found) -+ return found; -+ } -+ - return found; - } - -@@ -1422,6 +1453,37 @@ static struct hist_field *find_file_var(struct trace_event_file *file, - return NULL; - } - -+static struct hist_field * -+find_match_var(struct hist_trigger_data *hist_data, char *var_name) -+{ -+ struct trace_array *tr = hist_data->event_file->tr; -+ struct hist_field *hist_field, *found = NULL; -+ struct trace_event_file *file; -+ unsigned int i; -+ -+ for (i = 0; i < hist_data->n_actions; i++) { -+ struct action_data *data = hist_data->actions[i]; -+ -+ if (data->fn == action_trace) { -+ char *system = data->onmatch.match_event_system; -+ char *event_name = data->onmatch.match_event; -+ -+ file = find_var_file(tr, system, event_name, var_name); -+ if (!file) -+ continue; -+ hist_field = find_file_var(file, var_name); -+ if (hist_field) { -+ if (found) { -+ return ERR_PTR(-EINVAL); -+ } -+ -+ found = hist_field; -+ } -+ } -+ } -+ return found; -+} -+ - static struct hist_field *find_event_var(struct hist_trigger_data *hist_data, - char *system, - char *event_name, -@@ -1431,6 +1493,14 @@ static struct hist_field *find_event_var(struct hist_trigger_data *hist_data, - struct hist_field *hist_field = NULL; - struct trace_event_file *file; - -+ if (!system || !event_name) { -+ hist_field = find_match_var(hist_data, var_name); -+ if (IS_ERR(hist_field)) -+ return NULL; -+ if (hist_field) -+ return hist_field; -+ } -+ - file = find_var_file(tr, system, event_name, var_name); - if (!file) - return NULL; -@@ -1622,11 +1692,21 @@ static void destroy_hist_trigger_attrs(struct hist_trigger_attrs *attrs) - - static int parse_action(char *str, struct hist_trigger_attrs *attrs) - { -- int ret = 0; -+ int ret = -EINVAL; - - if (attrs->n_actions >= HIST_ACTIONS_MAX) - return ret; - -+ if ((strncmp(str, "onmatch(", strlen("onmatch(")) == 0)) { -+ attrs->action_str[attrs->n_actions] = kstrdup(str, GFP_KERNEL); -+ if (!attrs->action_str[attrs->n_actions]) { -+ ret = -ENOMEM; -+ return ret; -+ } -+ attrs->n_actions++; -+ ret = 0; -+ } -+ - return ret; - } - -@@ -2635,7 +2715,7 @@ find_synthetic_field_var(struct hist_trigger_data *target_hist_data, - * - * Return: The variable created for the field. - */ --struct hist_field * -+static struct hist_field * - create_field_var_hist(struct hist_trigger_data *target_hist_data, - char *subsys_name, char *event_name, char *field_name) - { -@@ -2748,7 +2828,7 @@ create_field_var_hist(struct hist_trigger_data *target_hist_data, - return event_var; - } - --struct hist_field * -+static struct hist_field * - find_target_event_var(struct hist_trigger_data *hist_data, - char *subsys_name, char *event_name, char *var_name) - { -@@ -2919,7 +2999,7 @@ static struct field_var *create_field_var(struct hist_trigger_data *hist_data, - * - * Return: The variable created for the field. - */ --struct field_var * -+static struct field_var * - create_target_field_var(struct hist_trigger_data *target_hist_data, - char *subsys_name, char *event_name, char *var_name) - { -@@ -2943,6 +3023,27 @@ create_target_field_var(struct hist_trigger_data *target_hist_data, - return create_field_var(target_hist_data, file, var_name); - } - -+static void onmatch_destroy(struct action_data *data) -+{ -+ unsigned int i; -+ -+ mutex_lock(&synth_event_mutex); -+ -+ kfree(data->onmatch.match_event); -+ kfree(data->onmatch.match_event_system); -+ kfree(data->onmatch.synth_event_name); -+ -+ for (i = 0; i < data->n_params; i++) -+ kfree(data->params[i]); -+ -+ if (data->onmatch.synth_event) -+ data->onmatch.synth_event->ref--; -+ -+ kfree(data); -+ -+ mutex_unlock(&synth_event_mutex); -+} -+ - static void destroy_field_var(struct field_var *field_var) - { - if (!field_var) -@@ -2962,8 +3063,8 @@ static void destroy_field_vars(struct hist_trigger_data *hist_data) - destroy_field_var(hist_data->field_vars[i]); - } - --void save_field_var(struct hist_trigger_data *hist_data, -- struct field_var *field_var) -+static void save_field_var(struct hist_trigger_data *hist_data, -+ struct field_var *field_var) - { - hist_data->field_vars[hist_data->n_field_vars++] = field_var; - -@@ -2971,6 +3072,304 @@ void save_field_var(struct hist_trigger_data *hist_data, - hist_data->n_field_var_str++; - } - -+ -+static void destroy_synth_var_refs(struct hist_trigger_data *hist_data) -+{ -+ unsigned int i; -+ -+ for (i = 0; i < hist_data->n_synth_var_refs; i++) -+ destroy_hist_field(hist_data->synth_var_refs[i], 0); -+} -+ -+static void save_synth_var_ref(struct hist_trigger_data *hist_data, -+ struct hist_field *var_ref) -+{ -+ hist_data->synth_var_refs[hist_data->n_synth_var_refs++] = var_ref; -+ -+ hist_data->var_refs[hist_data->n_var_refs] = var_ref; -+ var_ref->var_ref_idx = hist_data->n_var_refs++; -+} -+ -+static int check_synth_field(struct synth_event *event, -+ struct hist_field *hist_field, -+ unsigned int field_pos) -+{ -+ struct synth_field *field; -+ -+ if (field_pos >= event->n_fields) -+ return -EINVAL; -+ -+ field = event->fields[field_pos]; -+ -+ if (strcmp(field->type, hist_field->type) != 0) -+ return -EINVAL; -+ -+ return 0; -+} -+ -+static int parse_action_params(char *params, struct action_data *data) -+{ -+ char *param, *saved_param; -+ int ret = 0; -+ -+ while (params) { -+ if (data->n_params >= SYNTH_FIELDS_MAX) -+ goto out; -+ -+ param = strsep(¶ms, ","); -+ if (!param) { -+ ret = -EINVAL; -+ goto out; -+ } -+ -+ param = strstrip(param); -+ if (strlen(param) < 2) { -+ ret = -EINVAL; -+ goto out; -+ } -+ -+ saved_param = kstrdup(param, GFP_KERNEL); -+ if (!saved_param) { -+ ret = -ENOMEM; -+ goto out; -+ } -+ -+ data->params[data->n_params++] = saved_param; -+ } -+ out: -+ return ret; -+} -+ -+static struct hist_field * -+onmatch_find_var(struct hist_trigger_data *hist_data, struct action_data *data, -+ char *system, char *event, char *var) -+{ -+ struct hist_field *hist_field; -+ -+ var++; /* skip '$' */ -+ -+ hist_field = find_target_event_var(hist_data, system, event, var); -+ if (!hist_field) { -+ if (!system) { -+ system = data->onmatch.match_event_system; -+ event = data->onmatch.match_event; -+ } -+ -+ hist_field = find_event_var(hist_data, system, event, var); -+ } -+ -+ return hist_field; -+} -+ -+static struct hist_field * -+onmatch_create_field_var(struct hist_trigger_data *hist_data, -+ struct action_data *data, char *system, -+ char *event, char *var) -+{ -+ struct hist_field *hist_field = NULL; -+ struct field_var *field_var; -+ -+ /* -+ * First try to create a field var on the target event (the -+ * currently being defined). This will create a variable for -+ * unqualified fields on the target event, or if qualified, -+ * target fields that have qualified names matching the target. -+ */ -+ field_var = create_target_field_var(hist_data, system, event, var); -+ -+ if (field_var && !IS_ERR(field_var)) { -+ save_field_var(hist_data, field_var); -+ hist_field = field_var->var; -+ } else { -+ field_var = NULL; -+ /* -+ * If no explicit system.event is specfied, default to -+ * looking for fields on the onmatch(system.event.xxx) -+ * event. -+ */ -+ if (!system) { -+ system = data->onmatch.match_event_system; -+ event = data->onmatch.match_event; -+ } -+ -+ /* -+ * At this point, we're looking at a field on another -+ * event. Because we can't modify a hist trigger on -+ * another event to add a variable for a field, we need -+ * to create a new trigger on that event and create the -+ * variable at the same time. -+ */ -+ hist_field = create_field_var_hist(hist_data, system, event, var); -+ if (IS_ERR(hist_field)) -+ goto free; -+ } -+ out: -+ return hist_field; -+ free: -+ destroy_field_var(field_var); -+ hist_field = NULL; -+ goto out; -+} -+ -+static int onmatch_create(struct hist_trigger_data *hist_data, -+ struct trace_event_file *file, -+ struct action_data *data) -+{ -+ char *event_name, *param, *system = NULL; -+ struct hist_field *hist_field, *var_ref; -+ unsigned int i, var_ref_idx; -+ unsigned int field_pos = 0; -+ struct synth_event *event; -+ int ret = 0; -+ -+ mutex_lock(&synth_event_mutex); -+ event = find_synth_event(data->onmatch.synth_event_name); -+ if (!event) { -+ mutex_unlock(&synth_event_mutex); -+ return -EINVAL; -+ } -+ event->ref++; -+ mutex_unlock(&synth_event_mutex); -+ -+ var_ref_idx = hist_data->n_var_refs; -+ -+ for (i = 0; i < data->n_params; i++) { -+ char *p; -+ -+ p = param = kstrdup(data->params[i], GFP_KERNEL); -+ if (!param) { -+ ret = -ENOMEM; -+ goto err; -+ } -+ -+ system = strsep(¶m, "."); -+ if (!param) { -+ param = (char *)system; -+ system = event_name = NULL; -+ } else { -+ event_name = strsep(¶m, "."); -+ if (!param) { -+ kfree(p); -+ ret = -EINVAL; -+ goto err; -+ } -+ } -+ -+ if (param[0] == '$') -+ hist_field = onmatch_find_var(hist_data, data, system, -+ event_name, param); -+ else -+ hist_field = onmatch_create_field_var(hist_data, data, -+ system, -+ event_name, -+ param); -+ -+ if (!hist_field) { -+ kfree(p); -+ ret = -EINVAL; -+ goto err; -+ } -+ -+ if (check_synth_field(event, hist_field, field_pos) == 0) { -+ var_ref = create_var_ref(hist_field, system, event_name); -+ if (!var_ref) { -+ kfree(p); -+ ret = -ENOMEM; -+ goto err; -+ } -+ -+ save_synth_var_ref(hist_data, var_ref); -+ field_pos++; -+ kfree(p); -+ continue; -+ } -+ -+ kfree(p); -+ ret = -EINVAL; -+ goto err; -+ } -+ -+ if (field_pos != event->n_fields) { -+ ret = -EINVAL; -+ goto err; -+ } -+ -+ data->fn = action_trace; -+ data->onmatch.synth_event = event; -+ data->onmatch.var_ref_idx = var_ref_idx; -+ out: -+ return ret; -+ err: -+ mutex_lock(&synth_event_mutex); -+ event->ref--; -+ mutex_unlock(&synth_event_mutex); -+ -+ goto out; -+} -+ -+static struct action_data *onmatch_parse(struct trace_array *tr, char *str) -+{ -+ char *match_event, *match_event_system; -+ char *synth_event_name, *params; -+ struct action_data *data; -+ int ret = -EINVAL; -+ -+ data = kzalloc(sizeof(*data), GFP_KERNEL); -+ if (!data) -+ return ERR_PTR(-ENOMEM); -+ -+ match_event = strsep(&str, ")"); -+ if (!match_event || !str) -+ goto free; -+ -+ match_event_system = strsep(&match_event, "."); -+ if (!match_event) -+ goto free; -+ -+ if (IS_ERR(event_file(tr, match_event_system, match_event))) -+ goto free; -+ -+ data->onmatch.match_event = kstrdup(match_event, GFP_KERNEL); -+ if (!data->onmatch.match_event) { -+ ret = -ENOMEM; -+ goto free; -+ } -+ -+ data->onmatch.match_event_system = kstrdup(match_event_system, GFP_KERNEL); -+ if (!data->onmatch.match_event_system) { -+ ret = -ENOMEM; -+ goto free; -+ } -+ -+ strsep(&str, "."); -+ if (!str) -+ goto free; -+ -+ synth_event_name = strsep(&str, "("); -+ if (!synth_event_name || !str) -+ goto free; -+ -+ data->onmatch.synth_event_name = kstrdup(synth_event_name, GFP_KERNEL); -+ if (!data->onmatch.synth_event_name) { -+ ret = -ENOMEM; -+ goto free; -+ } -+ -+ params = strsep(&str, ")"); -+ if (!params || !str || (str && strlen(str))) -+ goto free; -+ -+ ret = parse_action_params(params, data); -+ if (ret) -+ goto free; -+ out: -+ return data; -+ free: -+ onmatch_destroy(data); -+ data = ERR_PTR(ret); -+ goto out; -+} -+ - static int create_hitcount_val(struct hist_trigger_data *hist_data) - { - hist_data->fields[HITCOUNT_IDX] = -@@ -3395,18 +3794,39 @@ static void destroy_actions(struct hist_trigger_data *hist_data) - for (i = 0; i < hist_data->n_actions; i++) { - struct action_data *data = hist_data->actions[i]; - -- kfree(data); -+ if (data->fn == action_trace) -+ onmatch_destroy(data); -+ else -+ kfree(data); - } - } - - static int parse_actions(struct hist_trigger_data *hist_data) - { -+ struct trace_array *tr = hist_data->event_file->tr; -+ struct action_data *data; - unsigned int i; - int ret = 0; - char *str; - - for (i = 0; i < hist_data->attrs->n_actions; i++) { - str = hist_data->attrs->action_str[i]; -+ -+ if (strncmp(str, "onmatch(", strlen("onmatch(")) == 0) { -+ char *action_str = str + strlen("onmatch("); -+ -+ data = onmatch_parse(tr, action_str); -+ if (IS_ERR(data)) { -+ ret = PTR_ERR(data); -+ break; -+ } -+ data->fn = action_trace; -+ } else { -+ ret = -EINVAL; -+ break; -+ } -+ -+ hist_data->actions[hist_data->n_actions++] = data; - } - - return ret; -@@ -3421,11 +3841,50 @@ static int create_actions(struct hist_trigger_data *hist_data, - - for (i = 0; i < hist_data->attrs->n_actions; i++) { - data = hist_data->actions[i]; -+ -+ if (data->fn == action_trace) { -+ ret = onmatch_create(hist_data, file, data); -+ if (ret) -+ return ret; -+ } - } - - return ret; - } - -+static void print_onmatch_spec(struct seq_file *m, -+ struct hist_trigger_data *hist_data, -+ struct action_data *data) -+{ -+ unsigned int i; -+ -+ seq_printf(m, ":onmatch(%s.%s).", data->onmatch.match_event_system, -+ data->onmatch.match_event); -+ -+ seq_printf(m, "%s(", data->onmatch.synth_event->name); -+ -+ for (i = 0; i < data->n_params; i++) { -+ if (i) -+ seq_puts(m, ","); -+ seq_printf(m, "%s", data->params[i]); -+ } -+ -+ seq_puts(m, ")"); -+} -+ -+static void print_actions_spec(struct seq_file *m, -+ struct hist_trigger_data *hist_data) -+{ -+ unsigned int i; -+ -+ for (i = 0; i < hist_data->n_actions; i++) { -+ struct action_data *data = hist_data->actions[i]; -+ -+ if (data->fn == action_trace) -+ print_onmatch_spec(m, hist_data, data); -+ } -+} -+ - static void destroy_field_var_hists(struct hist_trigger_data *hist_data) - { - unsigned int i; -@@ -3448,6 +3907,7 @@ static void destroy_hist_data(struct hist_trigger_data *hist_data) - destroy_actions(hist_data); - destroy_field_vars(hist_data); - destroy_field_var_hists(hist_data); -+ destroy_synth_var_refs(hist_data); - - kfree(hist_data); - } -@@ -4006,6 +4466,8 @@ static int event_hist_trigger_print(struct seq_file *m, - } - seq_printf(m, ":size=%u", (1 << hist_data->map->map_bits)); - -+ print_actions_spec(m, hist_data); -+ - if (data->filter_str) - seq_printf(m, " if %s", data->filter_str); - --- -2.19.2 - diff --git a/kernel/patches-4.14.x-rt/0104-tracing-Add-onmax-hist-trigger-action-support.patch b/kernel/patches-4.14.x-rt/0104-tracing-Add-onmax-hist-trigger-action-support.patch deleted file mode 100644 index bc6ea3687..000000000 --- a/kernel/patches-4.14.x-rt/0104-tracing-Add-onmax-hist-trigger-action-support.patch +++ /dev/null @@ -1,492 +0,0 @@ -From 1f029483405f380bc7a8471acf036e7b54ff75ab Mon Sep 17 00:00:00 2001 -From: Tom Zanussi -Date: Mon, 15 Jan 2018 20:52:01 -0600 -Subject: [PATCH 104/450] tracing: Add 'onmax' hist trigger action support - -Add an 'onmax(var).save(field,...)' hist trigger action which is -invoked whenever an event exceeds the current maximum. - -The end result is that the trace event fields or variables specified -as the onmax.save() params will be saved if 'var' exceeds the current -maximum for that hist trigger entry. This allows context from the -event that exhibited the new maximum to be saved for later reference. -When the histogram is displayed, additional fields displaying the -saved values will be printed. - -As an example the below defines a couple of hist triggers, one for -sched_wakeup and another for sched_switch, keyed on pid. Whenever a -sched_wakeup occurs, the timestamp is saved in the entry corresponding -to the current pid, and when the scheduler switches back to that pid, -the timestamp difference is calculated. If the resulting latency -exceeds the current maximum latency, the specified save() values are -saved: - - # echo 'hist:keys=pid:ts0=common_timestamp.usecs \ - if comm=="cyclictest"' >> \ - /sys/kernel/debug/tracing/events/sched/sched_wakeup/trigger - - # echo 'hist:keys=next_pid:\ - wakeup_lat=common_timestamp.usecs-$ts0:\ - onmax($wakeup_lat).save(next_comm,prev_pid,prev_prio,prev_comm) \ - if next_comm=="cyclictest"' >> \ - /sys/kernel/debug/tracing/events/sched/sched_switch/trigger - -When the histogram is displayed, the max value and the saved values -corresponding to the max are displayed following the rest of the -fields: - - # cat /sys/kernel/debug/tracing/events/sched/sched_switch/hist - - { next_pid: 3728 } hitcount: 199 \ - max: 123 next_comm: cyclictest prev_pid: 0 \ - prev_prio: 120 prev_comm: swapper/3 - { next_pid: 3730 } hitcount: 1321 \ - max: 15 next_comm: cyclictest prev_pid: 0 \ - prev_prio: 120 prev_comm: swapper/1 - { next_pid: 3729 } hitcount: 1973\ - max: 25 next_comm: cyclictest prev_pid: 0 \ - prev_prio: 120 prev_comm: swapper/0 - - Totals: - Hits: 3493 - Entries: 3 - Dropped: 0 - -Link: http://lkml.kernel.org/r/006907f71b1e839bb059337ec3c496f84fcb71de.1516069914.git.tom.zanussi@linux.intel.com - -Signed-off-by: Tom Zanussi -Signed-off-by: Steven Rostedt (VMware) -(cherry picked from commit 4e30c922f0a19496ff424edd5c473666e1690601) -Signed-off-by: Sebastian Andrzej Siewior ---- - kernel/trace/trace_events_hist.c | 331 +++++++++++++++++++++++++++---- - 1 file changed, 296 insertions(+), 35 deletions(-) - -diff --git a/kernel/trace/trace_events_hist.c b/kernel/trace/trace_events_hist.c -index 34be7af7cc1f..0803b843623c 100644 ---- a/kernel/trace/trace_events_hist.c -+++ b/kernel/trace/trace_events_hist.c -@@ -292,6 +292,10 @@ struct hist_trigger_data { - unsigned int n_field_var_str; - struct field_var_hist *field_var_hists[SYNTH_FIELDS_MAX]; - unsigned int n_field_var_hists; -+ -+ struct field_var *max_vars[SYNTH_FIELDS_MAX]; -+ unsigned int n_max_vars; -+ unsigned int n_max_var_str; - }; - - struct synth_field { -@@ -334,6 +338,14 @@ struct action_data { - char *synth_event_name; - struct synth_event *synth_event; - } onmatch; -+ -+ struct { -+ char *var_str; -+ char *fn_name; -+ unsigned int max_var_ref_idx; -+ struct hist_field *max_var; -+ struct hist_field *var; -+ } onmax; - }; - }; - -@@ -1697,7 +1709,8 @@ static int parse_action(char *str, struct hist_trigger_attrs *attrs) - if (attrs->n_actions >= HIST_ACTIONS_MAX) - return ret; - -- if ((strncmp(str, "onmatch(", strlen("onmatch(")) == 0)) { -+ if ((strncmp(str, "onmatch(", strlen("onmatch(")) == 0) || -+ (strncmp(str, "onmax(", strlen("onmax(")) == 0)) { - attrs->action_str[attrs->n_actions] = kstrdup(str, GFP_KERNEL); - if (!attrs->action_str[attrs->n_actions]) { - ret = -ENOMEM; -@@ -1869,7 +1882,7 @@ static int hist_trigger_elt_data_alloc(struct tracing_map_elt *elt) - } - } - -- n_str = hist_data->n_field_var_str; -+ n_str = hist_data->n_field_var_str + hist_data->n_max_var_str; - - size = STR_VAR_LEN_MAX; - -@@ -2894,6 +2907,15 @@ static void update_field_vars(struct hist_trigger_data *hist_data, - hist_data->n_field_vars, 0); - } - -+static void update_max_vars(struct hist_trigger_data *hist_data, -+ struct tracing_map_elt *elt, -+ struct ring_buffer_event *rbe, -+ void *rec) -+{ -+ __update_field_vars(elt, rbe, rec, hist_data->max_vars, -+ hist_data->n_max_vars, hist_data->n_field_var_str); -+} -+ - static struct hist_field *create_var(struct hist_trigger_data *hist_data, - struct trace_event_file *file, - char *name, int size, const char *type) -@@ -3023,6 +3045,227 @@ create_target_field_var(struct hist_trigger_data *target_hist_data, - return create_field_var(target_hist_data, file, var_name); - } - -+static void onmax_print(struct seq_file *m, -+ struct hist_trigger_data *hist_data, -+ struct tracing_map_elt *elt, -+ struct action_data *data) -+{ -+ unsigned int i, save_var_idx, max_idx = data->onmax.max_var->var.idx; -+ -+ seq_printf(m, "\n\tmax: %10llu", tracing_map_read_var(elt, max_idx)); -+ -+ for (i = 0; i < hist_data->n_max_vars; i++) { -+ struct hist_field *save_val = hist_data->max_vars[i]->val; -+ struct hist_field *save_var = hist_data->max_vars[i]->var; -+ u64 val; -+ -+ save_var_idx = save_var->var.idx; -+ -+ val = tracing_map_read_var(elt, save_var_idx); -+ -+ if (save_val->flags & HIST_FIELD_FL_STRING) { -+ seq_printf(m, " %s: %-32s", save_var->var.name, -+ (char *)(uintptr_t)(val)); -+ } else -+ seq_printf(m, " %s: %10llu", save_var->var.name, val); -+ } -+} -+ -+static void onmax_save(struct hist_trigger_data *hist_data, -+ struct tracing_map_elt *elt, void *rec, -+ struct ring_buffer_event *rbe, -+ struct action_data *data, u64 *var_ref_vals) -+{ -+ unsigned int max_idx = data->onmax.max_var->var.idx; -+ unsigned int max_var_ref_idx = data->onmax.max_var_ref_idx; -+ -+ u64 var_val, max_val; -+ -+ var_val = var_ref_vals[max_var_ref_idx]; -+ max_val = tracing_map_read_var(elt, max_idx); -+ -+ if (var_val <= max_val) -+ return; -+ -+ tracing_map_set_var(elt, max_idx, var_val); -+ -+ update_max_vars(hist_data, elt, rbe, rec); -+} -+ -+static void onmax_destroy(struct action_data *data) -+{ -+ unsigned int i; -+ -+ destroy_hist_field(data->onmax.max_var, 0); -+ destroy_hist_field(data->onmax.var, 0); -+ -+ kfree(data->onmax.var_str); -+ kfree(data->onmax.fn_name); -+ -+ for (i = 0; i < data->n_params; i++) -+ kfree(data->params[i]); -+ -+ kfree(data); -+} -+ -+static int onmax_create(struct hist_trigger_data *hist_data, -+ struct action_data *data) -+{ -+ struct trace_event_file *file = hist_data->event_file; -+ struct hist_field *var_field, *ref_field, *max_var; -+ unsigned int var_ref_idx = hist_data->n_var_refs; -+ struct field_var *field_var; -+ char *onmax_var_str, *param; -+ unsigned long flags; -+ unsigned int i; -+ int ret = 0; -+ -+ onmax_var_str = data->onmax.var_str; -+ if (onmax_var_str[0] != '$') -+ return -EINVAL; -+ onmax_var_str++; -+ -+ var_field = find_target_event_var(hist_data, NULL, NULL, onmax_var_str); -+ if (!var_field) -+ return -EINVAL; -+ -+ flags = HIST_FIELD_FL_VAR_REF; -+ ref_field = create_hist_field(hist_data, NULL, flags, NULL); -+ if (!ref_field) -+ return -ENOMEM; -+ -+ if (init_var_ref(ref_field, var_field, NULL, NULL)) { -+ destroy_hist_field(ref_field, 0); -+ ret = -ENOMEM; -+ goto out; -+ } -+ hist_data->var_refs[hist_data->n_var_refs] = ref_field; -+ ref_field->var_ref_idx = hist_data->n_var_refs++; -+ data->onmax.var = ref_field; -+ -+ data->fn = onmax_save; -+ data->onmax.max_var_ref_idx = var_ref_idx; -+ max_var = create_var(hist_data, file, "max", sizeof(u64), "u64"); -+ if (IS_ERR(max_var)) { -+ ret = PTR_ERR(max_var); -+ goto out; -+ } -+ data->onmax.max_var = max_var; -+ -+ for (i = 0; i < data->n_params; i++) { -+ param = kstrdup(data->params[i], GFP_KERNEL); -+ if (!param) { -+ ret = -ENOMEM; -+ goto out; -+ } -+ -+ field_var = create_target_field_var(hist_data, NULL, NULL, param); -+ if (IS_ERR(field_var)) { -+ ret = PTR_ERR(field_var); -+ kfree(param); -+ goto out; -+ } -+ -+ hist_data->max_vars[hist_data->n_max_vars++] = field_var; -+ if (field_var->val->flags & HIST_FIELD_FL_STRING) -+ hist_data->n_max_var_str++; -+ -+ kfree(param); -+ } -+ out: -+ return ret; -+} -+ -+static int parse_action_params(char *params, struct action_data *data) -+{ -+ char *param, *saved_param; -+ int ret = 0; -+ -+ while (params) { -+ if (data->n_params >= SYNTH_FIELDS_MAX) -+ goto out; -+ -+ param = strsep(¶ms, ","); -+ if (!param) { -+ ret = -EINVAL; -+ goto out; -+ } -+ -+ param = strstrip(param); -+ if (strlen(param) < 2) { -+ ret = -EINVAL; -+ goto out; -+ } -+ -+ saved_param = kstrdup(param, GFP_KERNEL); -+ if (!saved_param) { -+ ret = -ENOMEM; -+ goto out; -+ } -+ -+ data->params[data->n_params++] = saved_param; -+ } -+ out: -+ return ret; -+} -+ -+static struct action_data *onmax_parse(char *str) -+{ -+ char *onmax_fn_name, *onmax_var_str; -+ struct action_data *data; -+ int ret = -EINVAL; -+ -+ data = kzalloc(sizeof(*data), GFP_KERNEL); -+ if (!data) -+ return ERR_PTR(-ENOMEM); -+ -+ onmax_var_str = strsep(&str, ")"); -+ if (!onmax_var_str || !str) { -+ ret = -EINVAL; -+ goto free; -+ } -+ -+ data->onmax.var_str = kstrdup(onmax_var_str, GFP_KERNEL); -+ if (!data->onmax.var_str) { -+ ret = -ENOMEM; -+ goto free; -+ } -+ -+ strsep(&str, "."); -+ if (!str) -+ goto free; -+ -+ onmax_fn_name = strsep(&str, "("); -+ if (!onmax_fn_name || !str) -+ goto free; -+ -+ if (strncmp(onmax_fn_name, "save", strlen("save")) == 0) { -+ char *params = strsep(&str, ")"); -+ -+ if (!params) { -+ ret = -EINVAL; -+ goto free; -+ } -+ -+ ret = parse_action_params(params, data); -+ if (ret) -+ goto free; -+ } else -+ goto free; -+ -+ data->onmax.fn_name = kstrdup(onmax_fn_name, GFP_KERNEL); -+ if (!data->onmax.fn_name) { -+ ret = -ENOMEM; -+ goto free; -+ } -+ out: -+ return data; -+ free: -+ onmax_destroy(data); -+ data = ERR_PTR(ret); -+ goto out; -+} -+ - static void onmatch_destroy(struct action_data *data) - { - unsigned int i; -@@ -3107,39 +3350,6 @@ static int check_synth_field(struct synth_event *event, - return 0; - } - --static int parse_action_params(char *params, struct action_data *data) --{ -- char *param, *saved_param; -- int ret = 0; -- -- while (params) { -- if (data->n_params >= SYNTH_FIELDS_MAX) -- goto out; -- -- param = strsep(¶ms, ","); -- if (!param) { -- ret = -EINVAL; -- goto out; -- } -- -- param = strstrip(param); -- if (strlen(param) < 2) { -- ret = -EINVAL; -- goto out; -- } -- -- saved_param = kstrdup(param, GFP_KERNEL); -- if (!saved_param) { -- ret = -ENOMEM; -- goto out; -- } -- -- data->params[data->n_params++] = saved_param; -- } -- out: -- return ret; --} -- - static struct hist_field * - onmatch_find_var(struct hist_trigger_data *hist_data, struct action_data *data, - char *system, char *event, char *var) -@@ -3796,6 +4006,8 @@ static void destroy_actions(struct hist_trigger_data *hist_data) - - if (data->fn == action_trace) - onmatch_destroy(data); -+ else if (data->fn == onmax_save) -+ onmax_destroy(data); - else - kfree(data); - } -@@ -3821,6 +4033,15 @@ static int parse_actions(struct hist_trigger_data *hist_data) - break; - } - data->fn = action_trace; -+ } else if (strncmp(str, "onmax(", strlen("onmax(")) == 0) { -+ char *action_str = str + strlen("onmax("); -+ -+ data = onmax_parse(action_str); -+ if (IS_ERR(data)) { -+ ret = PTR_ERR(data); -+ break; -+ } -+ data->fn = onmax_save; - } else { - ret = -EINVAL; - break; -@@ -3846,12 +4067,48 @@ static int create_actions(struct hist_trigger_data *hist_data, - ret = onmatch_create(hist_data, file, data); - if (ret) - return ret; -+ } else if (data->fn == onmax_save) { -+ ret = onmax_create(hist_data, data); -+ if (ret) -+ return ret; - } - } - - return ret; - } - -+static void print_actions(struct seq_file *m, -+ struct hist_trigger_data *hist_data, -+ struct tracing_map_elt *elt) -+{ -+ unsigned int i; -+ -+ for (i = 0; i < hist_data->n_actions; i++) { -+ struct action_data *data = hist_data->actions[i]; -+ -+ if (data->fn == onmax_save) -+ onmax_print(m, hist_data, elt, data); -+ } -+} -+ -+static void print_onmax_spec(struct seq_file *m, -+ struct hist_trigger_data *hist_data, -+ struct action_data *data) -+{ -+ unsigned int i; -+ -+ seq_puts(m, ":onmax("); -+ seq_printf(m, "%s", data->onmax.var_str); -+ seq_printf(m, ").%s(", data->onmax.fn_name); -+ -+ for (i = 0; i < hist_data->n_max_vars; i++) { -+ seq_printf(m, "%s", hist_data->max_vars[i]->var->var.name); -+ if (i < hist_data->n_max_vars - 1) -+ seq_puts(m, ","); -+ } -+ seq_puts(m, ")"); -+} -+ - static void print_onmatch_spec(struct seq_file *m, - struct hist_trigger_data *hist_data, - struct action_data *data) -@@ -3882,6 +4139,8 @@ static void print_actions_spec(struct seq_file *m, - - if (data->fn == action_trace) - print_onmatch_spec(m, hist_data, data); -+ else if (data->fn == onmax_save) -+ print_onmax_spec(m, hist_data, data); - } - } - -@@ -4263,6 +4522,8 @@ hist_trigger_entry_print(struct seq_file *m, - } - } - -+ print_actions(m, hist_data, elt); -+ - seq_puts(m, "\n"); - } - --- -2.19.2 - diff --git a/kernel/patches-4.14.x-rt/0105-tracing-Allow-whitespace-to-surround-hist-trigger-fi.patch b/kernel/patches-4.14.x-rt/0105-tracing-Allow-whitespace-to-surround-hist-trigger-fi.patch deleted file mode 100644 index 96184bb1f..000000000 --- a/kernel/patches-4.14.x-rt/0105-tracing-Allow-whitespace-to-surround-hist-trigger-fi.patch +++ /dev/null @@ -1,81 +0,0 @@ -From a5ced6a976d4455f445e4bdef011b38acf4f47e8 Mon Sep 17 00:00:00 2001 -From: Tom Zanussi -Date: Mon, 15 Jan 2018 20:52:02 -0600 -Subject: [PATCH 105/450] tracing: Allow whitespace to surround hist trigger - filter - -The existing code only allows for one space before and after the 'if' -specifying the filter for a hist trigger. Add code to make that more -permissive as far as whitespace goes. Specifically, we want to allow -spaces in the trigger itself now that we have additional syntax -(onmatch/onmax) where spaces are more natural e.g. spaces after commas -in param lists. - -Link: http://lkml.kernel.org/r/1053090c3c308d4f431accdeb59dff4b511d4554.1516069914.git.tom.zanussi@linux.intel.com - -Signed-off-by: Tom Zanussi -Signed-off-by: Steven Rostedt (VMware) -(cherry picked from commit ab257ec0f8eb50c58fafd50b1cb5352553f31ccf) -Signed-off-by: Sebastian Andrzej Siewior ---- - kernel/trace/trace_events_hist.c | 37 +++++++++++++++++++++++++++----- - 1 file changed, 32 insertions(+), 5 deletions(-) - -diff --git a/kernel/trace/trace_events_hist.c b/kernel/trace/trace_events_hist.c -index 0803b843623c..0b73852f6923 100644 ---- a/kernel/trace/trace_events_hist.c -+++ b/kernel/trace/trace_events_hist.c -@@ -5164,7 +5164,7 @@ static int event_hist_trigger_func(struct event_command *cmd_ops, - struct synth_event *se; - const char *se_name; - bool remove = false; -- char *trigger; -+ char *trigger, *p; - int ret = 0; - - if (!param) -@@ -5173,10 +5173,37 @@ static int event_hist_trigger_func(struct event_command *cmd_ops, - if (glob[0] == '!') - remove = true; - -- /* separate the trigger from the filter (k:v [if filter]) */ -- trigger = strsep(¶m, " \t"); -- if (!trigger) -- return -EINVAL; -+ /* -+ * separate the trigger from the filter (k:v [if filter]) -+ * allowing for whitespace in the trigger -+ */ -+ p = trigger = param; -+ do { -+ p = strstr(p, "if"); -+ if (!p) -+ break; -+ if (p == param) -+ return -EINVAL; -+ if (*(p - 1) != ' ' && *(p - 1) != '\t') { -+ p++; -+ continue; -+ } -+ if (p >= param + strlen(param) - strlen("if") - 1) -+ return -EINVAL; -+ if (*(p + strlen("if")) != ' ' && *(p + strlen("if")) != '\t') { -+ p++; -+ continue; -+ } -+ break; -+ } while (p); -+ -+ if (!p) -+ param = NULL; -+ else { -+ *(p - 1) = '\0'; -+ param = strstrip(p); -+ trigger = strstrip(trigger); -+ } - - attrs = parse_hist_trigger_attrs(trigger); - if (IS_ERR(attrs)) --- -2.19.2 - diff --git a/kernel/patches-4.14.x-rt/0106-tracing-Add-cpu-field-for-hist-triggers.patch b/kernel/patches-4.14.x-rt/0106-tracing-Add-cpu-field-for-hist-triggers.patch deleted file mode 100644 index cb0b4c663..000000000 --- a/kernel/patches-4.14.x-rt/0106-tracing-Add-cpu-field-for-hist-triggers.patch +++ /dev/null @@ -1,122 +0,0 @@ -From 160df7fa3eacee8583ef796699bafa229cfb3cc5 Mon Sep 17 00:00:00 2001 -From: Tom Zanussi -Date: Mon, 15 Jan 2018 20:52:03 -0600 -Subject: [PATCH 106/450] tracing: Add cpu field for hist triggers - -A common key to use in a histogram is the cpuid - add a new cpu -'synthetic' field named 'cpu' for that purpose. - -Link: http://lkml.kernel.org/r/89537645bfc957e0d76e2cacf5f0ada88691a6cc.1516069914.git.tom.zanussi@linux.intel.com - -Signed-off-by: Tom Zanussi -Signed-off-by: Steven Rostedt (VMware) -(cherry picked from commit 4bfaa88f0e0e98e706d57647452e4d37afd78d00) -Signed-off-by: Sebastian Andrzej Siewior ---- - Documentation/trace/histogram.txt | 15 +++++++++++++++ - kernel/trace/trace_events_hist.c | 28 +++++++++++++++++++++++++++- - 2 files changed, 42 insertions(+), 1 deletion(-) - -diff --git a/Documentation/trace/histogram.txt b/Documentation/trace/histogram.txt -index 25c94730d3fe..be612ca79455 100644 ---- a/Documentation/trace/histogram.txt -+++ b/Documentation/trace/histogram.txt -@@ -172,6 +172,21 @@ - The examples below provide a more concrete illustration of the - concepts and typical usage patterns discussed above. - -+ 'special' event fields -+ ------------------------ -+ -+ There are a number of 'special event fields' available for use as -+ keys or values in a hist trigger. These look like and behave as if -+ they were actual event fields, but aren't really part of the event's -+ field definition or format file. They are however available for any -+ event, and can be used anywhere an actual event field could be. -+ They are: -+ -+ common_timestamp u64 - timestamp (from ring buffer) associated -+ with the event, in nanoseconds. May be -+ modified by .usecs to have timestamps -+ interpreted as microseconds. -+ cpu int - the cpu on which the event occurred. - - 6.2 'hist' trigger examples - --------------------------- -diff --git a/kernel/trace/trace_events_hist.c b/kernel/trace/trace_events_hist.c -index 0b73852f6923..34a2e8d0a052 100644 ---- a/kernel/trace/trace_events_hist.c -+++ b/kernel/trace/trace_events_hist.c -@@ -227,6 +227,7 @@ enum hist_field_flags { - HIST_FIELD_FL_VAR = 1 << 12, - HIST_FIELD_FL_EXPR = 1 << 13, - HIST_FIELD_FL_VAR_REF = 1 << 14, -+ HIST_FIELD_FL_CPU = 1 << 15, - }; - - struct var_defs { -@@ -1164,6 +1165,16 @@ static u64 hist_field_timestamp(struct hist_field *hist_field, - return ts; - } - -+static u64 hist_field_cpu(struct hist_field *hist_field, -+ struct tracing_map_elt *elt, -+ struct ring_buffer_event *rbe, -+ void *event) -+{ -+ int cpu = smp_processor_id(); -+ -+ return cpu; -+} -+ - static struct hist_field * - check_field_for_var_ref(struct hist_field *hist_field, - struct hist_trigger_data *var_data, -@@ -1602,6 +1613,8 @@ static const char *hist_field_name(struct hist_field *field, - field_name = hist_field_name(field->operands[0], ++level); - else if (field->flags & HIST_FIELD_FL_TIMESTAMP) - field_name = "common_timestamp"; -+ else if (field->flags & HIST_FIELD_FL_CPU) -+ field_name = "cpu"; - else if (field->flags & HIST_FIELD_FL_EXPR || - field->flags & HIST_FIELD_FL_VAR_REF) { - if (field->system) { -@@ -2109,6 +2122,15 @@ static struct hist_field *create_hist_field(struct hist_trigger_data *hist_data, - goto out; - } - -+ if (flags & HIST_FIELD_FL_CPU) { -+ hist_field->fn = hist_field_cpu; -+ hist_field->size = sizeof(int); -+ hist_field->type = kstrdup("unsigned int", GFP_KERNEL); -+ if (!hist_field->type) -+ goto free; -+ goto out; -+ } -+ - if (WARN_ON_ONCE(!field)) - goto out; - -@@ -2345,7 +2367,9 @@ parse_field(struct hist_trigger_data *hist_data, struct trace_event_file *file, - hist_data->enable_timestamps = true; - if (*flags & HIST_FIELD_FL_TIMESTAMP_USECS) - hist_data->attrs->ts_in_usecs = true; -- } else { -+ } else if (strcmp(field_name, "cpu") == 0) -+ *flags |= HIST_FIELD_FL_CPU; -+ else { - field = trace_find_event_field(file->event_call, field_name); - if (!field || !field->size) { - field = ERR_PTR(-EINVAL); -@@ -4621,6 +4645,8 @@ static void hist_field_print(struct seq_file *m, struct hist_field *hist_field) - - if (hist_field->flags & HIST_FIELD_FL_TIMESTAMP) - seq_puts(m, "common_timestamp"); -+ else if (hist_field->flags & HIST_FIELD_FL_CPU) -+ seq_puts(m, "cpu"); - else if (field_name) { - if (hist_field->flags & HIST_FIELD_FL_VAR_REF) - seq_putc(m, '$'); --- -2.19.2 - diff --git a/kernel/patches-4.14.x-rt/0107-tracing-Add-hist-trigger-support-for-variable-refere.patch b/kernel/patches-4.14.x-rt/0107-tracing-Add-hist-trigger-support-for-variable-refere.patch deleted file mode 100644 index ff9fc3cfb..000000000 --- a/kernel/patches-4.14.x-rt/0107-tracing-Add-hist-trigger-support-for-variable-refere.patch +++ /dev/null @@ -1,170 +0,0 @@ -From 446b49d3adc44a040542385bd5efc52858a73cd3 Mon Sep 17 00:00:00 2001 -From: Tom Zanussi -Date: Mon, 15 Jan 2018 20:52:04 -0600 -Subject: [PATCH 107/450] tracing: Add hist trigger support for variable - reference aliases - -Add support for alias=$somevar where alias can be used as -onmatch.xxx($alias). - -Aliases are a way of creating a new name for an existing variable, for -flexibly in making naming more clear in certain cases. For example in -the below the user perhaps feels that using $new_lat in the synthetic -event invocation is opaque or doesn't fit well stylistically with -previous triggers, so creates an alias of $new_lat named $latency and -uses that in the call instead: - - # echo 'hist:keys=next_pid:new_lat=common_timestamp.usecs' > - /sys/kernel/debug/tracing/events/sched/sched_switch/trigger - - # echo 'hist:keys=pid:latency=$new_lat: - onmatch(sched.sched_switch).wake2($latency,pid)' > - /sys/kernel/debug/tracing/events/synthetic/wake1/trigger - -Link: http://lkml.kernel.org/r/ef20a65d921af3a873a6f1e8c71407c926d5586f.1516069914.git.tom.zanussi@linux.intel.com - -Signed-off-by: Tom Zanussi -Signed-off-by: Steven Rostedt (VMware) -(cherry picked from commit 53c5a4f99f1a5f6ba304453716da571f3e51bc79) -Signed-off-by: Sebastian Andrzej Siewior ---- - kernel/trace/trace_events_hist.c | 74 +++++++++++++++++++++++++++++--- - 1 file changed, 67 insertions(+), 7 deletions(-) - -diff --git a/kernel/trace/trace_events_hist.c b/kernel/trace/trace_events_hist.c -index 34a2e8d0a052..c8cfc56ff3ae 100644 ---- a/kernel/trace/trace_events_hist.c -+++ b/kernel/trace/trace_events_hist.c -@@ -228,6 +228,7 @@ enum hist_field_flags { - HIST_FIELD_FL_EXPR = 1 << 13, - HIST_FIELD_FL_VAR_REF = 1 << 14, - HIST_FIELD_FL_CPU = 1 << 15, -+ HIST_FIELD_FL_ALIAS = 1 << 16, - }; - - struct var_defs { -@@ -1609,7 +1610,8 @@ static const char *hist_field_name(struct hist_field *field, - - if (field->field) - field_name = field->field->name; -- else if (field->flags & HIST_FIELD_FL_LOG2) -+ else if (field->flags & HIST_FIELD_FL_LOG2 || -+ field->flags & HIST_FIELD_FL_ALIAS) - field_name = hist_field_name(field->operands[0], ++level); - else if (field->flags & HIST_FIELD_FL_TIMESTAMP) - field_name = "common_timestamp"; -@@ -2080,7 +2082,7 @@ static struct hist_field *create_hist_field(struct hist_trigger_data *hist_data, - - hist_field->hist_data = hist_data; - -- if (flags & HIST_FIELD_FL_EXPR) -+ if (flags & HIST_FIELD_FL_EXPR || flags & HIST_FIELD_FL_ALIAS) - goto out; /* caller will populate */ - - if (flags & HIST_FIELD_FL_VAR_REF) { -@@ -2217,10 +2219,18 @@ static int init_var_ref(struct hist_field *ref_field, - } - } - -- ref_field->name = kstrdup(var_field->var.name, GFP_KERNEL); -- if (!ref_field->name) { -- err = -ENOMEM; -- goto free; -+ if (var_field->var.name) { -+ ref_field->name = kstrdup(var_field->var.name, GFP_KERNEL); -+ if (!ref_field->name) { -+ err = -ENOMEM; -+ goto free; -+ } -+ } else if (var_field->name) { -+ ref_field->name = kstrdup(var_field->name, GFP_KERNEL); -+ if (!ref_field->name) { -+ err = -ENOMEM; -+ goto free; -+ } - } - - ref_field->type = kstrdup(var_field->type, GFP_KERNEL); -@@ -2382,6 +2392,28 @@ parse_field(struct hist_trigger_data *hist_data, struct trace_event_file *file, - return field; - } - -+static struct hist_field *create_alias(struct hist_trigger_data *hist_data, -+ struct hist_field *var_ref, -+ char *var_name) -+{ -+ struct hist_field *alias = NULL; -+ unsigned long flags = HIST_FIELD_FL_ALIAS | HIST_FIELD_FL_VAR; -+ -+ alias = create_hist_field(hist_data, NULL, flags, var_name); -+ if (!alias) -+ return NULL; -+ -+ alias->fn = var_ref->fn; -+ alias->operands[0] = var_ref; -+ -+ if (init_var_ref(alias, var_ref, var_ref->system, var_ref->event_name)) { -+ destroy_hist_field(alias, 0); -+ return NULL; -+ } -+ -+ return alias; -+} -+ - static struct hist_field *parse_atom(struct hist_trigger_data *hist_data, - struct trace_event_file *file, char *str, - unsigned long *flags, char *var_name) -@@ -2415,6 +2447,13 @@ static struct hist_field *parse_atom(struct hist_trigger_data *hist_data, - if (hist_field) { - hist_data->var_refs[hist_data->n_var_refs] = hist_field; - hist_field->var_ref_idx = hist_data->n_var_refs++; -+ if (var_name) { -+ hist_field = create_alias(hist_data, hist_field, var_name); -+ if (!hist_field) { -+ ret = -ENOMEM; -+ goto out; -+ } -+ } - return hist_field; - } - } else -@@ -2515,6 +2554,26 @@ static int check_expr_operands(struct hist_field *operand1, - unsigned long operand1_flags = operand1->flags; - unsigned long operand2_flags = operand2->flags; - -+ if ((operand1_flags & HIST_FIELD_FL_VAR_REF) || -+ (operand1_flags & HIST_FIELD_FL_ALIAS)) { -+ struct hist_field *var; -+ -+ var = find_var_field(operand1->var.hist_data, operand1->name); -+ if (!var) -+ return -EINVAL; -+ operand1_flags = var->flags; -+ } -+ -+ if ((operand2_flags & HIST_FIELD_FL_VAR_REF) || -+ (operand2_flags & HIST_FIELD_FL_ALIAS)) { -+ struct hist_field *var; -+ -+ var = find_var_field(operand2->var.hist_data, operand2->name); -+ if (!var) -+ return -EINVAL; -+ operand2_flags = var->flags; -+ } -+ - if ((operand1_flags & HIST_FIELD_FL_TIMESTAMP_USECS) != - (operand2_flags & HIST_FIELD_FL_TIMESTAMP_USECS)) - return -EINVAL; -@@ -4648,7 +4707,8 @@ static void hist_field_print(struct seq_file *m, struct hist_field *hist_field) - else if (hist_field->flags & HIST_FIELD_FL_CPU) - seq_puts(m, "cpu"); - else if (field_name) { -- if (hist_field->flags & HIST_FIELD_FL_VAR_REF) -+ if (hist_field->flags & HIST_FIELD_FL_VAR_REF || -+ hist_field->flags & HIST_FIELD_FL_ALIAS) - seq_putc(m, '$'); - seq_printf(m, "%s", field_name); - } --- -2.19.2 - diff --git a/kernel/patches-4.14.x-rt/0108-tracing-Add-last-error-error-facility-for-hist-trigg.patch b/kernel/patches-4.14.x-rt/0108-tracing-Add-last-error-error-facility-for-hist-trigg.patch deleted file mode 100644 index 753e8b90e..000000000 --- a/kernel/patches-4.14.x-rt/0108-tracing-Add-last-error-error-facility-for-hist-trigg.patch +++ /dev/null @@ -1,510 +0,0 @@ -From be1cdd9536bb6be78ddaa8a461955dc5d701bfc1 Mon Sep 17 00:00:00 2001 -From: Tom Zanussi -Date: Mon, 15 Jan 2018 20:52:05 -0600 -Subject: [PATCH 108/450] tracing: Add 'last error' error facility for hist - triggers - -With the addition of variables and actions, it's become necessary to -provide more detailed error information to users about syntax errors. - -Add a 'last error' facility accessible via the erroring event's 'hist' -file. Reading the hist file after an error will display more detailed -information about what went wrong, if information is available. This -extended error information will be available until the next hist -trigger command for that event. - - # echo xxx > /sys/kernel/debug/tracing/events/sched/sched_wakeup/trigger - echo: write error: Invalid argument - - # cat /sys/kernel/debug/tracing/events/sched/sched_wakeup/hist - - ERROR: Couldn't yyy: zzz - Last command: xxx - -Also add specific error messages for variable and action errors. - -Link: http://lkml.kernel.org/r/64e9c422fc8aeafcc2f7a3b4328c0cffe7969129.1516069914.git.tom.zanussi@linux.intel.com - -Signed-off-by: Tom Zanussi -Signed-off-by: Steven Rostedt (VMware) -(cherry picked from commit 215016863b5ec1ee5db5e20f32ffe015a497209f) -Signed-off-by: Sebastian Andrzej Siewior ---- - Documentation/trace/histogram.txt | 20 ++++ - kernel/trace/trace_events_hist.c | 164 +++++++++++++++++++++++++++--- - 2 files changed, 170 insertions(+), 14 deletions(-) - -diff --git a/Documentation/trace/histogram.txt b/Documentation/trace/histogram.txt -index be612ca79455..0aec2d8e166b 100644 ---- a/Documentation/trace/histogram.txt -+++ b/Documentation/trace/histogram.txt -@@ -188,6 +188,26 @@ - interpreted as microseconds. - cpu int - the cpu on which the event occurred. - -+ Extended error information -+ -------------------------- -+ -+ For some error conditions encountered when invoking a hist trigger -+ command, extended error information is available via the -+ corresponding event's 'hist' file. Reading the hist file after an -+ error will display more detailed information about what went wrong, -+ if information is available. This extended error information will -+ be available until the next hist trigger command for that event. -+ -+ If available for a given error condition, the extended error -+ information and usage takes the following form: -+ -+ # echo xxx > /sys/kernel/debug/tracing/events/sched/sched_wakeup/trigger -+ echo: write error: Invalid argument -+ -+ # cat /sys/kernel/debug/tracing/events/sched/sched_wakeup/hist -+ ERROR: Couldn't yyy: zzz -+ Last command: xxx -+ - 6.2 'hist' trigger examples - --------------------------- - -diff --git a/kernel/trace/trace_events_hist.c b/kernel/trace/trace_events_hist.c -index c8cfc56ff3ae..3856f173559a 100644 ---- a/kernel/trace/trace_events_hist.c -+++ b/kernel/trace/trace_events_hist.c -@@ -351,6 +351,65 @@ struct action_data { - }; - }; - -+ -+static char last_hist_cmd[MAX_FILTER_STR_VAL]; -+static char hist_err_str[MAX_FILTER_STR_VAL]; -+ -+static void last_cmd_set(char *str) -+{ -+ if (!str) -+ return; -+ -+ strncpy(last_hist_cmd, str, MAX_FILTER_STR_VAL - 1); -+} -+ -+static void hist_err(char *str, char *var) -+{ -+ int maxlen = MAX_FILTER_STR_VAL - 1; -+ -+ if (!str) -+ return; -+ -+ if (strlen(hist_err_str)) -+ return; -+ -+ if (!var) -+ var = ""; -+ -+ if (strlen(hist_err_str) + strlen(str) + strlen(var) > maxlen) -+ return; -+ -+ strcat(hist_err_str, str); -+ strcat(hist_err_str, var); -+} -+ -+static void hist_err_event(char *str, char *system, char *event, char *var) -+{ -+ char err[MAX_FILTER_STR_VAL]; -+ -+ if (system && var) -+ snprintf(err, MAX_FILTER_STR_VAL, "%s.%s.%s", system, event, var); -+ else if (system) -+ snprintf(err, MAX_FILTER_STR_VAL, "%s.%s", system, event); -+ else -+ strncpy(err, var, MAX_FILTER_STR_VAL); -+ -+ hist_err(str, err); -+} -+ -+static void hist_err_clear(void) -+{ -+ hist_err_str[0] = '\0'; -+} -+ -+static bool have_hist_err(void) -+{ -+ if (strlen(hist_err_str)) -+ return true; -+ -+ return false; -+} -+ - static LIST_HEAD(synth_event_list); - static DEFINE_MUTEX(synth_event_mutex); - -@@ -1448,8 +1507,10 @@ static struct trace_event_file *find_var_file(struct trace_array *tr, - continue; - - if (find_var_field(var_hist_data, var_name)) { -- if (found) -+ if (found) { -+ hist_err_event("Variable name not unique, need to use fully qualified name (subsys.event.var) for variable: ", system, event_name, var_name); - return NULL; -+ } - - found = file; - } -@@ -1498,6 +1559,7 @@ find_match_var(struct hist_trigger_data *hist_data, char *var_name) - hist_field = find_file_var(file, var_name); - if (hist_field) { - if (found) { -+ hist_err_event("Variable name not unique, need to use fully qualified name (subsys.event.var) for variable: ", system, event_name, var_name); - return ERR_PTR(-EINVAL); - } - -@@ -1781,6 +1843,7 @@ static int parse_assignment(char *str, struct hist_trigger_attrs *attrs) - char *assignment; - - if (attrs->n_assignments == TRACING_MAP_VARS_MAX) { -+ hist_err("Too many variables defined: ", str); - ret = -EINVAL; - goto out; - } -@@ -2335,6 +2398,10 @@ static struct hist_field *parse_var_ref(struct hist_trigger_data *hist_data, - if (var_field) - ref_field = create_var_ref(var_field, system, event_name); - -+ if (!ref_field) -+ hist_err_event("Couldn't find variable: $", -+ system, event_name, var_name); -+ - return ref_field; - } - -@@ -2494,6 +2561,7 @@ static struct hist_field *parse_unary(struct hist_trigger_data *hist_data, - // we support only -(xxx) i.e. explicit parens required - - if (level > 3) { -+ hist_err("Too many subexpressions (3 max): ", str); - ret = -EINVAL; - goto free; - } -@@ -2575,8 +2643,10 @@ static int check_expr_operands(struct hist_field *operand1, - } - - if ((operand1_flags & HIST_FIELD_FL_TIMESTAMP_USECS) != -- (operand2_flags & HIST_FIELD_FL_TIMESTAMP_USECS)) -+ (operand2_flags & HIST_FIELD_FL_TIMESTAMP_USECS)) { -+ hist_err("Timestamp units in expression don't match", NULL); - return -EINVAL; -+ } - - return 0; - } -@@ -2591,8 +2661,10 @@ static struct hist_field *parse_expr(struct hist_trigger_data *hist_data, - int field_op, ret = -EINVAL; - char *sep, *operand1_str; - -- if (level > 3) -+ if (level > 3) { -+ hist_err("Too many subexpressions (3 max): ", str); - return ERR_PTR(-EINVAL); -+ } - - field_op = contains_operator(str); - -@@ -2826,12 +2898,17 @@ create_field_var_hist(struct hist_trigger_data *target_hist_data, - char *cmd; - int ret; - -- if (target_hist_data->n_field_var_hists >= SYNTH_FIELDS_MAX) -+ if (target_hist_data->n_field_var_hists >= SYNTH_FIELDS_MAX) { -+ hist_err_event("onmatch: Too many field variables defined: ", -+ subsys_name, event_name, field_name); - return ERR_PTR(-EINVAL); -+ } - - file = event_file(tr, subsys_name, event_name); - - if (IS_ERR(file)) { -+ hist_err_event("onmatch: Event file not found: ", -+ subsys_name, event_name, field_name); - ret = PTR_ERR(file); - return ERR_PTR(ret); - } -@@ -2843,8 +2920,11 @@ create_field_var_hist(struct hist_trigger_data *target_hist_data, - * yet a registered histogram so we can't use that. - */ - hist_data = find_compatible_hist(target_hist_data, file); -- if (!hist_data) -+ if (!hist_data) { -+ hist_err_event("onmatch: Matching event histogram not found: ", -+ subsys_name, event_name, field_name); - return ERR_PTR(-EINVAL); -+ } - - /* See if a synthetic field variable has already been created */ - event_var = find_synthetic_field_var(target_hist_data, subsys_name, -@@ -2903,6 +2983,8 @@ create_field_var_hist(struct hist_trigger_data *target_hist_data, - kfree(cmd); - kfree(var_hist->cmd); - kfree(var_hist); -+ hist_err_event("onmatch: Couldn't create histogram for field: ", -+ subsys_name, event_name, field_name); - return ERR_PTR(ret); - } - -@@ -2914,6 +2996,8 @@ create_field_var_hist(struct hist_trigger_data *target_hist_data, - if (IS_ERR_OR_NULL(event_var)) { - kfree(var_hist->cmd); - kfree(var_hist); -+ hist_err_event("onmatch: Couldn't find synthetic variable: ", -+ subsys_name, event_name, field_name); - return ERR_PTR(-EINVAL); - } - -@@ -3050,18 +3134,21 @@ static struct field_var *create_field_var(struct hist_trigger_data *hist_data, - int ret = 0; - - if (hist_data->n_field_vars >= SYNTH_FIELDS_MAX) { -+ hist_err("Too many field variables defined: ", field_name); - ret = -EINVAL; - goto err; - } - - val = parse_atom(hist_data, file, field_name, &flags, NULL); - if (IS_ERR(val)) { -+ hist_err("Couldn't parse field variable: ", field_name); - ret = PTR_ERR(val); - goto err; - } - - var = create_var(hist_data, file, field_name, val->size, val->type); - if (IS_ERR(var)) { -+ hist_err("Couldn't create or find variable: ", field_name); - kfree(val); - ret = PTR_ERR(var); - goto err; -@@ -3204,13 +3291,17 @@ static int onmax_create(struct hist_trigger_data *hist_data, - int ret = 0; - - onmax_var_str = data->onmax.var_str; -- if (onmax_var_str[0] != '$') -+ if (onmax_var_str[0] != '$') { -+ hist_err("onmax: For onmax(x), x must be a variable: ", onmax_var_str); - return -EINVAL; -+ } - onmax_var_str++; - - var_field = find_target_event_var(hist_data, NULL, NULL, onmax_var_str); -- if (!var_field) -+ if (!var_field) { -+ hist_err("onmax: Couldn't find onmax variable: ", onmax_var_str); - return -EINVAL; -+ } - - flags = HIST_FIELD_FL_VAR_REF; - ref_field = create_hist_field(hist_data, NULL, flags, NULL); -@@ -3230,6 +3321,7 @@ static int onmax_create(struct hist_trigger_data *hist_data, - data->onmax.max_var_ref_idx = var_ref_idx; - max_var = create_var(hist_data, file, "max", sizeof(u64), "u64"); - if (IS_ERR(max_var)) { -+ hist_err("onmax: Couldn't create onmax variable: ", "max"); - ret = PTR_ERR(max_var); - goto out; - } -@@ -3244,6 +3336,7 @@ static int onmax_create(struct hist_trigger_data *hist_data, - - field_var = create_target_field_var(hist_data, NULL, NULL, param); - if (IS_ERR(field_var)) { -+ hist_err("onmax: Couldn't create field variable: ", param); - ret = PTR_ERR(field_var); - kfree(param); - goto out; -@@ -3276,6 +3369,7 @@ static int parse_action_params(char *params, struct action_data *data) - - param = strstrip(param); - if (strlen(param) < 2) { -+ hist_err("Invalid action param: ", param); - ret = -EINVAL; - goto out; - } -@@ -3451,6 +3545,9 @@ onmatch_find_var(struct hist_trigger_data *hist_data, struct action_data *data, - hist_field = find_event_var(hist_data, system, event, var); - } - -+ if (!hist_field) -+ hist_err_event("onmatch: Couldn't find onmatch param: $", system, event, var); -+ - return hist_field; - } - -@@ -3518,6 +3615,7 @@ static int onmatch_create(struct hist_trigger_data *hist_data, - mutex_lock(&synth_event_mutex); - event = find_synth_event(data->onmatch.synth_event_name); - if (!event) { -+ hist_err("onmatch: Couldn't find synthetic event: ", data->onmatch.synth_event_name); - mutex_unlock(&synth_event_mutex); - return -EINVAL; - } -@@ -3577,12 +3675,15 @@ static int onmatch_create(struct hist_trigger_data *hist_data, - continue; - } - -+ hist_err_event("onmatch: Param type doesn't match synthetic event field type: ", -+ system, event_name, param); - kfree(p); - ret = -EINVAL; - goto err; - } - - if (field_pos != event->n_fields) { -+ hist_err("onmatch: Param count doesn't match synthetic event field count: ", event->name); - ret = -EINVAL; - goto err; - } -@@ -3612,15 +3713,22 @@ static struct action_data *onmatch_parse(struct trace_array *tr, char *str) - return ERR_PTR(-ENOMEM); - - match_event = strsep(&str, ")"); -- if (!match_event || !str) -+ if (!match_event || !str) { -+ hist_err("onmatch: Missing closing paren: ", match_event); - goto free; -+ } - - match_event_system = strsep(&match_event, "."); -- if (!match_event) -+ if (!match_event) { -+ hist_err("onmatch: Missing subsystem for match event: ", match_event_system); - goto free; -+ } - -- if (IS_ERR(event_file(tr, match_event_system, match_event))) -+ if (IS_ERR(event_file(tr, match_event_system, match_event))) { -+ hist_err_event("onmatch: Invalid subsystem or event name: ", -+ match_event_system, match_event, NULL); - goto free; -+ } - - data->onmatch.match_event = kstrdup(match_event, GFP_KERNEL); - if (!data->onmatch.match_event) { -@@ -3635,12 +3743,16 @@ static struct action_data *onmatch_parse(struct trace_array *tr, char *str) - } - - strsep(&str, "."); -- if (!str) -+ if (!str) { -+ hist_err("onmatch: Missing . after onmatch(): ", str); - goto free; -+ } - - synth_event_name = strsep(&str, "("); -- if (!synth_event_name || !str) -+ if (!synth_event_name || !str) { -+ hist_err("onmatch: Missing opening paramlist paren: ", synth_event_name); - goto free; -+ } - - data->onmatch.synth_event_name = kstrdup(synth_event_name, GFP_KERNEL); - if (!data->onmatch.synth_event_name) { -@@ -3649,8 +3761,10 @@ static struct action_data *onmatch_parse(struct trace_array *tr, char *str) - } - - params = strsep(&str, ")"); -- if (!params || !str || (str && strlen(str))) -+ if (!params || !str || (str && strlen(str))) { -+ hist_err("onmatch: Missing closing paramlist paren: ", params); - goto free; -+ } - - ret = parse_action_params(params, data); - if (ret) -@@ -3725,7 +3839,9 @@ static int create_var_field(struct hist_trigger_data *hist_data, - - if (WARN_ON(val_idx >= TRACING_MAP_VALS_MAX + TRACING_MAP_VARS_MAX)) - return -EINVAL; -+ - if (find_var(hist_data, file, var_name) && !hist_data->remove) { -+ hist_err("Variable already defined: ", var_name); - return -EINVAL; - } - -@@ -3806,6 +3922,7 @@ static int create_key_field(struct hist_trigger_data *hist_data, - } - - if (hist_field->flags & HIST_FIELD_FL_VAR_REF) { -+ hist_err("Using variable references as keys not supported: ", field_str); - destroy_hist_field(hist_field, 0); - ret = -EINVAL; - goto out; -@@ -3919,11 +4036,13 @@ static int parse_var_defs(struct hist_trigger_data *hist_data) - - var_name = strsep(&field_str, "="); - if (!var_name || !field_str) { -+ hist_err("Malformed assignment: ", var_name); - ret = -EINVAL; - goto free; - } - - if (n_vars == TRACING_MAP_VARS_MAX) { -+ hist_err("Too many variables defined: ", var_name); - ret = -EINVAL; - goto free; - } -@@ -4677,6 +4796,11 @@ static int hist_show(struct seq_file *m, void *v) - hist_trigger_show(m, data, n++); - } - -+ if (have_hist_err()) { -+ seq_printf(m, "\nERROR: %s\n", hist_err_str); -+ seq_printf(m, " Last command: %s\n", last_hist_cmd); -+ } -+ - out_unlock: - mutex_unlock(&event_mutex); - -@@ -5041,6 +5165,7 @@ static int hist_register_trigger(char *glob, struct event_trigger_ops *ops, - if (named_data) { - if (!hist_trigger_match(data, named_data, named_data, - true)) { -+ hist_err("Named hist trigger doesn't match existing named trigger (includes variables): ", hist_data->attrs->name); - ret = -EINVAL; - goto out; - } -@@ -5060,13 +5185,16 @@ static int hist_register_trigger(char *glob, struct event_trigger_ops *ops, - test->paused = false; - else if (hist_data->attrs->clear) - hist_clear(test); -- else -+ else { -+ hist_err("Hist trigger already exists", NULL); - ret = -EEXIST; -+ } - goto out; - } - } - new: - if (hist_data->attrs->cont || hist_data->attrs->clear) { -+ hist_err("Can't clear or continue a nonexistent hist trigger", NULL); - ret = -ENOENT; - goto out; - } -@@ -5253,6 +5381,11 @@ static int event_hist_trigger_func(struct event_command *cmd_ops, - char *trigger, *p; - int ret = 0; - -+ if (glob && strlen(glob)) { -+ last_cmd_set(param); -+ hist_err_clear(); -+ } -+ - if (!param) - return -EINVAL; - -@@ -5391,6 +5524,9 @@ static int event_hist_trigger_func(struct event_command *cmd_ops, - /* Just return zero, not the number of registered triggers */ - ret = 0; - out: -+ if (ret == 0) -+ hist_err_clear(); -+ - return ret; - out_unreg: - cmd_ops->unreg(glob+1, trigger_ops, trigger_data, file); --- -2.19.2 - diff --git a/kernel/patches-4.14.x-rt/0109-tracing-Add-inter-event-hist-trigger-Documentation.patch b/kernel/patches-4.14.x-rt/0109-tracing-Add-inter-event-hist-trigger-Documentation.patch deleted file mode 100644 index 1183254a5..000000000 --- a/kernel/patches-4.14.x-rt/0109-tracing-Add-inter-event-hist-trigger-Documentation.patch +++ /dev/null @@ -1,411 +0,0 @@ -From d3c22a59774ab35444d4c5958df90ced8600758a Mon Sep 17 00:00:00 2001 -From: Tom Zanussi -Date: Mon, 15 Jan 2018 20:52:06 -0600 -Subject: [PATCH 109/450] tracing: Add inter-event hist trigger Documentation - -Add background and details on inter-event hist triggers, including -hist variables, synthetic events, and actions. - -Link: http://lkml.kernel.org/r/b0414efb66535aa52aa7411f58c3d56724027fce.1516069914.git.tom.zanussi@linux.intel.com - -Signed-off-by: Tom Zanussi -Signed-off-by: Baohong Liu -Signed-off-by: Steven Rostedt (VMware) -(cherry picked from commit 7d5f30af5e39e572f6984c1083fe79fd7dc34d04) -Signed-off-by: Sebastian Andrzej Siewior ---- - Documentation/trace/histogram.txt | 381 ++++++++++++++++++++++++++++++ - 1 file changed, 381 insertions(+) - -diff --git a/Documentation/trace/histogram.txt b/Documentation/trace/histogram.txt -index 0aec2d8e166b..df08882d091c 100644 ---- a/Documentation/trace/histogram.txt -+++ b/Documentation/trace/histogram.txt -@@ -1603,3 +1603,384 @@ - Hits: 489 - Entries: 7 - Dropped: 0 -+ -+ -+2.2 Inter-event hist triggers -+----------------------------- -+ -+Inter-event hist triggers are hist triggers that combine values from -+one or more other events and create a histogram using that data. Data -+from an inter-event histogram can in turn become the source for -+further combined histograms, thus providing a chain of related -+histograms, which is important for some applications. -+ -+The most important example of an inter-event quantity that can be used -+in this manner is latency, which is simply a difference in timestamps -+between two events. Although latency is the most important -+inter-event quantity, note that because the support is completely -+general across the trace event subsystem, any event field can be used -+in an inter-event quantity. -+ -+An example of a histogram that combines data from other histograms -+into a useful chain would be a 'wakeupswitch latency' histogram that -+combines a 'wakeup latency' histogram and a 'switch latency' -+histogram. -+ -+Normally, a hist trigger specification consists of a (possibly -+compound) key along with one or more numeric values, which are -+continually updated sums associated with that key. A histogram -+specification in this case consists of individual key and value -+specifications that refer to trace event fields associated with a -+single event type. -+ -+The inter-event hist trigger extension allows fields from multiple -+events to be referenced and combined into a multi-event histogram -+specification. In support of this overall goal, a few enabling -+features have been added to the hist trigger support: -+ -+ - In order to compute an inter-event quantity, a value from one -+ event needs to saved and then referenced from another event. This -+ requires the introduction of support for histogram 'variables'. -+ -+ - The computation of inter-event quantities and their combination -+ require some minimal amount of support for applying simple -+ expressions to variables (+ and -). -+ -+ - A histogram consisting of inter-event quantities isn't logically a -+ histogram on either event (so having the 'hist' file for either -+ event host the histogram output doesn't really make sense). To -+ address the idea that the histogram is associated with a -+ combination of events, support is added allowing the creation of -+ 'synthetic' events that are events derived from other events. -+ These synthetic events are full-fledged events just like any other -+ and can be used as such, as for instance to create the -+ 'combination' histograms mentioned previously. -+ -+ - A set of 'actions' can be associated with histogram entries - -+ these can be used to generate the previously mentioned synthetic -+ events, but can also be used for other purposes, such as for -+ example saving context when a 'max' latency has been hit. -+ -+ - Trace events don't have a 'timestamp' associated with them, but -+ there is an implicit timestamp saved along with an event in the -+ underlying ftrace ring buffer. This timestamp is now exposed as a -+ a synthetic field named 'common_timestamp' which can be used in -+ histograms as if it were any other event field; it isn't an actual -+ field in the trace format but rather is a synthesized value that -+ nonetheless can be used as if it were an actual field. By default -+ it is in units of nanoseconds; appending '.usecs' to a -+ common_timestamp field changes the units to microseconds. -+ -+These features are decribed in more detail in the following sections. -+ -+2.2.1 Histogram Variables -+------------------------- -+ -+Variables are simply named locations used for saving and retrieving -+values between matching events. A 'matching' event is defined as an -+event that has a matching key - if a variable is saved for a histogram -+entry corresponding to that key, any subsequent event with a matching -+key can access that variable. -+ -+A variable's value is normally available to any subsequent event until -+it is set to something else by a subsequent event. The one exception -+to that rule is that any variable used in an expression is essentially -+'read-once' - once it's used by an expression in a subsequent event, -+it's reset to its 'unset' state, which means it can't be used again -+unless it's set again. This ensures not only that an event doesn't -+use an uninitialized variable in a calculation, but that that variable -+is used only once and not for any unrelated subsequent match. -+ -+The basic syntax for saving a variable is to simply prefix a unique -+variable name not corresponding to any keyword along with an '=' sign -+to any event field. -+ -+Either keys or values can be saved and retrieved in this way. This -+creates a variable named 'ts0' for a histogram entry with the key -+'next_pid': -+ -+ # echo 'hist:keys=next_pid:vals=$ts0:ts0=common_timestamp ... >> \ -+ event/trigger -+ -+The ts0 variable can be accessed by any subsequent event having the -+same pid as 'next_pid'. -+ -+Variable references are formed by prepending the variable name with -+the '$' sign. Thus for example, the ts0 variable above would be -+referenced as '$ts0' in expressions. -+ -+Because 'vals=' is used, the common_timestamp variable value above -+will also be summed as a normal histogram value would (though for a -+timestamp it makes little sense). -+ -+The below shows that a key value can also be saved in the same way: -+ -+ # echo 'hist:timer_pid=common_pid:key=timer_pid ...' >> event/trigger -+ -+If a variable isn't a key variable or prefixed with 'vals=', the -+associated event field will be saved in a variable but won't be summed -+as a value: -+ -+ # echo 'hist:keys=next_pid:ts1=common_timestamp ... >> event/trigger -+ -+Multiple variables can be assigned at the same time. The below would -+result in both ts0 and b being created as variables, with both -+common_timestamp and field1 additionally being summed as values: -+ -+ # echo 'hist:keys=pid:vals=$ts0,$b:ts0=common_timestamp,b=field1 ... >> \ -+ event/trigger -+ -+Note that variable assignments can appear either preceding or -+following their use. The command below behaves identically to the -+command above: -+ -+ # echo 'hist:keys=pid:ts0=common_timestamp,b=field1:vals=$ts0,$b ... >> \ -+ event/trigger -+ -+Any number of variables not bound to a 'vals=' prefix can also be -+assigned by simply separating them with colons. Below is the same -+thing but without the values being summed in the histogram: -+ -+ # echo 'hist:keys=pid:ts0=common_timestamp:b=field1 ... >> event/trigger -+ -+Variables set as above can be referenced and used in expressions on -+another event. -+ -+For example, here's how a latency can be calculated: -+ -+ # echo 'hist:keys=pid,prio:ts0=common_timestamp ... >> event1/trigger -+ # echo 'hist:keys=next_pid:wakeup_lat=common_timestamp-$ts0 ... >> event2/trigger -+ -+In the first line above, the event's timetamp is saved into the -+variable ts0. In the next line, ts0 is subtracted from the second -+event's timestamp to produce the latency, which is then assigned into -+yet another variable, 'wakeup_lat'. The hist trigger below in turn -+makes use of the wakeup_lat variable to compute a combined latency -+using the same key and variable from yet another event: -+ -+ # echo 'hist:key=pid:wakeupswitch_lat=$wakeup_lat+$switchtime_lat ... >> event3/trigger -+ -+2.2.2 Synthetic Events -+---------------------- -+ -+Synthetic events are user-defined events generated from hist trigger -+variables or fields associated with one or more other events. Their -+purpose is to provide a mechanism for displaying data spanning -+multiple events consistent with the existing and already familiar -+usage for normal events. -+ -+To define a synthetic event, the user writes a simple specification -+consisting of the name of the new event along with one or more -+variables and their types, which can be any valid field type, -+separated by semicolons, to the tracing/synthetic_events file. -+ -+For instance, the following creates a new event named 'wakeup_latency' -+with 3 fields: lat, pid, and prio. Each of those fields is simply a -+variable reference to a variable on another event: -+ -+ # echo 'wakeup_latency \ -+ u64 lat; \ -+ pid_t pid; \ -+ int prio' >> \ -+ /sys/kernel/debug/tracing/synthetic_events -+ -+Reading the tracing/synthetic_events file lists all the currently -+defined synthetic events, in this case the event defined above: -+ -+ # cat /sys/kernel/debug/tracing/synthetic_events -+ wakeup_latency u64 lat; pid_t pid; int prio -+ -+An existing synthetic event definition can be removed by prepending -+the command that defined it with a '!': -+ -+ # echo '!wakeup_latency u64 lat pid_t pid int prio' >> \ -+ /sys/kernel/debug/tracing/synthetic_events -+ -+At this point, there isn't yet an actual 'wakeup_latency' event -+instantiated in the event subsytem - for this to happen, a 'hist -+trigger action' needs to be instantiated and bound to actual fields -+and variables defined on other events (see Section 6.3.3 below). -+ -+Once that is done, an event instance is created, and a histogram can -+be defined using it: -+ -+ # echo 'hist:keys=pid,prio,lat.log2:sort=pid,lat' >> \ -+ /sys/kernel/debug/tracing/events/synthetic/wakeup_latency/trigger -+ -+The new event is created under the tracing/events/synthetic/ directory -+and looks and behaves just like any other event: -+ -+ # ls /sys/kernel/debug/tracing/events/synthetic/wakeup_latency -+ enable filter format hist id trigger -+ -+Like any other event, once a histogram is enabled for the event, the -+output can be displayed by reading the event's 'hist' file. -+ -+2.2.3 Hist trigger 'actions' -+---------------------------- -+ -+A hist trigger 'action' is a function that's executed whenever a -+histogram entry is added or updated. -+ -+The default 'action' if no special function is explicity specified is -+as it always has been, to simply update the set of values associated -+with an entry. Some applications, however, may want to perform -+additional actions at that point, such as generate another event, or -+compare and save a maximum. -+ -+The following additional actions are available. To specify an action -+for a given event, simply specify the action between colons in the -+hist trigger specification. -+ -+ - onmatch(matching.event).(param list) -+ -+ The 'onmatch(matching.event).(params)' hist -+ trigger action is invoked whenever an event matches and the -+ histogram entry would be added or updated. It causes the named -+ synthetic event to be generated with the values given in the -+ 'param list'. The result is the generation of a synthetic event -+ that consists of the values contained in those variables at the -+ time the invoking event was hit. -+ -+ The 'param list' consists of one or more parameters which may be -+ either variables or fields defined on either the 'matching.event' -+ or the target event. The variables or fields specified in the -+ param list may be either fully-qualified or unqualified. If a -+ variable is specified as unqualified, it must be unique between -+ the two events. A field name used as a param can be unqualified -+ if it refers to the target event, but must be fully qualified if -+ it refers to the matching event. A fully-qualified name is of the -+ form 'system.event_name.$var_name' or 'system.event_name.field'. -+ -+ The 'matching.event' specification is simply the fully qualified -+ event name of the event that matches the target event for the -+ onmatch() functionality, in the form 'system.event_name'. -+ -+ Finally, the number and type of variables/fields in the 'param -+ list' must match the number and types of the fields in the -+ synthetic event being generated. -+ -+ As an example the below defines a simple synthetic event and uses -+ a variable defined on the sched_wakeup_new event as a parameter -+ when invoking the synthetic event. Here we define the synthetic -+ event: -+ -+ # echo 'wakeup_new_test pid_t pid' >> \ -+ /sys/kernel/debug/tracing/synthetic_events -+ -+ # cat /sys/kernel/debug/tracing/synthetic_events -+ wakeup_new_test pid_t pid -+ -+ The following hist trigger both defines the missing testpid -+ variable and specifies an onmatch() action that generates a -+ wakeup_new_test synthetic event whenever a sched_wakeup_new event -+ occurs, which because of the 'if comm == "cyclictest"' filter only -+ happens when the executable is cyclictest: -+ -+ # echo 'hist:keys=$testpid:testpid=pid:onmatch(sched.sched_wakeup_new).\ -+ wakeup_new_test($testpid) if comm=="cyclictest"' >> \ -+ /sys/kernel/debug/tracing/events/sched/sched_wakeup_new/trigger -+ -+ Creating and displaying a histogram based on those events is now -+ just a matter of using the fields and new synthetic event in the -+ tracing/events/synthetic directory, as usual: -+ -+ # echo 'hist:keys=pid:sort=pid' >> \ -+ /sys/kernel/debug/tracing/events/synthetic/wakeup_new_test/trigger -+ -+ Running 'cyclictest' should cause wakeup_new events to generate -+ wakeup_new_test synthetic events which should result in histogram -+ output in the wakeup_new_test event's hist file: -+ -+ # cat /sys/kernel/debug/tracing/events/synthetic/wakeup_new_test/hist -+ -+ A more typical usage would be to use two events to calculate a -+ latency. The following example uses a set of hist triggers to -+ produce a 'wakeup_latency' histogram: -+ -+ First, we define a 'wakeup_latency' synthetic event: -+ -+ # echo 'wakeup_latency u64 lat; pid_t pid; int prio' >> \ -+ /sys/kernel/debug/tracing/synthetic_events -+ -+ Next, we specify that whenever we see a sched_waking event for a -+ cyclictest thread, save the timestamp in a 'ts0' variable: -+ -+ # echo 'hist:keys=$saved_pid:saved_pid=pid:ts0=common_timestamp.usecs \ -+ if comm=="cyclictest"' >> \ -+ /sys/kernel/debug/tracing/events/sched/sched_waking/trigger -+ -+ Then, when the corresponding thread is actually scheduled onto the -+ CPU by a sched_switch event, calculate the latency and use that -+ along with another variable and an event field to generate a -+ wakeup_latency synthetic event: -+ -+ # echo 'hist:keys=next_pid:wakeup_lat=common_timestamp.usecs-$ts0:\ -+ onmatch(sched.sched_waking).wakeup_latency($wakeup_lat,\ -+ $saved_pid,next_prio) if next_comm=="cyclictest"' >> \ -+ /sys/kernel/debug/tracing/events/sched/sched_switch/trigger -+ -+ We also need to create a histogram on the wakeup_latency synthetic -+ event in order to aggregate the generated synthetic event data: -+ -+ # echo 'hist:keys=pid,prio,lat:sort=pid,lat' >> \ -+ /sys/kernel/debug/tracing/events/synthetic/wakeup_latency/trigger -+ -+ Finally, once we've run cyclictest to actually generate some -+ events, we can see the output by looking at the wakeup_latency -+ synthetic event's hist file: -+ -+ # cat /sys/kernel/debug/tracing/events/synthetic/wakeup_latency/hist -+ -+ - onmax(var).save(field,.. .) -+ -+ The 'onmax(var).save(field,...)' hist trigger action is invoked -+ whenever the value of 'var' associated with a histogram entry -+ exceeds the current maximum contained in that variable. -+ -+ The end result is that the trace event fields specified as the -+ onmax.save() params will be saved if 'var' exceeds the current -+ maximum for that hist trigger entry. This allows context from the -+ event that exhibited the new maximum to be saved for later -+ reference. When the histogram is displayed, additional fields -+ displaying the saved values will be printed. -+ -+ As an example the below defines a couple of hist triggers, one for -+ sched_waking and another for sched_switch, keyed on pid. Whenever -+ a sched_waking occurs, the timestamp is saved in the entry -+ corresponding to the current pid, and when the scheduler switches -+ back to that pid, the timestamp difference is calculated. If the -+ resulting latency, stored in wakeup_lat, exceeds the current -+ maximum latency, the values specified in the save() fields are -+ recoreded: -+ -+ # echo 'hist:keys=pid:ts0=common_timestamp.usecs \ -+ if comm=="cyclictest"' >> \ -+ /sys/kernel/debug/tracing/events/sched/sched_waking/trigger -+ -+ # echo 'hist:keys=next_pid:\ -+ wakeup_lat=common_timestamp.usecs-$ts0:\ -+ onmax($wakeup_lat).save(next_comm,prev_pid,prev_prio,prev_comm) \ -+ if next_comm=="cyclictest"' >> \ -+ /sys/kernel/debug/tracing/events/sched/sched_switch/trigger -+ -+ When the histogram is displayed, the max value and the saved -+ values corresponding to the max are displayed following the rest -+ of the fields: -+ -+ # cat /sys/kernel/debug/tracing/events/sched/sched_switch/hist -+ { next_pid: 2255 } hitcount: 239 -+ common_timestamp-ts0: 0 -+ max: 27 -+ next_comm: cyclictest -+ prev_pid: 0 prev_prio: 120 prev_comm: swapper/1 -+ -+ { next_pid: 2256 } hitcount: 2355 -+ common_timestamp-ts0: 0 -+ max: 49 next_comm: cyclictest -+ prev_pid: 0 prev_prio: 120 prev_comm: swapper/0 -+ -+ Totals: -+ Hits: 12970 -+ Entries: 2 -+ Dropped: 0 --- -2.19.2 - diff --git a/kernel/patches-4.14.x-rt/0110-tracing-Make-tracing_set_clock-non-static.patch b/kernel/patches-4.14.x-rt/0110-tracing-Make-tracing_set_clock-non-static.patch deleted file mode 100644 index 0d7fb266a..000000000 --- a/kernel/patches-4.14.x-rt/0110-tracing-Make-tracing_set_clock-non-static.patch +++ /dev/null @@ -1,51 +0,0 @@ -From 6987f618fe9c279ef6bcfb0a9a1a37007a8e85d5 Mon Sep 17 00:00:00 2001 -From: Tom Zanussi -Date: Mon, 15 Jan 2018 20:52:07 -0600 -Subject: [PATCH 110/450] tracing: Make tracing_set_clock() non-static - -Allow tracing code outside of trace.c to access tracing_set_clock(). - -Some applications may require a particular clock in order to function -properly, such as latency calculations. - -Also, add an accessor returning the current clock string. - -Link: http://lkml.kernel.org/r/6d1c53e9ee2163f54e1849f5376573f54f0e6009.1516069914.git.tom.zanussi@linux.intel.com - -Signed-off-by: Tom Zanussi -Signed-off-by: Steven Rostedt (VMware) -(cherry picked from commit f8913a56885a33eda24452c1839102c305bf7df5) -Signed-off-by: Sebastian Andrzej Siewior ---- - kernel/trace/trace.c | 2 +- - kernel/trace/trace.h | 1 + - 2 files changed, 2 insertions(+), 1 deletion(-) - -diff --git a/kernel/trace/trace.c b/kernel/trace/trace.c -index 5b35e4257cc5..6c2aae7629a7 100644 ---- a/kernel/trace/trace.c -+++ b/kernel/trace/trace.c -@@ -6230,7 +6230,7 @@ static int tracing_clock_show(struct seq_file *m, void *v) - return 0; - } - --static int tracing_set_clock(struct trace_array *tr, const char *clockstr) -+int tracing_set_clock(struct trace_array *tr, const char *clockstr) - { - int i; - -diff --git a/kernel/trace/trace.h b/kernel/trace/trace.h -index 5975d5f5c4bc..0b8af849dc75 100644 ---- a/kernel/trace/trace.h -+++ b/kernel/trace/trace.h -@@ -289,6 +289,7 @@ extern int trace_array_get(struct trace_array *tr); - extern void trace_array_put(struct trace_array *tr); - - extern int tracing_set_time_stamp_abs(struct trace_array *tr, bool abs); -+extern int tracing_set_clock(struct trace_array *tr, const char *clockstr); - - extern bool trace_clock_in_ns(struct trace_array *tr); - --- -2.19.2 - diff --git a/kernel/patches-4.14.x-rt/0111-tracing-Add-a-clock-attribute-for-hist-triggers.patch b/kernel/patches-4.14.x-rt/0111-tracing-Add-a-clock-attribute-for-hist-triggers.patch deleted file mode 100644 index bdd2a6922..000000000 --- a/kernel/patches-4.14.x-rt/0111-tracing-Add-a-clock-attribute-for-hist-triggers.patch +++ /dev/null @@ -1,145 +0,0 @@ -From 89005b6d25c813eb854b61e5b6bdb950214107ce Mon Sep 17 00:00:00 2001 -From: Tom Zanussi -Date: Mon, 15 Jan 2018 20:52:08 -0600 -Subject: [PATCH 111/450] tracing: Add a clock attribute for hist triggers - -The default clock if timestamps are used in a histogram is "global". -If timestamps aren't used, the clock is irrelevant. - -Use the "clock=" param only if you want to override the default -"global" clock for a histogram with timestamps. - -Link: http://lkml.kernel.org/r/427bed1389c5d22aa40c3e0683e30cc3d151e260.1516069914.git.tom.zanussi@linux.intel.com - -Signed-off-by: Tom Zanussi -Signed-off-by: Rajvi Jingar -Signed-off-by: Steven Rostedt (VMware) -(cherry picked from commit 77e7689e0b182465cfcd7c328061b70eecdcde31) -Signed-off-by: Sebastian Andrzej Siewior ---- - Documentation/trace/histogram.txt | 11 +++++++- - kernel/trace/trace_events_hist.c | 42 ++++++++++++++++++++++++++++--- - 2 files changed, 49 insertions(+), 4 deletions(-) - -diff --git a/Documentation/trace/histogram.txt b/Documentation/trace/histogram.txt -index df08882d091c..6e05510afc28 100644 ---- a/Documentation/trace/histogram.txt -+++ b/Documentation/trace/histogram.txt -@@ -1671,7 +1671,16 @@ features have been added to the hist trigger support: - it is in units of nanoseconds; appending '.usecs' to a - common_timestamp field changes the units to microseconds. - --These features are decribed in more detail in the following sections. -+A note on inter-event timestamps: If common_timestamp is used in a -+histogram, the trace buffer is automatically switched over to using -+absolute timestamps and the "global" trace clock, in order to avoid -+bogus timestamp differences with other clocks that aren't coherent -+across CPUs. This can be overridden by specifying one of the other -+trace clocks instead, using the "clock=XXX" hist trigger attribute, -+where XXX is any of the clocks listed in the tracing/trace_clock -+pseudo-file. -+ -+These features are described in more detail in the following sections. - - 2.2.1 Histogram Variables - ------------------------- -diff --git a/kernel/trace/trace_events_hist.c b/kernel/trace/trace_events_hist.c -index 3856f173559a..e47b56632367 100644 ---- a/kernel/trace/trace_events_hist.c -+++ b/kernel/trace/trace_events_hist.c -@@ -242,6 +242,7 @@ struct hist_trigger_attrs { - char *vals_str; - char *sort_key_str; - char *name; -+ char *clock; - bool pause; - bool cont; - bool clear; -@@ -1776,6 +1777,7 @@ static void destroy_hist_trigger_attrs(struct hist_trigger_attrs *attrs) - kfree(attrs->sort_key_str); - kfree(attrs->keys_str); - kfree(attrs->vals_str); -+ kfree(attrs->clock); - kfree(attrs); - } - -@@ -1831,6 +1833,19 @@ static int parse_assignment(char *str, struct hist_trigger_attrs *attrs) - ret = -ENOMEM; - goto out; - } -+ } else if (strncmp(str, "clock=", strlen("clock=")) == 0) { -+ strsep(&str, "="); -+ if (!str) { -+ ret = -EINVAL; -+ goto out; -+ } -+ -+ str = strstrip(str); -+ attrs->clock = kstrdup(str, GFP_KERNEL); -+ if (!attrs->clock) { -+ ret = -ENOMEM; -+ goto out; -+ } - } else if (strncmp(str, "size=", strlen("size=")) == 0) { - int map_bits = parse_map_size(str); - -@@ -1895,6 +1910,14 @@ static struct hist_trigger_attrs *parse_hist_trigger_attrs(char *trigger_str) - goto free; - } - -+ if (!attrs->clock) { -+ attrs->clock = kstrdup("global", GFP_KERNEL); -+ if (!attrs->clock) { -+ ret = -ENOMEM; -+ goto free; -+ } -+ } -+ - return attrs; - free: - destroy_hist_trigger_attrs(attrs); -@@ -4936,6 +4959,8 @@ static int event_hist_trigger_print(struct seq_file *m, - seq_puts(m, ".descending"); - } - seq_printf(m, ":size=%u", (1 << hist_data->map->map_bits)); -+ if (hist_data->enable_timestamps) -+ seq_printf(m, ":clock=%s", hist_data->attrs->clock); - - print_actions_spec(m, hist_data); - -@@ -5203,7 +5228,6 @@ static int hist_register_trigger(char *glob, struct event_trigger_ops *ops, - data->paused = true; - - if (named_data) { -- destroy_hist_data(data->private_data); - data->private_data = named_data->private_data; - set_named_trigger_data(data, named_data); - data->ops = &event_hist_trigger_named_ops; -@@ -5215,10 +5239,22 @@ static int hist_register_trigger(char *glob, struct event_trigger_ops *ops, - goto out; - } - -- ret++; -+ if (hist_data->enable_timestamps) { -+ char *clock = hist_data->attrs->clock; -+ -+ ret = tracing_set_clock(file->tr, hist_data->attrs->clock); -+ if (ret) { -+ hist_err("Couldn't set trace_clock: ", clock); -+ goto out; -+ } - -- if (hist_data->enable_timestamps) - tracing_set_time_stamp_abs(file->tr, true); -+ } -+ -+ if (named_data) -+ destroy_hist_data(hist_data); -+ -+ ret++; - out: - return ret; - } --- -2.19.2 - diff --git a/kernel/patches-4.14.x-rt/0112-ring-buffer-Bring-back-context-level-recursive-check.patch b/kernel/patches-4.14.x-rt/0112-ring-buffer-Bring-back-context-level-recursive-check.patch deleted file mode 100644 index 59ff98773..000000000 --- a/kernel/patches-4.14.x-rt/0112-ring-buffer-Bring-back-context-level-recursive-check.patch +++ /dev/null @@ -1,133 +0,0 @@ -From 93f30f296ca22bd9468ca86e1d0b2a8873adfaf2 Mon Sep 17 00:00:00 2001 -From: "Steven Rostedt (VMware)" -Date: Mon, 15 Jan 2018 10:47:09 -0500 -Subject: [PATCH 112/450] ring-buffer: Bring back context level recursive - checks - -Commit 1a149d7d3f45 ("ring-buffer: Rewrite trace_recursive_(un)lock() to be -simpler") replaced the context level recursion checks with a simple counter. -This would prevent the ring buffer code from recursively calling itself more -than the max number of contexts that exist (Normal, softirq, irq, nmi). But -this change caused a lockup in a specific case, which was during suspend and -resume using a global clock. Adding a stack dump to see where this occurred, -the issue was in the trace global clock itself: - - trace_buffer_lock_reserve+0x1c/0x50 - __trace_graph_entry+0x2d/0x90 - trace_graph_entry+0xe8/0x200 - prepare_ftrace_return+0x69/0xc0 - ftrace_graph_caller+0x78/0xa8 - queued_spin_lock_slowpath+0x5/0x1d0 - trace_clock_global+0xb0/0xc0 - ring_buffer_lock_reserve+0xf9/0x390 - -The function graph tracer traced queued_spin_lock_slowpath that was called -by trace_clock_global. This pointed out that the trace_clock_global() is not -reentrant, as it takes a spin lock. It depended on the ring buffer recursive -lock from letting that happen. - -By removing the context detection and adding just a max number of allowable -recursions, it allowed the trace_clock_global() to be entered again and try -to retake the spinlock it already held, causing a deadlock. - -Fixes: 1a149d7d3f45 ("ring-buffer: Rewrite trace_recursive_(un)lock() to be simpler") -Reported-by: David Weinehall -Signed-off-by: Steven Rostedt (VMware) -(cherry picked from commit a0e3a18f4baf8e3754ac1e56f0ade924d0c0c721) -Signed-off-by: Sebastian Andrzej Siewior ---- - kernel/trace/ring_buffer.c | 62 +++++++++++++++++++++++++++----------- - 1 file changed, 45 insertions(+), 17 deletions(-) - -diff --git a/kernel/trace/ring_buffer.c b/kernel/trace/ring_buffer.c -index 197617001c0b..b7cda4701ab3 100644 ---- a/kernel/trace/ring_buffer.c -+++ b/kernel/trace/ring_buffer.c -@@ -2590,29 +2590,59 @@ rb_wakeups(struct ring_buffer *buffer, struct ring_buffer_per_cpu *cpu_buffer) - * The lock and unlock are done within a preempt disable section. - * The current_context per_cpu variable can only be modified - * by the current task between lock and unlock. But it can -- * be modified more than once via an interrupt. There are four -- * different contexts that we need to consider. -+ * be modified more than once via an interrupt. To pass this -+ * information from the lock to the unlock without having to -+ * access the 'in_interrupt()' functions again (which do show -+ * a bit of overhead in something as critical as function tracing, -+ * we use a bitmask trick. - * -- * Normal context. -- * SoftIRQ context -- * IRQ context -- * NMI context -+ * bit 0 = NMI context -+ * bit 1 = IRQ context -+ * bit 2 = SoftIRQ context -+ * bit 3 = normal context. - * -- * If for some reason the ring buffer starts to recurse, we -- * only allow that to happen at most 4 times (one for each -- * context). If it happens 5 times, then we consider this a -- * recusive loop and do not let it go further. -+ * This works because this is the order of contexts that can -+ * preempt other contexts. A SoftIRQ never preempts an IRQ -+ * context. -+ * -+ * When the context is determined, the corresponding bit is -+ * checked and set (if it was set, then a recursion of that context -+ * happened). -+ * -+ * On unlock, we need to clear this bit. To do so, just subtract -+ * 1 from the current_context and AND it to itself. -+ * -+ * (binary) -+ * 101 - 1 = 100 -+ * 101 & 100 = 100 (clearing bit zero) -+ * -+ * 1010 - 1 = 1001 -+ * 1010 & 1001 = 1000 (clearing bit 1) -+ * -+ * The least significant bit can be cleared this way, and it -+ * just so happens that it is the same bit corresponding to -+ * the current context. - */ - - static __always_inline int - trace_recursive_lock(struct ring_buffer_per_cpu *cpu_buffer) - { -- if (cpu_buffer->current_context >= 4) -+ unsigned int val = cpu_buffer->current_context; -+ unsigned long pc = preempt_count(); -+ int bit; -+ -+ if (!(pc & (NMI_MASK | HARDIRQ_MASK | SOFTIRQ_OFFSET))) -+ bit = RB_CTX_NORMAL; -+ else -+ bit = pc & NMI_MASK ? RB_CTX_NMI : -+ pc & HARDIRQ_MASK ? RB_CTX_IRQ : -+ pc & SOFTIRQ_OFFSET ? 2 : RB_CTX_SOFTIRQ; -+ -+ if (unlikely(val & (1 << bit))) - return 1; - -- cpu_buffer->current_context++; -- /* Interrupts must see this update */ -- barrier(); -+ val |= (1 << bit); -+ cpu_buffer->current_context = val; - - return 0; - } -@@ -2620,9 +2650,7 @@ trace_recursive_lock(struct ring_buffer_per_cpu *cpu_buffer) - static __always_inline void - trace_recursive_unlock(struct ring_buffer_per_cpu *cpu_buffer) - { -- /* Don't let the dec leak out */ -- barrier(); -- cpu_buffer->current_context--; -+ cpu_buffer->current_context &= cpu_buffer->current_context - 1; - } - - /** --- -2.19.2 - diff --git a/kernel/patches-4.14.x-rt/0113-ring-buffer-Fix-duplicate-results-in-mapping-context.patch b/kernel/patches-4.14.x-rt/0113-ring-buffer-Fix-duplicate-results-in-mapping-context.patch deleted file mode 100644 index 9b53bddd9..000000000 --- a/kernel/patches-4.14.x-rt/0113-ring-buffer-Fix-duplicate-results-in-mapping-context.patch +++ /dev/null @@ -1,42 +0,0 @@ -From 158c7e6197471e64b5d8b70c580808803b5383c5 Mon Sep 17 00:00:00 2001 -From: "Steven Rostedt (VMware)" -Date: Thu, 18 Jan 2018 15:42:09 -0500 -Subject: [PATCH 113/450] ring-buffer: Fix duplicate results in mapping context - to bits in recursive lock - -In bringing back the context checks, the code checks first if its normal -(non-interrupt) context, and then for NMI then IRQ then softirq. The final -check is redundant. Since the if branch is only hit if the context is one of -NMI, IRQ, or SOFTIRQ, if it's not NMI or IRQ there's no reason to check if -it is SOFTIRQ. The current code returns the same result even if its not a -SOFTIRQ. Which is confusing. - - pc & SOFTIRQ_OFFSET ? 2 : RB_CTX_SOFTIRQ - -Is redundant as RB_CTX_SOFTIRQ *is* 2! - -Fixes: a0e3a18f4baf ("ring-buffer: Bring back context level recursive checks") -Signed-off-by: Steven Rostedt (VMware) -(cherry picked from commit 0164e0d7e803af3ee1c63770978c728f8778ad01) -Signed-off-by: Sebastian Andrzej Siewior ---- - kernel/trace/ring_buffer.c | 3 +-- - 1 file changed, 1 insertion(+), 2 deletions(-) - -diff --git a/kernel/trace/ring_buffer.c b/kernel/trace/ring_buffer.c -index b7cda4701ab3..be296c38893f 100644 ---- a/kernel/trace/ring_buffer.c -+++ b/kernel/trace/ring_buffer.c -@@ -2635,8 +2635,7 @@ trace_recursive_lock(struct ring_buffer_per_cpu *cpu_buffer) - bit = RB_CTX_NORMAL; - else - bit = pc & NMI_MASK ? RB_CTX_NMI : -- pc & HARDIRQ_MASK ? RB_CTX_IRQ : -- pc & SOFTIRQ_OFFSET ? 2 : RB_CTX_SOFTIRQ; -+ pc & HARDIRQ_MASK ? RB_CTX_IRQ : RB_CTX_SOFTIRQ; - - if (unlikely(val & (1 << bit))) - return 1; --- -2.19.2 - diff --git a/kernel/patches-4.14.x-rt/0114-ring-buffer-Add-nesting-for-adding-events-within-eve.patch b/kernel/patches-4.14.x-rt/0114-ring-buffer-Add-nesting-for-adding-events-within-eve.patch deleted file mode 100644 index a4f9c8598..000000000 --- a/kernel/patches-4.14.x-rt/0114-ring-buffer-Add-nesting-for-adding-events-within-eve.patch +++ /dev/null @@ -1,127 +0,0 @@ -From 55a309475692c9c88440298c8c02d9f4e9e581c6 Mon Sep 17 00:00:00 2001 -From: "Steven Rostedt (VMware)" -Date: Wed, 7 Feb 2018 17:26:32 -0500 -Subject: [PATCH 114/450] ring-buffer: Add nesting for adding events within - events - -The ring-buffer code has recusion protection in case tracing ends up tracing -itself, the ring-buffer will detect that it was called at the same context -(normal, softirq, interrupt or NMI), and not continue to record the event. - -With the histogram synthetic events, they are called while tracing another -event at the same context. The recusion protection triggers because it -detects tracing at the same context and stops it. - -Add ring_buffer_nest_start() and ring_buffer_nest_end() that will notify the -ring buffer that a trace is about to happen within another trace and that it -is intended, and not to trigger the recursion blocking. - -Signed-off-by: Steven Rostedt (VMware) -(cherry picked from commit f932ff1d98c482716b4b71a5d76b2aa3d65f66f0) -Signed-off-by: Sebastian Andrzej Siewior ---- - include/linux/ring_buffer.h | 3 ++ - kernel/trace/ring_buffer.c | 57 +++++++++++++++++++++++++++++++++++-- - 2 files changed, 57 insertions(+), 3 deletions(-) - -diff --git a/include/linux/ring_buffer.h b/include/linux/ring_buffer.h -index 6c2a6b3f3c6d..abce5f5325e1 100644 ---- a/include/linux/ring_buffer.h -+++ b/include/linux/ring_buffer.h -@@ -117,6 +117,9 @@ int ring_buffer_unlock_commit(struct ring_buffer *buffer, - int ring_buffer_write(struct ring_buffer *buffer, - unsigned long length, void *data); - -+void ring_buffer_nest_start(struct ring_buffer *buffer); -+void ring_buffer_nest_end(struct ring_buffer *buffer); -+ - struct ring_buffer_event * - ring_buffer_peek(struct ring_buffer *buffer, int cpu, u64 *ts, - unsigned long *lost_events); -diff --git a/kernel/trace/ring_buffer.c b/kernel/trace/ring_buffer.c -index be296c38893f..e8ca1e01facd 100644 ---- a/kernel/trace/ring_buffer.c -+++ b/kernel/trace/ring_buffer.c -@@ -477,6 +477,7 @@ struct ring_buffer_per_cpu { - struct buffer_page *reader_page; - unsigned long lost_events; - unsigned long last_overrun; -+ unsigned long nest; - local_t entries_bytes; - local_t entries; - local_t overrun; -@@ -2637,10 +2638,10 @@ trace_recursive_lock(struct ring_buffer_per_cpu *cpu_buffer) - bit = pc & NMI_MASK ? RB_CTX_NMI : - pc & HARDIRQ_MASK ? RB_CTX_IRQ : RB_CTX_SOFTIRQ; - -- if (unlikely(val & (1 << bit))) -+ if (unlikely(val & (1 << (bit + cpu_buffer->nest)))) - return 1; - -- val |= (1 << bit); -+ val |= (1 << (bit + cpu_buffer->nest)); - cpu_buffer->current_context = val; - - return 0; -@@ -2649,7 +2650,57 @@ trace_recursive_lock(struct ring_buffer_per_cpu *cpu_buffer) - static __always_inline void - trace_recursive_unlock(struct ring_buffer_per_cpu *cpu_buffer) - { -- cpu_buffer->current_context &= cpu_buffer->current_context - 1; -+ cpu_buffer->current_context &= -+ cpu_buffer->current_context - (1 << cpu_buffer->nest); -+} -+ -+/* The recursive locking above uses 4 bits */ -+#define NESTED_BITS 4 -+ -+/** -+ * ring_buffer_nest_start - Allow to trace while nested -+ * @buffer: The ring buffer to modify -+ * -+ * The ring buffer has a safty mechanism to prevent recursion. -+ * But there may be a case where a trace needs to be done while -+ * tracing something else. In this case, calling this function -+ * will allow this function to nest within a currently active -+ * ring_buffer_lock_reserve(). -+ * -+ * Call this function before calling another ring_buffer_lock_reserve() and -+ * call ring_buffer_nest_end() after the nested ring_buffer_unlock_commit(). -+ */ -+void ring_buffer_nest_start(struct ring_buffer *buffer) -+{ -+ struct ring_buffer_per_cpu *cpu_buffer; -+ int cpu; -+ -+ /* Enabled by ring_buffer_nest_end() */ -+ preempt_disable_notrace(); -+ cpu = raw_smp_processor_id(); -+ cpu_buffer = buffer->buffers[cpu]; -+ /* This is the shift value for the above recusive locking */ -+ cpu_buffer->nest += NESTED_BITS; -+} -+ -+/** -+ * ring_buffer_nest_end - Allow to trace while nested -+ * @buffer: The ring buffer to modify -+ * -+ * Must be called after ring_buffer_nest_start() and after the -+ * ring_buffer_unlock_commit(). -+ */ -+void ring_buffer_nest_end(struct ring_buffer *buffer) -+{ -+ struct ring_buffer_per_cpu *cpu_buffer; -+ int cpu; -+ -+ /* disabled by ring_buffer_nest_start() */ -+ cpu = raw_smp_processor_id(); -+ cpu_buffer = buffer->buffers[cpu]; -+ /* This is the shift value for the above recusive locking */ -+ cpu_buffer->nest -= NESTED_BITS; -+ preempt_enable_notrace(); - } - - /** --- -2.19.2 - diff --git a/kernel/patches-4.14.x-rt/0115-tracing-Use-the-ring-buffer-nesting-to-allow-synthet.patch b/kernel/patches-4.14.x-rt/0115-tracing-Use-the-ring-buffer-nesting-to-allow-synthet.patch deleted file mode 100644 index 8606d5f1c..000000000 --- a/kernel/patches-4.14.x-rt/0115-tracing-Use-the-ring-buffer-nesting-to-allow-synthet.patch +++ /dev/null @@ -1,60 +0,0 @@ -From cfbff455010bbddb3772e6d9cde753fb717c1ee6 Mon Sep 17 00:00:00 2001 -From: "Steven Rostedt (VMware)" -Date: Wed, 7 Feb 2018 17:29:46 -0500 -Subject: [PATCH 115/450] tracing: Use the ring-buffer nesting to allow - synthetic events to be traced - -Synthetic events can be done within the recording of other events. Notify -the ring buffer via ring_buffer_nest_start() and ring_buffer_nest_end() that -this is intended and not to block it due to its recursion protection. - -Signed-off-by: Steven Rostedt (VMware) -(cherry picked from commit 92c571543120ffed5e725f5b57b9de0b535e9d0a) -Signed-off-by: Sebastian Andrzej Siewior ---- - kernel/trace/trace_events_hist.c | 12 +++++++++++- - 1 file changed, 11 insertions(+), 1 deletion(-) - -diff --git a/kernel/trace/trace_events_hist.c b/kernel/trace/trace_events_hist.c -index e47b56632367..49afef3cc384 100644 ---- a/kernel/trace/trace_events_hist.c -+++ b/kernel/trace/trace_events_hist.c -@@ -640,6 +640,7 @@ static notrace void trace_event_raw_event_synth(void *__data, - struct trace_event_file *trace_file = __data; - struct synth_trace_event *entry; - struct trace_event_buffer fbuffer; -+ struct ring_buffer *buffer; - struct synth_event *event; - unsigned int i, n_u64; - int fields_size = 0; -@@ -651,10 +652,17 @@ static notrace void trace_event_raw_event_synth(void *__data, - - fields_size = event->n_u64 * sizeof(u64); - -+ /* -+ * Avoid ring buffer recursion detection, as this event -+ * is being performed within another event. -+ */ -+ buffer = trace_file->tr->trace_buffer.buffer; -+ ring_buffer_nest_start(buffer); -+ - entry = trace_event_buffer_reserve(&fbuffer, trace_file, - sizeof(*entry) + fields_size); - if (!entry) -- return; -+ goto out; - - for (i = 0, n_u64 = 0; i < event->n_fields; i++) { - if (event->fields[i]->is_string) { -@@ -670,6 +678,8 @@ static notrace void trace_event_raw_event_synth(void *__data, - } - - trace_event_buffer_commit(&fbuffer); -+out: -+ ring_buffer_nest_end(buffer); - } - - static void free_synth_event_print_fmt(struct trace_event_call *call) --- -2.19.2 - diff --git a/kernel/patches-4.14.x-rt/0116-tracing-Add-inter-event-blurb-to-HIST_TRIGGERS-confi.patch b/kernel/patches-4.14.x-rt/0116-tracing-Add-inter-event-blurb-to-HIST_TRIGGERS-confi.patch deleted file mode 100644 index a3e33e08f..000000000 --- a/kernel/patches-4.14.x-rt/0116-tracing-Add-inter-event-blurb-to-HIST_TRIGGERS-confi.patch +++ /dev/null @@ -1,39 +0,0 @@ -From ba8152928d50e4c2a175f81f2035f5f79e05c1ab Mon Sep 17 00:00:00 2001 -From: Tom Zanussi -Date: Mon, 15 Jan 2018 20:52:10 -0600 -Subject: [PATCH 116/450] tracing: Add inter-event blurb to HIST_TRIGGERS - config option - -So that users know that inter-event tracing is supported as part of -the HIST_TRIGGERS option, include text to that effect in the help -text. - -Link: http://lkml.kernel.org/r/a38e24231d8d980be636b56d35814570acfd167a.1516069914.git.tom.zanussi@linux.intel.com - -Signed-off-by: Tom Zanussi -Signed-off-by: Steven Rostedt (VMware) -(cherry picked from commit 02942764c4fd12caeb29868822b7744fa91a9ad0) -Signed-off-by: Sebastian Andrzej Siewior ---- - kernel/trace/Kconfig | 5 ++++- - 1 file changed, 4 insertions(+), 1 deletion(-) - -diff --git a/kernel/trace/Kconfig b/kernel/trace/Kconfig -index 4ad6f6ca18c1..55d39a3fbdf7 100644 ---- a/kernel/trace/Kconfig -+++ b/kernel/trace/Kconfig -@@ -585,7 +585,10 @@ config HIST_TRIGGERS - event activity as an initial guide for further investigation - using more advanced tools. - -- See Documentation/trace/events.txt. -+ Inter-event tracing of quantities such as latencies is also -+ supported using hist triggers under this option. -+ -+ See Documentation/trace/histogram.txt. - If in doubt, say N. - - config MMIOTRACE_TEST --- -2.19.2 - diff --git a/kernel/patches-4.14.x-rt/0117-selftests-ftrace-Add-inter-event-hist-triggers-testc.patch b/kernel/patches-4.14.x-rt/0117-selftests-ftrace-Add-inter-event-hist-triggers-testc.patch deleted file mode 100644 index 02e9c1a6d..000000000 --- a/kernel/patches-4.14.x-rt/0117-selftests-ftrace-Add-inter-event-hist-triggers-testc.patch +++ /dev/null @@ -1,469 +0,0 @@ -From aa0c1808950ef2ac45c2653ca1180f828570980e Mon Sep 17 00:00:00 2001 -From: Rajvi Jingar -Date: Mon, 15 Jan 2018 20:52:11 -0600 -Subject: [PATCH 117/450] selftests: ftrace: Add inter-event hist triggers - testcases - - This adds inter-event hist triggers testcases which covers following: - - create/remove synthetic event - - disable histogram for synthetic event - - extended error support - - field variable support - - histogram variables - - histogram trigger onmatch action - - histogram trigger onmax action - - histogram trigger onmatch-onmax action - - simple expression support - - combined histogram - - Here is the test result. - === Ftrace unit tests === - [1] event trigger - test extended error support [PASS] - [2] event trigger - test field variable support [PASS] - [3] event trigger - test inter-event combined histogram trigger [PASS] - [4] event trigger - test inter-event histogram trigger onmatch action [PASS] - [5] event trigger - test inter-event histogram trigger onmatch-onmax action [PASS] - [6] event trigger - test inter-event histogram trigger onmax action [PASS] - [7] event trigger - test synthetic event create remove [PASS] - -Link: http://lkml.kernel.org/r/e07ef1e72f7bf0f84dc87c9b736d6dc91b4b0b49.1516069914.git.tom.zanussi@linux.intel.com - -Signed-off-by: Rajvi Jingar -Signed-off-by: Tom Zanussi -Signed-off-by: Steven Rostedt (VMware) -(cherry picked from commit fb08b656dc9caee4a097bc4d8e050e2ead59bc24) -Signed-off-by: Sebastian Andrzej Siewior ---- - .../testing/selftests/ftrace/test.d/functions | 7 +++ - .../trigger-extended-error-support.tc | 39 +++++++++++++ - .../trigger-field-variable-support.tc | 54 +++++++++++++++++ - .../trigger-inter-event-combined-hist.tc | 58 +++++++++++++++++++ - .../trigger-onmatch-action-hist.tc | 50 ++++++++++++++++ - .../trigger-onmatch-onmax-action-hist.tc | 50 ++++++++++++++++ - .../inter-event/trigger-onmax-action-hist.tc | 48 +++++++++++++++ - .../trigger-synthetic-event-createremove.tc | 54 +++++++++++++++++ - 8 files changed, 360 insertions(+) - create mode 100644 tools/testing/selftests/ftrace/test.d/trigger/inter-event/trigger-extended-error-support.tc - create mode 100644 tools/testing/selftests/ftrace/test.d/trigger/inter-event/trigger-field-variable-support.tc - create mode 100644 tools/testing/selftests/ftrace/test.d/trigger/inter-event/trigger-inter-event-combined-hist.tc - create mode 100644 tools/testing/selftests/ftrace/test.d/trigger/inter-event/trigger-onmatch-action-hist.tc - create mode 100644 tools/testing/selftests/ftrace/test.d/trigger/inter-event/trigger-onmatch-onmax-action-hist.tc - create mode 100644 tools/testing/selftests/ftrace/test.d/trigger/inter-event/trigger-onmax-action-hist.tc - create mode 100644 tools/testing/selftests/ftrace/test.d/trigger/inter-event/trigger-synthetic-event-createremove.tc - -diff --git a/tools/testing/selftests/ftrace/test.d/functions b/tools/testing/selftests/ftrace/test.d/functions -index 6a4982d029bf..843c2b0d948e 100644 ---- a/tools/testing/selftests/ftrace/test.d/functions -+++ b/tools/testing/selftests/ftrace/test.d/functions -@@ -70,6 +70,13 @@ disable_events() { - echo 0 > events/enable - } - -+clear_synthetic_events() { # reset all current synthetic events -+ grep -v ^# synthetic_events | -+ while read line; do -+ echo "!$line" >> synthetic_events -+ done -+} -+ - initialize_ftrace() { # Reset ftrace to initial-state - # As the initial state, ftrace will be set to nop tracer, - # no events, no triggers, no filters, no function filters, -diff --git a/tools/testing/selftests/ftrace/test.d/trigger/inter-event/trigger-extended-error-support.tc b/tools/testing/selftests/ftrace/test.d/trigger/inter-event/trigger-extended-error-support.tc -new file mode 100644 -index 000000000000..786dce7e48be ---- /dev/null -+++ b/tools/testing/selftests/ftrace/test.d/trigger/inter-event/trigger-extended-error-support.tc -@@ -0,0 +1,39 @@ -+#!/bin/sh -+# description: event trigger - test extended error support -+ -+ -+do_reset() { -+ reset_trigger -+ echo > set_event -+ clear_trace -+} -+ -+fail() { #msg -+ do_reset -+ echo $1 -+ exit_fail -+} -+ -+if [ ! -f set_event ]; then -+ echo "event tracing is not supported" -+ exit_unsupported -+fi -+ -+if [ ! -f synthetic_events ]; then -+ echo "synthetic event is not supported" -+ exit_unsupported -+fi -+ -+reset_tracer -+do_reset -+ -+echo "Test extended error support" -+echo 'hist:keys=pid:ts0=common_timestamp.usecs if comm=="ping"' > events/sched/sched_wakeup/trigger -+echo 'hist:keys=pid:ts0=common_timestamp.usecs if comm=="ping"' >> events/sched/sched_wakeup/trigger &>/dev/null -+if ! grep -q "ERROR:" events/sched/sched_wakeup/hist; then -+ fail "Failed to generate extended error in histogram" -+fi -+ -+do_reset -+ -+exit 0 -diff --git a/tools/testing/selftests/ftrace/test.d/trigger/inter-event/trigger-field-variable-support.tc b/tools/testing/selftests/ftrace/test.d/trigger/inter-event/trigger-field-variable-support.tc -new file mode 100644 -index 000000000000..7fd5b4a8f060 ---- /dev/null -+++ b/tools/testing/selftests/ftrace/test.d/trigger/inter-event/trigger-field-variable-support.tc -@@ -0,0 +1,54 @@ -+#!/bin/sh -+# description: event trigger - test field variable support -+ -+do_reset() { -+ reset_trigger -+ echo > set_event -+ clear_trace -+} -+ -+fail() { #msg -+ do_reset -+ echo $1 -+ exit_fail -+} -+ -+if [ ! -f set_event ]; then -+ echo "event tracing is not supported" -+ exit_unsupported -+fi -+ -+if [ ! -f synthetic_events ]; then -+ echo "synthetic event is not supported" -+ exit_unsupported -+fi -+ -+clear_synthetic_events -+reset_tracer -+do_reset -+ -+echo "Test field variable support" -+ -+echo 'wakeup_latency u64 lat; pid_t pid; int prio; char comm[16]' > synthetic_events -+echo 'hist:keys=comm:ts0=common_timestamp.usecs if comm=="ping"' > events/sched/sched_waking/trigger -+echo 'hist:keys=next_comm:wakeup_lat=common_timestamp.usecs-$ts0:onmatch(sched.sched_waking).wakeup_latency($wakeup_lat,next_pid,sched.sched_waking.prio,next_comm) if next_comm=="ping"' > events/sched/sched_switch/trigger -+echo 'hist:keys=pid,prio,comm:vals=lat:sort=pid,prio' > events/synthetic/wakeup_latency/trigger -+ -+ping localhost -c 3 -+if ! grep -q "ping" events/synthetic/wakeup_latency/hist; then -+ fail "Failed to create inter-event histogram" -+fi -+ -+if ! grep -q "synthetic_prio=prio" events/sched/sched_waking/hist; then -+ fail "Failed to create histogram with field variable" -+fi -+ -+echo '!hist:keys=next_comm:wakeup_lat=common_timestamp.usecs-$ts0:onmatch(sched.sched_waking).wakeup_latency($wakeup_lat,next_pid,sched.sched_waking.prio,next_comm) if next_comm=="ping"' >> events/sched/sched_switch/trigger -+ -+if grep -q "synthetic_prio=prio" events/sched/sched_waking/hist; then -+ fail "Failed to remove histogram with field variable" -+fi -+ -+do_reset -+ -+exit 0 -diff --git a/tools/testing/selftests/ftrace/test.d/trigger/inter-event/trigger-inter-event-combined-hist.tc b/tools/testing/selftests/ftrace/test.d/trigger/inter-event/trigger-inter-event-combined-hist.tc -new file mode 100644 -index 000000000000..c93dbe38b5df ---- /dev/null -+++ b/tools/testing/selftests/ftrace/test.d/trigger/inter-event/trigger-inter-event-combined-hist.tc -@@ -0,0 +1,58 @@ -+#!/bin/sh -+# description: event trigger - test inter-event combined histogram trigger -+ -+do_reset() { -+ reset_trigger -+ echo > set_event -+ clear_trace -+} -+ -+fail() { #msg -+ do_reset -+ echo $1 -+ exit_fail -+} -+ -+if [ ! -f set_event ]; then -+ echo "event tracing is not supported" -+ exit_unsupported -+fi -+ -+if [ ! -f synthetic_events ]; then -+ echo "synthetic event is not supported" -+ exit_unsupported -+fi -+ -+reset_tracer -+do_reset -+clear_synthetic_events -+ -+echo "Test create synthetic event" -+ -+echo 'waking_latency u64 lat pid_t pid' > synthetic_events -+if [ ! -d events/synthetic/waking_latency ]; then -+ fail "Failed to create waking_latency synthetic event" -+fi -+ -+echo "Test combined histogram" -+ -+echo 'hist:keys=pid:ts0=common_timestamp.usecs if comm=="ping"' > events/sched/sched_waking/trigger -+echo 'hist:keys=pid:waking_lat=common_timestamp.usecs-$ts0:onmatch(sched.sched_waking).waking_latency($waking_lat,pid) if comm=="ping"' > events/sched/sched_wakeup/trigger -+echo 'hist:keys=pid,lat:sort=pid,lat' > events/synthetic/waking_latency/trigger -+ -+echo 'wakeup_latency u64 lat pid_t pid' >> synthetic_events -+echo 'hist:keys=pid:ts1=common_timestamp.usecs if comm=="ping"' >> events/sched/sched_wakeup/trigger -+echo 'hist:keys=next_pid:wakeup_lat=common_timestamp.usecs-$ts1:onmatch(sched.sched_wakeup).wakeup_latency($wakeup_lat,next_pid) if next_comm=="ping"' > events/sched/sched_switch/trigger -+ -+echo 'waking+wakeup_latency u64 lat; pid_t pid' >> synthetic_events -+echo 'hist:keys=pid,lat:sort=pid,lat:ww_lat=$waking_lat+$wakeup_lat:onmatch(synthetic.wakeup_latency).waking+wakeup_latency($ww_lat,pid)' >> events/synthetic/wakeup_latency/trigger -+echo 'hist:keys=pid,lat:sort=pid,lat' >> events/synthetic/waking+wakeup_latency/trigger -+ -+ping localhost -c 3 -+if ! grep -q "pid:" events/synthetic/waking+wakeup_latency/hist; then -+ fail "Failed to create combined histogram" -+fi -+ -+do_reset -+ -+exit 0 -diff --git a/tools/testing/selftests/ftrace/test.d/trigger/inter-event/trigger-onmatch-action-hist.tc b/tools/testing/selftests/ftrace/test.d/trigger/inter-event/trigger-onmatch-action-hist.tc -new file mode 100644 -index 000000000000..e84e7d048566 ---- /dev/null -+++ b/tools/testing/selftests/ftrace/test.d/trigger/inter-event/trigger-onmatch-action-hist.tc -@@ -0,0 +1,50 @@ -+#!/bin/sh -+# description: event trigger - test inter-event histogram trigger onmatch action -+ -+do_reset() { -+ reset_trigger -+ echo > set_event -+ clear_trace -+} -+ -+fail() { #msg -+ do_reset -+ echo $1 -+ exit_fail -+} -+ -+if [ ! -f set_event ]; then -+ echo "event tracing is not supported" -+ exit_unsupported -+fi -+ -+if [ ! -f synthetic_events ]; then -+ echo "synthetic event is not supported" -+ exit_unsupported -+fi -+ -+clear_synthetic_events -+reset_tracer -+do_reset -+ -+echo "Test create synthetic event" -+ -+echo 'wakeup_latency u64 lat pid_t pid char comm[16]' > synthetic_events -+if [ ! -d events/synthetic/wakeup_latency ]; then -+ fail "Failed to create wakeup_latency synthetic event" -+fi -+ -+echo "Test create histogram for synthetic event" -+echo "Test histogram variables,simple expression support and onmatch action" -+ -+echo 'hist:keys=pid:ts0=common_timestamp.usecs if comm=="ping"' > events/sched/sched_wakeup/trigger -+echo 'hist:keys=next_pid:wakeup_lat=common_timestamp.usecs-$ts0:onmatch(sched.sched_wakeup).wakeup_latency($wakeup_lat,next_pid,next_comm) if next_comm=="ping"' > events/sched/sched_switch/trigger -+echo 'hist:keys=comm,pid,lat:wakeup_lat=lat:sort=lat' > events/synthetic/wakeup_latency/trigger -+ping localhost -c 5 -+if ! grep -q "ping" events/synthetic/wakeup_latency/hist; then -+ fail "Failed to create onmatch action inter-event histogram" -+fi -+ -+do_reset -+ -+exit 0 -diff --git a/tools/testing/selftests/ftrace/test.d/trigger/inter-event/trigger-onmatch-onmax-action-hist.tc b/tools/testing/selftests/ftrace/test.d/trigger/inter-event/trigger-onmatch-onmax-action-hist.tc -new file mode 100644 -index 000000000000..7907d8aacde3 ---- /dev/null -+++ b/tools/testing/selftests/ftrace/test.d/trigger/inter-event/trigger-onmatch-onmax-action-hist.tc -@@ -0,0 +1,50 @@ -+#!/bin/sh -+# description: event trigger - test inter-event histogram trigger onmatch-onmax action -+ -+do_reset() { -+ reset_trigger -+ echo > set_event -+ clear_trace -+} -+ -+fail() { #msg -+ do_reset -+ echo $1 -+ exit_fail -+} -+ -+if [ ! -f set_event ]; then -+ echo "event tracing is not supported" -+ exit_unsupported -+fi -+ -+if [ ! -f synthetic_events ]; then -+ echo "synthetic event is not supported" -+ exit_unsupported -+fi -+ -+clear_synthetic_events -+reset_tracer -+do_reset -+ -+echo "Test create synthetic event" -+ -+echo 'wakeup_latency u64 lat pid_t pid char comm[16]' > synthetic_events -+if [ ! -d events/synthetic/wakeup_latency ]; then -+ fail "Failed to create wakeup_latency synthetic event" -+fi -+ -+echo "Test create histogram for synthetic event" -+echo "Test histogram variables,simple expression support and onmatch-onmax action" -+ -+echo 'hist:keys=pid:ts0=common_timestamp.usecs if comm=="ping"' > events/sched/sched_wakeup/trigger -+echo 'hist:keys=next_pid:wakeup_lat=common_timestamp.usecs-$ts0:onmatch(sched.sched_wakeup).wakeup_latency($wakeup_lat,next_pid,next_comm):onmax($wakeup_lat).save(next_comm,prev_pid,prev_prio,prev_comm) if next_comm=="ping"' >> events/sched/sched_switch/trigger -+echo 'hist:keys=comm,pid,lat:wakeup_lat=lat:sort=lat' > events/synthetic/wakeup_latency/trigger -+ping localhost -c 5 -+if [ ! grep -q "ping" events/synthetic/wakeup_latency/hist -o ! grep -q "max:" events/sched/sched_switch/hist]; then -+ fail "Failed to create onmatch-onmax action inter-event histogram" -+fi -+ -+do_reset -+ -+exit 0 -diff --git a/tools/testing/selftests/ftrace/test.d/trigger/inter-event/trigger-onmax-action-hist.tc b/tools/testing/selftests/ftrace/test.d/trigger/inter-event/trigger-onmax-action-hist.tc -new file mode 100644 -index 000000000000..38b7ed6242b2 ---- /dev/null -+++ b/tools/testing/selftests/ftrace/test.d/trigger/inter-event/trigger-onmax-action-hist.tc -@@ -0,0 +1,48 @@ -+#!/bin/sh -+# description: event trigger - test inter-event histogram trigger onmax action -+ -+do_reset() { -+ reset_trigger -+ echo > set_event -+ clear_trace -+} -+ -+fail() { #msg -+ do_reset -+ echo $1 -+ exit_fail -+} -+ -+if [ ! -f set_event ]; then -+ echo "event tracing is not supported" -+ exit_unsupported -+fi -+ -+if [ ! -f synthetic_events ]; then -+ echo "synthetic event is not supported" -+ exit_unsupported -+fi -+ -+clear_synthetic_events -+reset_tracer -+do_reset -+ -+echo "Test create synthetic event" -+ -+echo 'wakeup_latency u64 lat pid_t pid char comm[16]' > synthetic_events -+if [ ! -d events/synthetic/wakeup_latency ]; then -+ fail "Failed to create wakeup_latency synthetic event" -+fi -+ -+echo "Test onmax action" -+ -+echo 'hist:keys=pid:ts0=common_timestamp.usecs if comm=="ping"' >> events/sched/sched_waking/trigger -+echo 'hist:keys=next_pid:wakeup_lat=common_timestamp.usecs-$ts0:onmax($wakeup_lat).save(next_comm,prev_pid,prev_prio,prev_comm) if next_comm=="ping"' >> events/sched/sched_switch/trigger -+ping localhost -c 3 -+if ! grep -q "max:" events/sched/sched_switch/hist; then -+ fail "Failed to create onmax action inter-event histogram" -+fi -+ -+do_reset -+ -+exit 0 -diff --git a/tools/testing/selftests/ftrace/test.d/trigger/inter-event/trigger-synthetic-event-createremove.tc b/tools/testing/selftests/ftrace/test.d/trigger/inter-event/trigger-synthetic-event-createremove.tc -new file mode 100644 -index 000000000000..cef11377dcbd ---- /dev/null -+++ b/tools/testing/selftests/ftrace/test.d/trigger/inter-event/trigger-synthetic-event-createremove.tc -@@ -0,0 +1,54 @@ -+#!/bin/sh -+# description: event trigger - test synthetic event create remove -+do_reset() { -+ reset_trigger -+ echo > set_event -+ clear_trace -+} -+ -+fail() { #msg -+ do_reset -+ echo $1 -+ exit_fail -+} -+ -+if [ ! -f set_event ]; then -+ echo "event tracing is not supported" -+ exit_unsupported -+fi -+ -+if [ ! -f synthetic_events ]; then -+ echo "synthetic event is not supported" -+ exit_unsupported -+fi -+ -+clear_synthetic_events -+reset_tracer -+do_reset -+ -+echo "Test create synthetic event" -+ -+echo 'wakeup_latency u64 lat pid_t pid char comm[16]' > synthetic_events -+if [ ! -d events/synthetic/wakeup_latency ]; then -+ fail "Failed to create wakeup_latency synthetic event" -+fi -+ -+reset_trigger -+ -+echo "Test create synthetic event with an error" -+echo 'wakeup_latency u64 lat pid_t pid char' > synthetic_events > /dev/null -+if [ -d events/synthetic/wakeup_latency ]; then -+ fail "Created wakeup_latency synthetic event with an invalid format" -+fi -+ -+reset_trigger -+ -+echo "Test remove synthetic event" -+echo '!wakeup_latency u64 lat pid_t pid char comm[16]' > synthetic_events -+if [ -d events/synthetic/wakeup_latency ]; then -+ fail "Failed to delete wakeup_latency synthetic event" -+fi -+ -+do_reset -+ -+exit 0 --- -2.19.2 - diff --git a/kernel/patches-4.14.x-rt/0118-tracing-Fix-display-of-hist-trigger-expressions-cont.patch b/kernel/patches-4.14.x-rt/0118-tracing-Fix-display-of-hist-trigger-expressions-cont.patch deleted file mode 100644 index 5e225d188..000000000 --- a/kernel/patches-4.14.x-rt/0118-tracing-Fix-display-of-hist-trigger-expressions-cont.patch +++ /dev/null @@ -1,82 +0,0 @@ -From 85830476840c2e6ebbba8fe775453ab912e28934 Mon Sep 17 00:00:00 2001 -From: Tom Zanussi -Date: Wed, 28 Mar 2018 15:10:53 -0500 -Subject: [PATCH 118/450] tracing: Fix display of hist trigger expressions - containing timestamps - -When displaying hist triggers, variable references that have the -timestamp field flag set are erroneously displayed as common_timestamp -rather than the variable reference. Additionally, timestamp -expressions are displayed in the same way. Fix this by forcing the -timestamp flag handling to follow variable reference and expression -handling. - -Before: - - # cat /sys/kernel/debug/tracing/events/sched/sched_switch/trigger - hist:keys=next_pid:vals=hitcount:wakeup_lat=common_timestamp.usecs:... - -After: - - # cat /sys/kernel/debug/tracing/events/sched/sched_switch/trigger - hist:keys=next_pid:vals=hitcount:wakeup_lat=common_timestamp.usecs-$ts0.usecs:... - -Signed-off-by: Tom Zanussi -Signed-off-by: Sebastian Andrzej Siewior ---- - kernel/trace/trace_events_hist.c | 19 +++++-------------- - 1 file changed, 5 insertions(+), 14 deletions(-) - -diff --git a/kernel/trace/trace_events_hist.c b/kernel/trace/trace_events_hist.c -index 49afef3cc384..85b032a04b29 100644 ---- a/kernel/trace/trace_events_hist.c -+++ b/kernel/trace/trace_events_hist.c -@@ -1686,8 +1686,6 @@ static const char *hist_field_name(struct hist_field *field, - else if (field->flags & HIST_FIELD_FL_LOG2 || - field->flags & HIST_FIELD_FL_ALIAS) - field_name = hist_field_name(field->operands[0], ++level); -- else if (field->flags & HIST_FIELD_FL_TIMESTAMP) -- field_name = "common_timestamp"; - else if (field->flags & HIST_FIELD_FL_CPU) - field_name = "cpu"; - else if (field->flags & HIST_FIELD_FL_EXPR || -@@ -1703,7 +1701,8 @@ static const char *hist_field_name(struct hist_field *field, - field_name = full_name; - } else - field_name = field->name; -- } -+ } else if (field->flags & HIST_FIELD_FL_TIMESTAMP) -+ field_name = "common_timestamp"; - - if (field_name == NULL) - field_name = ""; -@@ -4859,23 +4858,15 @@ static void hist_field_print(struct seq_file *m, struct hist_field *hist_field) - if (hist_field->var.name) - seq_printf(m, "%s=", hist_field->var.name); - -- if (hist_field->flags & HIST_FIELD_FL_TIMESTAMP) -- seq_puts(m, "common_timestamp"); -- else if (hist_field->flags & HIST_FIELD_FL_CPU) -+ if (hist_field->flags & HIST_FIELD_FL_CPU) - seq_puts(m, "cpu"); - else if (field_name) { - if (hist_field->flags & HIST_FIELD_FL_VAR_REF || - hist_field->flags & HIST_FIELD_FL_ALIAS) - seq_putc(m, '$'); - seq_printf(m, "%s", field_name); -- } -- -- if (hist_field->flags) { -- const char *flags_str = get_hist_field_flags(hist_field); -- -- if (flags_str) -- seq_printf(m, ".%s", flags_str); -- } -+ } else if (hist_field->flags & HIST_FIELD_FL_TIMESTAMP) -+ seq_puts(m, "common_timestamp"); - } - - static int event_hist_trigger_print(struct seq_file *m, --- -2.19.2 - diff --git a/kernel/patches-4.14.x-rt/0119-tracing-Don-t-add-flag-strings-when-displaying-varia.patch b/kernel/patches-4.14.x-rt/0119-tracing-Don-t-add-flag-strings-when-displaying-varia.patch deleted file mode 100644 index 2ecfec722..000000000 --- a/kernel/patches-4.14.x-rt/0119-tracing-Don-t-add-flag-strings-when-displaying-varia.patch +++ /dev/null @@ -1,40 +0,0 @@ -From 97e2b4fc323a7076160c1930e2f5a35022ca3724 Mon Sep 17 00:00:00 2001 -From: Tom Zanussi -Date: Wed, 28 Mar 2018 15:10:54 -0500 -Subject: [PATCH 119/450] tracing: Don't add flag strings when displaying - variable references - -Variable references should never have flags appended when displayed - -prevent that from happening. - -Before: - - # cat /sys/kernel/debug/tracing/events/sched/sched_switch/trigger - hist:keys=next_pid:vals=hitcount:wakeup_lat=common_timestamp.usecs-$ts0.usecs:... - -After: - - hist:keys=next_pid:vals=hitcount:wakeup_lat=common_timestamp.usecs-$ts0:... - -Signed-off-by: Tom Zanussi -Signed-off-by: Sebastian Andrzej Siewior ---- - kernel/trace/trace_events_hist.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/kernel/trace/trace_events_hist.c b/kernel/trace/trace_events_hist.c -index 85b032a04b29..9def33acb5eb 100644 ---- a/kernel/trace/trace_events_hist.c -+++ b/kernel/trace/trace_events_hist.c -@@ -2052,7 +2052,7 @@ static void expr_field_str(struct hist_field *field, char *expr) - - strcat(expr, hist_field_name(field, 0)); - -- if (field->flags) { -+ if (field->flags && !(field->flags & HIST_FIELD_FL_VAR_REF)) { - const char *flags_str = get_hist_field_flags(field); - - if (flags_str) { --- -2.19.2 - diff --git a/kernel/patches-4.14.x-rt/0120-tracing-Add-action-comparisons-when-testing-matching.patch b/kernel/patches-4.14.x-rt/0120-tracing-Add-action-comparisons-when-testing-matching.patch deleted file mode 100644 index 637255555..000000000 --- a/kernel/patches-4.14.x-rt/0120-tracing-Add-action-comparisons-when-testing-matching.patch +++ /dev/null @@ -1,90 +0,0 @@ -From e81731c6c75b86e46ce4ce026bcf274583814ef2 Mon Sep 17 00:00:00 2001 -From: Tom Zanussi -Date: Wed, 28 Mar 2018 15:10:55 -0500 -Subject: [PATCH 120/450] tracing: Add action comparisons when testing matching - hist triggers - -Actions also need to be considered when checking for matching triggers -- triggers differing only by action should be allowed, but currently -aren't because the matching check ignores the action and erroneously -returns -EEXIST. - -Add and call an actions_match() function to address that. - -Signed-off-by: Tom Zanussi -Signed-off-by: Sebastian Andrzej Siewior ---- - kernel/trace/trace_events_hist.c | 50 ++++++++++++++++++++++++++++++++ - 1 file changed, 50 insertions(+) - -diff --git a/kernel/trace/trace_events_hist.c b/kernel/trace/trace_events_hist.c -index 9def33acb5eb..514ec0b31eed 100644 ---- a/kernel/trace/trace_events_hist.c -+++ b/kernel/trace/trace_events_hist.c -@@ -4363,6 +4363,53 @@ static void print_onmatch_spec(struct seq_file *m, - seq_puts(m, ")"); - } - -+static bool actions_match(struct hist_trigger_data *hist_data, -+ struct hist_trigger_data *hist_data_test) -+{ -+ unsigned int i, j; -+ -+ if (hist_data->n_actions != hist_data_test->n_actions) -+ return false; -+ -+ for (i = 0; i < hist_data->n_actions; i++) { -+ struct action_data *data = hist_data->actions[i]; -+ struct action_data *data_test = hist_data_test->actions[i]; -+ -+ if (data->fn != data_test->fn) -+ return false; -+ -+ if (data->n_params != data_test->n_params) -+ return false; -+ -+ for (j = 0; j < data->n_params; j++) { -+ if (strcmp(data->params[j], data_test->params[j]) != 0) -+ return false; -+ } -+ -+ if (data->fn == action_trace) { -+ if (strcmp(data->onmatch.synth_event_name, -+ data_test->onmatch.synth_event_name) != 0) -+ return false; -+ if (strcmp(data->onmatch.match_event_system, -+ data_test->onmatch.match_event_system) != 0) -+ return false; -+ if (strcmp(data->onmatch.match_event, -+ data_test->onmatch.match_event) != 0) -+ return false; -+ } else if (data->fn == onmax_save) { -+ if (strcmp(data->onmax.var_str, -+ data_test->onmax.var_str) != 0) -+ return false; -+ if (strcmp(data->onmax.fn_name, -+ data_test->onmax.fn_name) != 0) -+ return false; -+ } -+ } -+ -+ return true; -+} -+ -+ - static void print_actions_spec(struct seq_file *m, - struct hist_trigger_data *hist_data) - { -@@ -5175,6 +5222,9 @@ static bool hist_trigger_match(struct event_trigger_data *data, - (strcmp(data->filter_str, data_test->filter_str) != 0)) - return false; - -+ if (!actions_match(hist_data, hist_data_test)) -+ return false; -+ - return true; - } - --- -2.19.2 - diff --git a/kernel/patches-4.14.x-rt/0121-tracing-Make-sure-variable-string-fields-are-NULL-te.patch b/kernel/patches-4.14.x-rt/0121-tracing-Make-sure-variable-string-fields-are-NULL-te.patch deleted file mode 100644 index fdb384272..000000000 --- a/kernel/patches-4.14.x-rt/0121-tracing-Make-sure-variable-string-fields-are-NULL-te.patch +++ /dev/null @@ -1,42 +0,0 @@ -From 9ced88cdeba23ed45c15816a15c57b08b0fecdc4 Mon Sep 17 00:00:00 2001 -From: Tom Zanussi -Date: Wed, 28 Mar 2018 15:10:56 -0500 -Subject: [PATCH 121/450] tracing: Make sure variable string fields are - NULL-terminated - -The strncpy() currently being used for variable string fields can -result in a lack of termination if the string length is equal to the -field size. Use the safer strscpy() instead, which will guarantee -termination. - -Signed-off-by: Tom Zanussi -Signed-off-by: Sebastian Andrzej Siewior ---- - kernel/trace/trace_events_hist.c | 4 ++-- - 1 file changed, 2 insertions(+), 2 deletions(-) - -diff --git a/kernel/trace/trace_events_hist.c b/kernel/trace/trace_events_hist.c -index 514ec0b31eed..37db86145c8b 100644 ---- a/kernel/trace/trace_events_hist.c -+++ b/kernel/trace/trace_events_hist.c -@@ -669,7 +669,7 @@ static notrace void trace_event_raw_event_synth(void *__data, - char *str_val = (char *)(long)var_ref_vals[var_ref_idx + i]; - char *str_field = (char *)&entry->fields[n_u64]; - -- strncpy(str_field, str_val, STR_VAR_LEN_MAX); -+ strscpy(str_field, str_val, STR_VAR_LEN_MAX); - n_u64 += STR_VAR_LEN_MAX / sizeof(u64); - } else { - entry->fields[n_u64] = var_ref_vals[var_ref_idx + i]; -@@ -3090,7 +3090,7 @@ static inline void __update_field_vars(struct tracing_map_elt *elt, - char *str = elt_data->field_var_str[j++]; - char *val_str = (char *)(uintptr_t)var_val; - -- strncpy(str, val_str, STR_VAR_LEN_MAX); -+ strscpy(str, val_str, STR_VAR_LEN_MAX); - var_val = (u64)(uintptr_t)str; - } - tracing_map_set_var(elt, var_idx, var_val); --- -2.19.2 - diff --git a/kernel/patches-4.14.x-rt/0122-block-Shorten-interrupt-disabled-regions.patch b/kernel/patches-4.14.x-rt/0122-block-Shorten-interrupt-disabled-regions.patch deleted file mode 100644 index 12a76659b..000000000 --- a/kernel/patches-4.14.x-rt/0122-block-Shorten-interrupt-disabled-regions.patch +++ /dev/null @@ -1,102 +0,0 @@ -From e8b31720561427506149812db62e949b6ca5e332 Mon Sep 17 00:00:00 2001 -From: Thomas Gleixner -Date: Wed, 22 Jun 2011 19:47:02 +0200 -Subject: [PATCH 122/450] block: Shorten interrupt disabled regions - -Moving the blk_sched_flush_plug() call out of the interrupt/preempt -disabled region in the scheduler allows us to replace -local_irq_save/restore(flags) by local_irq_disable/enable() in -blk_flush_plug(). - -Now instead of doing this we disable interrupts explicitely when we -lock the request_queue and reenable them when we drop the lock. That -allows interrupts to be handled when the plug list contains requests -for more than one queue. - -Aside of that this change makes the scope of the irq disabled region -more obvious. The current code confused the hell out of me when -looking at: - - local_irq_save(flags); - spin_lock(q->queue_lock); - ... - queue_unplugged(q...); - scsi_request_fn(); - spin_unlock(q->queue_lock); - spin_lock(shost->host_lock); - spin_unlock_irq(shost->host_lock); - --------------------^^^ ???? - - spin_lock_irq(q->queue_lock); - spin_unlock(q->lock); - local_irq_restore(flags); - -Also add a comment to __blk_run_queue() documenting that -q->request_fn() can drop q->queue_lock and reenable interrupts, but -must return with q->queue_lock held and interrupts disabled. - -Signed-off-by: Thomas Gleixner -Cc: Peter Zijlstra -Cc: Tejun Heo -Cc: Jens Axboe -Cc: Linus Torvalds -Link: http://lkml.kernel.org/r/20110622174919.025446432@linutronix.de ---- - block/blk-core.c | 12 ++---------- - 1 file changed, 2 insertions(+), 10 deletions(-) - -diff --git a/block/blk-core.c b/block/blk-core.c -index 0b14aebfd1a8..9e3521c4431a 100644 ---- a/block/blk-core.c -+++ b/block/blk-core.c -@@ -3312,7 +3312,7 @@ static void queue_unplugged(struct request_queue *q, unsigned int depth, - blk_run_queue_async(q); - else - __blk_run_queue(q); -- spin_unlock(q->queue_lock); -+ spin_unlock_irq(q->queue_lock); - } - - static void flush_plug_callbacks(struct blk_plug *plug, bool from_schedule) -@@ -3360,7 +3360,6 @@ EXPORT_SYMBOL(blk_check_plugged); - void blk_flush_plug_list(struct blk_plug *plug, bool from_schedule) - { - struct request_queue *q; -- unsigned long flags; - struct request *rq; - LIST_HEAD(list); - unsigned int depth; -@@ -3380,11 +3379,6 @@ void blk_flush_plug_list(struct blk_plug *plug, bool from_schedule) - q = NULL; - depth = 0; - -- /* -- * Save and disable interrupts here, to avoid doing it for every -- * queue lock we have to take. -- */ -- local_irq_save(flags); - while (!list_empty(&list)) { - rq = list_entry_rq(list.next); - list_del_init(&rq->queuelist); -@@ -3397,7 +3391,7 @@ void blk_flush_plug_list(struct blk_plug *plug, bool from_schedule) - queue_unplugged(q, depth, from_schedule); - q = rq->q; - depth = 0; -- spin_lock(q->queue_lock); -+ spin_lock_irq(q->queue_lock); - } - - /* -@@ -3424,8 +3418,6 @@ void blk_flush_plug_list(struct blk_plug *plug, bool from_schedule) - */ - if (q) - queue_unplugged(q, depth, from_schedule); -- -- local_irq_restore(flags); - } - - void blk_finish_plug(struct blk_plug *plug) --- -2.19.2 - diff --git a/kernel/patches-4.14.x-rt/0124-tracing-Account-for-preempt-off-in-preempt_schedule.patch b/kernel/patches-4.14.x-rt/0124-tracing-Account-for-preempt-off-in-preempt_schedule.patch deleted file mode 100644 index b75447700..000000000 --- a/kernel/patches-4.14.x-rt/0124-tracing-Account-for-preempt-off-in-preempt_schedule.patch +++ /dev/null @@ -1,53 +0,0 @@ -From c8ee195989e8750fdd93991969e1254120e503f8 Mon Sep 17 00:00:00 2001 -From: Steven Rostedt -Date: Thu, 29 Sep 2011 12:24:30 -0500 -Subject: [PATCH 124/450] tracing: Account for preempt off in - preempt_schedule() - -The preempt_schedule() uses the preempt_disable_notrace() version -because it can cause infinite recursion by the function tracer as -the function tracer uses preempt_enable_notrace() which may call -back into the preempt_schedule() code as the NEED_RESCHED is still -set and the PREEMPT_ACTIVE has not been set yet. - -See commit: d1f74e20b5b064a130cd0743a256c2d3cfe84010 that made this -change. - -The preemptoff and preemptirqsoff latency tracers require the first -and last preempt count modifiers to enable tracing. But this skips -the checks. Since we can not convert them back to the non notrace -version, we can use the idle() hooks for the latency tracers here. -That is, the start/stop_critical_timings() works well to manually -start and stop the latency tracer for preempt off timings. - -Signed-off-by: Steven Rostedt -Signed-off-by: Clark Williams -Signed-off-by: Thomas Gleixner ---- - kernel/sched/core.c | 9 +++++++++ - 1 file changed, 9 insertions(+) - -diff --git a/kernel/sched/core.c b/kernel/sched/core.c -index 590a3a396048..5b1a76112243 100644 ---- a/kernel/sched/core.c -+++ b/kernel/sched/core.c -@@ -3607,7 +3607,16 @@ asmlinkage __visible void __sched notrace preempt_schedule_notrace(void) - * an infinite recursion. - */ - prev_ctx = exception_enter(); -+ /* -+ * The add/subtract must not be traced by the function -+ * tracer. But we still want to account for the -+ * preempt off latency tracer. Since the _notrace versions -+ * of add/subtract skip the accounting for latency tracer -+ * we must force it manually. -+ */ -+ start_critical_timings(); - __schedule(true); -+ stop_critical_timings(); - exception_exit(prev_ctx); - - preempt_latency_stop(1); --- -2.19.2 - diff --git a/kernel/patches-4.14.x-rt/0128-posix-timers-Prevent-broadcast-signals.patch b/kernel/patches-4.14.x-rt/0128-posix-timers-Prevent-broadcast-signals.patch deleted file mode 100644 index 8577ea00a..000000000 --- a/kernel/patches-4.14.x-rt/0128-posix-timers-Prevent-broadcast-signals.patch +++ /dev/null @@ -1,38 +0,0 @@ -From 049f419be39f57dbd0ae2b8f71b282a2c28f7821 Mon Sep 17 00:00:00 2001 -From: Thomas Gleixner -Date: Fri, 3 Jul 2009 08:29:20 -0500 -Subject: [PATCH 128/450] posix-timers: Prevent broadcast signals - -Posix timers should not send broadcast signals and kernel only -signals. Prevent it. - -Signed-off-by: Thomas Gleixner ---- - kernel/time/posix-timers.c | 4 +++- - 1 file changed, 3 insertions(+), 1 deletion(-) - -diff --git a/kernel/time/posix-timers.c b/kernel/time/posix-timers.c -index 55d45fe2cc17..dff86a0157db 100644 ---- a/kernel/time/posix-timers.c -+++ b/kernel/time/posix-timers.c -@@ -443,6 +443,7 @@ static enum hrtimer_restart posix_timer_fn(struct hrtimer *timer) - static struct pid *good_sigevent(sigevent_t * event) - { - struct task_struct *rtn = current->group_leader; -+ int sig = event->sigev_signo; - - switch (event->sigev_notify) { - case SIGEV_SIGNAL | SIGEV_THREAD_ID: -@@ -452,7 +453,8 @@ static struct pid *good_sigevent(sigevent_t * event) - /* FALLTHRU */ - case SIGEV_SIGNAL: - case SIGEV_THREAD: -- if (event->sigev_signo <= 0 || event->sigev_signo > SIGRTMAX) -+ if (sig <= 0 || sig > SIGRTMAX || -+ sig_kernel_only(sig) || sig_kernel_coredump(sig)) - return NULL; - /* FALLTHRU */ - case SIGEV_NONE: --- -2.19.2 - diff --git a/kernel/patches-4.14.x-rt/0130-drivers-random-Reduce-preempt-disabled-region.patch b/kernel/patches-4.14.x-rt/0130-drivers-random-Reduce-preempt-disabled-region.patch deleted file mode 100644 index 51e2d1ab0..000000000 --- a/kernel/patches-4.14.x-rt/0130-drivers-random-Reduce-preempt-disabled-region.patch +++ /dev/null @@ -1,37 +0,0 @@ -From 3931903ca419f65c45ab81f67443109aa1bde3cd Mon Sep 17 00:00:00 2001 -From: Ingo Molnar -Date: Fri, 3 Jul 2009 08:29:30 -0500 -Subject: [PATCH 130/450] drivers: random: Reduce preempt disabled region - -No need to keep preemption disabled across the whole function. - -Signed-off-by: Ingo Molnar -Signed-off-by: Thomas Gleixner ---- - drivers/char/random.c | 3 --- - 1 file changed, 3 deletions(-) - -diff --git a/drivers/char/random.c b/drivers/char/random.c -index ea4dbfa30657..8a6228ab983c 100644 ---- a/drivers/char/random.c -+++ b/drivers/char/random.c -@@ -1122,8 +1122,6 @@ static void add_timer_randomness(struct timer_rand_state *state, unsigned num) - } sample; - long delta, delta2, delta3; - -- preempt_disable(); -- - sample.jiffies = jiffies; - sample.cycles = random_get_entropy(); - sample.num = num; -@@ -1164,7 +1162,6 @@ static void add_timer_randomness(struct timer_rand_state *state, unsigned num) - */ - credit_entropy_bits(r, min_t(int, fls(delta>>1), 11)); - } -- preempt_enable(); - } - - void add_input_randomness(unsigned int type, unsigned int code, --- -2.19.2 - diff --git a/kernel/patches-4.14.x-rt/0131-ARM-AT91-PIT-Remove-irq-handler-when-clock-event-is-.patch b/kernel/patches-4.14.x-rt/0131-ARM-AT91-PIT-Remove-irq-handler-when-clock-event-is-.patch deleted file mode 100644 index 829d57ff2..000000000 --- a/kernel/patches-4.14.x-rt/0131-ARM-AT91-PIT-Remove-irq-handler-when-clock-event-is-.patch +++ /dev/null @@ -1,157 +0,0 @@ -From fbd024901d7a248f536fd9d5c81f1c432af909ba Mon Sep 17 00:00:00 2001 -From: Benedikt Spranger -Date: Sat, 6 Mar 2010 17:47:10 +0100 -Subject: [PATCH 131/450] ARM: AT91: PIT: Remove irq handler when clock event - is unused -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -Setup and remove the interrupt handler in clock event mode selection. -This avoids calling the (shared) interrupt handler when the device is -not used. - -Signed-off-by: Benedikt Spranger -Signed-off-by: Thomas Gleixner -[bigeasy: redo the patch with NR_IRQS_LEGACY which is probably required since -commit 8fe82a55 ("ARM: at91: sparse irq support") which is included since v3.6. -Patch based on what Sami Pietikäinen suggested]. -Signed-off-by: Sebastian Andrzej Siewior ---- - drivers/clocksource/timer-atmel-pit.c | 19 +++++++-------- - drivers/clocksource/timer-atmel-st.c | 34 +++++++++++++++++---------- - 2 files changed, 31 insertions(+), 22 deletions(-) - -diff --git a/drivers/clocksource/timer-atmel-pit.c b/drivers/clocksource/timer-atmel-pit.c -index 2fab18fae4fc..68c530354512 100644 ---- a/drivers/clocksource/timer-atmel-pit.c -+++ b/drivers/clocksource/timer-atmel-pit.c -@@ -96,15 +96,24 @@ static int pit_clkevt_shutdown(struct clock_event_device *dev) - - /* disable irq, leaving the clocksource active */ - pit_write(data->base, AT91_PIT_MR, (data->cycle - 1) | AT91_PIT_PITEN); -+ free_irq(data->irq, data); - return 0; - } - -+static irqreturn_t at91sam926x_pit_interrupt(int irq, void *dev_id); - /* - * Clockevent device: interrupts every 1/HZ (== pit_cycles * MCK/16) - */ - static int pit_clkevt_set_periodic(struct clock_event_device *dev) - { - struct pit_data *data = clkevt_to_pit_data(dev); -+ int ret; -+ -+ ret = request_irq(data->irq, at91sam926x_pit_interrupt, -+ IRQF_SHARED | IRQF_TIMER | IRQF_IRQPOLL, -+ "at91_tick", data); -+ if (ret) -+ panic(pr_fmt("Unable to setup IRQ\n")); - - /* update clocksource counter */ - data->cnt += data->cycle * PIT_PICNT(pit_read(data->base, AT91_PIT_PIVR)); -@@ -233,16 +242,6 @@ static int __init at91sam926x_pit_dt_init(struct device_node *node) - goto exit; - } - -- /* Set up irq handler */ -- ret = request_irq(data->irq, at91sam926x_pit_interrupt, -- IRQF_SHARED | IRQF_TIMER | IRQF_IRQPOLL, -- "at91_tick", data); -- if (ret) { -- pr_err("Unable to setup IRQ\n"); -- clocksource_unregister(&data->clksrc); -- goto exit; -- } -- - /* Set up and register clockevents */ - data->clkevt.name = "pit"; - data->clkevt.features = CLOCK_EVT_FEAT_PERIODIC; -diff --git a/drivers/clocksource/timer-atmel-st.c b/drivers/clocksource/timer-atmel-st.c -index d2e660f475af..c63b96cfc23e 100644 ---- a/drivers/clocksource/timer-atmel-st.c -+++ b/drivers/clocksource/timer-atmel-st.c -@@ -115,18 +115,29 @@ static void clkdev32k_disable_and_flush_irq(void) - last_crtr = read_CRTR(); - } - -+static int atmel_st_irq; -+ - static int clkevt32k_shutdown(struct clock_event_device *evt) - { - clkdev32k_disable_and_flush_irq(); - irqmask = 0; - regmap_write(regmap_st, AT91_ST_IER, irqmask); -+ free_irq(atmel_st_irq, regmap_st); - return 0; - } - - static int clkevt32k_set_oneshot(struct clock_event_device *dev) - { -+ int ret; -+ - clkdev32k_disable_and_flush_irq(); - -+ ret = request_irq(atmel_st_irq, at91rm9200_timer_interrupt, -+ IRQF_SHARED | IRQF_TIMER | IRQF_IRQPOLL, -+ "at91_tick", regmap_st); -+ if (ret) -+ panic(pr_fmt("Unable to setup IRQ\n")); -+ - /* - * ALM for oneshot irqs, set by next_event() - * before 32 seconds have passed. -@@ -139,8 +150,16 @@ static int clkevt32k_set_oneshot(struct clock_event_device *dev) - - static int clkevt32k_set_periodic(struct clock_event_device *dev) - { -+ int ret; -+ - clkdev32k_disable_and_flush_irq(); - -+ ret = request_irq(atmel_st_irq, at91rm9200_timer_interrupt, -+ IRQF_SHARED | IRQF_TIMER | IRQF_IRQPOLL, -+ "at91_tick", regmap_st); -+ if (ret) -+ panic(pr_fmt("Unable to setup IRQ\n")); -+ - /* PIT for periodic irqs; fixed rate of 1/HZ */ - irqmask = AT91_ST_PITS; - regmap_write(regmap_st, AT91_ST_PIMR, timer_latch); -@@ -198,7 +217,7 @@ static int __init atmel_st_timer_init(struct device_node *node) - { - struct clk *sclk; - unsigned int sclk_rate, val; -- int irq, ret; -+ int ret; - - regmap_st = syscon_node_to_regmap(node); - if (IS_ERR(regmap_st)) { -@@ -212,21 +231,12 @@ static int __init atmel_st_timer_init(struct device_node *node) - regmap_read(regmap_st, AT91_ST_SR, &val); - - /* Get the interrupts property */ -- irq = irq_of_parse_and_map(node, 0); -- if (!irq) { -+ atmel_st_irq = irq_of_parse_and_map(node, 0); -+ if (!atmel_st_irq) { - pr_err("Unable to get IRQ from DT\n"); - return -EINVAL; - } - -- /* Make IRQs happen for the system timer */ -- ret = request_irq(irq, at91rm9200_timer_interrupt, -- IRQF_SHARED | IRQF_TIMER | IRQF_IRQPOLL, -- "at91_tick", regmap_st); -- if (ret) { -- pr_err("Unable to setup IRQ\n"); -- return ret; -- } -- - sclk = of_clk_get(node, 0); - if (IS_ERR(sclk)) { - pr_err("Unable to get slow clock\n"); --- -2.19.2 - diff --git a/kernel/patches-4.14.x-rt/0132-clockevents-drivers-timer-atmel-pit-fix-double-free_.patch b/kernel/patches-4.14.x-rt/0132-clockevents-drivers-timer-atmel-pit-fix-double-free_.patch deleted file mode 100644 index 26a46a4a3..000000000 --- a/kernel/patches-4.14.x-rt/0132-clockevents-drivers-timer-atmel-pit-fix-double-free_.patch +++ /dev/null @@ -1,52 +0,0 @@ -From 91b17ba12ebd2ebc2dff1cb0a5a46eb25b842acb Mon Sep 17 00:00:00 2001 -From: Alexandre Belloni -Date: Thu, 17 Mar 2016 21:09:43 +0100 -Subject: [PATCH 132/450] clockevents/drivers/timer-atmel-pit: fix double - free_irq - -clockevents_exchange_device() changes the state from detached to shutdown -and so at that point the IRQ has not yet been requested. - -Acked-by: Nicolas Ferre -Signed-off-by: Alexandre Belloni -Signed-off-by: Sebastian Andrzej Siewior ---- - drivers/clocksource/timer-atmel-pit.c | 8 +++++++- - 1 file changed, 7 insertions(+), 1 deletion(-) - -diff --git a/drivers/clocksource/timer-atmel-pit.c b/drivers/clocksource/timer-atmel-pit.c -index 68c530354512..98460c1bdec0 100644 ---- a/drivers/clocksource/timer-atmel-pit.c -+++ b/drivers/clocksource/timer-atmel-pit.c -@@ -46,6 +46,7 @@ struct pit_data { - u32 cycle; - u32 cnt; - unsigned int irq; -+ bool irq_requested; - struct clk *mck; - }; - -@@ -96,7 +97,10 @@ static int pit_clkevt_shutdown(struct clock_event_device *dev) - - /* disable irq, leaving the clocksource active */ - pit_write(data->base, AT91_PIT_MR, (data->cycle - 1) | AT91_PIT_PITEN); -- free_irq(data->irq, data); -+ if (data->irq_requested) { -+ free_irq(data->irq, data); -+ data->irq_requested = false; -+ } - return 0; - } - -@@ -115,6 +119,8 @@ static int pit_clkevt_set_periodic(struct clock_event_device *dev) - if (ret) - panic(pr_fmt("Unable to setup IRQ\n")); - -+ data->irq_requested = true; -+ - /* update clocksource counter */ - data->cnt += data->cycle * PIT_PICNT(pit_read(data->base, AT91_PIT_PIVR)); - pit_write(data->base, AT91_PIT_MR, --- -2.19.2 - diff --git a/kernel/patches-4.14.x-rt/0134-suspend-Prevent-might-sleep-splats.patch b/kernel/patches-4.14.x-rt/0134-suspend-Prevent-might-sleep-splats.patch deleted file mode 100644 index a8f35609f..000000000 --- a/kernel/patches-4.14.x-rt/0134-suspend-Prevent-might-sleep-splats.patch +++ /dev/null @@ -1,115 +0,0 @@ -From 41e3862e0041d35d44320b4401863707d4798640 Mon Sep 17 00:00:00 2001 -From: Thomas Gleixner -Date: Thu, 15 Jul 2010 10:29:00 +0200 -Subject: [PATCH 134/450] suspend: Prevent might sleep splats - -timekeeping suspend/resume calls read_persistant_clock() which takes -rtc_lock. That results in might sleep warnings because at that point -we run with interrupts disabled. - -We cannot convert rtc_lock to a raw spinlock as that would trigger -other might sleep warnings. - -As a temporary workaround we disable the might sleep warnings by -setting system_state to SYSTEM_SUSPEND before calling sysdev_suspend() -and restoring it to SYSTEM_RUNNING afer sysdev_resume(). - -Needs to be revisited. - -Signed-off-by: Thomas Gleixner ---- - include/linux/kernel.h | 1 + - kernel/power/hibernate.c | 7 +++++++ - kernel/power/suspend.c | 4 ++++ - 3 files changed, 12 insertions(+) - -diff --git a/include/linux/kernel.h b/include/linux/kernel.h -index 4b484ab9e163..f696993c052c 100644 ---- a/include/linux/kernel.h -+++ b/include/linux/kernel.h -@@ -531,6 +531,7 @@ extern enum system_states { - SYSTEM_HALT, - SYSTEM_POWER_OFF, - SYSTEM_RESTART, -+ SYSTEM_SUSPEND, - } system_state; - - #define TAINT_PROPRIETARY_MODULE 0 -diff --git a/kernel/power/hibernate.c b/kernel/power/hibernate.c -index a5c36e9c56a6..7c7dbbf23f37 100644 ---- a/kernel/power/hibernate.c -+++ b/kernel/power/hibernate.c -@@ -287,6 +287,8 @@ static int create_image(int platform_mode) - - local_irq_disable(); - -+ system_state = SYSTEM_SUSPEND; -+ - error = syscore_suspend(); - if (error) { - pr_err("Some system devices failed to power down, aborting hibernation\n"); -@@ -317,6 +319,7 @@ static int create_image(int platform_mode) - syscore_resume(); - - Enable_irqs: -+ system_state = SYSTEM_RUNNING; - local_irq_enable(); - - Enable_cpus: -@@ -445,6 +448,7 @@ static int resume_target_kernel(bool platform_mode) - goto Enable_cpus; - - local_irq_disable(); -+ system_state = SYSTEM_SUSPEND; - - error = syscore_suspend(); - if (error) -@@ -478,6 +482,7 @@ static int resume_target_kernel(bool platform_mode) - syscore_resume(); - - Enable_irqs: -+ system_state = SYSTEM_RUNNING; - local_irq_enable(); - - Enable_cpus: -@@ -563,6 +568,7 @@ int hibernation_platform_enter(void) - goto Enable_cpus; - - local_irq_disable(); -+ system_state = SYSTEM_SUSPEND; - syscore_suspend(); - if (pm_wakeup_pending()) { - error = -EAGAIN; -@@ -575,6 +581,7 @@ int hibernation_platform_enter(void) - - Power_up: - syscore_resume(); -+ system_state = SYSTEM_RUNNING; - local_irq_enable(); - - Enable_cpus: -diff --git a/kernel/power/suspend.c b/kernel/power/suspend.c -index c0bc2c89697a..0d3dab53c527 100644 ---- a/kernel/power/suspend.c -+++ b/kernel/power/suspend.c -@@ -428,6 +428,8 @@ static int suspend_enter(suspend_state_t state, bool *wakeup) - arch_suspend_disable_irqs(); - BUG_ON(!irqs_disabled()); - -+ system_state = SYSTEM_SUSPEND; -+ - error = syscore_suspend(); - if (!error) { - *wakeup = pm_wakeup_pending(); -@@ -443,6 +445,8 @@ static int suspend_enter(suspend_state_t state, bool *wakeup) - syscore_resume(); - } - -+ system_state = SYSTEM_RUNNING; -+ - arch_suspend_enable_irqs(); - BUG_ON(irqs_disabled()); - --- -2.19.2 - diff --git a/kernel/patches-4.14.x-rt/0135-net-flip-lock-dep-thingy.patch.patch b/kernel/patches-4.14.x-rt/0135-net-flip-lock-dep-thingy.patch.patch deleted file mode 100644 index ed822af38..000000000 --- a/kernel/patches-4.14.x-rt/0135-net-flip-lock-dep-thingy.patch.patch +++ /dev/null @@ -1,117 +0,0 @@ -From 57a08f446fd23ab42ab8ea35776be5c7a71f18d8 Mon Sep 17 00:00:00 2001 -From: Thomas Gleixner -Date: Tue, 28 Jun 2011 10:59:58 +0200 -Subject: [PATCH 135/450] net-flip-lock-dep-thingy.patch - -======================================================= -[ INFO: possible circular locking dependency detected ] -3.0.0-rc3+ #26 -------------------------------------------------------- -ip/1104 is trying to acquire lock: - (local_softirq_lock){+.+...}, at: [] __local_lock+0x25/0x68 - -but task is already holding lock: - (sk_lock-AF_INET){+.+...}, at: [] lock_sock+0x10/0x12 - -which lock already depends on the new lock. - - -the existing dependency chain (in reverse order) is: - --> #1 (sk_lock-AF_INET){+.+...}: - [] lock_acquire+0x103/0x12e - [] lock_sock_nested+0x82/0x92 - [] lock_sock+0x10/0x12 - [] tcp_close+0x1b/0x355 - [] inet_release+0xc3/0xcd - [] sock_release+0x1f/0x74 - [] sock_close+0x27/0x2b - [] fput+0x11d/0x1e3 - [] filp_close+0x70/0x7b - [] sys_close+0xf8/0x13d - [] system_call_fastpath+0x16/0x1b - --> #0 (local_softirq_lock){+.+...}: - [] __lock_acquire+0xacc/0xdc8 - [] lock_acquire+0x103/0x12e - [] _raw_spin_lock+0x3b/0x4a - [] __local_lock+0x25/0x68 - [] local_bh_disable+0x36/0x3b - [] _raw_write_lock_bh+0x16/0x4f - [] tcp_close+0x159/0x355 - [] inet_release+0xc3/0xcd - [] sock_release+0x1f/0x74 - [] sock_close+0x27/0x2b - [] fput+0x11d/0x1e3 - [] filp_close+0x70/0x7b - [] sys_close+0xf8/0x13d - [] system_call_fastpath+0x16/0x1b - -other info that might help us debug this: - - Possible unsafe locking scenario: - - CPU0 CPU1 - ---- ---- - lock(sk_lock-AF_INET); - lock(local_softirq_lock); - lock(sk_lock-AF_INET); - lock(local_softirq_lock); - - *** DEADLOCK *** - -1 lock held by ip/1104: - #0: (sk_lock-AF_INET){+.+...}, at: [] lock_sock+0x10/0x12 - -stack backtrace: -Pid: 1104, comm: ip Not tainted 3.0.0-rc3+ #26 -Call Trace: - [] print_circular_bug+0x1f8/0x209 - [] __lock_acquire+0xacc/0xdc8 - [] ? __local_lock+0x25/0x68 - [] lock_acquire+0x103/0x12e - [] ? __local_lock+0x25/0x68 - [] ? get_parent_ip+0x11/0x41 - [] _raw_spin_lock+0x3b/0x4a - [] ? __local_lock+0x25/0x68 - [] ? get_parent_ip+0x28/0x41 - [] __local_lock+0x25/0x68 - [] local_bh_disable+0x36/0x3b - [] ? lock_sock+0x10/0x12 - [] _raw_write_lock_bh+0x16/0x4f - [] tcp_close+0x159/0x355 - [] inet_release+0xc3/0xcd - [] sock_release+0x1f/0x74 - [] sock_close+0x27/0x2b - [] fput+0x11d/0x1e3 - [] filp_close+0x70/0x7b - [] sys_close+0xf8/0x13d - [] system_call_fastpath+0x16/0x1b - - -Signed-off-by: Thomas Gleixner ---- - net/core/sock.c | 3 +-- - 1 file changed, 1 insertion(+), 2 deletions(-) - -diff --git a/net/core/sock.c b/net/core/sock.c -index 36f19458e2fe..244f6fda0a96 100644 ---- a/net/core/sock.c -+++ b/net/core/sock.c -@@ -2757,12 +2757,11 @@ void lock_sock_nested(struct sock *sk, int subclass) - if (sk->sk_lock.owned) - __lock_sock(sk); - sk->sk_lock.owned = 1; -- spin_unlock(&sk->sk_lock.slock); -+ spin_unlock_bh(&sk->sk_lock.slock); - /* - * The sk_lock has mutex_lock() semantics here: - */ - mutex_acquire(&sk->sk_lock.dep_map, subclass, 0, _RET_IP_); -- local_bh_enable(); - } - EXPORT_SYMBOL(lock_sock_nested); - --- -2.19.2 - diff --git a/kernel/patches-4.14.x-rt/0138-x86-ioapic-Do-not-unmask-io_apic-when-interrupt-is-i.patch b/kernel/patches-4.14.x-rt/0138-x86-ioapic-Do-not-unmask-io_apic-when-interrupt-is-i.patch deleted file mode 100644 index 6dd2ffbe2..000000000 --- a/kernel/patches-4.14.x-rt/0138-x86-ioapic-Do-not-unmask-io_apic-when-interrupt-is-i.patch +++ /dev/null @@ -1,32 +0,0 @@ -From 645a7c79aa4e0503fccfa644355244eb9ce8c608 Mon Sep 17 00:00:00 2001 -From: Ingo Molnar -Date: Fri, 3 Jul 2009 08:29:27 -0500 -Subject: [PATCH 138/450] x86/ioapic: Do not unmask io_apic when interrupt is - in progress - -With threaded interrupts we might see an interrupt in progress on -migration. Do not unmask it when this is the case. - -Signed-off-by: Ingo Molnar -Signed-off-by: Thomas Gleixner ---- - arch/x86/kernel/apic/io_apic.c | 3 ++- - 1 file changed, 2 insertions(+), 1 deletion(-) - -diff --git a/arch/x86/kernel/apic/io_apic.c b/arch/x86/kernel/apic/io_apic.c -index 96a8a68f9c79..5832a9d657f2 100644 ---- a/arch/x86/kernel/apic/io_apic.c -+++ b/arch/x86/kernel/apic/io_apic.c -@@ -1691,7 +1691,8 @@ static bool io_apic_level_ack_pending(struct mp_chip_data *data) - static inline bool ioapic_irqd_mask(struct irq_data *data) - { - /* If we are moving the irq we need to mask it */ -- if (unlikely(irqd_is_setaffinity_pending(data))) { -+ if (unlikely(irqd_is_setaffinity_pending(data) && -+ !irqd_irq_inprogress(data))) { - mask_ioapic_irq(data); - return true; - } --- -2.19.2 - diff --git a/kernel/patches-4.14.x-rt/0139-rcu-segcblist-include-rcupdate.h.patch b/kernel/patches-4.14.x-rt/0139-rcu-segcblist-include-rcupdate.h.patch deleted file mode 100644 index 239c1d635..000000000 --- a/kernel/patches-4.14.x-rt/0139-rcu-segcblist-include-rcupdate.h.patch +++ /dev/null @@ -1,28 +0,0 @@ -From 9b94ddb647d12f1d2f18a8755e81ec0ee2455615 Mon Sep 17 00:00:00 2001 -From: Sebastian Andrzej Siewior -Date: Fri, 22 Sep 2017 15:01:46 +0200 -Subject: [PATCH 139/450] rcu/segcblist: include rcupdate.h - -The RT build on ARM complains about non-existing ULONG_CMP_LT. Since -rcu_segcblist.c uses that macro it should include the header file. - -Signed-off-by: Sebastian Andrzej Siewior ---- - kernel/rcu/rcu_segcblist.c | 1 + - 1 file changed, 1 insertion(+) - -diff --git a/kernel/rcu/rcu_segcblist.c b/kernel/rcu/rcu_segcblist.c -index 7649fcd2c4c7..88cba7c2956c 100644 ---- a/kernel/rcu/rcu_segcblist.c -+++ b/kernel/rcu/rcu_segcblist.c -@@ -23,6 +23,7 @@ - #include - #include - #include -+#include - - #include "rcu_segcblist.h" - --- -2.19.2 - diff --git a/kernel/patches-4.14.x-rt/0145-bug-BUG_ON-WARN_ON-variants-dependend-on-RT-RT.patch b/kernel/patches-4.14.x-rt/0145-bug-BUG_ON-WARN_ON-variants-dependend-on-RT-RT.patch deleted file mode 100644 index fd89f0c9a..000000000 --- a/kernel/patches-4.14.x-rt/0145-bug-BUG_ON-WARN_ON-variants-dependend-on-RT-RT.patch +++ /dev/null @@ -1,41 +0,0 @@ -From e084dc8c43f540679c499857a086cf82206762bf Mon Sep 17 00:00:00 2001 -From: Ingo Molnar -Date: Fri, 3 Jul 2009 08:29:58 -0500 -Subject: [PATCH 145/450] bug: BUG_ON/WARN_ON variants dependend on RT/!RT - -Introduce RT/NON-RT WARN/BUG statements to avoid ifdefs in the code. - -Signed-off-by: Ingo Molnar -Signed-off-by: Thomas Gleixner ---- - include/asm-generic/bug.h | 14 ++++++++++++++ - 1 file changed, 14 insertions(+) - -diff --git a/include/asm-generic/bug.h b/include/asm-generic/bug.h -index ae1a33aa8955..c6d04eca8345 100644 ---- a/include/asm-generic/bug.h -+++ b/include/asm-generic/bug.h -@@ -234,6 +234,20 @@ void __warn(const char *file, int line, void *caller, unsigned taint, - # define WARN_ON_SMP(x) ({0;}) - #endif - -+#ifdef CONFIG_PREEMPT_RT_BASE -+# define BUG_ON_RT(c) BUG_ON(c) -+# define BUG_ON_NONRT(c) do { } while (0) -+# define WARN_ON_RT(condition) WARN_ON(condition) -+# define WARN_ON_NONRT(condition) do { } while (0) -+# define WARN_ON_ONCE_NONRT(condition) do { } while (0) -+#else -+# define BUG_ON_RT(c) do { } while (0) -+# define BUG_ON_NONRT(c) BUG_ON(c) -+# define WARN_ON_RT(condition) do { } while (0) -+# define WARN_ON_NONRT(condition) WARN_ON(condition) -+# define WARN_ON_ONCE_NONRT(condition) WARN_ON_ONCE(condition) -+#endif -+ - #endif /* __ASSEMBLY__ */ - - #endif --- -2.19.2 - diff --git a/kernel/patches-4.14.x-rt/0146-iommu-amd-Use-WARN_ON_NORT-in-__attach_device.patch b/kernel/patches-4.14.x-rt/0146-iommu-amd-Use-WARN_ON_NORT-in-__attach_device.patch deleted file mode 100644 index 829b46609..000000000 --- a/kernel/patches-4.14.x-rt/0146-iommu-amd-Use-WARN_ON_NORT-in-__attach_device.patch +++ /dev/null @@ -1,52 +0,0 @@ -From 82f7c7f43cae44940e47867ef790f8f88cb748d5 Mon Sep 17 00:00:00 2001 -From: Thomas Gleixner -Date: Sat, 27 Feb 2016 10:22:23 +0100 -Subject: [PATCH 146/450] iommu/amd: Use WARN_ON_NORT in __attach_device() - -RT does not disable interrupts here, but the protection is still -correct. Fixup the WARN_ON so it won't yell on RT. - -Note: This WARN_ON is bogus anyway. The real thing this needs to check is that -amd_iommu_devtable_lock is held. - -Reported-by: DIXLOR -Signed-off-by: Thomas Gleixner ---- - drivers/iommu/amd_iommu.c | 12 ++++++------ - 1 file changed, 6 insertions(+), 6 deletions(-) - -diff --git a/drivers/iommu/amd_iommu.c b/drivers/iommu/amd_iommu.c -index 876947fcb4c6..7d9d41f803d1 100644 ---- a/drivers/iommu/amd_iommu.c -+++ b/drivers/iommu/amd_iommu.c -@@ -1943,10 +1943,10 @@ static int __attach_device(struct iommu_dev_data *dev_data, - int ret; - - /* -- * Must be called with IRQs disabled. Warn here to detect early -- * when its not. -+ * Must be called with IRQs disabled on a non RT kernel. Warn here to -+ * detect early when its not. - */ -- WARN_ON(!irqs_disabled()); -+ WARN_ON_NONRT(!irqs_disabled()); - - /* lock domain */ - spin_lock(&domain->lock); -@@ -2114,10 +2114,10 @@ static void __detach_device(struct iommu_dev_data *dev_data) - struct protection_domain *domain; - - /* -- * Must be called with IRQs disabled. Warn here to detect early -- * when its not. -+ * Must be called with IRQs disabled on a non RT kernel. Warn here to -+ * detect early when its not. - */ -- WARN_ON(!irqs_disabled()); -+ WARN_ON_NONRT(!irqs_disabled()); - - if (WARN_ON(!dev_data->domain)) - return; --- -2.19.2 - diff --git a/kernel/patches-4.14.x-rt/0147-rt-local_irq_-variants-depending-on-RT-RT.patch b/kernel/patches-4.14.x-rt/0147-rt-local_irq_-variants-depending-on-RT-RT.patch deleted file mode 100644 index 38cd66121..000000000 --- a/kernel/patches-4.14.x-rt/0147-rt-local_irq_-variants-depending-on-RT-RT.patch +++ /dev/null @@ -1,59 +0,0 @@ -From ae3322916ba39450d3ea4f935ba2acaaf44ed5a9 Mon Sep 17 00:00:00 2001 -From: Thomas Gleixner -Date: Tue, 21 Jul 2009 22:34:14 +0200 -Subject: [PATCH 147/450] rt: local_irq_* variants depending on RT/!RT - -Add local_irq_*_(no)rt variant which are mainly used to break -interrupt disabled sections on PREEMPT_RT or to explicitely disable -interrupts on PREEMPT_RT. - -Signed-off-by: Thomas Gleixner ---- - include/linux/interrupt.h | 2 +- - include/linux/irqflags.h | 19 +++++++++++++++++++ - 2 files changed, 20 insertions(+), 1 deletion(-) - -diff --git a/include/linux/interrupt.h b/include/linux/interrupt.h -index af15bfd89598..2957da07e967 100644 ---- a/include/linux/interrupt.h -+++ b/include/linux/interrupt.h -@@ -207,7 +207,7 @@ extern void devm_free_irq(struct device *dev, unsigned int irq, void *dev_id); - #ifdef CONFIG_LOCKDEP - # define local_irq_enable_in_hardirq() do { } while (0) - #else --# define local_irq_enable_in_hardirq() local_irq_enable() -+# define local_irq_enable_in_hardirq() local_irq_enable_nort() - #endif - - extern void disable_irq_nosync(unsigned int irq); -diff --git a/include/linux/irqflags.h b/include/linux/irqflags.h -index 46cb57d5eb13..7834117a1ef5 100644 ---- a/include/linux/irqflags.h -+++ b/include/linux/irqflags.h -@@ -165,4 +165,23 @@ do { \ - - #define irqs_disabled_flags(flags) raw_irqs_disabled_flags(flags) - -+/* -+ * local_irq* variants depending on RT/!RT -+ */ -+#ifdef CONFIG_PREEMPT_RT_FULL -+# define local_irq_disable_nort() do { } while (0) -+# define local_irq_enable_nort() do { } while (0) -+# define local_irq_save_nort(flags) local_save_flags(flags) -+# define local_irq_restore_nort(flags) (void)(flags) -+# define local_irq_disable_rt() local_irq_disable() -+# define local_irq_enable_rt() local_irq_enable() -+#else -+# define local_irq_disable_nort() local_irq_disable() -+# define local_irq_enable_nort() local_irq_enable() -+# define local_irq_save_nort(flags) local_irq_save(flags) -+# define local_irq_restore_nort(flags) local_irq_restore(flags) -+# define local_irq_disable_rt() do { } while (0) -+# define local_irq_enable_rt() do { } while (0) -+#endif -+ - #endif --- -2.19.2 - diff --git a/kernel/patches-4.14.x-rt/0151-ata-Do-not-disable-interrupts-in-ide-code-for-preemp.patch b/kernel/patches-4.14.x-rt/0151-ata-Do-not-disable-interrupts-in-ide-code-for-preemp.patch deleted file mode 100644 index b4d3278a3..000000000 --- a/kernel/patches-4.14.x-rt/0151-ata-Do-not-disable-interrupts-in-ide-code-for-preemp.patch +++ /dev/null @@ -1,34 +0,0 @@ -From d68b176c0966248883554b0d06bafdd2cfd9d4d6 Mon Sep 17 00:00:00 2001 -From: Steven Rostedt -Date: Fri, 3 Jul 2009 08:44:29 -0500 -Subject: [PATCH 151/450] ata: Do not disable interrupts in ide code for - preempt-rt - -Use the local_irq_*_nort variants. - -Signed-off-by: Steven Rostedt -Signed-off-by: Ingo Molnar -Signed-off-by: Thomas Gleixner ---- - drivers/ata/libata-sff.c | 4 ++-- - 1 file changed, 2 insertions(+), 2 deletions(-) - -diff --git a/drivers/ata/libata-sff.c b/drivers/ata/libata-sff.c -index cc2f2e35f4c2..0f0bc86e02df 100644 ---- a/drivers/ata/libata-sff.c -+++ b/drivers/ata/libata-sff.c -@@ -679,9 +679,9 @@ unsigned int ata_sff_data_xfer_noirq(struct ata_queued_cmd *qc, unsigned char *b - unsigned long flags; - unsigned int consumed; - -- local_irq_save(flags); -+ local_irq_save_nort(flags); - consumed = ata_sff_data_xfer32(qc, buf, buflen, rw); -- local_irq_restore(flags); -+ local_irq_restore_nort(flags); - - return consumed; - } --- -2.19.2 - diff --git a/kernel/patches-4.14.x-rt/0152-ide-Do-not-disable-interrupts-for-PREEMPT-RT.patch b/kernel/patches-4.14.x-rt/0152-ide-Do-not-disable-interrupts-for-PREEMPT-RT.patch deleted file mode 100644 index 72d9170df..000000000 --- a/kernel/patches-4.14.x-rt/0152-ide-Do-not-disable-interrupts-for-PREEMPT-RT.patch +++ /dev/null @@ -1,186 +0,0 @@ -From ce0317fb2714be2be8d385ffc6ef8a19f2bbaee2 Mon Sep 17 00:00:00 2001 -From: Ingo Molnar -Date: Fri, 3 Jul 2009 08:30:16 -0500 -Subject: [PATCH 152/450] ide: Do not disable interrupts for PREEMPT-RT - -Use the local_irq_*_nort variants. - -Signed-off-by: Ingo Molnar -Signed-off-by: Thomas Gleixner ---- - drivers/ide/alim15x3.c | 4 ++-- - drivers/ide/hpt366.c | 4 ++-- - drivers/ide/ide-io-std.c | 8 ++++---- - drivers/ide/ide-io.c | 2 +- - drivers/ide/ide-iops.c | 4 ++-- - drivers/ide/ide-probe.c | 4 ++-- - drivers/ide/ide-taskfile.c | 6 +++--- - 7 files changed, 16 insertions(+), 16 deletions(-) - -diff --git a/drivers/ide/alim15x3.c b/drivers/ide/alim15x3.c -index 36f76e28a0bf..394f142f90c7 100644 ---- a/drivers/ide/alim15x3.c -+++ b/drivers/ide/alim15x3.c -@@ -234,7 +234,7 @@ static int init_chipset_ali15x3(struct pci_dev *dev) - - isa_dev = pci_get_device(PCI_VENDOR_ID_AL, PCI_DEVICE_ID_AL_M1533, NULL); - -- local_irq_save(flags); -+ local_irq_save_nort(flags); - - if (m5229_revision < 0xC2) { - /* -@@ -325,7 +325,7 @@ static int init_chipset_ali15x3(struct pci_dev *dev) - } - pci_dev_put(north); - pci_dev_put(isa_dev); -- local_irq_restore(flags); -+ local_irq_restore_nort(flags); - return 0; - } - -diff --git a/drivers/ide/hpt366.c b/drivers/ide/hpt366.c -index 4b5dc0162e67..590cc7d64622 100644 ---- a/drivers/ide/hpt366.c -+++ b/drivers/ide/hpt366.c -@@ -1236,7 +1236,7 @@ static int init_dma_hpt366(ide_hwif_t *hwif, - - dma_old = inb(base + 2); - -- local_irq_save(flags); -+ local_irq_save_nort(flags); - - dma_new = dma_old; - pci_read_config_byte(dev, hwif->channel ? 0x4b : 0x43, &masterdma); -@@ -1247,7 +1247,7 @@ static int init_dma_hpt366(ide_hwif_t *hwif, - if (dma_new != dma_old) - outb(dma_new, base + 2); - -- local_irq_restore(flags); -+ local_irq_restore_nort(flags); - - printk(KERN_INFO " %s: BM-DMA at 0x%04lx-0x%04lx\n", - hwif->name, base, base + 7); -diff --git a/drivers/ide/ide-io-std.c b/drivers/ide/ide-io-std.c -index 19763977568c..4169433faab5 100644 ---- a/drivers/ide/ide-io-std.c -+++ b/drivers/ide/ide-io-std.c -@@ -175,7 +175,7 @@ void ide_input_data(ide_drive_t *drive, struct ide_cmd *cmd, void *buf, - unsigned long uninitialized_var(flags); - - if ((io_32bit & 2) && !mmio) { -- local_irq_save(flags); -+ local_irq_save_nort(flags); - ata_vlb_sync(io_ports->nsect_addr); - } - -@@ -186,7 +186,7 @@ void ide_input_data(ide_drive_t *drive, struct ide_cmd *cmd, void *buf, - insl(data_addr, buf, words); - - if ((io_32bit & 2) && !mmio) -- local_irq_restore(flags); -+ local_irq_restore_nort(flags); - - if (((len + 1) & 3) < 2) - return; -@@ -219,7 +219,7 @@ void ide_output_data(ide_drive_t *drive, struct ide_cmd *cmd, void *buf, - unsigned long uninitialized_var(flags); - - if ((io_32bit & 2) && !mmio) { -- local_irq_save(flags); -+ local_irq_save_nort(flags); - ata_vlb_sync(io_ports->nsect_addr); - } - -@@ -230,7 +230,7 @@ void ide_output_data(ide_drive_t *drive, struct ide_cmd *cmd, void *buf, - outsl(data_addr, buf, words); - - if ((io_32bit & 2) && !mmio) -- local_irq_restore(flags); -+ local_irq_restore_nort(flags); - - if (((len + 1) & 3) < 2) - return; -diff --git a/drivers/ide/ide-io.c b/drivers/ide/ide-io.c -index 3a234701d92c..420e4e645856 100644 ---- a/drivers/ide/ide-io.c -+++ b/drivers/ide/ide-io.c -@@ -660,7 +660,7 @@ void ide_timer_expiry (unsigned long data) - /* disable_irq_nosync ?? */ - disable_irq(hwif->irq); - /* local CPU only, as if we were handling an interrupt */ -- local_irq_disable(); -+ local_irq_disable_nort(); - if (hwif->polling) { - startstop = handler(drive); - } else if (drive_is_ready(drive)) { -diff --git a/drivers/ide/ide-iops.c b/drivers/ide/ide-iops.c -index 210a0887dd29..7bf05b6147e8 100644 ---- a/drivers/ide/ide-iops.c -+++ b/drivers/ide/ide-iops.c -@@ -129,12 +129,12 @@ int __ide_wait_stat(ide_drive_t *drive, u8 good, u8 bad, - if ((stat & ATA_BUSY) == 0) - break; - -- local_irq_restore(flags); -+ local_irq_restore_nort(flags); - *rstat = stat; - return -EBUSY; - } - } -- local_irq_restore(flags); -+ local_irq_restore_nort(flags); - } - /* - * Allow status to settle, then read it again. -diff --git a/drivers/ide/ide-probe.c b/drivers/ide/ide-probe.c -index eaf39e5db08b..be4c941eaa83 100644 ---- a/drivers/ide/ide-probe.c -+++ b/drivers/ide/ide-probe.c -@@ -196,10 +196,10 @@ static void do_identify(ide_drive_t *drive, u8 cmd, u16 *id) - int bswap = 1; - - /* local CPU only; some systems need this */ -- local_irq_save(flags); -+ local_irq_save_nort(flags); - /* read 512 bytes of id info */ - hwif->tp_ops->input_data(drive, NULL, id, SECTOR_SIZE); -- local_irq_restore(flags); -+ local_irq_restore_nort(flags); - - drive->dev_flags |= IDE_DFLAG_ID_READ; - #ifdef DEBUG -diff --git a/drivers/ide/ide-taskfile.c b/drivers/ide/ide-taskfile.c -index 4efe4c6e956c..7eae3aa1def7 100644 ---- a/drivers/ide/ide-taskfile.c -+++ b/drivers/ide/ide-taskfile.c -@@ -251,7 +251,7 @@ void ide_pio_bytes(ide_drive_t *drive, struct ide_cmd *cmd, - - page_is_high = PageHighMem(page); - if (page_is_high) -- local_irq_save(flags); -+ local_irq_save_nort(flags); - - buf = kmap_atomic(page) + offset; - -@@ -272,7 +272,7 @@ void ide_pio_bytes(ide_drive_t *drive, struct ide_cmd *cmd, - kunmap_atomic(buf); - - if (page_is_high) -- local_irq_restore(flags); -+ local_irq_restore_nort(flags); - - len -= nr_bytes; - } -@@ -415,7 +415,7 @@ static ide_startstop_t pre_task_out_intr(ide_drive_t *drive, - } - - if ((drive->dev_flags & IDE_DFLAG_UNMASK) == 0) -- local_irq_disable(); -+ local_irq_disable_nort(); - - ide_set_handler(drive, &task_pio_intr, WAIT_WORSTCASE); - --- -2.19.2 - diff --git a/kernel/patches-4.14.x-rt/0153-infiniband-Mellanox-IB-driver-patch-use-_nort-primit.patch b/kernel/patches-4.14.x-rt/0153-infiniband-Mellanox-IB-driver-patch-use-_nort-primit.patch deleted file mode 100644 index c9f492f60..000000000 --- a/kernel/patches-4.14.x-rt/0153-infiniband-Mellanox-IB-driver-patch-use-_nort-primit.patch +++ /dev/null @@ -1,46 +0,0 @@ -From 46035933fcfd103832c6eb11a9916698716d0f28 Mon Sep 17 00:00:00 2001 -From: Sven-Thorsten Dietrich -Date: Fri, 3 Jul 2009 08:30:35 -0500 -Subject: [PATCH 153/450] infiniband: Mellanox IB driver patch use _nort() - primitives - -Fixes in_atomic stack-dump, when Mellanox module is loaded into the RT -Kernel. - -Michael S. Tsirkin sayeth: -"Basically, if you just make spin_lock_irqsave (and spin_lock_irq) not disable -interrupts for non-raw spinlocks, I think all of infiniband will be fine without -changes." - -Signed-off-by: Sven-Thorsten Dietrich -Signed-off-by: Ingo Molnar -Signed-off-by: Thomas Gleixner ---- - drivers/infiniband/ulp/ipoib/ipoib_multicast.c | 4 ++-- - 1 file changed, 2 insertions(+), 2 deletions(-) - -diff --git a/drivers/infiniband/ulp/ipoib/ipoib_multicast.c b/drivers/infiniband/ulp/ipoib/ipoib_multicast.c -index 9b3f47ae2016..8327b598d909 100644 ---- a/drivers/infiniband/ulp/ipoib/ipoib_multicast.c -+++ b/drivers/infiniband/ulp/ipoib/ipoib_multicast.c -@@ -898,7 +898,7 @@ void ipoib_mcast_restart_task(struct work_struct *work) - - ipoib_dbg_mcast(priv, "restarting multicast task\n"); - -- local_irq_save(flags); -+ local_irq_save_nort(flags); - netif_addr_lock(dev); - spin_lock(&priv->lock); - -@@ -980,7 +980,7 @@ void ipoib_mcast_restart_task(struct work_struct *work) - - spin_unlock(&priv->lock); - netif_addr_unlock(dev); -- local_irq_restore(flags); -+ local_irq_restore_nort(flags); - - ipoib_mcast_remove_list(&remove_list); - --- -2.19.2 - diff --git a/kernel/patches-4.14.x-rt/0154-input-gameport-Do-not-disable-interrupts-on-PREEMPT_.patch b/kernel/patches-4.14.x-rt/0154-input-gameport-Do-not-disable-interrupts-on-PREEMPT_.patch deleted file mode 100644 index 4938eab11..000000000 --- a/kernel/patches-4.14.x-rt/0154-input-gameport-Do-not-disable-interrupts-on-PREEMPT_.patch +++ /dev/null @@ -1,66 +0,0 @@ -From c92f8a1a659ebf3ba6fc7e5b3a3ae3aabd06bac9 Mon Sep 17 00:00:00 2001 -From: Ingo Molnar -Date: Fri, 3 Jul 2009 08:30:16 -0500 -Subject: [PATCH 154/450] input: gameport: Do not disable interrupts on - PREEMPT_RT - -Use the _nort() primitives. - -Signed-off-by: Ingo Molnar -Signed-off-by: Thomas Gleixner ---- - drivers/input/gameport/gameport.c | 12 ++++++------ - 1 file changed, 6 insertions(+), 6 deletions(-) - -diff --git a/drivers/input/gameport/gameport.c b/drivers/input/gameport/gameport.c -index cedc665364cd..4a4fdef151aa 100644 ---- a/drivers/input/gameport/gameport.c -+++ b/drivers/input/gameport/gameport.c -@@ -91,13 +91,13 @@ static int gameport_measure_speed(struct gameport *gameport) - tx = ~0; - - for (i = 0; i < 50; i++) { -- local_irq_save(flags); -+ local_irq_save_nort(flags); - t1 = ktime_get_ns(); - for (t = 0; t < 50; t++) - gameport_read(gameport); - t2 = ktime_get_ns(); - t3 = ktime_get_ns(); -- local_irq_restore(flags); -+ local_irq_restore_nort(flags); - udelay(i * 10); - t = (t2 - t1) - (t3 - t2); - if (t < tx) -@@ -124,12 +124,12 @@ static int old_gameport_measure_speed(struct gameport *gameport) - tx = 1 << 30; - - for(i = 0; i < 50; i++) { -- local_irq_save(flags); -+ local_irq_save_nort(flags); - GET_TIME(t1); - for (t = 0; t < 50; t++) gameport_read(gameport); - GET_TIME(t2); - GET_TIME(t3); -- local_irq_restore(flags); -+ local_irq_restore_nort(flags); - udelay(i * 10); - if ((t = DELTA(t2,t1) - DELTA(t3,t2)) < tx) tx = t; - } -@@ -148,11 +148,11 @@ static int old_gameport_measure_speed(struct gameport *gameport) - tx = 1 << 30; - - for(i = 0; i < 50; i++) { -- local_irq_save(flags); -+ local_irq_save_nort(flags); - t1 = rdtsc(); - for (t = 0; t < 50; t++) gameport_read(gameport); - t2 = rdtsc(); -- local_irq_restore(flags); -+ local_irq_restore_nort(flags); - udelay(i * 10); - if (t2 - t1 < tx) tx = t2 - t1; - } --- -2.19.2 - diff --git a/kernel/patches-4.14.x-rt/0155-core-Do-not-disable-interrupts-on-RT-in-kernel-users.patch b/kernel/patches-4.14.x-rt/0155-core-Do-not-disable-interrupts-on-RT-in-kernel-users.patch deleted file mode 100644 index f8dba2c4a..000000000 --- a/kernel/patches-4.14.x-rt/0155-core-Do-not-disable-interrupts-on-RT-in-kernel-users.patch +++ /dev/null @@ -1,35 +0,0 @@ -From 6c7fa9bfc7c152897b0b1315e412703262182259 Mon Sep 17 00:00:00 2001 -From: Thomas Gleixner -Date: Tue, 21 Jul 2009 23:06:05 +0200 -Subject: [PATCH 155/450] core: Do not disable interrupts on RT in - kernel/users.c - -Use the local_irq_*_nort variants to reduce latencies in RT. The code -is serialized by the locks. No need to disable interrupts. - -Signed-off-by: Thomas Gleixner ---- - kernel/user.c | 4 ++-- - 1 file changed, 2 insertions(+), 2 deletions(-) - -diff --git a/kernel/user.c b/kernel/user.c -index 00281add65b2..f4cf1841f2fd 100644 ---- a/kernel/user.c -+++ b/kernel/user.c -@@ -162,11 +162,11 @@ void free_uid(struct user_struct *up) - if (!up) - return; - -- local_irq_save(flags); -+ local_irq_save_nort(flags); - if (atomic_dec_and_lock(&up->__count, &uidhash_lock)) - free_user(up, flags); - else -- local_irq_restore(flags); -+ local_irq_restore_nort(flags); - } - - struct user_struct *alloc_uid(kuid_t uid) --- -2.19.2 - diff --git a/kernel/patches-4.14.x-rt/0156-usb-Use-_nort-in-giveback-function.patch b/kernel/patches-4.14.x-rt/0156-usb-Use-_nort-in-giveback-function.patch deleted file mode 100644 index af305aa09..000000000 --- a/kernel/patches-4.14.x-rt/0156-usb-Use-_nort-in-giveback-function.patch +++ /dev/null @@ -1,63 +0,0 @@ -From ba9e47b77d0094bd6f1dd284baa481243aec2960 Mon Sep 17 00:00:00 2001 -From: Sebastian Andrzej Siewior -Date: Fri, 8 Nov 2013 17:34:54 +0100 -Subject: [PATCH 156/450] usb: Use _nort in giveback function - -Since commit 94dfd7ed ("USB: HCD: support giveback of URB in tasklet -context") I see - -|BUG: sleeping function called from invalid context at kernel/rtmutex.c:673 -|in_atomic(): 0, irqs_disabled(): 1, pid: 109, name: irq/11-uhci_hcd -|no locks held by irq/11-uhci_hcd/109. -|irq event stamp: 440 -|hardirqs last enabled at (439): [] _raw_spin_unlock_irqrestore+0x75/0x90 -|hardirqs last disabled at (440): [] __usb_hcd_giveback_urb+0x46/0xc0 -|softirqs last enabled at (0): [] copy_process.part.52+0x511/0x1510 -|softirqs last disabled at (0): [< (null)>] (null) -|CPU: 3 PID: 109 Comm: irq/11-uhci_hcd Not tainted 3.12.0-rt0-rc1+ #13 -|Hardware name: Bochs Bochs, BIOS Bochs 01/01/2011 -| 0000000000000000 ffff8800db9ffbe0 ffffffff8169f064 0000000000000000 -| ffff8800db9ffbf8 ffffffff810b2122 ffff88020f03e888 ffff8800db9ffc18 -| ffffffff816a6944 ffffffff810b5748 ffff88020f03c000 ffff8800db9ffc50 -|Call Trace: -| [] dump_stack+0x4e/0x8f -| [] __might_sleep+0x112/0x190 -| [] rt_spin_lock+0x24/0x60 -| [] hid_ctrl+0x3b/0x190 -| [] __usb_hcd_giveback_urb+0x4f/0xc0 -| [] usb_hcd_giveback_urb+0x3f/0x140 -| [] uhci_giveback_urb+0xaf/0x280 -| [] uhci_scan_schedule+0x47a/0xb10 -| [] uhci_irq+0xa6/0x1a0 -| [] usb_hcd_irq+0x28/0x40 -| [] irq_forced_thread_fn+0x23/0x70 -| [] irq_thread+0x10f/0x150 -| [] kthread+0xcd/0xe0 -| [] ret_from_fork+0x7c/0xb0 - -on -RT we run threaded so no need to disable interrupts. - -Signed-off-by: Sebastian Andrzej Siewior ---- - drivers/usb/core/hcd.c | 4 ++-- - 1 file changed, 2 insertions(+), 2 deletions(-) - -diff --git a/drivers/usb/core/hcd.c b/drivers/usb/core/hcd.c -index d0b2e0ed9bab..91f4f2bd55b0 100644 ---- a/drivers/usb/core/hcd.c -+++ b/drivers/usb/core/hcd.c -@@ -1775,9 +1775,9 @@ static void __usb_hcd_giveback_urb(struct urb *urb) - * and no one may trigger the above deadlock situation when - * running complete() in tasklet. - */ -- local_irq_save(flags); -+ local_irq_save_nort(flags); - urb->complete(urb); -- local_irq_restore(flags); -+ local_irq_restore_nort(flags); - - usb_anchor_resume_wakeups(anchor); - atomic_dec(&urb->use_count); --- -2.19.2 - diff --git a/kernel/patches-4.14.x-rt/0158-mm-workingset-Do-not-protect-workingset_shadow_nodes.patch b/kernel/patches-4.14.x-rt/0158-mm-workingset-Do-not-protect-workingset_shadow_nodes.patch deleted file mode 100644 index 7f6bba95d..000000000 --- a/kernel/patches-4.14.x-rt/0158-mm-workingset-Do-not-protect-workingset_shadow_nodes.patch +++ /dev/null @@ -1,196 +0,0 @@ -From 3ea1ded21463a93bb065b5f50e6d391b0ec3f891 Mon Sep 17 00:00:00 2001 -From: Sebastian Andrzej Siewior -Date: Thu, 29 Jan 2015 17:19:44 +0100 -Subject: [PATCH 158/450] mm/workingset: Do not protect workingset_shadow_nodes - with irq off - -workingset_shadow_nodes is protected by local_irq_disable(). Some users -use spin_lock_irq(). -Replace the irq/on with a local_lock(). Rename workingset_shadow_nodes -so I catch users of it which will be introduced later. - -Signed-off-by: Sebastian Andrzej Siewior ---- - include/linux/swap.h | 4 +++- - mm/filemap.c | 9 +++++++-- - mm/truncate.c | 4 +++- - mm/workingset.c | 31 ++++++++++++++++--------------- - 4 files changed, 29 insertions(+), 19 deletions(-) - -diff --git a/include/linux/swap.h b/include/linux/swap.h -index f02fb5db8914..aff4f8309f6b 100644 ---- a/include/linux/swap.h -+++ b/include/linux/swap.h -@@ -12,6 +12,7 @@ - #include - #include - #include -+#include - #include - - struct notifier_block; -@@ -297,7 +298,8 @@ struct vma_swap_readahead { - void *workingset_eviction(struct address_space *mapping, struct page *page); - bool workingset_refault(void *shadow); - void workingset_activation(struct page *page); --void workingset_update_node(struct radix_tree_node *node, void *private); -+void __workingset_update_node(struct radix_tree_node *node, void *private); -+DECLARE_LOCAL_IRQ_LOCK(shadow_nodes_lock); - - /* linux/mm/page_alloc.c */ - extern unsigned long totalram_pages; -diff --git a/mm/filemap.c b/mm/filemap.c -index e2e738cc08b1..c47070dae8b9 100644 ---- a/mm/filemap.c -+++ b/mm/filemap.c -@@ -110,6 +110,7 @@ - * ->i_mmap_rwsem - * ->tasklist_lock (memory_failure, collect_procs_ao) - */ -+DECLARE_LOCAL_IRQ_LOCK(shadow_nodes_lock); - - static int page_cache_tree_insert(struct address_space *mapping, - struct page *page, void **shadowp) -@@ -133,8 +134,10 @@ static int page_cache_tree_insert(struct address_space *mapping, - if (shadowp) - *shadowp = p; - } -+ local_lock(shadow_nodes_lock); - __radix_tree_replace(&mapping->page_tree, node, slot, page, -- workingset_update_node, mapping); -+ __workingset_update_node, mapping); -+ local_unlock(shadow_nodes_lock); - mapping->nrpages++; - return 0; - } -@@ -151,6 +154,7 @@ static void page_cache_tree_delete(struct address_space *mapping, - VM_BUG_ON_PAGE(PageTail(page), page); - VM_BUG_ON_PAGE(nr != 1 && shadow, page); - -+ local_lock(shadow_nodes_lock); - for (i = 0; i < nr; i++) { - struct radix_tree_node *node; - void **slot; -@@ -162,8 +166,9 @@ static void page_cache_tree_delete(struct address_space *mapping, - - radix_tree_clear_tags(&mapping->page_tree, node, slot); - __radix_tree_replace(&mapping->page_tree, node, slot, shadow, -- workingset_update_node, mapping); -+ __workingset_update_node, mapping); - } -+ local_unlock(shadow_nodes_lock); - - if (shadow) { - mapping->nrexceptional += nr; -diff --git a/mm/truncate.c b/mm/truncate.c -index d3a2737cc188..a25891e3d066 100644 ---- a/mm/truncate.c -+++ b/mm/truncate.c -@@ -41,8 +41,10 @@ static void clear_shadow_entry(struct address_space *mapping, pgoff_t index, - goto unlock; - if (*slot != entry) - goto unlock; -+ local_lock(shadow_nodes_lock); - __radix_tree_replace(&mapping->page_tree, node, slot, NULL, -- workingset_update_node, mapping); -+ __workingset_update_node, mapping); -+ local_unlock(shadow_nodes_lock); - mapping->nrexceptional--; - unlock: - spin_unlock_irq(&mapping->tree_lock); -diff --git a/mm/workingset.c b/mm/workingset.c -index b997c9de28f6..e252cc69a3d4 100644 ---- a/mm/workingset.c -+++ b/mm/workingset.c -@@ -338,9 +338,10 @@ void workingset_activation(struct page *page) - * point where they would still be useful. - */ - --static struct list_lru shadow_nodes; -+static struct list_lru __shadow_nodes; -+DEFINE_LOCAL_IRQ_LOCK(shadow_nodes_lock); - --void workingset_update_node(struct radix_tree_node *node, void *private) -+void __workingset_update_node(struct radix_tree_node *node, void *private) - { - struct address_space *mapping = private; - -@@ -358,10 +359,10 @@ void workingset_update_node(struct radix_tree_node *node, void *private) - */ - if (node->count && node->count == node->exceptional) { - if (list_empty(&node->private_list)) -- list_lru_add(&shadow_nodes, &node->private_list); -+ list_lru_add(&__shadow_nodes, &node->private_list); - } else { - if (!list_empty(&node->private_list)) -- list_lru_del(&shadow_nodes, &node->private_list); -+ list_lru_del(&__shadow_nodes, &node->private_list); - } - } - -@@ -373,9 +374,9 @@ static unsigned long count_shadow_nodes(struct shrinker *shrinker, - unsigned long cache; - - /* list_lru lock nests inside IRQ-safe mapping->tree_lock */ -- local_irq_disable(); -- nodes = list_lru_shrink_count(&shadow_nodes, sc); -- local_irq_enable(); -+ local_lock_irq(shadow_nodes_lock); -+ nodes = list_lru_shrink_count(&__shadow_nodes, sc); -+ local_unlock_irq(shadow_nodes_lock); - - /* - * Approximate a reasonable limit for the radix tree nodes -@@ -475,15 +476,15 @@ static enum lru_status shadow_lru_isolate(struct list_head *item, - goto out_invalid; - inc_lruvec_page_state(virt_to_page(node), WORKINGSET_NODERECLAIM); - __radix_tree_delete_node(&mapping->page_tree, node, -- workingset_update_node, mapping); -+ __workingset_update_node, mapping); - - out_invalid: - spin_unlock(&mapping->tree_lock); - ret = LRU_REMOVED_RETRY; - out: -- local_irq_enable(); -+ local_unlock_irq(shadow_nodes_lock); - cond_resched(); -- local_irq_disable(); -+ local_lock_irq(shadow_nodes_lock); - spin_lock(lru_lock); - return ret; - } -@@ -494,9 +495,9 @@ static unsigned long scan_shadow_nodes(struct shrinker *shrinker, - unsigned long ret; - - /* list_lru lock nests inside IRQ-safe mapping->tree_lock */ -- local_irq_disable(); -- ret = list_lru_shrink_walk(&shadow_nodes, sc, shadow_lru_isolate, NULL); -- local_irq_enable(); -+ local_lock_irq(shadow_nodes_lock); -+ ret = list_lru_shrink_walk(&__shadow_nodes, sc, shadow_lru_isolate, NULL); -+ local_unlock_irq(shadow_nodes_lock); - return ret; - } - -@@ -534,7 +535,7 @@ static int __init workingset_init(void) - pr_info("workingset: timestamp_bits=%d max_order=%d bucket_order=%u\n", - timestamp_bits, max_order, bucket_order); - -- ret = __list_lru_init(&shadow_nodes, true, &shadow_nodes_key); -+ ret = __list_lru_init(&__shadow_nodes, true, &shadow_nodes_key); - if (ret) - goto err; - ret = register_shrinker(&workingset_shadow_shrinker); -@@ -542,7 +543,7 @@ static int __init workingset_init(void) - goto err_list_lru; - return 0; - err_list_lru: -- list_lru_destroy(&shadow_nodes); -+ list_lru_destroy(&__shadow_nodes); - err: - return ret; - } --- -2.19.2 - diff --git a/kernel/patches-4.14.x-rt/0159-signal-Make-__lock_task_sighand-RT-aware.patch b/kernel/patches-4.14.x-rt/0159-signal-Make-__lock_task_sighand-RT-aware.patch deleted file mode 100644 index b2a0ad551..000000000 --- a/kernel/patches-4.14.x-rt/0159-signal-Make-__lock_task_sighand-RT-aware.patch +++ /dev/null @@ -1,44 +0,0 @@ -From ec5ba6046970ae761880bcaa018816a13370ccff Mon Sep 17 00:00:00 2001 -From: Thomas Gleixner -Date: Fri, 22 Jul 2011 08:07:08 +0200 -Subject: [PATCH 159/450] signal: Make __lock_task_sighand() RT aware - -local_irq_save() + spin_lock(&sighand->siglock) does not work on --RT. Use the nort variants. - -Signed-off-by: Thomas Gleixner ---- - kernel/signal.c | 6 +++--- - 1 file changed, 3 insertions(+), 3 deletions(-) - -diff --git a/kernel/signal.c b/kernel/signal.c -index ca7de0d8a4bd..374d60ea3699 100644 ---- a/kernel/signal.c -+++ b/kernel/signal.c -@@ -1301,12 +1301,12 @@ struct sighand_struct *__lock_task_sighand(struct task_struct *tsk, - * Disable interrupts early to avoid deadlocks. - * See rcu_read_unlock() comment header for details. - */ -- local_irq_save(*flags); -+ local_irq_save_nort(*flags); - rcu_read_lock(); - sighand = rcu_dereference(tsk->sighand); - if (unlikely(sighand == NULL)) { - rcu_read_unlock(); -- local_irq_restore(*flags); -+ local_irq_restore_nort(*flags); - break; - } - /* -@@ -1327,7 +1327,7 @@ struct sighand_struct *__lock_task_sighand(struct task_struct *tsk, - } - spin_unlock(&sighand->siglock); - rcu_read_unlock(); -- local_irq_restore(*flags); -+ local_irq_restore_nort(*flags); - } - - return sighand; --- -2.19.2 - diff --git a/kernel/patches-4.14.x-rt/0162-net-wireless-Use-WARN_ON_NORT.patch b/kernel/patches-4.14.x-rt/0162-net-wireless-Use-WARN_ON_NORT.patch deleted file mode 100644 index c24ff7d35..000000000 --- a/kernel/patches-4.14.x-rt/0162-net-wireless-Use-WARN_ON_NORT.patch +++ /dev/null @@ -1,29 +0,0 @@ -From e67f22f5ef343a0b326e6c4dbe735c50c43fa69e Mon Sep 17 00:00:00 2001 -From: Thomas Gleixner -Date: Thu, 21 Jul 2011 21:05:33 +0200 -Subject: [PATCH 162/450] net/wireless: Use WARN_ON_NORT() - -The softirq counter is meaningless on RT, so the check triggers a -false positive. - -Signed-off-by: Thomas Gleixner ---- - net/mac80211/rx.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/net/mac80211/rx.c b/net/mac80211/rx.c -index dddd498e1338..8f39b8162df8 100644 ---- a/net/mac80211/rx.c -+++ b/net/mac80211/rx.c -@@ -4252,7 +4252,7 @@ void ieee80211_rx_napi(struct ieee80211_hw *hw, struct ieee80211_sta *pubsta, - struct ieee80211_supported_band *sband; - struct ieee80211_rx_status *status = IEEE80211_SKB_RXCB(skb); - -- WARN_ON_ONCE(softirq_count() == 0); -+ WARN_ON_ONCE_NONRT(softirq_count() == 0); - - if (WARN_ON(status->band >= NUM_NL80211_BANDS)) - goto drop; --- -2.19.2 - diff --git a/kernel/patches-4.14.x-rt/0168-genirq-Force-interrupt-thread-on-RT.patch b/kernel/patches-4.14.x-rt/0168-genirq-Force-interrupt-thread-on-RT.patch deleted file mode 100644 index d80be5de1..000000000 --- a/kernel/patches-4.14.x-rt/0168-genirq-Force-interrupt-thread-on-RT.patch +++ /dev/null @@ -1,56 +0,0 @@ -From 2d09d245af35a2bb5b8ca6f92a26caf052e38ff6 Mon Sep 17 00:00:00 2001 -From: Thomas Gleixner -Date: Sun, 3 Apr 2011 11:57:29 +0200 -Subject: [PATCH 168/450] genirq: Force interrupt thread on RT - -Force threaded_irqs and optimize the code (force_irqthreads) in regard -to this. - -Signed-off-by: Thomas Gleixner ---- - include/linux/interrupt.h | 6 +++++- - kernel/irq/manage.c | 2 ++ - 2 files changed, 7 insertions(+), 1 deletion(-) - -diff --git a/include/linux/interrupt.h b/include/linux/interrupt.h -index 2957da07e967..2395ebb443b9 100644 ---- a/include/linux/interrupt.h -+++ b/include/linux/interrupt.h -@@ -429,9 +429,13 @@ extern int irq_set_irqchip_state(unsigned int irq, enum irqchip_irq_state which, - bool state); - - #ifdef CONFIG_IRQ_FORCED_THREADING -+# ifndef CONFIG_PREEMPT_RT_BASE - extern bool force_irqthreads; -+# else -+# define force_irqthreads (true) -+# endif - #else --#define force_irqthreads (0) -+#define force_irqthreads (false) - #endif - - #ifndef __ARCH_SET_SOFTIRQ_PENDING -diff --git a/kernel/irq/manage.c b/kernel/irq/manage.c -index 4cd85870f00e..f9934b6d879e 100644 ---- a/kernel/irq/manage.c -+++ b/kernel/irq/manage.c -@@ -24,6 +24,7 @@ - #include "internals.h" - - #ifdef CONFIG_IRQ_FORCED_THREADING -+# ifndef CONFIG_PREEMPT_RT_BASE - __read_mostly bool force_irqthreads; - - static int __init setup_forced_irqthreads(char *arg) -@@ -32,6 +33,7 @@ static int __init setup_forced_irqthreads(char *arg) - return 0; - } - early_param("threadirqs", setup_forced_irqthreads); -+# endif - #endif - - static void __synchronize_hardirq(struct irq_desc *desc) --- -2.19.2 - diff --git a/kernel/patches-4.14.x-rt/0169-drivers-net-vortex-fix-locking-issues.patch b/kernel/patches-4.14.x-rt/0169-drivers-net-vortex-fix-locking-issues.patch deleted file mode 100644 index 09e1c5b64..000000000 --- a/kernel/patches-4.14.x-rt/0169-drivers-net-vortex-fix-locking-issues.patch +++ /dev/null @@ -1,57 +0,0 @@ -From 4ee19b026a3e2b969b5da2f55cfee5122768a715 Mon Sep 17 00:00:00 2001 -From: Steven Rostedt -Date: Fri, 3 Jul 2009 08:30:00 -0500 -Subject: [PATCH 169/450] drivers/net: vortex fix locking issues - -Argh, cut and paste wasn't enough... - -Use this patch instead. It needs an irq disable. But, believe it or not, -on SMP this is actually better. If the irq is shared (as it is in Mark's -case), we don't stop the irq of other devices from being handled on -another CPU (unfortunately for Mark, he pinned all interrupts to one CPU). - -Signed-off-by: Steven Rostedt -Signed-off-by: Thomas Gleixner - - drivers/net/ethernet/3com/3c59x.c | 8 ++++---- - 1 file changed, 4 insertions(+), 4 deletions(-) - -Signed-off-by: Ingo Molnar ---- - drivers/net/ethernet/3com/3c59x.c | 8 ++++---- - 1 file changed, 4 insertions(+), 4 deletions(-) - -diff --git a/drivers/net/ethernet/3com/3c59x.c b/drivers/net/ethernet/3com/3c59x.c -index 402d9090ad29..9bc02563b853 100644 ---- a/drivers/net/ethernet/3com/3c59x.c -+++ b/drivers/net/ethernet/3com/3c59x.c -@@ -842,9 +842,9 @@ static void poll_vortex(struct net_device *dev) - { - struct vortex_private *vp = netdev_priv(dev); - unsigned long flags; -- local_irq_save(flags); -+ local_irq_save_nort(flags); - (vp->full_bus_master_rx ? boomerang_interrupt:vortex_interrupt)(dev->irq,dev); -- local_irq_restore(flags); -+ local_irq_restore_nort(flags); - } - #endif - -@@ -1908,12 +1908,12 @@ static void vortex_tx_timeout(struct net_device *dev) - * Block interrupts because vortex_interrupt does a bare spin_lock() - */ - unsigned long flags; -- local_irq_save(flags); -+ local_irq_save_nort(flags); - if (vp->full_bus_master_tx) - boomerang_interrupt(dev->irq, dev); - else - vortex_interrupt(dev->irq, dev); -- local_irq_restore(flags); -+ local_irq_restore_nort(flags); - } - } - --- -2.19.2 - diff --git a/kernel/patches-4.14.x-rt/0171-mm-page_alloc-Reduce-lock-sections-further.patch b/kernel/patches-4.14.x-rt/0171-mm-page_alloc-Reduce-lock-sections-further.patch deleted file mode 100644 index d5c8e797e..000000000 --- a/kernel/patches-4.14.x-rt/0171-mm-page_alloc-Reduce-lock-sections-further.patch +++ /dev/null @@ -1,203 +0,0 @@ -From 1e26ee0addd811f0636a8102a08e24950acc413d Mon Sep 17 00:00:00 2001 -From: Peter Zijlstra -Date: Fri, 3 Jul 2009 08:44:37 -0500 -Subject: [PATCH 171/450] mm: page_alloc: Reduce lock sections further - -Split out the pages which are to be freed into a separate list and -call free_pages_bulk() outside of the percpu page allocator locks. - -Signed-off-by: Peter Zijlstra -Signed-off-by: Thomas Gleixner ---- - mm/page_alloc.c | 93 ++++++++++++++++++++++++++++++++++--------------- - 1 file changed, 65 insertions(+), 28 deletions(-) - -diff --git a/mm/page_alloc.c b/mm/page_alloc.c -index 7316ae31df8e..ca19f55de422 100644 ---- a/mm/page_alloc.c -+++ b/mm/page_alloc.c -@@ -1107,7 +1107,7 @@ static bool bulkfree_pcp_prepare(struct page *page) - #endif /* CONFIG_DEBUG_VM */ - - /* -- * Frees a number of pages from the PCP lists -+ * Frees a number of pages which have been collected from the pcp lists. - * Assumes all pages on list are in same zone, and of same order. - * count is the number of pages to free. - * -@@ -1118,15 +1118,53 @@ static bool bulkfree_pcp_prepare(struct page *page) - * pinned" detection logic. - */ - static void free_pcppages_bulk(struct zone *zone, int count, -- struct per_cpu_pages *pcp) -+ struct list_head *list) - { -- int migratetype = 0; -- int batch_free = 0; - bool isolated_pageblocks; -+ unsigned long flags; - -- spin_lock(&zone->lock); -+ spin_lock_irqsave(&zone->lock, flags); - isolated_pageblocks = has_isolate_pageblock(zone); - -+ while (!list_empty(list)) { -+ struct page *page; -+ int mt; /* migratetype of the to-be-freed page */ -+ -+ page = list_first_entry(list, struct page, lru); -+ /* must delete as __free_one_page list manipulates */ -+ list_del(&page->lru); -+ -+ mt = get_pcppage_migratetype(page); -+ /* MIGRATE_ISOLATE page should not go to pcplists */ -+ VM_BUG_ON_PAGE(is_migrate_isolate(mt), page); -+ /* Pageblock could have been isolated meanwhile */ -+ if (unlikely(isolated_pageblocks)) -+ mt = get_pageblock_migratetype(page); -+ -+ if (bulkfree_pcp_prepare(page)) -+ continue; -+ -+ __free_one_page(page, page_to_pfn(page), zone, 0, mt); -+ trace_mm_page_pcpu_drain(page, 0, mt); -+ count--; -+ } -+ WARN_ON(count != 0); -+ spin_unlock_irqrestore(&zone->lock, flags); -+} -+ -+/* -+ * Moves a number of pages from the PCP lists to free list which -+ * is freed outside of the locked region. -+ * -+ * Assumes all pages on list are in same zone, and of same order. -+ * count is the number of pages to free. -+ */ -+static void isolate_pcp_pages(int count, struct per_cpu_pages *src, -+ struct list_head *dst) -+{ -+ int migratetype = 0; -+ int batch_free = 0; -+ - while (count) { - struct page *page; - struct list_head *list; -@@ -1142,7 +1180,7 @@ static void free_pcppages_bulk(struct zone *zone, int count, - batch_free++; - if (++migratetype == MIGRATE_PCPTYPES) - migratetype = 0; -- list = &pcp->lists[migratetype]; -+ list = &src->lists[migratetype]; - } while (list_empty(list)); - - /* This is the only non-empty list. Free them all. */ -@@ -1150,27 +1188,12 @@ static void free_pcppages_bulk(struct zone *zone, int count, - batch_free = count; - - do { -- int mt; /* migratetype of the to-be-freed page */ -- - page = list_last_entry(list, struct page, lru); -- /* must delete as __free_one_page list manipulates */ - list_del(&page->lru); - -- mt = get_pcppage_migratetype(page); -- /* MIGRATE_ISOLATE page should not go to pcplists */ -- VM_BUG_ON_PAGE(is_migrate_isolate(mt), page); -- /* Pageblock could have been isolated meanwhile */ -- if (unlikely(isolated_pageblocks)) -- mt = get_pageblock_migratetype(page); -- -- if (bulkfree_pcp_prepare(page)) -- continue; -- -- __free_one_page(page, page_to_pfn(page), zone, 0, mt); -- trace_mm_page_pcpu_drain(page, 0, mt); -+ list_add(&page->lru, dst); - } while (--count && --batch_free && !list_empty(list)); - } -- spin_unlock(&zone->lock); - } - - static void free_one_page(struct zone *zone, -@@ -1178,13 +1201,15 @@ static void free_one_page(struct zone *zone, - unsigned int order, - int migratetype) - { -- spin_lock(&zone->lock); -+ unsigned long flags; -+ -+ spin_lock_irqsave(&zone->lock, flags); - if (unlikely(has_isolate_pageblock(zone) || - is_migrate_isolate(migratetype))) { - migratetype = get_pfnblock_migratetype(page, pfn); - } - __free_one_page(page, pfn, zone, order, migratetype); -- spin_unlock(&zone->lock); -+ spin_unlock_irqrestore(&zone->lock, flags); - } - - static void __meminit __init_single_page(struct page *page, unsigned long pfn, -@@ -2391,16 +2416,18 @@ static int rmqueue_bulk(struct zone *zone, unsigned int order, - void drain_zone_pages(struct zone *zone, struct per_cpu_pages *pcp) - { - unsigned long flags; -+ LIST_HEAD(dst); - int to_drain, batch; - - local_lock_irqsave(pa_lock, flags); - batch = READ_ONCE(pcp->batch); - to_drain = min(pcp->count, batch); - if (to_drain > 0) { -- free_pcppages_bulk(zone, to_drain, pcp); -+ isolate_pcp_pages(to_drain, pcp, &dst); - pcp->count -= to_drain; - } - local_unlock_irqrestore(pa_lock, flags); -+ free_pcppages_bulk(zone, to_drain, &dst); - } - #endif - -@@ -2416,16 +2443,21 @@ static void drain_pages_zone(unsigned int cpu, struct zone *zone) - unsigned long flags; - struct per_cpu_pageset *pset; - struct per_cpu_pages *pcp; -+ LIST_HEAD(dst); -+ int count; - - cpu_lock_irqsave(cpu, flags); - pset = per_cpu_ptr(zone->pageset, cpu); - - pcp = &pset->pcp; -- if (pcp->count) { -- free_pcppages_bulk(zone, pcp->count, pcp); -+ count = pcp->count; -+ if (count) { -+ isolate_pcp_pages(count, pcp, &dst); - pcp->count = 0; - } - cpu_unlock_irqrestore(cpu, flags); -+ if (count) -+ free_pcppages_bulk(zone, count, &dst); - } - - /* -@@ -2659,8 +2691,13 @@ void free_hot_cold_page(struct page *page, bool cold) - pcp->count++; - if (pcp->count >= pcp->high) { - unsigned long batch = READ_ONCE(pcp->batch); -- free_pcppages_bulk(zone, batch, pcp); -+ LIST_HEAD(dst); -+ -+ isolate_pcp_pages(batch, pcp, &dst); - pcp->count -= batch; -+ local_unlock_irqrestore(pa_lock, flags); -+ free_pcppages_bulk(zone, batch, &dst); -+ return; - } - - out: --- -2.19.2 - diff --git a/kernel/patches-4.14.x-rt/0176-mm-bounce-Use-local_irq_save_nort.patch b/kernel/patches-4.14.x-rt/0176-mm-bounce-Use-local_irq_save_nort.patch deleted file mode 100644 index ebcc828f5..000000000 --- a/kernel/patches-4.14.x-rt/0176-mm-bounce-Use-local_irq_save_nort.patch +++ /dev/null @@ -1,33 +0,0 @@ -From 29e584d8a8a04c5531c3a2e0dfcad995b880848e Mon Sep 17 00:00:00 2001 -From: Thomas Gleixner -Date: Wed, 9 Jan 2013 10:33:09 +0100 -Subject: [PATCH 176/450] mm: bounce: Use local_irq_save_nort - -kmap_atomic() is preemptible on RT. - -Signed-off-by: Thomas Gleixner ---- - block/bounce.c | 4 ++-- - 1 file changed, 2 insertions(+), 2 deletions(-) - -diff --git a/block/bounce.c b/block/bounce.c -index 1d05c422c932..0101ffefddc4 100644 ---- a/block/bounce.c -+++ b/block/bounce.c -@@ -66,11 +66,11 @@ static void bounce_copy_vec(struct bio_vec *to, unsigned char *vfrom) - unsigned long flags; - unsigned char *vto; - -- local_irq_save(flags); -+ local_irq_save_nort(flags); - vto = kmap_atomic(to->bv_page); - memcpy(vto + to->bv_offset, vfrom, to->bv_len); - kunmap_atomic(vto); -- local_irq_restore(flags); -+ local_irq_restore_nort(flags); - } - - #else /* CONFIG_HIGHMEM */ --- -2.19.2 - diff --git a/kernel/patches-4.14.x-rt/0178-mm-Enable-SLUB-for-RT.patch b/kernel/patches-4.14.x-rt/0178-mm-Enable-SLUB-for-RT.patch deleted file mode 100644 index f4309210c..000000000 --- a/kernel/patches-4.14.x-rt/0178-mm-Enable-SLUB-for-RT.patch +++ /dev/null @@ -1,481 +0,0 @@ -From 1c78e1ec776c9a4b04e302110f3eee2ab5ef22b8 Mon Sep 17 00:00:00 2001 -From: Thomas Gleixner -Date: Thu, 25 Oct 2012 10:32:35 +0100 -Subject: [PATCH 178/450] mm: Enable SLUB for RT - -Make SLUB RT aware by converting locks to raw and using free lists to -move the freeing out of the lock held region. - -Signed-off-by: Thomas Gleixner ---- - mm/slab.h | 4 ++ - mm/slub.c | 136 ++++++++++++++++++++++++++++++++++++++++++------------ - 2 files changed, 110 insertions(+), 30 deletions(-) - -diff --git a/mm/slab.h b/mm/slab.h -index 485d9fbb8802..f3b06c48bf39 100644 ---- a/mm/slab.h -+++ b/mm/slab.h -@@ -451,7 +451,11 @@ static inline void slab_post_alloc_hook(struct kmem_cache *s, gfp_t flags, - * The slab lists for all objects. - */ - struct kmem_cache_node { -+#ifdef CONFIG_SLUB -+ raw_spinlock_t list_lock; -+#else - spinlock_t list_lock; -+#endif - - #ifdef CONFIG_SLAB - struct list_head slabs_partial; /* partial list first, better asm code */ -diff --git a/mm/slub.c b/mm/slub.c -index 220d42e592ef..2f9f5e133587 100644 ---- a/mm/slub.c -+++ b/mm/slub.c -@@ -1179,7 +1179,7 @@ static noinline int free_debug_processing( - unsigned long uninitialized_var(flags); - int ret = 0; - -- spin_lock_irqsave(&n->list_lock, flags); -+ raw_spin_lock_irqsave(&n->list_lock, flags); - slab_lock(page); - - if (s->flags & SLAB_CONSISTENCY_CHECKS) { -@@ -1214,7 +1214,7 @@ static noinline int free_debug_processing( - bulk_cnt, cnt); - - slab_unlock(page); -- spin_unlock_irqrestore(&n->list_lock, flags); -+ raw_spin_unlock_irqrestore(&n->list_lock, flags); - if (!ret) - slab_fix(s, "Object at 0x%p not freed", object); - return ret; -@@ -1342,6 +1342,12 @@ static inline void dec_slabs_node(struct kmem_cache *s, int node, - - #endif /* CONFIG_SLUB_DEBUG */ - -+struct slub_free_list { -+ raw_spinlock_t lock; -+ struct list_head list; -+}; -+static DEFINE_PER_CPU(struct slub_free_list, slub_free_list); -+ - /* - * Hooks for other subsystems that check memory allocations. In a typical - * production configuration these hooks all should produce no code at all. -@@ -1564,7 +1570,11 @@ static struct page *allocate_slab(struct kmem_cache *s, gfp_t flags, int node) - - flags &= gfp_allowed_mask; - -+#ifdef CONFIG_PREEMPT_RT_FULL -+ if (system_state > SYSTEM_BOOTING) -+#else - if (gfpflags_allow_blocking(flags)) -+#endif - local_irq_enable(); - - flags |= s->allocflags; -@@ -1623,7 +1633,11 @@ static struct page *allocate_slab(struct kmem_cache *s, gfp_t flags, int node) - page->frozen = 1; - - out: -+#ifdef CONFIG_PREEMPT_RT_FULL -+ if (system_state > SYSTEM_BOOTING) -+#else - if (gfpflags_allow_blocking(flags)) -+#endif - local_irq_disable(); - if (!page) - return NULL; -@@ -1681,6 +1695,16 @@ static void __free_slab(struct kmem_cache *s, struct page *page) - __free_pages(page, order); - } - -+static void free_delayed(struct list_head *h) -+{ -+ while(!list_empty(h)) { -+ struct page *page = list_first_entry(h, struct page, lru); -+ -+ list_del(&page->lru); -+ __free_slab(page->slab_cache, page); -+ } -+} -+ - #define need_reserve_slab_rcu \ - (sizeof(((struct page *)NULL)->lru) < sizeof(struct rcu_head)) - -@@ -1712,6 +1736,12 @@ static void free_slab(struct kmem_cache *s, struct page *page) - } - - call_rcu(head, rcu_free_slab); -+ } else if (irqs_disabled()) { -+ struct slub_free_list *f = this_cpu_ptr(&slub_free_list); -+ -+ raw_spin_lock(&f->lock); -+ list_add(&page->lru, &f->list); -+ raw_spin_unlock(&f->lock); - } else - __free_slab(s, page); - } -@@ -1819,7 +1849,7 @@ static void *get_partial_node(struct kmem_cache *s, struct kmem_cache_node *n, - if (!n || !n->nr_partial) - return NULL; - -- spin_lock(&n->list_lock); -+ raw_spin_lock(&n->list_lock); - list_for_each_entry_safe(page, page2, &n->partial, lru) { - void *t; - -@@ -1844,7 +1874,7 @@ static void *get_partial_node(struct kmem_cache *s, struct kmem_cache_node *n, - break; - - } -- spin_unlock(&n->list_lock); -+ raw_spin_unlock(&n->list_lock); - return object; - } - -@@ -2090,7 +2120,7 @@ static void deactivate_slab(struct kmem_cache *s, struct page *page, - * that acquire_slab() will see a slab page that - * is frozen - */ -- spin_lock(&n->list_lock); -+ raw_spin_lock(&n->list_lock); - } - } else { - m = M_FULL; -@@ -2101,7 +2131,7 @@ static void deactivate_slab(struct kmem_cache *s, struct page *page, - * slabs from diagnostic functions will not see - * any frozen slabs. - */ -- spin_lock(&n->list_lock); -+ raw_spin_lock(&n->list_lock); - } - } - -@@ -2136,7 +2166,7 @@ static void deactivate_slab(struct kmem_cache *s, struct page *page, - goto redo; - - if (lock) -- spin_unlock(&n->list_lock); -+ raw_spin_unlock(&n->list_lock); - - if (m == M_FREE) { - stat(s, DEACTIVATE_EMPTY); -@@ -2171,10 +2201,10 @@ static void unfreeze_partials(struct kmem_cache *s, - n2 = get_node(s, page_to_nid(page)); - if (n != n2) { - if (n) -- spin_unlock(&n->list_lock); -+ raw_spin_unlock(&n->list_lock); - - n = n2; -- spin_lock(&n->list_lock); -+ raw_spin_lock(&n->list_lock); - } - - do { -@@ -2203,7 +2233,7 @@ static void unfreeze_partials(struct kmem_cache *s, - } - - if (n) -- spin_unlock(&n->list_lock); -+ raw_spin_unlock(&n->list_lock); - - while (discard_page) { - page = discard_page; -@@ -2242,14 +2272,21 @@ static void put_cpu_partial(struct kmem_cache *s, struct page *page, int drain) - pobjects = oldpage->pobjects; - pages = oldpage->pages; - if (drain && pobjects > s->cpu_partial) { -+ struct slub_free_list *f; - unsigned long flags; -+ LIST_HEAD(tofree); - /* - * partial array is full. Move the existing - * set to the per node partial list. - */ - local_irq_save(flags); - unfreeze_partials(s, this_cpu_ptr(s->cpu_slab)); -+ f = this_cpu_ptr(&slub_free_list); -+ raw_spin_lock(&f->lock); -+ list_splice_init(&f->list, &tofree); -+ raw_spin_unlock(&f->lock); - local_irq_restore(flags); -+ free_delayed(&tofree); - oldpage = NULL; - pobjects = 0; - pages = 0; -@@ -2319,7 +2356,22 @@ static bool has_cpu_slab(int cpu, void *info) - - static void flush_all(struct kmem_cache *s) - { -+ LIST_HEAD(tofree); -+ int cpu; -+ - on_each_cpu_cond(has_cpu_slab, flush_cpu_slab, s, 1, GFP_ATOMIC); -+ for_each_online_cpu(cpu) { -+ struct slub_free_list *f; -+ -+ if (!has_cpu_slab(cpu, s)) -+ continue; -+ -+ f = &per_cpu(slub_free_list, cpu); -+ raw_spin_lock_irq(&f->lock); -+ list_splice_init(&f->list, &tofree); -+ raw_spin_unlock_irq(&f->lock); -+ free_delayed(&tofree); -+ } - } - - /* -@@ -2374,10 +2426,10 @@ static unsigned long count_partial(struct kmem_cache_node *n, - unsigned long x = 0; - struct page *page; - -- spin_lock_irqsave(&n->list_lock, flags); -+ raw_spin_lock_irqsave(&n->list_lock, flags); - list_for_each_entry(page, &n->partial, lru) - x += get_count(page); -- spin_unlock_irqrestore(&n->list_lock, flags); -+ raw_spin_unlock_irqrestore(&n->list_lock, flags); - return x; - } - #endif /* CONFIG_SLUB_DEBUG || CONFIG_SYSFS */ -@@ -2515,8 +2567,10 @@ static inline void *get_freelist(struct kmem_cache *s, struct page *page) - * already disabled (which is the case for bulk allocation). - */ - static void *___slab_alloc(struct kmem_cache *s, gfp_t gfpflags, int node, -- unsigned long addr, struct kmem_cache_cpu *c) -+ unsigned long addr, struct kmem_cache_cpu *c, -+ struct list_head *to_free) - { -+ struct slub_free_list *f; - void *freelist; - struct page *page; - -@@ -2572,6 +2626,13 @@ static void *___slab_alloc(struct kmem_cache *s, gfp_t gfpflags, int node, - VM_BUG_ON(!c->page->frozen); - c->freelist = get_freepointer(s, freelist); - c->tid = next_tid(c->tid); -+ -+out: -+ f = this_cpu_ptr(&slub_free_list); -+ raw_spin_lock(&f->lock); -+ list_splice_init(&f->list, to_free); -+ raw_spin_unlock(&f->lock); -+ - return freelist; - - new_slab: -@@ -2587,7 +2648,7 @@ static void *___slab_alloc(struct kmem_cache *s, gfp_t gfpflags, int node, - - if (unlikely(!freelist)) { - slab_out_of_memory(s, gfpflags, node); -- return NULL; -+ goto out; - } - - page = c->page; -@@ -2600,7 +2661,7 @@ static void *___slab_alloc(struct kmem_cache *s, gfp_t gfpflags, int node, - goto new_slab; /* Slab failed checks. Next slab needed */ - - deactivate_slab(s, page, get_freepointer(s, freelist), c); -- return freelist; -+ goto out; - } - - /* -@@ -2612,6 +2673,7 @@ static void *__slab_alloc(struct kmem_cache *s, gfp_t gfpflags, int node, - { - void *p; - unsigned long flags; -+ LIST_HEAD(tofree); - - local_irq_save(flags); - #ifdef CONFIG_PREEMPT -@@ -2623,8 +2685,9 @@ static void *__slab_alloc(struct kmem_cache *s, gfp_t gfpflags, int node, - c = this_cpu_ptr(s->cpu_slab); - #endif - -- p = ___slab_alloc(s, gfpflags, node, addr, c); -+ p = ___slab_alloc(s, gfpflags, node, addr, c, &tofree); - local_irq_restore(flags); -+ free_delayed(&tofree); - return p; - } - -@@ -2810,7 +2873,7 @@ static void __slab_free(struct kmem_cache *s, struct page *page, - - do { - if (unlikely(n)) { -- spin_unlock_irqrestore(&n->list_lock, flags); -+ raw_spin_unlock_irqrestore(&n->list_lock, flags); - n = NULL; - } - prior = page->freelist; -@@ -2842,7 +2905,7 @@ static void __slab_free(struct kmem_cache *s, struct page *page, - * Otherwise the list_lock will synchronize with - * other processors updating the list of slabs. - */ -- spin_lock_irqsave(&n->list_lock, flags); -+ raw_spin_lock_irqsave(&n->list_lock, flags); - - } - } -@@ -2884,7 +2947,7 @@ static void __slab_free(struct kmem_cache *s, struct page *page, - add_partial(n, page, DEACTIVATE_TO_TAIL); - stat(s, FREE_ADD_PARTIAL); - } -- spin_unlock_irqrestore(&n->list_lock, flags); -+ raw_spin_unlock_irqrestore(&n->list_lock, flags); - return; - - slab_empty: -@@ -2899,7 +2962,7 @@ static void __slab_free(struct kmem_cache *s, struct page *page, - remove_full(s, n, page); - } - -- spin_unlock_irqrestore(&n->list_lock, flags); -+ raw_spin_unlock_irqrestore(&n->list_lock, flags); - stat(s, FREE_SLAB); - discard_slab(s, page); - } -@@ -3104,6 +3167,7 @@ int kmem_cache_alloc_bulk(struct kmem_cache *s, gfp_t flags, size_t size, - void **p) - { - struct kmem_cache_cpu *c; -+ LIST_HEAD(to_free); - int i; - - /* memcg and kmem_cache debug support */ -@@ -3127,7 +3191,7 @@ int kmem_cache_alloc_bulk(struct kmem_cache *s, gfp_t flags, size_t size, - * of re-populating per CPU c->freelist - */ - p[i] = ___slab_alloc(s, flags, NUMA_NO_NODE, -- _RET_IP_, c); -+ _RET_IP_, c, &to_free); - if (unlikely(!p[i])) - goto error; - -@@ -3139,6 +3203,7 @@ int kmem_cache_alloc_bulk(struct kmem_cache *s, gfp_t flags, size_t size, - } - c->tid = next_tid(c->tid); - local_irq_enable(); -+ free_delayed(&to_free); - - /* Clear memory outside IRQ disabled fastpath loop */ - if (unlikely(flags & __GFP_ZERO)) { -@@ -3286,7 +3351,7 @@ static void - init_kmem_cache_node(struct kmem_cache_node *n) - { - n->nr_partial = 0; -- spin_lock_init(&n->list_lock); -+ raw_spin_lock_init(&n->list_lock); - INIT_LIST_HEAD(&n->partial); - #ifdef CONFIG_SLUB_DEBUG - atomic_long_set(&n->nr_slabs, 0); -@@ -3640,6 +3705,10 @@ static void list_slab_objects(struct kmem_cache *s, struct page *page, - const char *text) - { - #ifdef CONFIG_SLUB_DEBUG -+#ifdef CONFIG_PREEMPT_RT_BASE -+ /* XXX move out of irq-off section */ -+ slab_err(s, page, text, s->name); -+#else - void *addr = page_address(page); - void *p; - unsigned long *map = kzalloc(BITS_TO_LONGS(page->objects) * -@@ -3660,6 +3729,7 @@ static void list_slab_objects(struct kmem_cache *s, struct page *page, - slab_unlock(page); - kfree(map); - #endif -+#endif - } - - /* -@@ -3673,7 +3743,7 @@ static void free_partial(struct kmem_cache *s, struct kmem_cache_node *n) - struct page *page, *h; - - BUG_ON(irqs_disabled()); -- spin_lock_irq(&n->list_lock); -+ raw_spin_lock_irq(&n->list_lock); - list_for_each_entry_safe(page, h, &n->partial, lru) { - if (!page->inuse) { - remove_partial(n, page); -@@ -3683,7 +3753,7 @@ static void free_partial(struct kmem_cache *s, struct kmem_cache_node *n) - "Objects remaining in %s on __kmem_cache_shutdown()"); - } - } -- spin_unlock_irq(&n->list_lock); -+ raw_spin_unlock_irq(&n->list_lock); - - list_for_each_entry_safe(page, h, &discard, lru) - discard_slab(s, page); -@@ -3927,7 +3997,7 @@ int __kmem_cache_shrink(struct kmem_cache *s) - for (i = 0; i < SHRINK_PROMOTE_MAX; i++) - INIT_LIST_HEAD(promote + i); - -- spin_lock_irqsave(&n->list_lock, flags); -+ raw_spin_lock_irqsave(&n->list_lock, flags); - - /* - * Build lists of slabs to discard or promote. -@@ -3958,7 +4028,7 @@ int __kmem_cache_shrink(struct kmem_cache *s) - for (i = SHRINK_PROMOTE_MAX - 1; i >= 0; i--) - list_splice(promote + i, &n->partial); - -- spin_unlock_irqrestore(&n->list_lock, flags); -+ raw_spin_unlock_irqrestore(&n->list_lock, flags); - - /* Release empty slabs */ - list_for_each_entry_safe(page, t, &discard, lru) -@@ -4171,6 +4241,12 @@ void __init kmem_cache_init(void) - { - static __initdata struct kmem_cache boot_kmem_cache, - boot_kmem_cache_node; -+ int cpu; -+ -+ for_each_possible_cpu(cpu) { -+ raw_spin_lock_init(&per_cpu(slub_free_list, cpu).lock); -+ INIT_LIST_HEAD(&per_cpu(slub_free_list, cpu).list); -+ } - - if (debug_guardpage_minorder()) - slub_max_order = 0; -@@ -4379,7 +4455,7 @@ static int validate_slab_node(struct kmem_cache *s, - struct page *page; - unsigned long flags; - -- spin_lock_irqsave(&n->list_lock, flags); -+ raw_spin_lock_irqsave(&n->list_lock, flags); - - list_for_each_entry(page, &n->partial, lru) { - validate_slab_slab(s, page, map); -@@ -4401,7 +4477,7 @@ static int validate_slab_node(struct kmem_cache *s, - s->name, count, atomic_long_read(&n->nr_slabs)); - - out: -- spin_unlock_irqrestore(&n->list_lock, flags); -+ raw_spin_unlock_irqrestore(&n->list_lock, flags); - return count; - } - -@@ -4589,12 +4665,12 @@ static int list_locations(struct kmem_cache *s, char *buf, - if (!atomic_long_read(&n->nr_slabs)) - continue; - -- spin_lock_irqsave(&n->list_lock, flags); -+ raw_spin_lock_irqsave(&n->list_lock, flags); - list_for_each_entry(page, &n->partial, lru) - process_slab(&t, s, page, alloc, map); - list_for_each_entry(page, &n->full, lru) - process_slab(&t, s, page, alloc, map); -- spin_unlock_irqrestore(&n->list_lock, flags); -+ raw_spin_unlock_irqrestore(&n->list_lock, flags); - } - - for (i = 0; i < t.count; i++) { --- -2.19.2 - diff --git a/kernel/patches-4.14.x-rt/0179-mm-slub-close-possible-memory-leak-in-kmem_cache_all.patch b/kernel/patches-4.14.x-rt/0179-mm-slub-close-possible-memory-leak-in-kmem_cache_all.patch deleted file mode 100644 index 1e0087308..000000000 --- a/kernel/patches-4.14.x-rt/0179-mm-slub-close-possible-memory-leak-in-kmem_cache_all.patch +++ /dev/null @@ -1,31 +0,0 @@ -From 6521f7ac165e75bc3ada9bdd6cae84837c89095d Mon Sep 17 00:00:00 2001 -From: Sebastian Andrzej Siewior -Date: Wed, 13 Dec 2017 12:44:14 +0100 -Subject: [PATCH 179/450] mm/slub: close possible memory-leak in - kmem_cache_alloc_bulk() - -Under certain circumstances we could leak elements which were moved to -the local "to_free" list. The damage is limited since I can't find -any users here. - -Cc: stable-rt@vger.kernel.org -Signed-off-by: Sebastian Andrzej Siewior ---- - mm/slub.c | 1 + - 1 file changed, 1 insertion(+) - -diff --git a/mm/slub.c b/mm/slub.c -index 2f9f5e133587..aa884987df6b 100644 ---- a/mm/slub.c -+++ b/mm/slub.c -@@ -3218,6 +3218,7 @@ int kmem_cache_alloc_bulk(struct kmem_cache *s, gfp_t flags, size_t size, - return i; - error: - local_irq_enable(); -+ free_delayed(&to_free); - slab_post_alloc_hook(s, flags, i, p); - __kmem_cache_free_bulk(s, i, p); - return 0; --- -2.19.2 - diff --git a/kernel/patches-4.14.x-rt/0180-slub-Enable-irqs-for-__GFP_WAIT.patch b/kernel/patches-4.14.x-rt/0180-slub-Enable-irqs-for-__GFP_WAIT.patch deleted file mode 100644 index ef38bc94d..000000000 --- a/kernel/patches-4.14.x-rt/0180-slub-Enable-irqs-for-__GFP_WAIT.patch +++ /dev/null @@ -1,53 +0,0 @@ -From 5e111b9d402b33815f03e93e3bfed6c8f93c81cf Mon Sep 17 00:00:00 2001 -From: Thomas Gleixner -Date: Wed, 9 Jan 2013 12:08:15 +0100 -Subject: [PATCH 180/450] slub: Enable irqs for __GFP_WAIT - -SYSTEM_RUNNING might be too late for enabling interrupts. Allocations -with GFP_WAIT can happen before that. So use this as an indicator. - -Signed-off-by: Thomas Gleixner ---- - mm/slub.c | 13 ++++++------- - 1 file changed, 6 insertions(+), 7 deletions(-) - -diff --git a/mm/slub.c b/mm/slub.c -index aa884987df6b..9b337c28dd1f 100644 ---- a/mm/slub.c -+++ b/mm/slub.c -@@ -1567,14 +1567,17 @@ static struct page *allocate_slab(struct kmem_cache *s, gfp_t flags, int node) - void *start, *p; - int idx, order; - bool shuffle; -+ bool enableirqs = false; - - flags &= gfp_allowed_mask; - -+ if (gfpflags_allow_blocking(flags)) -+ enableirqs = true; - #ifdef CONFIG_PREEMPT_RT_FULL - if (system_state > SYSTEM_BOOTING) --#else -- if (gfpflags_allow_blocking(flags)) -+ enableirqs = true; - #endif -+ if (enableirqs) - local_irq_enable(); - - flags |= s->allocflags; -@@ -1633,11 +1636,7 @@ static struct page *allocate_slab(struct kmem_cache *s, gfp_t flags, int node) - page->frozen = 1; - - out: --#ifdef CONFIG_PREEMPT_RT_FULL -- if (system_state > SYSTEM_BOOTING) --#else -- if (gfpflags_allow_blocking(flags)) --#endif -+ if (enableirqs) - local_irq_disable(); - if (!page) - return NULL; --- -2.19.2 - diff --git a/kernel/patches-4.14.x-rt/0182-mm-page_alloc-Use-local_lock_on-instead-of-plain-spi.patch b/kernel/patches-4.14.x-rt/0182-mm-page_alloc-Use-local_lock_on-instead-of-plain-spi.patch deleted file mode 100644 index b0eb640db..000000000 --- a/kernel/patches-4.14.x-rt/0182-mm-page_alloc-Use-local_lock_on-instead-of-plain-spi.patch +++ /dev/null @@ -1,33 +0,0 @@ -From e2cb1c4c5be0f67847525fc5ceeaa24dd6fba341 Mon Sep 17 00:00:00 2001 -From: Thomas Gleixner -Date: Thu, 27 Sep 2012 11:11:46 +0200 -Subject: [PATCH 182/450] mm: page_alloc: Use local_lock_on() instead of plain - spinlock - -The plain spinlock while sufficient does not update the local_lock -internals. Use a proper local_lock function instead to ease debugging. - -Signed-off-by: Thomas Gleixner ---- - mm/page_alloc.c | 4 ++-- - 1 file changed, 2 insertions(+), 2 deletions(-) - -diff --git a/mm/page_alloc.c b/mm/page_alloc.c -index cd81e08bb504..c959b7b0292c 100644 ---- a/mm/page_alloc.c -+++ b/mm/page_alloc.c -@@ -291,9 +291,9 @@ static DEFINE_LOCAL_IRQ_LOCK(pa_lock); - - #ifdef CONFIG_PREEMPT_RT_BASE - # define cpu_lock_irqsave(cpu, flags) \ -- spin_lock_irqsave(&per_cpu(pa_lock, cpu).lock, flags) -+ local_lock_irqsave_on(pa_lock, flags, cpu) - # define cpu_unlock_irqrestore(cpu, flags) \ -- spin_unlock_irqrestore(&per_cpu(pa_lock, cpu).lock, flags) -+ local_unlock_irqrestore_on(pa_lock, flags, cpu) - #else - # define cpu_lock_irqsave(cpu, flags) local_irq_save(flags) - # define cpu_unlock_irqrestore(cpu, flags) local_irq_restore(flags) --- -2.19.2 - diff --git a/kernel/patches-4.14.x-rt/0185-mm-backing-dev-don-t-disable-IRQs-in-wb_congested_pu.patch b/kernel/patches-4.14.x-rt/0185-mm-backing-dev-don-t-disable-IRQs-in-wb_congested_pu.patch deleted file mode 100644 index 3b3e71d44..000000000 --- a/kernel/patches-4.14.x-rt/0185-mm-backing-dev-don-t-disable-IRQs-in-wb_congested_pu.patch +++ /dev/null @@ -1,48 +0,0 @@ -From 213cd45678dbce93ac53697715ef87044ee74d38 Mon Sep 17 00:00:00 2001 -From: Sebastian Andrzej Siewior -Date: Fri, 5 Feb 2016 12:17:14 +0100 -Subject: [PATCH 185/450] mm: backing-dev: don't disable IRQs in - wb_congested_put() - -it triggers: -|BUG: sleeping function called from invalid context at kernel/locking/rtmutex.c:930 -|in_atomic(): 0, irqs_disabled(): 1, pid: 12, name: rcuc/0 -|1 lock held by rcuc/0/12: -| #0: (rcu_callback){......}, at: [] rcu_cpu_kthread+0x376/0xb10 -|irq event stamp: 23636 -|hardirqs last enabled at (23635): [] _raw_spin_unlock_irqrestore+0x6c/0x80 -|hardirqs last disabled at (23636): [] wb_congested_put+0x18/0x90 -| [] rt_spin_lock+0x24/0x60 -| [] atomic_dec_and_spin_lock+0x52/0x90 -| [] wb_congested_put+0x28/0x90 -| [] __blkg_release_rcu+0x5e/0x1e0 -| [] ? __blkg_release_rcu+0x87/0x1e0 -| [] ? blkg_conf_finish+0x90/0x90 -| [] rcu_cpu_kthread+0x3b7/0xb10 - -due to cgwb_lock beeing taken with spin_lock_irqsave() usually. - -Signed-off-by: Sebastian Andrzej Siewior ---- - mm/backing-dev.c | 4 ++-- - 1 file changed, 2 insertions(+), 2 deletions(-) - -diff --git a/mm/backing-dev.c b/mm/backing-dev.c -index 9386c98dac12..5e9d804c37cb 100644 ---- a/mm/backing-dev.c -+++ b/mm/backing-dev.c -@@ -470,9 +470,9 @@ void wb_congested_put(struct bdi_writeback_congested *congested) - { - unsigned long flags; - -- local_irq_save(flags); -+ local_irq_save_nort(flags); - if (!atomic_dec_and_lock(&congested->refcnt, &cgwb_lock)) { -- local_irq_restore(flags); -+ local_irq_restore_nort(flags); - return; - } - --- -2.19.2 - diff --git a/kernel/patches-4.14.x-rt/0190-timer-delay-waking-softirqs-from-the-jiffy-tick.patch b/kernel/patches-4.14.x-rt/0190-timer-delay-waking-softirqs-from-the-jiffy-tick.patch deleted file mode 100644 index 9458d0be6..000000000 --- a/kernel/patches-4.14.x-rt/0190-timer-delay-waking-softirqs-from-the-jiffy-tick.patch +++ /dev/null @@ -1,80 +0,0 @@ -From 3842c13318573e304ee2bc4d4ea221c4d75bfdbd Mon Sep 17 00:00:00 2001 -From: Peter Zijlstra -Date: Fri, 21 Aug 2009 11:56:45 +0200 -Subject: [PATCH 190/450] timer: delay waking softirqs from the jiffy tick - -People were complaining about broken balancing with the recent -rt -series. - -A look at /proc/sched_debug yielded: - -cpu#0, 2393.874 MHz - .nr_running : 0 - .load : 0 - .cpu_load[0] : 177522 - .cpu_load[1] : 177522 - .cpu_load[2] : 177522 - .cpu_load[3] : 177522 - .cpu_load[4] : 177522 -cpu#1, 2393.874 MHz - .nr_running : 4 - .load : 4096 - .cpu_load[0] : 181618 - .cpu_load[1] : 180850 - .cpu_load[2] : 180274 - .cpu_load[3] : 179938 - .cpu_load[4] : 179758 - -Which indicated the cpu_load computation was hosed, the 177522 value -indicates that there is one RT task runnable. Initially I thought the -old problem of calculating the cpu_load from a softirq had re-surfaced, -however looking at the code shows its being done from scheduler_tick(). - -[ we really should fix this RT/cfs interaction some day... ] - -A few trace_printk()s later: - - sirq-timer/1-19 [001] 174.289744: 19: 50:S ==> [001] 0:140:R - -0 [001] 174.290724: enqueue_task_rt: adding task: 19/sirq-timer/1 with load: 177522 - -0 [001] 174.290725: 0:140:R + [001] 19: 50:S sirq-timer/1 - -0 [001] 174.290730: scheduler_tick: current load: 177522 - -0 [001] 174.290732: scheduler_tick: current: 0/swapper - -0 [001] 174.290736: 0:140:R ==> [001] 19: 50:R sirq-timer/1 - sirq-timer/1-19 [001] 174.290741: dequeue_task_rt: removing task: 19/sirq-timer/1 with load: 177522 - sirq-timer/1-19 [001] 174.290743: 19: 50:S ==> [001] 0:140:R - -We see that we always raise the timer softirq before doing the load -calculation. Avoid this by re-ordering the scheduler_tick() call in -update_process_times() to occur before we deal with timers. - -This lowers the load back to sanity and restores regular load-balancing -behaviour. - -Signed-off-by: Peter Zijlstra -Signed-off-by: Thomas Gleixner ---- - kernel/time/timer.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/kernel/time/timer.c b/kernel/time/timer.c -index 97c28b96aeb1..807133c1bc20 100644 ---- a/kernel/time/timer.c -+++ b/kernel/time/timer.c -@@ -1628,13 +1628,13 @@ void update_process_times(int user_tick) - - /* Note: this timer irq context must be accounted for as well. */ - account_process_tick(p, user_tick); -+ scheduler_tick(); - run_local_timers(); - rcu_check_callbacks(user_tick); - #ifdef CONFIG_IRQ_WORK - if (in_irq()) - irq_work_tick(); - #endif -- scheduler_tick(); - if (IS_ENABLED(CONFIG_POSIX_TIMERS)) - run_posix_cpu_timers(p); - } --- -2.19.2 - diff --git a/kernel/patches-4.14.x-rt/0191-nohz-Prevent-erroneous-tick-stop-invocations.patch b/kernel/patches-4.14.x-rt/0191-nohz-Prevent-erroneous-tick-stop-invocations.patch deleted file mode 100644 index a962a391c..000000000 --- a/kernel/patches-4.14.x-rt/0191-nohz-Prevent-erroneous-tick-stop-invocations.patch +++ /dev/null @@ -1,59 +0,0 @@ -From 896a19a34dac35a435de6e32986dade16c56f4d7 Mon Sep 17 00:00:00 2001 -From: Thomas Gleixner -Date: Fri, 22 Dec 2017 15:51:13 +0100 -Subject: [PATCH 191/450] nohz: Prevent erroneous tick stop invocations - -The conditions in irq_exit() to invoke tick_nohz_irq_exit() are: - - if ((idle_cpu(cpu) && !need_resched()) || tick_nohz_full_cpu(cpu)) - -This is too permissive in various aspects: - - 1) If need_resched() is set, then the tick cannot be stopped whether - the CPU is idle or in nohz full mode. - - 2) If need_resched() is not set, but softirqs are pending then this is an - indication that the softirq code punted and delegated the execution to - softirqd. need_resched() is not true because the current interrupted - task takes precedence over softirqd. - -Invoking tick_nohz_irq_exit() in these cases can cause an endless loop of -timer interrupts because the timer wheel contains an expired timer, but -softirqs are not yet executed. So it returns an immediate expiry request, -which causes the timer to fire immediately again. Lather, rinse and -repeat.... - -Prevent that by making the conditions proper and only allow invokation when -in idle or nohz full mode and neither need_resched() nor -local_softirq_pending() are set. - -Signed-off-by: Thomas Gleixner -[ bigeasy: XXX still needed for RT, to avoid hangup due to pending timer softirq, - keep it RT only ] -Signed-off-by: Sebastian Andrzej Siewior ---- - kernel/softirq.c | 8 +++++++- - 1 file changed, 7 insertions(+), 1 deletion(-) - -diff --git a/kernel/softirq.c b/kernel/softirq.c -index 1a5dfc8dcf49..36092932c532 100644 ---- a/kernel/softirq.c -+++ b/kernel/softirq.c -@@ -385,7 +385,13 @@ static inline void tick_irq_exit(void) - int cpu = smp_processor_id(); - - /* Make sure that timer wheel updates are propagated */ -- if ((idle_cpu(cpu) && !need_resched()) || tick_nohz_full_cpu(cpu)) { -+#ifdef CONFIG_PREEMPT_RT_BASE -+ if ((idle_cpu(cpu) || tick_nohz_full_cpu(cpu)) && -+ !need_resched() && !local_softirq_pending()) -+#else -+ if ((idle_cpu(cpu) && !need_resched()) || tick_nohz_full_cpu(cpu)) -+#endif -+ { - if (!in_irq()) - tick_nohz_irq_exit(); - } --- -2.19.2 - diff --git a/kernel/patches-4.14.x-rt/0202-alarmtimer-Prevent-live-lock-in-alarm_cancel.patch b/kernel/patches-4.14.x-rt/0202-alarmtimer-Prevent-live-lock-in-alarm_cancel.patch deleted file mode 100644 index 83ff077f3..000000000 --- a/kernel/patches-4.14.x-rt/0202-alarmtimer-Prevent-live-lock-in-alarm_cancel.patch +++ /dev/null @@ -1,32 +0,0 @@ -From 58fec41067dcdc269500b1dc6d8dfcf931c2d0b9 Mon Sep 17 00:00:00 2001 -From: Sebastian Andrzej Siewior -Date: Tue, 27 Mar 2018 15:58:16 +0200 -Subject: [PATCH 202/450] alarmtimer: Prevent live lock in alarm_cancel() - -If alarm_try_to_cancel() requires a retry, then depending on the -priority setting the retry loop might prevent timer callback completion -on RT. Prevent that by waiting for completion on RT, no change for a -non RT kernel. - -Cc: stable-rt@vger.kernel.org -Signed-off-by: Sebastian Andrzej Siewior ---- - kernel/time/alarmtimer.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/kernel/time/alarmtimer.c b/kernel/time/alarmtimer.c -index fa5de5e8de61..6020ee66e517 100644 ---- a/kernel/time/alarmtimer.c -+++ b/kernel/time/alarmtimer.c -@@ -436,7 +436,7 @@ int alarm_cancel(struct alarm *alarm) - int ret = alarm_try_to_cancel(alarm); - if (ret >= 0) - return ret; -- cpu_relax(); -+ hrtimer_wait_for_timer(&alarm->timer); - } - } - EXPORT_SYMBOL_GPL(alarm_cancel); --- -2.19.2 - diff --git a/kernel/patches-4.14.x-rt/0203-posix-timers-user-proper-timer-while-waiting-for-ala.patch b/kernel/patches-4.14.x-rt/0203-posix-timers-user-proper-timer-while-waiting-for-ala.patch deleted file mode 100644 index 2afa48a9b..000000000 --- a/kernel/patches-4.14.x-rt/0203-posix-timers-user-proper-timer-while-waiting-for-ala.patch +++ /dev/null @@ -1,75 +0,0 @@ -From 3b2696c2db2ea687ecb4572ff3362c03146b4288 Mon Sep 17 00:00:00 2001 -From: Sebastian Andrzej Siewior -Date: Wed, 28 Mar 2018 10:45:40 +0200 -Subject: [PATCH 203/450] posix-timers: user proper timer while waiting for - alarmtimer - -On RT the timer can be preempted while running and therefore we wait -with timer_wait_for_callback() for the timer to complete (instead of -busy looping). -The POSIX timer has an hrtimer underneath and this hrtimer is used to -wait for its completion. The alartimer has also an hrtimer but at a -different location. - -Instead of checking for ->timer_set which is the same for the alarmtimer -and the "posix-timers" I instead check for ->arm which is only used by -the "posix-timers". To match the alarmtimer I check for the alarm_clock -struct. - -Cc: stable-rt@vger.kernel.org -Signed-off-by: Sebastian Andrzej Siewior ---- - kernel/time/posix-timers.c | 30 ++++++++++++++++-------------- - 1 file changed, 16 insertions(+), 14 deletions(-) - -diff --git a/kernel/time/posix-timers.c b/kernel/time/posix-timers.c -index 27186326723f..5cf8bf8eea89 100644 ---- a/kernel/time/posix-timers.c -+++ b/kernel/time/posix-timers.c -@@ -806,20 +806,6 @@ SYSCALL_DEFINE1(timer_getoverrun, timer_t, timer_id) - return overrun; - } - --/* -- * Protected by RCU! -- */ --static void timer_wait_for_callback(const struct k_clock *kc, struct k_itimer *timr) --{ --#ifdef CONFIG_PREEMPT_RT_FULL -- if (kc->timer_set == common_timer_set) -- hrtimer_wait_for_timer(&timr->it.real.timer); -- else -- /* FIXME: Whacky hack for posix-cpu-timers */ -- schedule_timeout(1); --#endif --} -- - static void common_hrtimer_arm(struct k_itimer *timr, ktime_t expires, - bool absolute, bool sigev_none) - { -@@ -850,6 +836,22 @@ static void common_hrtimer_arm(struct k_itimer *timr, ktime_t expires, - hrtimer_start_expires(timer, HRTIMER_MODE_ABS); - } - -+/* -+ * Protected by RCU! -+ */ -+static void timer_wait_for_callback(const struct k_clock *kc, struct k_itimer *timr) -+{ -+#ifdef CONFIG_PREEMPT_RT_FULL -+ if (kc->timer_arm == common_hrtimer_arm) -+ hrtimer_wait_for_timer(&timr->it.real.timer); -+ else if (kc == &alarm_clock) -+ hrtimer_wait_for_timer(&timr->it.alarm.alarmtimer.timer); -+ else -+ /* FIXME: Whacky hack for posix-cpu-timers */ -+ schedule_timeout(1); -+#endif -+} -+ - static int common_hrtimer_try_to_cancel(struct k_itimer *timr) - { - return hrtimer_try_to_cancel(&timr->it.real.timer); --- -2.19.2 - diff --git a/kernel/patches-4.14.x-rt/0204-posix-timers-move-the-rcu-head-out-of-the-union.patch b/kernel/patches-4.14.x-rt/0204-posix-timers-move-the-rcu-head-out-of-the-union.patch deleted file mode 100644 index 48c27611f..000000000 --- a/kernel/patches-4.14.x-rt/0204-posix-timers-move-the-rcu-head-out-of-the-union.patch +++ /dev/null @@ -1,60 +0,0 @@ -From 9e9f595ba6639148f6d6c971f6c7cf65eb9d5c66 Mon Sep 17 00:00:00 2001 -From: Sebastian Andrzej Siewior -Date: Wed, 28 Mar 2018 11:15:19 +0200 -Subject: [PATCH 204/450] posix-timers: move the rcu head out of the union - -On RT the timer can be preempted while running and therefore we wait -with timer_wait_for_callback() for the timer to complete (instead of -busy looping). The RCU-readlock is held to ensure that this posix timer -is not removed while we wait on it. -If the timer is removed then it invokes call_rcu() with a pointer that -is shared with the hrtimer because it is part of the same union. -In order to avoid any possible side effects I am moving the rcu pointer -out of the union. - -Cc: stable-rt@vger.kernel.org -Signed-off-by: Sebastian Andrzej Siewior ---- - include/linux/posix-timers.h | 2 +- - kernel/time/posix-timers.c | 4 ++-- - 2 files changed, 3 insertions(+), 3 deletions(-) - -diff --git a/include/linux/posix-timers.h b/include/linux/posix-timers.h -index 437a539898ae..de5c49b0dccf 100644 ---- a/include/linux/posix-timers.h -+++ b/include/linux/posix-timers.h -@@ -101,8 +101,8 @@ struct k_itimer { - struct { - struct alarm alarmtimer; - } alarm; -- struct rcu_head rcu; - } it; -+ struct rcu_head rcu; - }; - - void run_posix_cpu_timers(struct task_struct *task); -diff --git a/kernel/time/posix-timers.c b/kernel/time/posix-timers.c -index 5cf8bf8eea89..5a59538f3d16 100644 ---- a/kernel/time/posix-timers.c -+++ b/kernel/time/posix-timers.c -@@ -480,7 +480,7 @@ static struct k_itimer * alloc_posix_timer(void) - - static void k_itimer_rcu_free(struct rcu_head *head) - { -- struct k_itimer *tmr = container_of(head, struct k_itimer, it.rcu); -+ struct k_itimer *tmr = container_of(head, struct k_itimer, rcu); - - kmem_cache_free(posix_timers_cache, tmr); - } -@@ -497,7 +497,7 @@ static void release_posix_timer(struct k_itimer *tmr, int it_id_set) - } - put_pid(tmr->it_pid); - sigqueue_free(tmr->sigq); -- call_rcu(&tmr->it.rcu, k_itimer_rcu_free); -+ call_rcu(&tmr->rcu, k_itimer_rcu_free); - } - - static int common_timer_create(struct k_itimer *new_timer) --- -2.19.2 - diff --git a/kernel/patches-4.14.x-rt/0206-timer-fd-Prevent-live-lock.patch b/kernel/patches-4.14.x-rt/0206-timer-fd-Prevent-live-lock.patch deleted file mode 100644 index a86e56d78..000000000 --- a/kernel/patches-4.14.x-rt/0206-timer-fd-Prevent-live-lock.patch +++ /dev/null @@ -1,35 +0,0 @@ -From 08baa369c0a7447cd14946c04f46810bdb301d27 Mon Sep 17 00:00:00 2001 -From: Thomas Gleixner -Date: Wed, 25 Jan 2012 11:08:40 +0100 -Subject: [PATCH 206/450] timer-fd: Prevent live lock - -If hrtimer_try_to_cancel() requires a retry, then depending on the -priority setting te retry loop might prevent timer callback completion -on RT. Prevent that by waiting for completion on RT, no change for a -non RT kernel. - -Reported-by: Sankara Muthukrishnan -Signed-off-by: Thomas Gleixner ---- - fs/timerfd.c | 5 ++++- - 1 file changed, 4 insertions(+), 1 deletion(-) - -diff --git a/fs/timerfd.c b/fs/timerfd.c -index 040612ec9598..b3d9d435926c 100644 ---- a/fs/timerfd.c -+++ b/fs/timerfd.c -@@ -471,7 +471,10 @@ static int do_timerfd_settime(int ufd, int flags, - break; - } - spin_unlock_irq(&ctx->wqh.lock); -- cpu_relax(); -+ if (isalarm(ctx)) -+ hrtimer_wait_for_timer(&ctx->t.alarm.timer); -+ else -+ hrtimer_wait_for_timer(&ctx->t.tmr); - } - - /* --- -2.19.2 - diff --git a/kernel/patches-4.14.x-rt/0213-sched-Prevent-task-state-corruption-by-spurious-lock.patch b/kernel/patches-4.14.x-rt/0213-sched-Prevent-task-state-corruption-by-spurious-lock.patch deleted file mode 100644 index d51a82a04..000000000 --- a/kernel/patches-4.14.x-rt/0213-sched-Prevent-task-state-corruption-by-spurious-lock.patch +++ /dev/null @@ -1,84 +0,0 @@ -From 70ff14704b10db1b8ef9f6534442d885be1a16aa Mon Sep 17 00:00:00 2001 -From: Thomas Gleixner -Date: Tue, 6 Jun 2017 14:20:37 +0200 -Subject: [PATCH 213/450] sched: Prevent task state corruption by spurious lock - wakeup - -Mathias and others reported GDB failures on RT. - -The following scenario leads to task state corruption: - -CPU0 CPU1 - -T1->state = TASK_XXX; -spin_lock(&lock) - rt_spin_lock_slowlock(&lock->rtmutex) - raw_spin_lock(&rtm->wait_lock); - T1->saved_state = current->state; - T1->state = TASK_UNINTERRUPTIBLE; - spin_unlock(&lock) - task_blocks_on_rt_mutex(rtm) rt_spin_lock_slowunlock(&lock->rtmutex) - queue_waiter(rtm) raw_spin_lock(&rtm->wait_lock); - pi_chain_walk(rtm) - raw_spin_unlock(&rtm->wait_lock); - wake_top_waiter(T1) - - raw_spin_lock(&rtm->wait_lock); - - for (;;) { - if (__try_to_take_rt_mutex()) <- Succeeds - break; - ... - } - - T1->state = T1->saved_state; - try_to_wake_up(T1) - ttwu_do_wakeup(T1) - T1->state = TASK_RUNNING; - -In most cases this is harmless because waiting for some event, which is the -usual reason for TASK_[UN]INTERRUPTIBLE has to be safe against other forms -of spurious wakeups anyway. - -But in case of TASK_TRACED this is actually fatal, because the task loses -the TASK_TRACED state. In consequence it fails to consume SIGSTOP which was -sent from the debugger and actually delivers SIGSTOP to the task which -breaks the ptrace mechanics and brings the debugger into an unexpected -state. - -The TASK_TRACED state should prevent getting there due to the state -matching logic in try_to_wake_up(). But that's not true because -wake_up_lock_sleeper() uses TASK_ALL as state mask. That's bogus because -lock sleepers always use TASK_UNINTERRUPTIBLE, so the wakeup should use -that as well. - -The cure is way simpler as figuring it out: - -Change the mask used in wake_up_lock_sleeper() from TASK_ALL to -TASK_UNINTERRUPTIBLE. - -Cc: stable-rt@vger.kernel.org -Reported-by: Mathias Koehrer -Reported-by: David Hauck -Signed-off-by: Thomas Gleixner -Signed-off-by: Sebastian Andrzej Siewior ---- - kernel/sched/core.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/kernel/sched/core.c b/kernel/sched/core.c -index d5210a7dae70..840f5fe684d5 100644 ---- a/kernel/sched/core.c -+++ b/kernel/sched/core.c -@@ -2224,7 +2224,7 @@ EXPORT_SYMBOL(wake_up_process); - */ - int wake_up_lock_sleeper(struct task_struct *p) - { -- return try_to_wake_up(p, TASK_ALL, WF_LOCK_SLEEPER); -+ return try_to_wake_up(p, TASK_UNINTERRUPTIBLE, WF_LOCK_SLEEPER); - } - - int wake_up_state(struct task_struct *p, unsigned int state) --- -2.19.2 - diff --git a/kernel/patches-4.14.x-rt/0214-sched-Remove-TASK_ALL.patch b/kernel/patches-4.14.x-rt/0214-sched-Remove-TASK_ALL.patch deleted file mode 100644 index 385aefd82..000000000 --- a/kernel/patches-4.14.x-rt/0214-sched-Remove-TASK_ALL.patch +++ /dev/null @@ -1,35 +0,0 @@ -From a51f5adc29f1df6843454d69065b53400f945989 Mon Sep 17 00:00:00 2001 -From: Peter Zijlstra -Date: Wed, 7 Jun 2017 10:12:45 +0200 -Subject: [PATCH 214/450] sched: Remove TASK_ALL - -It's unused: - -$ git grep "\" | wc -l -1 - -And dangerous, kill the bugger. - -Cc: stable-rt@vger.kernel.org -Acked-by: Thomas Gleixner -Signed-off-by: Peter Zijlstra (Intel) -Signed-off-by: Sebastian Andrzej Siewior ---- - include/linux/sched.h | 1 - - 1 file changed, 1 deletion(-) - -diff --git a/include/linux/sched.h b/include/linux/sched.h -index 962c3e6e8979..45c1bc53321f 100644 ---- a/include/linux/sched.h -+++ b/include/linux/sched.h -@@ -93,7 +93,6 @@ struct task_group; - - /* Convenience macros for the sake of wake_up(): */ - #define TASK_NORMAL (TASK_INTERRUPTIBLE | TASK_UNINTERRUPTIBLE) --#define TASK_ALL (TASK_NORMAL | __TASK_STOPPED | __TASK_TRACED) - - /* get_task_state(): */ - #define TASK_REPORT (TASK_RUNNING | TASK_INTERRUPTIBLE | \ --- -2.19.2 - diff --git a/kernel/patches-4.14.x-rt/0216-sched-Take-RT-softirq-semantics-into-account-in-cond.patch b/kernel/patches-4.14.x-rt/0216-sched-Take-RT-softirq-semantics-into-account-in-cond.patch deleted file mode 100644 index 081304004..000000000 --- a/kernel/patches-4.14.x-rt/0216-sched-Take-RT-softirq-semantics-into-account-in-cond.patch +++ /dev/null @@ -1,61 +0,0 @@ -From 3f298647538a3d62d66db495dc930dc92db762ff Mon Sep 17 00:00:00 2001 -From: Thomas Gleixner -Date: Thu, 14 Jul 2011 09:56:44 +0200 -Subject: [PATCH 216/450] sched: Take RT softirq semantics into account in - cond_resched() - -The softirq semantics work different on -RT. There is no SOFTIRQ_MASK in -the preemption counter which leads to the BUG_ON() statement in -__cond_resched_softirq(). As for -RT it is enough to perform a "normal" -schedule. - -Signed-off-by: Thomas Gleixner ---- - include/linux/sched.h | 4 ++++ - kernel/sched/core.c | 2 ++ - 2 files changed, 6 insertions(+) - -diff --git a/include/linux/sched.h b/include/linux/sched.h -index 45c1bc53321f..ea110a4dea9b 100644 ---- a/include/linux/sched.h -+++ b/include/linux/sched.h -@@ -1667,12 +1667,16 @@ extern int __cond_resched_lock(spinlock_t *lock); - __cond_resched_lock(lock); \ - }) - -+#ifndef CONFIG_PREEMPT_RT_FULL - extern int __cond_resched_softirq(void); - - #define cond_resched_softirq() ({ \ - ___might_sleep(__FILE__, __LINE__, SOFTIRQ_DISABLE_OFFSET); \ - __cond_resched_softirq(); \ - }) -+#else -+# define cond_resched_softirq() cond_resched() -+#endif - - static inline void cond_resched_rcu(void) - { -diff --git a/kernel/sched/core.c b/kernel/sched/core.c -index bcb5ea038266..148e7627c595 100644 ---- a/kernel/sched/core.c -+++ b/kernel/sched/core.c -@@ -4948,6 +4948,7 @@ int __cond_resched_lock(spinlock_t *lock) - } - EXPORT_SYMBOL(__cond_resched_lock); - -+#ifndef CONFIG_PREEMPT_RT_FULL - int __sched __cond_resched_softirq(void) - { - BUG_ON(!in_softirq()); -@@ -4961,6 +4962,7 @@ int __sched __cond_resched_softirq(void) - return 0; - } - EXPORT_SYMBOL(__cond_resched_softirq); -+#endif - - /** - * yield - yield the current processor to other threads. --- -2.19.2 - diff --git a/kernel/patches-4.14.x-rt/0220-sched-ttwu-Return-success-when-only-changing-the-sav.patch b/kernel/patches-4.14.x-rt/0220-sched-ttwu-Return-success-when-only-changing-the-sav.patch deleted file mode 100644 index a00068e4a..000000000 --- a/kernel/patches-4.14.x-rt/0220-sched-ttwu-Return-success-when-only-changing-the-sav.patch +++ /dev/null @@ -1,40 +0,0 @@ -From 88877013a5214ab58121c0adb371e0c2ab1b5067 Mon Sep 17 00:00:00 2001 -From: Thomas Gleixner -Date: Tue, 13 Dec 2011 21:42:19 +0100 -Subject: [PATCH 220/450] sched: ttwu: Return success when only changing the - saved_state value - -When a task blocks on a rt lock, it saves the current state in -p->saved_state, so a lock related wake up will not destroy the -original state. - -When a real wakeup happens, while the task is running due to a lock -wakeup already, we update p->saved_state to TASK_RUNNING, but we do -not return success, which might cause another wakeup in the waitqueue -code and the task remains in the waitqueue list. Return success in -that case as well. - -Signed-off-by: Thomas Gleixner ---- - kernel/sched/core.c | 4 +++- - 1 file changed, 3 insertions(+), 1 deletion(-) - -diff --git a/kernel/sched/core.c b/kernel/sched/core.c -index 148e7627c595..75c7bd31cba4 100644 ---- a/kernel/sched/core.c -+++ b/kernel/sched/core.c -@@ -2040,8 +2040,10 @@ try_to_wake_up(struct task_struct *p, unsigned int state, int wake_flags) - * if the wakeup condition is true. - */ - if (!(wake_flags & WF_LOCK_SLEEPER)) { -- if (p->saved_state & state) -+ if (p->saved_state & state) { - p->saved_state = TASK_RUNNING; -+ success = 1; -+ } - } - goto out; - } --- -2.19.2 - diff --git a/kernel/patches-4.14.x-rt/0223-stop_machine-convert-stop_machine_run-to-PREEMPT_RT.patch b/kernel/patches-4.14.x-rt/0223-stop_machine-convert-stop_machine_run-to-PREEMPT_RT.patch deleted file mode 100644 index 0c010acb1..000000000 --- a/kernel/patches-4.14.x-rt/0223-stop_machine-convert-stop_machine_run-to-PREEMPT_RT.patch +++ /dev/null @@ -1,41 +0,0 @@ -From 0dfbad209a41126dd1b51bb818e37e0878a9f2c9 Mon Sep 17 00:00:00 2001 -From: Ingo Molnar -Date: Fri, 3 Jul 2009 08:30:27 -0500 -Subject: [PATCH 223/450] stop_machine: convert stop_machine_run() to - PREEMPT_RT - -Instead of playing with non-preemption, introduce explicit -startup serialization. This is more robust and cleaner as -well. - -Signed-off-by: Ingo Molnar -Signed-off-by: Thomas Gleixner -[bigeasy: XXX: stopper_lock -> stop_cpus_lock] ---- - kernel/stop_machine.c | 10 ++++++++++ - 1 file changed, 10 insertions(+) - -diff --git a/kernel/stop_machine.c b/kernel/stop_machine.c -index 067cb83f37ea..f8d1ae9ed7be 100644 ---- a/kernel/stop_machine.c -+++ b/kernel/stop_machine.c -@@ -503,6 +503,16 @@ static void cpu_stopper_thread(unsigned int cpu) - struct cpu_stop_done *done = work->done; - int ret; - -+ /* -+ * Wait until the stopper finished scheduling on all -+ * cpus -+ */ -+ lg_global_lock(&stop_cpus_lock); -+ /* -+ * Let other cpu threads continue as well -+ */ -+ lg_global_unlock(&stop_cpus_lock); -+ - /* cpu stop callbacks must not sleep, make in_atomic() == T */ - preempt_count_inc(); - ret = fn(arg); --- -2.19.2 - diff --git a/kernel/patches-4.14.x-rt/0224-stop_machine-Use-raw-spinlocks.patch b/kernel/patches-4.14.x-rt/0224-stop_machine-Use-raw-spinlocks.patch deleted file mode 100644 index 46f5d3828..000000000 --- a/kernel/patches-4.14.x-rt/0224-stop_machine-Use-raw-spinlocks.patch +++ /dev/null @@ -1,36 +0,0 @@ -From eff70631cf55bb22b788ac7446b8e9613fbe392a Mon Sep 17 00:00:00 2001 -From: Thomas Gleixner -Date: Wed, 29 Jun 2011 11:01:51 +0200 -Subject: [PATCH 224/450] stop_machine: Use raw spinlocks - -Use raw-locks in stomp_machine() to allow locking in irq-off regions. - -Signed-off-by: Thomas Gleixner ---- - kernel/stop_machine.c | 10 +--------- - 1 file changed, 1 insertion(+), 9 deletions(-) - -diff --git a/kernel/stop_machine.c b/kernel/stop_machine.c -index f8d1ae9ed7be..56f2f2e01229 100644 ---- a/kernel/stop_machine.c -+++ b/kernel/stop_machine.c -@@ -503,15 +503,7 @@ static void cpu_stopper_thread(unsigned int cpu) - struct cpu_stop_done *done = work->done; - int ret; - -- /* -- * Wait until the stopper finished scheduling on all -- * cpus -- */ -- lg_global_lock(&stop_cpus_lock); -- /* -- * Let other cpu threads continue as well -- */ -- lg_global_unlock(&stop_cpus_lock); -+ /* XXX */ - - /* cpu stop callbacks must not sleep, make in_atomic() == T */ - preempt_count_inc(); --- -2.19.2 - diff --git a/kernel/patches-4.14.x-rt/0234-kernel-softirq-unlock-with-irqs-on.patch b/kernel/patches-4.14.x-rt/0234-kernel-softirq-unlock-with-irqs-on.patch deleted file mode 100644 index 7b5999afd..000000000 --- a/kernel/patches-4.14.x-rt/0234-kernel-softirq-unlock-with-irqs-on.patch +++ /dev/null @@ -1,33 +0,0 @@ -From 2e7e67779ed8539f0e92fb0db4811ee7ba244af0 Mon Sep 17 00:00:00 2001 -From: Sebastian Andrzej Siewior -Date: Tue, 9 Feb 2016 18:17:18 +0100 -Subject: [PATCH 234/450] kernel: softirq: unlock with irqs on - -We unlock the lock while the interrupts are off. This isn't a problem -now but will get because the migrate_disable() + enable are not -symmetrical in regard to the status of interrupts. - -Signed-off-by: Sebastian Andrzej Siewior ---- - kernel/softirq.c | 4 +++- - 1 file changed, 3 insertions(+), 1 deletion(-) - -diff --git a/kernel/softirq.c b/kernel/softirq.c -index 92fbc06bce6f..9b56981ccc8d 100644 ---- a/kernel/softirq.c -+++ b/kernel/softirq.c -@@ -564,8 +564,10 @@ static void do_current_softirqs(void) - do_single_softirq(i); - } - softirq_clr_runner(i); -- unlock_softirq(i); - WARN_ON(current->softirq_nestcnt != 1); -+ local_irq_enable(); -+ unlock_softirq(i); -+ local_irq_disable(); - } - } - --- -2.19.2 - diff --git a/kernel/patches-4.14.x-rt/0237-softirq-wake-the-timer-softirq-if-needed.patch b/kernel/patches-4.14.x-rt/0237-softirq-wake-the-timer-softirq-if-needed.patch deleted file mode 100644 index c293c3716..000000000 --- a/kernel/patches-4.14.x-rt/0237-softirq-wake-the-timer-softirq-if-needed.patch +++ /dev/null @@ -1,85 +0,0 @@ -From 9529533714b8e9522217aec0996f288d07eb6180 Mon Sep 17 00:00:00 2001 -From: Mike Galbraith -Date: Fri, 20 Jan 2017 18:10:20 +0100 -Subject: [PATCH 237/450] softirq: wake the timer softirq if needed - -The irq-exit path only checks the "normal"-softirq thread if it is -running and ignores the state of the "timer"-softirq thread. It is possible -that the timer-softirq thread is and has work pending which leads to the -following warning: - -[ 84.087571] NOHZ: local_softirq_pending 02 -[ 84.087593] NOHZ: local_softirq_pending 02 -[ 84.087598] NOHZ: local_softirq_pending 02 -[ 84.087904] NOHZ: local_softirq_pending 02 -[ 84.088526] NOHZ: local_softirq_pending 02 -[ 84.088899] NOHZ: local_softirq_pending 02 -[ 84.089463] NOHZ: local_softirq_pending 02 -[ 115.013470] NOHZ: local_softirq_pending 02 -[ 115.013601] NOHZ: local_softirq_pending 02 -[ 115.013709] NOHZ: local_softirq_pending 02 - -This was introduced during the timer-softirq split. - -Cc: stable-rt@vger.kernel.org -Signed-off-by: Mike Galbraith -Signed-off-by: Sebastian Andrzej Siewior ---- - kernel/softirq.c | 11 +++++------ - 1 file changed, 5 insertions(+), 6 deletions(-) - -diff --git a/kernel/softirq.c b/kernel/softirq.c -index ff8471aa1c0b..da87715b10be 100644 ---- a/kernel/softirq.c -+++ b/kernel/softirq.c -@@ -28,6 +28,7 @@ - #include - #include - #include -+#include - - #define CREATE_TRACE_POINTS - #include -@@ -206,6 +207,7 @@ static void handle_softirq(unsigned int vec_nr) - } - } - -+#ifndef CONFIG_PREEMPT_RT_FULL - /* - * If ksoftirqd is scheduled, we do not want to process pending softirqs - * right now. Let ksoftirqd handle this at its own rate, to get fairness, -@@ -221,7 +223,6 @@ static bool ksoftirqd_running(unsigned long pending) - return tsk && (tsk->state == TASK_RUNNING); - } - --#ifndef CONFIG_PREEMPT_RT_FULL - static inline int ksoftirqd_softirq_pending(void) - { - return local_softirq_pending(); -@@ -777,13 +778,10 @@ void irq_enter(void) - - static inline void invoke_softirq(void) - { --#ifdef CONFIG_PREEMPT_RT_FULL -- unsigned long flags; --#endif -- -+#ifndef CONFIG_PREEMPT_RT_FULL - if (ksoftirqd_running(local_softirq_pending())) - return; --#ifndef CONFIG_PREEMPT_RT_FULL -+ - if (!force_irqthreads) { - #ifdef CONFIG_HAVE_IRQ_EXIT_ON_IRQ_STACK - /* -@@ -804,6 +802,7 @@ static inline void invoke_softirq(void) - wakeup_softirqd(); - } - #else /* PREEMPT_RT_FULL */ -+ unsigned long flags; - - local_irq_save(flags); - if (__this_cpu_read(ksoftirqd) && --- -2.19.2 - diff --git a/kernel/patches-4.14.x-rt/0242-locking-rtmutex-don-t-drop-the-wait_lock-twice.patch b/kernel/patches-4.14.x-rt/0242-locking-rtmutex-don-t-drop-the-wait_lock-twice.patch deleted file mode 100644 index bc16a29fe..000000000 --- a/kernel/patches-4.14.x-rt/0242-locking-rtmutex-don-t-drop-the-wait_lock-twice.patch +++ /dev/null @@ -1,35 +0,0 @@ -From f7935d72b84fab0608c5951271acf243301f2729 Mon Sep 17 00:00:00 2001 -From: Sebastian Andrzej Siewior -Date: Thu, 7 Sep 2017 12:38:47 +0200 -Subject: [PATCH 242/450] locking/rtmutex: don't drop the wait_lock twice - -Since the futex rework, __rt_mutex_start_proxy_lock() does no longer -acquire the wait_lock so it must not drop it. Otherwise the lock is not -only unlocked twice but also the preemption counter is underflown. - -It is okay to remove that line because this function does not disable -interrupts nor does it acquire the ->wait_lock. The caller does this so it is -wrong do it here (after the futex rework). - -Cc: stable-rt@vger.kernel.org #v4.9.18-rt14+ -Reported-by: Gusenleitner Klaus -Signed-off-by: Sebastian Andrzej Siewior ---- - kernel/locking/rtmutex.c | 1 - - 1 file changed, 1 deletion(-) - -diff --git a/kernel/locking/rtmutex.c b/kernel/locking/rtmutex.c -index ea8dd82835c9..935adbbe08f1 100644 ---- a/kernel/locking/rtmutex.c -+++ b/kernel/locking/rtmutex.c -@@ -1787,7 +1787,6 @@ int __rt_mutex_start_proxy_lock(struct rt_mutex *lock, - raw_spin_lock(&task->pi_lock); - if (task->pi_blocked_on) { - raw_spin_unlock(&task->pi_lock); -- raw_spin_unlock_irq(&lock->wait_lock); - return -EAGAIN; - } - task->pi_blocked_on = PI_REQUEUE_INPROGRESS; --- -2.19.2 - diff --git a/kernel/patches-4.14.x-rt/0263-RCU-we-need-to-skip-that-warning-but-only-on-sleepin.patch b/kernel/patches-4.14.x-rt/0263-RCU-we-need-to-skip-that-warning-but-only-on-sleepin.patch deleted file mode 100644 index 297d73a2f..000000000 --- a/kernel/patches-4.14.x-rt/0263-RCU-we-need-to-skip-that-warning-but-only-on-sleepin.patch +++ /dev/null @@ -1,41 +0,0 @@ -From 7bb975338a8f37db0135bb469a0763c0f9089327 Mon Sep 17 00:00:00 2001 -From: Sebastian Andrzej Siewior -Date: Thu, 21 Sep 2017 14:25:13 +0200 -Subject: [PATCH 263/450] RCU: we need to skip that warning but only on - sleeping locks - -This check is okay for upstream. On RT we trigger this while blocking on -sleeping lock. In this case, it is okay to schedule() within a RCU -section. -Since spin_lock() and read_lock() disables migration it should be okay -to test for this as an indication whether or not a sleeping lock is -held. The ->pi_blocked_on member won't work becasuse it might also be -set on regular mutexes. - -Signed-off-by: Sebastian Andrzej Siewior ---- - kernel/rcu/tree_plugin.h | 6 +++++- - 1 file changed, 5 insertions(+), 1 deletion(-) - -diff --git a/kernel/rcu/tree_plugin.h b/kernel/rcu/tree_plugin.h -index 181e2487c8b8..787321ad4f5f 100644 ---- a/kernel/rcu/tree_plugin.h -+++ b/kernel/rcu/tree_plugin.h -@@ -323,9 +323,13 @@ static void rcu_preempt_note_context_switch(bool preempt) - struct task_struct *t = current; - struct rcu_data *rdp; - struct rcu_node *rnp; -+ int mg_counter = 0; - - RCU_LOCKDEP_WARN(!irqs_disabled(), "rcu_preempt_note_context_switch() invoked with interrupts enabled!!!\n"); -- WARN_ON_ONCE(!preempt && t->rcu_read_lock_nesting > 0); -+#if defined(CONFIG_PREEMPT_COUNT) && defined(CONFIG_SMP) -+ mg_counter = t->migrate_disable; -+#endif -+ WARN_ON_ONCE(!preempt && t->rcu_read_lock_nesting > 0 && !mg_counter); - if (t->rcu_read_lock_nesting > 0 && - !t->rcu_read_unlock_special.b.blocked) { - --- -2.19.2 - diff --git a/kernel/patches-4.14.x-rt/0264-RCU-skip-the-schedule-in-RCU-section-warning-on-UP-t.patch b/kernel/patches-4.14.x-rt/0264-RCU-skip-the-schedule-in-RCU-section-warning-on-UP-t.patch deleted file mode 100644 index c8125dcc2..000000000 --- a/kernel/patches-4.14.x-rt/0264-RCU-skip-the-schedule-in-RCU-section-warning-on-UP-t.patch +++ /dev/null @@ -1,132 +0,0 @@ -From 59f632ff902c1a2697e9c67e1cb4b496573ba883 Mon Sep 17 00:00:00 2001 -From: Sebastian Andrzej Siewior -Date: Fri, 16 Feb 2018 11:45:13 +0100 -Subject: [PATCH 264/450] RCU: skip the "schedule() in RCU section" warning on - UP, too - -In "RCU: we need to skip that warning but only on sleeping locks" we -skipped a warning on SMP systems in case we schedule out in a RCU -section while attempt to obtain a sleeping lock. This is also required -on UP systems. -In order to do so, I introduce a tiny version of migrate_disable() + -_enable() which only update the counters which we then can check against -on RT && !SMP. - -Cc: stable-rt@vger.kernel.org -Reported-by: Grygorii Strashko -Tested-by: Grygorii Strashko -Signed-off-by: Sebastian Andrzej Siewior ---- - include/linux/preempt.h | 9 ++++++++ - include/linux/sched.h | 6 ++++++ - kernel/rcu/tree_plugin.h | 2 +- - kernel/sched/core.c | 45 ++++++++++++++++++++++++++++++++++++++++ - 4 files changed, 61 insertions(+), 1 deletion(-) - -diff --git a/include/linux/preempt.h b/include/linux/preempt.h -index 2983043d2194..fd2efc6ffc3f 100644 ---- a/include/linux/preempt.h -+++ b/include/linux/preempt.h -@@ -211,6 +211,15 @@ extern void migrate_enable(void); - - int __migrate_disabled(struct task_struct *p); - -+#elif !defined(CONFIG_SMP) && defined(CONFIG_PREEMPT_RT_BASE) -+ -+extern void migrate_disable(void); -+extern void migrate_enable(void); -+static inline int __migrate_disabled(struct task_struct *p) -+{ -+ return 0; -+} -+ - #else - #define migrate_disable() barrier() - #define migrate_enable() barrier() -diff --git a/include/linux/sched.h b/include/linux/sched.h -index 04403a5a34f1..1689c832ffb3 100644 ---- a/include/linux/sched.h -+++ b/include/linux/sched.h -@@ -631,6 +631,12 @@ struct task_struct { - # ifdef CONFIG_SCHED_DEBUG - int migrate_disable_atomic; - # endif -+ -+#elif !defined(CONFIG_SMP) && defined(CONFIG_PREEMPT_RT_BASE) -+ int migrate_disable; -+# ifdef CONFIG_SCHED_DEBUG -+ int migrate_disable_atomic; -+# endif - #endif - - #ifdef CONFIG_PREEMPT_RCU -diff --git a/kernel/rcu/tree_plugin.h b/kernel/rcu/tree_plugin.h -index 787321ad4f5f..18b98ae934a2 100644 ---- a/kernel/rcu/tree_plugin.h -+++ b/kernel/rcu/tree_plugin.h -@@ -326,7 +326,7 @@ static void rcu_preempt_note_context_switch(bool preempt) - int mg_counter = 0; - - RCU_LOCKDEP_WARN(!irqs_disabled(), "rcu_preempt_note_context_switch() invoked with interrupts enabled!!!\n"); --#if defined(CONFIG_PREEMPT_COUNT) && defined(CONFIG_SMP) -+#if defined(CONFIG_PREEMPT_RT_BASE) - mg_counter = t->migrate_disable; - #endif - WARN_ON_ONCE(!preempt && t->rcu_read_lock_nesting > 0 && !mg_counter); -diff --git a/kernel/sched/core.c b/kernel/sched/core.c -index c9f8f0699885..44c22ff3e6fe 100644 ---- a/kernel/sched/core.c -+++ b/kernel/sched/core.c -@@ -7022,4 +7022,49 @@ void migrate_enable(void) - preempt_enable(); - } - EXPORT_SYMBOL(migrate_enable); -+ -+#elif !defined(CONFIG_SMP) && defined(CONFIG_PREEMPT_RT_BASE) -+void migrate_disable(void) -+{ -+ struct task_struct *p = current; -+ -+ if (in_atomic() || irqs_disabled()) { -+#ifdef CONFIG_SCHED_DEBUG -+ p->migrate_disable_atomic++; -+#endif -+ return; -+ } -+#ifdef CONFIG_SCHED_DEBUG -+ if (unlikely(p->migrate_disable_atomic)) { -+ tracing_off(); -+ WARN_ON_ONCE(1); -+ } -+#endif -+ -+ p->migrate_disable++; -+} -+EXPORT_SYMBOL(migrate_disable); -+ -+void migrate_enable(void) -+{ -+ struct task_struct *p = current; -+ -+ if (in_atomic() || irqs_disabled()) { -+#ifdef CONFIG_SCHED_DEBUG -+ p->migrate_disable_atomic--; -+#endif -+ return; -+ } -+ -+#ifdef CONFIG_SCHED_DEBUG -+ if (unlikely(p->migrate_disable_atomic)) { -+ tracing_off(); -+ WARN_ON_ONCE(1); -+ } -+#endif -+ -+ WARN_ON_ONCE(p->migrate_disable <= 0); -+ p->migrate_disable--; -+} -+EXPORT_SYMBOL(migrate_enable); - #endif --- -2.19.2 - diff --git a/kernel/patches-4.14.x-rt/0265-locking-don-t-check-for-__LINUX_SPINLOCK_TYPES_H-on-.patch b/kernel/patches-4.14.x-rt/0265-locking-don-t-check-for-__LINUX_SPINLOCK_TYPES_H-on-.patch deleted file mode 100644 index 4439eb05c..000000000 --- a/kernel/patches-4.14.x-rt/0265-locking-don-t-check-for-__LINUX_SPINLOCK_TYPES_H-on-.patch +++ /dev/null @@ -1,261 +0,0 @@ -From 86a533488648a2de4592cd00516722d47696a9ef Mon Sep 17 00:00:00 2001 -From: Sebastian Andrzej Siewior -Date: Fri, 4 Aug 2017 17:40:42 +0200 -Subject: [PATCH 265/450] locking: don't check for __LINUX_SPINLOCK_TYPES_H on - -RT archs - -Upstream uses arch_spinlock_t within spinlock_t and requests that -spinlock_types.h header file is included first. -On -RT we have the rt_mutex with its raw_lock wait_lock which needs -architectures' spinlock_types.h header file for its definition. However -we need rt_mutex first because it is used to build the spinlock_t so -that check does not work for us. -Therefore I am dropping that check. - -Signed-off-by: Sebastian Andrzej Siewior ---- - arch/alpha/include/asm/spinlock_types.h | 4 ---- - arch/arm/include/asm/spinlock_types.h | 4 ---- - arch/arm64/include/asm/spinlock_types.h | 4 ---- - arch/blackfin/include/asm/spinlock_types.h | 4 ---- - arch/hexagon/include/asm/spinlock_types.h | 4 ---- - arch/ia64/include/asm/spinlock_types.h | 4 ---- - arch/m32r/include/asm/spinlock_types.h | 4 ---- - arch/metag/include/asm/spinlock_types.h | 4 ---- - arch/mn10300/include/asm/spinlock_types.h | 4 ---- - arch/powerpc/include/asm/spinlock_types.h | 4 ---- - arch/s390/include/asm/spinlock_types.h | 4 ---- - arch/sh/include/asm/spinlock_types.h | 4 ---- - arch/tile/include/asm/spinlock_types.h | 4 ---- - arch/xtensa/include/asm/spinlock_types.h | 4 ---- - include/linux/spinlock_types_up.h | 4 ---- - 15 files changed, 60 deletions(-) - -diff --git a/arch/alpha/include/asm/spinlock_types.h b/arch/alpha/include/asm/spinlock_types.h -index 1d5716bc060b..6883bc952d22 100644 ---- a/arch/alpha/include/asm/spinlock_types.h -+++ b/arch/alpha/include/asm/spinlock_types.h -@@ -2,10 +2,6 @@ - #ifndef _ALPHA_SPINLOCK_TYPES_H - #define _ALPHA_SPINLOCK_TYPES_H - --#ifndef __LINUX_SPINLOCK_TYPES_H --# error "please don't include this file directly" --#endif -- - typedef struct { - volatile unsigned int lock; - } arch_spinlock_t; -diff --git a/arch/arm/include/asm/spinlock_types.h b/arch/arm/include/asm/spinlock_types.h -index 5976958647fe..a37c0803954b 100644 ---- a/arch/arm/include/asm/spinlock_types.h -+++ b/arch/arm/include/asm/spinlock_types.h -@@ -2,10 +2,6 @@ - #ifndef __ASM_SPINLOCK_TYPES_H - #define __ASM_SPINLOCK_TYPES_H - --#ifndef __LINUX_SPINLOCK_TYPES_H --# error "please don't include this file directly" --#endif -- - #define TICKET_SHIFT 16 - - typedef struct { -diff --git a/arch/arm64/include/asm/spinlock_types.h b/arch/arm64/include/asm/spinlock_types.h -index 55be59a35e3f..ba0cf1361f65 100644 ---- a/arch/arm64/include/asm/spinlock_types.h -+++ b/arch/arm64/include/asm/spinlock_types.h -@@ -16,10 +16,6 @@ - #ifndef __ASM_SPINLOCK_TYPES_H - #define __ASM_SPINLOCK_TYPES_H - --#if !defined(__LINUX_SPINLOCK_TYPES_H) && !defined(__ASM_SPINLOCK_H) --# error "please don't include this file directly" --#endif -- - #include - - #define TICKET_SHIFT 16 -diff --git a/arch/blackfin/include/asm/spinlock_types.h b/arch/blackfin/include/asm/spinlock_types.h -index 1a33608c958b..103b34d3dcf6 100644 ---- a/arch/blackfin/include/asm/spinlock_types.h -+++ b/arch/blackfin/include/asm/spinlock_types.h -@@ -7,10 +7,6 @@ - #ifndef __ASM_SPINLOCK_TYPES_H - #define __ASM_SPINLOCK_TYPES_H - --#ifndef __LINUX_SPINLOCK_TYPES_H --# error "please don't include this file directly" --#endif -- - #include - - typedef struct { -diff --git a/arch/hexagon/include/asm/spinlock_types.h b/arch/hexagon/include/asm/spinlock_types.h -index 7a906b5214a4..d8f596fec022 100644 ---- a/arch/hexagon/include/asm/spinlock_types.h -+++ b/arch/hexagon/include/asm/spinlock_types.h -@@ -21,10 +21,6 @@ - #ifndef _ASM_SPINLOCK_TYPES_H - #define _ASM_SPINLOCK_TYPES_H - --#ifndef __LINUX_SPINLOCK_TYPES_H --# error "please don't include this file directly" --#endif -- - typedef struct { - volatile unsigned int lock; - } arch_spinlock_t; -diff --git a/arch/ia64/include/asm/spinlock_types.h b/arch/ia64/include/asm/spinlock_types.h -index 6e345fefcdca..681408d6816f 100644 ---- a/arch/ia64/include/asm/spinlock_types.h -+++ b/arch/ia64/include/asm/spinlock_types.h -@@ -2,10 +2,6 @@ - #ifndef _ASM_IA64_SPINLOCK_TYPES_H - #define _ASM_IA64_SPINLOCK_TYPES_H - --#ifndef __LINUX_SPINLOCK_TYPES_H --# error "please don't include this file directly" --#endif -- - typedef struct { - volatile unsigned int lock; - } arch_spinlock_t; -diff --git a/arch/m32r/include/asm/spinlock_types.h b/arch/m32r/include/asm/spinlock_types.h -index bb0d17b64198..fc6afa42fe11 100644 ---- a/arch/m32r/include/asm/spinlock_types.h -+++ b/arch/m32r/include/asm/spinlock_types.h -@@ -2,10 +2,6 @@ - #ifndef _ASM_M32R_SPINLOCK_TYPES_H - #define _ASM_M32R_SPINLOCK_TYPES_H - --#ifndef __LINUX_SPINLOCK_TYPES_H --# error "please don't include this file directly" --#endif -- - typedef struct { - volatile int slock; - } arch_spinlock_t; -diff --git a/arch/metag/include/asm/spinlock_types.h b/arch/metag/include/asm/spinlock_types.h -index cd197f1bed59..adc26e9797c5 100644 ---- a/arch/metag/include/asm/spinlock_types.h -+++ b/arch/metag/include/asm/spinlock_types.h -@@ -2,10 +2,6 @@ - #ifndef _ASM_METAG_SPINLOCK_TYPES_H - #define _ASM_METAG_SPINLOCK_TYPES_H - --#ifndef __LINUX_SPINLOCK_TYPES_H --# error "please don't include this file directly" --#endif -- - typedef struct { - volatile unsigned int lock; - } arch_spinlock_t; -diff --git a/arch/mn10300/include/asm/spinlock_types.h b/arch/mn10300/include/asm/spinlock_types.h -index 32abdc89bbc7..c45230a12d60 100644 ---- a/arch/mn10300/include/asm/spinlock_types.h -+++ b/arch/mn10300/include/asm/spinlock_types.h -@@ -2,10 +2,6 @@ - #ifndef _ASM_SPINLOCK_TYPES_H - #define _ASM_SPINLOCK_TYPES_H - --#ifndef __LINUX_SPINLOCK_TYPES_H --# error "please don't include this file directly" --#endif -- - typedef struct arch_spinlock { - unsigned int slock; - } arch_spinlock_t; -diff --git a/arch/powerpc/include/asm/spinlock_types.h b/arch/powerpc/include/asm/spinlock_types.h -index 87adaf13b7e8..7305cb6a53e4 100644 ---- a/arch/powerpc/include/asm/spinlock_types.h -+++ b/arch/powerpc/include/asm/spinlock_types.h -@@ -2,10 +2,6 @@ - #ifndef _ASM_POWERPC_SPINLOCK_TYPES_H - #define _ASM_POWERPC_SPINLOCK_TYPES_H - --#ifndef __LINUX_SPINLOCK_TYPES_H --# error "please don't include this file directly" --#endif -- - typedef struct { - volatile unsigned int slock; - } arch_spinlock_t; -diff --git a/arch/s390/include/asm/spinlock_types.h b/arch/s390/include/asm/spinlock_types.h -index 1861a0c5dd47..74092ebaca3c 100644 ---- a/arch/s390/include/asm/spinlock_types.h -+++ b/arch/s390/include/asm/spinlock_types.h -@@ -2,10 +2,6 @@ - #ifndef __ASM_SPINLOCK_TYPES_H - #define __ASM_SPINLOCK_TYPES_H - --#ifndef __LINUX_SPINLOCK_TYPES_H --# error "please don't include this file directly" --#endif -- - typedef struct { - int lock; - } __attribute__ ((aligned (4))) arch_spinlock_t; -diff --git a/arch/sh/include/asm/spinlock_types.h b/arch/sh/include/asm/spinlock_types.h -index e82369f286a2..22ca9a98bbb8 100644 ---- a/arch/sh/include/asm/spinlock_types.h -+++ b/arch/sh/include/asm/spinlock_types.h -@@ -2,10 +2,6 @@ - #ifndef __ASM_SH_SPINLOCK_TYPES_H - #define __ASM_SH_SPINLOCK_TYPES_H - --#ifndef __LINUX_SPINLOCK_TYPES_H --# error "please don't include this file directly" --#endif -- - typedef struct { - volatile unsigned int lock; - } arch_spinlock_t; -diff --git a/arch/tile/include/asm/spinlock_types.h b/arch/tile/include/asm/spinlock_types.h -index a71f59b49c50..9311c6ff2abc 100644 ---- a/arch/tile/include/asm/spinlock_types.h -+++ b/arch/tile/include/asm/spinlock_types.h -@@ -15,10 +15,6 @@ - #ifndef _ASM_TILE_SPINLOCK_TYPES_H - #define _ASM_TILE_SPINLOCK_TYPES_H - --#ifndef __LINUX_SPINLOCK_TYPES_H --# error "please don't include this file directly" --#endif -- - #ifdef __tilegx__ - - /* Low 15 bits are "next"; high 15 bits are "current". */ -diff --git a/arch/xtensa/include/asm/spinlock_types.h b/arch/xtensa/include/asm/spinlock_types.h -index bb1fe6c1816e..8a22f1e7b6c9 100644 ---- a/arch/xtensa/include/asm/spinlock_types.h -+++ b/arch/xtensa/include/asm/spinlock_types.h -@@ -2,10 +2,6 @@ - #ifndef __ASM_SPINLOCK_TYPES_H - #define __ASM_SPINLOCK_TYPES_H - --#ifndef __LINUX_SPINLOCK_TYPES_H --# error "please don't include this file directly" --#endif -- - typedef struct { - volatile unsigned int slock; - } arch_spinlock_t; -diff --git a/include/linux/spinlock_types_up.h b/include/linux/spinlock_types_up.h -index c09b6407ae1b..b0243ba07fb7 100644 ---- a/include/linux/spinlock_types_up.h -+++ b/include/linux/spinlock_types_up.h -@@ -1,10 +1,6 @@ - #ifndef __LINUX_SPINLOCK_TYPES_UP_H - #define __LINUX_SPINLOCK_TYPES_UP_H - --#ifndef __LINUX_SPINLOCK_TYPES_H --# error "please don't include this file directly" --#endif -- - /* - * include/linux/spinlock_types_up.h - spinlock type definitions for UP - * --- -2.19.2 - diff --git a/kernel/patches-4.14.x-rt/0269-rcutree-rcu_bh_qs-Disable-irq-while-calling-rcu_pree.patch b/kernel/patches-4.14.x-rt/0269-rcutree-rcu_bh_qs-Disable-irq-while-calling-rcu_pree.patch deleted file mode 100644 index b922a5b55..000000000 --- a/kernel/patches-4.14.x-rt/0269-rcutree-rcu_bh_qs-Disable-irq-while-calling-rcu_pree.patch +++ /dev/null @@ -1,55 +0,0 @@ -From 2c097d3b0a94fedd8cf237efab16c710d120a642 Mon Sep 17 00:00:00 2001 -From: Tiejun Chen -Date: Wed, 18 Dec 2013 17:51:49 +0800 -Subject: [PATCH 269/450] rcutree/rcu_bh_qs: Disable irq while calling - rcu_preempt_qs() - -Any callers to the function rcu_preempt_qs() must disable irqs in -order to protect the assignment to ->rcu_read_unlock_special. In -RT case, rcu_bh_qs() as the wrapper of rcu_preempt_qs() is called -in some scenarios where irq is enabled, like this path, - -do_single_softirq() - | - + local_irq_enable(); - + handle_softirq() - | | - | + rcu_bh_qs() - | | - | + rcu_preempt_qs() - | - + local_irq_disable() - -So here we'd better disable irq directly inside of rcu_bh_qs() to -fix this, otherwise the kernel may be freezable sometimes as -observed. And especially this way is also kind and safe for the -potential rcu_bh_qs() usage elsewhere in the future. - - -Signed-off-by: Tiejun Chen -Signed-off-by: Bin Jiang -Signed-off-by: Sebastian Andrzej Siewior ---- - kernel/rcu/tree.c | 5 +++++ - 1 file changed, 5 insertions(+) - -diff --git a/kernel/rcu/tree.c b/kernel/rcu/tree.c -index 5e991041f50a..f37d06ec5ee1 100644 ---- a/kernel/rcu/tree.c -+++ b/kernel/rcu/tree.c -@@ -248,7 +248,12 @@ static void rcu_preempt_qs(void); - - void rcu_bh_qs(void) - { -+ unsigned long flags; -+ -+ /* Callers to this function, rcu_preempt_qs(), must disable irqs. */ -+ local_irq_save(flags); - rcu_preempt_qs(); -+ local_irq_restore(flags); - } - #else - void rcu_bh_qs(void) --- -2.19.2 - diff --git a/kernel/patches-4.14.x-rt/0275-fs-namespace-preemption-fix.patch b/kernel/patches-4.14.x-rt/0275-fs-namespace-preemption-fix.patch deleted file mode 100644 index 6e987a520..000000000 --- a/kernel/patches-4.14.x-rt/0275-fs-namespace-preemption-fix.patch +++ /dev/null @@ -1,35 +0,0 @@ -From 77899fdd6dfbc3f2a974498231ae7822a84d24d1 Mon Sep 17 00:00:00 2001 -From: Thomas Gleixner -Date: Sun, 19 Jul 2009 08:44:27 -0500 -Subject: [PATCH 275/450] fs: namespace preemption fix - -On RT we cannot loop with preemption disabled here as -mnt_make_readonly() might have been preempted. We can safely enable -preemption while waiting for MNT_WRITE_HOLD to be cleared. Safe on !RT -as well. - -Signed-off-by: Thomas Gleixner ---- - fs/namespace.c | 5 ++++- - 1 file changed, 4 insertions(+), 1 deletion(-) - -diff --git a/fs/namespace.c b/fs/namespace.c -index e9c13eedd739..47bfbb592a2c 100644 ---- a/fs/namespace.c -+++ b/fs/namespace.c -@@ -353,8 +353,11 @@ int __mnt_want_write(struct vfsmount *m) - * incremented count after it has set MNT_WRITE_HOLD. - */ - smp_mb(); -- while (ACCESS_ONCE(mnt->mnt.mnt_flags) & MNT_WRITE_HOLD) -+ while (ACCESS_ONCE(mnt->mnt.mnt_flags) & MNT_WRITE_HOLD) { -+ preempt_enable(); - cpu_relax(); -+ preempt_disable(); -+ } - /* - * After the slowpath clears MNT_WRITE_HOLD, mnt_is_readonly will - * be set to match its requirements. So we must not load that until --- -2.19.2 - diff --git a/kernel/patches-4.14.x-rt/0277-block-Turn-off-warning-which-is-bogus-on-RT.patch b/kernel/patches-4.14.x-rt/0277-block-Turn-off-warning-which-is-bogus-on-RT.patch deleted file mode 100644 index c8fb096a4..000000000 --- a/kernel/patches-4.14.x-rt/0277-block-Turn-off-warning-which-is-bogus-on-RT.patch +++ /dev/null @@ -1,28 +0,0 @@ -From 2fc78f9f6ab3222710f63e11c01f7fcada05ea3a Mon Sep 17 00:00:00 2001 -From: Thomas Gleixner -Date: Tue, 14 Jun 2011 17:05:09 +0200 -Subject: [PATCH 277/450] block: Turn off warning which is bogus on RT - -On -RT the context is always with IRQs enabled. Ignore this warning on -RT. - -Signed-off-by: Thomas Gleixner ---- - block/blk-core.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/block/blk-core.c b/block/blk-core.c -index 9e3521c4431a..b3edf248d148 100644 ---- a/block/blk-core.c -+++ b/block/blk-core.c -@@ -280,7 +280,7 @@ EXPORT_SYMBOL(blk_start_queue_async); - void blk_start_queue(struct request_queue *q) - { - lockdep_assert_held(q->queue_lock); -- WARN_ON(!in_interrupt() && !irqs_disabled()); -+ WARN_ON_NONRT(!in_interrupt() && !irqs_disabled()); - WARN_ON_ONCE(q->mq_ops); - - queue_flag_clear(QUEUE_FLAG_STOPPED, q); --- -2.19.2 - diff --git a/kernel/patches-4.14.x-rt/0278-fs-ntfs-disable-interrupt-only-on-RT.patch b/kernel/patches-4.14.x-rt/0278-fs-ntfs-disable-interrupt-only-on-RT.patch deleted file mode 100644 index aa0729194..000000000 --- a/kernel/patches-4.14.x-rt/0278-fs-ntfs-disable-interrupt-only-on-RT.patch +++ /dev/null @@ -1,80 +0,0 @@ -From 0d72351ed31f4b49b5cd01fd3c91eb3113c2fe23 Mon Sep 17 00:00:00 2001 -From: Mike Galbraith -Date: Fri, 3 Jul 2009 08:44:12 -0500 -Subject: [PATCH 278/450] fs: ntfs: disable interrupt only on !RT - -On Sat, 2007-10-27 at 11:44 +0200, Ingo Molnar wrote: -> * Nick Piggin wrote: -> -> > > [10138.175796] [] show_trace+0x12/0x14 -> > > [10138.180291] [] dump_stack+0x16/0x18 -> > > [10138.184769] [] native_smp_call_function_mask+0x138/0x13d -> > > [10138.191117] [] smp_call_function+0x1e/0x24 -> > > [10138.196210] [] on_each_cpu+0x25/0x50 -> > > [10138.200807] [] flush_tlb_all+0x1e/0x20 -> > > [10138.205553] [] kmap_high+0x1b6/0x417 -> > > [10138.210118] [] kmap+0x4d/0x4f -> > > [10138.214102] [] ntfs_end_buffer_async_read+0x228/0x2f9 -> > > [10138.220163] [] end_bio_bh_io_sync+0x26/0x3f -> > > [10138.225352] [] bio_endio+0x42/0x6d -> > > [10138.229769] [] __end_that_request_first+0x115/0x4ac -> > > [10138.235682] [] end_that_request_chunk+0x8/0xa -> > > [10138.241052] [] ide_end_request+0x55/0x10a -> > > [10138.246058] [] ide_dma_intr+0x6f/0xac -> > > [10138.250727] [] ide_intr+0x93/0x1e0 -> > > [10138.255125] [] handle_IRQ_event+0x5c/0xc9 -> > -> > Looks like ntfs is kmap()ing from interrupt context. Should be using -> > kmap_atomic instead, I think. -> -> it's not atomic interrupt context but irq thread context - and -rt -> remaps kmap_atomic() to kmap() internally. - -Hm. Looking at the change to mm/bounce.c, perhaps I should do this -instead? - -Signed-off-by: Ingo Molnar -Signed-off-by: Thomas Gleixner ---- - fs/ntfs/aops.c | 8 ++++---- - 1 file changed, 4 insertions(+), 4 deletions(-) - -diff --git a/fs/ntfs/aops.c b/fs/ntfs/aops.c -index e11411997769..a982d7c3ad91 100644 ---- a/fs/ntfs/aops.c -+++ b/fs/ntfs/aops.c -@@ -93,13 +93,13 @@ static void ntfs_end_buffer_async_read(struct buffer_head *bh, int uptodate) - ofs = 0; - if (file_ofs < init_size) - ofs = init_size - file_ofs; -- local_irq_save(flags); -+ local_irq_save_nort(flags); - kaddr = kmap_atomic(page); - memset(kaddr + bh_offset(bh) + ofs, 0, - bh->b_size - ofs); - flush_dcache_page(page); - kunmap_atomic(kaddr); -- local_irq_restore(flags); -+ local_irq_restore_nort(flags); - } - } else { - clear_buffer_uptodate(bh); -@@ -144,13 +144,13 @@ static void ntfs_end_buffer_async_read(struct buffer_head *bh, int uptodate) - recs = PAGE_SIZE / rec_size; - /* Should have been verified before we got here... */ - BUG_ON(!recs); -- local_irq_save(flags); -+ local_irq_save_nort(flags); - kaddr = kmap_atomic(page); - for (i = 0; i < recs; i++) - post_read_mst_fixup((NTFS_RECORD*)(kaddr + - i * rec_size), rec_size); - kunmap_atomic(kaddr); -- local_irq_restore(flags); -+ local_irq_restore_nort(flags); - flush_dcache_page(page); - if (likely(page_uptodate && !PageError(page))) - SetPageUptodate(page); --- -2.19.2 - diff --git a/kernel/patches-4.14.x-rt/0279-fs-jbd2-pull-your-plug-when-waiting-for-space.patch b/kernel/patches-4.14.x-rt/0279-fs-jbd2-pull-your-plug-when-waiting-for-space.patch deleted file mode 100644 index 4594c8bc9..000000000 --- a/kernel/patches-4.14.x-rt/0279-fs-jbd2-pull-your-plug-when-waiting-for-space.patch +++ /dev/null @@ -1,37 +0,0 @@ -From 09a289609a3fdf987214160fc713bf5a412ab407 Mon Sep 17 00:00:00 2001 -From: Sebastian Andrzej Siewior -Date: Mon, 17 Feb 2014 17:30:03 +0100 -Subject: [PATCH 279/450] fs: jbd2: pull your plug when waiting for space - -Two cps in parallel managed to stall the the ext4 fs. It seems that -journal code is either waiting for locks or sleeping waiting for -something to happen. This seems similar to what Mike observed on ext3, -here is his description: - -|With an -rt kernel, and a heavy sync IO load, tasks can jam -|up on journal locks without unplugging, which can lead to -|terminal IO starvation. Unplug and schedule when waiting -|for space. - - -Signed-off-by: Sebastian Andrzej Siewior ---- - fs/jbd2/checkpoint.c | 2 ++ - 1 file changed, 2 insertions(+) - -diff --git a/fs/jbd2/checkpoint.c b/fs/jbd2/checkpoint.c -index fe4fe155b7fb..03f08a7ca5bc 100644 ---- a/fs/jbd2/checkpoint.c -+++ b/fs/jbd2/checkpoint.c -@@ -116,6 +116,8 @@ void __jbd2_log_wait_for_space(journal_t *journal) - nblocks = jbd2_space_needed(journal); - while (jbd2_log_space_left(journal) < nblocks) { - write_unlock(&journal->j_state_lock); -+ if (current->plug) -+ io_schedule(); - mutex_lock(&journal->j_checkpoint_mutex); - - /* --- -2.19.2 - diff --git a/kernel/patches-4.14.x-rt/0280-Revert-fs-jbd2-pull-your-plug-when-waiting-for-space.patch b/kernel/patches-4.14.x-rt/0280-Revert-fs-jbd2-pull-your-plug-when-waiting-for-space.patch deleted file mode 100644 index 08f97350b..000000000 --- a/kernel/patches-4.14.x-rt/0280-Revert-fs-jbd2-pull-your-plug-when-waiting-for-space.patch +++ /dev/null @@ -1,32 +0,0 @@ -From a732209c07fa86aedcfbb0c4d9591ecfb1712857 Mon Sep 17 00:00:00 2001 -From: Sebastian Andrzej Siewior -Date: Thu, 23 Nov 2017 17:51:51 +0100 -Subject: [PATCH 280/450] Revert "fs: jbd2: pull your plug when waiting for - space" - -This reverts commit "fs: jbd2: pull your plug when waiting for space". -This was a duct-tape fix which shouldn't be needed since commit -"locking/rt-mutex: fix deadlock in device mapper / block-IO". - -Cc: stable-rt@vger.kernel.org -Signed-off-by: Sebastian Andrzej Siewior ---- - fs/jbd2/checkpoint.c | 2 -- - 1 file changed, 2 deletions(-) - -diff --git a/fs/jbd2/checkpoint.c b/fs/jbd2/checkpoint.c -index 03f08a7ca5bc..fe4fe155b7fb 100644 ---- a/fs/jbd2/checkpoint.c -+++ b/fs/jbd2/checkpoint.c -@@ -116,8 +116,6 @@ void __jbd2_log_wait_for_space(journal_t *journal) - nblocks = jbd2_space_needed(journal); - while (jbd2_log_space_left(journal) < nblocks) { - write_unlock(&journal->j_state_lock); -- if (current->plug) -- io_schedule(); - mutex_lock(&journal->j_checkpoint_mutex); - - /* --- -2.19.2 - diff --git a/kernel/patches-4.14.x-rt/0283-x86-Convert-mce-timer-to-hrtimer.patch b/kernel/patches-4.14.x-rt/0283-x86-Convert-mce-timer-to-hrtimer.patch deleted file mode 100644 index b8eaa5330..000000000 --- a/kernel/patches-4.14.x-rt/0283-x86-Convert-mce-timer-to-hrtimer.patch +++ /dev/null @@ -1,173 +0,0 @@ -From 47d6f280a4fb9fa2f3856f07da8a7607e3320e5f Mon Sep 17 00:00:00 2001 -From: Thomas Gleixner -Date: Mon, 13 Dec 2010 16:33:39 +0100 -Subject: [PATCH 283/450] x86: Convert mce timer to hrtimer - -mce_timer is started in atomic contexts of cpu bringup. This results -in might_sleep() warnings on RT. Convert mce_timer to a hrtimer to -avoid this. - -Signed-off-by: Thomas Gleixner -fold in: -|From: Mike Galbraith -|Date: Wed, 29 May 2013 13:52:13 +0200 -|Subject: [PATCH] x86/mce: fix mce timer interval -| -|Seems mce timer fire at the wrong frequency in -rt kernels since roughly -|forever due to 32 bit overflow. 3.8-rt is also missing a multiplier. -| -|Add missing us -> ns conversion and 32 bit overflow prevention. -| -|Signed-off-by: Mike Galbraith -|[bigeasy: use ULL instead of u64 cast] -|Signed-off-by: Sebastian Andrzej Siewior ---- - arch/x86/kernel/cpu/mcheck/mce.c | 54 +++++++++++++++----------------- - 1 file changed, 26 insertions(+), 28 deletions(-) - -diff --git a/arch/x86/kernel/cpu/mcheck/mce.c b/arch/x86/kernel/cpu/mcheck/mce.c -index 98e4e4dc4a3b..5cce2ee3b9f6 100644 ---- a/arch/x86/kernel/cpu/mcheck/mce.c -+++ b/arch/x86/kernel/cpu/mcheck/mce.c -@@ -42,6 +42,7 @@ - #include - #include - #include -+#include - #include - - #include -@@ -1365,7 +1366,7 @@ int memory_failure(unsigned long pfn, int vector, int flags) - static unsigned long check_interval = INITIAL_CHECK_INTERVAL; - - static DEFINE_PER_CPU(unsigned long, mce_next_interval); /* in jiffies */ --static DEFINE_PER_CPU(struct timer_list, mce_timer); -+static DEFINE_PER_CPU(struct hrtimer, mce_timer); - - static unsigned long mce_adjust_timer_default(unsigned long interval) - { -@@ -1374,27 +1375,19 @@ static unsigned long mce_adjust_timer_default(unsigned long interval) - - static unsigned long (*mce_adjust_timer)(unsigned long interval) = mce_adjust_timer_default; - --static void __start_timer(struct timer_list *t, unsigned long interval) -+static void __start_timer(struct hrtimer *t, unsigned long iv) - { -- unsigned long when = jiffies + interval; -- unsigned long flags; -- -- local_irq_save(flags); -- -- if (!timer_pending(t) || time_before(when, t->expires)) -- mod_timer(t, round_jiffies(when)); -+ if (!iv) -+ return; - -- local_irq_restore(flags); -+ hrtimer_start_range_ns(t, ns_to_ktime(jiffies_to_usecs(iv) * 1000ULL), -+ 0, HRTIMER_MODE_REL_PINNED); - } - --static void mce_timer_fn(unsigned long data) -+static enum hrtimer_restart mce_timer_fn(struct hrtimer *timer) - { -- struct timer_list *t = this_cpu_ptr(&mce_timer); -- int cpu = smp_processor_id(); - unsigned long iv; - -- WARN_ON(cpu != data); -- - iv = __this_cpu_read(mce_next_interval); - - if (mce_available(this_cpu_ptr(&cpu_info))) { -@@ -1417,7 +1410,11 @@ static void mce_timer_fn(unsigned long data) - - done: - __this_cpu_write(mce_next_interval, iv); -- __start_timer(t, iv); -+ if (!iv) -+ return HRTIMER_NORESTART; -+ -+ hrtimer_forward_now(timer, ns_to_ktime(jiffies_to_nsecs(iv))); -+ return HRTIMER_RESTART; - } - - /* -@@ -1425,7 +1422,7 @@ static void mce_timer_fn(unsigned long data) - */ - void mce_timer_kick(unsigned long interval) - { -- struct timer_list *t = this_cpu_ptr(&mce_timer); -+ struct hrtimer *t = this_cpu_ptr(&mce_timer); - unsigned long iv = __this_cpu_read(mce_next_interval); - - __start_timer(t, interval); -@@ -1440,7 +1437,7 @@ static void mce_timer_delete_all(void) - int cpu; - - for_each_online_cpu(cpu) -- del_timer_sync(&per_cpu(mce_timer, cpu)); -+ hrtimer_cancel(&per_cpu(mce_timer, cpu)); - } - - /* -@@ -1769,7 +1766,7 @@ static void __mcheck_cpu_clear_vendor(struct cpuinfo_x86 *c) - } - } - --static void mce_start_timer(struct timer_list *t) -+static void mce_start_timer(struct hrtimer *t) - { - unsigned long iv = check_interval * HZ; - -@@ -1782,18 +1779,19 @@ static void mce_start_timer(struct timer_list *t) - - static void __mcheck_cpu_setup_timer(void) - { -- struct timer_list *t = this_cpu_ptr(&mce_timer); -- unsigned int cpu = smp_processor_id(); -+ struct hrtimer *t = this_cpu_ptr(&mce_timer); - -- setup_pinned_timer(t, mce_timer_fn, cpu); -+ hrtimer_init(t, CLOCK_MONOTONIC, HRTIMER_MODE_REL); -+ t->function = mce_timer_fn; - } - - static void __mcheck_cpu_init_timer(void) - { -- struct timer_list *t = this_cpu_ptr(&mce_timer); -- unsigned int cpu = smp_processor_id(); -+ struct hrtimer *t = this_cpu_ptr(&mce_timer); -+ -+ hrtimer_init(t, CLOCK_MONOTONIC, HRTIMER_MODE_REL); -+ t->function = mce_timer_fn; - -- setup_pinned_timer(t, mce_timer_fn, cpu); - mce_start_timer(t); - } - -@@ -2309,7 +2307,7 @@ static int mce_cpu_dead(unsigned int cpu) - - static int mce_cpu_online(unsigned int cpu) - { -- struct timer_list *t = this_cpu_ptr(&mce_timer); -+ struct hrtimer *t = this_cpu_ptr(&mce_timer); - int ret; - - mce_device_create(cpu); -@@ -2326,10 +2324,10 @@ static int mce_cpu_online(unsigned int cpu) - - static int mce_cpu_pre_down(unsigned int cpu) - { -- struct timer_list *t = this_cpu_ptr(&mce_timer); -+ struct hrtimer *t = this_cpu_ptr(&mce_timer); - - mce_disable_cpu(); -- del_timer_sync(t); -+ hrtimer_cancel(t); - mce_threshold_remove_device(cpu); - mce_device_remove(cpu); - return 0; --- -2.19.2 - diff --git a/kernel/patches-4.14.x-rt/0284-x86-mce-use-swait-queue-for-mce-wakeups.patch b/kernel/patches-4.14.x-rt/0284-x86-mce-use-swait-queue-for-mce-wakeups.patch deleted file mode 100644 index 0a89d5356..000000000 --- a/kernel/patches-4.14.x-rt/0284-x86-mce-use-swait-queue-for-mce-wakeups.patch +++ /dev/null @@ -1,131 +0,0 @@ -From c9dfaf6f866b9dcdf82ec90717101d20b7599002 Mon Sep 17 00:00:00 2001 -From: Steven Rostedt -Date: Fri, 27 Feb 2015 15:20:37 +0100 -Subject: [PATCH 284/450] x86/mce: use swait queue for mce wakeups - -We had a customer report a lockup on a 3.0-rt kernel that had the -following backtrace: - -[ffff88107fca3e80] rt_spin_lock_slowlock at ffffffff81499113 -[ffff88107fca3f40] rt_spin_lock at ffffffff81499a56 -[ffff88107fca3f50] __wake_up at ffffffff81043379 -[ffff88107fca3f80] mce_notify_irq at ffffffff81017328 -[ffff88107fca3f90] intel_threshold_interrupt at ffffffff81019508 -[ffff88107fca3fa0] smp_threshold_interrupt at ffffffff81019fc1 -[ffff88107fca3fb0] threshold_interrupt at ffffffff814a1853 - -It actually bugged because the lock was taken by the same owner that -already had that lock. What happened was the thread that was setting -itself on a wait queue had the lock when an MCE triggered. The MCE -interrupt does a wake up on its wait list and grabs the same lock. - -NOTE: THIS IS NOT A BUG ON MAINLINE - -Sorry for yelling, but as I Cc'd mainline maintainers I want them to -know that this is an PREEMPT_RT bug only. I only Cc'd them for advice. - -On PREEMPT_RT the wait queue locks are converted from normal -"spin_locks" into an rt_mutex (see the rt_spin_lock_slowlock above). -These are not to be taken by hard interrupt context. This usually isn't -a problem as most all interrupts in PREEMPT_RT are converted into -schedulable threads. Unfortunately that's not the case with the MCE irq. - -As wait queue locks are notorious for long hold times, we can not -convert them to raw_spin_locks without causing issues with -rt. But -Thomas has created a "simple-wait" structure that uses raw spin locks -which may have been a good fit. - -Unfortunately, wait queues are not the only issue, as the mce_notify_irq -also does a schedule_work(), which grabs the workqueue spin locks that -have the exact same issue. - -Thus, this patch I'm proposing is to move the actual work of the MCE -interrupt into a helper thread that gets woken up on the MCE interrupt -and does the work in a schedulable context. - -NOTE: THIS PATCH ONLY CHANGES THE BEHAVIOR WHEN PREEMPT_RT IS SET - -Oops, sorry for yelling again, but I want to stress that I keep the same -behavior of mainline when PREEMPT_RT is not set. Thus, this only changes -the MCE behavior when PREEMPT_RT is configured. - -Signed-off-by: Steven Rostedt -[bigeasy@linutronix: make mce_notify_work() a proper prototype, use - kthread_run()] -Signed-off-by: Sebastian Andrzej Siewior -[wagi: use work-simple framework to defer work to a kthread] -Signed-off-by: Daniel Wagner ---- - arch/x86/kernel/cpu/mcheck/dev-mcelog.c | 37 +++++++++++++++++++++++-- - 1 file changed, 34 insertions(+), 3 deletions(-) - -diff --git a/arch/x86/kernel/cpu/mcheck/dev-mcelog.c b/arch/x86/kernel/cpu/mcheck/dev-mcelog.c -index 7f85b76f43bc..9e74b805070f 100644 ---- a/arch/x86/kernel/cpu/mcheck/dev-mcelog.c -+++ b/arch/x86/kernel/cpu/mcheck/dev-mcelog.c -@@ -14,6 +14,7 @@ - #include - #include - #include -+#include - - #include "mce-internal.h" - -@@ -86,13 +87,43 @@ static void mce_do_trigger(struct work_struct *work) - - static DECLARE_WORK(mce_trigger_work, mce_do_trigger); - -- --void mce_work_trigger(void) -+static void __mce_work_trigger(struct swork_event *event) - { - if (mce_helper[0]) - schedule_work(&mce_trigger_work); - } - -+#ifdef CONFIG_PREEMPT_RT_FULL -+static bool notify_work_ready __read_mostly; -+static struct swork_event notify_work; -+ -+static int mce_notify_work_init(void) -+{ -+ int err; -+ -+ err = swork_get(); -+ if (err) -+ return err; -+ -+ INIT_SWORK(¬ify_work, __mce_work_trigger); -+ notify_work_ready = true; -+ return 0; -+} -+ -+void mce_work_trigger(void) -+{ -+ if (notify_work_ready) -+ swork_queue(¬ify_work); -+} -+ -+#else -+void mce_work_trigger(void) -+{ -+ __mce_work_trigger(NULL); -+} -+static inline int mce_notify_work_init(void) { return 0; } -+#endif -+ - static ssize_t - show_trigger(struct device *s, struct device_attribute *attr, char *buf) - { -@@ -356,7 +387,7 @@ static __init int dev_mcelog_init_device(void) - - return err; - } -- -+ mce_notify_work_init(); - mce_register_decode_chain(&dev_mcelog_nb); - return 0; - } --- -2.19.2 - diff --git a/kernel/patches-4.14.x-rt/0287-x86-UV-raw_spinlock-conversion.patch b/kernel/patches-4.14.x-rt/0287-x86-UV-raw_spinlock-conversion.patch deleted file mode 100644 index 1d19f7f8b..000000000 --- a/kernel/patches-4.14.x-rt/0287-x86-UV-raw_spinlock-conversion.patch +++ /dev/null @@ -1,229 +0,0 @@ -From 470030e88c452ee6759644780d01eff7f4e0fd69 Mon Sep 17 00:00:00 2001 -From: Mike Galbraith -Date: Sun, 2 Nov 2014 08:31:37 +0100 -Subject: [PATCH 287/450] x86: UV: raw_spinlock conversion - -Shrug. Lots of hobbyists have a beast in their basement, right? - - -Signed-off-by: Mike Galbraith -Signed-off-by: Sebastian Andrzej Siewior ---- - arch/x86/include/asm/uv/uv_bau.h | 14 +++++++------- - arch/x86/platform/uv/tlb_uv.c | 26 +++++++++++++------------- - arch/x86/platform/uv/uv_time.c | 20 ++++++++++++-------- - 3 files changed, 32 insertions(+), 28 deletions(-) - -diff --git a/arch/x86/include/asm/uv/uv_bau.h b/arch/x86/include/asm/uv/uv_bau.h -index 7cac79802ad2..2ac6e347bdc5 100644 ---- a/arch/x86/include/asm/uv/uv_bau.h -+++ b/arch/x86/include/asm/uv/uv_bau.h -@@ -643,9 +643,9 @@ struct bau_control { - cycles_t send_message; - cycles_t period_end; - cycles_t period_time; -- spinlock_t uvhub_lock; -- spinlock_t queue_lock; -- spinlock_t disable_lock; -+ raw_spinlock_t uvhub_lock; -+ raw_spinlock_t queue_lock; -+ raw_spinlock_t disable_lock; - /* tunables */ - int max_concurr; - int max_concurr_const; -@@ -847,15 +847,15 @@ static inline int atom_asr(short i, struct atomic_short *v) - * to be lowered below the current 'v'. atomic_add_unless can only stop - * on equal. - */ --static inline int atomic_inc_unless_ge(spinlock_t *lock, atomic_t *v, int u) -+static inline int atomic_inc_unless_ge(raw_spinlock_t *lock, atomic_t *v, int u) - { -- spin_lock(lock); -+ raw_spin_lock(lock); - if (atomic_read(v) >= u) { -- spin_unlock(lock); -+ raw_spin_unlock(lock); - return 0; - } - atomic_inc(v); -- spin_unlock(lock); -+ raw_spin_unlock(lock); - return 1; - } - -diff --git a/arch/x86/platform/uv/tlb_uv.c b/arch/x86/platform/uv/tlb_uv.c -index 34f9a9ce6236..5607611df740 100644 ---- a/arch/x86/platform/uv/tlb_uv.c -+++ b/arch/x86/platform/uv/tlb_uv.c -@@ -740,9 +740,9 @@ static void destination_plugged(struct bau_desc *bau_desc, - - quiesce_local_uvhub(hmaster); - -- spin_lock(&hmaster->queue_lock); -+ raw_spin_lock(&hmaster->queue_lock); - reset_with_ipi(&bau_desc->distribution, bcp); -- spin_unlock(&hmaster->queue_lock); -+ raw_spin_unlock(&hmaster->queue_lock); - - end_uvhub_quiesce(hmaster); - -@@ -762,9 +762,9 @@ static void destination_timeout(struct bau_desc *bau_desc, - - quiesce_local_uvhub(hmaster); - -- spin_lock(&hmaster->queue_lock); -+ raw_spin_lock(&hmaster->queue_lock); - reset_with_ipi(&bau_desc->distribution, bcp); -- spin_unlock(&hmaster->queue_lock); -+ raw_spin_unlock(&hmaster->queue_lock); - - end_uvhub_quiesce(hmaster); - -@@ -785,7 +785,7 @@ static void disable_for_period(struct bau_control *bcp, struct ptc_stats *stat) - cycles_t tm1; - - hmaster = bcp->uvhub_master; -- spin_lock(&hmaster->disable_lock); -+ raw_spin_lock(&hmaster->disable_lock); - if (!bcp->baudisabled) { - stat->s_bau_disabled++; - tm1 = get_cycles(); -@@ -798,7 +798,7 @@ static void disable_for_period(struct bau_control *bcp, struct ptc_stats *stat) - } - } - } -- spin_unlock(&hmaster->disable_lock); -+ raw_spin_unlock(&hmaster->disable_lock); - } - - static void count_max_concurr(int stat, struct bau_control *bcp, -@@ -861,7 +861,7 @@ static void record_send_stats(cycles_t time1, cycles_t time2, - */ - static void uv1_throttle(struct bau_control *hmaster, struct ptc_stats *stat) - { -- spinlock_t *lock = &hmaster->uvhub_lock; -+ raw_spinlock_t *lock = &hmaster->uvhub_lock; - atomic_t *v; - - v = &hmaster->active_descriptor_count; -@@ -995,7 +995,7 @@ static int check_enable(struct bau_control *bcp, struct ptc_stats *stat) - struct bau_control *hmaster; - - hmaster = bcp->uvhub_master; -- spin_lock(&hmaster->disable_lock); -+ raw_spin_lock(&hmaster->disable_lock); - if (bcp->baudisabled && (get_cycles() >= bcp->set_bau_on_time)) { - stat->s_bau_reenabled++; - for_each_present_cpu(tcpu) { -@@ -1007,10 +1007,10 @@ static int check_enable(struct bau_control *bcp, struct ptc_stats *stat) - tbcp->period_giveups = 0; - } - } -- spin_unlock(&hmaster->disable_lock); -+ raw_spin_unlock(&hmaster->disable_lock); - return 0; - } -- spin_unlock(&hmaster->disable_lock); -+ raw_spin_unlock(&hmaster->disable_lock); - return -1; - } - -@@ -1942,9 +1942,9 @@ static void __init init_per_cpu_tunables(void) - bcp->cong_reps = congested_reps; - bcp->disabled_period = sec_2_cycles(disabled_period); - bcp->giveup_limit = giveup_limit; -- spin_lock_init(&bcp->queue_lock); -- spin_lock_init(&bcp->uvhub_lock); -- spin_lock_init(&bcp->disable_lock); -+ raw_spin_lock_init(&bcp->queue_lock); -+ raw_spin_lock_init(&bcp->uvhub_lock); -+ raw_spin_lock_init(&bcp->disable_lock); - } - } - -diff --git a/arch/x86/platform/uv/uv_time.c b/arch/x86/platform/uv/uv_time.c -index b082d71b08ee..badf377efc21 100644 ---- a/arch/x86/platform/uv/uv_time.c -+++ b/arch/x86/platform/uv/uv_time.c -@@ -57,7 +57,7 @@ static DEFINE_PER_CPU(struct clock_event_device, cpu_ced); - - /* There is one of these allocated per node */ - struct uv_rtc_timer_head { -- spinlock_t lock; -+ raw_spinlock_t lock; - /* next cpu waiting for timer, local node relative: */ - int next_cpu; - /* number of cpus on this node: */ -@@ -177,7 +177,7 @@ static __init int uv_rtc_allocate_timers(void) - uv_rtc_deallocate_timers(); - return -ENOMEM; - } -- spin_lock_init(&head->lock); -+ raw_spin_lock_init(&head->lock); - head->ncpus = uv_blade_nr_possible_cpus(bid); - head->next_cpu = -1; - blade_info[bid] = head; -@@ -231,7 +231,7 @@ static int uv_rtc_set_timer(int cpu, u64 expires) - unsigned long flags; - int next_cpu; - -- spin_lock_irqsave(&head->lock, flags); -+ raw_spin_lock_irqsave(&head->lock, flags); - - next_cpu = head->next_cpu; - *t = expires; -@@ -243,12 +243,12 @@ static int uv_rtc_set_timer(int cpu, u64 expires) - if (uv_setup_intr(cpu, expires)) { - *t = ULLONG_MAX; - uv_rtc_find_next_timer(head, pnode); -- spin_unlock_irqrestore(&head->lock, flags); -+ raw_spin_unlock_irqrestore(&head->lock, flags); - return -ETIME; - } - } - -- spin_unlock_irqrestore(&head->lock, flags); -+ raw_spin_unlock_irqrestore(&head->lock, flags); - return 0; - } - -@@ -267,7 +267,7 @@ static int uv_rtc_unset_timer(int cpu, int force) - unsigned long flags; - int rc = 0; - -- spin_lock_irqsave(&head->lock, flags); -+ raw_spin_lock_irqsave(&head->lock, flags); - - if ((head->next_cpu == bcpu && uv_read_rtc(NULL) >= *t) || force) - rc = 1; -@@ -279,7 +279,7 @@ static int uv_rtc_unset_timer(int cpu, int force) - uv_rtc_find_next_timer(head, pnode); - } - -- spin_unlock_irqrestore(&head->lock, flags); -+ raw_spin_unlock_irqrestore(&head->lock, flags); - - return rc; - } -@@ -299,13 +299,17 @@ static int uv_rtc_unset_timer(int cpu, int force) - static u64 uv_read_rtc(struct clocksource *cs) - { - unsigned long offset; -+ u64 cycles; - -+ preempt_disable(); - if (uv_get_min_hub_revision_id() == 1) - offset = 0; - else - offset = (uv_blade_processor_id() * L1_CACHE_BYTES) % PAGE_SIZE; - -- return (u64)uv_read_local_mmr(UVH_RTC | offset); -+ cycles = (u64)uv_read_local_mmr(UVH_RTC | offset); -+ preempt_enable(); -+ return cycles; - } - - /* --- -2.19.2 - diff --git a/kernel/patches-4.14.x-rt/0295-md-raid5-do-not-disable-interrupts.patch b/kernel/patches-4.14.x-rt/0295-md-raid5-do-not-disable-interrupts.patch deleted file mode 100644 index ebcd22209..000000000 --- a/kernel/patches-4.14.x-rt/0295-md-raid5-do-not-disable-interrupts.patch +++ /dev/null @@ -1,60 +0,0 @@ -From 2705da3c07149ffffcefb1fa85526ac5c2034d12 Mon Sep 17 00:00:00 2001 -From: Sebastian Andrzej Siewior -Date: Fri, 17 Nov 2017 16:21:00 +0100 -Subject: [PATCH 295/450] md/raid5: do not disable interrupts - -|BUG: sleeping function called from invalid context at kernel/locking/rtmutex.c:974 -|in_atomic(): 0, irqs_disabled(): 1, pid: 2992, name: lvm -|CPU: 2 PID: 2992 Comm: lvm Not tainted 4.13.10-rt3+ #54 -|Call Trace: -| dump_stack+0x4f/0x65 -| ___might_sleep+0xfc/0x150 -| atomic_dec_and_spin_lock+0x3c/0x80 -| raid5_release_stripe+0x73/0x110 -| grow_one_stripe+0xce/0xf0 -| setup_conf+0x841/0xaa0 -| raid5_run+0x7e7/0xa40 -| md_run+0x515/0xaf0 -| raid_ctr+0x147d/0x25e0 -| dm_table_add_target+0x155/0x320 -| table_load+0x103/0x320 -| ctl_ioctl+0x1d9/0x510 -| dm_ctl_ioctl+0x9/0x10 -| do_vfs_ioctl+0x8e/0x670 -| SyS_ioctl+0x3c/0x70 -| entry_SYSCALL_64_fastpath+0x17/0x98 - -The interrupts were disabled because ->device_lock is taken with -interrupts disabled. - -Cc: stable-rt@vger.kernel.org -Signed-off-by: Sebastian Andrzej Siewior ---- - drivers/md/raid5.c | 4 ++-- - 1 file changed, 2 insertions(+), 2 deletions(-) - -diff --git a/drivers/md/raid5.c b/drivers/md/raid5.c -index dd0c17736633..5cfccaf87687 100644 ---- a/drivers/md/raid5.c -+++ b/drivers/md/raid5.c -@@ -410,7 +410,7 @@ void raid5_release_stripe(struct stripe_head *sh) - md_wakeup_thread(conf->mddev->thread); - return; - slow_path: -- local_irq_save(flags); -+ local_irq_save_nort(flags); - /* we are ok here if STRIPE_ON_RELEASE_LIST is set or not */ - if (atomic_dec_and_lock(&sh->count, &conf->device_lock)) { - INIT_LIST_HEAD(&list); -@@ -419,7 +419,7 @@ void raid5_release_stripe(struct stripe_head *sh) - spin_unlock(&conf->device_lock); - release_inactive_stripe_list(conf, &list, hash); - } -- local_irq_restore(flags); -+ local_irq_restore_nort(flags); - } - - static inline void remove_hash(struct stripe_head *sh) --- -2.19.2 - diff --git a/kernel/patches-4.14.x-rt/0297-cpu_chill-Add-a-UNINTERRUPTIBLE-hrtimer_nanosleep.patch b/kernel/patches-4.14.x-rt/0297-cpu_chill-Add-a-UNINTERRUPTIBLE-hrtimer_nanosleep.patch deleted file mode 100644 index cb2248925..000000000 --- a/kernel/patches-4.14.x-rt/0297-cpu_chill-Add-a-UNINTERRUPTIBLE-hrtimer_nanosleep.patch +++ /dev/null @@ -1,108 +0,0 @@ -From 23b34d8a6e474c7025ac9cddd5cddfba5dd2d56a Mon Sep 17 00:00:00 2001 -From: Steven Rostedt -Date: Tue, 4 Mar 2014 12:28:32 -0500 -Subject: [PATCH 297/450] cpu_chill: Add a UNINTERRUPTIBLE hrtimer_nanosleep - -We hit another bug that was caused by switching cpu_chill() from -msleep() to hrtimer_nanosleep(). - -This time it is a livelock. The problem is that hrtimer_nanosleep() -calls schedule with the state == TASK_INTERRUPTIBLE. But these means -that if a signal is pending, the scheduler wont schedule, and will -simply change the current task state back to TASK_RUNNING. This -nullifies the whole point of cpu_chill() in the first place. That is, -if a task is spinning on a try_lock() and it preempted the owner of the -lock, if it has a signal pending, it will never give up the CPU to let -the owner of the lock run. - -I made a static function __hrtimer_nanosleep() that takes a fifth -parameter "state", which determines the task state of that the -nanosleep() will be in. The normal hrtimer_nanosleep() will act the -same, but cpu_chill() will call the __hrtimer_nanosleep() directly with -the TASK_UNINTERRUPTIBLE state. - -cpu_chill() only cares that the first sleep happens, and does not care -about the state of the restart schedule (in hrtimer_nanosleep_restart). - - -Reported-by: Ulrich Obergfell -Signed-off-by: Steven Rostedt -Signed-off-by: Sebastian Andrzej Siewior ---- - kernel/time/hrtimer.c | 24 +++++++++++++++++------- - 1 file changed, 17 insertions(+), 7 deletions(-) - -diff --git a/kernel/time/hrtimer.c b/kernel/time/hrtimer.c -index ad67ac12d6b6..6c77643eaf02 100644 ---- a/kernel/time/hrtimer.c -+++ b/kernel/time/hrtimer.c -@@ -1742,12 +1742,13 @@ int nanosleep_copyout(struct restart_block *restart, struct timespec64 *ts) - return -ERESTART_RESTARTBLOCK; - } - --static int __sched do_nanosleep(struct hrtimer_sleeper *t, enum hrtimer_mode mode) -+static int __sched do_nanosleep(struct hrtimer_sleeper *t, enum hrtimer_mode mode, -+ unsigned long state) - { - struct restart_block *restart; - - do { -- set_current_state(TASK_INTERRUPTIBLE); -+ set_current_state(state); - hrtimer_start_expires(&t->timer, mode); - - if (likely(t->task)) -@@ -1785,13 +1786,15 @@ static long __sched hrtimer_nanosleep_restart(struct restart_block *restart) - hrtimer_init_sleeper_on_stack(&t, restart->nanosleep.clockid, - HRTIMER_MODE_ABS, current); - hrtimer_set_expires_tv64(&t.timer, restart->nanosleep.expires); -- ret = do_nanosleep(&t, HRTIMER_MODE_ABS); -+ /* cpu_chill() does not care about restart state. */ -+ ret = do_nanosleep(&t, HRTIMER_MODE_ABS, TASK_INTERRUPTIBLE); - destroy_hrtimer_on_stack(&t.timer); - return ret; - } - --long hrtimer_nanosleep(const struct timespec64 *rqtp, -- const enum hrtimer_mode mode, const clockid_t clockid) -+static long __hrtimer_nanosleep(const struct timespec64 *rqtp, -+ const enum hrtimer_mode mode, const clockid_t clockid, -+ unsigned long state) - { - struct restart_block *restart; - struct hrtimer_sleeper t; -@@ -1804,7 +1807,7 @@ long hrtimer_nanosleep(const struct timespec64 *rqtp, - - hrtimer_init_sleeper_on_stack(&t, clockid, mode, current); - hrtimer_set_expires_range_ns(&t.timer, timespec64_to_ktime(*rqtp), slack); -- ret = do_nanosleep(&t, mode); -+ ret = do_nanosleep(&t, mode, state); - if (ret != -ERESTART_RESTARTBLOCK) - goto out; - -@@ -1823,6 +1826,12 @@ long hrtimer_nanosleep(const struct timespec64 *rqtp, - return ret; - } - -+long hrtimer_nanosleep(const struct timespec64 *rqtp, -+ const enum hrtimer_mode mode, const clockid_t clockid) -+{ -+ return __hrtimer_nanosleep(rqtp, mode, clockid, TASK_INTERRUPTIBLE); -+} -+ - SYSCALL_DEFINE2(nanosleep, struct timespec __user *, rqtp, - struct timespec __user *, rmtp) - { -@@ -1870,7 +1879,8 @@ void cpu_chill(void) - unsigned int freeze_flag = current->flags & PF_NOFREEZE; - - current->flags |= PF_NOFREEZE; -- hrtimer_nanosleep(&tu, HRTIMER_MODE_REL_HARD, CLOCK_MONOTONIC); -+ __hrtimer_nanosleep(&tu, HRTIMER_MODE_REL_HARD, CLOCK_MONOTONIC, -+ TASK_UNINTERRUPTIBLE); - if (!freeze_flag) - current->flags &= ~PF_NOFREEZE; - } --- -2.19.2 - diff --git a/kernel/patches-4.14.x-rt/0298-kernel-cpu_chill-use-schedule_hrtimeout.patch b/kernel/patches-4.14.x-rt/0298-kernel-cpu_chill-use-schedule_hrtimeout.patch deleted file mode 100644 index 941c44cfe..000000000 --- a/kernel/patches-4.14.x-rt/0298-kernel-cpu_chill-use-schedule_hrtimeout.patch +++ /dev/null @@ -1,46 +0,0 @@ -From 7a5da5da915b3f847332aadcbc23c51673943579 Mon Sep 17 00:00:00 2001 -From: Sebastian Andrzej Siewior -Date: Fri, 16 Mar 2018 13:07:59 +0100 -Subject: [PATCH 298/450] kernel/cpu_chill: use schedule_hrtimeout() - -If a task calls cpu_chill() and gets woken up by a regular or spurious -wakeup and has a signal pending, then it exits the sleep loop in -do_nanosleep() and sets up the restart block. If restart->nanosleep.type is -not TI_NONE then this results in accessing a stale user pointer from a -previously interrupted syscall and a copy to user based on the stale -pointer or a BUG() when 'type' is not supported in nanosleep_copyout(). - -Instead all this trouble, use schedule_hrtimeout(). - -Cc: stable-rt@vger.kernel.org -Signed-off-by: Sebastian Andrzej Siewior ---- - kernel/time/hrtimer.c | 9 ++++----- - 1 file changed, 4 insertions(+), 5 deletions(-) - -diff --git a/kernel/time/hrtimer.c b/kernel/time/hrtimer.c -index 6c77643eaf02..c0efc22ba635 100644 ---- a/kernel/time/hrtimer.c -+++ b/kernel/time/hrtimer.c -@@ -1873,14 +1873,13 @@ COMPAT_SYSCALL_DEFINE2(nanosleep, struct compat_timespec __user *, rqtp, - */ - void cpu_chill(void) - { -- struct timespec64 tu = { -- .tv_nsec = NSEC_PER_MSEC, -- }; -+ ktime_t chill_time; - unsigned int freeze_flag = current->flags & PF_NOFREEZE; - -+ chill_time = ktime_set(0, NSEC_PER_MSEC); -+ set_current_state(TASK_UNINTERRUPTIBLE); - current->flags |= PF_NOFREEZE; -- __hrtimer_nanosleep(&tu, HRTIMER_MODE_REL_HARD, CLOCK_MONOTONIC, -- TASK_UNINTERRUPTIBLE); -+ schedule_hrtimeout(&chill_time, HRTIMER_MODE_REL_HARD); - if (!freeze_flag) - current->flags &= ~PF_NOFREEZE; - } --- -2.19.2 - diff --git a/kernel/patches-4.14.x-rt/0299-Revert-cpu_chill-Add-a-UNINTERRUPTIBLE-hrtimer_nanos.patch b/kernel/patches-4.14.x-rt/0299-Revert-cpu_chill-Add-a-UNINTERRUPTIBLE-hrtimer_nanos.patch deleted file mode 100644 index 5aaec2016..000000000 --- a/kernel/patches-4.14.x-rt/0299-Revert-cpu_chill-Add-a-UNINTERRUPTIBLE-hrtimer_nanos.patch +++ /dev/null @@ -1,80 +0,0 @@ -From 9c6140c9ba1a5991e6fb52bf1705d3129d255d3a Mon Sep 17 00:00:00 2001 -From: Sebastian Andrzej Siewior -Date: Fri, 16 Mar 2018 15:04:49 +0100 -Subject: [PATCH 299/450] Revert "cpu_chill: Add a UNINTERRUPTIBLE - hrtimer_nanosleep" - -This reverts commit "cpu_chill: Add a UNINTERRUPTIBLE -hrtimer_nanosleep". Since cpu_chill() is now using schedule_hrtimeout() -we can remove that change since we have no users for it. - -Cc: stable-rt@vger.kernel.org -Signed-off-by: Sebastian Andrzej Siewior ---- - kernel/time/hrtimer.c | 21 ++++++--------------- - 1 file changed, 6 insertions(+), 15 deletions(-) - -diff --git a/kernel/time/hrtimer.c b/kernel/time/hrtimer.c -index c0efc22ba635..ce2c2d04cbaa 100644 ---- a/kernel/time/hrtimer.c -+++ b/kernel/time/hrtimer.c -@@ -1742,13 +1742,12 @@ int nanosleep_copyout(struct restart_block *restart, struct timespec64 *ts) - return -ERESTART_RESTARTBLOCK; - } - --static int __sched do_nanosleep(struct hrtimer_sleeper *t, enum hrtimer_mode mode, -- unsigned long state) -+static int __sched do_nanosleep(struct hrtimer_sleeper *t, enum hrtimer_mode mode) - { - struct restart_block *restart; - - do { -- set_current_state(state); -+ set_current_state(TASK_INTERRUPTIBLE); - hrtimer_start_expires(&t->timer, mode); - - if (likely(t->task)) -@@ -1786,15 +1785,13 @@ static long __sched hrtimer_nanosleep_restart(struct restart_block *restart) - hrtimer_init_sleeper_on_stack(&t, restart->nanosleep.clockid, - HRTIMER_MODE_ABS, current); - hrtimer_set_expires_tv64(&t.timer, restart->nanosleep.expires); -- /* cpu_chill() does not care about restart state. */ -- ret = do_nanosleep(&t, HRTIMER_MODE_ABS, TASK_INTERRUPTIBLE); -+ ret = do_nanosleep(&t, HRTIMER_MODE_ABS); - destroy_hrtimer_on_stack(&t.timer); - return ret; - } - --static long __hrtimer_nanosleep(const struct timespec64 *rqtp, -- const enum hrtimer_mode mode, const clockid_t clockid, -- unsigned long state) -+long hrtimer_nanosleep(const struct timespec64 *rqtp, -+ const enum hrtimer_mode mode, const clockid_t clockid) - { - struct restart_block *restart; - struct hrtimer_sleeper t; -@@ -1807,7 +1804,7 @@ static long __hrtimer_nanosleep(const struct timespec64 *rqtp, - - hrtimer_init_sleeper_on_stack(&t, clockid, mode, current); - hrtimer_set_expires_range_ns(&t.timer, timespec64_to_ktime(*rqtp), slack); -- ret = do_nanosleep(&t, mode, state); -+ ret = do_nanosleep(&t, mode); - if (ret != -ERESTART_RESTARTBLOCK) - goto out; - -@@ -1826,12 +1823,6 @@ static long __hrtimer_nanosleep(const struct timespec64 *rqtp, - return ret; - } - --long hrtimer_nanosleep(const struct timespec64 *rqtp, -- const enum hrtimer_mode mode, const clockid_t clockid) --{ -- return __hrtimer_nanosleep(rqtp, mode, clockid, TASK_INTERRUPTIBLE); --} -- - SYSCALL_DEFINE2(nanosleep, struct timespec __user *, rqtp, - struct timespec __user *, rmtp) - { --- -2.19.2 - diff --git a/kernel/patches-4.14.x-rt/0303-fs-dcache-Use-cpu_chill-in-trylock-loops.patch b/kernel/patches-4.14.x-rt/0303-fs-dcache-Use-cpu_chill-in-trylock-loops.patch deleted file mode 100644 index 6184e2226..000000000 --- a/kernel/patches-4.14.x-rt/0303-fs-dcache-Use-cpu_chill-in-trylock-loops.patch +++ /dev/null @@ -1,118 +0,0 @@ -From 01650e0ff97ecbd4e530cbf632c89c771f118f37 Mon Sep 17 00:00:00 2001 -From: Thomas Gleixner -Date: Wed, 7 Mar 2012 21:00:34 +0100 -Subject: [PATCH 303/450] fs: dcache: Use cpu_chill() in trylock loops - -Retry loops on RT might loop forever when the modifying side was -preempted. Use cpu_chill() instead of cpu_relax() to let the system -make progress. - -Signed-off-by: Thomas Gleixner ---- - fs/autofs4/autofs_i.h | 1 + - fs/autofs4/expire.c | 2 +- - fs/dcache.c | 20 ++++++++++++++++---- - fs/namespace.c | 3 ++- - 4 files changed, 20 insertions(+), 6 deletions(-) - -diff --git a/fs/autofs4/autofs_i.h b/fs/autofs4/autofs_i.h -index ce696d6c4641..b120fbd41483 100644 ---- a/fs/autofs4/autofs_i.h -+++ b/fs/autofs4/autofs_i.h -@@ -20,6 +20,7 @@ - #include - #include - #include -+#include - #include - #include - #include -diff --git a/fs/autofs4/expire.c b/fs/autofs4/expire.c -index 57725d4a8c59..62220508bace 100644 ---- a/fs/autofs4/expire.c -+++ b/fs/autofs4/expire.c -@@ -148,7 +148,7 @@ static struct dentry *get_next_positive_dentry(struct dentry *prev, - parent = p->d_parent; - if (!spin_trylock(&parent->d_lock)) { - spin_unlock(&p->d_lock); -- cpu_relax(); -+ cpu_chill(); - goto relock; - } - spin_unlock(&p->d_lock); -diff --git a/fs/dcache.c b/fs/dcache.c -index 8aa63a9d18cd..c00380d37a3a 100644 ---- a/fs/dcache.c -+++ b/fs/dcache.c -@@ -19,6 +19,7 @@ - #include - #include - #include -+#include - #include - #include - #include -@@ -808,6 +809,8 @@ static inline bool fast_dput(struct dentry *dentry) - */ - void dput(struct dentry *dentry) - { -+ struct dentry *parent; -+ - if (unlikely(!dentry)) - return; - -@@ -844,9 +847,18 @@ void dput(struct dentry *dentry) - return; - - kill_it: -- dentry = dentry_kill(dentry); -- if (dentry) { -- cond_resched(); -+ parent = dentry_kill(dentry); -+ if (parent) { -+ int r; -+ -+ if (parent == dentry) { -+ /* the task with the highest priority won't schedule */ -+ r = cond_resched(); -+ if (!r) -+ cpu_chill(); -+ } else { -+ dentry = parent; -+ } - goto repeat; - } - } -@@ -2414,7 +2426,7 @@ void d_delete(struct dentry * dentry) - if (dentry->d_lockref.count == 1) { - if (!spin_trylock(&inode->i_lock)) { - spin_unlock(&dentry->d_lock); -- cpu_relax(); -+ cpu_chill(); - goto again; - } - dentry->d_flags &= ~DCACHE_CANT_MOUNT; -diff --git a/fs/namespace.c b/fs/namespace.c -index 47bfbb592a2c..991a2054bad9 100644 ---- a/fs/namespace.c -+++ b/fs/namespace.c -@@ -14,6 +14,7 @@ - #include - #include - #include -+#include - #include - #include - #include -@@ -355,7 +356,7 @@ int __mnt_want_write(struct vfsmount *m) - smp_mb(); - while (ACCESS_ONCE(mnt->mnt.mnt_flags) & MNT_WRITE_HOLD) { - preempt_enable(); -- cpu_relax(); -+ cpu_chill(); - preempt_disable(); - } - /* --- -2.19.2 - diff --git a/kernel/patches-4.14.x-rt/0310-percpu_ida-Use-local-locks.patch b/kernel/patches-4.14.x-rt/0310-percpu_ida-Use-local-locks.patch deleted file mode 100644 index c9226c928..000000000 --- a/kernel/patches-4.14.x-rt/0310-percpu_ida-Use-local-locks.patch +++ /dev/null @@ -1,107 +0,0 @@ -From a6c51384a63d6f33598449898ed3f0c63ec0410e Mon Sep 17 00:00:00 2001 -From: Sebastian Andrzej Siewior -Date: Wed, 9 Apr 2014 11:58:17 +0200 -Subject: [PATCH 310/450] percpu_ida: Use local locks - -the local_irq_save() + spin_lock() does not work that well on -RT - -Signed-off-by: Sebastian Andrzej Siewior ---- - lib/percpu_ida.c | 20 ++++++++++++-------- - 1 file changed, 12 insertions(+), 8 deletions(-) - -diff --git a/lib/percpu_ida.c b/lib/percpu_ida.c -index 6016f1deb1f5..cdd43086b55b 100644 ---- a/lib/percpu_ida.c -+++ b/lib/percpu_ida.c -@@ -27,6 +27,9 @@ - #include - #include - #include -+#include -+ -+static DEFINE_LOCAL_IRQ_LOCK(irq_off_lock); - - struct percpu_ida_cpu { - /* -@@ -149,13 +152,13 @@ int percpu_ida_alloc(struct percpu_ida *pool, int state) - unsigned long flags; - int tag; - -- local_irq_save(flags); -+ local_lock_irqsave(irq_off_lock, flags); - tags = this_cpu_ptr(pool->tag_cpu); - - /* Fastpath */ - tag = alloc_local_tag(tags); - if (likely(tag >= 0)) { -- local_irq_restore(flags); -+ local_unlock_irqrestore(irq_off_lock, flags); - return tag; - } - -@@ -174,6 +177,7 @@ int percpu_ida_alloc(struct percpu_ida *pool, int state) - - if (!tags->nr_free) - alloc_global_tags(pool, tags); -+ - if (!tags->nr_free) - steal_tags(pool, tags); - -@@ -185,7 +189,7 @@ int percpu_ida_alloc(struct percpu_ida *pool, int state) - } - - spin_unlock(&pool->lock); -- local_irq_restore(flags); -+ local_unlock_irqrestore(irq_off_lock, flags); - - if (tag >= 0 || state == TASK_RUNNING) - break; -@@ -197,7 +201,7 @@ int percpu_ida_alloc(struct percpu_ida *pool, int state) - - schedule(); - -- local_irq_save(flags); -+ local_lock_irqsave(irq_off_lock, flags); - tags = this_cpu_ptr(pool->tag_cpu); - } - if (state != TASK_RUNNING) -@@ -222,7 +226,7 @@ void percpu_ida_free(struct percpu_ida *pool, unsigned tag) - - BUG_ON(tag >= pool->nr_tags); - -- local_irq_save(flags); -+ local_lock_irqsave(irq_off_lock, flags); - tags = this_cpu_ptr(pool->tag_cpu); - - spin_lock(&tags->lock); -@@ -254,7 +258,7 @@ void percpu_ida_free(struct percpu_ida *pool, unsigned tag) - spin_unlock(&pool->lock); - } - -- local_irq_restore(flags); -+ local_unlock_irqrestore(irq_off_lock, flags); - } - EXPORT_SYMBOL_GPL(percpu_ida_free); - -@@ -346,7 +350,7 @@ int percpu_ida_for_each_free(struct percpu_ida *pool, percpu_ida_cb fn, - struct percpu_ida_cpu *remote; - unsigned cpu, i, err = 0; - -- local_irq_save(flags); -+ local_lock_irqsave(irq_off_lock, flags); - for_each_possible_cpu(cpu) { - remote = per_cpu_ptr(pool->tag_cpu, cpu); - spin_lock(&remote->lock); -@@ -368,7 +372,7 @@ int percpu_ida_for_each_free(struct percpu_ida *pool, percpu_ida_cb fn, - } - spin_unlock(&pool->lock); - out: -- local_irq_restore(flags); -+ local_unlock_irqrestore(irq_off_lock, flags); - return err; - } - EXPORT_SYMBOL_GPL(percpu_ida_for_each_free); --- -2.19.2 - diff --git a/kernel/patches-4.14.x-rt/0316-net-core-cpuhotplug-Drain-input_pkt_queue-lockless.patch b/kernel/patches-4.14.x-rt/0316-net-core-cpuhotplug-Drain-input_pkt_queue-lockless.patch deleted file mode 100644 index f43901c58..000000000 --- a/kernel/patches-4.14.x-rt/0316-net-core-cpuhotplug-Drain-input_pkt_queue-lockless.patch +++ /dev/null @@ -1,52 +0,0 @@ -From eb700e9352fbbbe85063578727f9d03235f6a0ac Mon Sep 17 00:00:00 2001 -From: Grygorii Strashko -Date: Fri, 9 Oct 2015 09:25:49 -0500 -Subject: [PATCH 316/450] net/core/cpuhotplug: Drain input_pkt_queue lockless - -I can constantly see below error report with 4.1 RT-kernel on TI ARM dra7-evm -if I'm trying to unplug cpu1: - -[ 57.737589] CPU1: shutdown -[ 57.767537] BUG: spinlock bad magic on CPU#0, sh/137 -[ 57.767546] lock: 0xee994730, .magic: 00000000, .owner: /-1, .owner_cpu: 0 -[ 57.767552] CPU: 0 PID: 137 Comm: sh Not tainted 4.1.10-rt8-01700-g2c38702-dirty #55 -[ 57.767555] Hardware name: Generic DRA74X (Flattened Device Tree) -[ 57.767568] [] (unwind_backtrace) from [] (show_stack+0x20/0x24) -[ 57.767579] [] (show_stack) from [] (dump_stack+0x84/0xa0) -[ 57.767593] [] (dump_stack) from [] (spin_dump+0x84/0xac) -[ 57.767603] [] (spin_dump) from [] (spin_bug+0x34/0x38) -[ 57.767614] [] (spin_bug) from [] (do_raw_spin_lock+0x168/0x1c0) -[ 57.767624] [] (do_raw_spin_lock) from [] (_raw_spin_lock+0x4c/0x54) -[ 57.767631] [] (_raw_spin_lock) from [] (rt_spin_lock_slowlock+0x5c/0x374) -[ 57.767638] [] (rt_spin_lock_slowlock) from [] (rt_spin_lock+0x38/0x70) -[ 57.767649] [] (rt_spin_lock) from [] (skb_dequeue+0x28/0x7c) -[ 57.767662] [] (skb_dequeue) from [] (dev_cpu_callback+0x1b8/0x240) -[ 57.767673] [] (dev_cpu_callback) from [] (notifier_call_chain+0x3c/0xb4) - -The reason is that skb_dequeue is taking skb->lock, but RT changed the -core code to use a raw spinlock. The non-raw lock is not initialized -on purpose to catch exactly this kind of problem. - -Fixes: 91df05da13a6 'net: Use skbufhead with raw lock' -Signed-off-by: Thomas Gleixner -Cc: stable-rt@vger.kernel.org ---- - net/core/dev.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/net/core/dev.c b/net/core/dev.c -index b26b1b82f680..093b2bf46ce7 100644 ---- a/net/core/dev.c -+++ b/net/core/dev.c -@@ -8477,7 +8477,7 @@ static int dev_cpu_dead(unsigned int oldcpu) - netif_rx_ni(skb); - input_queue_head_incr(oldsd); - } -- while ((skb = skb_dequeue(&oldsd->input_pkt_queue))) { -+ while ((skb = __skb_dequeue(&oldsd->input_pkt_queue))) { - netif_rx_ni(skb); - input_queue_head_incr(oldsd); - } --- -2.19.2 - diff --git a/kernel/patches-4.14.x-rt/0317-net-move-xmit_recursion-to-per-task-variable-on-RT.patch b/kernel/patches-4.14.x-rt/0317-net-move-xmit_recursion-to-per-task-variable-on-RT.patch deleted file mode 100644 index 2a438696c..000000000 --- a/kernel/patches-4.14.x-rt/0317-net-move-xmit_recursion-to-per-task-variable-on-RT.patch +++ /dev/null @@ -1,162 +0,0 @@ -From 60d98d8d56aaf5ef8a9c8f74d26326df8fba4a24 Mon Sep 17 00:00:00 2001 -From: Sebastian Andrzej Siewior -Date: Wed, 13 Jan 2016 15:55:02 +0100 -Subject: [PATCH 317/450] net: move xmit_recursion to per-task variable on -RT - -A softirq on -RT can be preempted. That means one task is in -__dev_queue_xmit(), gets preempted and another task may enter -__dev_queue_xmit() aw well. netperf together with a bridge device -will then trigger the `recursion alert` because each task increments -the xmit_recursion variable which is per-CPU. -A virtual device like br0 is required to trigger this warning. - -This patch moves the counter to per task instead per-CPU so it counts -the recursion properly on -RT. - -Cc: stable-rt@vger.kernel.org -Signed-off-by: Sebastian Andrzej Siewior ---- - include/linux/netdevice.h | 41 ++++++++++++++++++++++++++++++++++++++- - include/linux/sched.h | 3 +++ - net/core/dev.c | 9 +++++---- - net/core/filter.c | 6 +++--- - 4 files changed, 51 insertions(+), 8 deletions(-) - -diff --git a/include/linux/netdevice.h b/include/linux/netdevice.h -index fd318a3b4fc1..4480f0907e55 100644 ---- a/include/linux/netdevice.h -+++ b/include/linux/netdevice.h -@@ -2440,14 +2440,53 @@ void netdev_freemem(struct net_device *dev); - void synchronize_net(void); - int init_dummy_netdev(struct net_device *dev); - --DECLARE_PER_CPU(int, xmit_recursion); - #define XMIT_RECURSION_LIMIT 10 -+#ifdef CONFIG_PREEMPT_RT_FULL -+static inline int dev_recursion_level(void) -+{ -+ return current->xmit_recursion; -+} -+ -+static inline int xmit_rec_read(void) -+{ -+ return current->xmit_recursion; -+} -+ -+static inline void xmit_rec_inc(void) -+{ -+ current->xmit_recursion++; -+} -+ -+static inline void xmit_rec_dec(void) -+{ -+ current->xmit_recursion--; -+} -+ -+#else -+ -+DECLARE_PER_CPU(int, xmit_recursion); - - static inline int dev_recursion_level(void) - { - return this_cpu_read(xmit_recursion); - } - -+static inline int xmit_rec_read(void) -+{ -+ return __this_cpu_read(xmit_recursion); -+} -+ -+static inline void xmit_rec_inc(void) -+{ -+ __this_cpu_inc(xmit_recursion); -+} -+ -+static inline void xmit_rec_dec(void) -+{ -+ __this_cpu_dec(xmit_recursion); -+} -+#endif -+ - struct net_device *dev_get_by_index(struct net *net, int ifindex); - struct net_device *__dev_get_by_index(struct net *net, int ifindex); - struct net_device *dev_get_by_index_rcu(struct net *net, int ifindex); -diff --git a/include/linux/sched.h b/include/linux/sched.h -index 675cbae7adfb..ff13666bc6dd 100644 ---- a/include/linux/sched.h -+++ b/include/linux/sched.h -@@ -1155,6 +1155,9 @@ struct task_struct { - #endif - #ifdef CONFIG_DEBUG_ATOMIC_SLEEP - unsigned long task_state_change; -+#endif -+#ifdef CONFIG_PREEMPT_RT_FULL -+ int xmit_recursion; - #endif - int pagefault_disabled; - #ifdef CONFIG_MMU -diff --git a/net/core/dev.c b/net/core/dev.c -index 093b2bf46ce7..73161f5455d1 100644 ---- a/net/core/dev.c -+++ b/net/core/dev.c -@@ -3270,8 +3270,10 @@ static void skb_update_prio(struct sk_buff *skb) - #define skb_update_prio(skb) - #endif - -+#ifndef CONFIG_PREEMPT_RT_FULL - DEFINE_PER_CPU(int, xmit_recursion); - EXPORT_SYMBOL(xmit_recursion); -+#endif - - /** - * dev_loopback_xmit - loop back @skb -@@ -3512,8 +3514,7 @@ static int __dev_queue_xmit(struct sk_buff *skb, void *accel_priv) - int cpu = smp_processor_id(); /* ok because BHs are off */ - - if (txq->xmit_lock_owner != cpu) { -- if (unlikely(__this_cpu_read(xmit_recursion) > -- XMIT_RECURSION_LIMIT)) -+ if (unlikely(xmit_rec_read() > XMIT_RECURSION_LIMIT)) - goto recursion_alert; - - skb = validate_xmit_skb(skb, dev); -@@ -3523,9 +3524,9 @@ static int __dev_queue_xmit(struct sk_buff *skb, void *accel_priv) - HARD_TX_LOCK(dev, txq, cpu); - - if (!netif_xmit_stopped(txq)) { -- __this_cpu_inc(xmit_recursion); -+ xmit_rec_inc(); - skb = dev_hard_start_xmit(skb, dev, txq, &rc); -- __this_cpu_dec(xmit_recursion); -+ xmit_rec_dec(); - if (dev_xmit_complete(rc)) { - HARD_TX_UNLOCK(dev, txq); - goto out; -diff --git a/net/core/filter.c b/net/core/filter.c -index d5158a10ac8f..ad96ec78f7b8 100644 ---- a/net/core/filter.c -+++ b/net/core/filter.c -@@ -1696,7 +1696,7 @@ static inline int __bpf_tx_skb(struct net_device *dev, struct sk_buff *skb) - { - int ret; - -- if (unlikely(__this_cpu_read(xmit_recursion) > XMIT_RECURSION_LIMIT)) { -+ if (unlikely(xmit_rec_read() > XMIT_RECURSION_LIMIT)) { - net_crit_ratelimited("bpf: recursion limit reached on datapath, buggy bpf program?\n"); - kfree_skb(skb); - return -ENETDOWN; -@@ -1704,9 +1704,9 @@ static inline int __bpf_tx_skb(struct net_device *dev, struct sk_buff *skb) - - skb->dev = dev; - -- __this_cpu_inc(xmit_recursion); -+ xmit_rec_inc(); - ret = dev_queue_xmit(skb); -- __this_cpu_dec(xmit_recursion); -+ xmit_rec_dec(); - - return ret; - } --- -2.19.2 - diff --git a/kernel/patches-4.14.x-rt/0318-net-use-task_struct-instead-of-CPU-number-as-the-que.patch b/kernel/patches-4.14.x-rt/0318-net-use-task_struct-instead-of-CPU-number-as-the-que.patch deleted file mode 100644 index c3c8552ca..000000000 --- a/kernel/patches-4.14.x-rt/0318-net-use-task_struct-instead-of-CPU-number-as-the-que.patch +++ /dev/null @@ -1,153 +0,0 @@ -From 3a58c2a589dd012d6bc31e7f0b2c4415f1b3903c Mon Sep 17 00:00:00 2001 -From: Sebastian Andrzej Siewior -Date: Wed, 21 Feb 2018 10:39:54 +0100 -Subject: [PATCH 318/450] net: use task_struct instead of CPU number as the - queue owner on -RT - -In commit ("net: move xmit_recursion to per-task variable on -RT") the -recursion level was changed to be per-task since we can get preempted in -BH on -RT. The lock owner should consequently be recorded as the task -that holds the lock and not the CPU. Otherwise we trigger the "Dead loop -on virtual device" warning on SMP systems. - -Cc: stable-rt@vger.kernel.org -Reported-by: Kurt Kanzenbach -Tested-by: Kurt Kanzenbach -Signed-off-by: Sebastian Andrzej Siewior ---- - include/linux/netdevice.h | 54 ++++++++++++++++++++++++++++++++++----- - net/core/dev.c | 6 ++++- - 2 files changed, 53 insertions(+), 7 deletions(-) - -diff --git a/include/linux/netdevice.h b/include/linux/netdevice.h -index 4480f0907e55..6b891e37d8e3 100644 ---- a/include/linux/netdevice.h -+++ b/include/linux/netdevice.h -@@ -571,7 +571,11 @@ struct netdev_queue { - * write-mostly part - */ - spinlock_t _xmit_lock ____cacheline_aligned_in_smp; -+#ifdef CONFIG_PREEMPT_RT_FULL -+ struct task_struct *xmit_lock_owner; -+#else - int xmit_lock_owner; -+#endif - /* - * Time (in jiffies) of last Tx - */ -@@ -3562,10 +3566,48 @@ static inline u32 netif_msg_init(int debug_value, int default_msg_enable_bits) - return (1 << debug_value) - 1; - } - -+#ifdef CONFIG_PREEMPT_RT_FULL -+static inline void netdev_queue_set_owner(struct netdev_queue *txq, int cpu) -+{ -+ txq->xmit_lock_owner = current; -+} -+ -+static inline void netdev_queue_clear_owner(struct netdev_queue *txq) -+{ -+ txq->xmit_lock_owner = NULL; -+} -+ -+static inline bool netdev_queue_has_owner(struct netdev_queue *txq) -+{ -+ if (txq->xmit_lock_owner != NULL) -+ return true; -+ return false; -+} -+ -+#else -+ -+static inline void netdev_queue_set_owner(struct netdev_queue *txq, int cpu) -+{ -+ txq->xmit_lock_owner = cpu; -+} -+ -+static inline void netdev_queue_clear_owner(struct netdev_queue *txq) -+{ -+ txq->xmit_lock_owner = -1; -+} -+ -+static inline bool netdev_queue_has_owner(struct netdev_queue *txq) -+{ -+ if (txq->xmit_lock_owner != -1) -+ return true; -+ return false; -+} -+#endif -+ - static inline void __netif_tx_lock(struct netdev_queue *txq, int cpu) - { - spin_lock(&txq->_xmit_lock); -- txq->xmit_lock_owner = cpu; -+ netdev_queue_set_owner(txq, cpu); - } - - static inline bool __netif_tx_acquire(struct netdev_queue *txq) -@@ -3582,32 +3624,32 @@ static inline void __netif_tx_release(struct netdev_queue *txq) - static inline void __netif_tx_lock_bh(struct netdev_queue *txq) - { - spin_lock_bh(&txq->_xmit_lock); -- txq->xmit_lock_owner = smp_processor_id(); -+ netdev_queue_set_owner(txq, smp_processor_id()); - } - - static inline bool __netif_tx_trylock(struct netdev_queue *txq) - { - bool ok = spin_trylock(&txq->_xmit_lock); - if (likely(ok)) -- txq->xmit_lock_owner = smp_processor_id(); -+ netdev_queue_set_owner(txq, smp_processor_id()); - return ok; - } - - static inline void __netif_tx_unlock(struct netdev_queue *txq) - { -- txq->xmit_lock_owner = -1; -+ netdev_queue_clear_owner(txq); - spin_unlock(&txq->_xmit_lock); - } - - static inline void __netif_tx_unlock_bh(struct netdev_queue *txq) - { -- txq->xmit_lock_owner = -1; -+ netdev_queue_clear_owner(txq); - spin_unlock_bh(&txq->_xmit_lock); - } - - static inline void txq_trans_update(struct netdev_queue *txq) - { -- if (txq->xmit_lock_owner != -1) -+ if (netdev_queue_has_owner(txq)) - txq->trans_start = jiffies; - } - -diff --git a/net/core/dev.c b/net/core/dev.c -index 73161f5455d1..8d35a35d99a0 100644 ---- a/net/core/dev.c -+++ b/net/core/dev.c -@@ -3513,7 +3513,11 @@ static int __dev_queue_xmit(struct sk_buff *skb, void *accel_priv) - if (dev->flags & IFF_UP) { - int cpu = smp_processor_id(); /* ok because BHs are off */ - -+#ifdef CONFIG_PREEMPT_RT_FULL -+ if (txq->xmit_lock_owner != current) { -+#else - if (txq->xmit_lock_owner != cpu) { -+#endif - if (unlikely(xmit_rec_read() > XMIT_RECURSION_LIMIT)) - goto recursion_alert; - -@@ -7524,7 +7528,7 @@ static void netdev_init_one_queue(struct net_device *dev, - /* Initialize queue lock */ - spin_lock_init(&queue->_xmit_lock); - netdev_set_xmit_lockdep_class(&queue->_xmit_lock, dev->type); -- queue->xmit_lock_owner = -1; -+ netdev_queue_clear_owner(queue); - netdev_queue_numa_node_write(queue, NUMA_NO_NODE); - queue->dev = dev; - #ifdef CONFIG_BQL --- -2.19.2 - diff --git a/kernel/patches-4.14.x-rt/0323-net-take-the-tcp_sk_lock-lock-with-BH-disabled.patch b/kernel/patches-4.14.x-rt/0323-net-take-the-tcp_sk_lock-lock-with-BH-disabled.patch deleted file mode 100644 index 89322ad5d..000000000 --- a/kernel/patches-4.14.x-rt/0323-net-take-the-tcp_sk_lock-lock-with-BH-disabled.patch +++ /dev/null @@ -1,73 +0,0 @@ -From f63534d5a04a3fe4e7501e511d51e271e8884efe Mon Sep 17 00:00:00 2001 -From: Sebastian Andrzej Siewior -Date: Mon, 21 Aug 2017 15:09:13 +0200 -Subject: [PATCH 323/450] net: take the tcp_sk_lock lock with BH disabled - -Lockdep may complain about an unsafe locking scenario: -| CPU0 CPU1 -| ---- ---- -| lock((tcp_sk_lock).lock); -| lock(&per_cpu(local_softirq_locks[i], __cpu).lock); -| lock((tcp_sk_lock).lock); -| lock(&per_cpu(local_softirq_locks[i], __cpu).lock); - -in the call paths: - do_current_softirqs -> tcp_v4_send_ack() -vs - tcp_v4_send_reset -> do_current_softirqs(). - -This should not happen since local_softirq_locks is per CPU. Reversing -the order makes lockdep happy. - -Reported-by: Jacek Konieczny -Signed-off-by: Sebastian Andrzej Siewior ---- - net/ipv4/tcp_ipv4.c | 8 ++++---- - 1 file changed, 4 insertions(+), 4 deletions(-) - -diff --git a/net/ipv4/tcp_ipv4.c b/net/ipv4/tcp_ipv4.c -index a08d68e97bdb..851f241e70b5 100644 ---- a/net/ipv4/tcp_ipv4.c -+++ b/net/ipv4/tcp_ipv4.c -@@ -711,8 +711,8 @@ static void tcp_v4_send_reset(const struct sock *sk, struct sk_buff *skb) - - arg.tos = ip_hdr(skb)->tos; - arg.uid = sock_net_uid(net, sk && sk_fullsock(sk) ? sk : NULL); -- local_lock(tcp_sk_lock); - local_bh_disable(); -+ local_lock(tcp_sk_lock); - ip_send_unicast_reply(*this_cpu_ptr(net->ipv4.tcp_sk), - skb, &TCP_SKB_CB(skb)->header.h4.opt, - ip_hdr(skb)->saddr, ip_hdr(skb)->daddr, -@@ -720,8 +720,8 @@ static void tcp_v4_send_reset(const struct sock *sk, struct sk_buff *skb) - - __TCP_INC_STATS(net, TCP_MIB_OUTSEGS); - __TCP_INC_STATS(net, TCP_MIB_OUTRSTS); -- local_bh_enable(); - local_unlock(tcp_sk_lock); -+ local_bh_enable(); - - #ifdef CONFIG_TCP_MD5SIG - out: -@@ -799,16 +799,16 @@ static void tcp_v4_send_ack(const struct sock *sk, - arg.bound_dev_if = oif; - arg.tos = tos; - arg.uid = sock_net_uid(net, sk_fullsock(sk) ? sk : NULL); -- local_lock(tcp_sk_lock); - local_bh_disable(); -+ local_lock(tcp_sk_lock); - ip_send_unicast_reply(*this_cpu_ptr(net->ipv4.tcp_sk), - skb, &TCP_SKB_CB(skb)->header.h4.opt, - ip_hdr(skb)->saddr, ip_hdr(skb)->daddr, - &arg, arg.iov[0].iov_len); - - __TCP_INC_STATS(net, TCP_MIB_OUTSEGS); -- local_bh_enable(); - local_unlock(tcp_sk_lock); -+ local_bh_enable(); - } - - static void tcp_v4_timewait_ack(struct sock *sk, struct sk_buff *skb) --- -2.19.2 - diff --git a/kernel/patches-4.14.x-rt/0324-net-add-a-lock-around-icmp_sk.patch b/kernel/patches-4.14.x-rt/0324-net-add-a-lock-around-icmp_sk.patch deleted file mode 100644 index abba335fc..000000000 --- a/kernel/patches-4.14.x-rt/0324-net-add-a-lock-around-icmp_sk.patch +++ /dev/null @@ -1,71 +0,0 @@ -From b0befb6b2f25d200ec4d384aae4fbf621f6e41d7 Mon Sep 17 00:00:00 2001 -From: Sebastian Andrzej Siewior -Date: Wed, 31 Aug 2016 17:54:09 +0200 -Subject: [PATCH 324/450] net: add a lock around icmp_sk() - -It looks like the this_cpu_ptr() access in icmp_sk() is protected with -local_bh_disable(). To avoid missing serialization in -RT I am adding -here a local lock. No crash has been observed, this is just precaution. - -Cc: stable-rt@vger.kernel.org -Signed-off-by: Sebastian Andrzej Siewior ---- - net/ipv4/icmp.c | 7 +++++++ - 1 file changed, 7 insertions(+) - -diff --git a/net/ipv4/icmp.c b/net/ipv4/icmp.c -index 3c1570d3e22f..6e1ae84d662c 100644 ---- a/net/ipv4/icmp.c -+++ b/net/ipv4/icmp.c -@@ -77,6 +77,7 @@ - #include - #include - #include -+#include - #include - #include - #include -@@ -204,6 +205,8 @@ static const struct icmp_control icmp_pointers[NR_ICMP_TYPES+1]; - * - * On SMP we have one ICMP socket per-cpu. - */ -+static DEFINE_LOCAL_IRQ_LOCK(icmp_sk_lock); -+ - static struct sock *icmp_sk(struct net *net) - { - return *this_cpu_ptr(net->ipv4.icmp_sk); -@@ -417,6 +420,7 @@ static void icmp_reply(struct icmp_bxm *icmp_param, struct sk_buff *skb) - - /* Needed by both icmp_global_allow and icmp_xmit_lock */ - local_bh_disable(); -+ local_lock(icmp_sk_lock); - - /* global icmp_msgs_per_sec */ - if (!icmpv4_global_allow(net, type, code)) -@@ -461,6 +465,7 @@ static void icmp_reply(struct icmp_bxm *icmp_param, struct sk_buff *skb) - out_unlock: - icmp_xmit_unlock(sk); - out_bh_enable: -+ local_unlock(icmp_sk_lock); - local_bh_enable(); - } - -@@ -656,6 +661,7 @@ void icmp_send(struct sk_buff *skb_in, int type, int code, __be32 info) - - /* Needed by both icmp_global_allow and icmp_xmit_lock */ - local_bh_disable(); -+ local_lock(icmp_sk_lock); - - /* Check global sysctl_icmp_msgs_per_sec ratelimit, unless - * incoming dev is loopback. If outgoing dev change to not be -@@ -744,6 +750,7 @@ void icmp_send(struct sk_buff *skb_in, int type, int code, __be32 info) - out_unlock: - icmp_xmit_unlock(sk); - out_bh_enable: -+ local_unlock(icmp_sk_lock); - local_bh_enable(); - out:; - } --- -2.19.2 - diff --git a/kernel/patches-4.14.x-rt/0325-net-use-trylock-in-icmp_sk.patch b/kernel/patches-4.14.x-rt/0325-net-use-trylock-in-icmp_sk.patch deleted file mode 100644 index 0acfb18d6..000000000 --- a/kernel/patches-4.14.x-rt/0325-net-use-trylock-in-icmp_sk.patch +++ /dev/null @@ -1,79 +0,0 @@ -From babaed17d873a03392afd8ffb8244cebee8146fe Mon Sep 17 00:00:00 2001 -From: Sebastian Andrzej Siewior -Date: Thu, 21 Sep 2017 14:42:04 +0200 -Subject: [PATCH 325/450] net: use trylock in icmp_sk - -The locking path can be recursive (same as for sk->sk_lock.slock) and -therefore we need a trylock version for the locallock, too. - -Cc: stable-rt@vger.kernel.org -Reported-by: Jacek Konieczny -Signed-off-by: Sebastian Andrzej Siewior ---- - net/ipv4/icmp.c | 9 +++++---- - 1 file changed, 5 insertions(+), 4 deletions(-) - -diff --git a/net/ipv4/icmp.c b/net/ipv4/icmp.c -index 6e1ae84d662c..0310ea93f877 100644 ---- a/net/ipv4/icmp.c -+++ b/net/ipv4/icmp.c -@@ -217,12 +217,16 @@ static inline struct sock *icmp_xmit_lock(struct net *net) - { - struct sock *sk; - -+ if (!local_trylock(icmp_sk_lock)) -+ return NULL; -+ - sk = icmp_sk(net); - - if (unlikely(!spin_trylock(&sk->sk_lock.slock))) { - /* This can happen if the output path signals a - * dst_link_failure() for an outgoing ICMP packet. - */ -+ local_unlock(icmp_sk_lock); - return NULL; - } - return sk; -@@ -231,6 +235,7 @@ static inline struct sock *icmp_xmit_lock(struct net *net) - static inline void icmp_xmit_unlock(struct sock *sk) - { - spin_unlock(&sk->sk_lock.slock); -+ local_unlock(icmp_sk_lock); - } - - int sysctl_icmp_msgs_per_sec __read_mostly = 1000; -@@ -420,7 +425,6 @@ static void icmp_reply(struct icmp_bxm *icmp_param, struct sk_buff *skb) - - /* Needed by both icmp_global_allow and icmp_xmit_lock */ - local_bh_disable(); -- local_lock(icmp_sk_lock); - - /* global icmp_msgs_per_sec */ - if (!icmpv4_global_allow(net, type, code)) -@@ -465,7 +469,6 @@ static void icmp_reply(struct icmp_bxm *icmp_param, struct sk_buff *skb) - out_unlock: - icmp_xmit_unlock(sk); - out_bh_enable: -- local_unlock(icmp_sk_lock); - local_bh_enable(); - } - -@@ -661,7 +664,6 @@ void icmp_send(struct sk_buff *skb_in, int type, int code, __be32 info) - - /* Needed by both icmp_global_allow and icmp_xmit_lock */ - local_bh_disable(); -- local_lock(icmp_sk_lock); - - /* Check global sysctl_icmp_msgs_per_sec ratelimit, unless - * incoming dev is loopback. If outgoing dev change to not be -@@ -750,7 +752,6 @@ void icmp_send(struct sk_buff *skb_in, int type, int code, __be32 info) - out_unlock: - icmp_xmit_unlock(sk); - out_bh_enable: -- local_unlock(icmp_sk_lock); - local_bh_enable(); - out:; - } --- -2.19.2 - diff --git a/kernel/patches-4.14.x-rt/0328-irqwork-Move-irq-safe-work-to-irq-context.patch b/kernel/patches-4.14.x-rt/0328-irqwork-Move-irq-safe-work-to-irq-context.patch deleted file mode 100644 index 1c7ca060a..000000000 --- a/kernel/patches-4.14.x-rt/0328-irqwork-Move-irq-safe-work-to-irq-context.patch +++ /dev/null @@ -1,87 +0,0 @@ -From 7b1fee64ed369ee92692ea1690d11461950f8f9d Mon Sep 17 00:00:00 2001 -From: Thomas Gleixner -Date: Sun, 15 Nov 2015 18:40:17 +0100 -Subject: [PATCH 328/450] irqwork: Move irq safe work to irq context - -On architectures where arch_irq_work_has_interrupt() returns false, we -end up running the irq safe work from the softirq context. That -results in a potential deadlock in the scheduler irq work which -expects that function to be called with interrupts disabled. - -Split the irq_work_tick() function into a hard and soft variant. Call -the hard variant from the tick interrupt and add the soft variant to -the timer softirq. - -Reported-and-tested-by: Yanjiang Jin -Signed-off-by: Thomas Gleixner -Cc: stable-rt@vger.kernel.org ---- - include/linux/irq_work.h | 6 ++++++ - kernel/irq_work.c | 9 +++++++++ - kernel/time/timer.c | 6 ++---- - 3 files changed, 17 insertions(+), 4 deletions(-) - -diff --git a/include/linux/irq_work.h b/include/linux/irq_work.h -index 929fb9091d16..1e66fac6f1d2 100644 ---- a/include/linux/irq_work.h -+++ b/include/linux/irq_work.h -@@ -53,4 +53,10 @@ static inline bool irq_work_needs_cpu(void) { return false; } - static inline void irq_work_run(void) { } - #endif - -+#if defined(CONFIG_IRQ_WORK) && defined(CONFIG_PREEMPT_RT_FULL) -+void irq_work_tick_soft(void); -+#else -+static inline void irq_work_tick_soft(void) { } -+#endif -+ - #endif /* _LINUX_IRQ_WORK_H */ -diff --git a/kernel/irq_work.c b/kernel/irq_work.c -index 0ddaf1e66d8c..2899ba0d23d1 100644 ---- a/kernel/irq_work.c -+++ b/kernel/irq_work.c -@@ -200,8 +200,17 @@ void irq_work_tick(void) - - if (!llist_empty(raised) && !arch_irq_work_has_interrupt()) - irq_work_run_list(raised); -+ -+ if (!IS_ENABLED(CONFIG_PREEMPT_RT_FULL)) -+ irq_work_run_list(this_cpu_ptr(&lazy_list)); -+} -+ -+#if defined(CONFIG_IRQ_WORK) && defined(CONFIG_PREEMPT_RT_FULL) -+void irq_work_tick_soft(void) -+{ - irq_work_run_list(this_cpu_ptr(&lazy_list)); - } -+#endif - - /* - * Synchronize against the irq_work @entry, ensures the entry is not -diff --git a/kernel/time/timer.c b/kernel/time/timer.c -index 2362b03051aa..ea742b49bdb5 100644 ---- a/kernel/time/timer.c -+++ b/kernel/time/timer.c -@@ -1638,7 +1638,7 @@ void update_process_times(int user_tick) - scheduler_tick(); - run_local_timers(); - rcu_check_callbacks(user_tick); --#if defined(CONFIG_IRQ_WORK) && !defined(CONFIG_PREEMPT_RT_FULL) -+#if defined(CONFIG_IRQ_WORK) - if (in_irq()) - irq_work_tick(); - #endif -@@ -1695,9 +1695,7 @@ static __latent_entropy void run_timer_softirq(struct softirq_action *h) - { - struct timer_base *base = this_cpu_ptr(&timer_bases[BASE_STD]); - --#if defined(CONFIG_IRQ_WORK) && defined(CONFIG_PREEMPT_RT_FULL) -- irq_work_tick(); --#endif -+ irq_work_tick_soft(); - __run_timers(base); - if (IS_ENABLED(CONFIG_NO_HZ_COMMON)) - __run_timers(this_cpu_ptr(&timer_bases[BASE_DEF])); --- -2.19.2 - diff --git a/kernel/patches-4.14.x-rt/0329-snd-pcm-fix-snd_pcm_stream_lock-irqs_disabled-splats.patch b/kernel/patches-4.14.x-rt/0329-snd-pcm-fix-snd_pcm_stream_lock-irqs_disabled-splats.patch deleted file mode 100644 index 8ad937070..000000000 --- a/kernel/patches-4.14.x-rt/0329-snd-pcm-fix-snd_pcm_stream_lock-irqs_disabled-splats.patch +++ /dev/null @@ -1,76 +0,0 @@ -From f2c0ec10c4936c60a5619e06c6c3ed3bcb69c51f Mon Sep 17 00:00:00 2001 -From: Mike Galbraith -Date: Wed, 18 Feb 2015 15:09:23 +0100 -Subject: [PATCH 329/450] snd/pcm: fix snd_pcm_stream_lock*() irqs_disabled() - splats - -Locking functions previously using read_lock_irq()/read_lock_irqsave() were -changed to local_irq_disable/save(), leading to gripes. Use nort variants. - -|BUG: sleeping function called from invalid context at kernel/locking/rtmutex.c:915 -|in_atomic(): 0, irqs_disabled(): 1, pid: 5947, name: alsa-sink-ALC88 -|CPU: 5 PID: 5947 Comm: alsa-sink-ALC88 Not tainted 3.18.7-rt1 #9 -|Hardware name: MEDION MS-7848/MS-7848, BIOS M7848W08.404 11/06/2014 -| ffff880409316240 ffff88040866fa38 ffffffff815bdeb5 0000000000000002 -| 0000000000000000 ffff88040866fa58 ffffffff81073c86 ffffffffa03b2640 -| ffff88040239ec00 ffff88040866fa78 ffffffff815c3d34 ffffffffa03b2640 -|Call Trace: -| [] dump_stack+0x4f/0x9e -| [] __might_sleep+0xe6/0x150 -| [] __rt_spin_lock+0x24/0x50 -| [] rt_read_lock+0x34/0x40 -| [] snd_pcm_stream_lock+0x29/0x70 [snd_pcm] -| [] snd_pcm_playback_poll+0x5d/0x120 [snd_pcm] -| [] do_sys_poll+0x322/0x5b0 -| [] SyS_ppoll+0x1a8/0x1c0 -| [] system_call_fastpath+0x16/0x1b - -Signed-off-by: Mike Galbraith -Signed-off-by: Sebastian Andrzej Siewior ---- - sound/core/pcm_native.c | 8 ++++---- - 1 file changed, 4 insertions(+), 4 deletions(-) - -diff --git a/sound/core/pcm_native.c b/sound/core/pcm_native.c -index ab3bf36786b6..f0bb7c9aa4be 100644 ---- a/sound/core/pcm_native.c -+++ b/sound/core/pcm_native.c -@@ -148,7 +148,7 @@ EXPORT_SYMBOL_GPL(snd_pcm_stream_unlock); - void snd_pcm_stream_lock_irq(struct snd_pcm_substream *substream) - { - if (!substream->pcm->nonatomic) -- local_irq_disable(); -+ local_irq_disable_nort(); - snd_pcm_stream_lock(substream); - } - EXPORT_SYMBOL_GPL(snd_pcm_stream_lock_irq); -@@ -163,7 +163,7 @@ void snd_pcm_stream_unlock_irq(struct snd_pcm_substream *substream) - { - snd_pcm_stream_unlock(substream); - if (!substream->pcm->nonatomic) -- local_irq_enable(); -+ local_irq_enable_nort(); - } - EXPORT_SYMBOL_GPL(snd_pcm_stream_unlock_irq); - -@@ -171,7 +171,7 @@ unsigned long _snd_pcm_stream_lock_irqsave(struct snd_pcm_substream *substream) - { - unsigned long flags = 0; - if (!substream->pcm->nonatomic) -- local_irq_save(flags); -+ local_irq_save_nort(flags); - snd_pcm_stream_lock(substream); - return flags; - } -@@ -189,7 +189,7 @@ void snd_pcm_stream_unlock_irqrestore(struct snd_pcm_substream *substream, - { - snd_pcm_stream_unlock(substream); - if (!substream->pcm->nonatomic) -- local_irq_restore(flags); -+ local_irq_restore_nort(flags); - } - EXPORT_SYMBOL_GPL(snd_pcm_stream_unlock_irqrestore); - --- -2.19.2 - diff --git a/kernel/patches-4.14.x-rt/0332-printk-Drop-the-logbuf_lock-more-often.patch b/kernel/patches-4.14.x-rt/0332-printk-Drop-the-logbuf_lock-more-often.patch deleted file mode 100644 index e7124e11d..000000000 --- a/kernel/patches-4.14.x-rt/0332-printk-Drop-the-logbuf_lock-more-often.patch +++ /dev/null @@ -1,82 +0,0 @@ -From 72626dd71e5dbdbf829cd3383c77b9b825c75580 Mon Sep 17 00:00:00 2001 -From: Sebastian Andrzej Siewior -Date: Thu, 21 Mar 2013 19:01:05 +0100 -Subject: [PATCH 332/450] printk: Drop the logbuf_lock more often - -The lock is hold with irgs off. The latency drops 500us+ on my arm bugs -with a "full" buffer after executing "dmesg" on the shell. - -Signed-off-by: Sebastian Andrzej Siewior ---- - kernel/printk/printk.c | 27 +++++++++++++++++++++++++++ - 1 file changed, 27 insertions(+) - -diff --git a/kernel/printk/printk.c b/kernel/printk/printk.c -index 9b0deab74376..8a7c4f79fca0 100644 ---- a/kernel/printk/printk.c -+++ b/kernel/printk/printk.c -@@ -1353,6 +1353,8 @@ static int syslog_print_all(char __user *buf, int size, bool clear) - { - char *text; - int len = 0; -+ int attempts = 0; -+ int num_msg; - - text = kmalloc(LOG_LINE_MAX + PREFIX_MAX, GFP_KERNEL); - if (!text) -@@ -1364,6 +1366,14 @@ static int syslog_print_all(char __user *buf, int size, bool clear) - u64 seq; - u32 idx; - -+try_again: -+ attempts++; -+ if (attempts > 10) { -+ len = -EBUSY; -+ goto out; -+ } -+ num_msg = 0; -+ - /* - * Find first record that fits, including all following records, - * into the user-provided buffer for this dump. -@@ -1376,6 +1386,14 @@ static int syslog_print_all(char __user *buf, int size, bool clear) - len += msg_print_text(msg, true, NULL, 0); - idx = log_next(idx); - seq++; -+ num_msg++; -+ if (num_msg > 5) { -+ num_msg = 0; -+ logbuf_unlock_irq(); -+ logbuf_lock_irq(); -+ if (clear_seq < log_first_seq) -+ goto try_again; -+ } - } - - /* move first record forward until length fits into the buffer */ -@@ -1387,6 +1405,14 @@ static int syslog_print_all(char __user *buf, int size, bool clear) - len -= msg_print_text(msg, true, NULL, 0); - idx = log_next(idx); - seq++; -+ num_msg++; -+ if (num_msg > 5) { -+ num_msg = 0; -+ logbuf_unlock_irq(); -+ logbuf_lock_irq(); -+ if (clear_seq < log_first_seq) -+ goto try_again; -+ } - } - - /* last message fitting into this dump */ -@@ -1425,6 +1451,7 @@ static int syslog_print_all(char __user *buf, int size, bool clear) - clear_seq = log_next_seq; - clear_idx = log_next_idx; - } -+out: - logbuf_unlock_irq(); - - kfree(text); --- -2.19.2 - diff --git a/kernel/patches-4.14.x-rt/0335-powerpc-ps3-device-init.c-adapt-to-completions-using.patch b/kernel/patches-4.14.x-rt/0335-powerpc-ps3-device-init.c-adapt-to-completions-using.patch deleted file mode 100644 index 8d898c5fe..000000000 --- a/kernel/patches-4.14.x-rt/0335-powerpc-ps3-device-init.c-adapt-to-completions-using.patch +++ /dev/null @@ -1,38 +0,0 @@ -From 195da94d715c74d541c2decfba84b3f14b56c909 Mon Sep 17 00:00:00 2001 -From: Paul Gortmaker -Date: Sun, 31 May 2015 14:44:42 -0400 -Subject: [PATCH 335/450] powerpc: ps3/device-init.c - adapt to completions - using swait vs wait - -To fix: - - cc1: warnings being treated as errors - arch/powerpc/platforms/ps3/device-init.c: In function 'ps3_notification_read_write': - arch/powerpc/platforms/ps3/device-init.c:755:2: error: passing argument 1 of 'prepare_to_wait_event' from incompatible pointer type - arch/powerpc/platforms/ps3/device-init.c:755:2: error: passing argument 1 of 'abort_exclusive_wait' from incompatible pointer type - arch/powerpc/platforms/ps3/device-init.c:755:2: error: passing argument 1 of 'finish_wait' from incompatible pointer type - arch/powerpc/platforms/ps3/device-init.o] Error 1 - make[3]: *** Waiting for unfinished jobs.... - -Signed-off-by: Paul Gortmaker -Signed-off-by: Sebastian Andrzej Siewior ---- - arch/powerpc/platforms/ps3/device-init.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/arch/powerpc/platforms/ps3/device-init.c b/arch/powerpc/platforms/ps3/device-init.c -index e48462447ff0..2670cee66064 100644 ---- a/arch/powerpc/platforms/ps3/device-init.c -+++ b/arch/powerpc/platforms/ps3/device-init.c -@@ -752,7 +752,7 @@ static int ps3_notification_read_write(struct ps3_notification_device *dev, - } - pr_debug("%s:%u: notification %s issued\n", __func__, __LINE__, op); - -- res = wait_event_interruptible(dev->done.wait, -+ res = swait_event_interruptible(dev->done.wait, - dev->done.done || kthread_should_stop()); - if (kthread_should_stop()) - res = -EINTR; --- -2.19.2 - diff --git a/kernel/patches-4.14.x-rt/0336-ARM-at91-tclib-Default-to-tclib-timer-for-RT.patch b/kernel/patches-4.14.x-rt/0336-ARM-at91-tclib-Default-to-tclib-timer-for-RT.patch deleted file mode 100644 index 46eab4ce2..000000000 --- a/kernel/patches-4.14.x-rt/0336-ARM-at91-tclib-Default-to-tclib-timer-for-RT.patch +++ /dev/null @@ -1,37 +0,0 @@ -From 6587bc3d8e7b714bea195a2541f81cb77dccbe5a Mon Sep 17 00:00:00 2001 -From: Thomas Gleixner -Date: Sat, 1 May 2010 18:29:35 +0200 -Subject: [PATCH 336/450] ARM: at91: tclib: Default to tclib timer for RT - -RT is not too happy about the shared timer interrupt in AT91 -devices. Default to tclib timer for RT. - -Signed-off-by: Thomas Gleixner ---- - drivers/misc/Kconfig | 3 ++- - 1 file changed, 2 insertions(+), 1 deletion(-) - -diff --git a/drivers/misc/Kconfig b/drivers/misc/Kconfig -index d2feb491e689..86e83b9629d7 100644 ---- a/drivers/misc/Kconfig -+++ b/drivers/misc/Kconfig -@@ -54,6 +54,7 @@ config AD525X_DPOT_SPI - config ATMEL_TCLIB - bool "Atmel AT32/AT91 Timer/Counter Library" - depends on (AVR32 || ARCH_AT91) -+ default y if PREEMPT_RT_FULL - help - Select this if you want a library to allocate the Timer/Counter - blocks found on many Atmel processors. This facilitates using -@@ -86,7 +87,7 @@ config ATMEL_TCB_CLKSRC_BLOCK - config ATMEL_TCB_CLKSRC_USE_SLOW_CLOCK - bool "TC Block use 32 KiHz clock" - depends on ATMEL_TCB_CLKSRC -- default y -+ default y if !PREEMPT_RT_FULL - help - Select this to use 32 KiHz base clock rate as TC block clock - source for clock events. --- -2.19.2 - diff --git a/kernel/patches-4.14.x-rt/0341-arm64-xen-Make-XEN-depend-on-RT.patch b/kernel/patches-4.14.x-rt/0341-arm64-xen-Make-XEN-depend-on-RT.patch deleted file mode 100644 index eec27bdee..000000000 --- a/kernel/patches-4.14.x-rt/0341-arm64-xen-Make-XEN-depend-on-RT.patch +++ /dev/null @@ -1,29 +0,0 @@ -From 876d09f497787b832cb9abdd4e684220071ee0cc Mon Sep 17 00:00:00 2001 -From: Thomas Gleixner -Date: Mon, 12 Oct 2015 11:18:40 +0200 -Subject: [PATCH 341/450] arm64/xen: Make XEN depend on !RT - -It's not ready and probably never will be, unless xen folks have a -look at it. - -Signed-off-by: Thomas Gleixner ---- - arch/arm64/Kconfig | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig -index c30cd78b6918..724afce517fd 100644 ---- a/arch/arm64/Kconfig -+++ b/arch/arm64/Kconfig -@@ -790,7 +790,7 @@ config XEN_DOM0 - - config XEN - bool "Xen guest support on ARM64" -- depends on ARM64 && OF -+ depends on ARM64 && OF && !PREEMPT_RT_FULL - select SWIOTLB_XEN - select PARAVIRT - help --- -2.19.2 - diff --git a/kernel/patches-4.14.x-rt/0347-mm-rt-Fix-generic-kmap_atomic-for-RT.patch b/kernel/patches-4.14.x-rt/0347-mm-rt-Fix-generic-kmap_atomic-for-RT.patch deleted file mode 100644 index e04c86b7a..000000000 --- a/kernel/patches-4.14.x-rt/0347-mm-rt-Fix-generic-kmap_atomic-for-RT.patch +++ /dev/null @@ -1,46 +0,0 @@ -From 97029d8f7c055c56fb221d6efbfa6dcad02ac788 Mon Sep 17 00:00:00 2001 -From: Thomas Gleixner -Date: Sat, 19 Sep 2015 10:15:00 +0200 -Subject: [PATCH 347/450] mm: rt: Fix generic kmap_atomic for RT - -The update to 4.1 brought in the mainline variant of the pagefault -disable distangling from preempt count. That introduced a -preempt_disable/enable pair in the generic kmap_atomic/kunmap_atomic -implementations which got not converted to the _nort() variant. - -That results in massive 'scheduling while atomic/sleeping function -called from invalid context' splats. - -Fix that up. - -Reported-and-tested-by: Juergen Borleis -Signed-off-by: Thomas Gleixner ---- - include/linux/highmem.h | 4 ++-- - 1 file changed, 2 insertions(+), 2 deletions(-) - -diff --git a/include/linux/highmem.h b/include/linux/highmem.h -index cfcd7b7ab205..8f248e2137eb 100644 ---- a/include/linux/highmem.h -+++ b/include/linux/highmem.h -@@ -66,7 +66,7 @@ static inline void kunmap(struct page *page) - - static inline void *kmap_atomic(struct page *page) - { -- preempt_disable(); -+ preempt_disable_nort(); - pagefault_disable(); - return page_address(page); - } -@@ -75,7 +75,7 @@ static inline void *kmap_atomic(struct page *page) - static inline void __kunmap_atomic(void *addr) - { - pagefault_enable(); -- preempt_enable(); -+ preempt_enable_nort(); - } - - #define kmap_atomic_pfn(pfn) kmap_atomic(pfn_to_page(pfn)) --- -2.19.2 - diff --git a/kernel/patches-4.14.x-rt/0352-sas-ata-isci-dont-t-disable-interrupts-in-qc_issue-h.patch b/kernel/patches-4.14.x-rt/0352-sas-ata-isci-dont-t-disable-interrupts-in-qc_issue-h.patch deleted file mode 100644 index 533151326..000000000 --- a/kernel/patches-4.14.x-rt/0352-sas-ata-isci-dont-t-disable-interrupts-in-qc_issue-h.patch +++ /dev/null @@ -1,85 +0,0 @@ -From e0c7598e6c5b61e2fb283d10d967c82b73c56d98 Mon Sep 17 00:00:00 2001 -From: Paul Gortmaker -Date: Sat, 14 Feb 2015 11:01:16 -0500 -Subject: [PATCH 352/450] sas-ata/isci: dont't disable interrupts in qc_issue - handler - -On 3.14-rt we see the following trace on Canoe Pass for -SCSI_ISCI "Intel(R) C600 Series Chipset SAS Controller" -when the sas qc_issue handler is run: - - BUG: sleeping function called from invalid context at kernel/locking/rtmutex.c:905 - in_atomic(): 0, irqs_disabled(): 1, pid: 432, name: udevd - CPU: 11 PID: 432 Comm: udevd Not tainted 3.14.28-rt22 #2 - Hardware name: Intel Corporation S2600CP/S2600CP, BIOS SE5C600.86B.02.01.0002.082220131453 08/22/2013 - ffff880fab500000 ffff880fa9f239c0 ffffffff81a2d273 0000000000000000 - ffff880fa9f239d8 ffffffff8107f023 ffff880faac23dc0 ffff880fa9f239f0 - ffffffff81a33cc0 ffff880faaeb1400 ffff880fa9f23a40 ffffffff815de891 - Call Trace: - [] dump_stack+0x4e/0x7a - [] __might_sleep+0xe3/0x160 - [] rt_spin_lock+0x20/0x50 - [] isci_task_execute_task+0x171/0x2f0 <----- - [] sas_ata_qc_issue+0x25b/0x2a0 - [] ata_qc_issue+0x1f3/0x370 - [] ? ata_scsi_invalid_field+0x40/0x40 - [] ata_scsi_translate+0xa5/0x1b0 - [] ata_sas_queuecmd+0x86/0x280 - [] sas_queuecommand+0x196/0x230 - [] ? get_parent_ip+0xd/0x50 - [] scsi_dispatch_cmd+0xb4/0x210 - [] scsi_request_fn+0x314/0x530 - -and gdb shows: - -(gdb) list * isci_task_execute_task+0x171 -0xffffffff815ddfb1 is in isci_task_execute_task (drivers/scsi/isci/task.c:138). -133 dev_dbg(&ihost->pdev->dev, "%s: num=%d\n", __func__, num); -134 -135 for_each_sas_task(num, task) { -136 enum sci_status status = SCI_FAILURE; -137 -138 spin_lock_irqsave(&ihost->scic_lock, flags); <----- -139 idev = isci_lookup_device(task->dev); -140 io_ready = isci_device_io_ready(idev, task); -141 tag = isci_alloc_tag(ihost); -142 spin_unlock_irqrestore(&ihost->scic_lock, flags); -(gdb) - -In addition to the scic_lock, the function also contains locking of -the task_state_lock -- which is clearly not a candidate for raw lock -conversion. As can be seen by the comment nearby, we really should -be running the qc_issue code with interrupts enabled anyway. - - -Signed-off-by: Paul Gortmaker -Signed-off-by: Sebastian Andrzej Siewior ---- - drivers/scsi/libsas/sas_ata.c | 4 ++-- - 1 file changed, 2 insertions(+), 2 deletions(-) - -diff --git a/drivers/scsi/libsas/sas_ata.c b/drivers/scsi/libsas/sas_ata.c -index 70be4425ae0b..a23ef685deac 100644 ---- a/drivers/scsi/libsas/sas_ata.c -+++ b/drivers/scsi/libsas/sas_ata.c -@@ -190,7 +190,7 @@ static unsigned int sas_ata_qc_issue(struct ata_queued_cmd *qc) - /* TODO: audit callers to ensure they are ready for qc_issue to - * unconditionally re-enable interrupts - */ -- local_irq_save(flags); -+ local_irq_save_nort(flags); - spin_unlock(ap->lock); - - /* If the device fell off, no sense in issuing commands */ -@@ -252,7 +252,7 @@ static unsigned int sas_ata_qc_issue(struct ata_queued_cmd *qc) - - out: - spin_lock(ap->lock); -- local_irq_restore(flags); -+ local_irq_restore_nort(flags); - return ret; - } - --- -2.19.2 - diff --git a/kernel/patches-4.14.x-rt/0354-crypto-Reduce-preempt-disabled-regions-more-algos.patch b/kernel/patches-4.14.x-rt/0354-crypto-Reduce-preempt-disabled-regions-more-algos.patch deleted file mode 100644 index d7a93495a..000000000 --- a/kernel/patches-4.14.x-rt/0354-crypto-Reduce-preempt-disabled-regions-more-algos.patch +++ /dev/null @@ -1,249 +0,0 @@ -From 42aa2b5a9ebac3a19effb1ad5c9cf5efa7d07ddc Mon Sep 17 00:00:00 2001 -From: Sebastian Andrzej Siewior -Date: Fri, 21 Feb 2014 17:24:04 +0100 -Subject: [PATCH 354/450] crypto: Reduce preempt disabled regions, more algos - -Don Estabrook reported -| kernel: WARNING: CPU: 2 PID: 858 at kernel/sched/core.c:2428 migrate_disable+0xed/0x100() -| kernel: WARNING: CPU: 2 PID: 858 at kernel/sched/core.c:2462 migrate_enable+0x17b/0x200() -| kernel: WARNING: CPU: 3 PID: 865 at kernel/sched/core.c:2428 migrate_disable+0xed/0x100() - -and his backtrace showed some crypto functions which looked fine. - -The problem is the following sequence: - -glue_xts_crypt_128bit() -{ - blkcipher_walk_virt(); /* normal migrate_disable() */ - - glue_fpu_begin(); /* get atomic */ - - while (nbytes) { - __glue_xts_crypt_128bit(); - blkcipher_walk_done(); /* with nbytes = 0, migrate_enable() - * while we are atomic */ - }; - glue_fpu_end() /* no longer atomic */ -} - -and this is why the counter get out of sync and the warning is printed. -The other problem is that we are non-preemptible between -glue_fpu_begin() and glue_fpu_end() and the latency grows. To fix this, -I shorten the FPU off region and ensure blkcipher_walk_done() is called -with preemption enabled. This might hurt the performance because we now -enable/disable the FPU state more often but we gain lower latency and -the bug is gone. - - -Reported-by: Don Estabrook -Signed-off-by: Sebastian Andrzej Siewior ---- - arch/x86/crypto/cast5_avx_glue.c | 21 +++++++++------------ - arch/x86/crypto/glue_helper.c | 31 +++++++++++++++---------------- - 2 files changed, 24 insertions(+), 28 deletions(-) - -diff --git a/arch/x86/crypto/cast5_avx_glue.c b/arch/x86/crypto/cast5_avx_glue.c -index 575292a33bdf..0a4b0a222b18 100644 ---- a/arch/x86/crypto/cast5_avx_glue.c -+++ b/arch/x86/crypto/cast5_avx_glue.c -@@ -59,7 +59,7 @@ static inline void cast5_fpu_end(bool fpu_enabled) - static int ecb_crypt(struct blkcipher_desc *desc, struct blkcipher_walk *walk, - bool enc) - { -- bool fpu_enabled = false; -+ bool fpu_enabled; - struct cast5_ctx *ctx = crypto_blkcipher_ctx(desc->tfm); - const unsigned int bsize = CAST5_BLOCK_SIZE; - unsigned int nbytes; -@@ -73,7 +73,7 @@ static int ecb_crypt(struct blkcipher_desc *desc, struct blkcipher_walk *walk, - u8 *wsrc = walk->src.virt.addr; - u8 *wdst = walk->dst.virt.addr; - -- fpu_enabled = cast5_fpu_begin(fpu_enabled, nbytes); -+ fpu_enabled = cast5_fpu_begin(false, nbytes); - - /* Process multi-block batch */ - if (nbytes >= bsize * CAST5_PARALLEL_BLOCKS) { -@@ -102,10 +102,9 @@ static int ecb_crypt(struct blkcipher_desc *desc, struct blkcipher_walk *walk, - } while (nbytes >= bsize); - - done: -+ cast5_fpu_end(fpu_enabled); - err = blkcipher_walk_done(desc, walk, nbytes); - } -- -- cast5_fpu_end(fpu_enabled); - return err; - } - -@@ -226,7 +225,7 @@ static unsigned int __cbc_decrypt(struct blkcipher_desc *desc, - static int cbc_decrypt(struct blkcipher_desc *desc, struct scatterlist *dst, - struct scatterlist *src, unsigned int nbytes) - { -- bool fpu_enabled = false; -+ bool fpu_enabled; - struct blkcipher_walk walk; - int err; - -@@ -235,12 +234,11 @@ static int cbc_decrypt(struct blkcipher_desc *desc, struct scatterlist *dst, - desc->flags &= ~CRYPTO_TFM_REQ_MAY_SLEEP; - - while ((nbytes = walk.nbytes)) { -- fpu_enabled = cast5_fpu_begin(fpu_enabled, nbytes); -+ fpu_enabled = cast5_fpu_begin(false, nbytes); - nbytes = __cbc_decrypt(desc, &walk); -+ cast5_fpu_end(fpu_enabled); - err = blkcipher_walk_done(desc, &walk, nbytes); - } -- -- cast5_fpu_end(fpu_enabled); - return err; - } - -@@ -309,7 +307,7 @@ static unsigned int __ctr_crypt(struct blkcipher_desc *desc, - static int ctr_crypt(struct blkcipher_desc *desc, struct scatterlist *dst, - struct scatterlist *src, unsigned int nbytes) - { -- bool fpu_enabled = false; -+ bool fpu_enabled; - struct blkcipher_walk walk; - int err; - -@@ -318,13 +316,12 @@ static int ctr_crypt(struct blkcipher_desc *desc, struct scatterlist *dst, - desc->flags &= ~CRYPTO_TFM_REQ_MAY_SLEEP; - - while ((nbytes = walk.nbytes) >= CAST5_BLOCK_SIZE) { -- fpu_enabled = cast5_fpu_begin(fpu_enabled, nbytes); -+ fpu_enabled = cast5_fpu_begin(false, nbytes); - nbytes = __ctr_crypt(desc, &walk); -+ cast5_fpu_end(fpu_enabled); - err = blkcipher_walk_done(desc, &walk, nbytes); - } - -- cast5_fpu_end(fpu_enabled); -- - if (walk.nbytes) { - ctr_crypt_final(desc, &walk); - err = blkcipher_walk_done(desc, &walk, 0); -diff --git a/arch/x86/crypto/glue_helper.c b/arch/x86/crypto/glue_helper.c -index d61e57960fe0..c67560d9718a 100644 ---- a/arch/x86/crypto/glue_helper.c -+++ b/arch/x86/crypto/glue_helper.c -@@ -40,7 +40,7 @@ static int __glue_ecb_crypt_128bit(const struct common_glue_ctx *gctx, - void *ctx = crypto_blkcipher_ctx(desc->tfm); - const unsigned int bsize = 128 / 8; - unsigned int nbytes, i, func_bytes; -- bool fpu_enabled = false; -+ bool fpu_enabled; - int err; - - err = blkcipher_walk_virt(desc, walk); -@@ -50,7 +50,7 @@ static int __glue_ecb_crypt_128bit(const struct common_glue_ctx *gctx, - u8 *wdst = walk->dst.virt.addr; - - fpu_enabled = glue_fpu_begin(bsize, gctx->fpu_blocks_limit, -- desc, fpu_enabled, nbytes); -+ desc, false, nbytes); - - for (i = 0; i < gctx->num_funcs; i++) { - func_bytes = bsize * gctx->funcs[i].num_blocks; -@@ -72,10 +72,10 @@ static int __glue_ecb_crypt_128bit(const struct common_glue_ctx *gctx, - } - - done: -+ glue_fpu_end(fpu_enabled); - err = blkcipher_walk_done(desc, walk, nbytes); - } - -- glue_fpu_end(fpu_enabled); - return err; - } - -@@ -192,7 +192,7 @@ int glue_cbc_decrypt_128bit(const struct common_glue_ctx *gctx, - struct scatterlist *src, unsigned int nbytes) - { - const unsigned int bsize = 128 / 8; -- bool fpu_enabled = false; -+ bool fpu_enabled; - struct blkcipher_walk walk; - int err; - -@@ -201,12 +201,12 @@ int glue_cbc_decrypt_128bit(const struct common_glue_ctx *gctx, - - while ((nbytes = walk.nbytes)) { - fpu_enabled = glue_fpu_begin(bsize, gctx->fpu_blocks_limit, -- desc, fpu_enabled, nbytes); -+ desc, false, nbytes); - nbytes = __glue_cbc_decrypt_128bit(gctx, desc, &walk); -+ glue_fpu_end(fpu_enabled); - err = blkcipher_walk_done(desc, &walk, nbytes); - } - -- glue_fpu_end(fpu_enabled); - return err; - } - EXPORT_SYMBOL_GPL(glue_cbc_decrypt_128bit); -@@ -275,7 +275,7 @@ int glue_ctr_crypt_128bit(const struct common_glue_ctx *gctx, - struct scatterlist *src, unsigned int nbytes) - { - const unsigned int bsize = 128 / 8; -- bool fpu_enabled = false; -+ bool fpu_enabled; - struct blkcipher_walk walk; - int err; - -@@ -284,13 +284,12 @@ int glue_ctr_crypt_128bit(const struct common_glue_ctx *gctx, - - while ((nbytes = walk.nbytes) >= bsize) { - fpu_enabled = glue_fpu_begin(bsize, gctx->fpu_blocks_limit, -- desc, fpu_enabled, nbytes); -+ desc, false, nbytes); - nbytes = __glue_ctr_crypt_128bit(gctx, desc, &walk); -+ glue_fpu_end(fpu_enabled); - err = blkcipher_walk_done(desc, &walk, nbytes); - } - -- glue_fpu_end(fpu_enabled); -- - if (walk.nbytes) { - glue_ctr_crypt_final_128bit( - gctx->funcs[gctx->num_funcs - 1].fn_u.ctr, desc, &walk); -@@ -380,7 +379,7 @@ int glue_xts_crypt_128bit(const struct common_glue_ctx *gctx, - void *tweak_ctx, void *crypt_ctx) - { - const unsigned int bsize = 128 / 8; -- bool fpu_enabled = false; -+ bool fpu_enabled; - struct blkcipher_walk walk; - int err; - -@@ -393,21 +392,21 @@ int glue_xts_crypt_128bit(const struct common_glue_ctx *gctx, - - /* set minimum length to bsize, for tweak_fn */ - fpu_enabled = glue_fpu_begin(bsize, gctx->fpu_blocks_limit, -- desc, fpu_enabled, -+ desc, false, - nbytes < bsize ? bsize : nbytes); -- - /* calculate first value of T */ - tweak_fn(tweak_ctx, walk.iv, walk.iv); -+ glue_fpu_end(fpu_enabled); - - while (nbytes) { -+ fpu_enabled = glue_fpu_begin(bsize, gctx->fpu_blocks_limit, -+ desc, false, nbytes); - nbytes = __glue_xts_crypt_128bit(gctx, crypt_ctx, desc, &walk); - -+ glue_fpu_end(fpu_enabled); - err = blkcipher_walk_done(desc, &walk, nbytes); - nbytes = walk.nbytes; - } -- -- glue_fpu_end(fpu_enabled); -- - return err; - } - EXPORT_SYMBOL_GPL(glue_xts_crypt_128bit); --- -2.19.2 - diff --git a/kernel/patches-4.14.x-rt/0355-crypto-limit-more-FPU-enabled-sections.patch b/kernel/patches-4.14.x-rt/0355-crypto-limit-more-FPU-enabled-sections.patch deleted file mode 100644 index b3bb8ab48..000000000 --- a/kernel/patches-4.14.x-rt/0355-crypto-limit-more-FPU-enabled-sections.patch +++ /dev/null @@ -1,500 +0,0 @@ -From 6c60a376a30a4c4009517c4bc742afdab31b7b3e Mon Sep 17 00:00:00 2001 -From: Sebastian Andrzej Siewior -Date: Thu, 30 Nov 2017 13:40:10 +0100 -Subject: [PATCH 355/450] crypto: limit more FPU-enabled sections -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -Those crypto drivers use SSE/AVX/… for their crypto work and in order to -do so in kernel they need to enable the "FPU" in kernel mode which -disables preemption. -There are two problems with the way they are used: -- the while loop which processes X bytes may create latency spikes and - should be avoided or limited. -- the cipher-walk-next part may allocate/free memory and may use - kmap_atomic(). - -The whole kernel_fpu_begin()/end() processing isn't probably that cheap. -It most likely makes sense to process as much of those as possible in one -go. The new *_fpu_sched_rt() schedules only if a RT task is pending. - -Probably we should measure the performance those ciphers in pure SW -mode and with this optimisations to see if it makes sense to keep them -for RT. - -This kernel_fpu_resched() makes the code more preemptible which might hurt -performance. - -Cc: stable-rt@vger.kernel.org -Signed-off-by: Sebastian Andrzej Siewior ---- - arch/x86/crypto/camellia_aesni_avx2_glue.c | 20 ++++++++++++++++ - arch/x86/crypto/camellia_aesni_avx_glue.c | 19 +++++++++++++++ - arch/x86/crypto/cast6_avx_glue.c | 24 +++++++++++++++---- - arch/x86/crypto/chacha20_glue.c | 9 ++++---- - arch/x86/crypto/serpent_avx2_glue.c | 19 +++++++++++++++ - arch/x86/crypto/serpent_avx_glue.c | 23 ++++++++++++++---- - arch/x86/crypto/serpent_sse2_glue.c | 23 ++++++++++++++---- - arch/x86/crypto/twofish_avx_glue.c | 27 ++++++++++++++++++++-- - arch/x86/include/asm/fpu/api.h | 1 + - arch/x86/kernel/fpu/core.c | 12 ++++++++++ - 10 files changed, 158 insertions(+), 19 deletions(-) - -diff --git a/arch/x86/crypto/camellia_aesni_avx2_glue.c b/arch/x86/crypto/camellia_aesni_avx2_glue.c -index 60907c139c4e..0902db7d326a 100644 ---- a/arch/x86/crypto/camellia_aesni_avx2_glue.c -+++ b/arch/x86/crypto/camellia_aesni_avx2_glue.c -@@ -206,6 +206,20 @@ struct crypt_priv { - bool fpu_enabled; - }; - -+#ifdef CONFIG_PREEMPT_RT_FULL -+static void camellia_fpu_end_rt(struct crypt_priv *ctx) -+{ -+ bool fpu_enabled = ctx->fpu_enabled; -+ -+ if (!fpu_enabled) -+ return; -+ camellia_fpu_end(fpu_enabled); -+ ctx->fpu_enabled = false; -+} -+#else -+static void camellia_fpu_end_rt(struct crypt_priv *ctx) { } -+#endif -+ - static void encrypt_callback(void *priv, u8 *srcdst, unsigned int nbytes) - { - const unsigned int bsize = CAMELLIA_BLOCK_SIZE; -@@ -221,16 +235,19 @@ static void encrypt_callback(void *priv, u8 *srcdst, unsigned int nbytes) - } - - if (nbytes >= CAMELLIA_AESNI_PARALLEL_BLOCKS * bsize) { -+ kernel_fpu_resched(); - camellia_ecb_enc_16way(ctx->ctx, srcdst, srcdst); - srcdst += bsize * CAMELLIA_AESNI_PARALLEL_BLOCKS; - nbytes -= bsize * CAMELLIA_AESNI_PARALLEL_BLOCKS; - } - - while (nbytes >= CAMELLIA_PARALLEL_BLOCKS * bsize) { -+ kernel_fpu_resched(); - camellia_enc_blk_2way(ctx->ctx, srcdst, srcdst); - srcdst += bsize * CAMELLIA_PARALLEL_BLOCKS; - nbytes -= bsize * CAMELLIA_PARALLEL_BLOCKS; - } -+ camellia_fpu_end_rt(ctx); - - for (i = 0; i < nbytes / bsize; i++, srcdst += bsize) - camellia_enc_blk(ctx->ctx, srcdst, srcdst); -@@ -251,16 +268,19 @@ static void decrypt_callback(void *priv, u8 *srcdst, unsigned int nbytes) - } - - if (nbytes >= CAMELLIA_AESNI_PARALLEL_BLOCKS * bsize) { -+ kernel_fpu_resched(); - camellia_ecb_dec_16way(ctx->ctx, srcdst, srcdst); - srcdst += bsize * CAMELLIA_AESNI_PARALLEL_BLOCKS; - nbytes -= bsize * CAMELLIA_AESNI_PARALLEL_BLOCKS; - } - - while (nbytes >= CAMELLIA_PARALLEL_BLOCKS * bsize) { -+ kernel_fpu_resched(); - camellia_dec_blk_2way(ctx->ctx, srcdst, srcdst); - srcdst += bsize * CAMELLIA_PARALLEL_BLOCKS; - nbytes -= bsize * CAMELLIA_PARALLEL_BLOCKS; - } -+ camellia_fpu_end_rt(ctx); - - for (i = 0; i < nbytes / bsize; i++, srcdst += bsize) - camellia_dec_blk(ctx->ctx, srcdst, srcdst); -diff --git a/arch/x86/crypto/camellia_aesni_avx_glue.c b/arch/x86/crypto/camellia_aesni_avx_glue.c -index d96429da88eb..3b8e91841039 100644 ---- a/arch/x86/crypto/camellia_aesni_avx_glue.c -+++ b/arch/x86/crypto/camellia_aesni_avx_glue.c -@@ -210,6 +210,21 @@ struct crypt_priv { - bool fpu_enabled; - }; - -+#ifdef CONFIG_PREEMPT_RT_FULL -+static void camellia_fpu_end_rt(struct crypt_priv *ctx) -+{ -+ bool fpu_enabled = ctx->fpu_enabled; -+ -+ if (!fpu_enabled) -+ return; -+ camellia_fpu_end(fpu_enabled); -+ ctx->fpu_enabled = false; -+} -+ -+#else -+static void camellia_fpu_end_rt(struct crypt_priv *ctx) { } -+#endif -+ - static void encrypt_callback(void *priv, u8 *srcdst, unsigned int nbytes) - { - const unsigned int bsize = CAMELLIA_BLOCK_SIZE; -@@ -225,10 +240,12 @@ static void encrypt_callback(void *priv, u8 *srcdst, unsigned int nbytes) - } - - while (nbytes >= CAMELLIA_PARALLEL_BLOCKS * bsize) { -+ kernel_fpu_resched(); - camellia_enc_blk_2way(ctx->ctx, srcdst, srcdst); - srcdst += bsize * CAMELLIA_PARALLEL_BLOCKS; - nbytes -= bsize * CAMELLIA_PARALLEL_BLOCKS; - } -+ camellia_fpu_end_rt(ctx); - - for (i = 0; i < nbytes / bsize; i++, srcdst += bsize) - camellia_enc_blk(ctx->ctx, srcdst, srcdst); -@@ -249,10 +266,12 @@ static void decrypt_callback(void *priv, u8 *srcdst, unsigned int nbytes) - } - - while (nbytes >= CAMELLIA_PARALLEL_BLOCKS * bsize) { -+ kernel_fpu_resched(); - camellia_dec_blk_2way(ctx->ctx, srcdst, srcdst); - srcdst += bsize * CAMELLIA_PARALLEL_BLOCKS; - nbytes -= bsize * CAMELLIA_PARALLEL_BLOCKS; - } -+ camellia_fpu_end_rt(ctx); - - for (i = 0; i < nbytes / bsize; i++, srcdst += bsize) - camellia_dec_blk(ctx->ctx, srcdst, srcdst); -diff --git a/arch/x86/crypto/cast6_avx_glue.c b/arch/x86/crypto/cast6_avx_glue.c -index 50e684768c55..8caf9ba8c1da 100644 ---- a/arch/x86/crypto/cast6_avx_glue.c -+++ b/arch/x86/crypto/cast6_avx_glue.c -@@ -205,19 +205,33 @@ struct crypt_priv { - bool fpu_enabled; - }; - -+#ifdef CONFIG_PREEMPT_RT_FULL -+static void cast6_fpu_end_rt(struct crypt_priv *ctx) -+{ -+ bool fpu_enabled = ctx->fpu_enabled; -+ -+ if (!fpu_enabled) -+ return; -+ cast6_fpu_end(fpu_enabled); -+ ctx->fpu_enabled = false; -+} -+ -+#else -+static void cast6_fpu_end_rt(struct crypt_priv *ctx) { } -+#endif -+ - static void encrypt_callback(void *priv, u8 *srcdst, unsigned int nbytes) - { - const unsigned int bsize = CAST6_BLOCK_SIZE; - struct crypt_priv *ctx = priv; - int i; - -- ctx->fpu_enabled = cast6_fpu_begin(ctx->fpu_enabled, nbytes); -- - if (nbytes == bsize * CAST6_PARALLEL_BLOCKS) { -+ ctx->fpu_enabled = cast6_fpu_begin(ctx->fpu_enabled, nbytes); - cast6_ecb_enc_8way(ctx->ctx, srcdst, srcdst); -+ cast6_fpu_end_rt(ctx); - return; - } -- - for (i = 0; i < nbytes / bsize; i++, srcdst += bsize) - __cast6_encrypt(ctx->ctx, srcdst, srcdst); - } -@@ -228,10 +242,10 @@ static void decrypt_callback(void *priv, u8 *srcdst, unsigned int nbytes) - struct crypt_priv *ctx = priv; - int i; - -- ctx->fpu_enabled = cast6_fpu_begin(ctx->fpu_enabled, nbytes); -- - if (nbytes == bsize * CAST6_PARALLEL_BLOCKS) { -+ ctx->fpu_enabled = cast6_fpu_begin(ctx->fpu_enabled, nbytes); - cast6_ecb_dec_8way(ctx->ctx, srcdst, srcdst); -+ cast6_fpu_end_rt(ctx); - return; - } - -diff --git a/arch/x86/crypto/chacha20_glue.c b/arch/x86/crypto/chacha20_glue.c -index 1e6af1b35f7b..e7809fd2a4fd 100644 ---- a/arch/x86/crypto/chacha20_glue.c -+++ b/arch/x86/crypto/chacha20_glue.c -@@ -81,23 +81,24 @@ static int chacha20_simd(struct skcipher_request *req) - - crypto_chacha20_init(state, ctx, walk.iv); - -- kernel_fpu_begin(); -- - while (walk.nbytes >= CHACHA20_BLOCK_SIZE) { -+ kernel_fpu_begin(); -+ - chacha20_dosimd(state, walk.dst.virt.addr, walk.src.virt.addr, - rounddown(walk.nbytes, CHACHA20_BLOCK_SIZE)); -+ kernel_fpu_end(); - err = skcipher_walk_done(&walk, - walk.nbytes % CHACHA20_BLOCK_SIZE); - } - - if (walk.nbytes) { -+ kernel_fpu_begin(); - chacha20_dosimd(state, walk.dst.virt.addr, walk.src.virt.addr, - walk.nbytes); -+ kernel_fpu_end(); - err = skcipher_walk_done(&walk, 0); - } - -- kernel_fpu_end(); -- - return err; - } - -diff --git a/arch/x86/crypto/serpent_avx2_glue.c b/arch/x86/crypto/serpent_avx2_glue.c -index 870f6d812a2d..5c806bf39f1d 100644 ---- a/arch/x86/crypto/serpent_avx2_glue.c -+++ b/arch/x86/crypto/serpent_avx2_glue.c -@@ -184,6 +184,21 @@ struct crypt_priv { - bool fpu_enabled; - }; - -+#ifdef CONFIG_PREEMPT_RT_FULL -+static void serpent_fpu_end_rt(struct crypt_priv *ctx) -+{ -+ bool fpu_enabled = ctx->fpu_enabled; -+ -+ if (!fpu_enabled) -+ return; -+ serpent_fpu_end(fpu_enabled); -+ ctx->fpu_enabled = false; -+} -+ -+#else -+static void serpent_fpu_end_rt(struct crypt_priv *ctx) { } -+#endif -+ - static void encrypt_callback(void *priv, u8 *srcdst, unsigned int nbytes) - { - const unsigned int bsize = SERPENT_BLOCK_SIZE; -@@ -199,10 +214,12 @@ static void encrypt_callback(void *priv, u8 *srcdst, unsigned int nbytes) - } - - while (nbytes >= SERPENT_PARALLEL_BLOCKS * bsize) { -+ kernel_fpu_resched(); - serpent_ecb_enc_8way_avx(ctx->ctx, srcdst, srcdst); - srcdst += bsize * SERPENT_PARALLEL_BLOCKS; - nbytes -= bsize * SERPENT_PARALLEL_BLOCKS; - } -+ serpent_fpu_end_rt(ctx); - - for (i = 0; i < nbytes / bsize; i++, srcdst += bsize) - __serpent_encrypt(ctx->ctx, srcdst, srcdst); -@@ -223,10 +240,12 @@ static void decrypt_callback(void *priv, u8 *srcdst, unsigned int nbytes) - } - - while (nbytes >= SERPENT_PARALLEL_BLOCKS * bsize) { -+ kernel_fpu_resched(); - serpent_ecb_dec_8way_avx(ctx->ctx, srcdst, srcdst); - srcdst += bsize * SERPENT_PARALLEL_BLOCKS; - nbytes -= bsize * SERPENT_PARALLEL_BLOCKS; - } -+ serpent_fpu_end_rt(ctx); - - for (i = 0; i < nbytes / bsize; i++, srcdst += bsize) - __serpent_decrypt(ctx->ctx, srcdst, srcdst); -diff --git a/arch/x86/crypto/serpent_avx_glue.c b/arch/x86/crypto/serpent_avx_glue.c -index 6f778d3daa22..46dcbdbd0518 100644 ---- a/arch/x86/crypto/serpent_avx_glue.c -+++ b/arch/x86/crypto/serpent_avx_glue.c -@@ -218,16 +218,31 @@ struct crypt_priv { - bool fpu_enabled; - }; - -+#ifdef CONFIG_PREEMPT_RT_FULL -+static void serpent_fpu_end_rt(struct crypt_priv *ctx) -+{ -+ bool fpu_enabled = ctx->fpu_enabled; -+ -+ if (!fpu_enabled) -+ return; -+ serpent_fpu_end(fpu_enabled); -+ ctx->fpu_enabled = false; -+} -+ -+#else -+static void serpent_fpu_end_rt(struct crypt_priv *ctx) { } -+#endif -+ - static void encrypt_callback(void *priv, u8 *srcdst, unsigned int nbytes) - { - const unsigned int bsize = SERPENT_BLOCK_SIZE; - struct crypt_priv *ctx = priv; - int i; - -- ctx->fpu_enabled = serpent_fpu_begin(ctx->fpu_enabled, nbytes); -- - if (nbytes == bsize * SERPENT_PARALLEL_BLOCKS) { -+ ctx->fpu_enabled = serpent_fpu_begin(ctx->fpu_enabled, nbytes); - serpent_ecb_enc_8way_avx(ctx->ctx, srcdst, srcdst); -+ serpent_fpu_end_rt(ctx); - return; - } - -@@ -241,10 +256,10 @@ static void decrypt_callback(void *priv, u8 *srcdst, unsigned int nbytes) - struct crypt_priv *ctx = priv; - int i; - -- ctx->fpu_enabled = serpent_fpu_begin(ctx->fpu_enabled, nbytes); -- - if (nbytes == bsize * SERPENT_PARALLEL_BLOCKS) { -+ ctx->fpu_enabled = serpent_fpu_begin(ctx->fpu_enabled, nbytes); - serpent_ecb_dec_8way_avx(ctx->ctx, srcdst, srcdst); -+ serpent_fpu_end_rt(ctx); - return; - } - -diff --git a/arch/x86/crypto/serpent_sse2_glue.c b/arch/x86/crypto/serpent_sse2_glue.c -index ac0e831943f5..d35f607d067f 100644 ---- a/arch/x86/crypto/serpent_sse2_glue.c -+++ b/arch/x86/crypto/serpent_sse2_glue.c -@@ -187,16 +187,31 @@ struct crypt_priv { - bool fpu_enabled; - }; - -+#ifdef CONFIG_PREEMPT_RT_FULL -+static void serpent_fpu_end_rt(struct crypt_priv *ctx) -+{ -+ bool fpu_enabled = ctx->fpu_enabled; -+ -+ if (!fpu_enabled) -+ return; -+ serpent_fpu_end(fpu_enabled); -+ ctx->fpu_enabled = false; -+} -+ -+#else -+static void serpent_fpu_end_rt(struct crypt_priv *ctx) { } -+#endif -+ - static void encrypt_callback(void *priv, u8 *srcdst, unsigned int nbytes) - { - const unsigned int bsize = SERPENT_BLOCK_SIZE; - struct crypt_priv *ctx = priv; - int i; - -- ctx->fpu_enabled = serpent_fpu_begin(ctx->fpu_enabled, nbytes); -- - if (nbytes == bsize * SERPENT_PARALLEL_BLOCKS) { -+ ctx->fpu_enabled = serpent_fpu_begin(ctx->fpu_enabled, nbytes); - serpent_enc_blk_xway(ctx->ctx, srcdst, srcdst); -+ serpent_fpu_end_rt(ctx); - return; - } - -@@ -210,10 +225,10 @@ static void decrypt_callback(void *priv, u8 *srcdst, unsigned int nbytes) - struct crypt_priv *ctx = priv; - int i; - -- ctx->fpu_enabled = serpent_fpu_begin(ctx->fpu_enabled, nbytes); -- - if (nbytes == bsize * SERPENT_PARALLEL_BLOCKS) { -+ ctx->fpu_enabled = serpent_fpu_begin(ctx->fpu_enabled, nbytes); - serpent_dec_blk_xway(ctx->ctx, srcdst, srcdst); -+ serpent_fpu_end_rt(ctx); - return; - } - -diff --git a/arch/x86/crypto/twofish_avx_glue.c b/arch/x86/crypto/twofish_avx_glue.c -index b7a3904b953c..de00fe24927e 100644 ---- a/arch/x86/crypto/twofish_avx_glue.c -+++ b/arch/x86/crypto/twofish_avx_glue.c -@@ -218,6 +218,21 @@ struct crypt_priv { - bool fpu_enabled; - }; - -+#ifdef CONFIG_PREEMPT_RT_FULL -+static void twofish_fpu_end_rt(struct crypt_priv *ctx) -+{ -+ bool fpu_enabled = ctx->fpu_enabled; -+ -+ if (!fpu_enabled) -+ return; -+ twofish_fpu_end(fpu_enabled); -+ ctx->fpu_enabled = false; -+} -+ -+#else -+static void twofish_fpu_end_rt(struct crypt_priv *ctx) { } -+#endif -+ - static void encrypt_callback(void *priv, u8 *srcdst, unsigned int nbytes) - { - const unsigned int bsize = TF_BLOCK_SIZE; -@@ -228,12 +243,16 @@ static void encrypt_callback(void *priv, u8 *srcdst, unsigned int nbytes) - - if (nbytes == bsize * TWOFISH_PARALLEL_BLOCKS) { - twofish_ecb_enc_8way(ctx->ctx, srcdst, srcdst); -+ twofish_fpu_end_rt(ctx); - return; - } - -- for (i = 0; i < nbytes / (bsize * 3); i++, srcdst += bsize * 3) -+ for (i = 0; i < nbytes / (bsize * 3); i++, srcdst += bsize * 3) { -+ kernel_fpu_resched(); - twofish_enc_blk_3way(ctx->ctx, srcdst, srcdst); -+ } - -+ twofish_fpu_end_rt(ctx); - nbytes %= bsize * 3; - - for (i = 0; i < nbytes / bsize; i++, srcdst += bsize) -@@ -250,11 +269,15 @@ static void decrypt_callback(void *priv, u8 *srcdst, unsigned int nbytes) - - if (nbytes == bsize * TWOFISH_PARALLEL_BLOCKS) { - twofish_ecb_dec_8way(ctx->ctx, srcdst, srcdst); -+ twofish_fpu_end_rt(ctx); - return; - } - -- for (i = 0; i < nbytes / (bsize * 3); i++, srcdst += bsize * 3) -+ for (i = 0; i < nbytes / (bsize * 3); i++, srcdst += bsize * 3) { -+ kernel_fpu_resched(); - twofish_dec_blk_3way(ctx->ctx, srcdst, srcdst); -+ } -+ twofish_fpu_end_rt(ctx); - - nbytes %= bsize * 3; - -diff --git a/arch/x86/include/asm/fpu/api.h b/arch/x86/include/asm/fpu/api.h -index a9caac9d4a72..18b31f22ca5d 100644 ---- a/arch/x86/include/asm/fpu/api.h -+++ b/arch/x86/include/asm/fpu/api.h -@@ -25,6 +25,7 @@ extern void __kernel_fpu_begin(void); - extern void __kernel_fpu_end(void); - extern void kernel_fpu_begin(void); - extern void kernel_fpu_end(void); -+extern void kernel_fpu_resched(void); - extern bool irq_fpu_usable(void); - - /* -diff --git a/arch/x86/kernel/fpu/core.c b/arch/x86/kernel/fpu/core.c -index 2ea85b32421a..6914dc569d1e 100644 ---- a/arch/x86/kernel/fpu/core.c -+++ b/arch/x86/kernel/fpu/core.c -@@ -138,6 +138,18 @@ void kernel_fpu_end(void) - } - EXPORT_SYMBOL_GPL(kernel_fpu_end); - -+void kernel_fpu_resched(void) -+{ -+ WARN_ON_FPU(!this_cpu_read(in_kernel_fpu)); -+ -+ if (should_resched(PREEMPT_OFFSET)) { -+ kernel_fpu_end(); -+ cond_resched(); -+ kernel_fpu_begin(); -+ } -+} -+EXPORT_SYMBOL_GPL(kernel_fpu_resched); -+ - /* - * Save the FPU state (mark it for reload if necessary): - * --- -2.19.2 - diff --git a/kernel/patches-4.14.x-rt/0357-dm-Make-rt-aware.patch b/kernel/patches-4.14.x-rt/0357-dm-Make-rt-aware.patch deleted file mode 100644 index 50a886e85..000000000 --- a/kernel/patches-4.14.x-rt/0357-dm-Make-rt-aware.patch +++ /dev/null @@ -1,32 +0,0 @@ -From 23563bf9128445fc6ad675d46f669ea4dc2d943a Mon Sep 17 00:00:00 2001 -From: Thomas Gleixner -Date: Mon, 14 Nov 2011 23:06:09 +0100 -Subject: [PATCH 357/450] dm: Make rt aware - -Use the BUG_ON_NORT variant for the irq_disabled() checks. RT has -interrupts legitimately enabled here as we cant deadlock against the -irq thread due to the "sleeping spinlocks" conversion. - -Reported-by: Luis Claudio R. Goncalves - -Signed-off-by: Thomas Gleixner ---- - drivers/md/dm-rq.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/drivers/md/dm-rq.c b/drivers/md/dm-rq.c -index eadfcfd106ff..8824aeda85cf 100644 ---- a/drivers/md/dm-rq.c -+++ b/drivers/md/dm-rq.c -@@ -671,7 +671,7 @@ static void dm_old_request_fn(struct request_queue *q) - /* Establish tio->ti before queuing work (map_tio_request) */ - tio->ti = ti; - kthread_queue_work(&md->kworker, &tio->work); -- BUG_ON(!irqs_disabled()); -+ BUG_ON_NONRT(!irqs_disabled()); - } - } - --- -2.19.2 - diff --git a/kernel/patches-4.14.x-rt/0358-acpi-rt-Convert-acpi_gbl_hardware-lock-back-to-a-raw.patch b/kernel/patches-4.14.x-rt/0358-acpi-rt-Convert-acpi_gbl_hardware-lock-back-to-a-raw.patch deleted file mode 100644 index b26e79206..000000000 --- a/kernel/patches-4.14.x-rt/0358-acpi-rt-Convert-acpi_gbl_hardware-lock-back-to-a-raw.patch +++ /dev/null @@ -1,188 +0,0 @@ -From ee23cef60bf3b4086ea1f2ea2d0dcc26dabed41b Mon Sep 17 00:00:00 2001 -From: Steven Rostedt -Date: Wed, 13 Feb 2013 09:26:05 -0500 -Subject: [PATCH 358/450] acpi/rt: Convert acpi_gbl_hardware lock back to a - raw_spinlock_t - -We hit the following bug with 3.6-rt: - -[ 5.898990] BUG: scheduling while atomic: swapper/3/0/0x00000002 -[ 5.898991] no locks held by swapper/3/0. -[ 5.898993] Modules linked in: -[ 5.898996] Pid: 0, comm: swapper/3 Not tainted 3.6.11-rt28.19.el6rt.x86_64.debug #1 -[ 5.898997] Call Trace: -[ 5.899011] [] __schedule_bug+0x67/0x90 -[ 5.899028] [] __schedule+0x793/0x7a0 -[ 5.899032] [] ? debug_rt_mutex_print_deadlock+0x50/0x200 -[ 5.899034] [] schedule+0x29/0x70 -[ 5.899036] BUG: scheduling while atomic: swapper/7/0/0x00000002 -[ 5.899037] no locks held by swapper/7/0. -[ 5.899039] [] rt_spin_lock_slowlock+0xe5/0x2f0 -[ 5.899040] Modules linked in: -[ 5.899041] -[ 5.899045] [] ? _raw_spin_unlock_irqrestore+0x38/0x90 -[ 5.899046] Pid: 0, comm: swapper/7 Not tainted 3.6.11-rt28.19.el6rt.x86_64.debug #1 -[ 5.899047] Call Trace: -[ 5.899049] [] rt_spin_lock+0x16/0x40 -[ 5.899052] [] __schedule_bug+0x67/0x90 -[ 5.899054] [] ? notifier_call_chain+0x80/0x80 -[ 5.899056] [] __schedule+0x793/0x7a0 -[ 5.899059] [] acpi_os_acquire_lock+0x1f/0x23 -[ 5.899062] [] ? debug_rt_mutex_print_deadlock+0x50/0x200 -[ 5.899068] [] acpi_write_bit_register+0x33/0xb0 -[ 5.899071] [] schedule+0x29/0x70 -[ 5.899072] [] ? acpi_read_bit_register+0x33/0x51 -[ 5.899074] [] rt_spin_lock_slowlock+0xe5/0x2f0 -[ 5.899077] [] acpi_idle_enter_bm+0x8a/0x28e -[ 5.899079] [] ? _raw_spin_unlock_irqrestore+0x38/0x90 -[ 5.899081] [] ? this_cpu_load+0x1a/0x30 -[ 5.899083] [] rt_spin_lock+0x16/0x40 -[ 5.899087] [] cpuidle_enter+0x19/0x20 -[ 5.899088] [] ? notifier_call_chain+0x80/0x80 -[ 5.899090] [] cpuidle_enter_state+0x17/0x50 -[ 5.899092] [] acpi_os_acquire_lock+0x1f/0x23 -[ 5.899094] [] cpuidle899101] [] ? - -As the acpi code disables interrupts in acpi_idle_enter_bm, and calls -code that grabs the acpi lock, it causes issues as the lock is currently -in RT a sleeping lock. - -The lock was converted from a raw to a sleeping lock due to some -previous issues, and tests that showed it didn't seem to matter. -Unfortunately, it did matter for one of our boxes. - -This patch converts the lock back to a raw lock. I've run this code on a -few of my own machines, one being my laptop that uses the acpi quite -extensively. I've been able to suspend and resume without issues. - -[ tglx: Made the change exclusive for acpi_gbl_hardware_lock ] - -Signed-off-by: Steven Rostedt -Cc: John Kacur -Cc: Clark Williams -Link: http://lkml.kernel.org/r/1360765565.23152.5.camel@gandalf.local.home - -Signed-off-by: Thomas Gleixner -Signed-off-by: Sebastian Andrzej Siewior ---- - drivers/acpi/acpica/acglobal.h | 2 +- - drivers/acpi/acpica/hwregs.c | 4 ++-- - drivers/acpi/acpica/hwxface.c | 4 ++-- - drivers/acpi/acpica/utmutex.c | 4 ++-- - include/acpi/platform/aclinux.h | 15 +++++++++++++++ - 5 files changed, 22 insertions(+), 7 deletions(-) - -diff --git a/drivers/acpi/acpica/acglobal.h b/drivers/acpi/acpica/acglobal.h -index 95eed442703f..50bc5b61d899 100644 ---- a/drivers/acpi/acpica/acglobal.h -+++ b/drivers/acpi/acpica/acglobal.h -@@ -116,7 +116,7 @@ ACPI_GLOBAL(u8, acpi_gbl_global_lock_pending); - * interrupt level - */ - ACPI_GLOBAL(acpi_spinlock, acpi_gbl_gpe_lock); /* For GPE data structs and registers */ --ACPI_GLOBAL(acpi_spinlock, acpi_gbl_hardware_lock); /* For ACPI H/W except GPE registers */ -+ACPI_GLOBAL(acpi_raw_spinlock, acpi_gbl_hardware_lock); /* For ACPI H/W except GPE registers */ - ACPI_GLOBAL(acpi_spinlock, acpi_gbl_reference_count_lock); - - /* Mutex for _OSI support */ -diff --git a/drivers/acpi/acpica/hwregs.c b/drivers/acpi/acpica/hwregs.c -index acb417b58bbb..ea49e08c263f 100644 ---- a/drivers/acpi/acpica/hwregs.c -+++ b/drivers/acpi/acpica/hwregs.c -@@ -428,14 +428,14 @@ acpi_status acpi_hw_clear_acpi_status(void) - ACPI_BITMASK_ALL_FIXED_STATUS, - ACPI_FORMAT_UINT64(acpi_gbl_xpm1a_status.address))); - -- lock_flags = acpi_os_acquire_lock(acpi_gbl_hardware_lock); -+ raw_spin_lock_irqsave(acpi_gbl_hardware_lock, lock_flags); - - /* Clear the fixed events in PM1 A/B */ - - status = acpi_hw_register_write(ACPI_REGISTER_PM1_STATUS, - ACPI_BITMASK_ALL_FIXED_STATUS); - -- acpi_os_release_lock(acpi_gbl_hardware_lock, lock_flags); -+ raw_spin_unlock_irqrestore(acpi_gbl_hardware_lock, lock_flags); - - if (ACPI_FAILURE(status)) { - goto exit; -diff --git a/drivers/acpi/acpica/hwxface.c b/drivers/acpi/acpica/hwxface.c -index 34684ae89981..fb84983e1839 100644 ---- a/drivers/acpi/acpica/hwxface.c -+++ b/drivers/acpi/acpica/hwxface.c -@@ -373,7 +373,7 @@ acpi_status acpi_write_bit_register(u32 register_id, u32 value) - return_ACPI_STATUS(AE_BAD_PARAMETER); - } - -- lock_flags = acpi_os_acquire_lock(acpi_gbl_hardware_lock); -+ raw_spin_lock_irqsave(acpi_gbl_hardware_lock, lock_flags); - - /* - * At this point, we know that the parent register is one of the -@@ -434,7 +434,7 @@ acpi_status acpi_write_bit_register(u32 register_id, u32 value) - - unlock_and_exit: - -- acpi_os_release_lock(acpi_gbl_hardware_lock, lock_flags); -+ raw_spin_unlock_irqrestore(acpi_gbl_hardware_lock, lock_flags); - return_ACPI_STATUS(status); - } - -diff --git a/drivers/acpi/acpica/utmutex.c b/drivers/acpi/acpica/utmutex.c -index 586354788018..3a3c2a86437f 100644 ---- a/drivers/acpi/acpica/utmutex.c -+++ b/drivers/acpi/acpica/utmutex.c -@@ -88,7 +88,7 @@ acpi_status acpi_ut_mutex_initialize(void) - return_ACPI_STATUS (status); - } - -- status = acpi_os_create_lock (&acpi_gbl_hardware_lock); -+ status = acpi_os_create_raw_lock (&acpi_gbl_hardware_lock); - if (ACPI_FAILURE (status)) { - return_ACPI_STATUS (status); - } -@@ -145,7 +145,7 @@ void acpi_ut_mutex_terminate(void) - /* Delete the spinlocks */ - - acpi_os_delete_lock(acpi_gbl_gpe_lock); -- acpi_os_delete_lock(acpi_gbl_hardware_lock); -+ acpi_os_delete_raw_lock(acpi_gbl_hardware_lock); - acpi_os_delete_lock(acpi_gbl_reference_count_lock); - - /* Delete the reader/writer lock */ -diff --git a/include/acpi/platform/aclinux.h b/include/acpi/platform/aclinux.h -index 1b473efd9eb6..89ee5e1dac48 100644 ---- a/include/acpi/platform/aclinux.h -+++ b/include/acpi/platform/aclinux.h -@@ -134,6 +134,7 @@ - - #define acpi_cache_t struct kmem_cache - #define acpi_spinlock spinlock_t * -+#define acpi_raw_spinlock raw_spinlock_t * - #define acpi_cpu_flags unsigned long - - /* Use native linux version of acpi_os_allocate_zeroed */ -@@ -152,6 +153,20 @@ - #define ACPI_USE_ALTERNATE_PROTOTYPE_acpi_os_get_thread_id - #define ACPI_USE_ALTERNATE_PROTOTYPE_acpi_os_create_lock - -+#define acpi_os_create_raw_lock(__handle) \ -+({ \ -+ raw_spinlock_t *lock = ACPI_ALLOCATE(sizeof(*lock)); \ -+ \ -+ if (lock) { \ -+ *(__handle) = lock; \ -+ raw_spin_lock_init(*(__handle)); \ -+ } \ -+ lock ? AE_OK : AE_NO_MEMORY; \ -+ }) -+ -+#define acpi_os_delete_raw_lock(__handle) kfree(__handle) -+ -+ - /* - * OSL interfaces used by debugger/disassembler - */ --- -2.19.2 - diff --git a/kernel/patches-4.14.x-rt/0362-char-random-don-t-print-that-the-init-is-done.patch b/kernel/patches-4.14.x-rt/0362-char-random-don-t-print-that-the-init-is-done.patch deleted file mode 100644 index 9a5d70abb..000000000 --- a/kernel/patches-4.14.x-rt/0362-char-random-don-t-print-that-the-init-is-done.patch +++ /dev/null @@ -1,186 +0,0 @@ -From d7d0f062f6df80c62645ed9029993b3a170a21a2 Mon Sep 17 00:00:00 2001 -From: Sebastian Andrzej Siewior -Date: Tue, 30 May 2017 16:39:01 +0200 -Subject: [PATCH 362/450] char/random: don't print that the init is done - -On RT we run into circular locking with pendingb_lock (workqueue), -port_lock_key (uart) and the primary_crng (random): - - ====================================================== - [ INFO: possible circular locking dependency detected ] - ------------------------------------------------------- - irq/4-serial/512 is trying to acquire lock: - ((pendingb_lock).lock){+.+...}, at: [] queue_work_on+0x5d/0x190 - - but task is already holding lock: - (&port_lock_key){+.+...}, at: [] serial8250_handle_irq.part.27+0x16/0xb0 - - which lock already depends on the new lock. - - the existing dependency chain (in reverse order) is: - - -> #3 (&port_lock_key){+.+...}: - lock_acquire+0xac/0x240 - rt_spin_lock+0x46/0x50 - serial8250_console_write+0x211/0x220 - univ8250_console_write+0x1c/0x20 - console_unlock+0x563/0x5c0 - vprintk_emit+0x277/0x320 - vprintk_default+0x1a/0x20 - vprintk_func+0x20/0x80 - printk+0x3e/0x46 - crng_fast_load+0xde/0xe0 - add_interrupt_randomness+0x16c/0x1a0 - irq_thread+0x15c/0x1e0 - kthread+0x112/0x150 - ret_from_fork+0x31/0x40 - - -> #2 (primary_crng.lock){+.+...}: - lock_acquire+0xac/0x240 - rt_spin_lock+0x46/0x50 - _extract_crng+0x39/0xa0 - extract_crng+0x3a/0x40 - get_random_u32+0x120/0x190 - new_slab+0x1d6/0x7c0 - ___slab_alloc+0x30b/0x6f0 - __slab_alloc.isra.78+0x6c/0xc0 - __kmalloc+0x254/0x3a0 - pcpu_mem_zalloc+0x3a/0x70 - percpu_init_late+0x4f/0x8a - start_kernel+0x1ec/0x3b8 - x86_64_start_reservations+0x2a/0x2c - x86_64_start_kernel+0x13d/0x14c - verify_cpu+0x0/0xfc - - -> #1 ((batched_entropy_u32_lock).lock){+.+...}: - lock_acquire+0xac/0x240 - rt_spin_lock__no_mg+0x41/0x50 - get_random_u32+0x64/0x190 - new_slab+0x1d6/0x7c0 - ___slab_alloc+0x30b/0x6f0 - __slab_alloc.isra.78+0x6c/0xc0 - kmem_cache_alloc+0x26a/0x370 - __debug_object_init+0x325/0x460 - debug_object_activate+0x11c/0x1f0 - __queue_work+0x2c/0x770 - queue_work_on+0x12a/0x190 - serio_queue_event+0xd3/0x140 - __serio_register_port+0x17e/0x1a0 - i8042_probe+0x623/0x687 - platform_drv_probe+0x36/0x90 - driver_probe_device+0x1f8/0x2e0 - __driver_attach+0x96/0xa0 - bus_for_each_dev+0x5d/0x90 - driver_attach+0x19/0x20 - bus_add_driver+0x125/0x220 - driver_register+0x5b/0xd0 - __platform_driver_probe+0x5b/0x120 - __platform_create_bundle+0xaa/0xd0 - i8042_init+0x3f1/0x430 - do_one_initcall+0x3e/0x180 - kernel_init_freeable+0x212/0x295 - kernel_init+0x9/0x100 - ret_from_fork+0x31/0x40 - - -> #0 ((pendingb_lock).lock){+.+...}: - __lock_acquire+0x11b4/0x1320 - lock_acquire+0xac/0x240 - rt_spin_lock+0x46/0x50 - queue_work_on+0x5d/0x190 - tty_flip_buffer_push+0x26/0x30 - serial8250_rx_chars+0x120/0x1f0 - serial8250_handle_irq.part.27+0x58/0xb0 - serial8250_default_handle_irq+0x4b/0x60 - serial8250_interrupt+0x5f/0xd0 - irq_forced_thread_fn+0x1e/0x70 - irq_thread+0x137/0x1e0 - kthread+0x112/0x150 - ret_from_fork+0x31/0x40 - - other info that might help us debug this: - - Chain exists of: - (pendingb_lock).lock --> primary_crng.lock --> &port_lock_key - - Possible unsafe locking scenario: - - CPU0 CPU1 - ---- ---- - lock(&port_lock_key); - lock(primary_crng.lock); - lock(&port_lock_key); - lock((pendingb_lock).lock); - - *** DEADLOCK *** - - 2 locks held by irq/4-serial/512: - #0: (&i->lock){+.+...}, at: [] serial8250_interrupt+0x30/0xd0 - #1: (&port_lock_key){+.+...}, at: [] serial8250_handle_irq.part.27+0x16/0xb0 - - stack backtrace: - CPU: 4 PID: 512 Comm: irq/4-serial Not tainted 4.11.3-rt0+ #101 - Hardware name: QEMU Standard PC (Q35 + ICH9, 2009), BIOS 1.10.2-1 04/01/2014 - Call Trace: - dump_stack+0x86/0xc1 - print_circular_bug+0x1be/0x210 - __lock_acquire+0x11b4/0x1320 - lock_acquire+0xac/0x240 - rt_spin_lock+0x46/0x50 - queue_work_on+0x5d/0x190 - tty_flip_buffer_push+0x26/0x30 - serial8250_rx_chars+0x120/0x1f0 - serial8250_handle_irq.part.27+0x58/0xb0 - serial8250_default_handle_irq+0x4b/0x60 - serial8250_interrupt+0x5f/0xd0 - irq_forced_thread_fn+0x1e/0x70 - irq_thread+0x137/0x1e0 - kthread+0x112/0x150 - ret_from_fork+0x31/0x40 - -It should work if we delay that printk after dropping the lock but we -also could skip it. - -Signed-off-by: Sebastian Andrzej Siewior ---- - drivers/char/random.c | 8 ++++++-- - 1 file changed, 6 insertions(+), 2 deletions(-) - -diff --git a/drivers/char/random.c b/drivers/char/random.c -index 9fb3c929765c..c72a7f0b4494 100644 ---- a/drivers/char/random.c -+++ b/drivers/char/random.c -@@ -857,7 +857,7 @@ static int crng_fast_load(const char *cp, size_t len) - invalidate_batched_entropy(); - crng_init = 1; - wake_up_interruptible(&crng_init_wait); -- pr_notice("random: fast init done\n"); -+ /* pr_notice("random: fast init done\n"); */ - } - return 1; - } -@@ -942,17 +942,21 @@ static void crng_reseed(struct crng_state *crng, struct entropy_store *r) - crng_init = 2; - process_random_ready_list(); - wake_up_interruptible(&crng_init_wait); -- pr_notice("random: crng init done\n"); -+ /* pr_notice("random: crng init done\n"); */ - if (unseeded_warning.missed) { -+#if 0 - pr_notice("random: %d get_random_xx warning(s) missed " - "due to ratelimiting\n", - unseeded_warning.missed); -+#endif - unseeded_warning.missed = 0; - } - if (urandom_warning.missed) { -+#if 0 - pr_notice("random: %d urandom warning(s) missed " - "due to ratelimiting\n", - urandom_warning.missed); -+#endif - urandom_warning.missed = 0; - } - } --- -2.19.2 - diff --git a/kernel/patches-4.14.x-rt/0365-scsi-qla2xxx-Use-local_irq_save_nort-in-qla2x00_poll.patch b/kernel/patches-4.14.x-rt/0365-scsi-qla2xxx-Use-local_irq_save_nort-in-qla2x00_poll.patch deleted file mode 100644 index 37443ec9f..000000000 --- a/kernel/patches-4.14.x-rt/0365-scsi-qla2xxx-Use-local_irq_save_nort-in-qla2x00_poll.patch +++ /dev/null @@ -1,54 +0,0 @@ -From 361de8c2f7523f488650c799c72f97bf6db9d9c7 Mon Sep 17 00:00:00 2001 -From: John Kacur -Date: Fri, 27 Apr 2012 12:48:46 +0200 -Subject: [PATCH 365/450] scsi: qla2xxx: Use local_irq_save_nort() in - qla2x00_poll - -RT triggers the following: - -[ 11.307652] [] __might_sleep+0xe7/0x110 -[ 11.307663] [] rt_spin_lock+0x24/0x60 -[ 11.307670] [] ? rt_spin_lock_slowunlock+0x78/0x90 -[ 11.307703] [] qla24xx_intr_handler+0x63/0x2d0 [qla2xxx] -[ 11.307736] [] qla2x00_poll+0x67/0x90 [qla2xxx] - -Function qla2x00_poll does local_irq_save() before calling qla24xx_intr_handler -which has a spinlock. Since spinlocks are sleepable on rt, it is not allowed -to call them with interrupts disabled. Therefore we use local_irq_save_nort() -instead which saves flags without disabling interrupts. - -This fix needs to be applied to v3.0-rt, v3.2-rt and v3.4-rt - -Suggested-by: Thomas Gleixner -Signed-off-by: John Kacur -Cc: Steven Rostedt -Cc: David Sommerseth -Link: http://lkml.kernel.org/r/1335523726-10024-1-git-send-email-jkacur@redhat.com - -Signed-off-by: Thomas Gleixner ---- - drivers/scsi/qla2xxx/qla_inline.h | 4 ++-- - 1 file changed, 2 insertions(+), 2 deletions(-) - -diff --git a/drivers/scsi/qla2xxx/qla_inline.h b/drivers/scsi/qla2xxx/qla_inline.h -index 3f5a0f0f8b62..c75783143dc1 100644 ---- a/drivers/scsi/qla2xxx/qla_inline.h -+++ b/drivers/scsi/qla2xxx/qla_inline.h -@@ -59,12 +59,12 @@ qla2x00_poll(struct rsp_que *rsp) - { - unsigned long flags; - struct qla_hw_data *ha = rsp->hw; -- local_irq_save(flags); -+ local_irq_save_nort(flags); - if (IS_P3P_TYPE(ha)) - qla82xx_poll(0, rsp); - else - ha->isp_ops->intr_handler(0, rsp); -- local_irq_restore(flags); -+ local_irq_restore_nort(flags); - } - - static inline uint8_t * --- -2.19.2 - diff --git a/kernel/patches-4.14.x-rt/0371-crypto-Convert-crypto-notifier-chain-to-SRCU.patch b/kernel/patches-4.14.x-rt/0371-crypto-Convert-crypto-notifier-chain-to-SRCU.patch deleted file mode 100644 index 3c6ba07a3..000000000 --- a/kernel/patches-4.14.x-rt/0371-crypto-Convert-crypto-notifier-chain-to-SRCU.patch +++ /dev/null @@ -1,192 +0,0 @@ -From 0d82bb96b2e9ad36832519b81e06c0e1c7a2a750 Mon Sep 17 00:00:00 2001 -From: Peter Zijlstra -Date: Fri, 5 Oct 2012 09:03:24 +0100 -Subject: [PATCH 371/450] crypto: Convert crypto notifier chain to SRCU - -The crypto notifier deadlocks on RT. Though this can be a real deadlock -on mainline as well due to fifo fair rwsems. - -The involved parties here are: - -[ 82.172678] swapper/0 S 0000000000000001 0 1 0 0x00000000 -[ 82.172682] ffff88042f18fcf0 0000000000000046 ffff88042f18fc80 ffffffff81491238 -[ 82.172685] 0000000000011cc0 0000000000011cc0 ffff88042f18c040 ffff88042f18ffd8 -[ 82.172688] 0000000000011cc0 0000000000011cc0 ffff88042f18ffd8 0000000000011cc0 -[ 82.172689] Call Trace: -[ 82.172697] [] ? _raw_spin_unlock_irqrestore+0x6c/0x7a -[ 82.172701] [] schedule+0x64/0x66 -[ 82.172704] [] schedule_timeout+0x27/0xd0 -[ 82.172708] [] ? unpin_current_cpu+0x1a/0x6c -[ 82.172713] [] ? migrate_enable+0x12f/0x141 -[ 82.172716] [] wait_for_common+0xbb/0x11f -[ 82.172719] [] ? try_to_wake_up+0x182/0x182 -[ 82.172722] [] wait_for_completion_interruptible+0x1d/0x2e -[ 82.172726] [] crypto_wait_for_test+0x49/0x6b -[ 82.172728] [] crypto_register_alg+0x53/0x5a -[ 82.172730] [] crypto_register_algs+0x33/0x72 -[ 82.172734] [] ? aes_init+0x12/0x12 -[ 82.172737] [] aesni_init+0x64/0x66 -[ 82.172741] [] do_one_initcall+0x7f/0x13b -[ 82.172744] [] kernel_init+0x199/0x22c -[ 82.172747] [] ? loglevel+0x31/0x31 -[ 82.172752] [] kernel_thread_helper+0x4/0x10 -[ 82.172755] [] ? retint_restore_args+0x13/0x13 -[ 82.172759] [] ? start_kernel+0x3ca/0x3ca -[ 82.172761] [] ? gs_change+0x13/0x13 - -[ 82.174186] cryptomgr_test S 0000000000000001 0 41 2 0x00000000 -[ 82.174189] ffff88042c971980 0000000000000046 ffffffff81d74830 0000000000000292 -[ 82.174192] 0000000000011cc0 0000000000011cc0 ffff88042c96eb80 ffff88042c971fd8 -[ 82.174195] 0000000000011cc0 0000000000011cc0 ffff88042c971fd8 0000000000011cc0 -[ 82.174195] Call Trace: -[ 82.174198] [] schedule+0x64/0x66 -[ 82.174201] [] schedule_timeout+0x27/0xd0 -[ 82.174204] [] ? unpin_current_cpu+0x1a/0x6c -[ 82.174206] [] ? migrate_enable+0x12f/0x141 -[ 82.174209] [] wait_for_common+0xbb/0x11f -[ 82.174212] [] ? try_to_wake_up+0x182/0x182 -[ 82.174215] [] wait_for_completion_interruptible+0x1d/0x2e -[ 82.174218] [] cryptomgr_notify+0x280/0x385 -[ 82.174221] [] notifier_call_chain+0x6b/0x98 -[ 82.174224] [] ? rt_down_read+0x10/0x12 -[ 82.174227] [] __blocking_notifier_call_chain+0x70/0x8d -[ 82.174230] [] blocking_notifier_call_chain+0x14/0x16 -[ 82.174234] [] crypto_probing_notify+0x24/0x50 -[ 82.174236] [] crypto_alg_mod_lookup+0x3e/0x74 -[ 82.174238] [] crypto_alloc_base+0x36/0x8f -[ 82.174241] [] cryptd_alloc_ablkcipher+0x6e/0xb5 -[ 82.174243] [] ? kzalloc.clone.5+0xe/0x10 -[ 82.174246] [] ablk_init_common+0x1d/0x38 -[ 82.174249] [] ablk_ecb_init+0x15/0x17 -[ 82.174251] [] __crypto_alloc_tfm+0xc7/0x114 -[ 82.174254] [] ? crypto_lookup_skcipher+0x1f/0xe4 -[ 82.174256] [] crypto_alloc_ablkcipher+0x60/0xa5 -[ 82.174258] [] alg_test_skcipher+0x24/0x9b -[ 82.174261] [] ? finish_task_switch+0x3f/0xfa -[ 82.174263] [] alg_test+0x16f/0x1d7 -[ 82.174267] [] ? cryptomgr_probe+0xac/0xac -[ 82.174269] [] cryptomgr_test+0x2c/0x47 -[ 82.174272] [] kthread+0x7e/0x86 -[ 82.174275] [] ? finish_task_switch+0xaf/0xfa -[ 82.174278] [] kernel_thread_helper+0x4/0x10 -[ 82.174281] [] ? retint_restore_args+0x13/0x13 -[ 82.174284] [] ? __init_kthread_worker+0x8c/0x8c -[ 82.174287] [] ? gs_change+0x13/0x13 - -[ 82.174329] cryptomgr_probe D 0000000000000002 0 47 2 0x00000000 -[ 82.174332] ffff88042c991b70 0000000000000046 ffff88042c991bb0 0000000000000006 -[ 82.174335] 0000000000011cc0 0000000000011cc0 ffff88042c98ed00 ffff88042c991fd8 -[ 82.174338] 0000000000011cc0 0000000000011cc0 ffff88042c991fd8 0000000000011cc0 -[ 82.174338] Call Trace: -[ 82.174342] [] schedule+0x64/0x66 -[ 82.174344] [] __rt_mutex_slowlock+0x85/0xbe -[ 82.174347] [] rt_mutex_slowlock+0xec/0x159 -[ 82.174351] [] rt_mutex_fastlock.clone.8+0x29/0x2f -[ 82.174353] [] rt_mutex_lock+0x33/0x37 -[ 82.174356] [] __rt_down_read+0x50/0x5a -[ 82.174358] [] ? rt_down_read+0x10/0x12 -[ 82.174360] [] rt_down_read+0x10/0x12 -[ 82.174363] [] __blocking_notifier_call_chain+0x58/0x8d -[ 82.174366] [] blocking_notifier_call_chain+0x14/0x16 -[ 82.174369] [] crypto_probing_notify+0x24/0x50 -[ 82.174372] [] crypto_wait_for_test+0x22/0x6b -[ 82.174374] [] crypto_register_instance+0xb4/0xc0 -[ 82.174377] [] cryptd_create+0x378/0x3b6 -[ 82.174379] [] ? __crypto_lookup_template+0x5b/0x63 -[ 82.174382] [] cryptomgr_probe+0x45/0xac -[ 82.174385] [] ? crypto_alloc_pcomp+0x1b/0x1b -[ 82.174388] [] kthread+0x7e/0x86 -[ 82.174391] [] ? finish_task_switch+0xaf/0xfa -[ 82.174394] [] kernel_thread_helper+0x4/0x10 -[ 82.174398] [] ? retint_restore_args+0x13/0x13 -[ 82.174401] [] ? __init_kthread_worker+0x8c/0x8c -[ 82.174403] [] ? gs_change+0x13/0x13 - -cryptomgr_test spawns the cryptomgr_probe thread from the notifier -call. The probe thread fires the same notifier as the test thread and -deadlocks on the rwsem on RT. - -Now this is a potential deadlock in mainline as well, because we have -fifo fair rwsems. If another thread blocks with a down_write() on the -notifier chain before the probe thread issues the down_read() it will -block the probe thread and the whole party is dead locked. - -Signed-off-by: Peter Zijlstra -Signed-off-by: Thomas Gleixner ---- - crypto/algapi.c | 4 ++-- - crypto/api.c | 6 +++--- - crypto/internal.h | 4 ++-- - 3 files changed, 7 insertions(+), 7 deletions(-) - -diff --git a/crypto/algapi.c b/crypto/algapi.c -index 50eb828db767..7bce92a6599a 100644 ---- a/crypto/algapi.c -+++ b/crypto/algapi.c -@@ -731,13 +731,13 @@ EXPORT_SYMBOL_GPL(crypto_spawn_tfm2); - - int crypto_register_notifier(struct notifier_block *nb) - { -- return blocking_notifier_chain_register(&crypto_chain, nb); -+ return srcu_notifier_chain_register(&crypto_chain, nb); - } - EXPORT_SYMBOL_GPL(crypto_register_notifier); - - int crypto_unregister_notifier(struct notifier_block *nb) - { -- return blocking_notifier_chain_unregister(&crypto_chain, nb); -+ return srcu_notifier_chain_unregister(&crypto_chain, nb); - } - EXPORT_SYMBOL_GPL(crypto_unregister_notifier); - -diff --git a/crypto/api.c b/crypto/api.c -index e485aed11ad0..089e648d2fa9 100644 ---- a/crypto/api.c -+++ b/crypto/api.c -@@ -31,7 +31,7 @@ EXPORT_SYMBOL_GPL(crypto_alg_list); - DECLARE_RWSEM(crypto_alg_sem); - EXPORT_SYMBOL_GPL(crypto_alg_sem); - --BLOCKING_NOTIFIER_HEAD(crypto_chain); -+SRCU_NOTIFIER_HEAD(crypto_chain); - EXPORT_SYMBOL_GPL(crypto_chain); - - static struct crypto_alg *crypto_larval_wait(struct crypto_alg *alg); -@@ -236,10 +236,10 @@ int crypto_probing_notify(unsigned long val, void *v) - { - int ok; - -- ok = blocking_notifier_call_chain(&crypto_chain, val, v); -+ ok = srcu_notifier_call_chain(&crypto_chain, val, v); - if (ok == NOTIFY_DONE) { - request_module("cryptomgr"); -- ok = blocking_notifier_call_chain(&crypto_chain, val, v); -+ ok = srcu_notifier_call_chain(&crypto_chain, val, v); - } - - return ok; -diff --git a/crypto/internal.h b/crypto/internal.h -index f07320423191..333d985088fe 100644 ---- a/crypto/internal.h -+++ b/crypto/internal.h -@@ -47,7 +47,7 @@ struct crypto_larval { - - extern struct list_head crypto_alg_list; - extern struct rw_semaphore crypto_alg_sem; --extern struct blocking_notifier_head crypto_chain; -+extern struct srcu_notifier_head crypto_chain; - - #ifdef CONFIG_PROC_FS - void __init crypto_init_proc(void); -@@ -143,7 +143,7 @@ static inline int crypto_is_moribund(struct crypto_alg *alg) - - static inline void crypto_notify(unsigned long val, void *v) - { -- blocking_notifier_call_chain(&crypto_chain, val, v); -+ srcu_notifier_call_chain(&crypto_chain, val, v); - } - - #endif /* _CRYPTO_INTERNAL_H */ --- -2.19.2 - diff --git a/kernel/patches-4.14.x-rt/0375-srcu-Prohibit-call_srcu-use-under-raw-spinlocks.patch b/kernel/patches-4.14.x-rt/0375-srcu-Prohibit-call_srcu-use-under-raw-spinlocks.patch deleted file mode 100644 index a2e9117ed..000000000 --- a/kernel/patches-4.14.x-rt/0375-srcu-Prohibit-call_srcu-use-under-raw-spinlocks.patch +++ /dev/null @@ -1,410 +0,0 @@ -From 43889bcadc61d257269a3e2a53b9e18735eed7cd Mon Sep 17 00:00:00 2001 -From: "Paul E. McKenney" -Date: Tue, 10 Oct 2017 13:52:30 -0700 -Subject: [PATCH 375/450] srcu: Prohibit call_srcu() use under raw spinlocks - -Upstream commit 08265b8f1a139c1cff052b35ab7cf929528f88bb - -Invoking queue_delayed_work() while holding a raw spinlock is forbidden -in -rt kernels, which is exactly what __call_srcu() does, indirectly via -srcu_funnel_gp_start(). This commit therefore downgrades Tree SRCU's -locking from raw to non-raw spinlocks, which works because call_srcu() -is not ever called while holding a raw spinlock. - -Reported-by: Sebastian Andrzej Siewior -Signed-off-by: Paul E. McKenney ---- - include/linux/srcutree.h | 8 +-- - kernel/rcu/srcutree.c | 109 ++++++++++++++++++++++++--------------- - 2 files changed, 72 insertions(+), 45 deletions(-) - -diff --git a/include/linux/srcutree.h b/include/linux/srcutree.h -index 85ae8c0dddb4..745d4ca4dd50 100644 ---- a/include/linux/srcutree.h -+++ b/include/linux/srcutree.h -@@ -40,7 +40,7 @@ struct srcu_data { - unsigned long srcu_unlock_count[2]; /* Unlocks per CPU. */ - - /* Update-side state. */ -- raw_spinlock_t __private lock ____cacheline_internodealigned_in_smp; -+ spinlock_t __private lock ____cacheline_internodealigned_in_smp; - struct rcu_segcblist srcu_cblist; /* List of callbacks.*/ - unsigned long srcu_gp_seq_needed; /* Furthest future GP needed. */ - unsigned long srcu_gp_seq_needed_exp; /* Furthest future exp GP. */ -@@ -58,7 +58,7 @@ struct srcu_data { - * Node in SRCU combining tree, similar in function to rcu_data. - */ - struct srcu_node { -- raw_spinlock_t __private lock; -+ spinlock_t __private lock; - unsigned long srcu_have_cbs[4]; /* GP seq for children */ - /* having CBs, but only */ - /* is > ->srcu_gq_seq. */ -@@ -78,7 +78,7 @@ struct srcu_struct { - struct srcu_node *level[RCU_NUM_LVLS + 1]; - /* First node at each level. */ - struct mutex srcu_cb_mutex; /* Serialize CB preparation. */ -- raw_spinlock_t __private lock; /* Protect counters */ -+ spinlock_t __private lock; /* Protect counters */ - struct mutex srcu_gp_mutex; /* Serialize GP work. */ - unsigned int srcu_idx; /* Current rdr array element. */ - unsigned long srcu_gp_seq; /* Grace-period seq #. */ -@@ -107,7 +107,7 @@ struct srcu_struct { - #define __SRCU_STRUCT_INIT(name, pcpu_name) \ - { \ - .sda = &pcpu_name, \ -- .lock = __RAW_SPIN_LOCK_UNLOCKED(name.lock), \ -+ .lock = __SPIN_LOCK_UNLOCKED(name.lock), \ - .srcu_gp_seq_needed = 0 - 1, \ - __SRCU_DEP_MAP_INIT(name) \ - } -diff --git a/kernel/rcu/srcutree.c b/kernel/rcu/srcutree.c -index b72d8c552604..c9d1f0e5f899 100644 ---- a/kernel/rcu/srcutree.c -+++ b/kernel/rcu/srcutree.c -@@ -54,6 +54,33 @@ static void srcu_invoke_callbacks(struct work_struct *work); - static void srcu_reschedule(struct srcu_struct *sp, unsigned long delay); - static void process_srcu(struct work_struct *work); - -+/* Wrappers for lock acquisition and release, see raw_spin_lock_rcu_node(). */ -+#define spin_lock_rcu_node(p) \ -+do { \ -+ spin_lock(&ACCESS_PRIVATE(p, lock)); \ -+ smp_mb__after_unlock_lock(); \ -+} while (0) -+ -+#define spin_unlock_rcu_node(p) spin_unlock(&ACCESS_PRIVATE(p, lock)) -+ -+#define spin_lock_irq_rcu_node(p) \ -+do { \ -+ spin_lock_irq(&ACCESS_PRIVATE(p, lock)); \ -+ smp_mb__after_unlock_lock(); \ -+} while (0) -+ -+#define spin_unlock_irq_rcu_node(p) \ -+ spin_unlock_irq(&ACCESS_PRIVATE(p, lock)) -+ -+#define spin_lock_irqsave_rcu_node(p, flags) \ -+do { \ -+ spin_lock_irqsave(&ACCESS_PRIVATE(p, lock), flags); \ -+ smp_mb__after_unlock_lock(); \ -+} while (0) -+ -+#define spin_unlock_irqrestore_rcu_node(p, flags) \ -+ spin_unlock_irqrestore(&ACCESS_PRIVATE(p, lock), flags) \ -+ - /* - * Initialize SRCU combining tree. Note that statically allocated - * srcu_struct structures might already have srcu_read_lock() and -@@ -78,7 +105,7 @@ static void init_srcu_struct_nodes(struct srcu_struct *sp, bool is_static) - - /* Each pass through this loop initializes one srcu_node structure. */ - rcu_for_each_node_breadth_first(sp, snp) { -- raw_spin_lock_init(&ACCESS_PRIVATE(snp, lock)); -+ spin_lock_init(&ACCESS_PRIVATE(snp, lock)); - WARN_ON_ONCE(ARRAY_SIZE(snp->srcu_have_cbs) != - ARRAY_SIZE(snp->srcu_data_have_cbs)); - for (i = 0; i < ARRAY_SIZE(snp->srcu_have_cbs); i++) { -@@ -112,7 +139,7 @@ static void init_srcu_struct_nodes(struct srcu_struct *sp, bool is_static) - snp_first = sp->level[level]; - for_each_possible_cpu(cpu) { - sdp = per_cpu_ptr(sp->sda, cpu); -- raw_spin_lock_init(&ACCESS_PRIVATE(sdp, lock)); -+ spin_lock_init(&ACCESS_PRIVATE(sdp, lock)); - rcu_segcblist_init(&sdp->srcu_cblist); - sdp->srcu_cblist_invoking = false; - sdp->srcu_gp_seq_needed = sp->srcu_gp_seq; -@@ -171,7 +198,7 @@ int __init_srcu_struct(struct srcu_struct *sp, const char *name, - /* Don't re-initialize a lock while it is held. */ - debug_check_no_locks_freed((void *)sp, sizeof(*sp)); - lockdep_init_map(&sp->dep_map, name, key, 0); -- raw_spin_lock_init(&ACCESS_PRIVATE(sp, lock)); -+ spin_lock_init(&ACCESS_PRIVATE(sp, lock)); - return init_srcu_struct_fields(sp, false); - } - EXPORT_SYMBOL_GPL(__init_srcu_struct); -@@ -188,7 +215,7 @@ EXPORT_SYMBOL_GPL(__init_srcu_struct); - */ - int init_srcu_struct(struct srcu_struct *sp) - { -- raw_spin_lock_init(&ACCESS_PRIVATE(sp, lock)); -+ spin_lock_init(&ACCESS_PRIVATE(sp, lock)); - return init_srcu_struct_fields(sp, false); - } - EXPORT_SYMBOL_GPL(init_srcu_struct); -@@ -211,13 +238,13 @@ static void check_init_srcu_struct(struct srcu_struct *sp) - /* The smp_load_acquire() pairs with the smp_store_release(). */ - if (!rcu_seq_state(smp_load_acquire(&sp->srcu_gp_seq_needed))) /*^^^*/ - return; /* Already initialized. */ -- raw_spin_lock_irqsave_rcu_node(sp, flags); -+ spin_lock_irqsave_rcu_node(sp, flags); - if (!rcu_seq_state(sp->srcu_gp_seq_needed)) { -- raw_spin_unlock_irqrestore_rcu_node(sp, flags); -+ spin_unlock_irqrestore_rcu_node(sp, flags); - return; - } - init_srcu_struct_fields(sp, true); -- raw_spin_unlock_irqrestore_rcu_node(sp, flags); -+ spin_unlock_irqrestore_rcu_node(sp, flags); - } - - /* -@@ -499,7 +526,7 @@ static void srcu_gp_end(struct srcu_struct *sp) - mutex_lock(&sp->srcu_cb_mutex); - - /* End the current grace period. */ -- raw_spin_lock_irq_rcu_node(sp); -+ spin_lock_irq_rcu_node(sp); - idx = rcu_seq_state(sp->srcu_gp_seq); - WARN_ON_ONCE(idx != SRCU_STATE_SCAN2); - cbdelay = srcu_get_delay(sp); -@@ -508,7 +535,7 @@ static void srcu_gp_end(struct srcu_struct *sp) - gpseq = rcu_seq_current(&sp->srcu_gp_seq); - if (ULONG_CMP_LT(sp->srcu_gp_seq_needed_exp, gpseq)) - sp->srcu_gp_seq_needed_exp = gpseq; -- raw_spin_unlock_irq_rcu_node(sp); -+ spin_unlock_irq_rcu_node(sp); - mutex_unlock(&sp->srcu_gp_mutex); - /* A new grace period can start at this point. But only one. */ - -@@ -516,7 +543,7 @@ static void srcu_gp_end(struct srcu_struct *sp) - idx = rcu_seq_ctr(gpseq) % ARRAY_SIZE(snp->srcu_have_cbs); - idxnext = (idx + 1) % ARRAY_SIZE(snp->srcu_have_cbs); - rcu_for_each_node_breadth_first(sp, snp) { -- raw_spin_lock_irq_rcu_node(snp); -+ spin_lock_irq_rcu_node(snp); - cbs = false; - if (snp >= sp->level[rcu_num_lvls - 1]) - cbs = snp->srcu_have_cbs[idx] == gpseq; -@@ -526,7 +553,7 @@ static void srcu_gp_end(struct srcu_struct *sp) - snp->srcu_gp_seq_needed_exp = gpseq; - mask = snp->srcu_data_have_cbs[idx]; - snp->srcu_data_have_cbs[idx] = 0; -- raw_spin_unlock_irq_rcu_node(snp); -+ spin_unlock_irq_rcu_node(snp); - if (cbs) - srcu_schedule_cbs_snp(sp, snp, mask, cbdelay); - -@@ -534,11 +561,11 @@ static void srcu_gp_end(struct srcu_struct *sp) - if (!(gpseq & counter_wrap_check)) - for (cpu = snp->grplo; cpu <= snp->grphi; cpu++) { - sdp = per_cpu_ptr(sp->sda, cpu); -- raw_spin_lock_irqsave_rcu_node(sdp, flags); -+ spin_lock_irqsave_rcu_node(sdp, flags); - if (ULONG_CMP_GE(gpseq, - sdp->srcu_gp_seq_needed + 100)) - sdp->srcu_gp_seq_needed = gpseq; -- raw_spin_unlock_irqrestore_rcu_node(sdp, flags); -+ spin_unlock_irqrestore_rcu_node(sdp, flags); - } - } - -@@ -546,17 +573,17 @@ static void srcu_gp_end(struct srcu_struct *sp) - mutex_unlock(&sp->srcu_cb_mutex); - - /* Start a new grace period if needed. */ -- raw_spin_lock_irq_rcu_node(sp); -+ spin_lock_irq_rcu_node(sp); - gpseq = rcu_seq_current(&sp->srcu_gp_seq); - if (!rcu_seq_state(gpseq) && - ULONG_CMP_LT(gpseq, sp->srcu_gp_seq_needed)) { - srcu_gp_start(sp); -- raw_spin_unlock_irq_rcu_node(sp); -+ spin_unlock_irq_rcu_node(sp); - /* Throttle expedited grace periods: Should be rare! */ - srcu_reschedule(sp, rcu_seq_ctr(gpseq) & 0x3ff - ? 0 : SRCU_INTERVAL); - } else { -- raw_spin_unlock_irq_rcu_node(sp); -+ spin_unlock_irq_rcu_node(sp); - } - } - -@@ -576,18 +603,18 @@ static void srcu_funnel_exp_start(struct srcu_struct *sp, struct srcu_node *snp, - if (rcu_seq_done(&sp->srcu_gp_seq, s) || - ULONG_CMP_GE(READ_ONCE(snp->srcu_gp_seq_needed_exp), s)) - return; -- raw_spin_lock_irqsave_rcu_node(snp, flags); -+ spin_lock_irqsave_rcu_node(snp, flags); - if (ULONG_CMP_GE(snp->srcu_gp_seq_needed_exp, s)) { -- raw_spin_unlock_irqrestore_rcu_node(snp, flags); -+ spin_unlock_irqrestore_rcu_node(snp, flags); - return; - } - WRITE_ONCE(snp->srcu_gp_seq_needed_exp, s); -- raw_spin_unlock_irqrestore_rcu_node(snp, flags); -+ spin_unlock_irqrestore_rcu_node(snp, flags); - } -- raw_spin_lock_irqsave_rcu_node(sp, flags); -+ spin_lock_irqsave_rcu_node(sp, flags); - if (!ULONG_CMP_LT(sp->srcu_gp_seq_needed_exp, s)) - sp->srcu_gp_seq_needed_exp = s; -- raw_spin_unlock_irqrestore_rcu_node(sp, flags); -+ spin_unlock_irqrestore_rcu_node(sp, flags); - } - - /* -@@ -609,12 +636,12 @@ static void srcu_funnel_gp_start(struct srcu_struct *sp, struct srcu_data *sdp, - for (; snp != NULL; snp = snp->srcu_parent) { - if (rcu_seq_done(&sp->srcu_gp_seq, s) && snp != sdp->mynode) - return; /* GP already done and CBs recorded. */ -- raw_spin_lock_irqsave_rcu_node(snp, flags); -+ spin_lock_irqsave_rcu_node(snp, flags); - if (ULONG_CMP_GE(snp->srcu_have_cbs[idx], s)) { - snp_seq = snp->srcu_have_cbs[idx]; - if (snp == sdp->mynode && snp_seq == s) - snp->srcu_data_have_cbs[idx] |= sdp->grpmask; -- raw_spin_unlock_irqrestore_rcu_node(snp, flags); -+ spin_unlock_irqrestore_rcu_node(snp, flags); - if (snp == sdp->mynode && snp_seq != s) { - srcu_schedule_cbs_sdp(sdp, do_norm - ? SRCU_INTERVAL -@@ -630,11 +657,11 @@ static void srcu_funnel_gp_start(struct srcu_struct *sp, struct srcu_data *sdp, - snp->srcu_data_have_cbs[idx] |= sdp->grpmask; - if (!do_norm && ULONG_CMP_LT(snp->srcu_gp_seq_needed_exp, s)) - snp->srcu_gp_seq_needed_exp = s; -- raw_spin_unlock_irqrestore_rcu_node(snp, flags); -+ spin_unlock_irqrestore_rcu_node(snp, flags); - } - - /* Top of tree, must ensure the grace period will be started. */ -- raw_spin_lock_irqsave_rcu_node(sp, flags); -+ spin_lock_irqsave_rcu_node(sp, flags); - if (ULONG_CMP_LT(sp->srcu_gp_seq_needed, s)) { - /* - * Record need for grace period s. Pair with load -@@ -653,7 +680,7 @@ static void srcu_funnel_gp_start(struct srcu_struct *sp, struct srcu_data *sdp, - queue_delayed_work(system_power_efficient_wq, &sp->work, - srcu_get_delay(sp)); - } -- raw_spin_unlock_irqrestore_rcu_node(sp, flags); -+ spin_unlock_irqrestore_rcu_node(sp, flags); - } - - /* -@@ -816,7 +843,7 @@ void __call_srcu(struct srcu_struct *sp, struct rcu_head *rhp, - rhp->func = func; - local_irq_save(flags); - sdp = this_cpu_ptr(sp->sda); -- raw_spin_lock_rcu_node(sdp); -+ spin_lock_rcu_node(sdp); - rcu_segcblist_enqueue(&sdp->srcu_cblist, rhp, false); - rcu_segcblist_advance(&sdp->srcu_cblist, - rcu_seq_current(&sp->srcu_gp_seq)); -@@ -830,7 +857,7 @@ void __call_srcu(struct srcu_struct *sp, struct rcu_head *rhp, - sdp->srcu_gp_seq_needed_exp = s; - needexp = true; - } -- raw_spin_unlock_irqrestore_rcu_node(sdp, flags); -+ spin_unlock_irqrestore_rcu_node(sdp, flags); - if (needgp) - srcu_funnel_gp_start(sp, sdp, s, do_norm); - else if (needexp) -@@ -886,7 +913,7 @@ static void __synchronize_srcu(struct srcu_struct *sp, bool do_norm) - - /* - * Make sure that later code is ordered after the SRCU grace -- * period. This pairs with the raw_spin_lock_irq_rcu_node() -+ * period. This pairs with the spin_lock_irq_rcu_node() - * in srcu_invoke_callbacks(). Unlike Tree RCU, this is needed - * because the current CPU might have been totally uninvolved with - * (and thus unordered against) that grace period. -@@ -1010,7 +1037,7 @@ void srcu_barrier(struct srcu_struct *sp) - */ - for_each_possible_cpu(cpu) { - sdp = per_cpu_ptr(sp->sda, cpu); -- raw_spin_lock_irq_rcu_node(sdp); -+ spin_lock_irq_rcu_node(sdp); - atomic_inc(&sp->srcu_barrier_cpu_cnt); - sdp->srcu_barrier_head.func = srcu_barrier_cb; - debug_rcu_head_queue(&sdp->srcu_barrier_head); -@@ -1019,7 +1046,7 @@ void srcu_barrier(struct srcu_struct *sp) - debug_rcu_head_unqueue(&sdp->srcu_barrier_head); - atomic_dec(&sp->srcu_barrier_cpu_cnt); - } -- raw_spin_unlock_irq_rcu_node(sdp); -+ spin_unlock_irq_rcu_node(sdp); - } - - /* Remove the initial count, at which point reaching zero can happen. */ -@@ -1068,17 +1095,17 @@ static void srcu_advance_state(struct srcu_struct *sp) - */ - idx = rcu_seq_state(smp_load_acquire(&sp->srcu_gp_seq)); /* ^^^ */ - if (idx == SRCU_STATE_IDLE) { -- raw_spin_lock_irq_rcu_node(sp); -+ spin_lock_irq_rcu_node(sp); - if (ULONG_CMP_GE(sp->srcu_gp_seq, sp->srcu_gp_seq_needed)) { - WARN_ON_ONCE(rcu_seq_state(sp->srcu_gp_seq)); -- raw_spin_unlock_irq_rcu_node(sp); -+ spin_unlock_irq_rcu_node(sp); - mutex_unlock(&sp->srcu_gp_mutex); - return; - } - idx = rcu_seq_state(READ_ONCE(sp->srcu_gp_seq)); - if (idx == SRCU_STATE_IDLE) - srcu_gp_start(sp); -- raw_spin_unlock_irq_rcu_node(sp); -+ spin_unlock_irq_rcu_node(sp); - if (idx != SRCU_STATE_IDLE) { - mutex_unlock(&sp->srcu_gp_mutex); - return; /* Someone else started the grace period. */ -@@ -1127,19 +1154,19 @@ static void srcu_invoke_callbacks(struct work_struct *work) - sdp = container_of(work, struct srcu_data, work.work); - sp = sdp->sp; - rcu_cblist_init(&ready_cbs); -- raw_spin_lock_irq_rcu_node(sdp); -+ spin_lock_irq_rcu_node(sdp); - rcu_segcblist_advance(&sdp->srcu_cblist, - rcu_seq_current(&sp->srcu_gp_seq)); - if (sdp->srcu_cblist_invoking || - !rcu_segcblist_ready_cbs(&sdp->srcu_cblist)) { -- raw_spin_unlock_irq_rcu_node(sdp); -+ spin_unlock_irq_rcu_node(sdp); - return; /* Someone else on the job or nothing to do. */ - } - - /* We are on the job! Extract and invoke ready callbacks. */ - sdp->srcu_cblist_invoking = true; - rcu_segcblist_extract_done_cbs(&sdp->srcu_cblist, &ready_cbs); -- raw_spin_unlock_irq_rcu_node(sdp); -+ spin_unlock_irq_rcu_node(sdp); - rhp = rcu_cblist_dequeue(&ready_cbs); - for (; rhp != NULL; rhp = rcu_cblist_dequeue(&ready_cbs)) { - debug_rcu_head_unqueue(rhp); -@@ -1152,13 +1179,13 @@ static void srcu_invoke_callbacks(struct work_struct *work) - * Update counts, accelerate new callbacks, and if needed, - * schedule another round of callback invocation. - */ -- raw_spin_lock_irq_rcu_node(sdp); -+ spin_lock_irq_rcu_node(sdp); - rcu_segcblist_insert_count(&sdp->srcu_cblist, &ready_cbs); - (void)rcu_segcblist_accelerate(&sdp->srcu_cblist, - rcu_seq_snap(&sp->srcu_gp_seq)); - sdp->srcu_cblist_invoking = false; - more = rcu_segcblist_ready_cbs(&sdp->srcu_cblist); -- raw_spin_unlock_irq_rcu_node(sdp); -+ spin_unlock_irq_rcu_node(sdp); - if (more) - srcu_schedule_cbs_sdp(sdp, 0); - } -@@ -1171,7 +1198,7 @@ static void srcu_reschedule(struct srcu_struct *sp, unsigned long delay) - { - bool pushgp = true; - -- raw_spin_lock_irq_rcu_node(sp); -+ spin_lock_irq_rcu_node(sp); - if (ULONG_CMP_GE(sp->srcu_gp_seq, sp->srcu_gp_seq_needed)) { - if (!WARN_ON_ONCE(rcu_seq_state(sp->srcu_gp_seq))) { - /* All requests fulfilled, time to go idle. */ -@@ -1181,7 +1208,7 @@ static void srcu_reschedule(struct srcu_struct *sp, unsigned long delay) - /* Outstanding request and no GP. Start one. */ - srcu_gp_start(sp); - } -- raw_spin_unlock_irq_rcu_node(sp); -+ spin_unlock_irq_rcu_node(sp); - - if (pushgp) - queue_delayed_work(system_power_efficient_wq, &sp->work, delay); --- -2.19.2 - diff --git a/kernel/patches-4.14.x-rt/0388-mmci-Remove-bogus-local_irq_save.patch b/kernel/patches-4.14.x-rt/0388-mmci-Remove-bogus-local_irq_save.patch deleted file mode 100644 index deacf0784..000000000 --- a/kernel/patches-4.14.x-rt/0388-mmci-Remove-bogus-local_irq_save.patch +++ /dev/null @@ -1,45 +0,0 @@ -From 00e0a0a9acb880d960e1b10a4fa3224d6a2f630a Mon Sep 17 00:00:00 2001 -From: Thomas Gleixner -Date: Wed, 9 Jan 2013 12:11:12 +0100 -Subject: [PATCH 388/450] mmci: Remove bogus local_irq_save() - -On !RT interrupt runs with interrupts disabled. On RT it's in a -thread, so no need to disable interrupts at all. - -Signed-off-by: Thomas Gleixner ---- - drivers/mmc/host/mmci.c | 5 ----- - 1 file changed, 5 deletions(-) - -diff --git a/drivers/mmc/host/mmci.c b/drivers/mmc/host/mmci.c -index f1f54a818489..ce102378df02 100644 ---- a/drivers/mmc/host/mmci.c -+++ b/drivers/mmc/host/mmci.c -@@ -1200,15 +1200,12 @@ static irqreturn_t mmci_pio_irq(int irq, void *dev_id) - struct sg_mapping_iter *sg_miter = &host->sg_miter; - struct variant_data *variant = host->variant; - void __iomem *base = host->base; -- unsigned long flags; - u32 status; - - status = readl(base + MMCISTATUS); - - dev_dbg(mmc_dev(host->mmc), "irq1 (pio) %08x\n", status); - -- local_irq_save(flags); -- - do { - unsigned int remain, len; - char *buffer; -@@ -1248,8 +1245,6 @@ static irqreturn_t mmci_pio_irq(int irq, void *dev_id) - - sg_miter_stop(sg_miter); - -- local_irq_restore(flags); -- - /* - * If we have less than the fifo 'half-full' threshold to transfer, - * trigger a PIO interrupt as soon as any data is available. --- -2.19.2 - diff --git a/kernel/patches-4.14.x-rt/0399-memcontrol-Prevent-scheduling-while-atomic-in-cgroup.patch b/kernel/patches-4.14.x-rt/0399-memcontrol-Prevent-scheduling-while-atomic-in-cgroup.patch deleted file mode 100644 index bdc064874..000000000 --- a/kernel/patches-4.14.x-rt/0399-memcontrol-Prevent-scheduling-while-atomic-in-cgroup.patch +++ /dev/null @@ -1,111 +0,0 @@ -From 34595ece203d1febe0328f568e10ed4d6a5a70c5 Mon Sep 17 00:00:00 2001 -From: Mike Galbraith -Date: Sat, 21 Jun 2014 10:09:48 +0200 -Subject: [PATCH 399/450] memcontrol: Prevent scheduling while atomic in cgroup - code - -mm, memcg: make refill_stock() use get_cpu_light() - -Nikita reported the following memcg scheduling while atomic bug: - -Call Trace: -[e22d5a90] [c0007ea8] show_stack+0x4c/0x168 (unreliable) -[e22d5ad0] [c0618c04] __schedule_bug+0x94/0xb0 -[e22d5ae0] [c060b9ec] __schedule+0x530/0x550 -[e22d5bf0] [c060bacc] schedule+0x30/0xbc -[e22d5c00] [c060ca24] rt_spin_lock_slowlock+0x180/0x27c -[e22d5c70] [c00b39dc] res_counter_uncharge_until+0x40/0xc4 -[e22d5ca0] [c013ca88] drain_stock.isra.20+0x54/0x98 -[e22d5cc0] [c01402ac] __mem_cgroup_try_charge+0x2e8/0xbac -[e22d5d70] [c01410d4] mem_cgroup_charge_common+0x3c/0x70 -[e22d5d90] [c0117284] __do_fault+0x38c/0x510 -[e22d5df0] [c011a5f4] handle_pte_fault+0x98/0x858 -[e22d5e50] [c060ed08] do_page_fault+0x42c/0x6fc -[e22d5f40] [c000f5b4] handle_page_fault+0xc/0x80 - -What happens: - - refill_stock() - get_cpu_var() - drain_stock() - res_counter_uncharge() - res_counter_uncharge_until() - spin_lock() <== boom - -Fix it by replacing get/put_cpu_var() with get/put_cpu_light(). - -Reported-by: Nikita Yushchenko -Signed-off-by: Mike Galbraith -[bigeasy: use memcg_stock_ll as a locallock since it is now IRQ-off region] -Signed-off-by: Sebastian Andrzej Siewior ---- - mm/memcontrol.c | 13 +++++++------ - 1 file changed, 7 insertions(+), 6 deletions(-) - -diff --git a/mm/memcontrol.c b/mm/memcontrol.c -index 3cc297730103..8d08b70b1ccb 100644 ---- a/mm/memcontrol.c -+++ b/mm/memcontrol.c -@@ -1723,6 +1723,7 @@ struct memcg_stock_pcp { - #define FLUSHING_CACHED_CHARGE 0 - }; - static DEFINE_PER_CPU(struct memcg_stock_pcp, memcg_stock); -+static DEFINE_LOCAL_IRQ_LOCK(memcg_stock_ll); - static DEFINE_MUTEX(percpu_charge_mutex); - - /** -@@ -1745,7 +1746,7 @@ static bool consume_stock(struct mem_cgroup *memcg, unsigned int nr_pages) - if (nr_pages > CHARGE_BATCH) - return ret; - -- local_irq_save(flags); -+ local_lock_irqsave(memcg_stock_ll, flags); - - stock = this_cpu_ptr(&memcg_stock); - if (memcg == stock->cached && stock->nr_pages >= nr_pages) { -@@ -1753,7 +1754,7 @@ static bool consume_stock(struct mem_cgroup *memcg, unsigned int nr_pages) - ret = true; - } - -- local_irq_restore(flags); -+ local_unlock_irqrestore(memcg_stock_ll, flags); - - return ret; - } -@@ -1784,13 +1785,13 @@ static void drain_local_stock(struct work_struct *dummy) - * The only protection from memory hotplug vs. drain_stock races is - * that we always operate on local CPU stock here with IRQ disabled - */ -- local_irq_save(flags); -+ local_lock_irqsave(memcg_stock_ll, flags); - - stock = this_cpu_ptr(&memcg_stock); - drain_stock(stock); - clear_bit(FLUSHING_CACHED_CHARGE, &stock->flags); - -- local_irq_restore(flags); -+ local_unlock_irqrestore(memcg_stock_ll, flags); - } - - /* -@@ -1802,7 +1803,7 @@ static void refill_stock(struct mem_cgroup *memcg, unsigned int nr_pages) - struct memcg_stock_pcp *stock; - unsigned long flags; - -- local_irq_save(flags); -+ local_lock_irqsave(memcg_stock_ll, flags); - - stock = this_cpu_ptr(&memcg_stock); - if (stock->cached != memcg) { /* reset if necessary */ -@@ -1814,7 +1815,7 @@ static void refill_stock(struct mem_cgroup *memcg, unsigned int nr_pages) - if (stock->nr_pages > CHARGE_BATCH) - drain_stock(stock); - -- local_irq_restore(flags); -+ local_unlock_irqrestore(memcg_stock_ll, flags); - } - - /* --- -2.19.2 - diff --git a/kernel/patches-4.14.x-rt/0400-Revert-memcontrol-Prevent-scheduling-while-atomic-in.patch b/kernel/patches-4.14.x-rt/0400-Revert-memcontrol-Prevent-scheduling-while-atomic-in.patch deleted file mode 100644 index 25e877b83..000000000 --- a/kernel/patches-4.14.x-rt/0400-Revert-memcontrol-Prevent-scheduling-while-atomic-in.patch +++ /dev/null @@ -1,106 +0,0 @@ -From 01aa0701d977d76b4eac89743dc50139389ed301 Mon Sep 17 00:00:00 2001 -From: "Steven Rostedt (VMware)" -Date: Wed, 22 Nov 2017 07:31:19 -0500 -Subject: [PATCH 400/450] Revert "memcontrol: Prevent scheduling while atomic - in cgroup code" - -The commit "memcontrol: Prevent scheduling while atomic in cgroup code" -fixed this issue: - - refill_stock() - get_cpu_var() - drain_stock() - res_counter_uncharge() - res_counter_uncharge_until() - spin_lock() <== boom - -But commit 3e32cb2e0a12b ("mm: memcontrol: lockless page counters") replaced -the calls to res_counter_uncharge() in drain_stock() to the lockless -function page_counter_uncharge(). There is no more spin lock there and no -more reason to have that local lock. - -Cc: -Reported-by: Haiyang HY1 Tan -Signed-off-by: Steven Rostedt (VMware) -[bigeasy: That upstream commit appeared in v3.19 and the patch in - question in v3.18.7-rt2 and v3.18 seems still to be maintained. So I - guess that v3.18 would need the locallocks that we are about to remove - here. I am not sure if any earlier versions have the patch - backported. - The stable tag here is because Haiyang reported (and debugged) a crash - in 4.4-RT with this patch applied (which has get_cpu_light() instead - the locallocks it gained in v4.9-RT). - https://lkml.kernel.org/r/05AA4EC5C6EC1D48BE2CDCFF3AE0B8A637F78A15@CNMAILEX04.lenovo.com -] -Signed-off-by: Sebastian Andrzej Siewior ---- - mm/memcontrol.c | 13 ++++++------- - 1 file changed, 6 insertions(+), 7 deletions(-) - -diff --git a/mm/memcontrol.c b/mm/memcontrol.c -index 8d08b70b1ccb..3cc297730103 100644 ---- a/mm/memcontrol.c -+++ b/mm/memcontrol.c -@@ -1723,7 +1723,6 @@ struct memcg_stock_pcp { - #define FLUSHING_CACHED_CHARGE 0 - }; - static DEFINE_PER_CPU(struct memcg_stock_pcp, memcg_stock); --static DEFINE_LOCAL_IRQ_LOCK(memcg_stock_ll); - static DEFINE_MUTEX(percpu_charge_mutex); - - /** -@@ -1746,7 +1745,7 @@ static bool consume_stock(struct mem_cgroup *memcg, unsigned int nr_pages) - if (nr_pages > CHARGE_BATCH) - return ret; - -- local_lock_irqsave(memcg_stock_ll, flags); -+ local_irq_save(flags); - - stock = this_cpu_ptr(&memcg_stock); - if (memcg == stock->cached && stock->nr_pages >= nr_pages) { -@@ -1754,7 +1753,7 @@ static bool consume_stock(struct mem_cgroup *memcg, unsigned int nr_pages) - ret = true; - } - -- local_unlock_irqrestore(memcg_stock_ll, flags); -+ local_irq_restore(flags); - - return ret; - } -@@ -1785,13 +1784,13 @@ static void drain_local_stock(struct work_struct *dummy) - * The only protection from memory hotplug vs. drain_stock races is - * that we always operate on local CPU stock here with IRQ disabled - */ -- local_lock_irqsave(memcg_stock_ll, flags); -+ local_irq_save(flags); - - stock = this_cpu_ptr(&memcg_stock); - drain_stock(stock); - clear_bit(FLUSHING_CACHED_CHARGE, &stock->flags); - -- local_unlock_irqrestore(memcg_stock_ll, flags); -+ local_irq_restore(flags); - } - - /* -@@ -1803,7 +1802,7 @@ static void refill_stock(struct mem_cgroup *memcg, unsigned int nr_pages) - struct memcg_stock_pcp *stock; - unsigned long flags; - -- local_lock_irqsave(memcg_stock_ll, flags); -+ local_irq_save(flags); - - stock = this_cpu_ptr(&memcg_stock); - if (stock->cached != memcg) { /* reset if necessary */ -@@ -1815,7 +1814,7 @@ static void refill_stock(struct mem_cgroup *memcg, unsigned int nr_pages) - if (stock->nr_pages > CHARGE_BATCH) - drain_stock(stock); - -- local_unlock_irqrestore(memcg_stock_ll, flags); -+ local_irq_restore(flags); - } - - /* --- -2.19.2 - diff --git a/kernel/patches-4.14.x-rt/0402-rt-ntp-Move-call-to-schedule_delayed_work-to-helper-.patch b/kernel/patches-4.14.x-rt/0402-rt-ntp-Move-call-to-schedule_delayed_work-to-helper-.patch deleted file mode 100644 index 8b87bed0d..000000000 --- a/kernel/patches-4.14.x-rt/0402-rt-ntp-Move-call-to-schedule_delayed_work-to-helper-.patch +++ /dev/null @@ -1,79 +0,0 @@ -From adcfdb200a27ac5fe36e4b2acf769140cd46a0ef Mon Sep 17 00:00:00 2001 -From: Steven Rostedt -Date: Wed, 26 Jun 2013 15:28:11 -0400 -Subject: [PATCH 402/450] rt,ntp: Move call to schedule_delayed_work() to - helper thread - -The ntp code for notify_cmos_timer() is called from a hard interrupt -context. schedule_delayed_work() under PREEMPT_RT_FULL calls spinlocks -that have been converted to mutexes, thus calling schedule_delayed_work() -from interrupt is not safe. - -Add a helper thread that does the call to schedule_delayed_work and wake -up that thread instead of calling schedule_delayed_work() directly. -This is only for CONFIG_PREEMPT_RT_FULL, otherwise the code still calls -schedule_delayed_work() directly in irq context. - -Note: There's a few places in the kernel that do this. Perhaps the RT -code should have a dedicated thread that does the checks. Just register -a notifier on boot up for your check and wake up the thread when -needed. This will be a todo. - -Signed-off-by: Steven Rostedt -[bigeasy: use swork_queue() instead a helper thread] -Signed-off-by: Sebastian Andrzej Siewior ---- - kernel/time/ntp.c | 26 ++++++++++++++++++++++++++ - 1 file changed, 26 insertions(+) - -diff --git a/kernel/time/ntp.c b/kernel/time/ntp.c -index 99e03bec68e4..2c226b90c231 100644 ---- a/kernel/time/ntp.c -+++ b/kernel/time/ntp.c -@@ -18,6 +18,7 @@ - #include - #include - #include -+#include - - #include "ntp_internal.h" - #include "timekeeping_internal.h" -@@ -569,10 +570,35 @@ static void sync_cmos_clock(struct work_struct *work) - &sync_cmos_work, timespec64_to_jiffies(&next)); - } - -+#ifdef CONFIG_PREEMPT_RT_FULL -+ -+static void run_clock_set_delay(struct swork_event *event) -+{ -+ queue_delayed_work(system_power_efficient_wq, &sync_cmos_work, 0); -+} -+ -+static struct swork_event ntp_cmos_swork; -+ -+void ntp_notify_cmos_timer(void) -+{ -+ swork_queue(&ntp_cmos_swork); -+} -+ -+static __init int create_cmos_delay_thread(void) -+{ -+ WARN_ON(swork_get()); -+ INIT_SWORK(&ntp_cmos_swork, run_clock_set_delay); -+ return 0; -+} -+early_initcall(create_cmos_delay_thread); -+ -+#else -+ - void ntp_notify_cmos_timer(void) - { - queue_delayed_work(system_power_efficient_wq, &sync_cmos_work, 0); - } -+#endif /* CONFIG_PREEMPT_RT_FULL */ - - #else - void ntp_notify_cmos_timer(void) { } --- -2.19.2 - diff --git a/kernel/patches-4.14.x-rt/0403-Revert-rt-ntp-Move-call-to-schedule_delayed_work-to-.patch b/kernel/patches-4.14.x-rt/0403-Revert-rt-ntp-Move-call-to-schedule_delayed_work-to-.patch deleted file mode 100644 index 8e35cad7d..000000000 --- a/kernel/patches-4.14.x-rt/0403-Revert-rt-ntp-Move-call-to-schedule_delayed_work-to-.patch +++ /dev/null @@ -1,77 +0,0 @@ -From 9b8e921f44850673998d430379102463ddb4e322 Mon Sep 17 00:00:00 2001 -From: Sebastian Andrzej Siewior -Date: Fri, 2 Mar 2018 11:37:57 +0100 -Subject: [PATCH 403/450] Revert "rt,ntp: Move call to schedule_delayed_work() - to helper thread" - -I've been looking at this in v3.10-RT where it got in. The patch -description says - -|The ntp code for notify_cmos_timer() is called from a hard interrupt -|context. - -I see only one caller of ntp_notify_cmos_timer() and that is -do_adjtimex() after "raw_spin_unlock_irqrestore()". -I see a few callers of do_adjtimex() which is SYS_adjtimex() (+compat) -and posix_clock_realtime_adj() which in turn is called by -SYS_clock_adjtime(). - -Reverting the patch. - -Cc: stable-rt@vger.kernel.org -Signed-off-by: Sebastian Andrzej Siewior ---- - kernel/time/ntp.c | 26 -------------------------- - 1 file changed, 26 deletions(-) - -diff --git a/kernel/time/ntp.c b/kernel/time/ntp.c -index 2c226b90c231..99e03bec68e4 100644 ---- a/kernel/time/ntp.c -+++ b/kernel/time/ntp.c -@@ -18,7 +18,6 @@ - #include - #include - #include --#include - - #include "ntp_internal.h" - #include "timekeeping_internal.h" -@@ -570,35 +569,10 @@ static void sync_cmos_clock(struct work_struct *work) - &sync_cmos_work, timespec64_to_jiffies(&next)); - } - --#ifdef CONFIG_PREEMPT_RT_FULL -- --static void run_clock_set_delay(struct swork_event *event) --{ -- queue_delayed_work(system_power_efficient_wq, &sync_cmos_work, 0); --} -- --static struct swork_event ntp_cmos_swork; -- --void ntp_notify_cmos_timer(void) --{ -- swork_queue(&ntp_cmos_swork); --} -- --static __init int create_cmos_delay_thread(void) --{ -- WARN_ON(swork_get()); -- INIT_SWORK(&ntp_cmos_swork, run_clock_set_delay); -- return 0; --} --early_initcall(create_cmos_delay_thread); -- --#else -- - void ntp_notify_cmos_timer(void) - { - queue_delayed_work(system_power_efficient_wq, &sync_cmos_work, 0); - } --#endif /* CONFIG_PREEMPT_RT_FULL */ - - #else - void ntp_notify_cmos_timer(void) { } --- -2.19.2 - diff --git a/kernel/patches-4.14.x-rt/0407-Add-localversion-for-RT-release.patch b/kernel/patches-4.14.x-rt/0407-Add-localversion-for-RT-release.patch deleted file mode 100644 index 97b842737..000000000 --- a/kernel/patches-4.14.x-rt/0407-Add-localversion-for-RT-release.patch +++ /dev/null @@ -1,21 +0,0 @@ -From 48efc524be9a3f19f515111ef17bd8d2b384c13c Mon Sep 17 00:00:00 2001 -From: Thomas Gleixner -Date: Fri, 8 Jul 2011 20:25:16 +0200 -Subject: [PATCH 407/450] Add localversion for -RT release - -Signed-off-by: Thomas Gleixner ---- - localversion-rt | 1 + - 1 file changed, 1 insertion(+) - create mode 100644 localversion-rt - -diff --git a/localversion-rt b/localversion-rt -new file mode 100644 -index 000000000000..90290c642ed5 ---- /dev/null -+++ b/localversion-rt -@@ -0,0 +1 @@ -+-rt29 --- -2.19.2 - diff --git a/kernel/patches-4.14.x-rt/0408-tracing-Add-field-modifier-parsing-hist-error-for-hi.patch b/kernel/patches-4.14.x-rt/0408-tracing-Add-field-modifier-parsing-hist-error-for-hi.patch deleted file mode 100644 index bfa0bdc55..000000000 --- a/kernel/patches-4.14.x-rt/0408-tracing-Add-field-modifier-parsing-hist-error-for-hi.patch +++ /dev/null @@ -1,52 +0,0 @@ -From 73ad7ee5b5504b356b95554b8eca6fd7b860f4c4 Mon Sep 17 00:00:00 2001 -From: Tom Zanussi -Date: Thu, 26 Apr 2018 20:04:49 -0500 -Subject: [PATCH 408/450] tracing: Add field modifier parsing hist error for - hist triggers - -[ commit dcf234577cd31fa16874e828b90659166ad6b80d ] - -If the user specifies an invalid field modifier for a hist trigger, -the current code correctly flags that as an error, but doesn't tell -the user what happened. - -Fix this by invoking hist_err() with an appropriate message when -invalid modifiers are specified. - -Before: - - # echo 'hist:keys=pid:ts0=common_timestamp.junkusecs' >> /sys/kernel/debug/tracing/events/sched/sched_wakeup/trigger - -su: echo: write error: Invalid argument - # cat /sys/kernel/debug/tracing/events/sched/sched_wakeup/hist - -After: - - # echo 'hist:keys=pid:ts0=common_timestamp.junkusecs' >> /sys/kernel/debug/tracing/events/sched/sched_wakeup/trigger - -su: echo: write error: Invalid argument - # cat /sys/kernel/debug/tracing/events/sched/sched_wakeup/hist - ERROR: Invalid field modifier: junkusecs - Last command: keys=pid:ts0=common_timestamp.junkusecs - -Link: http://lkml.kernel.org/r/b043c59fa79acd06a5f14a1d44dee9e5a3cd1248.1524790601.git.tom.zanussi@linux.intel.com - -Signed-off-by: Tom Zanussi -Signed-off-by: Steven Rostedt (VMware) ---- - kernel/trace/trace_events_hist.c | 1 + - 1 file changed, 1 insertion(+) - -diff --git a/kernel/trace/trace_events_hist.c b/kernel/trace/trace_events_hist.c -index 37db86145c8b..b8fee11b5be9 100644 ---- a/kernel/trace/trace_events_hist.c -+++ b/kernel/trace/trace_events_hist.c -@@ -2466,6 +2466,7 @@ parse_field(struct hist_trigger_data *hist_data, struct trace_event_file *file, - else if (strcmp(modifier, "usecs") == 0) - *flags |= HIST_FIELD_FL_TIMESTAMP_USECS; - else { -+ hist_err("Invalid field modifier: ", modifier); - field = ERR_PTR(-EINVAL); - goto out; - } --- -2.19.2 - diff --git a/kernel/patches-4.14.x-rt/0409-tracing-Add-field-parsing-hist-error-for-hist-trigge.patch b/kernel/patches-4.14.x-rt/0409-tracing-Add-field-parsing-hist-error-for-hist-trigge.patch deleted file mode 100644 index cb80f5156..000000000 --- a/kernel/patches-4.14.x-rt/0409-tracing-Add-field-parsing-hist-error-for-hist-trigge.patch +++ /dev/null @@ -1,53 +0,0 @@ -From 021f7471b02c2cfdad311aea8ede35632c0ee645 Mon Sep 17 00:00:00 2001 -From: Tom Zanussi -Date: Thu, 26 Apr 2018 20:04:48 -0500 -Subject: [PATCH 409/450] tracing: Add field parsing hist error for hist - triggers - -[ commit 5ec432d7bf9dd3b4a2b84f8974e3adb71f45fb1d ] - -If the user specifies a nonexistent field for a hist trigger, the -current code correctly flags that as an error, but doesn't tell the -user what happened. - -Fix this by invoking hist_err() with an appropriate message when -nonexistent fields are specified. - -Before: - - # echo 'hist:keys=pid:ts0=common_timestamp.usecs' >> /sys/kernel/debug/tracing/events/sched/sched_switch/trigger - -su: echo: write error: Invalid argument - # cat /sys/kernel/debug/tracing/events/sched/sched_switch/hist - -After: - - # echo 'hist:keys=pid:ts0=common_timestamp.usecs' >> /sys/kernel/debug/tracing/events/sched/sched_switch/trigger - -su: echo: write error: Invalid argument - # cat /sys/kernel/debug/tracing/events/sched/sched_switch/hist - ERROR: Couldn't find field: pid - Last command: keys=pid:ts0=common_timestamp.usecs - -Link: http://lkml.kernel.org/r/fdc8746969d16906120f162b99dd71c741e0b62c.1524790601.git.tom.zanussi@linux.intel.com - -Signed-off-by: Tom Zanussi -Reported-by: Masami Hiramatsu -Signed-off-by: Steven Rostedt (VMware) ---- - kernel/trace/trace_events_hist.c | 1 + - 1 file changed, 1 insertion(+) - -diff --git a/kernel/trace/trace_events_hist.c b/kernel/trace/trace_events_hist.c -index b8fee11b5be9..9dac8bae4f34 100644 ---- a/kernel/trace/trace_events_hist.c -+++ b/kernel/trace/trace_events_hist.c -@@ -2482,6 +2482,7 @@ parse_field(struct hist_trigger_data *hist_data, struct trace_event_file *file, - else { - field = trace_find_event_field(file->event_call, field_name); - if (!field || !field->size) { -+ hist_err("Couldn't find field: ", field_name); - field = ERR_PTR(-EINVAL); - goto out; - } --- -2.19.2 - diff --git a/kernel/patches-4.14.x-rt/0410-tracing-Restore-proper-field-flag-printing-when-disp.patch b/kernel/patches-4.14.x-rt/0410-tracing-Restore-proper-field-flag-printing-when-disp.patch deleted file mode 100644 index 902813924..000000000 --- a/kernel/patches-4.14.x-rt/0410-tracing-Restore-proper-field-flag-printing-when-disp.patch +++ /dev/null @@ -1,68 +0,0 @@ -From fde475b48caa0305c67f9be0779b4a40bb395d80 Mon Sep 17 00:00:00 2001 -From: Tom Zanussi -Date: Thu, 26 Apr 2018 20:04:47 -0500 -Subject: [PATCH 410/450] tracing: Restore proper field flag printing when - displaying triggers - -[ commit 608940dabe1bd2ce4c97524004ec86637cf80f2c ] - -The flag-printing code used when displaying hist triggers somehow got -dropped during refactoring of the inter-event patchset. This restores -it. - -Below are a couple examples - in the first case, .usecs wasn't being -displayed properly for common_timestamps and the second illustrates -the same for other flags such as .execname. - -Before: - - # echo 'hist:key=common_pid.execname:val=count:sort=count' > /sys/kernel/debug/tracing/events/syscalls/sys_enter_read/trigger - # cat /sys/kernel/debug/tracing/events/syscalls/sys_enter_read/trigger - hist:keys=common_pid:vals=hitcount,count:sort=count:size=2048 [active] - - # echo 'hist:keys=pid:ts0=common_timestamp.usecs if comm=="cyclictest"' >> /sys/kernel/debug/tracing/events/sched/sched_wakeup/trigger - # cat /sys/kernel/debug/tracing/events/sched/sched_wakeup/trigger - hist:keys=pid:vals=hitcount:ts0=common_timestamp:sort=hitcount:size=2048:clock=global if comm=="cyclictest" [active] - -After: - - # echo 'hist:key=common_pid.execname:val=count:sort=count' > /sys/kernel/debug/tracing/events/syscalls/sys_enter_read/trigger - # cat /sys/kernel/debug/tracing/events/syscalls/sys_enter_read/trigger - hist:keys=common_pid.execname:vals=hitcount,count:sort=count:size=2048 [active] - - # echo 'hist:keys=pid:ts0=common_timestamp.usecs if comm=="cyclictest"' >> /sys/kernel/debug/tracing/events/sched/sched_wakeup/trigger - # cat /sys/kernel/debug/tracing/events/sched/sched_wakeup/trigger - hist:keys=pid:vals=hitcount:ts0=common_timestamp.usecs:sort=hitcount:size=2048:clock=global if comm=="cyclictest" [active] - -Link: http://lkml.kernel.org/r/492bab42ff21806600af98a8ea901af10efbee0c.1524790601.git.tom.zanussi@linux.intel.com - -Signed-off-by: Tom Zanussi -Signed-off-by: Steven Rostedt (VMware) ---- - kernel/trace/trace_events_hist.c | 10 ++++++++++ - 1 file changed, 10 insertions(+) - -diff --git a/kernel/trace/trace_events_hist.c b/kernel/trace/trace_events_hist.c -index 9dac8bae4f34..4745ed588607 100644 ---- a/kernel/trace/trace_events_hist.c -+++ b/kernel/trace/trace_events_hist.c -@@ -4916,6 +4916,16 @@ static void hist_field_print(struct seq_file *m, struct hist_field *hist_field) - seq_printf(m, "%s", field_name); - } else if (hist_field->flags & HIST_FIELD_FL_TIMESTAMP) - seq_puts(m, "common_timestamp"); -+ -+ if (hist_field->flags) { -+ if (!(hist_field->flags & HIST_FIELD_FL_VAR_REF) && -+ !(hist_field->flags & HIST_FIELD_FL_EXPR)) { -+ const char *flags = get_hist_field_flags(hist_field); -+ -+ if (flags) -+ seq_printf(m, ".%s", flags); -+ } -+ } - } - - static int event_hist_trigger_print(struct seq_file *m, --- -2.19.2 - diff --git a/kernel/patches-4.14.x-rt/0411-tracing-Uninitialized-variable-in-create_tracing_map.patch b/kernel/patches-4.14.x-rt/0411-tracing-Uninitialized-variable-in-create_tracing_map.patch deleted file mode 100644 index 9ba593d6f..000000000 --- a/kernel/patches-4.14.x-rt/0411-tracing-Uninitialized-variable-in-create_tracing_map.patch +++ /dev/null @@ -1,39 +0,0 @@ -From 725257de5a2c7d7f5c56e8c7cd2e2bdebc89827a Mon Sep 17 00:00:00 2001 -From: Dan Carpenter -Date: Wed, 28 Mar 2018 14:48:15 +0300 -Subject: [PATCH 411/450] tracing: Uninitialized variable in - create_tracing_map_fields() - -[ commit b28d7b2dc27f0eef1ae608b49d6860f2463910f1 ] - -Smatch complains that idx can be used uninitialized when we check if -(idx < 0). It has to be the first iteration through the loop and the -HIST_FIELD_FL_STACKTRACE bit has to be clear and the HIST_FIELD_FL_VAR -bit has to be set to reach the bug. - -Link: http://lkml.kernel.org/r/20180328114815.GC29050@mwanda - -Fixes: 30350d65ac56 ("tracing: Add variable support to hist triggers") -Acked-by: Tom Zanussi -Signed-off-by: Dan Carpenter -Signed-off-by: Steven Rostedt (VMware) ---- - kernel/trace/trace_events_hist.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/kernel/trace/trace_events_hist.c b/kernel/trace/trace_events_hist.c -index 4745ed588607..b3808969ac92 100644 ---- a/kernel/trace/trace_events_hist.c -+++ b/kernel/trace/trace_events_hist.c -@@ -4459,7 +4459,7 @@ static int create_tracing_map_fields(struct hist_trigger_data *hist_data) - struct tracing_map *map = hist_data->map; - struct ftrace_event_field *field; - struct hist_field *hist_field; -- int i, idx; -+ int i, idx = 0; - - for_each_hist_field(i, hist_data) { - hist_field = hist_data->fields[i]; --- -2.19.2 - diff --git a/kernel/patches-4.14.x-rt/0412-tracing-Fix-a-potential-NULL-dereference.patch b/kernel/patches-4.14.x-rt/0412-tracing-Fix-a-potential-NULL-dereference.patch deleted file mode 100644 index b86b3cca4..000000000 --- a/kernel/patches-4.14.x-rt/0412-tracing-Fix-a-potential-NULL-dereference.patch +++ /dev/null @@ -1,35 +0,0 @@ -From af8d7ff47947a46db5dae3490d96902af582e85c Mon Sep 17 00:00:00 2001 -From: Dan Carpenter -Date: Fri, 23 Mar 2018 14:37:36 +0300 -Subject: [PATCH 412/450] tracing: Fix a potential NULL dereference - -[ commit 5e4cf2bf6d1c198a90ccc0df5ffd8e0d4ea36b48 ] - -We forgot to set the error code on this path so we return ERR_PTR(0) -which is NULL. It results in a NULL dereference in the caller. - -Link: http://lkml.kernel.org/r/20180323113735.GC28518@mwanda - -Fixes: 100719dcef44 ("tracing: Add simple expression support to hist triggers") -Acked-by: Tom Zanussi -Signed-off-by: Dan Carpenter -Signed-off-by: Steven Rostedt (VMware) ---- - kernel/trace/trace_events_hist.c | 1 + - 1 file changed, 1 insertion(+) - -diff --git a/kernel/trace/trace_events_hist.c b/kernel/trace/trace_events_hist.c -index b3808969ac92..24bc0769fdd6 100644 ---- a/kernel/trace/trace_events_hist.c -+++ b/kernel/trace/trace_events_hist.c -@@ -2777,6 +2777,7 @@ static struct hist_field *parse_expr(struct hist_trigger_data *hist_data, - expr->fn = hist_field_plus; - break; - default: -+ ret = -EINVAL; - goto free; - } - --- -2.19.2 - diff --git a/kernel/patches-4.14.x-rt/0413-sched-fair-Fix-CFS-bandwidth-control-lockdep-DEADLOC.patch b/kernel/patches-4.14.x-rt/0413-sched-fair-Fix-CFS-bandwidth-control-lockdep-DEADLOC.patch deleted file mode 100644 index 60a9fcc1f..000000000 --- a/kernel/patches-4.14.x-rt/0413-sched-fair-Fix-CFS-bandwidth-control-lockdep-DEADLOC.patch +++ /dev/null @@ -1,58 +0,0 @@ -From e03fc4f4b97262c8bddc2e79a6203f422adc41c3 Mon Sep 17 00:00:00 2001 -From: Mike Galbraith -Date: Fri, 4 May 2018 08:14:38 +0200 -Subject: [PATCH 413/450] sched/fair: Fix CFS bandwidth control lockdep - DEADLOCK report - -[ Upstream commit df7e8acc0c9a84979a448d215b8ef889efe4ac5a ] - -CFS bandwidth control yields the inversion gripe below, moving -handling quells it. - -|======================================================== -|WARNING: possible irq lock inversion dependency detected -|4.16.7-rt1-rt #2 Tainted: G E -|-------------------------------------------------------- -|sirq-hrtimer/0/15 just changed the state of lock: -| (&cfs_b->lock){+...}, at: [<000000009adb5cf7>] sched_cfs_period_timer+0x28/0x140 -|but this lock was taken by another, HARDIRQ-safe lock in the past: (&rq->lock){-...} -|and interrupts could create inverse lock ordering between them. -|other info that might help us debug this: -| Possible interrupt unsafe locking scenario: -| CPU0 CPU1 -| ---- ---- -| lock(&cfs_b->lock); -| local_irq_disable(); -| lock(&rq->lock); -| lock(&cfs_b->lock); -| -| lock(&rq->lock); - -Cc: stable-rt@vger.kernel.org -Acked-by: Steven Rostedt (VMware) -Signed-off-by: Mike Galbraith -Signed-off-by: Sebastian Andrzej Siewior -Signed-off-by: Steven Rostedt (VMware) ---- - kernel/sched/fair.c | 4 ++-- - 1 file changed, 2 insertions(+), 2 deletions(-) - -diff --git a/kernel/sched/fair.c b/kernel/sched/fair.c -index 9cae149e78b6..d0c0c13b3bcb 100644 ---- a/kernel/sched/fair.c -+++ b/kernel/sched/fair.c -@@ -4701,9 +4701,9 @@ void init_cfs_bandwidth(struct cfs_bandwidth *cfs_b) - cfs_b->period = ns_to_ktime(default_cfs_period()); - - INIT_LIST_HEAD(&cfs_b->throttled_cfs_rq); -- hrtimer_init(&cfs_b->period_timer, CLOCK_MONOTONIC, HRTIMER_MODE_ABS_PINNED); -+ hrtimer_init(&cfs_b->period_timer, CLOCK_MONOTONIC, HRTIMER_MODE_ABS_PINNED_HARD); - cfs_b->period_timer.function = sched_cfs_period_timer; -- hrtimer_init(&cfs_b->slack_timer, CLOCK_MONOTONIC, HRTIMER_MODE_REL); -+ hrtimer_init(&cfs_b->slack_timer, CLOCK_MONOTONIC, HRTIMER_MODE_REL_HARD); - cfs_b->slack_timer.function = sched_cfs_slack_timer; - cfs_b->distribute_running = 0; - } --- -2.19.2 - diff --git a/kernel/patches-4.14.x-rt/0416-PM-suspend-Prevent-might-sleep-splats-updated.patch b/kernel/patches-4.14.x-rt/0416-PM-suspend-Prevent-might-sleep-splats-updated.patch deleted file mode 100644 index c10b496a7..000000000 --- a/kernel/patches-4.14.x-rt/0416-PM-suspend-Prevent-might-sleep-splats-updated.patch +++ /dev/null @@ -1,39 +0,0 @@ -From 2c9553a6b784c6d6c423df6d05f39fb46218f9b1 Mon Sep 17 00:00:00 2001 -From: Sebastian Andrzej Siewior -Date: Tue, 29 May 2018 17:44:24 +0200 -Subject: [PATCH 416/450] PM / suspend: Prevent might sleep splats (updated) - -[ Upstream commit ec7ff06b919647a2fd7d2761a26f5a1d465e819c ] - -This is an updated version of this patch which was merged upstream as -commit c1a957d17086d20d52d7f9c8dffaeac2ee09d6f9 - -Signed-off-by: Sebastian Andrzej Siewior -Signed-off-by: Steven Rostedt (VMware) ---- - kernel/time/tick-common.c | 2 ++ - 1 file changed, 2 insertions(+) - -diff --git a/kernel/time/tick-common.c b/kernel/time/tick-common.c -index 7f5a26c3a8ee..7a87a4488a5e 100644 ---- a/kernel/time/tick-common.c -+++ b/kernel/time/tick-common.c -@@ -492,6 +492,7 @@ void tick_freeze(void) - if (tick_freeze_depth == num_online_cpus()) { - trace_suspend_resume(TPS("timekeeping_freeze"), - smp_processor_id(), true); -+ system_state = SYSTEM_SUSPEND; - timekeeping_suspend(); - } else { - tick_suspend_local(); -@@ -515,6 +516,7 @@ void tick_unfreeze(void) - - if (tick_freeze_depth == num_online_cpus()) { - timekeeping_resume(); -+ system_state = SYSTEM_RUNNING; - trace_suspend_resume(TPS("timekeeping_freeze"), - smp_processor_id(), false); - } else { --- -2.19.2 - diff --git a/kernel/patches-4.14.x-rt/0417-PM-wakeup-Make-events_lock-a-RAW_SPINLOCK.patch b/kernel/patches-4.14.x-rt/0417-PM-wakeup-Make-events_lock-a-RAW_SPINLOCK.patch deleted file mode 100644 index 7f5d48a0c..000000000 --- a/kernel/patches-4.14.x-rt/0417-PM-wakeup-Make-events_lock-a-RAW_SPINLOCK.patch +++ /dev/null @@ -1,91 +0,0 @@ -From d2b5a1778932ef8e6d6d9fad741154c7ac96ef12 Mon Sep 17 00:00:00 2001 -From: Sebastian Andrzej Siewior -Date: Fri, 25 May 2018 09:57:42 +0200 -Subject: [PATCH 417/450] PM / wakeup: Make events_lock a RAW_SPINLOCK - -[ Upstream commit 1debb85a1d7d5c7655b4574f5b0ddf5f7c84873e ] - -The `events_lock' is acquired during suspend while interrupts are -disabled even on RT. The lock is taken only for a very brief moment. -Make it a RAW lock which avoids "sleeping while atomic" warnings on RT. - -Signed-off-by: Sebastian Andrzej Siewior -Signed-off-by: Steven Rostedt (VMware) ---- - drivers/base/power/wakeup.c | 18 +++++++++--------- - 1 file changed, 9 insertions(+), 9 deletions(-) - -diff --git a/drivers/base/power/wakeup.c b/drivers/base/power/wakeup.c -index cdd6f256da59..2269d379c92f 100644 ---- a/drivers/base/power/wakeup.c -+++ b/drivers/base/power/wakeup.c -@@ -52,7 +52,7 @@ static void split_counters(unsigned int *cnt, unsigned int *inpr) - /* A preserved old value of the events counter. */ - static unsigned int saved_count; - --static DEFINE_SPINLOCK(events_lock); -+static DEFINE_RAW_SPINLOCK(events_lock); - - static void pm_wakeup_timer_fn(unsigned long data); - -@@ -180,9 +180,9 @@ void wakeup_source_add(struct wakeup_source *ws) - ws->active = false; - ws->last_time = ktime_get(); - -- spin_lock_irqsave(&events_lock, flags); -+ raw_spin_lock_irqsave(&events_lock, flags); - list_add_rcu(&ws->entry, &wakeup_sources); -- spin_unlock_irqrestore(&events_lock, flags); -+ raw_spin_unlock_irqrestore(&events_lock, flags); - } - EXPORT_SYMBOL_GPL(wakeup_source_add); - -@@ -197,9 +197,9 @@ void wakeup_source_remove(struct wakeup_source *ws) - if (WARN_ON(!ws)) - return; - -- spin_lock_irqsave(&events_lock, flags); -+ raw_spin_lock_irqsave(&events_lock, flags); - list_del_rcu(&ws->entry); -- spin_unlock_irqrestore(&events_lock, flags); -+ raw_spin_unlock_irqrestore(&events_lock, flags); - synchronize_srcu(&wakeup_srcu); - } - EXPORT_SYMBOL_GPL(wakeup_source_remove); -@@ -844,7 +844,7 @@ bool pm_wakeup_pending(void) - unsigned long flags; - bool ret = false; - -- spin_lock_irqsave(&events_lock, flags); -+ raw_spin_lock_irqsave(&events_lock, flags); - if (events_check_enabled) { - unsigned int cnt, inpr; - -@@ -852,7 +852,7 @@ bool pm_wakeup_pending(void) - ret = (cnt != saved_count || inpr > 0); - events_check_enabled = !ret; - } -- spin_unlock_irqrestore(&events_lock, flags); -+ raw_spin_unlock_irqrestore(&events_lock, flags); - - if (ret) { - pr_info("PM: Wakeup pending, aborting suspend\n"); -@@ -941,13 +941,13 @@ bool pm_save_wakeup_count(unsigned int count) - unsigned long flags; - - events_check_enabled = false; -- spin_lock_irqsave(&events_lock, flags); -+ raw_spin_lock_irqsave(&events_lock, flags); - split_counters(&cnt, &inpr); - if (cnt == count && inpr == 0) { - saved_count = count; - events_check_enabled = true; - } -- spin_unlock_irqrestore(&events_lock, flags); -+ raw_spin_unlock_irqrestore(&events_lock, flags); - return events_check_enabled; - } - --- -2.19.2 - diff --git a/kernel/patches-4.14.x-rt/0418-PM-s2idle-Make-s2idle_wait_head-swait-based.patch b/kernel/patches-4.14.x-rt/0418-PM-s2idle-Make-s2idle_wait_head-swait-based.patch deleted file mode 100644 index a8ac3aee7..000000000 --- a/kernel/patches-4.14.x-rt/0418-PM-s2idle-Make-s2idle_wait_head-swait-based.patch +++ /dev/null @@ -1,62 +0,0 @@ -From 2803214c9456f6e0a7cf24b2177f744fbde0b2ec Mon Sep 17 00:00:00 2001 -From: Sebastian Andrzej Siewior -Date: Fri, 25 May 2018 10:05:13 +0200 -Subject: [PATCH 418/450] PM / s2idle: Make s2idle_wait_head swait based - -[ Upstream commit 93f141324d4860a1294e6899923c01ec5411d70b ] - -s2idle_wait_head is used during s2idle with interrupts disabled even on -RT. There is no "custom" wake up function so swait could be used instead -which is also lower weight compared to the wait_queue. -Make s2idle_wait_head a swait_queue_head. - -Signed-off-by: Sebastian Andrzej Siewior -Signed-off-by: Steven Rostedt (VMware) ---- - kernel/power/suspend.c | 9 +++++---- - 1 file changed, 5 insertions(+), 4 deletions(-) - -diff --git a/kernel/power/suspend.c b/kernel/power/suspend.c -index 999236413460..b89605fe0e88 100644 ---- a/kernel/power/suspend.c -+++ b/kernel/power/suspend.c -@@ -27,6 +27,7 @@ - #include - #include - #include -+#include - #include - #include - #include -@@ -57,7 +58,7 @@ EXPORT_SYMBOL_GPL(pm_suspend_global_flags); - - static const struct platform_suspend_ops *suspend_ops; - static const struct platform_s2idle_ops *s2idle_ops; --static DECLARE_WAIT_QUEUE_HEAD(s2idle_wait_head); -+static DECLARE_SWAIT_QUEUE_HEAD(s2idle_wait_head); - - enum s2idle_states __read_mostly s2idle_state; - static DEFINE_RAW_SPINLOCK(s2idle_lock); -@@ -91,8 +92,8 @@ static void s2idle_enter(void) - /* Push all the CPUs into the idle loop. */ - wake_up_all_idle_cpus(); - /* Make the current CPU wait so it can enter the idle loop too. */ -- wait_event(s2idle_wait_head, -- s2idle_state == S2IDLE_STATE_WAKE); -+ swait_event(s2idle_wait_head, -+ s2idle_state == S2IDLE_STATE_WAKE); - - cpuidle_pause(); - put_online_cpus(); -@@ -159,7 +160,7 @@ void s2idle_wake(void) - raw_spin_lock_irqsave(&s2idle_lock, flags); - if (s2idle_state > S2IDLE_STATE_NONE) { - s2idle_state = S2IDLE_STATE_WAKE; -- wake_up(&s2idle_wait_head); -+ swake_up(&s2idle_wait_head); - } - raw_spin_unlock_irqrestore(&s2idle_lock, flags); - } --- -2.19.2 - diff --git a/kernel/patches-4.14.x-rt/0419-seqlock-provide-the-same-ordering-semantics-as-mainl.patch b/kernel/patches-4.14.x-rt/0419-seqlock-provide-the-same-ordering-semantics-as-mainl.patch deleted file mode 100644 index 4ff46c01e..000000000 --- a/kernel/patches-4.14.x-rt/0419-seqlock-provide-the-same-ordering-semantics-as-mainl.patch +++ /dev/null @@ -1,39 +0,0 @@ -From afe78b8ee4460bb77ce376aa675bcb60ee95ace2 Mon Sep 17 00:00:00 2001 -From: Julia Cartwright -Date: Thu, 26 Apr 2018 15:02:03 -0500 -Subject: [PATCH 419/450] seqlock: provide the same ordering semantics as - mainline - -[ Upstream commit afa4c06b89a3c0fb7784ff900ccd707bef519cb7 ] - -The mainline implementation of read_seqbegin() orders prior loads w.r.t. -the read-side critical section. Fixup the RT writer-boosting -implementation to provide the same guarantee. - -Also, while we're here, update the usage of ACCESS_ONCE() to use -READ_ONCE(). - -Fixes: e69f15cf77c23 ("seqlock: Prevent rt starvation") -Cc: stable-rt@vger.kernel.org -Signed-off-by: Julia Cartwright -Signed-off-by: Sebastian Andrzej Siewior -Signed-off-by: Steven Rostedt (VMware) ---- - include/linux/seqlock.h | 1 + - 1 file changed, 1 insertion(+) - -diff --git a/include/linux/seqlock.h b/include/linux/seqlock.h -index a59751276b94..107079a2d7ed 100644 ---- a/include/linux/seqlock.h -+++ b/include/linux/seqlock.h -@@ -462,6 +462,7 @@ static inline unsigned read_seqbegin(seqlock_t *sl) - spin_unlock_wait(&sl->lock); - goto repeat; - } -+ smp_rmb(); - return ret; - } - #endif --- -2.19.2 - diff --git a/kernel/patches-4.14.x-rt/0420-Revert-x86-UV-raw_spinlock-conversion.patch b/kernel/patches-4.14.x-rt/0420-Revert-x86-UV-raw_spinlock-conversion.patch deleted file mode 100644 index 30aa997ae..000000000 --- a/kernel/patches-4.14.x-rt/0420-Revert-x86-UV-raw_spinlock-conversion.patch +++ /dev/null @@ -1,256 +0,0 @@ -From ac07ce3c3b6d12aae774e58bb8c449c772ecc185 Mon Sep 17 00:00:00 2001 -From: Sebastian Andrzej Siewior -Date: Mon, 18 Jun 2018 10:34:34 +0200 -Subject: [PATCH 420/450] Revert "x86: UV: raw_spinlock conversion" - -[ Upstream commit 2a9c45d8f89112458364285cbe2b0729561953f1 ] - -Drop the Ultraviolet patch. UV looks broken upstream for PREEMPT, too. -Mike is the only person I know that has such a thing and he isn't going -to fix this upstream (from 1526977462.6491.1.camel@gmx.de): - -|From: Mike Galbraith -|On Tue, 2018-05-22 at 08:50 +0200, Sebastian Andrzej Siewior wrote: -|> -|> Regarding the preempt_disable() in the original patch in uv_read_rtc(): -|> This looks essential for PREEMPT configs. Is it possible to get this -|> tested by someone or else get rid of the UV code? It looks broken for -|> "uv_get_min_hub_revision_id() != 1". -| -|I suspect SGI cares not one whit about PREEMPT. -| -|> Why does PREEMPT_RT require migrate_disable() but PREEMPT only is fine -|> as-is? This does not look right. -| -|UV is not ok with a PREEMPT config, it's just that for RT it's dirt -|simple to shut it up, whereas for PREEMPT, preempt_disable() across -|uv_bau_init() doesn't cut it due to allocations, and whatever else I -|would have met before ending the whack-a-mole game. -| -|If I were in your shoes, I think I'd just stop caring about UV until a -|real user appears. AFAIK, I'm the only guy who ever ran RT on UV, and -|I only did so because SUSE asked me to look into it.. years ago now. -| -| -Mike - -Signed-off-by: Sebastian Andrzej Siewior -Signed-off-by: Steven Rostedt (VMware) ---- - arch/x86/include/asm/uv/uv_bau.h | 14 +++++++------- - arch/x86/platform/uv/tlb_uv.c | 26 +++++++++++++------------- - arch/x86/platform/uv/uv_time.c | 20 ++++++++------------ - 3 files changed, 28 insertions(+), 32 deletions(-) - -diff --git a/arch/x86/include/asm/uv/uv_bau.h b/arch/x86/include/asm/uv/uv_bau.h -index 2ac6e347bdc5..7cac79802ad2 100644 ---- a/arch/x86/include/asm/uv/uv_bau.h -+++ b/arch/x86/include/asm/uv/uv_bau.h -@@ -643,9 +643,9 @@ struct bau_control { - cycles_t send_message; - cycles_t period_end; - cycles_t period_time; -- raw_spinlock_t uvhub_lock; -- raw_spinlock_t queue_lock; -- raw_spinlock_t disable_lock; -+ spinlock_t uvhub_lock; -+ spinlock_t queue_lock; -+ spinlock_t disable_lock; - /* tunables */ - int max_concurr; - int max_concurr_const; -@@ -847,15 +847,15 @@ static inline int atom_asr(short i, struct atomic_short *v) - * to be lowered below the current 'v'. atomic_add_unless can only stop - * on equal. - */ --static inline int atomic_inc_unless_ge(raw_spinlock_t *lock, atomic_t *v, int u) -+static inline int atomic_inc_unless_ge(spinlock_t *lock, atomic_t *v, int u) - { -- raw_spin_lock(lock); -+ spin_lock(lock); - if (atomic_read(v) >= u) { -- raw_spin_unlock(lock); -+ spin_unlock(lock); - return 0; - } - atomic_inc(v); -- raw_spin_unlock(lock); -+ spin_unlock(lock); - return 1; - } - -diff --git a/arch/x86/platform/uv/tlb_uv.c b/arch/x86/platform/uv/tlb_uv.c -index 5607611df740..34f9a9ce6236 100644 ---- a/arch/x86/platform/uv/tlb_uv.c -+++ b/arch/x86/platform/uv/tlb_uv.c -@@ -740,9 +740,9 @@ static void destination_plugged(struct bau_desc *bau_desc, - - quiesce_local_uvhub(hmaster); - -- raw_spin_lock(&hmaster->queue_lock); -+ spin_lock(&hmaster->queue_lock); - reset_with_ipi(&bau_desc->distribution, bcp); -- raw_spin_unlock(&hmaster->queue_lock); -+ spin_unlock(&hmaster->queue_lock); - - end_uvhub_quiesce(hmaster); - -@@ -762,9 +762,9 @@ static void destination_timeout(struct bau_desc *bau_desc, - - quiesce_local_uvhub(hmaster); - -- raw_spin_lock(&hmaster->queue_lock); -+ spin_lock(&hmaster->queue_lock); - reset_with_ipi(&bau_desc->distribution, bcp); -- raw_spin_unlock(&hmaster->queue_lock); -+ spin_unlock(&hmaster->queue_lock); - - end_uvhub_quiesce(hmaster); - -@@ -785,7 +785,7 @@ static void disable_for_period(struct bau_control *bcp, struct ptc_stats *stat) - cycles_t tm1; - - hmaster = bcp->uvhub_master; -- raw_spin_lock(&hmaster->disable_lock); -+ spin_lock(&hmaster->disable_lock); - if (!bcp->baudisabled) { - stat->s_bau_disabled++; - tm1 = get_cycles(); -@@ -798,7 +798,7 @@ static void disable_for_period(struct bau_control *bcp, struct ptc_stats *stat) - } - } - } -- raw_spin_unlock(&hmaster->disable_lock); -+ spin_unlock(&hmaster->disable_lock); - } - - static void count_max_concurr(int stat, struct bau_control *bcp, -@@ -861,7 +861,7 @@ static void record_send_stats(cycles_t time1, cycles_t time2, - */ - static void uv1_throttle(struct bau_control *hmaster, struct ptc_stats *stat) - { -- raw_spinlock_t *lock = &hmaster->uvhub_lock; -+ spinlock_t *lock = &hmaster->uvhub_lock; - atomic_t *v; - - v = &hmaster->active_descriptor_count; -@@ -995,7 +995,7 @@ static int check_enable(struct bau_control *bcp, struct ptc_stats *stat) - struct bau_control *hmaster; - - hmaster = bcp->uvhub_master; -- raw_spin_lock(&hmaster->disable_lock); -+ spin_lock(&hmaster->disable_lock); - if (bcp->baudisabled && (get_cycles() >= bcp->set_bau_on_time)) { - stat->s_bau_reenabled++; - for_each_present_cpu(tcpu) { -@@ -1007,10 +1007,10 @@ static int check_enable(struct bau_control *bcp, struct ptc_stats *stat) - tbcp->period_giveups = 0; - } - } -- raw_spin_unlock(&hmaster->disable_lock); -+ spin_unlock(&hmaster->disable_lock); - return 0; - } -- raw_spin_unlock(&hmaster->disable_lock); -+ spin_unlock(&hmaster->disable_lock); - return -1; - } - -@@ -1942,9 +1942,9 @@ static void __init init_per_cpu_tunables(void) - bcp->cong_reps = congested_reps; - bcp->disabled_period = sec_2_cycles(disabled_period); - bcp->giveup_limit = giveup_limit; -- raw_spin_lock_init(&bcp->queue_lock); -- raw_spin_lock_init(&bcp->uvhub_lock); -- raw_spin_lock_init(&bcp->disable_lock); -+ spin_lock_init(&bcp->queue_lock); -+ spin_lock_init(&bcp->uvhub_lock); -+ spin_lock_init(&bcp->disable_lock); - } - } - -diff --git a/arch/x86/platform/uv/uv_time.c b/arch/x86/platform/uv/uv_time.c -index badf377efc21..b082d71b08ee 100644 ---- a/arch/x86/platform/uv/uv_time.c -+++ b/arch/x86/platform/uv/uv_time.c -@@ -57,7 +57,7 @@ static DEFINE_PER_CPU(struct clock_event_device, cpu_ced); - - /* There is one of these allocated per node */ - struct uv_rtc_timer_head { -- raw_spinlock_t lock; -+ spinlock_t lock; - /* next cpu waiting for timer, local node relative: */ - int next_cpu; - /* number of cpus on this node: */ -@@ -177,7 +177,7 @@ static __init int uv_rtc_allocate_timers(void) - uv_rtc_deallocate_timers(); - return -ENOMEM; - } -- raw_spin_lock_init(&head->lock); -+ spin_lock_init(&head->lock); - head->ncpus = uv_blade_nr_possible_cpus(bid); - head->next_cpu = -1; - blade_info[bid] = head; -@@ -231,7 +231,7 @@ static int uv_rtc_set_timer(int cpu, u64 expires) - unsigned long flags; - int next_cpu; - -- raw_spin_lock_irqsave(&head->lock, flags); -+ spin_lock_irqsave(&head->lock, flags); - - next_cpu = head->next_cpu; - *t = expires; -@@ -243,12 +243,12 @@ static int uv_rtc_set_timer(int cpu, u64 expires) - if (uv_setup_intr(cpu, expires)) { - *t = ULLONG_MAX; - uv_rtc_find_next_timer(head, pnode); -- raw_spin_unlock_irqrestore(&head->lock, flags); -+ spin_unlock_irqrestore(&head->lock, flags); - return -ETIME; - } - } - -- raw_spin_unlock_irqrestore(&head->lock, flags); -+ spin_unlock_irqrestore(&head->lock, flags); - return 0; - } - -@@ -267,7 +267,7 @@ static int uv_rtc_unset_timer(int cpu, int force) - unsigned long flags; - int rc = 0; - -- raw_spin_lock_irqsave(&head->lock, flags); -+ spin_lock_irqsave(&head->lock, flags); - - if ((head->next_cpu == bcpu && uv_read_rtc(NULL) >= *t) || force) - rc = 1; -@@ -279,7 +279,7 @@ static int uv_rtc_unset_timer(int cpu, int force) - uv_rtc_find_next_timer(head, pnode); - } - -- raw_spin_unlock_irqrestore(&head->lock, flags); -+ spin_unlock_irqrestore(&head->lock, flags); - - return rc; - } -@@ -299,17 +299,13 @@ static int uv_rtc_unset_timer(int cpu, int force) - static u64 uv_read_rtc(struct clocksource *cs) - { - unsigned long offset; -- u64 cycles; - -- preempt_disable(); - if (uv_get_min_hub_revision_id() == 1) - offset = 0; - else - offset = (uv_blade_processor_id() * L1_CACHE_BYTES) % PAGE_SIZE; - -- cycles = (u64)uv_read_local_mmr(UVH_RTC | offset); -- preempt_enable(); -- return cycles; -+ return (u64)uv_read_local_mmr(UVH_RTC | offset); - } - - /* --- -2.19.2 - diff --git a/kernel/patches-4.14.x-rt/0421-Revert-timer-delay-waking-softirqs-from-the-jiffy-ti.patch b/kernel/patches-4.14.x-rt/0421-Revert-timer-delay-waking-softirqs-from-the-jiffy-ti.patch deleted file mode 100644 index 8e99accea..000000000 --- a/kernel/patches-4.14.x-rt/0421-Revert-timer-delay-waking-softirqs-from-the-jiffy-ti.patch +++ /dev/null @@ -1,44 +0,0 @@ -From d05efb043fdc95a8cf20c7b0642eeec1817f9c33 Mon Sep 17 00:00:00 2001 -From: Anna-Maria Gleixner -Date: Thu, 5 Jul 2018 12:43:18 +0200 -Subject: [PATCH 421/450] Revert "timer: delay waking softirqs from the jiffy - tick" - -[ Upstream commit b5b16907c58280e015d5673dca4c6bd3fde0c348 ] - -This patch was required as long as RT tasks where accounted to CFS -load but this was only a work around. Upstream Commit 17bdcf949d03 -("sched: Drop all load weight manipulation for RT tasks") fixed the -accounting of RT tasks into CFS load. - -Remove the patch and fix dependencies. - -Signed-off-by: Anna-Maria Gleixner -Signed-off-by: Sebastian Andrzej Siewior -Signed-off-by: Steven Rostedt (VMware) ---- - kernel/time/timer.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/kernel/time/timer.c b/kernel/time/timer.c -index ea742b49bdb5..5fadd754ce20 100644 ---- a/kernel/time/timer.c -+++ b/kernel/time/timer.c -@@ -1635,13 +1635,13 @@ void update_process_times(int user_tick) - - /* Note: this timer irq context must be accounted for as well. */ - account_process_tick(p, user_tick); -- scheduler_tick(); - run_local_timers(); - rcu_check_callbacks(user_tick); - #if defined(CONFIG_IRQ_WORK) - if (in_irq()) - irq_work_tick(); - #endif -+ scheduler_tick(); - if (IS_ENABLED(CONFIG_POSIX_TIMERS)) - run_posix_cpu_timers(p); - } --- -2.19.2 - diff --git a/kernel/patches-4.14.x-rt/0422-irqchip-gic-v3-its-Make-its_lock-a-raw_spin_lock_t.patch b/kernel/patches-4.14.x-rt/0422-irqchip-gic-v3-its-Make-its_lock-a-raw_spin_lock_t.patch deleted file mode 100644 index cdedb2dac..000000000 --- a/kernel/patches-4.14.x-rt/0422-irqchip-gic-v3-its-Make-its_lock-a-raw_spin_lock_t.patch +++ /dev/null @@ -1,65 +0,0 @@ -From 931ccf1b69d6dfecdea4048cec1a5f212511960c Mon Sep 17 00:00:00 2001 -From: Sebastian Andrzej Siewior -Date: Fri, 13 Jul 2018 15:30:52 +0200 -Subject: [PATCH 422/450] irqchip/gic-v3-its: Make its_lock a raw_spin_lock_t - -[ Upstream commit c7a3334c762a9b1dd2e39cb2ded00ce66e8a06d1 ] - -The its_lock lock is held while a new device is added to the list and -during setup while the CPU is booted. Even on -RT the CPU-bootup is -performed with disabled interrupts. - -Make its_lock a raw_spin_lock_t. - -Signed-off-by: Sebastian Andrzej Siewior -Signed-off-by: Steven Rostedt (VMware) ---- - drivers/irqchip/irq-gic-v3-its.c | 10 +++++----- - 1 file changed, 5 insertions(+), 5 deletions(-) - -diff --git a/drivers/irqchip/irq-gic-v3-its.c b/drivers/irqchip/irq-gic-v3-its.c -index 2ea39a83737f..e8217ebe8c1e 100644 ---- a/drivers/irqchip/irq-gic-v3-its.c -+++ b/drivers/irqchip/irq-gic-v3-its.c -@@ -148,7 +148,7 @@ static struct { - } vpe_proxy; - - static LIST_HEAD(its_nodes); --static DEFINE_SPINLOCK(its_lock); -+static DEFINE_RAW_SPINLOCK(its_lock); - static struct rdists *gic_rdists; - static struct irq_domain *its_parent; - -@@ -1850,7 +1850,7 @@ static void its_cpu_init_collection(void) - struct its_node *its; - int cpu; - -- spin_lock(&its_lock); -+ raw_spin_lock(&its_lock); - cpu = smp_processor_id(); - - list_for_each_entry(its, &its_nodes, entry) { -@@ -1892,7 +1892,7 @@ static void its_cpu_init_collection(void) - its_send_invall(its, &its->collections[cpu]); - } - -- spin_unlock(&its_lock); -+ raw_spin_unlock(&its_lock); - } - - static struct its_device *its_find_device(struct its_node *its, u32 dev_id) -@@ -3041,9 +3041,9 @@ static int __init its_probe_one(struct resource *res, - if (err) - goto out_free_tables; - -- spin_lock(&its_lock); -+ raw_spin_lock(&its_lock); - list_add(&its->entry, &its_nodes); -- spin_unlock(&its_lock); -+ raw_spin_unlock(&its_lock); - - return 0; - --- -2.19.2 - diff --git a/kernel/patches-4.14.x-rt/0424-irqchip-gic-v3-its-Move-ITS-pend_page-allocation-int.patch b/kernel/patches-4.14.x-rt/0424-irqchip-gic-v3-its-Move-ITS-pend_page-allocation-int.patch deleted file mode 100644 index 3023ad562..000000000 --- a/kernel/patches-4.14.x-rt/0424-irqchip-gic-v3-its-Move-ITS-pend_page-allocation-int.patch +++ /dev/null @@ -1,137 +0,0 @@ -From 1536114d052ea22427284cb92273283011d46bf6 Mon Sep 17 00:00:00 2001 -From: Sebastian Andrzej Siewior -Date: Fri, 13 Jul 2018 15:45:36 +0200 -Subject: [PATCH 424/450] irqchip/gic-v3-its: Move ITS' ->pend_page allocation - into an early CPU up hook - -[ Upstream commit e083f14dc2e98ced872bf077b4d1cccf95b7e4f8 ] - -The AP-GIC-starting hook allocates memory for the ->pend_page while the -CPU is started during boot-up. This callback is invoked on the target -CPU with disabled interrupts. -This does not work on -RT beacuse memory allocations are not possible -with disabled interrupts. -Move the memory allocation to an earlier hotplug step which invoked with -enabled interrupts on the boot CPU. - -Signed-off-by: Sebastian Andrzej Siewior -Signed-off-by: Steven Rostedt (VMware) ---- - drivers/irqchip/irq-gic-v3-its.c | 60 ++++++++++++++++++++++---------- - 1 file changed, 41 insertions(+), 19 deletions(-) - -diff --git a/drivers/irqchip/irq-gic-v3-its.c b/drivers/irqchip/irq-gic-v3-its.c -index e8217ebe8c1e..60533a795124 100644 ---- a/drivers/irqchip/irq-gic-v3-its.c -+++ b/drivers/irqchip/irq-gic-v3-its.c -@@ -165,6 +165,7 @@ static DEFINE_RAW_SPINLOCK(vmovp_lock); - static DEFINE_IDA(its_vpeid_ida); - - #define gic_data_rdist() (raw_cpu_ptr(gic_rdists->rdist)) -+#define gic_data_rdist_cpu(cpu) (per_cpu_ptr(gic_rdists->rdist, cpu)) - #define gic_data_rdist_rd_base() (gic_data_rdist()->rd_base) - #define gic_data_rdist_vlpi_base() (gic_data_rdist_rd_base() + SZ_128K) - -@@ -1734,15 +1735,17 @@ static int its_alloc_collections(struct its_node *its) - return 0; - } - --static struct page *its_allocate_pending_table(gfp_t gfp_flags) -+static struct page *its_allocate_pending_table(unsigned int cpu) - { - struct page *pend_page; -+ unsigned int order; - /* - * The pending pages have to be at least 64kB aligned, - * hence the 'max(LPI_PENDBASE_SZ, SZ_64K)' below. - */ -- pend_page = alloc_pages(gfp_flags | __GFP_ZERO, -- get_order(max_t(u32, LPI_PENDBASE_SZ, SZ_64K))); -+ order = get_order(max_t(u32, LPI_PENDBASE_SZ, SZ_64K)); -+ pend_page = alloc_pages_node(cpu_to_node(cpu), GFP_KERNEL | __GFP_ZERO, -+ order); - if (!pend_page) - return NULL; - -@@ -1758,6 +1761,28 @@ static void its_free_pending_table(struct page *pt) - get_order(max_t(u32, LPI_PENDBASE_SZ, SZ_64K))); - } - -+static int its_alloc_pend_page(unsigned int cpu) -+{ -+ struct page *pend_page; -+ phys_addr_t paddr; -+ -+ pend_page = gic_data_rdist_cpu(cpu)->pend_page; -+ if (pend_page) -+ return 0; -+ -+ pend_page = its_allocate_pending_table(cpu); -+ if (!pend_page) { -+ pr_err("Failed to allocate PENDBASE for CPU%d\n", -+ smp_processor_id()); -+ return -ENOMEM; -+ } -+ -+ paddr = page_to_phys(pend_page); -+ pr_info("CPU%d: using LPI pending table @%pa\n", cpu, &paddr); -+ gic_data_rdist_cpu(cpu)->pend_page = pend_page; -+ return 0; -+} -+ - static void its_cpu_init_lpis(void) - { - void __iomem *rbase = gic_data_rdist_rd_base(); -@@ -1766,21 +1791,8 @@ static void its_cpu_init_lpis(void) - - /* If we didn't allocate the pending table yet, do it now */ - pend_page = gic_data_rdist()->pend_page; -- if (!pend_page) { -- phys_addr_t paddr; -- -- pend_page = its_allocate_pending_table(GFP_NOWAIT); -- if (!pend_page) { -- pr_err("Failed to allocate PENDBASE for CPU%d\n", -- smp_processor_id()); -- return; -- } -- -- paddr = page_to_phys(pend_page); -- pr_info("CPU%d: using LPI pending table @%pa\n", -- smp_processor_id(), &paddr); -- gic_data_rdist()->pend_page = pend_page; -- } -+ if (!pend_page) -+ return; - - /* Disable LPIs */ - val = readl_relaxed(rbase + GICR_CTLR); -@@ -2599,7 +2611,7 @@ static int its_vpe_init(struct its_vpe *vpe) - return vpe_id; - - /* Allocate VPT */ -- vpt_page = its_allocate_pending_table(GFP_KERNEL); -+ vpt_page = its_allocate_pending_table(raw_smp_processor_id()); - if (!vpt_page) { - its_vpe_id_free(vpe_id); - return -ENOMEM; -@@ -3282,6 +3294,16 @@ int __init its_init(struct fwnode_handle *handle, struct rdists *rdists, - if (err) - return err; - -+ err = cpuhp_setup_state(CPUHP_BP_PREPARE_DYN, "irqchip/arm/gicv3:prepare", -+ its_alloc_pend_page, NULL); -+ if (err < 0) { -+ pr_warn("ITS: Can't register CPU-hoplug callback.\n"); -+ return err; -+ } -+ err = its_alloc_pend_page(smp_processor_id()); -+ if (err < 0) -+ return err; -+ - list_for_each_entry(its, &its_nodes, entry) - has_v4 |= its->is_v4; - --- -2.19.2 - diff --git a/kernel/patches-4.14.x-rt/0425-irqchip-gic-v3-its-Move-pending-table-allocation-to-.patch b/kernel/patches-4.14.x-rt/0425-irqchip-gic-v3-its-Move-pending-table-allocation-to-.patch deleted file mode 100644 index e2d73e834..000000000 --- a/kernel/patches-4.14.x-rt/0425-irqchip-gic-v3-its-Move-pending-table-allocation-to-.patch +++ /dev/null @@ -1,173 +0,0 @@ -From 0f211fcb3e547aaa7e2148b82f3a019aa9eb0ffd Mon Sep 17 00:00:00 2001 -From: Marc Zyngier -Date: Fri, 27 Jul 2018 13:38:54 +0100 -Subject: [PATCH 425/450] irqchip/gic-v3-its: Move pending table allocation to - init time - -[ Upstream commit 4a0819bb25d12d39c0390636122eefba232596c1 ] - -Signed-off-by: Marc Zyngier -[bigeasy: backport commit effe377d415 ("irqchip/gic-v3-its: Move pending - table allocation to init time")] -Signed-off-by: Sebastian Andrzej Siewior -Signed-off-by: Steven Rostedt (VMware) ---- - drivers/irqchip/irq-gic-v3-its.c | 71 +++++++++++++++--------------- - include/linux/irqchip/arm-gic-v3.h | 1 + - 2 files changed, 37 insertions(+), 35 deletions(-) - -diff --git a/drivers/irqchip/irq-gic-v3-its.c b/drivers/irqchip/irq-gic-v3-its.c -index 60533a795124..a3e23d0fc4af 100644 ---- a/drivers/irqchip/irq-gic-v3-its.c -+++ b/drivers/irqchip/irq-gic-v3-its.c -@@ -1433,7 +1433,7 @@ static void its_free_prop_table(struct page *prop_page) - get_order(LPI_PROPBASE_SZ)); - } - --static int __init its_alloc_lpi_tables(void) -+static int __init its_alloc_lpi_prop_table(void) - { - phys_addr_t paddr; - -@@ -1735,17 +1735,15 @@ static int its_alloc_collections(struct its_node *its) - return 0; - } - --static struct page *its_allocate_pending_table(unsigned int cpu) -+static struct page *its_allocate_pending_table(gfp_t gfp_flags) - { - struct page *pend_page; -- unsigned int order; - /* - * The pending pages have to be at least 64kB aligned, - * hence the 'max(LPI_PENDBASE_SZ, SZ_64K)' below. - */ -- order = get_order(max_t(u32, LPI_PENDBASE_SZ, SZ_64K)); -- pend_page = alloc_pages_node(cpu_to_node(cpu), GFP_KERNEL | __GFP_ZERO, -- order); -+ pend_page = alloc_pages(gfp_flags | __GFP_ZERO, -+ get_order(max_t(u32, LPI_PENDBASE_SZ, SZ_64K))); - if (!pend_page) - return NULL; - -@@ -1761,25 +1759,31 @@ static void its_free_pending_table(struct page *pt) - get_order(max_t(u32, LPI_PENDBASE_SZ, SZ_64K))); - } - --static int its_alloc_pend_page(unsigned int cpu) -+static int __init allocate_lpi_tables(void) - { -- struct page *pend_page; -- phys_addr_t paddr; -+ int err, cpu; - -- pend_page = gic_data_rdist_cpu(cpu)->pend_page; -- if (pend_page) -- return 0; -+ err = its_alloc_lpi_prop_table(); -+ if (err) -+ return err; - -- pend_page = its_allocate_pending_table(cpu); -- if (!pend_page) { -- pr_err("Failed to allocate PENDBASE for CPU%d\n", -- smp_processor_id()); -- return -ENOMEM; -+ /* -+ * We allocate all the pending tables anyway, as we may have a -+ * mix of RDs that have had LPIs enabled, and some that -+ * don't. We'll free the unused ones as each CPU comes online. -+ */ -+ for_each_possible_cpu(cpu) { -+ struct page *pend_page; -+ -+ pend_page = its_allocate_pending_table(GFP_NOWAIT); -+ if (!pend_page) { -+ pr_err("Failed to allocate PENDBASE for CPU%d\n", cpu); -+ return -ENOMEM; -+ } -+ -+ gic_data_rdist_cpu(cpu)->pend_page = pend_page; - } - -- paddr = page_to_phys(pend_page); -- pr_info("CPU%d: using LPI pending table @%pa\n", cpu, &paddr); -- gic_data_rdist_cpu(cpu)->pend_page = pend_page; - return 0; - } - -@@ -1787,13 +1791,15 @@ static void its_cpu_init_lpis(void) - { - void __iomem *rbase = gic_data_rdist_rd_base(); - struct page *pend_page; -+ phys_addr_t paddr; - u64 val, tmp; - -- /* If we didn't allocate the pending table yet, do it now */ -- pend_page = gic_data_rdist()->pend_page; -- if (!pend_page) -+ if (gic_data_rdist()->lpi_enabled) - return; - -+ pend_page = gic_data_rdist()->pend_page; -+ paddr = page_to_phys(pend_page); -+ - /* Disable LPIs */ - val = readl_relaxed(rbase + GICR_CTLR); - val &= ~GICR_CTLR_ENABLE_LPIS; -@@ -1855,6 +1861,10 @@ static void its_cpu_init_lpis(void) - - /* Make sure the GIC has seen the above */ - dsb(sy); -+ gic_data_rdist()->lpi_enabled = true; -+ pr_info("GICv3: CPU%d: using LPI pending table @%pa\n", -+ smp_processor_id(), -+ &paddr); - } - - static void its_cpu_init_collection(void) -@@ -2611,7 +2621,7 @@ static int its_vpe_init(struct its_vpe *vpe) - return vpe_id; - - /* Allocate VPT */ -- vpt_page = its_allocate_pending_table(raw_smp_processor_id()); -+ vpt_page = its_allocate_pending_table(GFP_KERNEL); - if (!vpt_page) { - its_vpe_id_free(vpe_id); - return -ENOMEM; -@@ -3290,18 +3300,9 @@ int __init its_init(struct fwnode_handle *handle, struct rdists *rdists, - } - - gic_rdists = rdists; -- err = its_alloc_lpi_tables(); -- if (err) -- return err; - -- err = cpuhp_setup_state(CPUHP_BP_PREPARE_DYN, "irqchip/arm/gicv3:prepare", -- its_alloc_pend_page, NULL); -- if (err < 0) { -- pr_warn("ITS: Can't register CPU-hoplug callback.\n"); -- return err; -- } -- err = its_alloc_pend_page(smp_processor_id()); -- if (err < 0) -+ err = allocate_lpi_tables(); -+ if (err) - return err; - - list_for_each_entry(its, &its_nodes, entry) -diff --git a/include/linux/irqchip/arm-gic-v3.h b/include/linux/irqchip/arm-gic-v3.h -index bacb499c512c..688f2565294c 100644 ---- a/include/linux/irqchip/arm-gic-v3.h -+++ b/include/linux/irqchip/arm-gic-v3.h -@@ -568,6 +568,7 @@ struct rdists { - void __iomem *rd_base; - struct page *pend_page; - phys_addr_t phys_base; -+ bool lpi_enabled; - } __percpu *rdist; - struct page *prop_page; - int id_bits; --- -2.19.2 - diff --git a/kernel/patches-4.14.x-rt/0431-sched-core-Avoid-__schedule-being-called-twice-in-a-.patch b/kernel/patches-4.14.x-rt/0431-sched-core-Avoid-__schedule-being-called-twice-in-a-.patch deleted file mode 100644 index 793fe75d9..000000000 --- a/kernel/patches-4.14.x-rt/0431-sched-core-Avoid-__schedule-being-called-twice-in-a-.patch +++ /dev/null @@ -1,63 +0,0 @@ -From 339ab2c54f152afd0404e49eaa811e16f0f8ba4a Mon Sep 17 00:00:00 2001 -From: Daniel Bristot de Oliveira -Date: Mon, 30 Jul 2018 15:00:00 +0200 -Subject: [PATCH 431/450] sched/core: Avoid __schedule() being called twice in - a row - -[ Upstream commit 2bb94c48b2ffaabf8c15a51e5cc1b4c541988cab ] - -If a worker invokes schedule() then we may have the call chain: - schedule() - -> sched_submit_work() - -> wq_worker_sleeping() - -> wake_up_worker() - -> wake_up_process(). - -The last wakeup may cause a schedule which is unnecessary because we are -already in schedule() and do it anyway. - -Add a preempt_disable() + preempt_enable_no_resched() around -wq_worker_sleeping() so the context switch could be delayed until -__schedule(). - -Signed-off-by: Daniel Bristot de Oliveira -Cc: Clark Williams -Cc: Tommaso Cucinotta -Cc: Romulo da Silva de Oliveira -Cc: Sebastian Andrzej Siewior -Cc: Steven Rostedt -Cc: Thomas Gleixner -Cc: Ingo Molnar -Cc: Peter Zijlstra -Signed-off-by: Steven Rostedt (VMware) -[bigeasy: rewrite changelog] -Signed-off-by: Sebastian Andrzej Siewior ---- - kernel/sched/core.c | 9 +++++++-- - 1 file changed, 7 insertions(+), 2 deletions(-) - -diff --git a/kernel/sched/core.c b/kernel/sched/core.c -index 97b690d741f4..e1fc94836fe0 100644 ---- a/kernel/sched/core.c -+++ b/kernel/sched/core.c -@@ -3482,10 +3482,15 @@ static inline void sched_submit_work(struct task_struct *tsk) - /* - * If a worker went to sleep, notify and ask workqueue whether - * it wants to wake up a task to maintain concurrency. -+ * As this function is called inside the schedule() context, -+ * we disable preemption to avoid it calling schedule() again -+ * in the possible wakeup of a kworker. - */ -- if (tsk->flags & PF_WQ_WORKER) -+ if (tsk->flags & PF_WQ_WORKER) { -+ preempt_disable(); - wq_worker_sleeping(tsk); -- -+ preempt_enable_no_resched(); -+ } - - if (tsk_is_pi_blocked(tsk)) - return; --- -2.19.2 - diff --git a/kernel/patches-4.14.x-rt/0432-Revert-arm64-xen-Make-XEN-depend-on-RT.patch b/kernel/patches-4.14.x-rt/0432-Revert-arm64-xen-Make-XEN-depend-on-RT.patch deleted file mode 100644 index 347a636f0..000000000 --- a/kernel/patches-4.14.x-rt/0432-Revert-arm64-xen-Make-XEN-depend-on-RT.patch +++ /dev/null @@ -1,33 +0,0 @@ -From b22fe53abbec4dc14892f13227d5fcac87fdbfa8 Mon Sep 17 00:00:00 2001 -From: Sebastian Andrzej Siewior -Date: Thu, 2 Aug 2018 17:11:01 +0200 -Subject: [PATCH 432/450] Revert "arm64/xen: Make XEN depend on !RT" - -[ Upstream commit c0a308b58829bd4066bce841fe49e8277a0cb32b ] - -Iain Hunter reported that there are no problems with it so there is no -reason to keep it disabled. - -Reported-by: Iain Hunter -Signed-off-by: Sebastian Andrzej Siewior -Signed-off-by: Steven Rostedt (VMware) ---- - arch/arm64/Kconfig | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig -index f3c5213ea0ec..458d2033ffde 100644 ---- a/arch/arm64/Kconfig -+++ b/arch/arm64/Kconfig -@@ -791,7 +791,7 @@ config XEN_DOM0 - - config XEN - bool "Xen guest support on ARM64" -- depends on ARM64 && OF && !PREEMPT_RT_FULL -+ depends on ARM64 && OF - select SWIOTLB_XEN - select PARAVIRT - help --- -2.19.2 - diff --git a/kernel/patches-4.14.x-rt/0435-Revert-softirq-keep-the-softirq-pending-check-RT-onl.patch b/kernel/patches-4.14.x-rt/0435-Revert-softirq-keep-the-softirq-pending-check-RT-onl.patch deleted file mode 100644 index 8ccdd238a..000000000 --- a/kernel/patches-4.14.x-rt/0435-Revert-softirq-keep-the-softirq-pending-check-RT-onl.patch +++ /dev/null @@ -1,44 +0,0 @@ -From 0b426ba3f0d9f10f0e68cc12ec761cbc18ad7e07 Mon Sep 17 00:00:00 2001 -From: "Steven Rostedt (VMware)" -Date: Fri, 7 Sep 2018 15:49:16 -0400 -Subject: [PATCH 435/450] Revert "softirq: keep the 'softirq pending' check - RT-only" - -This reverts commit 5536f5491a2e098ba34995662dfc0e82d66d65c9. - -Sebastian says that the stable commits: - - 0a0e0829f9901 ("nohz: Fix missing tick reprogram when interrupting an inline softirq") - 80d20d35af1ed ("nohz: Fix local_timer_softirq_pending()") - -Make this commit obsolete, thus it should be reverted. - -Link: http://lkml.kernel.org/r/20180906193028.jvyp2dj3rto4ax7s@linutronix.de - -Signed-off-by: Steven Rostedt (VMware) ---- - kernel/softirq.c | 7 +------ - 1 file changed, 1 insertion(+), 6 deletions(-) - -diff --git a/kernel/softirq.c b/kernel/softirq.c -index e3f89bcef432..583c9ecf04e3 100644 ---- a/kernel/softirq.c -+++ b/kernel/softirq.c -@@ -842,13 +842,8 @@ static inline void tick_irq_exit(void) - int cpu = smp_processor_id(); - - /* Make sure that timer wheel updates are propagated */ --#ifdef CONFIG_PREEMPT_RT_BASE - if ((idle_cpu(cpu) || tick_nohz_full_cpu(cpu)) && -- !need_resched() && !local_softirq_pending()) --#else -- if ((idle_cpu(cpu) && !need_resched()) || tick_nohz_full_cpu(cpu)) --#endif -- { -+ !need_resched() && !local_softirq_pending()) { - if (!in_irq()) - tick_nohz_irq_exit(); - } --- -2.19.2 - diff --git a/kernel/patches-4.14.x-rt/0436-printk-Do-not-disable-preemption-calling-console_unl.patch b/kernel/patches-4.14.x-rt/0436-printk-Do-not-disable-preemption-calling-console_unl.patch deleted file mode 100644 index 39e073566..000000000 --- a/kernel/patches-4.14.x-rt/0436-printk-Do-not-disable-preemption-calling-console_unl.patch +++ /dev/null @@ -1,45 +0,0 @@ -From cf8995800318059df3252b7c58fca53dc3e59062 Mon Sep 17 00:00:00 2001 -From: Steven Rostedt -Date: Tue, 18 Dec 2018 14:30:10 -0500 -Subject: [PATCH 436/450] printk: Do not disable preemption calling - console_unlock() in PREEMPT_RT - -A stable backport placed open coded preempt_disable() around console_unlock() -to prevent delays in output of printk() due to a task holding the console -lock being preempted. But most consoles are not PREEMPT_RT safe, thus -it needs to be preemptable when PREEMPT_RT is enabled. - -Replace the open coded preempt_disable() with migrate_disable() which -is a preempt_disable() on non PREEMPT_RT, but just disables migration -on PREEMPT_RT, even though it doesn't really depend on that. - -Signed-off-by: Steven Rostedt ---- - kernel/printk/printk.c | 4 ++-- - 1 file changed, 2 insertions(+), 2 deletions(-) - -diff --git a/kernel/printk/printk.c b/kernel/printk/printk.c -index 8a7c4f79fca0..029ae3caa80e 100644 ---- a/kernel/printk/printk.c -+++ b/kernel/printk/printk.c -@@ -1811,7 +1811,7 @@ asmlinkage int vprintk_emit(int facility, int level, - * console_sem which would prevent anyone from printing to - * console - */ -- preempt_disable(); -+ migrate_disable(); - /* - * Try to acquire and then immediately release the console - * semaphore. The release will print out buffers and wake up -@@ -1819,7 +1819,7 @@ asmlinkage int vprintk_emit(int facility, int level, - */ - if (may_trylock && console_trylock()) - console_unlock(); -- preempt_enable(); -+ migrate_enable(); - } - - return printed_len; --- -2.19.2 - diff --git a/kernel/patches-4.14.x-rt/0442-pinctrl-bcm2835-Use-raw-spinlock-for-RT-compatibilit.patch b/kernel/patches-4.14.x-rt/0442-pinctrl-bcm2835-Use-raw-spinlock-for-RT-compatibilit.patch deleted file mode 100644 index f7739a896..000000000 --- a/kernel/patches-4.14.x-rt/0442-pinctrl-bcm2835-Use-raw-spinlock-for-RT-compatibilit.patch +++ /dev/null @@ -1,104 +0,0 @@ -From 12130747ad4501dd4e03a3a111f2586eaa91d2b5 Mon Sep 17 00:00:00 2001 -From: Lukas Wunner -Date: Sat, 27 Oct 2018 10:15:33 +0200 -Subject: [PATCH 442/450] pinctrl: bcm2835: Use raw spinlock for RT - compatibility - -[ Upstream commit 71dfaa749f2f7c1722ebf6716d3f797a04528cba ] - -The BCM2835 pinctrl driver acquires a spinlock in its ->irq_enable, -->irq_disable and ->irq_set_type callbacks. Spinlocks become sleeping -locks with CONFIG_PREEMPT_RT_FULL=y, therefore invocation of one of the -callbacks in atomic context may cause a hard lockup if at least two GPIO -pins in the same bank are used as interrupts. The issue doesn't occur -with just a single interrupt pin per bank because the lock is never -contended. I'm experiencing such lockups with GPIO 8 and 28 used as -level-triggered interrupts, i.e. with ->irq_disable being invoked on -reception of every IRQ. - -The critical section protected by the spinlock is very small (one bitop -and one RMW of an MMIO register), hence converting to a raw spinlock -seems a better trade-off than converting the driver to threaded IRQ -handling (which would increase latency to handle an interrupt). - -Cc: Mathias Duckeck -Signed-off-by: Lukas Wunner -Acked-by: Julia Cartwright -Signed-off-by: Linus Walleij -Signed-off-by: Sebastian Andrzej Siewior -Signed-off-by: Steven Rostedt (VMware) ---- - drivers/pinctrl/bcm/pinctrl-bcm2835.c | 16 ++++++++-------- - 1 file changed, 8 insertions(+), 8 deletions(-) - -diff --git a/drivers/pinctrl/bcm/pinctrl-bcm2835.c b/drivers/pinctrl/bcm/pinctrl-bcm2835.c -index ff782445dfb7..e72bf2502eca 100644 ---- a/drivers/pinctrl/bcm/pinctrl-bcm2835.c -+++ b/drivers/pinctrl/bcm/pinctrl-bcm2835.c -@@ -92,7 +92,7 @@ struct bcm2835_pinctrl { - struct gpio_chip gpio_chip; - struct pinctrl_gpio_range gpio_range; - -- spinlock_t irq_lock[BCM2835_NUM_BANKS]; -+ raw_spinlock_t irq_lock[BCM2835_NUM_BANKS]; - }; - - /* pins are just named GPIO0..GPIO53 */ -@@ -471,10 +471,10 @@ static void bcm2835_gpio_irq_enable(struct irq_data *data) - unsigned bank = GPIO_REG_OFFSET(gpio); - unsigned long flags; - -- spin_lock_irqsave(&pc->irq_lock[bank], flags); -+ raw_spin_lock_irqsave(&pc->irq_lock[bank], flags); - set_bit(offset, &pc->enabled_irq_map[bank]); - bcm2835_gpio_irq_config(pc, gpio, true); -- spin_unlock_irqrestore(&pc->irq_lock[bank], flags); -+ raw_spin_unlock_irqrestore(&pc->irq_lock[bank], flags); - } - - static void bcm2835_gpio_irq_disable(struct irq_data *data) -@@ -486,12 +486,12 @@ static void bcm2835_gpio_irq_disable(struct irq_data *data) - unsigned bank = GPIO_REG_OFFSET(gpio); - unsigned long flags; - -- spin_lock_irqsave(&pc->irq_lock[bank], flags); -+ raw_spin_lock_irqsave(&pc->irq_lock[bank], flags); - bcm2835_gpio_irq_config(pc, gpio, false); - /* Clear events that were latched prior to clearing event sources */ - bcm2835_gpio_set_bit(pc, GPEDS0, gpio); - clear_bit(offset, &pc->enabled_irq_map[bank]); -- spin_unlock_irqrestore(&pc->irq_lock[bank], flags); -+ raw_spin_unlock_irqrestore(&pc->irq_lock[bank], flags); - } - - static int __bcm2835_gpio_irq_set_type_disabled(struct bcm2835_pinctrl *pc, -@@ -594,7 +594,7 @@ static int bcm2835_gpio_irq_set_type(struct irq_data *data, unsigned int type) - unsigned long flags; - int ret; - -- spin_lock_irqsave(&pc->irq_lock[bank], flags); -+ raw_spin_lock_irqsave(&pc->irq_lock[bank], flags); - - if (test_bit(offset, &pc->enabled_irq_map[bank])) - ret = __bcm2835_gpio_irq_set_type_enabled(pc, gpio, type); -@@ -606,7 +606,7 @@ static int bcm2835_gpio_irq_set_type(struct irq_data *data, unsigned int type) - else - irq_set_handler_locked(data, handle_level_irq); - -- spin_unlock_irqrestore(&pc->irq_lock[bank], flags); -+ raw_spin_unlock_irqrestore(&pc->irq_lock[bank], flags); - - return ret; - } -@@ -1021,7 +1021,7 @@ static int bcm2835_pinctrl_probe(struct platform_device *pdev) - for_each_set_bit(offset, &events, 32) - bcm2835_gpio_wr(pc, GPEDS0 + i * 4, BIT(offset)); - -- spin_lock_init(&pc->irq_lock[i]); -+ raw_spin_lock_init(&pc->irq_lock[i]); - } - - err = gpiochip_add_data(&pc->gpio_chip, pc); --- -2.19.2 - diff --git a/kernel/patches-4.14.x-rt/0443-rcu-make-RCU_BOOST-default-on-RT-without-EXPERT.patch b/kernel/patches-4.14.x-rt/0443-rcu-make-RCU_BOOST-default-on-RT-without-EXPERT.patch deleted file mode 100644 index 3f35feb38..000000000 --- a/kernel/patches-4.14.x-rt/0443-rcu-make-RCU_BOOST-default-on-RT-without-EXPERT.patch +++ /dev/null @@ -1,42 +0,0 @@ -From eaad86f001b651d6933a3c57915c3f78a9bbb9ed Mon Sep 17 00:00:00 2001 -From: Sebastian Andrzej Siewior -Date: Fri, 9 Nov 2018 15:02:49 +0100 -Subject: [PATCH 443/450] rcu: make RCU_BOOST default on RT without EXPERT - -[ Upstream commit 78cab7cb632b6a4c84e78e4f12bb9e83c09b8885 ] - -Paul E. McKenney suggested to allow enabling RCU_BOOST on RT without the -need to go through the EXPERT option first. - -Suggeted-by: Paul E. McKenney -Signed-off-by: Sebastian Andrzej Siewior -Signed-off-by: Steven Rostedt (VMware) ---- - kernel/rcu/Kconfig | 4 ++-- - 1 file changed, 2 insertions(+), 2 deletions(-) - -diff --git a/kernel/rcu/Kconfig b/kernel/rcu/Kconfig -index 0be2c96fb640..a243a78ff38c 100644 ---- a/kernel/rcu/Kconfig -+++ b/kernel/rcu/Kconfig -@@ -36,7 +36,7 @@ config TINY_RCU - - config RCU_EXPERT - bool "Make expert-level adjustments to RCU configuration" -- default y if PREEMPT_RT_FULL -+ default n - help - This option needs to be enabled if you wish to make - expert-level adjustments to RCU configuration. By default, -@@ -190,7 +190,7 @@ config RCU_FAST_NO_HZ - - config RCU_BOOST - bool "Enable RCU priority boosting" -- depends on RT_MUTEXES && PREEMPT_RCU && RCU_EXPERT -+ depends on (RT_MUTEXES && PREEMPT_RCU && RCU_EXPERT) || PREEMPT_RT_FULL - default y if PREEMPT_RT_FULL - help - This option boosts the priority of preempted RCU readers that --- -2.19.2 - diff --git a/kernel/patches-4.14.x-rt/0449-drm-i915-skip-DRM_I915_LOW_LEVEL_TRACEPOINTS-with-NO.patch b/kernel/patches-4.14.x-rt/0449-drm-i915-skip-DRM_I915_LOW_LEVEL_TRACEPOINTS-with-NO.patch deleted file mode 100644 index 576c010fb..000000000 --- a/kernel/patches-4.14.x-rt/0449-drm-i915-skip-DRM_I915_LOW_LEVEL_TRACEPOINTS-with-NO.patch +++ /dev/null @@ -1,35 +0,0 @@ -From e3583ea0acbf741fbc7841eb93548c64d9e4f728 Mon Sep 17 00:00:00 2001 -From: Sebastian Andrzej Siewior -Date: Wed, 19 Dec 2018 10:47:02 +0100 -Subject: [PATCH 449/450] drm/i915: skip DRM_I915_LOW_LEVEL_TRACEPOINTS with - NOTRACE - -[ Upstream commit 29f5e025fd8fc9798b5650dfde5beda7cc85868e ] - -The order of the header files is important. If this header file is -included after tracepoint.h was included then the NOTRACE here becomes a -nop. Currently this happens for two .c files which use the tracepoitns -behind DRM_I915_LOW_LEVEL_TRACEPOINTS. - -Signed-off-by: Sebastian Andrzej Siewior -Signed-off-by: Steven Rostedt (VMware) ---- - drivers/gpu/drm/i915/i915_trace.h | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/drivers/gpu/drm/i915/i915_trace.h b/drivers/gpu/drm/i915/i915_trace.h -index adf0974415bc..a8a349d6d0fa 100644 ---- a/drivers/gpu/drm/i915/i915_trace.h -+++ b/drivers/gpu/drm/i915/i915_trace.h -@@ -707,7 +707,7 @@ DEFINE_EVENT(i915_gem_request, i915_gem_request_add, - TP_ARGS(req) - ); - --#if defined(CONFIG_DRM_I915_LOW_LEVEL_TRACEPOINTS) -+#if defined(CONFIG_DRM_I915_LOW_LEVEL_TRACEPOINTS) && !defined(NOTRACE) - DEFINE_EVENT(i915_gem_request, i915_gem_request_submit, - TP_PROTO(struct drm_i915_gem_request *req), - TP_ARGS(req) --- -2.19.2 - diff --git a/kernel/patches-4.14.x-rt/0450-Linux-4.14.87-rt50-REBASE.patch b/kernel/patches-4.14.x-rt/0450-Linux-4.14.87-rt50-REBASE.patch deleted file mode 100644 index 7560dd2bf..000000000 --- a/kernel/patches-4.14.x-rt/0450-Linux-4.14.87-rt50-REBASE.patch +++ /dev/null @@ -1,19 +0,0 @@ -From 9ff100f0120bbcb8e5209ee9a3820a421372d257 Mon Sep 17 00:00:00 2001 -From: "Steven Rostedt (VMware)" -Date: Fri, 4 Jan 2019 20:59:15 -0500 -Subject: [PATCH 450/450] Linux 4.14.87-rt50 REBASE - ---- - localversion-rt | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/localversion-rt b/localversion-rt -index 90290c642ed5..42c384668389 100644 ---- a/localversion-rt -+++ b/localversion-rt -@@ -1 +1 @@ ---rt29 -+-rt50 --- -2.19.2 - diff --git a/kernel/patches-4.19.x-rt/0001-0001-ARM-at91-add-TCB-registers-definitions.patch b/kernel/patches-4.19.x-rt/0001-0001-ARM-at91-add-TCB-registers-definitions.patch new file mode 100644 index 000000000..547035dac --- /dev/null +++ b/kernel/patches-4.19.x-rt/0001-0001-ARM-at91-add-TCB-registers-definitions.patch @@ -0,0 +1,202 @@ +From: Alexandre Belloni +Date: Thu, 13 Sep 2018 13:30:18 +0200 +Subject: [PATCH 1/7] ARM: at91: add TCB registers definitions + +Add registers and bits definitions for the timer counter blocks found on +Atmel ARM SoCs. + +Tested-by: Alexander Dahl +Tested-by: Andras Szemzo +Signed-off-by: Alexandre Belloni +Signed-off-by: Sebastian Andrzej Siewior +--- + include/soc/at91/atmel_tcb.h | 183 +++++++++++++++++++++++++++++++++++++++++++ + 1 file changed, 183 insertions(+) + create mode 100644 include/soc/at91/atmel_tcb.h + +--- /dev/null ++++ b/include/soc/at91/atmel_tcb.h +@@ -0,0 +1,183 @@ ++//SPDX-License-Identifier: GPL-2.0 ++/* Copyright (C) 2018 Microchip */ ++ ++#ifndef __SOC_ATMEL_TCB_H ++#define __SOC_ATMEL_TCB_H ++ ++/* Channel registers */ ++#define ATMEL_TC_COFFS(c) ((c) * 0x40) ++#define ATMEL_TC_CCR(c) ATMEL_TC_COFFS(c) ++#define ATMEL_TC_CMR(c) (ATMEL_TC_COFFS(c) + 0x4) ++#define ATMEL_TC_SMMR(c) (ATMEL_TC_COFFS(c) + 0x8) ++#define ATMEL_TC_RAB(c) (ATMEL_TC_COFFS(c) + 0xc) ++#define ATMEL_TC_CV(c) (ATMEL_TC_COFFS(c) + 0x10) ++#define ATMEL_TC_RA(c) (ATMEL_TC_COFFS(c) + 0x14) ++#define ATMEL_TC_RB(c) (ATMEL_TC_COFFS(c) + 0x18) ++#define ATMEL_TC_RC(c) (ATMEL_TC_COFFS(c) + 0x1c) ++#define ATMEL_TC_SR(c) (ATMEL_TC_COFFS(c) + 0x20) ++#define ATMEL_TC_IER(c) (ATMEL_TC_COFFS(c) + 0x24) ++#define ATMEL_TC_IDR(c) (ATMEL_TC_COFFS(c) + 0x28) ++#define ATMEL_TC_IMR(c) (ATMEL_TC_COFFS(c) + 0x2c) ++#define ATMEL_TC_EMR(c) (ATMEL_TC_COFFS(c) + 0x30) ++ ++/* Block registers */ ++#define ATMEL_TC_BCR 0xc0 ++#define ATMEL_TC_BMR 0xc4 ++#define ATMEL_TC_QIER 0xc8 ++#define ATMEL_TC_QIDR 0xcc ++#define ATMEL_TC_QIMR 0xd0 ++#define ATMEL_TC_QISR 0xd4 ++#define ATMEL_TC_FMR 0xd8 ++#define ATMEL_TC_WPMR 0xe4 ++ ++/* CCR fields */ ++#define ATMEL_TC_CCR_CLKEN BIT(0) ++#define ATMEL_TC_CCR_CLKDIS BIT(1) ++#define ATMEL_TC_CCR_SWTRG BIT(2) ++ ++/* Common CMR fields */ ++#define ATMEL_TC_CMR_TCLKS_MSK GENMASK(2, 0) ++#define ATMEL_TC_CMR_TCLK(x) (x) ++#define ATMEL_TC_CMR_XC(x) ((x) + 5) ++#define ATMEL_TC_CMR_CLKI BIT(3) ++#define ATMEL_TC_CMR_BURST_MSK GENMASK(5, 4) ++#define ATMEL_TC_CMR_BURST_XC(x) (((x) + 1) << 4) ++#define ATMEL_TC_CMR_WAVE BIT(15) ++ ++/* Capture mode CMR fields */ ++#define ATMEL_TC_CMR_LDBSTOP BIT(6) ++#define ATMEL_TC_CMR_LDBDIS BIT(7) ++#define ATMEL_TC_CMR_ETRGEDG_MSK GENMASK(9, 8) ++#define ATMEL_TC_CMR_ETRGEDG_NONE (0 << 8) ++#define ATMEL_TC_CMR_ETRGEDG_RISING (1 << 8) ++#define ATMEL_TC_CMR_ETRGEDG_FALLING (2 << 8) ++#define ATMEL_TC_CMR_ETRGEDG_BOTH (3 << 8) ++#define ATMEL_TC_CMR_ABETRG BIT(10) ++#define ATMEL_TC_CMR_CPCTRG BIT(14) ++#define ATMEL_TC_CMR_LDRA_MSK GENMASK(17, 16) ++#define ATMEL_TC_CMR_LDRA_NONE (0 << 16) ++#define ATMEL_TC_CMR_LDRA_RISING (1 << 16) ++#define ATMEL_TC_CMR_LDRA_FALLING (2 << 16) ++#define ATMEL_TC_CMR_LDRA_BOTH (3 << 16) ++#define ATMEL_TC_CMR_LDRB_MSK GENMASK(19, 18) ++#define ATMEL_TC_CMR_LDRB_NONE (0 << 18) ++#define ATMEL_TC_CMR_LDRB_RISING (1 << 18) ++#define ATMEL_TC_CMR_LDRB_FALLING (2 << 18) ++#define ATMEL_TC_CMR_LDRB_BOTH (3 << 18) ++#define ATMEL_TC_CMR_SBSMPLR_MSK GENMASK(22, 20) ++#define ATMEL_TC_CMR_SBSMPLR(x) ((x) << 20) ++ ++/* Waveform mode CMR fields */ ++#define ATMEL_TC_CMR_CPCSTOP BIT(6) ++#define ATMEL_TC_CMR_CPCDIS BIT(7) ++#define ATMEL_TC_CMR_EEVTEDG_MSK GENMASK(9, 8) ++#define ATMEL_TC_CMR_EEVTEDG_NONE (0 << 8) ++#define ATMEL_TC_CMR_EEVTEDG_RISING (1 << 8) ++#define ATMEL_TC_CMR_EEVTEDG_FALLING (2 << 8) ++#define ATMEL_TC_CMR_EEVTEDG_BOTH (3 << 8) ++#define ATMEL_TC_CMR_EEVT_MSK GENMASK(11, 10) ++#define ATMEL_TC_CMR_EEVT_XC(x) (((x) + 1) << 10) ++#define ATMEL_TC_CMR_ENETRG BIT(12) ++#define ATMEL_TC_CMR_WAVESEL_MSK GENMASK(14, 13) ++#define ATMEL_TC_CMR_WAVESEL_UP (0 << 13) ++#define ATMEL_TC_CMR_WAVESEL_UPDOWN (1 << 13) ++#define ATMEL_TC_CMR_WAVESEL_UPRC (2 << 13) ++#define ATMEL_TC_CMR_WAVESEL_UPDOWNRC (3 << 13) ++#define ATMEL_TC_CMR_ACPA_MSK GENMASK(17, 16) ++#define ATMEL_TC_CMR_ACPA(a) (ATMEL_TC_CMR_ACTION_##a << 16) ++#define ATMEL_TC_CMR_ACPC_MSK GENMASK(19, 18) ++#define ATMEL_TC_CMR_ACPC(a) (ATMEL_TC_CMR_ACTION_##a << 18) ++#define ATMEL_TC_CMR_AEEVT_MSK GENMASK(21, 20) ++#define ATMEL_TC_CMR_AEEVT(a) (ATMEL_TC_CMR_ACTION_##a << 20) ++#define ATMEL_TC_CMR_ASWTRG_MSK GENMASK(23, 22) ++#define ATMEL_TC_CMR_ASWTRG(a) (ATMEL_TC_CMR_ACTION_##a << 22) ++#define ATMEL_TC_CMR_BCPB_MSK GENMASK(25, 24) ++#define ATMEL_TC_CMR_BCPB(a) (ATMEL_TC_CMR_ACTION_##a << 24) ++#define ATMEL_TC_CMR_BCPC_MSK GENMASK(27, 26) ++#define ATMEL_TC_CMR_BCPC(a) (ATMEL_TC_CMR_ACTION_##a << 26) ++#define ATMEL_TC_CMR_BEEVT_MSK GENMASK(29, 28) ++#define ATMEL_TC_CMR_BEEVT(a) (ATMEL_TC_CMR_ACTION_##a << 28) ++#define ATMEL_TC_CMR_BSWTRG_MSK GENMASK(31, 30) ++#define ATMEL_TC_CMR_BSWTRG(a) (ATMEL_TC_CMR_ACTION_##a << 30) ++#define ATMEL_TC_CMR_ACTION_NONE 0 ++#define ATMEL_TC_CMR_ACTION_SET 1 ++#define ATMEL_TC_CMR_ACTION_CLEAR 2 ++#define ATMEL_TC_CMR_ACTION_TOGGLE 3 ++ ++/* SMMR fields */ ++#define ATMEL_TC_SMMR_GCEN BIT(0) ++#define ATMEL_TC_SMMR_DOWN BIT(1) ++ ++/* SR/IER/IDR/IMR fields */ ++#define ATMEL_TC_COVFS BIT(0) ++#define ATMEL_TC_LOVRS BIT(1) ++#define ATMEL_TC_CPAS BIT(2) ++#define ATMEL_TC_CPBS BIT(3) ++#define ATMEL_TC_CPCS BIT(4) ++#define ATMEL_TC_LDRAS BIT(5) ++#define ATMEL_TC_LDRBS BIT(6) ++#define ATMEL_TC_ETRGS BIT(7) ++#define ATMEL_TC_CLKSTA BIT(16) ++#define ATMEL_TC_MTIOA BIT(17) ++#define ATMEL_TC_MTIOB BIT(18) ++ ++/* EMR fields */ ++#define ATMEL_TC_EMR_TRIGSRCA_MSK GENMASK(1, 0) ++#define ATMEL_TC_EMR_TRIGSRCA_TIOA 0 ++#define ATMEL_TC_EMR_TRIGSRCA_PWMX 1 ++#define ATMEL_TC_EMR_TRIGSRCB_MSK GENMASK(5, 4) ++#define ATMEL_TC_EMR_TRIGSRCB_TIOB (0 << 4) ++#define ATMEL_TC_EMR_TRIGSRCB_PWM (1 << 4) ++#define ATMEL_TC_EMR_NOCLKDIV BIT(8) ++ ++/* BCR fields */ ++#define ATMEL_TC_BCR_SYNC BIT(0) ++ ++/* BMR fields */ ++#define ATMEL_TC_BMR_TCXC_MSK(c) GENMASK(((c) * 2) + 1, (c) * 2) ++#define ATMEL_TC_BMR_TCXC(x, c) ((x) << (2 * (c))) ++#define ATMEL_TC_BMR_QDEN BIT(8) ++#define ATMEL_TC_BMR_POSEN BIT(9) ++#define ATMEL_TC_BMR_SPEEDEN BIT(10) ++#define ATMEL_TC_BMR_QDTRANS BIT(11) ++#define ATMEL_TC_BMR_EDGPHA BIT(12) ++#define ATMEL_TC_BMR_INVA BIT(13) ++#define ATMEL_TC_BMR_INVB BIT(14) ++#define ATMEL_TC_BMR_INVIDX BIT(15) ++#define ATMEL_TC_BMR_SWAP BIT(16) ++#define ATMEL_TC_BMR_IDXPHB BIT(17) ++#define ATMEL_TC_BMR_AUTOC BIT(18) ++#define ATMEL_TC_MAXFILT_MSK GENMASK(25, 20) ++#define ATMEL_TC_MAXFILT(x) (((x) - 1) << 20) ++#define ATMEL_TC_MAXCMP_MSK GENMASK(29, 26) ++#define ATMEL_TC_MAXCMP(x) ((x) << 26) ++ ++/* QEDC fields */ ++#define ATMEL_TC_QEDC_IDX BIT(0) ++#define ATMEL_TC_QEDC_DIRCHG BIT(1) ++#define ATMEL_TC_QEDC_QERR BIT(2) ++#define ATMEL_TC_QEDC_MPE BIT(3) ++#define ATMEL_TC_QEDC_DIR BIT(8) ++ ++/* FMR fields */ ++#define ATMEL_TC_FMR_ENCF(x) BIT(x) ++ ++/* WPMR fields */ ++#define ATMEL_TC_WPMR_WPKEY (0x54494d << 8) ++#define ATMEL_TC_WPMR_WPEN BIT(0) ++ ++static const u8 atmel_tc_divisors[5] = { 2, 8, 32, 128, 0, }; ++ ++static const struct of_device_id atmel_tcb_dt_ids[] = { ++ { ++ .compatible = "atmel,at91rm9200-tcb", ++ .data = (void *)16, ++ }, { ++ .compatible = "atmel,at91sam9x5-tcb", ++ .data = (void *)32, ++ }, { ++ /* sentinel */ ++ } ++}; ++ ++#endif /* __SOC_ATMEL_TCB_H */ diff --git a/kernel/patches-4.19.x-rt/0002-0002-clocksource-drivers-Add-a-new-driver-for-the-Atmel-A.patch b/kernel/patches-4.19.x-rt/0002-0002-clocksource-drivers-Add-a-new-driver-for-the-Atmel-A.patch new file mode 100644 index 000000000..58026eee9 --- /dev/null +++ b/kernel/patches-4.19.x-rt/0002-0002-clocksource-drivers-Add-a-new-driver-for-the-Atmel-A.patch @@ -0,0 +1,473 @@ +From: Alexandre Belloni +Date: Thu, 13 Sep 2018 13:30:19 +0200 +Subject: [PATCH 2/7] clocksource/drivers: Add a new driver for the Atmel ARM + TC blocks + +Add a driver for the Atmel Timer Counter Blocks. This driver provides a +clocksource and two clockevent devices. + +One of the clockevent device is linked to the clocksource counter and so it +will run at the same frequency. This will be used when there is only on TCB +channel available for timers. + +The other clockevent device runs on a separate TCB channel when available. + +This driver uses regmap and syscon to be able to probe early in the boot +and avoid having to switch on the TCB clocksource later. Using regmap also +means that unused TCB channels may be used by other drivers (PWM for +example). read/writel are still used to access channel specific registers +to avoid the performance impact of regmap (mainly locking). + +Tested-by: Alexander Dahl +Tested-by: Andras Szemzo +Signed-off-by: Alexandre Belloni +Signed-off-by: Sebastian Andrzej Siewior +--- + drivers/clocksource/Kconfig | 8 + drivers/clocksource/Makefile | 3 + drivers/clocksource/timer-atmel-tcb.c | 410 ++++++++++++++++++++++++++++++++++ + 3 files changed, 420 insertions(+), 1 deletion(-) + create mode 100644 drivers/clocksource/timer-atmel-tcb.c + +--- a/drivers/clocksource/Kconfig ++++ b/drivers/clocksource/Kconfig +@@ -404,6 +404,14 @@ config ATMEL_ST + help + Support for the Atmel ST timer. + ++config ATMEL_ARM_TCB_CLKSRC ++ bool "Microchip ARM TC Block" if COMPILE_TEST ++ select REGMAP_MMIO ++ depends on GENERIC_CLOCKEVENTS ++ help ++ This enables build of clocksource and clockevent driver for ++ the integrated Timer Counter Blocks in Microchip ARM SoCs. ++ + config CLKSRC_EXYNOS_MCT + bool "Exynos multi core timer driver" if COMPILE_TEST + depends on ARM || ARM64 +--- a/drivers/clocksource/Makefile ++++ b/drivers/clocksource/Makefile +@@ -3,7 +3,8 @@ obj-$(CONFIG_TIMER_OF) += timer-of.o + obj-$(CONFIG_TIMER_PROBE) += timer-probe.o + obj-$(CONFIG_ATMEL_PIT) += timer-atmel-pit.o + obj-$(CONFIG_ATMEL_ST) += timer-atmel-st.o +-obj-$(CONFIG_ATMEL_TCB_CLKSRC) += tcb_clksrc.o ++obj-$(CONFIG_ATMEL_TCB_CLKSRC) += tcb_clksrc.o ++obj-$(CONFIG_ATMEL_ARM_TCB_CLKSRC) += timer-atmel-tcb.o + obj-$(CONFIG_X86_PM_TIMER) += acpi_pm.o + obj-$(CONFIG_SCx200HR_TIMER) += scx200_hrt.o + obj-$(CONFIG_CS5535_CLOCK_EVENT_SRC) += cs5535-clockevt.o +--- /dev/null ++++ b/drivers/clocksource/timer-atmel-tcb.c +@@ -0,0 +1,410 @@ ++// SPDX-License-Identifier: GPL-2.0 ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++struct atmel_tcb_clksrc { ++ struct clocksource clksrc; ++ struct clock_event_device clkevt; ++ struct regmap *regmap; ++ void __iomem *base; ++ struct clk *clk[2]; ++ char name[20]; ++ int channels[2]; ++ int bits; ++ int irq; ++ struct { ++ u32 cmr; ++ u32 imr; ++ u32 rc; ++ bool clken; ++ } cache[2]; ++ u32 bmr_cache; ++ bool registered; ++ bool clk_enabled; ++}; ++ ++static struct atmel_tcb_clksrc tc; ++ ++static struct clk *tcb_clk_get(struct device_node *node, int channel) ++{ ++ struct clk *clk; ++ char clk_name[] = "t0_clk"; ++ ++ clk_name[1] += channel; ++ clk = of_clk_get_by_name(node->parent, clk_name); ++ if (!IS_ERR(clk)) ++ return clk; ++ ++ return of_clk_get_by_name(node->parent, "t0_clk"); ++} ++ ++/* ++ * Clocksource and clockevent using the same channel(s) ++ */ ++static u64 tc_get_cycles(struct clocksource *cs) ++{ ++ u32 lower, upper; ++ ++ do { ++ upper = readl_relaxed(tc.base + ATMEL_TC_CV(tc.channels[1])); ++ lower = readl_relaxed(tc.base + ATMEL_TC_CV(tc.channels[0])); ++ } while (upper != readl_relaxed(tc.base + ATMEL_TC_CV(tc.channels[1]))); ++ ++ return (upper << 16) | lower; ++} ++ ++static u64 tc_get_cycles32(struct clocksource *cs) ++{ ++ return readl_relaxed(tc.base + ATMEL_TC_CV(tc.channels[0])); ++} ++ ++static u64 notrace tc_sched_clock_read(void) ++{ ++ return tc_get_cycles(&tc.clksrc); ++} ++ ++static u64 notrace tc_sched_clock_read32(void) ++{ ++ return tc_get_cycles32(&tc.clksrc); ++} ++ ++static int tcb_clkevt_next_event(unsigned long delta, ++ struct clock_event_device *d) ++{ ++ u32 old, next, cur; ++ ++ old = readl(tc.base + ATMEL_TC_CV(tc.channels[0])); ++ next = old + delta; ++ writel(next, tc.base + ATMEL_TC_RC(tc.channels[0])); ++ cur = readl(tc.base + ATMEL_TC_CV(tc.channels[0])); ++ ++ /* check whether the delta elapsed while setting the register */ ++ if ((next < old && cur < old && cur > next) || ++ (next > old && (cur < old || cur > next))) { ++ /* ++ * Clear the CPCS bit in the status register to avoid ++ * generating a spurious interrupt next time a valid ++ * timer event is configured. ++ */ ++ old = readl(tc.base + ATMEL_TC_SR(tc.channels[0])); ++ return -ETIME; ++ } ++ ++ writel(ATMEL_TC_CPCS, tc.base + ATMEL_TC_IER(tc.channels[0])); ++ ++ return 0; ++} ++ ++static irqreturn_t tc_clkevt_irq(int irq, void *handle) ++{ ++ unsigned int sr; ++ ++ sr = readl(tc.base + ATMEL_TC_SR(tc.channels[0])); ++ if (sr & ATMEL_TC_CPCS) { ++ tc.clkevt.event_handler(&tc.clkevt); ++ return IRQ_HANDLED; ++ } ++ ++ return IRQ_NONE; ++} ++ ++static int tcb_clkevt_oneshot(struct clock_event_device *dev) ++{ ++ if (clockevent_state_oneshot(dev)) ++ return 0; ++ ++ /* ++ * Because both clockevent devices may share the same IRQ, we don't want ++ * the less likely one to stay requested ++ */ ++ return request_irq(tc.irq, tc_clkevt_irq, IRQF_TIMER | IRQF_SHARED, ++ tc.name, &tc); ++} ++ ++static int tcb_clkevt_shutdown(struct clock_event_device *dev) ++{ ++ writel(0xff, tc.base + ATMEL_TC_IDR(tc.channels[0])); ++ if (tc.bits == 16) ++ writel(0xff, tc.base + ATMEL_TC_IDR(tc.channels[1])); ++ ++ if (!clockevent_state_detached(dev)) ++ free_irq(tc.irq, &tc); ++ ++ return 0; ++} ++ ++static void __init tcb_setup_dual_chan(struct atmel_tcb_clksrc *tc, ++ int mck_divisor_idx) ++{ ++ /* first channel: waveform mode, input mclk/8, clock TIOA on overflow */ ++ writel(mck_divisor_idx /* likely divide-by-8 */ ++ | ATMEL_TC_CMR_WAVE ++ | ATMEL_TC_CMR_WAVESEL_UP /* free-run */ ++ | ATMEL_TC_CMR_ACPA(SET) /* TIOA rises at 0 */ ++ | ATMEL_TC_CMR_ACPC(CLEAR), /* (duty cycle 50%) */ ++ tc->base + ATMEL_TC_CMR(tc->channels[0])); ++ writel(0x0000, tc->base + ATMEL_TC_RA(tc->channels[0])); ++ writel(0x8000, tc->base + ATMEL_TC_RC(tc->channels[0])); ++ writel(0xff, tc->base + ATMEL_TC_IDR(tc->channels[0])); /* no irqs */ ++ writel(ATMEL_TC_CCR_CLKEN, tc->base + ATMEL_TC_CCR(tc->channels[0])); ++ ++ /* second channel: waveform mode, input TIOA */ ++ writel(ATMEL_TC_CMR_XC(tc->channels[1]) /* input: TIOA */ ++ | ATMEL_TC_CMR_WAVE ++ | ATMEL_TC_CMR_WAVESEL_UP, /* free-run */ ++ tc->base + ATMEL_TC_CMR(tc->channels[1])); ++ writel(0xff, tc->base + ATMEL_TC_IDR(tc->channels[1])); /* no irqs */ ++ writel(ATMEL_TC_CCR_CLKEN, tc->base + ATMEL_TC_CCR(tc->channels[1])); ++ ++ /* chain both channel, we assume the previous channel */ ++ regmap_write(tc->regmap, ATMEL_TC_BMR, ++ ATMEL_TC_BMR_TCXC(1 + tc->channels[1], tc->channels[1])); ++ /* then reset all the timers */ ++ regmap_write(tc->regmap, ATMEL_TC_BCR, ATMEL_TC_BCR_SYNC); ++} ++ ++static void __init tcb_setup_single_chan(struct atmel_tcb_clksrc *tc, ++ int mck_divisor_idx) ++{ ++ /* channel 0: waveform mode, input mclk/8 */ ++ writel(mck_divisor_idx /* likely divide-by-8 */ ++ | ATMEL_TC_CMR_WAVE ++ | ATMEL_TC_CMR_WAVESEL_UP, /* free-run */ ++ tc->base + ATMEL_TC_CMR(tc->channels[0])); ++ writel(0xff, tc->base + ATMEL_TC_IDR(tc->channels[0])); /* no irqs */ ++ writel(ATMEL_TC_CCR_CLKEN, tc->base + ATMEL_TC_CCR(tc->channels[0])); ++ ++ /* then reset all the timers */ ++ regmap_write(tc->regmap, ATMEL_TC_BCR, ATMEL_TC_BCR_SYNC); ++} ++ ++static void tc_clksrc_suspend(struct clocksource *cs) ++{ ++ int i; ++ ++ for (i = 0; i < 1 + (tc.bits == 16); i++) { ++ tc.cache[i].cmr = readl(tc.base + ATMEL_TC_CMR(tc.channels[i])); ++ tc.cache[i].imr = readl(tc.base + ATMEL_TC_IMR(tc.channels[i])); ++ tc.cache[i].rc = readl(tc.base + ATMEL_TC_RC(tc.channels[i])); ++ tc.cache[i].clken = !!(readl(tc.base + ++ ATMEL_TC_SR(tc.channels[i])) & ++ ATMEL_TC_CLKSTA); ++ } ++ ++ if (tc.bits == 16) ++ regmap_read(tc.regmap, ATMEL_TC_BMR, &tc.bmr_cache); ++} ++ ++static void tc_clksrc_resume(struct clocksource *cs) ++{ ++ int i; ++ ++ for (i = 0; i < 1 + (tc.bits == 16); i++) { ++ /* Restore registers for the channel, RA and RB are not used */ ++ writel(tc.cache[i].cmr, tc.base + ATMEL_TC_CMR(tc.channels[i])); ++ writel(tc.cache[i].rc, tc.base + ATMEL_TC_RC(tc.channels[i])); ++ writel(0, tc.base + ATMEL_TC_RA(tc.channels[i])); ++ writel(0, tc.base + ATMEL_TC_RB(tc.channels[i])); ++ /* Disable all the interrupts */ ++ writel(0xff, tc.base + ATMEL_TC_IDR(tc.channels[i])); ++ /* Reenable interrupts that were enabled before suspending */ ++ writel(tc.cache[i].imr, tc.base + ATMEL_TC_IER(tc.channels[i])); ++ ++ /* Start the clock if it was used */ ++ if (tc.cache[i].clken) ++ writel(ATMEL_TC_CCR_CLKEN, tc.base + ++ ATMEL_TC_CCR(tc.channels[i])); ++ } ++ ++ /* in case of dual channel, chain channels */ ++ if (tc.bits == 16) ++ regmap_write(tc.regmap, ATMEL_TC_BMR, tc.bmr_cache); ++ /* Finally, trigger all the channels*/ ++ regmap_write(tc.regmap, ATMEL_TC_BCR, ATMEL_TC_BCR_SYNC); ++} ++ ++static int __init tcb_clksrc_register(struct device_node *node, ++ struct regmap *regmap, void __iomem *base, ++ int channel, int channel1, int irq, ++ int bits) ++{ ++ u32 rate, divided_rate = 0; ++ int best_divisor_idx = -1; ++ int i, err = -1; ++ u64 (*tc_sched_clock)(void); ++ ++ tc.regmap = regmap; ++ tc.base = base; ++ tc.channels[0] = channel; ++ tc.channels[1] = channel1; ++ tc.irq = irq; ++ tc.bits = bits; ++ ++ tc.clk[0] = tcb_clk_get(node, tc.channels[0]); ++ if (IS_ERR(tc.clk[0])) ++ return PTR_ERR(tc.clk[0]); ++ err = clk_prepare_enable(tc.clk[0]); ++ if (err) { ++ pr_debug("can't enable T0 clk\n"); ++ goto err_clk; ++ } ++ ++ /* How fast will we be counting? Pick something over 5 MHz. */ ++ rate = (u32)clk_get_rate(tc.clk[0]); ++ for (i = 0; i < 5; i++) { ++ unsigned int divisor = atmel_tc_divisors[i]; ++ unsigned int tmp; ++ ++ if (!divisor) ++ continue; ++ ++ tmp = rate / divisor; ++ pr_debug("TC: %u / %-3u [%d] --> %u\n", rate, divisor, i, tmp); ++ if (best_divisor_idx > 0) { ++ if (tmp < 5 * 1000 * 1000) ++ continue; ++ } ++ divided_rate = tmp; ++ best_divisor_idx = i; ++ } ++ ++ if (tc.bits == 32) { ++ tc.clksrc.read = tc_get_cycles32; ++ tcb_setup_single_chan(&tc, best_divisor_idx); ++ tc_sched_clock = tc_sched_clock_read32; ++ snprintf(tc.name, sizeof(tc.name), "%s:%d", ++ kbasename(node->parent->full_name), tc.channels[0]); ++ } else { ++ tc.clk[1] = tcb_clk_get(node, tc.channels[1]); ++ if (IS_ERR(tc.clk[1])) ++ goto err_disable_t0; ++ ++ err = clk_prepare_enable(tc.clk[1]); ++ if (err) { ++ pr_debug("can't enable T1 clk\n"); ++ goto err_clk1; ++ } ++ tc.clksrc.read = tc_get_cycles, ++ tcb_setup_dual_chan(&tc, best_divisor_idx); ++ tc_sched_clock = tc_sched_clock_read; ++ snprintf(tc.name, sizeof(tc.name), "%s:%d,%d", ++ kbasename(node->parent->full_name), tc.channels[0], ++ tc.channels[1]); ++ } ++ ++ pr_debug("%s at %d.%03d MHz\n", tc.name, ++ divided_rate / 1000000, ++ ((divided_rate + 500000) % 1000000) / 1000); ++ ++ tc.clksrc.name = tc.name; ++ tc.clksrc.suspend = tc_clksrc_suspend; ++ tc.clksrc.resume = tc_clksrc_resume; ++ tc.clksrc.rating = 200; ++ tc.clksrc.mask = CLOCKSOURCE_MASK(32); ++ tc.clksrc.flags = CLOCK_SOURCE_IS_CONTINUOUS; ++ ++ err = clocksource_register_hz(&tc.clksrc, divided_rate); ++ if (err) ++ goto err_disable_t1; ++ ++ sched_clock_register(tc_sched_clock, 32, divided_rate); ++ ++ tc.registered = true; ++ ++ /* Set up and register clockevents */ ++ tc.clkevt.name = tc.name; ++ tc.clkevt.cpumask = cpumask_of(0); ++ tc.clkevt.set_next_event = tcb_clkevt_next_event; ++ tc.clkevt.set_state_oneshot = tcb_clkevt_oneshot; ++ tc.clkevt.set_state_shutdown = tcb_clkevt_shutdown; ++ tc.clkevt.features = CLOCK_EVT_FEAT_ONESHOT; ++ tc.clkevt.rating = 125; ++ ++ clockevents_config_and_register(&tc.clkevt, divided_rate, 1, ++ BIT(tc.bits) - 1); ++ ++ return 0; ++ ++err_disable_t1: ++ if (tc.bits == 16) ++ clk_disable_unprepare(tc.clk[1]); ++ ++err_clk1: ++ if (tc.bits == 16) ++ clk_put(tc.clk[1]); ++ ++err_disable_t0: ++ clk_disable_unprepare(tc.clk[0]); ++ ++err_clk: ++ clk_put(tc.clk[0]); ++ ++ pr_err("%s: unable to register clocksource/clockevent\n", ++ tc.clksrc.name); ++ ++ return err; ++} ++ ++static int __init tcb_clksrc_init(struct device_node *node) ++{ ++ const struct of_device_id *match; ++ struct regmap *regmap; ++ void __iomem *tcb_base; ++ u32 channel; ++ int irq, err, chan1 = -1; ++ unsigned bits; ++ ++ if (tc.registered) ++ return -ENODEV; ++ ++ /* ++ * The regmap has to be used to access registers that are shared ++ * between channels on the same TCB but we keep direct IO access for ++ * the counters to avoid the impact on performance ++ */ ++ regmap = syscon_node_to_regmap(node->parent); ++ if (IS_ERR(regmap)) ++ return PTR_ERR(regmap); ++ ++ tcb_base = of_iomap(node->parent, 0); ++ if (!tcb_base) { ++ pr_err("%s +%d %s\n", __FILE__, __LINE__, __func__); ++ return -ENXIO; ++ } ++ ++ match = of_match_node(atmel_tcb_dt_ids, node->parent); ++ bits = (uintptr_t)match->data; ++ ++ err = of_property_read_u32_index(node, "reg", 0, &channel); ++ if (err) ++ return err; ++ ++ irq = of_irq_get(node->parent, channel); ++ if (irq < 0) { ++ irq = of_irq_get(node->parent, 0); ++ if (irq < 0) ++ return irq; ++ } ++ ++ if (bits == 16) { ++ of_property_read_u32_index(node, "reg", 1, &chan1); ++ if (chan1 == -1) { ++ pr_err("%s: clocksource needs two channels\n", ++ node->parent->full_name); ++ return -EINVAL; ++ } ++ } ++ ++ return tcb_clksrc_register(node, regmap, tcb_base, channel, chan1, irq, ++ bits); ++} ++TIMER_OF_DECLARE(atmel_tcb_clksrc, "atmel,tcb-timer", tcb_clksrc_init); diff --git a/kernel/patches-4.19.x-rt/0003-0003-clocksource-drivers-timer-atmel-tcb-add-clockevent-d.patch b/kernel/patches-4.19.x-rt/0003-0003-clocksource-drivers-timer-atmel-tcb-add-clockevent-d.patch new file mode 100644 index 000000000..698988cbd --- /dev/null +++ b/kernel/patches-4.19.x-rt/0003-0003-clocksource-drivers-timer-atmel-tcb-add-clockevent-d.patch @@ -0,0 +1,264 @@ +From: Alexandre Belloni +Date: Thu, 13 Sep 2018 13:30:20 +0200 +Subject: [PATCH 3/7] clocksource/drivers: timer-atmel-tcb: add clockevent + device on separate channel + +Add an other clockevent device that uses a separate TCB channel when +available. + +Signed-off-by: Alexandre Belloni +Signed-off-by: Sebastian Andrzej Siewior +--- + drivers/clocksource/timer-atmel-tcb.c | 217 +++++++++++++++++++++++++++++++++- + 1 file changed, 212 insertions(+), 5 deletions(-) + +--- a/drivers/clocksource/timer-atmel-tcb.c ++++ b/drivers/clocksource/timer-atmel-tcb.c +@@ -32,7 +32,7 @@ struct atmel_tcb_clksrc { + bool clk_enabled; + }; + +-static struct atmel_tcb_clksrc tc; ++static struct atmel_tcb_clksrc tc, tce; + + static struct clk *tcb_clk_get(struct device_node *node, int channel) + { +@@ -48,6 +48,203 @@ static struct clk *tcb_clk_get(struct de + } + + /* ++ * Clockevent device using its own channel ++ */ ++ ++static void tc_clkevt2_clk_disable(struct clock_event_device *d) ++{ ++ clk_disable(tce.clk[0]); ++ tce.clk_enabled = false; ++} ++ ++static void tc_clkevt2_clk_enable(struct clock_event_device *d) ++{ ++ if (tce.clk_enabled) ++ return; ++ clk_enable(tce.clk[0]); ++ tce.clk_enabled = true; ++} ++ ++static int tc_clkevt2_stop(struct clock_event_device *d) ++{ ++ writel(0xff, tce.base + ATMEL_TC_IDR(tce.channels[0])); ++ writel(ATMEL_TC_CCR_CLKDIS, tce.base + ATMEL_TC_CCR(tce.channels[0])); ++ ++ return 0; ++} ++ ++static int tc_clkevt2_shutdown(struct clock_event_device *d) ++{ ++ tc_clkevt2_stop(d); ++ if (!clockevent_state_detached(d)) ++ tc_clkevt2_clk_disable(d); ++ ++ return 0; ++} ++ ++/* For now, we always use the 32K clock ... this optimizes for NO_HZ, ++ * because using one of the divided clocks would usually mean the ++ * tick rate can never be less than several dozen Hz (vs 0.5 Hz). ++ * ++ * A divided clock could be good for high resolution timers, since ++ * 30.5 usec resolution can seem "low". ++ */ ++static int tc_clkevt2_set_oneshot(struct clock_event_device *d) ++{ ++ if (clockevent_state_oneshot(d) || clockevent_state_periodic(d)) ++ tc_clkevt2_stop(d); ++ ++ tc_clkevt2_clk_enable(d); ++ ++ /* slow clock, count up to RC, then irq and stop */ ++ writel(ATMEL_TC_CMR_TCLK(4) | ATMEL_TC_CMR_CPCSTOP | ++ ATMEL_TC_CMR_WAVE | ATMEL_TC_CMR_WAVESEL_UPRC, ++ tce.base + ATMEL_TC_CMR(tce.channels[0])); ++ writel(ATMEL_TC_CPCS, tce.base + ATMEL_TC_IER(tce.channels[0])); ++ ++ return 0; ++} ++ ++static int tc_clkevt2_set_periodic(struct clock_event_device *d) ++{ ++ if (clockevent_state_oneshot(d) || clockevent_state_periodic(d)) ++ tc_clkevt2_stop(d); ++ ++ /* By not making the gentime core emulate periodic mode on top ++ * of oneshot, we get lower overhead and improved accuracy. ++ */ ++ tc_clkevt2_clk_enable(d); ++ ++ /* slow clock, count up to RC, then irq and restart */ ++ writel(ATMEL_TC_CMR_TCLK(4) | ATMEL_TC_CMR_WAVE | ++ ATMEL_TC_CMR_WAVESEL_UPRC, ++ tce.base + ATMEL_TC_CMR(tce.channels[0])); ++ writel((32768 + HZ / 2) / HZ, tce.base + ATMEL_TC_RC(tce.channels[0])); ++ ++ /* Enable clock and interrupts on RC compare */ ++ writel(ATMEL_TC_CPCS, tce.base + ATMEL_TC_IER(tce.channels[0])); ++ writel(ATMEL_TC_CCR_CLKEN | ATMEL_TC_CCR_SWTRG, ++ tce.base + ATMEL_TC_CCR(tce.channels[0])); ++ ++ return 0; ++} ++ ++static int tc_clkevt2_next_event(unsigned long delta, ++ struct clock_event_device *d) ++{ ++ writel(delta, tce.base + ATMEL_TC_RC(tce.channels[0])); ++ writel(ATMEL_TC_CCR_CLKEN | ATMEL_TC_CCR_SWTRG, ++ tce.base + ATMEL_TC_CCR(tce.channels[0])); ++ ++ return 0; ++} ++ ++static irqreturn_t tc_clkevt2_irq(int irq, void *handle) ++{ ++ unsigned int sr; ++ ++ sr = readl(tce.base + ATMEL_TC_SR(tce.channels[0])); ++ if (sr & ATMEL_TC_CPCS) { ++ tce.clkevt.event_handler(&tce.clkevt); ++ return IRQ_HANDLED; ++ } ++ ++ return IRQ_NONE; ++} ++ ++static void tc_clkevt2_suspend(struct clock_event_device *d) ++{ ++ tce.cache[0].cmr = readl(tce.base + ATMEL_TC_CMR(tce.channels[0])); ++ tce.cache[0].imr = readl(tce.base + ATMEL_TC_IMR(tce.channels[0])); ++ tce.cache[0].rc = readl(tce.base + ATMEL_TC_RC(tce.channels[0])); ++ tce.cache[0].clken = !!(readl(tce.base + ATMEL_TC_SR(tce.channels[0])) & ++ ATMEL_TC_CLKSTA); ++} ++ ++static void tc_clkevt2_resume(struct clock_event_device *d) ++{ ++ /* Restore registers for the channel, RA and RB are not used */ ++ writel(tce.cache[0].cmr, tc.base + ATMEL_TC_CMR(tce.channels[0])); ++ writel(tce.cache[0].rc, tc.base + ATMEL_TC_RC(tce.channels[0])); ++ writel(0, tc.base + ATMEL_TC_RA(tce.channels[0])); ++ writel(0, tc.base + ATMEL_TC_RB(tce.channels[0])); ++ /* Disable all the interrupts */ ++ writel(0xff, tc.base + ATMEL_TC_IDR(tce.channels[0])); ++ /* Reenable interrupts that were enabled before suspending */ ++ writel(tce.cache[0].imr, tc.base + ATMEL_TC_IER(tce.channels[0])); ++ ++ /* Start the clock if it was used */ ++ if (tce.cache[0].clken) ++ writel(ATMEL_TC_CCR_CLKEN | ATMEL_TC_CCR_SWTRG, ++ tc.base + ATMEL_TC_CCR(tce.channels[0])); ++} ++ ++static int __init tc_clkevt_register(struct device_node *node, ++ struct regmap *regmap, void __iomem *base, ++ int channel, int irq, int bits) ++{ ++ int ret; ++ struct clk *slow_clk; ++ ++ tce.regmap = regmap; ++ tce.base = base; ++ tce.channels[0] = channel; ++ tce.irq = irq; ++ ++ slow_clk = of_clk_get_by_name(node->parent, "slow_clk"); ++ if (IS_ERR(slow_clk)) ++ return PTR_ERR(slow_clk); ++ ++ ret = clk_prepare_enable(slow_clk); ++ if (ret) ++ return ret; ++ ++ tce.clk[0] = tcb_clk_get(node, tce.channels[0]); ++ if (IS_ERR(tce.clk[0])) { ++ ret = PTR_ERR(tce.clk[0]); ++ goto err_slow; ++ } ++ ++ snprintf(tce.name, sizeof(tce.name), "%s:%d", ++ kbasename(node->parent->full_name), channel); ++ tce.clkevt.cpumask = cpumask_of(0); ++ tce.clkevt.name = tce.name; ++ tce.clkevt.set_next_event = tc_clkevt2_next_event, ++ tce.clkevt.set_state_shutdown = tc_clkevt2_shutdown, ++ tce.clkevt.set_state_periodic = tc_clkevt2_set_periodic, ++ tce.clkevt.set_state_oneshot = tc_clkevt2_set_oneshot, ++ tce.clkevt.suspend = tc_clkevt2_suspend, ++ tce.clkevt.resume = tc_clkevt2_resume, ++ tce.clkevt.features = CLOCK_EVT_FEAT_PERIODIC | CLOCK_EVT_FEAT_ONESHOT; ++ tce.clkevt.rating = 140; ++ ++ /* try to enable clk to avoid future errors in mode change */ ++ ret = clk_prepare_enable(tce.clk[0]); ++ if (ret) ++ goto err_slow; ++ clk_disable(tce.clk[0]); ++ ++ clockevents_config_and_register(&tce.clkevt, 32768, 1, ++ CLOCKSOURCE_MASK(bits)); ++ ++ ret = request_irq(tce.irq, tc_clkevt2_irq, IRQF_TIMER | IRQF_SHARED, ++ tce.clkevt.name, &tce); ++ if (ret) ++ goto err_clk; ++ ++ tce.registered = true; ++ ++ return 0; ++ ++err_clk: ++ clk_unprepare(tce.clk[0]); ++err_slow: ++ clk_disable_unprepare(slow_clk); ++ ++ return ret; ++} ++ ++/* + * Clocksource and clockevent using the same channel(s) + */ + static u64 tc_get_cycles(struct clocksource *cs) +@@ -363,7 +560,7 @@ static int __init tcb_clksrc_init(struct + int irq, err, chan1 = -1; + unsigned bits; + +- if (tc.registered) ++ if (tc.registered && tce.registered) + return -ENODEV; + + /* +@@ -395,12 +592,22 @@ static int __init tcb_clksrc_init(struct + return irq; + } + ++ if (tc.registered) ++ return tc_clkevt_register(node, regmap, tcb_base, channel, irq, ++ bits); ++ + if (bits == 16) { + of_property_read_u32_index(node, "reg", 1, &chan1); + if (chan1 == -1) { +- pr_err("%s: clocksource needs two channels\n", +- node->parent->full_name); +- return -EINVAL; ++ if (tce.registered) { ++ pr_err("%s: clocksource needs two channels\n", ++ node->parent->full_name); ++ return -EINVAL; ++ } else { ++ return tc_clkevt_register(node, regmap, ++ tcb_base, channel, ++ irq, bits); ++ } + } + } + diff --git a/kernel/patches-4.19.x-rt/0004-0004-clocksource-drivers-atmel-pit-make-option-silent.patch b/kernel/patches-4.19.x-rt/0004-0004-clocksource-drivers-atmel-pit-make-option-silent.patch new file mode 100644 index 000000000..a8ada4bc5 --- /dev/null +++ b/kernel/patches-4.19.x-rt/0004-0004-clocksource-drivers-atmel-pit-make-option-silent.patch @@ -0,0 +1,29 @@ +From: Alexandre Belloni +Date: Thu, 13 Sep 2018 13:30:21 +0200 +Subject: [PATCH 4/7] clocksource/drivers: atmel-pit: make option silent + +To conform with the other option, make the ATMEL_PIT option silent so it +can be selected from the platform + +Tested-by: Alexander Dahl +Signed-off-by: Alexandre Belloni +Signed-off-by: Sebastian Andrzej Siewior +--- + drivers/clocksource/Kconfig | 5 ++++- + 1 file changed, 4 insertions(+), 1 deletion(-) + +--- a/drivers/clocksource/Kconfig ++++ b/drivers/clocksource/Kconfig +@@ -393,8 +393,11 @@ config ARMV7M_SYSTICK + This options enables support for the ARMv7M system timer unit + + config ATMEL_PIT ++ bool "Microchip ARM Periodic Interval Timer (PIT)" if COMPILE_TEST + select TIMER_OF if OF +- def_bool SOC_AT91SAM9 || SOC_SAMA5 ++ help ++ This enables build of clocksource and clockevent driver for ++ the integrated PIT in Microchip ARM SoCs. + + config ATMEL_ST + bool "Atmel ST timer support" if COMPILE_TEST diff --git a/kernel/patches-4.19.x-rt/0005-0005-ARM-at91-Implement-clocksource-selection.patch b/kernel/patches-4.19.x-rt/0005-0005-ARM-at91-Implement-clocksource-selection.patch new file mode 100644 index 000000000..b044504c9 --- /dev/null +++ b/kernel/patches-4.19.x-rt/0005-0005-ARM-at91-Implement-clocksource-selection.patch @@ -0,0 +1,48 @@ +From: Alexandre Belloni +Date: Thu, 13 Sep 2018 13:30:22 +0200 +Subject: [PATCH 5/7] ARM: at91: Implement clocksource selection + +Allow selecting and unselecting the PIT clocksource driver so it doesn't +have to be compile when unused. + +Tested-by: Alexander Dahl +Signed-off-by: Alexandre Belloni +Signed-off-by: Sebastian Andrzej Siewior +--- + arch/arm/mach-at91/Kconfig | 25 +++++++++++++++++++++++++ + 1 file changed, 25 insertions(+) + +--- a/arch/arm/mach-at91/Kconfig ++++ b/arch/arm/mach-at91/Kconfig +@@ -107,6 +107,31 @@ config SOC_AT91SAM9 + AT91SAM9X35 + AT91SAM9XE + ++comment "Clocksource driver selection" ++ ++config ATMEL_CLOCKSOURCE_PIT ++ bool "Periodic Interval Timer (PIT) support" ++ depends on SOC_AT91SAM9 || SOC_SAMA5 ++ default SOC_AT91SAM9 || SOC_SAMA5 ++ select ATMEL_PIT ++ help ++ Select this to get a clocksource based on the Atmel Periodic Interval ++ Timer. It has a relatively low resolution and the TC Block clocksource ++ should be preferred. ++ ++config ATMEL_CLOCKSOURCE_TCB ++ bool "Timer Counter Blocks (TCB) support" ++ depends on SOC_AT91RM9200 || SOC_AT91SAM9 || SOC_SAMA5 || COMPILE_TEST ++ default SOC_AT91RM9200 || SOC_AT91SAM9 || SOC_SAMA5 ++ depends on !ATMEL_TCLIB ++ select ATMEL_ARM_TCB_CLKSRC ++ help ++ Select this to get a high precision clocksource based on a ++ TC block with a 5+ MHz base clock rate. ++ On platforms with 16-bit counters, two timer channels are combined ++ to make a single 32-bit timer. ++ It can also be used as a clock event device supporting oneshot mode. ++ + config HAVE_AT91_UTMI + bool + diff --git a/kernel/patches-4.19.x-rt/0006-0006-ARM-configs-at91-use-new-TCB-timer-driver.patch b/kernel/patches-4.19.x-rt/0006-0006-ARM-configs-at91-use-new-TCB-timer-driver.patch new file mode 100644 index 000000000..aaeac8138 --- /dev/null +++ b/kernel/patches-4.19.x-rt/0006-0006-ARM-configs-at91-use-new-TCB-timer-driver.patch @@ -0,0 +1,34 @@ +From: Alexandre Belloni +Date: Thu, 13 Sep 2018 13:30:23 +0200 +Subject: [PATCH 6/7] ARM: configs: at91: use new TCB timer driver + +Unselecting ATMEL_TCLIB switches the TCB timer driver from tcb_clksrc to +timer-atmel-tcb. + +Signed-off-by: Alexandre Belloni +Signed-off-by: Sebastian Andrzej Siewior +--- + arch/arm/configs/at91_dt_defconfig | 1 - + arch/arm/configs/sama5_defconfig | 1 - + 2 files changed, 2 deletions(-) + +--- a/arch/arm/configs/at91_dt_defconfig ++++ b/arch/arm/configs/at91_dt_defconfig +@@ -64,7 +64,6 @@ CONFIG_BLK_DEV_LOOP=y + CONFIG_BLK_DEV_RAM=y + CONFIG_BLK_DEV_RAM_COUNT=4 + CONFIG_BLK_DEV_RAM_SIZE=8192 +-CONFIG_ATMEL_TCLIB=y + CONFIG_ATMEL_SSC=y + CONFIG_SCSI=y + CONFIG_BLK_DEV_SD=y +--- a/arch/arm/configs/sama5_defconfig ++++ b/arch/arm/configs/sama5_defconfig +@@ -75,7 +75,6 @@ CONFIG_BLK_DEV_LOOP=y + CONFIG_BLK_DEV_RAM=y + CONFIG_BLK_DEV_RAM_COUNT=4 + CONFIG_BLK_DEV_RAM_SIZE=8192 +-CONFIG_ATMEL_TCLIB=y + CONFIG_ATMEL_SSC=y + CONFIG_EEPROM_AT24=y + CONFIG_SCSI=y diff --git a/kernel/patches-4.19.x-rt/0007-0007-ARM-configs-at91-unselect-PIT.patch b/kernel/patches-4.19.x-rt/0007-0007-ARM-configs-at91-unselect-PIT.patch new file mode 100644 index 000000000..f5694ce09 --- /dev/null +++ b/kernel/patches-4.19.x-rt/0007-0007-ARM-configs-at91-unselect-PIT.patch @@ -0,0 +1,35 @@ +From: Alexandre Belloni +Date: Thu, 13 Sep 2018 13:30:24 +0200 +Subject: [PATCH 7/7] ARM: configs: at91: unselect PIT + +The PIT is not required anymore to successfully boot and may actually harm +in case preempt-rt is used because the PIT interrupt is shared. +Disable it so the TCB clocksource is used. + +Signed-off-by: Alexandre Belloni +Signed-off-by: Sebastian Andrzej Siewior +--- + arch/arm/configs/at91_dt_defconfig | 1 + + arch/arm/configs/sama5_defconfig | 1 + + 2 files changed, 2 insertions(+) + +--- a/arch/arm/configs/at91_dt_defconfig ++++ b/arch/arm/configs/at91_dt_defconfig +@@ -19,6 +19,7 @@ CONFIG_ARCH_MULTI_V5=y + CONFIG_ARCH_AT91=y + CONFIG_SOC_AT91RM9200=y + CONFIG_SOC_AT91SAM9=y ++# CONFIG_ATMEL_CLOCKSOURCE_PIT is not set + CONFIG_AEABI=y + CONFIG_UACCESS_WITH_MEMCPY=y + CONFIG_ZBOOT_ROM_TEXT=0x0 +--- a/arch/arm/configs/sama5_defconfig ++++ b/arch/arm/configs/sama5_defconfig +@@ -20,6 +20,7 @@ CONFIG_ARCH_AT91=y + CONFIG_SOC_SAMA5D2=y + CONFIG_SOC_SAMA5D3=y + CONFIG_SOC_SAMA5D4=y ++# CONFIG_ATMEL_CLOCKSOURCE_PIT is not set + CONFIG_AEABI=y + CONFIG_UACCESS_WITH_MEMCPY=y + CONFIG_ZBOOT_ROM_TEXT=0x0 diff --git a/kernel/patches-4.19.x-rt/0008-irqchip-gic-v3-its-Move-pending-table-allocation-to-.patch b/kernel/patches-4.19.x-rt/0008-irqchip-gic-v3-its-Move-pending-table-allocation-to-.patch new file mode 100644 index 000000000..3041a5b8c --- /dev/null +++ b/kernel/patches-4.19.x-rt/0008-irqchip-gic-v3-its-Move-pending-table-allocation-to-.patch @@ -0,0 +1,162 @@ +From: Marc Zyngier +Date: Fri, 27 Jul 2018 13:38:54 +0100 +Subject: [PATCH] irqchip/gic-v3-its: Move pending table allocation to init + time + +Signed-off-by: Marc Zyngier +Signed-off-by: Sebastian Andrzej Siewior +--- + drivers/irqchip/irq-gic-v3-its.c | 80 ++++++++++++++++++++++++------------- + include/linux/irqchip/arm-gic-v3.h | 1 + 2 files changed, 53 insertions(+), 28 deletions(-) + +--- a/drivers/irqchip/irq-gic-v3-its.c ++++ b/drivers/irqchip/irq-gic-v3-its.c +@@ -179,6 +179,7 @@ static DEFINE_RAW_SPINLOCK(vmovp_lock); + static DEFINE_IDA(its_vpeid_ida); + + #define gic_data_rdist() (raw_cpu_ptr(gic_rdists->rdist)) ++#define gic_data_rdist_cpu(cpu) (per_cpu_ptr(gic_rdists->rdist, cpu)) + #define gic_data_rdist_rd_base() (gic_data_rdist()->rd_base) + #define gic_data_rdist_vlpi_base() (gic_data_rdist_rd_base() + SZ_128K) + +@@ -1628,7 +1629,7 @@ static void its_free_prop_table(struct p + get_order(LPI_PROPBASE_SZ)); + } + +-static int __init its_alloc_lpi_tables(void) ++static int __init its_alloc_lpi_prop_table(void) + { + phys_addr_t paddr; + +@@ -1951,30 +1952,47 @@ static void its_free_pending_table(struc + get_order(max_t(u32, LPI_PENDBASE_SZ, SZ_64K))); + } + +-static void its_cpu_init_lpis(void) ++static int __init allocate_lpi_tables(void) + { +- void __iomem *rbase = gic_data_rdist_rd_base(); +- struct page *pend_page; +- u64 val, tmp; ++ int err, cpu; + +- /* If we didn't allocate the pending table yet, do it now */ +- pend_page = gic_data_rdist()->pend_page; +- if (!pend_page) { +- phys_addr_t paddr; ++ err = its_alloc_lpi_prop_table(); ++ if (err) ++ return err; ++ ++ /* ++ * We allocate all the pending tables anyway, as we may have a ++ * mix of RDs that have had LPIs enabled, and some that ++ * don't. We'll free the unused ones as each CPU comes online. ++ */ ++ for_each_possible_cpu(cpu) { ++ struct page *pend_page; + + pend_page = its_allocate_pending_table(GFP_NOWAIT); + if (!pend_page) { +- pr_err("Failed to allocate PENDBASE for CPU%d\n", +- smp_processor_id()); +- return; ++ pr_err("Failed to allocate PENDBASE for CPU%d\n", cpu); ++ return -ENOMEM; + } + +- paddr = page_to_phys(pend_page); +- pr_info("CPU%d: using LPI pending table @%pa\n", +- smp_processor_id(), &paddr); +- gic_data_rdist()->pend_page = pend_page; ++ gic_data_rdist_cpu(cpu)->pend_page = pend_page; + } + ++ return 0; ++} ++ ++static void its_cpu_init_lpis(void) ++{ ++ void __iomem *rbase = gic_data_rdist_rd_base(); ++ struct page *pend_page; ++ phys_addr_t paddr; ++ u64 val, tmp; ++ ++ if (gic_data_rdist()->lpi_enabled) ++ return; ++ ++ pend_page = gic_data_rdist()->pend_page; ++ paddr = page_to_phys(pend_page); ++ + /* set PROPBASE */ + val = (page_to_phys(gic_rdists->prop_page) | + GICR_PROPBASER_InnerShareable | +@@ -2026,6 +2044,10 @@ static void its_cpu_init_lpis(void) + + /* Make sure the GIC has seen the above */ + dsb(sy); ++ gic_data_rdist()->lpi_enabled = true; ++ pr_info("GICv3: CPU%d: using LPI pending table @%pa\n", ++ smp_processor_id(), ++ &paddr); + } + + static void its_cpu_init_collection(struct its_node *its) +@@ -3521,16 +3543,6 @@ static int redist_disable_lpis(void) + u64 timeout = USEC_PER_SEC; + u64 val; + +- /* +- * If coming via a CPU hotplug event, we don't need to disable +- * LPIs before trying to re-enable them. They are already +- * configured and all is well in the world. Detect this case +- * by checking the allocation of the pending table for the +- * current CPU. +- */ +- if (gic_data_rdist()->pend_page) +- return 0; +- + if (!gic_rdists_supports_plpis()) { + pr_info("CPU%d: LPIs not supported\n", smp_processor_id()); + return -ENXIO; +@@ -3540,7 +3552,18 @@ static int redist_disable_lpis(void) + if (!(val & GICR_CTLR_ENABLE_LPIS)) + return 0; + +- pr_warn("CPU%d: Booted with LPIs enabled, memory probably corrupted\n", ++ /* ++ * If coming via a CPU hotplug event, we don't need to disable ++ * LPIs before trying to re-enable them. They are already ++ * configured and all is well in the world. ++ */ ++ if (gic_data_rdist()->lpi_enabled) ++ return 0; ++ ++ /* ++ * From that point on, we only try to do some damage control. ++ */ ++ pr_warn("GICv3: CPU%d: Booted with LPIs enabled, memory probably corrupted\n", + smp_processor_id()); + add_taint(TAINT_CRAP, LOCKDEP_STILL_OK); + +@@ -3796,7 +3819,8 @@ int __init its_init(struct fwnode_handle + } + + gic_rdists = rdists; +- err = its_alloc_lpi_tables(); ++ ++ err = allocate_lpi_tables(); + if (err) + return err; + +--- a/include/linux/irqchip/arm-gic-v3.h ++++ b/include/linux/irqchip/arm-gic-v3.h +@@ -585,6 +585,7 @@ struct rdists { + void __iomem *rd_base; + struct page *pend_page; + phys_addr_t phys_base; ++ bool lpi_enabled; + } __percpu *rdist; + struct page *prop_page; + u64 flags; diff --git a/kernel/patches-4.14.x-rt/0438-kthread-convert-worker-lock-to-raw-spinlock.patch b/kernel/patches-4.19.x-rt/0009-kthread-convert-worker-lock-to-raw-spinlock.patch similarity index 75% rename from kernel/patches-4.14.x-rt/0438-kthread-convert-worker-lock-to-raw-spinlock.patch rename to kernel/patches-4.19.x-rt/0009-kthread-convert-worker-lock-to-raw-spinlock.patch index 2a2647831..6404b1cce 100644 --- a/kernel/patches-4.14.x-rt/0438-kthread-convert-worker-lock-to-raw-spinlock.patch +++ b/kernel/patches-4.19.x-rt/0009-kthread-convert-worker-lock-to-raw-spinlock.patch @@ -1,9 +1,6 @@ -From 488d578d986a515351e86d77cad9b28c0f3c10c0 Mon Sep 17 00:00:00 2001 From: Julia Cartwright Date: Fri, 28 Sep 2018 21:03:51 +0000 -Subject: [PATCH 438/450] kthread: convert worker lock to raw spinlock - -[ Upstream commit 5c8919eed1cfcad5da452047bd4ab088837afc41 ] +Subject: [PATCH] kthread: convert worker lock to raw spinlock In order to enable the queuing of kthread work items from hardirq context even when PREEMPT_RT_FULL is enabled, convert the worker @@ -18,17 +15,14 @@ Reported-and-tested-by: Steffen Trumtrar Reported-by: Tim Sander Signed-off-by: Julia Cartwright Signed-off-by: Sebastian Andrzej Siewior -Signed-off-by: Steven Rostedt (VMware) --- - include/linux/kthread.h | 2 +- - kernel/kthread.c | 42 ++++++++++++++++++++--------------------- + include/linux/kthread.h | 2 +- + kernel/kthread.c | 42 +++++++++++++++++++++--------------------- 2 files changed, 22 insertions(+), 22 deletions(-) -diff --git a/include/linux/kthread.h b/include/linux/kthread.h -index 4e26609c77d4..4e0449df82c3 100644 --- a/include/linux/kthread.h +++ b/include/linux/kthread.h -@@ -84,7 +84,7 @@ enum { +@@ -85,7 +85,7 @@ enum { struct kthread_worker { unsigned int flags; @@ -37,11 +31,9 @@ index 4e26609c77d4..4e0449df82c3 100644 struct list_head work_list; struct list_head delayed_work_list; struct task_struct *task; -diff --git a/kernel/kthread.c b/kernel/kthread.c -index 4e6d85b63201..430fd79cd3fe 100644 --- a/kernel/kthread.c +++ b/kernel/kthread.c -@@ -579,7 +579,7 @@ void __kthread_init_worker(struct kthread_worker *worker, +@@ -599,7 +599,7 @@ void __kthread_init_worker(struct kthrea struct lock_class_key *key) { memset(worker, 0, sizeof(struct kthread_worker)); @@ -50,7 +42,7 @@ index 4e6d85b63201..430fd79cd3fe 100644 lockdep_set_class_and_name(&worker->lock, key, name); INIT_LIST_HEAD(&worker->work_list); INIT_LIST_HEAD(&worker->delayed_work_list); -@@ -621,21 +621,21 @@ int kthread_worker_fn(void *worker_ptr) +@@ -641,21 +641,21 @@ int kthread_worker_fn(void *worker_ptr) if (kthread_should_stop()) { __set_current_state(TASK_RUNNING); @@ -76,7 +68,7 @@ index 4e6d85b63201..430fd79cd3fe 100644 if (work) { __set_current_state(TASK_RUNNING); -@@ -792,12 +792,12 @@ bool kthread_queue_work(struct kthread_worker *worker, +@@ -812,12 +812,12 @@ bool kthread_queue_work(struct kthread_w bool ret = false; unsigned long flags; @@ -91,7 +83,7 @@ index 4e6d85b63201..430fd79cd3fe 100644 return ret; } EXPORT_SYMBOL_GPL(kthread_queue_work); -@@ -824,7 +824,7 @@ void kthread_delayed_work_timer_fn(unsigned long __data) +@@ -843,7 +843,7 @@ void kthread_delayed_work_timer_fn(struc if (WARN_ON_ONCE(!worker)) return; @@ -100,7 +92,7 @@ index 4e6d85b63201..430fd79cd3fe 100644 /* Work must not be used with >1 worker, see kthread_queue_work(). */ WARN_ON_ONCE(work->worker != worker); -@@ -833,7 +833,7 @@ void kthread_delayed_work_timer_fn(unsigned long __data) +@@ -852,7 +852,7 @@ void kthread_delayed_work_timer_fn(struc list_del_init(&work->node); kthread_insert_work(worker, work, &worker->work_list); @@ -109,7 +101,7 @@ index 4e6d85b63201..430fd79cd3fe 100644 } EXPORT_SYMBOL(kthread_delayed_work_timer_fn); -@@ -890,14 +890,14 @@ bool kthread_queue_delayed_work(struct kthread_worker *worker, +@@ -908,14 +908,14 @@ bool kthread_queue_delayed_work(struct k unsigned long flags; bool ret = false; @@ -126,7 +118,7 @@ index 4e6d85b63201..430fd79cd3fe 100644 return ret; } EXPORT_SYMBOL_GPL(kthread_queue_delayed_work); -@@ -933,7 +933,7 @@ void kthread_flush_work(struct kthread_work *work) +@@ -951,7 +951,7 @@ void kthread_flush_work(struct kthread_w if (!worker) return; @@ -135,7 +127,7 @@ index 4e6d85b63201..430fd79cd3fe 100644 /* Work must not be used with >1 worker, see kthread_queue_work(). */ WARN_ON_ONCE(work->worker != worker); -@@ -945,7 +945,7 @@ void kthread_flush_work(struct kthread_work *work) +@@ -963,7 +963,7 @@ void kthread_flush_work(struct kthread_w else noop = true; @@ -144,7 +136,7 @@ index 4e6d85b63201..430fd79cd3fe 100644 if (!noop) wait_for_completion(&fwork.done); -@@ -978,9 +978,9 @@ static bool __kthread_cancel_work(struct kthread_work *work, bool is_dwork, +@@ -996,9 +996,9 @@ static bool __kthread_cancel_work(struct * any queuing is blocked by setting the canceling counter. */ work->canceling++; @@ -156,7 +148,7 @@ index 4e6d85b63201..430fd79cd3fe 100644 work->canceling--; } -@@ -1027,7 +1027,7 @@ bool kthread_mod_delayed_work(struct kthread_worker *worker, +@@ -1045,7 +1045,7 @@ bool kthread_mod_delayed_work(struct kth unsigned long flags; int ret = false; @@ -165,7 +157,7 @@ index 4e6d85b63201..430fd79cd3fe 100644 /* Do not bother with canceling when never queued. */ if (!work->worker) -@@ -1044,7 +1044,7 @@ bool kthread_mod_delayed_work(struct kthread_worker *worker, +@@ -1062,7 +1062,7 @@ bool kthread_mod_delayed_work(struct kth fast_queue: __kthread_queue_delayed_work(worker, dwork, delay); out: @@ -174,7 +166,7 @@ index 4e6d85b63201..430fd79cd3fe 100644 return ret; } EXPORT_SYMBOL_GPL(kthread_mod_delayed_work); -@@ -1058,7 +1058,7 @@ static bool __kthread_cancel_work_sync(struct kthread_work *work, bool is_dwork) +@@ -1076,7 +1076,7 @@ static bool __kthread_cancel_work_sync(s if (!worker) goto out; @@ -183,7 +175,7 @@ index 4e6d85b63201..430fd79cd3fe 100644 /* Work must not be used with >1 worker, see kthread_queue_work(). */ WARN_ON_ONCE(work->worker != worker); -@@ -1072,13 +1072,13 @@ static bool __kthread_cancel_work_sync(struct kthread_work *work, bool is_dwork) +@@ -1090,13 +1090,13 @@ static bool __kthread_cancel_work_sync(s * In the meantime, block any queuing by setting the canceling counter. */ work->canceling++; @@ -200,6 +192,3 @@ index 4e6d85b63201..430fd79cd3fe 100644 out: return ret; } --- -2.19.2 - diff --git a/kernel/patches-4.19.x-rt/0010-crypto-caam-qi-simplify-CGR-allocation-freeing.patch b/kernel/patches-4.19.x-rt/0010-crypto-caam-qi-simplify-CGR-allocation-freeing.patch new file mode 100644 index 000000000..bcf3bf8d7 --- /dev/null +++ b/kernel/patches-4.19.x-rt/0010-crypto-caam-qi-simplify-CGR-allocation-freeing.patch @@ -0,0 +1,131 @@ +From: =?UTF-8?q?Horia=20Geant=C4=83?= +Date: Mon, 8 Oct 2018 14:09:37 +0300 +Subject: [PATCH] crypto: caam/qi - simplify CGR allocation, freeing +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +[Upstream commit 29e83c757006fd751966bdc53392bb22d74179c6] + +CGRs (Congestion Groups) have to be freed by the same CPU that +initialized them. +This is why currently the driver takes special measures; however, using +set_cpus_allowed_ptr() is incorrect - as reported by Sebastian. + +Instead of the generic solution of replacing set_cpus_allowed_ptr() with +work_on_cpu_safe(), we use the qman_delete_cgr_safe() QBMan API instead +of qman_delete_cgr() - which internally takes care of proper CGR +deletion. + +Link: https://lkml.kernel.org/r/20181005125443.dfhd2asqktm22ney@linutronix.de +Reported-by: Sebastian Andrzej Siewior +Signed-off-by: Horia Geantă +Signed-off-by: Herbert Xu +--- + drivers/crypto/caam/qi.c | 43 ++++--------------------------------------- + drivers/crypto/caam/qi.h | 2 +- + 2 files changed, 5 insertions(+), 40 deletions(-) + +--- a/drivers/crypto/caam/qi.c ++++ b/drivers/crypto/caam/qi.c +@@ -84,13 +84,6 @@ static u64 times_congested; + #endif + + /* +- * CPU from where the module initialised. This is required because QMan driver +- * requires CGRs to be removed from same CPU from where they were originally +- * allocated. +- */ +-static int mod_init_cpu; +- +-/* + * This is a a cache of buffers, from which the users of CAAM QI driver + * can allocate short (CAAM_QI_MEMCACHE_SIZE) buffers. It's faster than + * doing malloc on the hotpath. +@@ -492,12 +485,11 @@ void caam_drv_ctx_rel(struct caam_drv_ct + } + EXPORT_SYMBOL(caam_drv_ctx_rel); + +-int caam_qi_shutdown(struct device *qidev) ++void caam_qi_shutdown(struct device *qidev) + { +- int i, ret; ++ int i; + struct caam_qi_priv *priv = dev_get_drvdata(qidev); + const cpumask_t *cpus = qman_affine_cpus(); +- struct cpumask old_cpumask = current->cpus_allowed; + + for_each_cpu(i, cpus) { + struct napi_struct *irqtask; +@@ -510,26 +502,12 @@ int caam_qi_shutdown(struct device *qide + dev_err(qidev, "Rsp FQ kill failed, cpu: %d\n", i); + } + +- /* +- * QMan driver requires CGRs to be deleted from same CPU from where they +- * were instantiated. Hence we get the module removal execute from the +- * same CPU from where it was originally inserted. +- */ +- set_cpus_allowed_ptr(current, get_cpu_mask(mod_init_cpu)); +- +- ret = qman_delete_cgr(&priv->cgr); +- if (ret) +- dev_err(qidev, "Deletion of CGR failed: %d\n", ret); +- else +- qman_release_cgrid(priv->cgr.cgrid); ++ qman_delete_cgr_safe(&priv->cgr); ++ qman_release_cgrid(priv->cgr.cgrid); + + kmem_cache_destroy(qi_cache); + +- /* Now that we're done with the CGRs, restore the cpus allowed mask */ +- set_cpus_allowed_ptr(current, &old_cpumask); +- + platform_device_unregister(priv->qi_pdev); +- return ret; + } + + static void cgr_cb(struct qman_portal *qm, struct qman_cgr *cgr, int congested) +@@ -718,22 +696,11 @@ int caam_qi_init(struct platform_device + struct device *ctrldev = &caam_pdev->dev, *qidev; + struct caam_drv_private *ctrlpriv; + const cpumask_t *cpus = qman_affine_cpus(); +- struct cpumask old_cpumask = current->cpus_allowed; + static struct platform_device_info qi_pdev_info = { + .name = "caam_qi", + .id = PLATFORM_DEVID_NONE + }; + +- /* +- * QMAN requires CGRs to be removed from same CPU+portal from where it +- * was originally allocated. Hence we need to note down the +- * initialisation CPU and use the same CPU for module exit. +- * We select the first CPU to from the list of portal owning CPUs. +- * Then we pin module init to this CPU. +- */ +- mod_init_cpu = cpumask_first(cpus); +- set_cpus_allowed_ptr(current, get_cpu_mask(mod_init_cpu)); +- + qi_pdev_info.parent = ctrldev; + qi_pdev_info.dma_mask = dma_get_mask(ctrldev); + qi_pdev = platform_device_register_full(&qi_pdev_info); +@@ -795,8 +762,6 @@ int caam_qi_init(struct platform_device + return -ENOMEM; + } + +- /* Done with the CGRs; restore the cpus allowed mask */ +- set_cpus_allowed_ptr(current, &old_cpumask); + #ifdef CONFIG_DEBUG_FS + debugfs_create_file("qi_congested", 0444, ctrlpriv->ctl, + ×_congested, &caam_fops_u64_ro); +--- a/drivers/crypto/caam/qi.h ++++ b/drivers/crypto/caam/qi.h +@@ -174,7 +174,7 @@ int caam_drv_ctx_update(struct caam_drv_ + void caam_drv_ctx_rel(struct caam_drv_ctx *drv_ctx); + + int caam_qi_init(struct platform_device *pdev); +-int caam_qi_shutdown(struct device *dev); ++void caam_qi_shutdown(struct device *dev); + + /** + * qi_cache_alloc - Allocate buffers from CAAM-QI cache diff --git a/kernel/patches-4.19.x-rt/0011-sched-fair-Robustify-CFS-bandwidth-timer-locking.patch b/kernel/patches-4.19.x-rt/0011-sched-fair-Robustify-CFS-bandwidth-timer-locking.patch new file mode 100644 index 000000000..b1af1e937 --- /dev/null +++ b/kernel/patches-4.19.x-rt/0011-sched-fair-Robustify-CFS-bandwidth-timer-locking.patch @@ -0,0 +1,141 @@ +From: Peter Zijlstra +Date: Mon, 7 Jan 2019 13:52:31 +0100 +Subject: [PATCH] sched/fair: Robustify CFS-bandwidth timer locking + +Traditionally hrtimer callbacks were run with IRQs disabled, but with +the introduction of HRTIMER_MODE_SOFT it is possible they run from +SoftIRQ context, which does _NOT_ have IRQs disabled. + +Allow for the CFS bandwidth timers (period_timer and slack_timer) to +be ran from SoftIRQ context; this entails removing the assumption that +IRQs are already disabled from the locking. + +While mainline doesn't strictly need this, -RT forces all timers not +explicitly marked with MODE_HARD into MODE_SOFT and trips over this. +And marking these timers as MODE_HARD doesn't make sense as they're +not required for RT operation and can potentially be quite expensive. + +Cc: Ingo Molnar +Cc: Thomas Gleixner +Cc: Sebastian Andrzej Siewior +Reported-by: Tom Putzeys +Tested-by: Mike Galbraith +Signed-off-by: Peter Zijlstra (Intel) +Link: https://lkml.kernel.org/r/20190107125231.GE14122@hirez.programming.kicks-ass.net +Signed-off-by: Sebastian Andrzej Siewior +--- + kernel/sched/fair.c | 30 ++++++++++++++++-------------- + 1 file changed, 16 insertions(+), 14 deletions(-) + +--- a/kernel/sched/fair.c ++++ b/kernel/sched/fair.c +@@ -4553,7 +4553,7 @@ static u64 distribute_cfs_runtime(struct + struct rq *rq = rq_of(cfs_rq); + struct rq_flags rf; + +- rq_lock(rq, &rf); ++ rq_lock_irqsave(rq, &rf); + if (!cfs_rq_throttled(cfs_rq)) + goto next; + +@@ -4570,7 +4570,7 @@ static u64 distribute_cfs_runtime(struct + unthrottle_cfs_rq(cfs_rq); + + next: +- rq_unlock(rq, &rf); ++ rq_unlock_irqrestore(rq, &rf); + + if (!remaining) + break; +@@ -4586,7 +4586,7 @@ static u64 distribute_cfs_runtime(struct + * period the timer is deactivated until scheduling resumes; cfs_b->idle is + * used to track this state. + */ +-static int do_sched_cfs_period_timer(struct cfs_bandwidth *cfs_b, int overrun) ++static int do_sched_cfs_period_timer(struct cfs_bandwidth *cfs_b, int overrun, unsigned long flags) + { + u64 runtime, runtime_expires; + int throttled; +@@ -4628,11 +4628,11 @@ static int do_sched_cfs_period_timer(str + while (throttled && cfs_b->runtime > 0 && !cfs_b->distribute_running) { + runtime = cfs_b->runtime; + cfs_b->distribute_running = 1; +- raw_spin_unlock(&cfs_b->lock); ++ raw_spin_unlock_irqrestore(&cfs_b->lock, flags); + /* we can't nest cfs_b->lock while distributing bandwidth */ + runtime = distribute_cfs_runtime(cfs_b, runtime, + runtime_expires); +- raw_spin_lock(&cfs_b->lock); ++ raw_spin_lock_irqsave(&cfs_b->lock, flags); + + cfs_b->distribute_running = 0; + throttled = !list_empty(&cfs_b->throttled_cfs_rq); +@@ -4741,17 +4741,18 @@ static __always_inline void return_cfs_r + static void do_sched_cfs_slack_timer(struct cfs_bandwidth *cfs_b) + { + u64 runtime = 0, slice = sched_cfs_bandwidth_slice(); ++ unsigned long flags; + u64 expires; + + /* confirm we're still not at a refresh boundary */ +- raw_spin_lock(&cfs_b->lock); ++ raw_spin_lock_irqsave(&cfs_b->lock, flags); + if (cfs_b->distribute_running) { +- raw_spin_unlock(&cfs_b->lock); ++ raw_spin_unlock_irqrestore(&cfs_b->lock, flags); + return; + } + + if (runtime_refresh_within(cfs_b, min_bandwidth_expiration)) { +- raw_spin_unlock(&cfs_b->lock); ++ raw_spin_unlock_irqrestore(&cfs_b->lock, flags); + return; + } + +@@ -4762,18 +4763,18 @@ static void do_sched_cfs_slack_timer(str + if (runtime) + cfs_b->distribute_running = 1; + +- raw_spin_unlock(&cfs_b->lock); ++ raw_spin_unlock_irqrestore(&cfs_b->lock, flags); + + if (!runtime) + return; + + runtime = distribute_cfs_runtime(cfs_b, runtime, expires); + +- raw_spin_lock(&cfs_b->lock); ++ raw_spin_lock_irqsave(&cfs_b->lock, flags); + if (expires == cfs_b->runtime_expires) + cfs_b->runtime -= min(runtime, cfs_b->runtime); + cfs_b->distribute_running = 0; +- raw_spin_unlock(&cfs_b->lock); ++ raw_spin_unlock_irqrestore(&cfs_b->lock, flags); + } + + /* +@@ -4851,20 +4852,21 @@ static enum hrtimer_restart sched_cfs_pe + { + struct cfs_bandwidth *cfs_b = + container_of(timer, struct cfs_bandwidth, period_timer); ++ unsigned long flags; + int overrun; + int idle = 0; + +- raw_spin_lock(&cfs_b->lock); ++ raw_spin_lock_irqsave(&cfs_b->lock, flags); + for (;;) { + overrun = hrtimer_forward_now(timer, cfs_b->period); + if (!overrun) + break; + +- idle = do_sched_cfs_period_timer(cfs_b, overrun); ++ idle = do_sched_cfs_period_timer(cfs_b, overrun, flags); + } + if (idle) + cfs_b->period_active = 0; +- raw_spin_unlock(&cfs_b->lock); ++ raw_spin_unlock_irqrestore(&cfs_b->lock, flags); + + return idle ? HRTIMER_NORESTART : HRTIMER_RESTART; + } diff --git a/kernel/patches-4.14.x-rt/0126-arm-Convert-arm-boot_lock-to-raw.patch b/kernel/patches-4.19.x-rt/0012-arm-convert-boot-lock-to-raw.patch similarity index 69% rename from kernel/patches-4.14.x-rt/0126-arm-Convert-arm-boot_lock-to-raw.patch rename to kernel/patches-4.19.x-rt/0012-arm-convert-boot-lock-to-raw.patch index 55adaf514..bd61c05b9 100644 --- a/kernel/patches-4.14.x-rt/0126-arm-Convert-arm-boot_lock-to-raw.patch +++ b/kernel/patches-4.19.x-rt/0012-arm-convert-boot-lock-to-raw.patch @@ -1,7 +1,6 @@ -From 181e6d8c5d3fd3c3c6d751c64b3716e56dad29f3 Mon Sep 17 00:00:00 2001 From: Frank Rowand Date: Mon, 19 Sep 2011 14:51:14 -0700 -Subject: [PATCH 126/450] arm: Convert arm boot_lock to raw +Subject: arm: Convert arm boot_lock to raw The arm boot_lock is used by the secondary processor startup code. The locking task is the idle thread, which has idle->sched_class == &idle_sched_class. @@ -19,23 +18,25 @@ Fix by converting boot_lock to a raw spin lock. Signed-off-by: Frank Rowand Link: http://lkml.kernel.org/r/4E77B952.3010606@am.sony.com Signed-off-by: Thomas Gleixner +Tested-by: Tony Lindgren +Acked-by: Krzysztof Kozlowski +Tested-by: Krzysztof Kozlowski [Exynos5422 Linaro PM-QA] +Signed-off-by: Sebastian Andrzej Siewior --- - arch/arm/mach-exynos/platsmp.c | 12 ++++++------ - arch/arm/mach-hisi/platmcpm.c | 22 +++++++++++----------- - arch/arm/mach-omap2/omap-smp.c | 10 +++++----- - arch/arm/mach-prima2/platsmp.c | 10 +++++----- - arch/arm/mach-qcom/platsmp.c | 10 +++++----- - arch/arm/mach-spear/platsmp.c | 10 +++++----- - arch/arm/mach-sti/platsmp.c | 10 +++++----- - arch/arm/plat-versatile/platsmp.c | 10 +++++----- + arch/arm/mach-exynos/platsmp.c | 12 ++++++------ + arch/arm/mach-hisi/platmcpm.c | 22 +++++++++++----------- + arch/arm/mach-omap2/omap-smp.c | 10 +++++----- + arch/arm/mach-prima2/platsmp.c | 10 +++++----- + arch/arm/mach-qcom/platsmp.c | 10 +++++----- + arch/arm/mach-spear/platsmp.c | 10 +++++----- + arch/arm/mach-sti/platsmp.c | 10 +++++----- + arch/arm/plat-versatile/platsmp.c | 10 +++++----- 8 files changed, 47 insertions(+), 47 deletions(-) -diff --git a/arch/arm/mach-exynos/platsmp.c b/arch/arm/mach-exynos/platsmp.c -index 5a03bffe7226..3080ea833d19 100644 --- a/arch/arm/mach-exynos/platsmp.c +++ b/arch/arm/mach-exynos/platsmp.c -@@ -229,7 +229,7 @@ static void __iomem *scu_base_addr(void) - return (void __iomem *)(S5P_VA_SCU); +@@ -239,7 +239,7 @@ static void write_pen_release(int val) + sync_cache_w(&pen_release); } -static DEFINE_SPINLOCK(boot_lock); @@ -43,7 +44,7 @@ index 5a03bffe7226..3080ea833d19 100644 static void exynos_secondary_init(unsigned int cpu) { -@@ -242,8 +242,8 @@ static void exynos_secondary_init(unsigned int cpu) +@@ -252,8 +252,8 @@ static void exynos_secondary_init(unsign /* * Synchronise with the boot thread. */ @@ -54,7 +55,7 @@ index 5a03bffe7226..3080ea833d19 100644 } int exynos_set_boot_addr(u32 core_id, unsigned long boot_addr) -@@ -307,7 +307,7 @@ static int exynos_boot_secondary(unsigned int cpu, struct task_struct *idle) +@@ -317,7 +317,7 @@ static int exynos_boot_secondary(unsigne * Set synchronisation state between this boot processor * and the secondary one */ @@ -63,7 +64,7 @@ index 5a03bffe7226..3080ea833d19 100644 /* * The secondary processor is waiting to be released from -@@ -334,7 +334,7 @@ static int exynos_boot_secondary(unsigned int cpu, struct task_struct *idle) +@@ -344,7 +344,7 @@ static int exynos_boot_secondary(unsigne if (timeout == 0) { printk(KERN_ERR "cpu1 power enable failed"); @@ -72,7 +73,7 @@ index 5a03bffe7226..3080ea833d19 100644 return -ETIMEDOUT; } } -@@ -380,7 +380,7 @@ static int exynos_boot_secondary(unsigned int cpu, struct task_struct *idle) +@@ -390,7 +390,7 @@ static int exynos_boot_secondary(unsigne * calibrations, then wait for it to finish */ fail: @@ -81,8 +82,6 @@ index 5a03bffe7226..3080ea833d19 100644 return pen_release != -1 ? ret : 0; } -diff --git a/arch/arm/mach-hisi/platmcpm.c b/arch/arm/mach-hisi/platmcpm.c -index f66815c3dd07..00524abd963f 100644 --- a/arch/arm/mach-hisi/platmcpm.c +++ b/arch/arm/mach-hisi/platmcpm.c @@ -61,7 +61,7 @@ @@ -94,7 +93,7 @@ index f66815c3dd07..00524abd963f 100644 static u32 fabric_phys_addr; /* * [0]: bootwrapper physical address -@@ -113,7 +113,7 @@ static int hip04_boot_secondary(unsigned int l_cpu, struct task_struct *idle) +@@ -113,7 +113,7 @@ static int hip04_boot_secondary(unsigned if (cluster >= HIP04_MAX_CLUSTERS || cpu >= HIP04_MAX_CPUS_PER_CLUSTER) return -EINVAL; @@ -103,7 +102,7 @@ index f66815c3dd07..00524abd963f 100644 if (hip04_cpu_table[cluster][cpu]) goto out; -@@ -147,7 +147,7 @@ static int hip04_boot_secondary(unsigned int l_cpu, struct task_struct *idle) +@@ -147,7 +147,7 @@ static int hip04_boot_secondary(unsigned out: hip04_cpu_table[cluster][cpu]++; @@ -112,7 +111,7 @@ index f66815c3dd07..00524abd963f 100644 return 0; } -@@ -162,11 +162,11 @@ static void hip04_cpu_die(unsigned int l_cpu) +@@ -162,11 +162,11 @@ static void hip04_cpu_die(unsigned int l cpu = MPIDR_AFFINITY_LEVEL(mpidr, 0); cluster = MPIDR_AFFINITY_LEVEL(mpidr, 1); @@ -126,7 +125,7 @@ index f66815c3dd07..00524abd963f 100644 return; } else if (hip04_cpu_table[cluster][cpu] > 1) { pr_err("Cluster %d CPU%d boots multiple times\n", cluster, cpu); -@@ -174,7 +174,7 @@ static void hip04_cpu_die(unsigned int l_cpu) +@@ -174,7 +174,7 @@ static void hip04_cpu_die(unsigned int l } last_man = hip04_cluster_is_down(cluster); @@ -135,7 +134,7 @@ index f66815c3dd07..00524abd963f 100644 if (last_man) { /* Since it's Cortex A15, disable L2 prefetching. */ asm volatile( -@@ -203,7 +203,7 @@ static int hip04_cpu_kill(unsigned int l_cpu) +@@ -203,7 +203,7 @@ static int hip04_cpu_kill(unsigned int l cpu >= HIP04_MAX_CPUS_PER_CLUSTER); count = TIMEOUT_MSEC / POLL_MSEC; @@ -144,7 +143,7 @@ index f66815c3dd07..00524abd963f 100644 for (tries = 0; tries < count; tries++) { if (hip04_cpu_table[cluster][cpu]) goto err; -@@ -211,10 +211,10 @@ static int hip04_cpu_kill(unsigned int l_cpu) +@@ -211,10 +211,10 @@ static int hip04_cpu_kill(unsigned int l data = readl_relaxed(sysctrl + SC_CPU_RESET_STATUS(cluster)); if (data & CORE_WFI_STATUS(cpu)) break; @@ -157,7 +156,7 @@ index f66815c3dd07..00524abd963f 100644 } if (tries >= count) goto err; -@@ -231,10 +231,10 @@ static int hip04_cpu_kill(unsigned int l_cpu) +@@ -231,10 +231,10 @@ static int hip04_cpu_kill(unsigned int l goto err; if (hip04_cluster_is_down(cluster)) hip04_set_snoop_filter(cluster, 0); @@ -170,11 +169,9 @@ index f66815c3dd07..00524abd963f 100644 return 0; } #endif -diff --git a/arch/arm/mach-omap2/omap-smp.c b/arch/arm/mach-omap2/omap-smp.c -index 1c73694c871a..ac4d2f030b87 100644 --- a/arch/arm/mach-omap2/omap-smp.c +++ b/arch/arm/mach-omap2/omap-smp.c -@@ -69,7 +69,7 @@ static const struct omap_smp_config omap5_cfg __initconst = { +@@ -69,7 +69,7 @@ static const struct omap_smp_config omap .startup_addr = omap5_secondary_startup, }; @@ -183,7 +180,7 @@ index 1c73694c871a..ac4d2f030b87 100644 void __iomem *omap4_get_scu_base(void) { -@@ -177,8 +177,8 @@ static void omap4_secondary_init(unsigned int cpu) +@@ -177,8 +177,8 @@ static void omap4_secondary_init(unsigne /* * Synchronise with the boot thread. */ @@ -194,7 +191,7 @@ index 1c73694c871a..ac4d2f030b87 100644 } static int omap4_boot_secondary(unsigned int cpu, struct task_struct *idle) -@@ -191,7 +191,7 @@ static int omap4_boot_secondary(unsigned int cpu, struct task_struct *idle) +@@ -191,7 +191,7 @@ static int omap4_boot_secondary(unsigned * Set synchronisation state between this boot processor * and the secondary one */ @@ -203,7 +200,7 @@ index 1c73694c871a..ac4d2f030b87 100644 /* * Update the AuxCoreBoot0 with boot state for secondary core. -@@ -270,7 +270,7 @@ static int omap4_boot_secondary(unsigned int cpu, struct task_struct *idle) +@@ -270,7 +270,7 @@ static int omap4_boot_secondary(unsigned * Now the secondary core is starting up let it run its * calibrations, then wait for it to finish */ @@ -212,8 +209,6 @@ index 1c73694c871a..ac4d2f030b87 100644 return 0; } -diff --git a/arch/arm/mach-prima2/platsmp.c b/arch/arm/mach-prima2/platsmp.c -index 75ef5d4be554..c17c86e5d860 100644 --- a/arch/arm/mach-prima2/platsmp.c +++ b/arch/arm/mach-prima2/platsmp.c @@ -22,7 +22,7 @@ @@ -225,7 +220,7 @@ index 75ef5d4be554..c17c86e5d860 100644 static void sirfsoc_secondary_init(unsigned int cpu) { -@@ -36,8 +36,8 @@ static void sirfsoc_secondary_init(unsigned int cpu) +@@ -36,8 +36,8 @@ static void sirfsoc_secondary_init(unsig /* * Synchronise with the boot thread. */ @@ -236,7 +231,7 @@ index 75ef5d4be554..c17c86e5d860 100644 } static const struct of_device_id clk_ids[] = { -@@ -75,7 +75,7 @@ static int sirfsoc_boot_secondary(unsigned int cpu, struct task_struct *idle) +@@ -75,7 +75,7 @@ static int sirfsoc_boot_secondary(unsign /* make sure write buffer is drained */ mb(); @@ -245,7 +240,7 @@ index 75ef5d4be554..c17c86e5d860 100644 /* * The secondary processor is waiting to be released from -@@ -107,7 +107,7 @@ static int sirfsoc_boot_secondary(unsigned int cpu, struct task_struct *idle) +@@ -107,7 +107,7 @@ static int sirfsoc_boot_secondary(unsign * now the secondary core is starting up let it run its * calibrations, then wait for it to finish */ @@ -254,8 +249,6 @@ index 75ef5d4be554..c17c86e5d860 100644 return pen_release != -1 ? -ENOSYS : 0; } -diff --git a/arch/arm/mach-qcom/platsmp.c b/arch/arm/mach-qcom/platsmp.c -index 5494c9e0c909..e8ce157d3548 100644 --- a/arch/arm/mach-qcom/platsmp.c +++ b/arch/arm/mach-qcom/platsmp.c @@ -46,7 +46,7 @@ @@ -267,7 +260,7 @@ index 5494c9e0c909..e8ce157d3548 100644 #ifdef CONFIG_HOTPLUG_CPU static void qcom_cpu_die(unsigned int cpu) -@@ -60,8 +60,8 @@ static void qcom_secondary_init(unsigned int cpu) +@@ -60,8 +60,8 @@ static void qcom_secondary_init(unsigned /* * Synchronise with the boot thread. */ @@ -278,7 +271,7 @@ index 5494c9e0c909..e8ce157d3548 100644 } static int scss_release_secondary(unsigned int cpu) -@@ -284,7 +284,7 @@ static int qcom_boot_secondary(unsigned int cpu, int (*func)(unsigned int)) +@@ -284,7 +284,7 @@ static int qcom_boot_secondary(unsigned * set synchronisation state between this boot processor * and the secondary one */ @@ -287,7 +280,7 @@ index 5494c9e0c909..e8ce157d3548 100644 /* * Send the secondary CPU a soft interrupt, thereby causing -@@ -297,7 +297,7 @@ static int qcom_boot_secondary(unsigned int cpu, int (*func)(unsigned int)) +@@ -297,7 +297,7 @@ static int qcom_boot_secondary(unsigned * now the secondary core is starting up let it run its * calibrations, then wait for it to finish */ @@ -296,8 +289,6 @@ index 5494c9e0c909..e8ce157d3548 100644 return ret; } -diff --git a/arch/arm/mach-spear/platsmp.c b/arch/arm/mach-spear/platsmp.c -index 39038a03836a..6da5c93872bf 100644 --- a/arch/arm/mach-spear/platsmp.c +++ b/arch/arm/mach-spear/platsmp.c @@ -32,7 +32,7 @@ static void write_pen_release(int val) @@ -309,7 +300,7 @@ index 39038a03836a..6da5c93872bf 100644 static void __iomem *scu_base = IOMEM(VA_SCU_BASE); -@@ -47,8 +47,8 @@ static void spear13xx_secondary_init(unsigned int cpu) +@@ -47,8 +47,8 @@ static void spear13xx_secondary_init(uns /* * Synchronise with the boot thread. */ @@ -320,7 +311,7 @@ index 39038a03836a..6da5c93872bf 100644 } static int spear13xx_boot_secondary(unsigned int cpu, struct task_struct *idle) -@@ -59,7 +59,7 @@ static int spear13xx_boot_secondary(unsigned int cpu, struct task_struct *idle) +@@ -59,7 +59,7 @@ static int spear13xx_boot_secondary(unsi * set synchronisation state between this boot processor * and the secondary one */ @@ -329,7 +320,7 @@ index 39038a03836a..6da5c93872bf 100644 /* * The secondary processor is waiting to be released from -@@ -84,7 +84,7 @@ static int spear13xx_boot_secondary(unsigned int cpu, struct task_struct *idle) +@@ -84,7 +84,7 @@ static int spear13xx_boot_secondary(unsi * now the secondary core is starting up let it run its * calibrations, then wait for it to finish */ @@ -338,8 +329,6 @@ index 39038a03836a..6da5c93872bf 100644 return pen_release != -1 ? -ENOSYS : 0; } -diff --git a/arch/arm/mach-sti/platsmp.c b/arch/arm/mach-sti/platsmp.c -index 231f19e17436..a3419b7003e6 100644 --- a/arch/arm/mach-sti/platsmp.c +++ b/arch/arm/mach-sti/platsmp.c @@ -35,7 +35,7 @@ static void write_pen_release(int val) @@ -351,7 +340,7 @@ index 231f19e17436..a3419b7003e6 100644 static void sti_secondary_init(unsigned int cpu) { -@@ -48,8 +48,8 @@ static void sti_secondary_init(unsigned int cpu) +@@ -48,8 +48,8 @@ static void sti_secondary_init(unsigned /* * Synchronise with the boot thread. */ @@ -362,7 +351,7 @@ index 231f19e17436..a3419b7003e6 100644 } static int sti_boot_secondary(unsigned int cpu, struct task_struct *idle) -@@ -60,7 +60,7 @@ static int sti_boot_secondary(unsigned int cpu, struct task_struct *idle) +@@ -60,7 +60,7 @@ static int sti_boot_secondary(unsigned i * set synchronisation state between this boot processor * and the secondary one */ @@ -371,7 +360,7 @@ index 231f19e17436..a3419b7003e6 100644 /* * The secondary processor is waiting to be released from -@@ -91,7 +91,7 @@ static int sti_boot_secondary(unsigned int cpu, struct task_struct *idle) +@@ -91,7 +91,7 @@ static int sti_boot_secondary(unsigned i * now the secondary core is starting up let it run its * calibrations, then wait for it to finish */ @@ -380,8 +369,6 @@ index 231f19e17436..a3419b7003e6 100644 return pen_release != -1 ? -ENOSYS : 0; } -diff --git a/arch/arm/plat-versatile/platsmp.c b/arch/arm/plat-versatile/platsmp.c -index c2366510187a..6b60f582b738 100644 --- a/arch/arm/plat-versatile/platsmp.c +++ b/arch/arm/plat-versatile/platsmp.c @@ -32,7 +32,7 @@ static void write_pen_release(int val) @@ -393,7 +380,7 @@ index c2366510187a..6b60f582b738 100644 void versatile_secondary_init(unsigned int cpu) { -@@ -45,8 +45,8 @@ void versatile_secondary_init(unsigned int cpu) +@@ -45,8 +45,8 @@ void versatile_secondary_init(unsigned i /* * Synchronise with the boot thread. */ @@ -404,7 +391,7 @@ index c2366510187a..6b60f582b738 100644 } int versatile_boot_secondary(unsigned int cpu, struct task_struct *idle) -@@ -57,7 +57,7 @@ int versatile_boot_secondary(unsigned int cpu, struct task_struct *idle) +@@ -57,7 +57,7 @@ int versatile_boot_secondary(unsigned in * Set synchronisation state between this boot processor * and the secondary one */ @@ -413,7 +400,7 @@ index c2366510187a..6b60f582b738 100644 /* * This is really belt and braces; we hold unintended secondary -@@ -87,7 +87,7 @@ int versatile_boot_secondary(unsigned int cpu, struct task_struct *idle) +@@ -87,7 +87,7 @@ int versatile_boot_secondary(unsigned in * now the secondary core is starting up let it run its * calibrations, then wait for it to finish */ @@ -422,6 +409,3 @@ index c2366510187a..6b60f582b738 100644 return pen_release != -1 ? -ENOSYS : 0; } --- -2.19.2 - diff --git a/kernel/patches-4.14.x-rt/0426-x86-ioapic-Don-t-let-setaffinity-unmask-threaded-EOI.patch b/kernel/patches-4.19.x-rt/0013-x86-ioapic-Don-t-let-setaffinity-unmask-threaded-EOI.patch similarity index 72% rename from kernel/patches-4.14.x-rt/0426-x86-ioapic-Don-t-let-setaffinity-unmask-threaded-EOI.patch rename to kernel/patches-4.19.x-rt/0013-x86-ioapic-Don-t-let-setaffinity-unmask-threaded-EOI.patch index c648c6ab3..9206860a3 100644 --- a/kernel/patches-4.14.x-rt/0426-x86-ioapic-Don-t-let-setaffinity-unmask-threaded-EOI.patch +++ b/kernel/patches-4.19.x-rt/0013-x86-ioapic-Don-t-let-setaffinity-unmask-threaded-EOI.patch @@ -1,11 +1,8 @@ -From c7627c7bde5f3a171a7838b80b8e146e9deb79ae Mon Sep 17 00:00:00 2001 From: Thomas Gleixner -Date: Thu, 19 Jul 2018 21:50:23 +0200 -Subject: [PATCH 426/450] x86/ioapic: Don't let setaffinity unmask threaded EOI +Date: Tue, 17 Jul 2018 18:25:31 +0200 +Subject: [PATCH] x86/ioapic: Don't let setaffinity unmask threaded EOI interrupt too early -[ Upstream commit ac14002317721910204b82b9d8611dadb1cec2bb ] - There is an issue with threaded interrupts which are marked ONESHOT and using the fasteoi handler. @@ -28,19 +25,16 @@ The patch below should cure the issue. It also renames the horribly misnomed functions so it becomes clear what they are supposed to do. Signed-off-by: Thomas Gleixner -Signed-off-by: Steven Rostedt (VMware) [bigeasy: add the body of the patch, use the same functions in both ifdef paths (spotted by Andy Shevchenko)] Signed-off-by: Sebastian Andrzej Siewior --- - arch/x86/kernel/apic/io_apic.c | 26 ++++++++++++++------------ - 1 file changed, 14 insertions(+), 12 deletions(-) + arch/x86/kernel/apic/io_apic.c | 23 +++++++++++++---------- + 1 file changed, 13 insertions(+), 10 deletions(-) -diff --git a/arch/x86/kernel/apic/io_apic.c b/arch/x86/kernel/apic/io_apic.c -index 5832a9d657f2..c9af5afebc4a 100644 --- a/arch/x86/kernel/apic/io_apic.c +++ b/arch/x86/kernel/apic/io_apic.c -@@ -1688,20 +1688,20 @@ static bool io_apic_level_ack_pending(struct mp_chip_data *data) +@@ -1722,19 +1722,20 @@ static bool io_apic_level_ack_pending(st return false; } @@ -48,10 +42,8 @@ index 5832a9d657f2..c9af5afebc4a 100644 +static inline bool ioapic_prepare_move(struct irq_data *data) { /* If we are moving the irq we need to mask it */ -- if (unlikely(irqd_is_setaffinity_pending(data) && -- !irqd_irq_inprogress(data))) { + if (unlikely(irqd_is_setaffinity_pending(data))) { - mask_ioapic_irq(data); -+ if (unlikely(irqd_is_setaffinity_pending(data))) { + if (!irqd_irq_masked(data)) + mask_ioapic_irq(data); return true; @@ -67,7 +59,7 @@ index 5832a9d657f2..c9af5afebc4a 100644 /* Only migrate the irq if the ack has been received. * * On rare occasions the broadcast level triggered ack gets -@@ -1730,15 +1730,17 @@ static inline void ioapic_irqd_unmask(struct irq_data *data, bool masked) +@@ -1763,15 +1764,17 @@ static inline void ioapic_irqd_unmask(st */ if (!io_apic_level_ack_pending(data->chip_data)) irq_move_masked_irq(data); @@ -88,7 +80,7 @@ index 5832a9d657f2..c9af5afebc4a 100644 { } #endif -@@ -1747,11 +1749,11 @@ static void ioapic_ack_level(struct irq_data *irq_data) +@@ -1780,11 +1783,11 @@ static void ioapic_ack_level(struct irq_ { struct irq_cfg *cfg = irqd_cfg(irq_data); unsigned long v; @@ -102,7 +94,7 @@ index 5832a9d657f2..c9af5afebc4a 100644 /* * It appears there is an erratum which affects at least version 0x11 -@@ -1806,7 +1808,7 @@ static void ioapic_ack_level(struct irq_data *irq_data) +@@ -1839,7 +1842,7 @@ static void ioapic_ack_level(struct irq_ eoi_ioapic_pin(cfg->vector, irq_data->chip_data); } @@ -111,6 +103,3 @@ index 5832a9d657f2..c9af5afebc4a 100644 } static void ioapic_ir_ack_level(struct irq_data *irq_data) --- -2.19.2 - diff --git a/kernel/patches-4.14.x-rt/0127-arm-kprobe-replace-patch_lock-to-raw-lock.patch b/kernel/patches-4.19.x-rt/0014-arm-kprobe-replace-patch_lock-to-raw-lock.patch similarity index 84% rename from kernel/patches-4.14.x-rt/0127-arm-kprobe-replace-patch_lock-to-raw-lock.patch rename to kernel/patches-4.19.x-rt/0014-arm-kprobe-replace-patch_lock-to-raw-lock.patch index 35d71121d..9a0fa6413 100644 --- a/kernel/patches-4.14.x-rt/0127-arm-kprobe-replace-patch_lock-to-raw-lock.patch +++ b/kernel/patches-4.19.x-rt/0014-arm-kprobe-replace-patch_lock-to-raw-lock.patch @@ -1,7 +1,6 @@ -From e9331a157470378a4524092971a16d10c3e9fd64 Mon Sep 17 00:00:00 2001 From: Yang Shi Date: Thu, 10 Nov 2016 16:17:55 -0800 -Subject: [PATCH 127/450] arm: kprobe: replace patch_lock to raw lock +Subject: [PATCH] arm: kprobe: replace patch_lock to raw lock When running kprobe on -rt kernel, the below bug is caught: @@ -36,11 +35,9 @@ to raw lock. Signed-off-by: Yang Shi Signed-off-by: Sebastian Andrzej Siewior --- - arch/arm/kernel/patch.c | 6 +++--- + arch/arm/kernel/patch.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) -diff --git a/arch/arm/kernel/patch.c b/arch/arm/kernel/patch.c -index a50dc00d79a2..d0a05a3bdb96 100644 --- a/arch/arm/kernel/patch.c +++ b/arch/arm/kernel/patch.c @@ -16,7 +16,7 @@ struct patch { @@ -52,7 +49,7 @@ index a50dc00d79a2..d0a05a3bdb96 100644 static void __kprobes *patch_map(void *addr, int fixmap, unsigned long *flags) __acquires(&patch_lock) -@@ -33,7 +33,7 @@ static void __kprobes *patch_map(void *addr, int fixmap, unsigned long *flags) +@@ -33,7 +33,7 @@ static void __kprobes *patch_map(void *a return addr; if (flags) @@ -61,7 +58,7 @@ index a50dc00d79a2..d0a05a3bdb96 100644 else __acquire(&patch_lock); -@@ -48,7 +48,7 @@ static void __kprobes patch_unmap(int fixmap, unsigned long *flags) +@@ -48,7 +48,7 @@ static void __kprobes patch_unmap(int fi clear_fixmap(fixmap); if (flags) @@ -70,6 +67,3 @@ index a50dc00d79a2..d0a05a3bdb96 100644 else __release(&patch_lock); } --- -2.19.2 - diff --git a/kernel/patches-4.14.x-rt/0337-arm-unwind-use-a-raw_spin_lock.patch b/kernel/patches-4.19.x-rt/0015-arm-unwind-use_raw_lock.patch similarity index 75% rename from kernel/patches-4.14.x-rt/0337-arm-unwind-use-a-raw_spin_lock.patch rename to kernel/patches-4.19.x-rt/0015-arm-unwind-use_raw_lock.patch index b76a069ee..9c10dd91c 100644 --- a/kernel/patches-4.14.x-rt/0337-arm-unwind-use-a-raw_spin_lock.patch +++ b/kernel/patches-4.19.x-rt/0015-arm-unwind-use_raw_lock.patch @@ -1,7 +1,6 @@ -From 84c7064aa5cc108e31e9b32fbdb3c56d0d6c82b4 Mon Sep 17 00:00:00 2001 From: Sebastian Andrzej Siewior Date: Fri, 20 Sep 2013 14:31:54 +0200 -Subject: [PATCH 337/450] arm/unwind: use a raw_spin_lock +Subject: arm/unwind: use a raw_spin_lock Mostly unwind is done with irqs enabled however SLUB may call it with irqs disabled while creating a new SLUB cache. @@ -26,14 +25,12 @@ interrupts and then Signed-off-by: Sebastian Andrzej Siewior --- - arch/arm/kernel/unwind.c | 14 +++++++------- + arch/arm/kernel/unwind.c | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) -diff --git a/arch/arm/kernel/unwind.c b/arch/arm/kernel/unwind.c -index 0bee233fef9a..314cfb232a63 100644 --- a/arch/arm/kernel/unwind.c +++ b/arch/arm/kernel/unwind.c -@@ -93,7 +93,7 @@ extern const struct unwind_idx __start_unwind_idx[]; +@@ -93,7 +93,7 @@ extern const struct unwind_idx __start_u static const struct unwind_idx *__origin_unwind_idx; extern const struct unwind_idx __stop_unwind_idx[]; @@ -42,7 +39,7 @@ index 0bee233fef9a..314cfb232a63 100644 static LIST_HEAD(unwind_tables); /* Convert a prel31 symbol to an absolute address */ -@@ -201,7 +201,7 @@ static const struct unwind_idx *unwind_find_idx(unsigned long addr) +@@ -201,7 +201,7 @@ static const struct unwind_idx *unwind_f /* module unwind tables */ struct unwind_table *table; @@ -51,7 +48,7 @@ index 0bee233fef9a..314cfb232a63 100644 list_for_each_entry(table, &unwind_tables, list) { if (addr >= table->begin_addr && addr < table->end_addr) { -@@ -213,7 +213,7 @@ static const struct unwind_idx *unwind_find_idx(unsigned long addr) +@@ -213,7 +213,7 @@ static const struct unwind_idx *unwind_f break; } } @@ -60,7 +57,7 @@ index 0bee233fef9a..314cfb232a63 100644 } pr_debug("%s: idx = %p\n", __func__, idx); -@@ -529,9 +529,9 @@ struct unwind_table *unwind_table_add(unsigned long start, unsigned long size, +@@ -529,9 +529,9 @@ struct unwind_table *unwind_table_add(un tab->begin_addr = text_addr; tab->end_addr = text_addr + text_size; @@ -72,7 +69,7 @@ index 0bee233fef9a..314cfb232a63 100644 return tab; } -@@ -543,9 +543,9 @@ void unwind_table_del(struct unwind_table *tab) +@@ -543,9 +543,9 @@ void unwind_table_del(struct unwind_tabl if (!tab) return; @@ -84,6 +81,3 @@ index 0bee233fef9a..314cfb232a63 100644 kfree(tab); } --- -2.19.2 - diff --git a/kernel/patches-4.19.x-rt/0016-cgroup-use-irqsave-in-cgroup_rstat_flush_locked.patch b/kernel/patches-4.19.x-rt/0016-cgroup-use-irqsave-in-cgroup_rstat_flush_locked.patch new file mode 100644 index 000000000..92feca234 --- /dev/null +++ b/kernel/patches-4.19.x-rt/0016-cgroup-use-irqsave-in-cgroup_rstat_flush_locked.patch @@ -0,0 +1,43 @@ +From: Sebastian Andrzej Siewior +Date: Tue, 3 Jul 2018 18:19:48 +0200 +Subject: [PATCH] cgroup: use irqsave in cgroup_rstat_flush_locked() + +All callers of cgroup_rstat_flush_locked() acquire cgroup_rstat_lock +either with spin_lock_irq() or spin_lock_irqsave(). +cgroup_rstat_flush_locked() itself acquires cgroup_rstat_cpu_lock which +is a raw_spin_lock. This lock is also acquired in cgroup_rstat_updated() +in IRQ context and therefore requires _irqsave() locking suffix in +cgroup_rstat_flush_locked(). +Since there is no difference between spin_lock_t and raw_spin_lock_t +on !RT lockdep does not complain here. On RT lockdep complains because +the interrupts were not disabled here and a deadlock is possible. + +Acquire the raw_spin_lock_t with disabled interrupts. + +Signed-off-by: Sebastian Andrzej Siewior +--- + kernel/cgroup/rstat.c | 5 +++-- + 1 file changed, 3 insertions(+), 2 deletions(-) + +--- a/kernel/cgroup/rstat.c ++++ b/kernel/cgroup/rstat.c +@@ -157,8 +157,9 @@ static void cgroup_rstat_flush_locked(st + raw_spinlock_t *cpu_lock = per_cpu_ptr(&cgroup_rstat_cpu_lock, + cpu); + struct cgroup *pos = NULL; ++ unsigned long flags; + +- raw_spin_lock(cpu_lock); ++ raw_spin_lock_irqsave(cpu_lock, flags); + while ((pos = cgroup_rstat_cpu_pop_updated(pos, cgrp, cpu))) { + struct cgroup_subsys_state *css; + +@@ -170,7 +171,7 @@ static void cgroup_rstat_flush_locked(st + css->ss->css_rstat_flush(css, cpu); + rcu_read_unlock(); + } +- raw_spin_unlock(cpu_lock); ++ raw_spin_unlock_irqrestore(cpu_lock, flags); + + /* if @may_sleep, play nice and yield if necessary */ + if (may_sleep && (need_resched() || diff --git a/kernel/patches-4.19.x-rt/0017-fscache-initialize-cookie-hash-table-raw-spinlocks.patch b/kernel/patches-4.19.x-rt/0017-fscache-initialize-cookie-hash-table-raw-spinlocks.patch new file mode 100644 index 000000000..8dd59acf1 --- /dev/null +++ b/kernel/patches-4.19.x-rt/0017-fscache-initialize-cookie-hash-table-raw-spinlocks.patch @@ -0,0 +1,53 @@ +From: Clark Williams +Date: Tue, 3 Jul 2018 13:34:30 -0500 +Subject: [PATCH] fscache: initialize cookie hash table raw spinlocks + +The fscache cookie mechanism uses a hash table of hlist_bl_head structures. The +PREEMPT_RT patcheset adds a raw spinlock to this structure and so on PREEMPT_RT +the structures get used uninitialized, causing warnings about bad magic numbers +when spinlock debugging is turned on. + +Use the init function for fscache cookies. + +Signed-off-by: Clark Williams +Signed-off-by: Sebastian Andrzej Siewior +--- + fs/fscache/cookie.c | 8 ++++++++ + fs/fscache/main.c | 1 + + include/linux/fscache.h | 1 + + 3 files changed, 10 insertions(+) + +--- a/fs/fscache/cookie.c ++++ b/fs/fscache/cookie.c +@@ -962,3 +962,11 @@ int __fscache_check_consistency(struct f + return -ESTALE; + } + EXPORT_SYMBOL(__fscache_check_consistency); ++ ++void __init fscache_cookie_init(void) ++{ ++ int i; ++ ++ for (i = 0; i < (1 << fscache_cookie_hash_shift) - 1; i++) ++ INIT_HLIST_BL_HEAD(&fscache_cookie_hash[i]); ++} +--- a/fs/fscache/main.c ++++ b/fs/fscache/main.c +@@ -149,6 +149,7 @@ static int __init fscache_init(void) + ret = -ENOMEM; + goto error_cookie_jar; + } ++ fscache_cookie_init(); + + fscache_root = kobject_create_and_add("fscache", kernel_kobj); + if (!fscache_root) +--- a/include/linux/fscache.h ++++ b/include/linux/fscache.h +@@ -230,6 +230,7 @@ extern void __fscache_readpages_cancel(s + extern void __fscache_disable_cookie(struct fscache_cookie *, const void *, bool); + extern void __fscache_enable_cookie(struct fscache_cookie *, const void *, loff_t, + bool (*)(void *), void *); ++extern void fscache_cookie_init(void); + + /** + * fscache_register_netfs - Register a filesystem as desiring caching services diff --git a/kernel/patches-4.14.x-rt/0434-Drivers-hv-vmbus-include-header-for-get_irq_regs.patch b/kernel/patches-4.19.x-rt/0018-Drivers-hv-vmbus-include-header-for-get_irq_regs.patch similarity index 64% rename from kernel/patches-4.14.x-rt/0434-Drivers-hv-vmbus-include-header-for-get_irq_regs.patch rename to kernel/patches-4.19.x-rt/0018-Drivers-hv-vmbus-include-header-for-get_irq_regs.patch index b2fe4a625..9d5c1f0db 100644 --- a/kernel/patches-4.14.x-rt/0434-Drivers-hv-vmbus-include-header-for-get_irq_regs.patch +++ b/kernel/patches-4.19.x-rt/0018-Drivers-hv-vmbus-include-header-for-get_irq_regs.patch @@ -1,13 +1,10 @@ -From 8fd20e50ef3f7e79440646e5152d2070c2894059 Mon Sep 17 00:00:00 2001 From: Sebastian Andrzej Siewior Date: Wed, 29 Aug 2018 21:59:04 +0200 -Subject: [PATCH 434/450] Drivers: hv: vmbus: include header for get_irq_regs() +Subject: [PATCH] Drivers: hv: vmbus: include header for get_irq_regs() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit -[ Upstream commit b9fcc1867cc7921bb8441be327ed58461ed12255 ] - On !RT the header file get_irq_regs() gets pulled in via other header files. On RT it does not and the build fails: @@ -20,24 +17,17 @@ vmbus_drv.c by hv.c for their get_irq_regs() usage. Reported-by: Bernhard Landauer Reported-by: Ralf Ramsauer Signed-off-by: Sebastian Andrzej Siewior -Signed-off-by: Steven Rostedt (VMware) -Integrated-by: Tiejun Chen --- - drivers/hv/hyperv_vmbus.h | 1 + + drivers/hv/hyperv_vmbus.h | 1 + 1 file changed, 1 insertion(+) -diff --git a/drivers/hv/hyperv_vmbus.h b/drivers/hv/hyperv_vmbus.h -index 49569f8fe038..a3608cd52805 100644 --- a/drivers/hv/hyperv_vmbus.h +++ b/drivers/hv/hyperv_vmbus.h -@@ -26,6 +26,7 @@ - #define _HYPERV_VMBUS_H - - #include -+#include - #include +@@ -31,6 +31,7 @@ #include #include --- -2.19.2 - + #include ++#include + + #include "hv_trace.h" + diff --git a/kernel/patches-4.19.x-rt/0019-percpu-include-irqflags.h-for-raw_local_irq_save.patch b/kernel/patches-4.19.x-rt/0019-percpu-include-irqflags.h-for-raw_local_irq_save.patch new file mode 100644 index 000000000..86a018707 --- /dev/null +++ b/kernel/patches-4.19.x-rt/0019-percpu-include-irqflags.h-for-raw_local_irq_save.patch @@ -0,0 +1,26 @@ +From: Sebastian Andrzej Siewior +Date: Thu, 11 Oct 2018 16:39:59 +0200 +Subject: [PATCH] percpu: include irqflags.h for raw_local_irq_save() + +The header percpu.h header file is using raw_local_irq_save() but does +not include irqflags.h for its definition. It compiles because the +header file is included via an other header file. +On -RT the build fails because raw_local_irq_save() is not defined. + +Include irqflags.h in percpu.h. + +Signed-off-by: Sebastian Andrzej Siewior +--- + include/asm-generic/percpu.h | 1 + + 1 file changed, 1 insertion(+) + +--- a/include/asm-generic/percpu.h ++++ b/include/asm-generic/percpu.h +@@ -5,6 +5,7 @@ + #include + #include + #include ++#include + + #ifdef CONFIG_SMP + diff --git a/kernel/patches-4.14.x-rt/0427-efi-Allow-efi-runtime.patch b/kernel/patches-4.19.x-rt/0020-efi-Allow-efi-runtime.patch similarity index 55% rename from kernel/patches-4.14.x-rt/0427-efi-Allow-efi-runtime.patch rename to kernel/patches-4.19.x-rt/0020-efi-Allow-efi-runtime.patch index bf47acb62..5a3dfd3b4 100644 --- a/kernel/patches-4.14.x-rt/0427-efi-Allow-efi-runtime.patch +++ b/kernel/patches-4.19.x-rt/0020-efi-Allow-efi-runtime.patch @@ -1,24 +1,19 @@ -From 18fe30d8c5cba94eb27edfb01aa859bd05e8df12 Mon Sep 17 00:00:00 2001 From: Sebastian Andrzej Siewior Date: Thu, 26 Jul 2018 15:06:10 +0200 -Subject: [PATCH 427/450] efi: Allow efi=runtime - -[ Upstream commit 71bef7da4112ed2677d4f10a58202a5a4638fb90 ] +Subject: [PATCH] efi: Allow efi=runtime In case the option "efi=noruntime" is default at built-time, the user could overwrite its sate by `efi=runtime' and allow it again. +Acked-by: Ard Biesheuvel Signed-off-by: Sebastian Andrzej Siewior -Signed-off-by: Steven Rostedt (VMware) --- - drivers/firmware/efi/efi.c | 3 +++ + drivers/firmware/efi/efi.c | 3 +++ 1 file changed, 3 insertions(+) -diff --git a/drivers/firmware/efi/efi.c b/drivers/firmware/efi/efi.c -index c3eefa126e3b..9bd749389f31 100644 --- a/drivers/firmware/efi/efi.c +++ b/drivers/firmware/efi/efi.c -@@ -100,6 +100,9 @@ static int __init parse_efi_cmdline(char *str) +@@ -113,6 +113,9 @@ static int __init parse_efi_cmdline(char if (parse_option_str(str, "noruntime")) disable_runtime = true; @@ -28,6 +23,3 @@ index c3eefa126e3b..9bd749389f31 100644 return 0; } early_param("efi", parse_efi_cmdline); --- -2.19.2 - diff --git a/kernel/patches-4.19.x-rt/0021-x86-efi-drop-task_lock-from-efi_switch_mm.patch b/kernel/patches-4.19.x-rt/0021-x86-efi-drop-task_lock-from-efi_switch_mm.patch new file mode 100644 index 000000000..eec4cea4c --- /dev/null +++ b/kernel/patches-4.19.x-rt/0021-x86-efi-drop-task_lock-from-efi_switch_mm.patch @@ -0,0 +1,48 @@ +From: Sebastian Andrzej Siewior +Date: Tue, 24 Jul 2018 14:48:55 +0200 +Subject: [PATCH] x86/efi: drop task_lock() from efi_switch_mm() + +efi_switch_mm() is a wrapper around switch_mm() which saves current's +->active_mm, sets the requests mm as ->active_mm and invokes +switch_mm(). +I don't think that task_lock() is required during that procedure. It +protects ->mm which isn't changed here. + +It needs to be mentioned that during the whole procedure (switch to +EFI's mm and back) the preemption needs to be disabled. A context switch +at this point would reset the cr3 value based on current->mm. Also, this +function may not be invoked at the same time on a different CPU because +it would overwrite the efi_scratch.prev_mm information. + +Remove task_lock() and also update the comment to reflect it. + +Signed-off-by: Sebastian Andrzej Siewior +--- + arch/x86/platform/efi/efi_64.c | 10 ++++------ + 1 file changed, 4 insertions(+), 6 deletions(-) + +--- a/arch/x86/platform/efi/efi_64.c ++++ b/arch/x86/platform/efi/efi_64.c +@@ -619,18 +619,16 @@ void __init efi_dump_pagetable(void) + + /* + * Makes the calling thread switch to/from efi_mm context. Can be used +- * for SetVirtualAddressMap() i.e. current->active_mm == init_mm as well +- * as during efi runtime calls i.e current->active_mm == current_mm. +- * We are not mm_dropping()/mm_grabbing() any mm, because we are not +- * losing/creating any references. ++ * in a kernel thread and user context. Preemption needs to remain disabled ++ * while the EFI-mm is borrowed. mmgrab()/mmdrop() is not used because the mm ++ * can not change under us. ++ * It should be ensured that there are no concurent calls to this function. + */ + void efi_switch_mm(struct mm_struct *mm) + { +- task_lock(current); + efi_scratch.prev_mm = current->active_mm; + current->active_mm = mm; + switch_mm(efi_scratch.prev_mm, mm, NULL); +- task_unlock(current); + } + + #ifdef CONFIG_EFI_MIXED diff --git a/kernel/patches-4.19.x-rt/0022-arm64-KVM-compute_layout-before-altenates-are-applie.patch b/kernel/patches-4.19.x-rt/0022-arm64-KVM-compute_layout-before-altenates-are-applie.patch new file mode 100644 index 000000000..d3748a712 --- /dev/null +++ b/kernel/patches-4.19.x-rt/0022-arm64-KVM-compute_layout-before-altenates-are-applie.patch @@ -0,0 +1,71 @@ +From: Sebastian Andrzej Siewior +Date: Thu, 26 Jul 2018 09:13:42 +0200 +Subject: [PATCH] arm64: KVM: compute_layout before altenates are applied + +compute_layout() is invoked as part of an alternative fixup under +stop_machine() and needs a sleeping lock as part of get_random_long(). + +Invoke compute_layout() before the alternatives are applied. + +Signed-off-by: Sebastian Andrzej Siewior +--- + arch/arm64/include/asm/alternative.h | 6 ++++++ + arch/arm64/kernel/alternative.c | 1 + + arch/arm64/kvm/va_layout.c | 7 +------ + 3 files changed, 8 insertions(+), 6 deletions(-) + +--- a/arch/arm64/include/asm/alternative.h ++++ b/arch/arm64/include/asm/alternative.h +@@ -35,6 +35,12 @@ void apply_alternatives_module(void *sta + static inline void apply_alternatives_module(void *start, size_t length) { } + #endif + ++#ifdef CONFIG_KVM_ARM_HOST ++void kvm_compute_layout(void); ++#else ++static inline void kvm_compute_layout(void) { } ++#endif ++ + #define ALTINSTR_ENTRY(feature,cb) \ + " .word 661b - .\n" /* label */ \ + " .if " __stringify(cb) " == 0\n" \ +--- a/arch/arm64/kernel/alternative.c ++++ b/arch/arm64/kernel/alternative.c +@@ -224,6 +224,7 @@ static int __apply_alternatives_multi_st + void __init apply_alternatives_all(void) + { + /* better not try code patching on a live SMP system */ ++ kvm_compute_layout(); + stop_machine(__apply_alternatives_multi_stop, NULL, cpu_online_mask); + } + +--- a/arch/arm64/kvm/va_layout.c ++++ b/arch/arm64/kvm/va_layout.c +@@ -33,7 +33,7 @@ static u8 tag_lsb; + static u64 tag_val; + static u64 va_mask; + +-static void compute_layout(void) ++__init void kvm_compute_layout(void) + { + phys_addr_t idmap_addr = __pa_symbol(__hyp_idmap_text_start); + u64 hyp_va_msb; +@@ -121,8 +121,6 @@ void __init kvm_update_va_mask(struct al + + BUG_ON(nr_inst != 5); + +- if (!has_vhe() && !va_mask) +- compute_layout(); + + for (i = 0; i < nr_inst; i++) { + u32 rd, rn, insn, oinsn; +@@ -167,9 +165,6 @@ void kvm_patch_vector_branch(struct alt_ + return; + } + +- if (!va_mask) +- compute_layout(); +- + /* + * Compute HYP VA by using the same computation as kern_hyp_va() + */ diff --git a/kernel/patches-4.19.x-rt/0023-of-allocate-free-phandle-cache-outside-of-the-devtre.patch b/kernel/patches-4.19.x-rt/0023-of-allocate-free-phandle-cache-outside-of-the-devtre.patch new file mode 100644 index 000000000..8d14e1f77 --- /dev/null +++ b/kernel/patches-4.19.x-rt/0023-of-allocate-free-phandle-cache-outside-of-the-devtre.patch @@ -0,0 +1,95 @@ +From: Sebastian Andrzej Siewior +Date: Fri, 31 Aug 2018 14:16:30 +0200 +Subject: [PATCH] of: allocate / free phandle cache outside of the devtree_lock + +The phandle cache code allocates memory while holding devtree_lock which +is a raw_spinlock_t. Memory allocation (and free()) is not possible on +RT while a raw_spinlock_t is held. +Invoke the kfree() and kcalloc() while the lock is dropped. + +Cc: Rob Herring +Cc: Frank Rowand +Cc: devicetree@vger.kernel.org +Signed-off-by: Sebastian Andrzej Siewior +--- + drivers/of/base.c | 19 +++++++++++++------ + 1 file changed, 13 insertions(+), 6 deletions(-) + +--- a/drivers/of/base.c ++++ b/drivers/of/base.c +@@ -130,31 +130,34 @@ static u32 phandle_cache_mask; + /* + * Caller must hold devtree_lock. + */ +-static void __of_free_phandle_cache(void) ++static struct device_node** __of_free_phandle_cache(void) + { + u32 cache_entries = phandle_cache_mask + 1; + u32 k; ++ struct device_node **shadow; + + if (!phandle_cache) +- return; ++ return NULL; + + for (k = 0; k < cache_entries; k++) + of_node_put(phandle_cache[k]); + +- kfree(phandle_cache); ++ shadow = phandle_cache; + phandle_cache = NULL; ++ return shadow; + } + + int of_free_phandle_cache(void) + { + unsigned long flags; ++ struct device_node **shadow; + + raw_spin_lock_irqsave(&devtree_lock, flags); + +- __of_free_phandle_cache(); ++ shadow = __of_free_phandle_cache(); + + raw_spin_unlock_irqrestore(&devtree_lock, flags); +- ++ kfree(shadow); + return 0; + } + #if !defined(CONFIG_MODULES) +@@ -189,10 +192,11 @@ void of_populate_phandle_cache(void) + u32 cache_entries; + struct device_node *np; + u32 phandles = 0; ++ struct device_node **shadow; + + raw_spin_lock_irqsave(&devtree_lock, flags); + +- __of_free_phandle_cache(); ++ shadow = __of_free_phandle_cache(); + + for_each_of_allnodes(np) + if (np->phandle && np->phandle != OF_PHANDLE_ILLEGAL) +@@ -200,12 +204,14 @@ void of_populate_phandle_cache(void) + + if (!phandles) + goto out; ++ raw_spin_unlock_irqrestore(&devtree_lock, flags); + + cache_entries = roundup_pow_of_two(phandles); + phandle_cache_mask = cache_entries - 1; + + phandle_cache = kcalloc(cache_entries, sizeof(*phandle_cache), + GFP_ATOMIC); ++ raw_spin_lock_irqsave(&devtree_lock, flags); + if (!phandle_cache) + goto out; + +@@ -217,6 +223,7 @@ void of_populate_phandle_cache(void) + + out: + raw_spin_unlock_irqrestore(&devtree_lock, flags); ++ kfree(shadow); + } + + void __init of_core_init(void) diff --git a/kernel/patches-4.14.x-rt/0439-mm-kasan-make-quarantine_lock-a-raw_spinlock_t.patch b/kernel/patches-4.19.x-rt/0024-mm-kasan-make-quarantine_lock-a-raw_spinlock_t.patch similarity index 81% rename from kernel/patches-4.14.x-rt/0439-mm-kasan-make-quarantine_lock-a-raw_spinlock_t.patch rename to kernel/patches-4.19.x-rt/0024-mm-kasan-make-quarantine_lock-a-raw_spinlock_t.patch index ff606a23f..6172cac6f 100644 --- a/kernel/patches-4.14.x-rt/0439-mm-kasan-make-quarantine_lock-a-raw_spinlock_t.patch +++ b/kernel/patches-4.19.x-rt/0024-mm-kasan-make-quarantine_lock-a-raw_spinlock_t.patch @@ -1,9 +1,6 @@ -From 21a121fecc257eaa0769f9d71a6239ff27c5d285 Mon Sep 17 00:00:00 2001 From: Clark Williams Date: Tue, 18 Sep 2018 10:29:31 -0500 -Subject: [PATCH 439/450] mm/kasan: make quarantine_lock a raw_spinlock_t - -[ Upstream commit 089cb35faad5da57fa90399b230b3aee4920bb02 ] +Subject: [PATCH] mm/kasan: make quarantine_lock a raw_spinlock_t The static lock quarantine_lock is used in quarantine.c to protect the quarantine queue datastructures. It is taken inside quarantine queue @@ -19,13 +16,10 @@ the lock is held is limited. Signed-off-by: Clark Williams Signed-off-by: Sebastian Andrzej Siewior -Signed-off-by: Steven Rostedt (VMware) --- - mm/kasan/quarantine.c | 18 +++++++++--------- + mm/kasan/quarantine.c | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) -diff --git a/mm/kasan/quarantine.c b/mm/kasan/quarantine.c -index 3a8ddf8baf7d..b209dbaefde8 100644 --- a/mm/kasan/quarantine.c +++ b/mm/kasan/quarantine.c @@ -103,7 +103,7 @@ static int quarantine_head; @@ -37,7 +31,7 @@ index 3a8ddf8baf7d..b209dbaefde8 100644 DEFINE_STATIC_SRCU(remove_cache_srcu); /* Maximum size of the global queue. */ -@@ -190,7 +190,7 @@ void quarantine_put(struct kasan_free_meta *info, struct kmem_cache *cache) +@@ -190,7 +190,7 @@ void quarantine_put(struct kasan_free_me if (unlikely(q->bytes > QUARANTINE_PERCPU_SIZE)) { qlist_move_all(q, &temp); @@ -46,7 +40,7 @@ index 3a8ddf8baf7d..b209dbaefde8 100644 WRITE_ONCE(quarantine_size, quarantine_size + temp.bytes); qlist_move_all(&temp, &global_quarantine[quarantine_tail]); if (global_quarantine[quarantine_tail].bytes >= -@@ -203,7 +203,7 @@ void quarantine_put(struct kasan_free_meta *info, struct kmem_cache *cache) +@@ -203,7 +203,7 @@ void quarantine_put(struct kasan_free_me if (new_tail != quarantine_head) quarantine_tail = new_tail; } @@ -73,7 +67,7 @@ index 3a8ddf8baf7d..b209dbaefde8 100644 qlist_free_all(&to_free, NULL); srcu_read_unlock(&remove_cache_srcu, srcu_idx); -@@ -310,17 +310,17 @@ void quarantine_remove_cache(struct kmem_cache *cache) +@@ -310,17 +310,17 @@ void quarantine_remove_cache(struct kmem */ on_each_cpu(per_cpu_remove_cache, cache, 1); @@ -95,6 +89,3 @@ index 3a8ddf8baf7d..b209dbaefde8 100644 qlist_free_all(&to_free, cache); --- -2.19.2 - diff --git a/kernel/patches-4.19.x-rt/0025-EXP-rcu-Revert-expedited-GP-parallelization-cleverne.patch b/kernel/patches-4.19.x-rt/0025-EXP-rcu-Revert-expedited-GP-parallelization-cleverne.patch new file mode 100644 index 000000000..579a4c586 --- /dev/null +++ b/kernel/patches-4.19.x-rt/0025-EXP-rcu-Revert-expedited-GP-parallelization-cleverne.patch @@ -0,0 +1,43 @@ +From: Paul E. McKenney +Date: Mon, 29 Oct 2018 11:53:01 +0100 +Subject: [PATCH] EXP rcu: Revert expedited GP parallelization cleverness + +(Commit 258ba8e089db23f760139266c232f01bad73f85c from linux-rcu) + +This commit reverts a series of commits starting with fcc635436501 ("rcu: +Make expedited GPs handle CPU 0 being offline") and its successors, thus +queueing each rcu_node structure's expedited grace-period initialization +work on the first CPU of that rcu_node structure. + +Suggested-by: Sebastian Andrzej Siewior +Signed-off-by: Paul E. McKenney +Signed-off-by: Sebastian Andrzej Siewior +--- + kernel/rcu/tree_exp.h | 9 +-------- + 1 file changed, 1 insertion(+), 8 deletions(-) + +--- a/kernel/rcu/tree_exp.h ++++ b/kernel/rcu/tree_exp.h +@@ -472,7 +472,6 @@ static void sync_rcu_exp_select_node_cpu + static void sync_rcu_exp_select_cpus(struct rcu_state *rsp, + smp_call_func_t func) + { +- int cpu; + struct rcu_node *rnp; + + trace_rcu_exp_grace_period(rsp->name, rcu_exp_gp_seq_endval(rsp), TPS("reset")); +@@ -494,13 +493,7 @@ static void sync_rcu_exp_select_cpus(str + continue; + } + INIT_WORK(&rnp->rew.rew_work, sync_rcu_exp_select_node_cpus); +- preempt_disable(); +- cpu = cpumask_next(rnp->grplo - 1, cpu_online_mask); +- /* If all offline, queue the work on an unbound CPU. */ +- if (unlikely(cpu > rnp->grphi)) +- cpu = WORK_CPU_UNBOUND; +- queue_work_on(cpu, rcu_par_gp_wq, &rnp->rew.rew_work); +- preempt_enable(); ++ queue_work_on(rnp->grplo, rcu_par_gp_wq, &rnp->rew.rew_work); + rnp->exp_need_flush = true; + } + diff --git a/kernel/patches-4.14.x-rt/0448-kmemleak-Turn-kmemleak_lock-to-raw-spinlock-on-RT.patch b/kernel/patches-4.19.x-rt/0026-kmemleak-Turn-kmemleak_lock-to-raw-spinlock-on-RT.patch similarity index 81% rename from kernel/patches-4.14.x-rt/0448-kmemleak-Turn-kmemleak_lock-to-raw-spinlock-on-RT.patch rename to kernel/patches-4.19.x-rt/0026-kmemleak-Turn-kmemleak_lock-to-raw-spinlock-on-RT.patch index 41cfb9704..5f508352d 100644 --- a/kernel/patches-4.14.x-rt/0448-kmemleak-Turn-kmemleak_lock-to-raw-spinlock-on-RT.patch +++ b/kernel/patches-4.19.x-rt/0026-kmemleak-Turn-kmemleak_lock-to-raw-spinlock-on-RT.patch @@ -1,12 +1,6 @@ -From 655ba99fb534bbff254a2d739dbeeab01d56465e Mon Sep 17 00:00:00 2001 From: He Zhe Date: Wed, 19 Dec 2018 16:30:57 +0100 -Subject: [PATCH 448/450] kmemleak: Turn kmemleak_lock to raw spinlock on RT -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -[ Upstream commit 41cf9e5bb14fbbf782e4191b792d3b898c130469 ] +Subject: [PATCH] kmemleak: Turn kmemleak_lock to raw spinlock on RT kmemleak_lock, as a rwlock on RT, can possibly be held in atomic context and causes the follow BUG. @@ -75,13 +69,10 @@ Acked-by: Catalin Marinas Link: https://lkml.kernel.org/r/1542877459-144382-1-git-send-email-zhe.he@windriver.com Link: https://lkml.kernel.org/r/20181218150744.GB20197@arrakis.emea.arm.com Signed-off-by: Sebastian Andrzej Siewior -Signed-off-by: Steven Rostedt (VMware) --- - mm/kmemleak.c | 20 ++++++++++---------- + mm/kmemleak.c | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) -diff --git a/mm/kmemleak.c b/mm/kmemleak.c -index d9e0be2a8189..98876d2f17b5 100644 --- a/mm/kmemleak.c +++ b/mm/kmemleak.c @@ -26,7 +26,7 @@ @@ -93,7 +84,7 @@ index d9e0be2a8189..98876d2f17b5 100644 * accesses to the object_tree_root. The object_list is the main list * holding the metadata (struct kmemleak_object) for the allocated memory * blocks. The object_tree_root is a red black tree used to look-up -@@ -198,7 +198,7 @@ static LIST_HEAD(gray_list); +@@ -197,7 +197,7 @@ static LIST_HEAD(gray_list); /* search tree for object boundaries */ static struct rb_root object_tree_root = RB_ROOT; /* rw_lock protecting the access to object_list and object_tree_root */ @@ -102,7 +93,7 @@ index d9e0be2a8189..98876d2f17b5 100644 /* allocation caches for kmemleak internal data */ static struct kmem_cache *object_cache; -@@ -492,9 +492,9 @@ static struct kmemleak_object *find_and_get_object(unsigned long ptr, int alias) +@@ -491,9 +491,9 @@ static struct kmemleak_object *find_and_ struct kmemleak_object *object; rcu_read_lock(); @@ -114,7 +105,7 @@ index d9e0be2a8189..98876d2f17b5 100644 /* check whether the object is still available */ if (object && !get_object(object)) -@@ -514,13 +514,13 @@ static struct kmemleak_object *find_and_remove_object(unsigned long ptr, int ali +@@ -513,13 +513,13 @@ static struct kmemleak_object *find_and_ unsigned long flags; struct kmemleak_object *object; @@ -130,7 +121,7 @@ index d9e0be2a8189..98876d2f17b5 100644 return object; } -@@ -594,7 +594,7 @@ static struct kmemleak_object *create_object(unsigned long ptr, size_t size, +@@ -593,7 +593,7 @@ static struct kmemleak_object *create_ob /* kernel backtrace */ object->trace_len = __save_stack_trace(object->trace); @@ -139,7 +130,7 @@ index d9e0be2a8189..98876d2f17b5 100644 min_addr = min(min_addr, ptr); max_addr = max(max_addr, ptr + size); -@@ -625,7 +625,7 @@ static struct kmemleak_object *create_object(unsigned long ptr, size_t size, +@@ -624,7 +624,7 @@ static struct kmemleak_object *create_ob list_add_tail_rcu(&object->object_list, &object_list); out: @@ -148,7 +139,7 @@ index d9e0be2a8189..98876d2f17b5 100644 return object; } -@@ -1301,7 +1301,7 @@ static void scan_block(void *_start, void *_end, +@@ -1310,7 +1310,7 @@ static void scan_block(void *_start, voi unsigned long *end = _end - (BYTES_PER_POINTER - 1); unsigned long flags; @@ -157,7 +148,7 @@ index d9e0be2a8189..98876d2f17b5 100644 for (ptr = start; ptr < end; ptr++) { struct kmemleak_object *object; unsigned long pointer; -@@ -1358,7 +1358,7 @@ static void scan_block(void *_start, void *_end, +@@ -1367,7 +1367,7 @@ static void scan_block(void *_start, voi spin_unlock(&object->lock); } } @@ -166,6 +157,3 @@ index d9e0be2a8189..98876d2f17b5 100644 } /* --- -2.19.2 - diff --git a/kernel/patches-4.14.x-rt/0058-NFSv4-replace-seqcount_t-with-a-seqlock_t.patch b/kernel/patches-4.19.x-rt/0027-NFSv4-replace-seqcount_t-with-a-seqlock_t.patch similarity index 72% rename from kernel/patches-4.14.x-rt/0058-NFSv4-replace-seqcount_t-with-a-seqlock_t.patch rename to kernel/patches-4.19.x-rt/0027-NFSv4-replace-seqcount_t-with-a-seqlock_t.patch index e0bcd3cf9..002906141 100644 --- a/kernel/patches-4.14.x-rt/0058-NFSv4-replace-seqcount_t-with-a-seqlock_t.patch +++ b/kernel/patches-4.19.x-rt/0027-NFSv4-replace-seqcount_t-with-a-seqlock_t.patch @@ -1,7 +1,10 @@ -From 45a017ae2c5bb2548baa8a2848ac7d81c86dc757 Mon Sep 17 00:00:00 2001 -From: Sebastian Andrzej Siewior -Date: Fri, 28 Oct 2016 23:05:11 +0200 -Subject: [PATCH 058/450] NFSv4: replace seqcount_t with a seqlock_t +Date: Fri, 28 Oct 2016 23:05:11 +0200 +From: Sebastian Andrzej Siewior +To: Trond Myklebust +Cc: Anna Schumaker , + linux-nfs@vger.kernel.org, linux-kernel@vger.kernel.org, + tglx@linutronix.de +Subject: NFSv4: replace seqcount_t with a seqlock_t The raw_write_seqcount_begin() in nfs4_reclaim_open_state() bugs me because it maps to preempt_disable() in -RT which I can't have at this @@ -19,17 +22,15 @@ block readers). Reported-by: kernel test robot Signed-off-by: Sebastian Andrzej Siewior --- - fs/nfs/delegation.c | 4 ++-- - fs/nfs/nfs4_fs.h | 2 +- - fs/nfs/nfs4proc.c | 4 ++-- - fs/nfs/nfs4state.c | 22 ++++++++++++++++------ + fs/nfs/delegation.c | 4 ++-- + fs/nfs/nfs4_fs.h | 2 +- + fs/nfs/nfs4proc.c | 4 ++-- + fs/nfs/nfs4state.c | 22 ++++++++++++++++------ 4 files changed, 21 insertions(+), 11 deletions(-) -diff --git a/fs/nfs/delegation.c b/fs/nfs/delegation.c -index 606dd3871f66..fa41eb75b4d8 100644 --- a/fs/nfs/delegation.c +++ b/fs/nfs/delegation.c -@@ -150,11 +150,11 @@ static int nfs_delegation_claim_opens(struct inode *inode, +@@ -152,11 +152,11 @@ static int nfs_delegation_claim_opens(st sp = state->owner; /* Block nfs4_proc_unlck */ mutex_lock(&sp->so_delegreturn_mutex); @@ -43,11 +44,9 @@ index 606dd3871f66..fa41eb75b4d8 100644 err = -EAGAIN; mutex_unlock(&sp->so_delegreturn_mutex); put_nfs_open_context(ctx); -diff --git a/fs/nfs/nfs4_fs.h b/fs/nfs/nfs4_fs.h -index a73144b3cb8c..0c403d280b96 100644 --- a/fs/nfs/nfs4_fs.h +++ b/fs/nfs/nfs4_fs.h -@@ -112,7 +112,7 @@ struct nfs4_state_owner { +@@ -114,7 +114,7 @@ struct nfs4_state_owner { unsigned long so_flags; struct list_head so_states; struct nfs_seqid_counter so_seqid; @@ -56,20 +55,18 @@ index a73144b3cb8c..0c403d280b96 100644 struct mutex so_delegreturn_mutex; }; -diff --git a/fs/nfs/nfs4proc.c b/fs/nfs/nfs4proc.c -index a3b67d3b1dfb..4ce6ec109c2b 100644 --- a/fs/nfs/nfs4proc.c +++ b/fs/nfs/nfs4proc.c -@@ -2700,7 +2700,7 @@ static int _nfs4_open_and_get_state(struct nfs4_opendata *opendata, +@@ -2859,7 +2859,7 @@ static int _nfs4_open_and_get_state(stru unsigned int seq; int ret; - seq = raw_seqcount_begin(&sp->so_reclaim_seqcount); + seq = raw_seqcount_begin(&sp->so_reclaim_seqlock.seqcount); - ret = _nfs4_proc_open(opendata); + ret = _nfs4_proc_open(opendata, ctx); if (ret != 0) -@@ -2738,7 +2738,7 @@ static int _nfs4_open_and_get_state(struct nfs4_opendata *opendata, +@@ -2900,7 +2900,7 @@ static int _nfs4_open_and_get_state(stru if (d_inode(dentry) == state->inode) { nfs_inode_attach_open_context(ctx); @@ -77,12 +74,10 @@ index a3b67d3b1dfb..4ce6ec109c2b 100644 + if (read_seqretry(&sp->so_reclaim_seqlock, seq)) nfs4_schedule_stateid_recovery(server, state); } - out: -diff --git a/fs/nfs/nfs4state.c b/fs/nfs/nfs4state.c -index e1d88bca815e..c51bcc176026 100644 + --- a/fs/nfs/nfs4state.c +++ b/fs/nfs/nfs4state.c -@@ -494,7 +494,7 @@ nfs4_alloc_state_owner(struct nfs_server *server, +@@ -511,7 +511,7 @@ nfs4_alloc_state_owner(struct nfs_server nfs4_init_seqid_counter(&sp->so_seqid); atomic_set(&sp->so_count, 1); INIT_LIST_HEAD(&sp->so_lru); @@ -91,7 +86,7 @@ index e1d88bca815e..c51bcc176026 100644 mutex_init(&sp->so_delegreturn_mutex); return sp; } -@@ -1521,8 +1521,12 @@ static int nfs4_reclaim_open_state(struct nfs4_state_owner *sp, const struct nfs +@@ -1564,8 +1564,12 @@ static int nfs4_reclaim_open_state(struc * recovering after a network partition or a reboot from a * server that doesn't support a grace period. */ @@ -105,7 +100,7 @@ index e1d88bca815e..c51bcc176026 100644 restart: list_for_each_entry(state, &sp->so_states, open_states) { if (!test_and_clear_bit(ops->state_flag_bit, &state->flags)) -@@ -1591,14 +1595,20 @@ static int nfs4_reclaim_open_state(struct nfs4_state_owner *sp, const struct nfs +@@ -1652,14 +1656,20 @@ static int nfs4_reclaim_open_state(struc spin_lock(&sp->so_lock); goto restart; } @@ -130,6 +125,3 @@ index e1d88bca815e..c51bcc176026 100644 return status; } --- -2.19.2 - diff --git a/kernel/patches-4.14.x-rt/0068-kernel-sched-Provide-a-pointer-to-the-valid-CPU-mask.patch b/kernel/patches-4.19.x-rt/0028-kernel-sched-Provide-a-pointer-to-the-valid-CPU-mask.patch similarity index 64% rename from kernel/patches-4.14.x-rt/0068-kernel-sched-Provide-a-pointer-to-the-valid-CPU-mask.patch rename to kernel/patches-4.19.x-rt/0028-kernel-sched-Provide-a-pointer-to-the-valid-CPU-mask.patch index 2f0a789f8..18460630d 100644 --- a/kernel/patches-4.14.x-rt/0068-kernel-sched-Provide-a-pointer-to-the-valid-CPU-mask.patch +++ b/kernel/patches-4.19.x-rt/0028-kernel-sched-Provide-a-pointer-to-the-valid-CPU-mask.patch @@ -1,8 +1,6 @@ -From 48bcffa01b2e8a54e5b8fb0100dffce5f3864bea Mon Sep 17 00:00:00 2001 From: Sebastian Andrzej Siewior Date: Tue, 4 Apr 2017 12:50:16 +0200 -Subject: [PATCH 068/450] kernel: sched: Provide a pointer to the valid CPU - mask +Subject: [PATCH] kernel: sched: Provide a pointer to the valid CPU mask MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit @@ -58,37 +56,34 @@ Cc: Ingo Molnar Cc: Rafael J. Wysocki Signed-off-by: Sebastian Andrzej Siewior --- - arch/ia64/kernel/mca.c | 2 +- - arch/mips/include/asm/switch_to.h | 4 +-- - arch/mips/kernel/mips-mt-fpaff.c | 2 +- - arch/mips/kernel/traps.c | 6 ++-- - arch/powerpc/platforms/cell/spufs/sched.c | 2 +- - arch/tile/include/asm/setup.h | 2 +- - arch/tile/kernel/hardwall.c | 10 +++--- - drivers/infiniband/hw/hfi1/affinity.c | 6 ++-- - drivers/infiniband/hw/hfi1/sdma.c | 3 +- - drivers/infiniband/hw/qib/qib_file_ops.c | 7 ++-- - fs/proc/array.c | 4 +-- - include/linux/init_task.h | 3 +- - include/linux/sched.h | 5 +-- - kernel/cgroup/cpuset.c | 2 +- - kernel/fork.c | 3 +- - kernel/sched/core.c | 40 +++++++++++----------- - kernel/sched/cpudeadline.c | 4 +-- - kernel/sched/cpupri.c | 4 +-- - kernel/sched/deadline.c | 6 ++-- - kernel/sched/fair.c | 28 +++++++-------- - kernel/sched/rt.c | 4 +-- - kernel/trace/trace_hwlat.c | 2 +- - lib/smp_processor_id.c | 2 +- - samples/trace_events/trace-events-sample.c | 2 +- - 24 files changed, 77 insertions(+), 76 deletions(-) + arch/ia64/kernel/mca.c | 2 - + arch/mips/include/asm/switch_to.h | 4 +- + arch/mips/kernel/mips-mt-fpaff.c | 2 - + arch/mips/kernel/traps.c | 6 ++-- + arch/powerpc/platforms/cell/spufs/sched.c | 2 - + arch/x86/kernel/cpu/intel_rdt_pseudo_lock.c | 2 - + drivers/infiniband/hw/hfi1/affinity.c | 6 ++-- + drivers/infiniband/hw/hfi1/sdma.c | 3 -- + drivers/infiniband/hw/qib/qib_file_ops.c | 7 ++-- + fs/proc/array.c | 4 +- + include/linux/sched.h | 5 ++- + init/init_task.c | 3 +- + kernel/cgroup/cpuset.c | 2 - + kernel/fork.c | 2 + + kernel/sched/core.c | 40 ++++++++++++++-------------- + kernel/sched/cpudeadline.c | 4 +- + kernel/sched/cpupri.c | 4 +- + kernel/sched/deadline.c | 6 ++-- + kernel/sched/fair.c | 32 +++++++++++----------- + kernel/sched/rt.c | 4 +- + kernel/trace/trace_hwlat.c | 2 - + lib/smp_processor_id.c | 2 - + samples/trace_events/trace-events-sample.c | 2 - + 23 files changed, 74 insertions(+), 72 deletions(-) -diff --git a/arch/ia64/kernel/mca.c b/arch/ia64/kernel/mca.c -index 555b11180156..6866201a7603 100644 --- a/arch/ia64/kernel/mca.c +++ b/arch/ia64/kernel/mca.c -@@ -1824,7 +1824,7 @@ format_mca_init_stack(void *mca_data, unsigned long offset, +@@ -1824,7 +1824,7 @@ format_mca_init_stack(void *mca_data, un ti->cpu = cpu; p->stack = ti; p->state = TASK_UNINTERRUPTIBLE; @@ -97,8 +92,6 @@ index 555b11180156..6866201a7603 100644 INIT_LIST_HEAD(&p->tasks); p->parent = p->real_parent = p->group_leader = p; INIT_LIST_HEAD(&p->children); -diff --git a/arch/mips/include/asm/switch_to.h b/arch/mips/include/asm/switch_to.h -index e610473d61b8..1428b4febbc9 100644 --- a/arch/mips/include/asm/switch_to.h +++ b/arch/mips/include/asm/switch_to.h @@ -42,7 +42,7 @@ extern struct task_struct *ll_task; @@ -119,11 +112,9 @@ index e610473d61b8..1428b4febbc9 100644 } \ next->thread.emulated_fp = 0; \ } while(0) -diff --git a/arch/mips/kernel/mips-mt-fpaff.c b/arch/mips/kernel/mips-mt-fpaff.c -index a7c0f97e4b0d..1a08428eedcf 100644 --- a/arch/mips/kernel/mips-mt-fpaff.c +++ b/arch/mips/kernel/mips-mt-fpaff.c -@@ -177,7 +177,7 @@ asmlinkage long mipsmt_sys_sched_getaffinity(pid_t pid, unsigned int len, +@@ -177,7 +177,7 @@ asmlinkage long mipsmt_sys_sched_getaffi if (retval) goto out_unlock; @@ -132,11 +123,9 @@ index a7c0f97e4b0d..1a08428eedcf 100644 cpumask_and(&mask, &allowed, cpu_active_mask); out_unlock: -diff --git a/arch/mips/kernel/traps.c b/arch/mips/kernel/traps.c -index 583aed906933..24ad7aaca5eb 100644 --- a/arch/mips/kernel/traps.c +++ b/arch/mips/kernel/traps.c -@@ -1193,12 +1193,12 @@ static void mt_ase_fp_affinity(void) +@@ -1174,12 +1174,12 @@ static void mt_ase_fp_affinity(void) * restricted the allowed set to exclude any CPUs with FPUs, * we'll skip the procedure. */ @@ -152,11 +141,9 @@ index 583aed906933..24ad7aaca5eb 100644 &mt_fpu_cpumask); set_cpus_allowed_ptr(current, &tmask); set_thread_flag(TIF_FPUBOUND); -diff --git a/arch/powerpc/platforms/cell/spufs/sched.c b/arch/powerpc/platforms/cell/spufs/sched.c -index 1fbb5da17dd2..ca86366d5424 100644 --- a/arch/powerpc/platforms/cell/spufs/sched.c +++ b/arch/powerpc/platforms/cell/spufs/sched.c -@@ -141,7 +141,7 @@ void __spu_update_sched_info(struct spu_context *ctx) +@@ -141,7 +141,7 @@ void __spu_update_sched_info(struct spu_ * runqueue. The context will be rescheduled on the proper node * if it is timesliced or preempted. */ @@ -165,64 +152,20 @@ index 1fbb5da17dd2..ca86366d5424 100644 /* Save the current cpu id for spu interrupt routing. */ ctx->last_ran = raw_smp_processor_id(); -diff --git a/arch/tile/include/asm/setup.h b/arch/tile/include/asm/setup.h -index 2a0347af0702..670fa2f4cfc3 100644 ---- a/arch/tile/include/asm/setup.h -+++ b/arch/tile/include/asm/setup.h -@@ -49,7 +49,7 @@ int hardwall_ipi_valid(int cpu); - - /* Hook hardwall code into changes in affinity. */ - #define arch_set_cpus_allowed(p, new_mask) do { \ -- if (!cpumask_equal(&p->cpus_allowed, new_mask)) \ -+ if (!cpumask_equal(p->cpus_ptr, new_mask)) \ - hardwall_deactivate_all(p); \ - } while (0) - #endif -diff --git a/arch/tile/kernel/hardwall.c b/arch/tile/kernel/hardwall.c -index 2fd1694ac1d0..98f4fb696289 100644 ---- a/arch/tile/kernel/hardwall.c -+++ b/arch/tile/kernel/hardwall.c -@@ -590,12 +590,12 @@ static int hardwall_activate(struct hardwall_info *info) - * Get our affinity; if we're not bound to this tile uniquely, - * we can't access the network registers. +--- a/arch/x86/kernel/cpu/intel_rdt_pseudo_lock.c ++++ b/arch/x86/kernel/cpu/intel_rdt_pseudo_lock.c +@@ -1435,7 +1435,7 @@ static int pseudo_lock_dev_mmap(struct f + * may be scheduled elsewhere and invalidate entries in the + * pseudo-locked region. */ -- if (cpumask_weight(&p->cpus_allowed) != 1) -+ if (p->nr_cpus_allowed != 1) - return -EPERM; - - /* Make sure we are bound to a cpu assigned to this resource. */ - cpu = smp_processor_id(); -- BUG_ON(cpumask_first(&p->cpus_allowed) != cpu); -+ BUG_ON(cpumask_first(p->cpus_ptr) != cpu); - if (!cpumask_test_cpu(cpu, &info->cpumask)) +- if (!cpumask_subset(¤t->cpus_allowed, &plr->d->cpu_mask)) { ++ if (!cpumask_subset(current->cpus_ptr, &plr->d->cpu_mask)) { + mutex_unlock(&rdtgroup_mutex); return -EINVAL; - -@@ -621,17 +621,17 @@ static int hardwall_activate(struct hardwall_info *info) - * Deactivate a task's hardwall. Must hold lock for hardwall_type. - * This method may be called from exit_thread(), so we don't want to - * rely on too many fields of struct task_struct still being valid. -- * We assume the cpus_allowed, pid, and comm fields are still valid. -+ * We assume the nr_cpus_allowed, pid, and comm fields are still valid. - */ - static void _hardwall_deactivate(struct hardwall_type *hwt, - struct task_struct *task) - { - struct thread_struct *ts = &task->thread; - -- if (cpumask_weight(&task->cpus_allowed) != 1) { -+ if (task->nr_cpus_allowed != 1) { - pr_err("pid %d (%s) releasing %s hardwall with an affinity mask containing %d cpus!\n", - task->pid, task->comm, hwt->name, -- cpumask_weight(&task->cpus_allowed)); -+ task->nr_cpus_allowed); - BUG(); } - -diff --git a/drivers/infiniband/hw/hfi1/affinity.c b/drivers/infiniband/hw/hfi1/affinity.c -index b197e925fe36..95ac319c8e69 100644 --- a/drivers/infiniband/hw/hfi1/affinity.c +++ b/drivers/infiniband/hw/hfi1/affinity.c -@@ -593,7 +593,7 @@ int hfi1_get_proc_affinity(int node) +@@ -1037,7 +1037,7 @@ int hfi1_get_proc_affinity(int node) struct hfi1_affinity_node *entry; cpumask_var_t diff, hw_thread_mask, available_mask, intrs_mask; const struct cpumask *node_mask, @@ -231,7 +174,7 @@ index b197e925fe36..95ac319c8e69 100644 struct hfi1_affinity_node_list *affinity = &node_affinity; struct cpu_mask_set *set = &affinity->proc; -@@ -601,7 +601,7 @@ int hfi1_get_proc_affinity(int node) +@@ -1045,7 +1045,7 @@ int hfi1_get_proc_affinity(int node) * check whether process/context affinity has already * been set */ @@ -240,7 +183,7 @@ index b197e925fe36..95ac319c8e69 100644 hfi1_cdbg(PROC, "PID %u %s affinity set to CPU %*pbl", current->pid, current->comm, cpumask_pr_args(proc_mask)); -@@ -612,7 +612,7 @@ int hfi1_get_proc_affinity(int node) +@@ -1056,7 +1056,7 @@ int hfi1_get_proc_affinity(int node) cpu = cpumask_first(proc_mask); cpumask_set_cpu(cpu, &set->used); goto done; @@ -249,11 +192,9 @@ index b197e925fe36..95ac319c8e69 100644 hfi1_cdbg(PROC, "PID %u %s affinity set to CPU set(s) %*pbl", current->pid, current->comm, cpumask_pr_args(proc_mask)); -diff --git a/drivers/infiniband/hw/hfi1/sdma.c b/drivers/infiniband/hw/hfi1/sdma.c -index 6781bcdb10b3..d069ad261572 100644 --- a/drivers/infiniband/hw/hfi1/sdma.c +++ b/drivers/infiniband/hw/hfi1/sdma.c -@@ -856,14 +856,13 @@ struct sdma_engine *sdma_select_user_engine(struct hfi1_devdata *dd, +@@ -855,14 +855,13 @@ struct sdma_engine *sdma_select_user_eng { struct sdma_rht_node *rht_node; struct sdma_engine *sde = NULL; @@ -269,11 +210,9 @@ index 6781bcdb10b3..d069ad261572 100644 goto out; cpu_id = smp_processor_id(); -diff --git a/drivers/infiniband/hw/qib/qib_file_ops.c b/drivers/infiniband/hw/qib/qib_file_ops.c -index 40efc9151ec4..12924aad90cc 100644 --- a/drivers/infiniband/hw/qib/qib_file_ops.c +++ b/drivers/infiniband/hw/qib/qib_file_ops.c -@@ -1167,7 +1167,7 @@ static unsigned int qib_poll(struct file *fp, struct poll_table_struct *pt) +@@ -1142,7 +1142,7 @@ static __poll_t qib_poll(struct file *fp static void assign_ctxt_affinity(struct file *fp, struct qib_devdata *dd) { struct qib_filedata *fd = fp->private_data; @@ -282,7 +221,7 @@ index 40efc9151ec4..12924aad90cc 100644 const struct cpumask *local_mask = cpumask_of_pcibus(dd->pcidev->bus); int local_cpu; -@@ -1648,9 +1648,8 @@ static int qib_assign_ctxt(struct file *fp, const struct qib_user_info *uinfo) +@@ -1623,9 +1623,8 @@ static int qib_assign_ctxt(struct file * ret = find_free_ctxt(i_minor - 1, fp, uinfo); else { int unit; @@ -294,11 +233,9 @@ index 40efc9151ec4..12924aad90cc 100644 if (weight == 1 && !test_bit(cpu, qib_cpulist)) if (!find_hca(cpu, &unit) && unit >= 0) -diff --git a/fs/proc/array.c b/fs/proc/array.c -index 4ac811e1a26c..9dcb40690cde 100644 --- a/fs/proc/array.c +++ b/fs/proc/array.c -@@ -386,9 +386,9 @@ static inline void task_context_switch_counts(struct seq_file *m, +@@ -381,9 +381,9 @@ static inline void task_context_switch_c static void task_cpus_allowed(struct seq_file *m, struct task_struct *task) { seq_printf(m, "Cpus_allowed:\t%*pb\n", @@ -309,26 +246,10 @@ index 4ac811e1a26c..9dcb40690cde 100644 + cpumask_pr_args(task->cpus_ptr)); } - int proc_pid_status(struct seq_file *m, struct pid_namespace *ns, -diff --git a/include/linux/init_task.h b/include/linux/init_task.h -index 8062e6cc607c..53ee20e0b168 100644 ---- a/include/linux/init_task.h -+++ b/include/linux/init_task.h -@@ -234,7 +234,8 @@ extern struct cred init_cred; - .static_prio = MAX_PRIO-20, \ - .normal_prio = MAX_PRIO-20, \ - .policy = SCHED_NORMAL, \ -- .cpus_allowed = CPU_MASK_ALL, \ -+ .cpus_ptr = &tsk.cpus_mask, \ -+ .cpus_mask = CPU_MASK_ALL, \ - .nr_cpus_allowed= NR_CPUS, \ - .mm = NULL, \ - .active_mm = &init_mm, \ -diff --git a/include/linux/sched.h b/include/linux/sched.h -index 866439c361a9..7a8983b9880e 100644 + static inline void task_core_dumping(struct seq_file *m, struct mm_struct *mm) --- a/include/linux/sched.h +++ b/include/linux/sched.h -@@ -618,7 +618,8 @@ struct task_struct { +@@ -660,7 +660,8 @@ struct task_struct { unsigned int policy; int nr_cpus_allowed; @@ -338,7 +259,7 @@ index 866439c361a9..7a8983b9880e 100644 #ifdef CONFIG_PREEMPT_RCU int rcu_read_lock_nesting; -@@ -1355,7 +1356,7 @@ extern struct pid *cad_pid; +@@ -1390,7 +1391,7 @@ extern struct pid *cad_pid; #define PF_KTHREAD 0x00200000 /* I am a kernel thread */ #define PF_RANDOMIZE 0x00400000 /* Randomize virtual address space */ #define PF_SWAPWRITE 0x00800000 /* Allowed to write to swap */ @@ -347,11 +268,21 @@ index 866439c361a9..7a8983b9880e 100644 #define PF_MCE_EARLY 0x08000000 /* Early kill for mce process policy */ #define PF_MUTEX_TESTER 0x20000000 /* Thread belongs to the rt mutex tester */ #define PF_FREEZER_SKIP 0x40000000 /* Freezer should not count it as freezable */ -diff --git a/kernel/cgroup/cpuset.c b/kernel/cgroup/cpuset.c -index 4657e2924ecb..7bb7384b543a 100644 +--- a/init/init_task.c ++++ b/init/init_task.c +@@ -71,7 +71,8 @@ struct task_struct init_task + .static_prio = MAX_PRIO - 20, + .normal_prio = MAX_PRIO - 20, + .policy = SCHED_NORMAL, +- .cpus_allowed = CPU_MASK_ALL, ++ .cpus_ptr = &init_task.cpus_mask, ++ .cpus_mask = CPU_MASK_ALL, + .nr_cpus_allowed= NR_CPUS, + .mm = NULL, + .active_mm = &init_mm, --- a/kernel/cgroup/cpuset.c +++ b/kernel/cgroup/cpuset.c -@@ -2094,7 +2094,7 @@ static void cpuset_fork(struct task_struct *task) +@@ -2090,7 +2090,7 @@ static void cpuset_fork(struct task_stru if (task_css_is_root(task, cpuset_cgrp_id)) return; @@ -360,25 +291,20 @@ index 4657e2924ecb..7bb7384b543a 100644 task->mems_allowed = current->mems_allowed; } -diff --git a/kernel/fork.c b/kernel/fork.c -index 6a219fea4926..d45043432b17 100644 --- a/kernel/fork.c +++ b/kernel/fork.c -@@ -563,7 +563,8 @@ static struct task_struct *dup_task_struct(struct task_struct *orig, int node) - #ifdef CONFIG_CC_STACKPROTECTOR +@@ -845,6 +845,8 @@ static struct task_struct *dup_task_stru + #ifdef CONFIG_STACKPROTECTOR tsk->stack_canary = get_random_canary(); #endif -- + if (orig->cpus_ptr == &orig->cpus_mask) + tsk->cpus_ptr = &tsk->cpus_mask; + /* * One for us, one for whoever does the "release_task()" (usually - * parent) -diff --git a/kernel/sched/core.c b/kernel/sched/core.c -index 0552ddbb25e2..977b32a40784 100644 --- a/kernel/sched/core.c +++ b/kernel/sched/core.c -@@ -912,7 +912,7 @@ static inline bool is_per_cpu_kthread(struct task_struct *p) +@@ -876,7 +876,7 @@ static inline bool is_per_cpu_kthread(st */ static inline bool is_cpu_allowed(struct task_struct *p, int cpu) { @@ -387,7 +313,7 @@ index 0552ddbb25e2..977b32a40784 100644 return false; if (is_per_cpu_kthread(p)) -@@ -1007,7 +1007,7 @@ static int migration_cpu_stop(void *data) +@@ -971,7 +971,7 @@ static int migration_cpu_stop(void *data local_irq_disable(); /* * We need to explicitly wake pending tasks before running @@ -396,7 +322,7 @@ index 0552ddbb25e2..977b32a40784 100644 * during wakeups, see set_cpus_allowed_ptr()'s TASK_WAKING test. */ sched_ttwu_pending(); -@@ -1038,7 +1038,7 @@ static int migration_cpu_stop(void *data) +@@ -1002,7 +1002,7 @@ static int migration_cpu_stop(void *data */ void set_cpus_allowed_common(struct task_struct *p, const struct cpumask *new_mask) { @@ -405,7 +331,7 @@ index 0552ddbb25e2..977b32a40784 100644 p->nr_cpus_allowed = cpumask_weight(new_mask); } -@@ -1108,7 +1108,7 @@ static int __set_cpus_allowed_ptr(struct task_struct *p, +@@ -1072,7 +1072,7 @@ static int __set_cpus_allowed_ptr(struct goto out; } @@ -414,7 +340,7 @@ index 0552ddbb25e2..977b32a40784 100644 goto out; if (!cpumask_intersects(new_mask, cpu_valid_mask)) { -@@ -1269,10 +1269,10 @@ static int migrate_swap_stop(void *data) +@@ -1235,10 +1235,10 @@ static int migrate_swap_stop(void *data) if (task_cpu(arg->src_task) != arg->src_cpu) goto unlock; @@ -427,7 +353,7 @@ index 0552ddbb25e2..977b32a40784 100644 goto unlock; __migrate_swap_task(arg->src_task, arg->dst_cpu); -@@ -1313,10 +1313,10 @@ int migrate_swap(struct task_struct *cur, struct task_struct *p) +@@ -1280,10 +1280,10 @@ int migrate_swap(struct task_struct *cur if (!cpu_active(arg.src_cpu) || !cpu_active(arg.dst_cpu)) goto out; @@ -440,7 +366,7 @@ index 0552ddbb25e2..977b32a40784 100644 goto out; trace_sched_swap_numa(cur, arg.src_cpu, p, arg.dst_cpu); -@@ -1460,7 +1460,7 @@ void kick_process(struct task_struct *p) +@@ -1428,7 +1428,7 @@ void kick_process(struct task_struct *p) EXPORT_SYMBOL_GPL(kick_process); /* @@ -449,7 +375,7 @@ index 0552ddbb25e2..977b32a40784 100644 * * A few notes on cpu_active vs cpu_online: * -@@ -1500,14 +1500,14 @@ static int select_fallback_rq(int cpu, struct task_struct *p) +@@ -1468,14 +1468,14 @@ static int select_fallback_rq(int cpu, s for_each_cpu(dest_cpu, nodemask) { if (!cpu_active(dest_cpu)) continue; @@ -466,7 +392,7 @@ index 0552ddbb25e2..977b32a40784 100644 if (!is_cpu_allowed(p, dest_cpu)) continue; -@@ -1551,7 +1551,7 @@ static int select_fallback_rq(int cpu, struct task_struct *p) +@@ -1519,7 +1519,7 @@ static int select_fallback_rq(int cpu, s } /* @@ -475,7 +401,7 @@ index 0552ddbb25e2..977b32a40784 100644 */ static inline int select_task_rq(struct task_struct *p, int cpu, int sd_flags, int wake_flags) -@@ -1561,11 +1561,11 @@ int select_task_rq(struct task_struct *p, int cpu, int sd_flags, int wake_flags) +@@ -1529,11 +1529,11 @@ int select_task_rq(struct task_struct *p if (p->nr_cpus_allowed > 1) cpu = p->sched_class->select_task_rq(p, cpu, sd_flags, wake_flags); else @@ -489,7 +415,7 @@ index 0552ddbb25e2..977b32a40784 100644 * CPU. * * Since this is common to all placement strategies, this lives here. -@@ -2462,7 +2462,7 @@ void wake_up_new_task(struct task_struct *p) +@@ -2400,7 +2400,7 @@ void wake_up_new_task(struct task_struct #ifdef CONFIG_SMP /* * Fork balancing, do it here and not earlier because: @@ -498,7 +424,7 @@ index 0552ddbb25e2..977b32a40784 100644 * - any previously selected CPU might disappear through hotplug * * Use __set_task_cpu() to avoid calling sched_class::migrate_task_rq, -@@ -4164,7 +4164,7 @@ static int __sched_setscheduler(struct task_struct *p, +@@ -4273,7 +4273,7 @@ static int __sched_setscheduler(struct t * the entire root_domain to become SCHED_DEADLINE. We * will also fail if there's no bandwidth available. */ @@ -507,7 +433,7 @@ index 0552ddbb25e2..977b32a40784 100644 rq->rd->dl_bw.bw == 0) { task_rq_unlock(rq, p, &rf); return -EPERM; -@@ -4758,7 +4758,7 @@ long sched_getaffinity(pid_t pid, struct cpumask *mask) +@@ -4872,7 +4872,7 @@ long sched_getaffinity(pid_t pid, struct goto out_unlock; raw_spin_lock_irqsave(&p->pi_lock, flags); @@ -516,7 +442,7 @@ index 0552ddbb25e2..977b32a40784 100644 raw_spin_unlock_irqrestore(&p->pi_lock, flags); out_unlock: -@@ -5323,7 +5323,7 @@ int task_can_attach(struct task_struct *p, +@@ -5452,7 +5452,7 @@ int task_can_attach(struct task_struct * * allowed nodes is unnecessary. Thus, cpusets are not * applicable for such threads. This prevents checking for * success of set_cpus_allowed_ptr() on all attached tasks @@ -525,7 +451,7 @@ index 0552ddbb25e2..977b32a40784 100644 */ if (p->flags & PF_NO_SETAFFINITY) { ret = -EINVAL; -@@ -5350,7 +5350,7 @@ int migrate_task_to(struct task_struct *p, int target_cpu) +@@ -5479,7 +5479,7 @@ int migrate_task_to(struct task_struct * if (curr_cpu == target_cpu) return 0; @@ -534,7 +460,7 @@ index 0552ddbb25e2..977b32a40784 100644 return -EINVAL; /* TODO: This is not properly updating schedstats */ -@@ -5487,7 +5487,7 @@ static void migrate_tasks(struct rq *dead_rq, struct rq_flags *rf) +@@ -5617,7 +5617,7 @@ static void migrate_tasks(struct rq *dea put_prev_task(rq, next); /* @@ -543,11 +469,9 @@ index 0552ddbb25e2..977b32a40784 100644 * both pi_lock and rq->lock, such that holding either * stabilizes the mask. * -diff --git a/kernel/sched/cpudeadline.c b/kernel/sched/cpudeadline.c -index 8d9562d890d3..91a0702fe3df 100644 --- a/kernel/sched/cpudeadline.c +++ b/kernel/sched/cpudeadline.c -@@ -127,13 +127,13 @@ int cpudl_find(struct cpudl *cp, struct task_struct *p, +@@ -124,14 +124,14 @@ int cpudl_find(struct cpudl *cp, struct const struct sched_dl_entity *dl_se = &p->dl; if (later_mask && @@ -556,6 +480,7 @@ index 8d9562d890d3..91a0702fe3df 100644 return 1; } else { int best_cpu = cpudl_maximum(cp); + WARN_ON(best_cpu != -1 && !cpu_present(best_cpu)); - if (cpumask_test_cpu(best_cpu, &p->cpus_allowed) && @@ -563,11 +488,9 @@ index 8d9562d890d3..91a0702fe3df 100644 dl_time_before(dl_se->deadline, cp->elements[0].dl)) { if (later_mask) cpumask_set_cpu(best_cpu, later_mask); -diff --git a/kernel/sched/cpupri.c b/kernel/sched/cpupri.c -index 2511aba36b89..7b9bc1de0e6c 100644 --- a/kernel/sched/cpupri.c +++ b/kernel/sched/cpupri.c -@@ -103,11 +103,11 @@ int cpupri_find(struct cpupri *cp, struct task_struct *p, +@@ -98,11 +98,11 @@ int cpupri_find(struct cpupri *cp, struc if (skip) continue; @@ -581,20 +504,18 @@ index 2511aba36b89..7b9bc1de0e6c 100644 /* * We have to ensure that we have at least one bit -diff --git a/kernel/sched/deadline.c b/kernel/sched/deadline.c -index b2589c7e9439..7be1f4421cb8 100644 --- a/kernel/sched/deadline.c +++ b/kernel/sched/deadline.c -@@ -504,7 +504,7 @@ static struct rq *dl_task_offline_migration(struct rq *rq, struct task_struct *p +@@ -539,7 +539,7 @@ static struct rq *dl_task_offline_migrat * If we cannot preempt any rq, fall back to pick any - * online cpu. + * online CPU: */ - cpu = cpumask_any_and(cpu_active_mask, &p->cpus_allowed); + cpu = cpumask_any_and(cpu_active_mask, p->cpus_ptr); if (cpu >= nr_cpu_ids) { /* - * Fail to find any suitable cpu. -@@ -1753,7 +1753,7 @@ static void set_curr_task_dl(struct rq *rq) + * Failed to find any suitable CPU. +@@ -1824,7 +1824,7 @@ static void set_curr_task_dl(struct rq * static int pick_dl_task(struct rq *rq, struct task_struct *p, int cpu) { if (!task_running(rq, p) && @@ -603,7 +524,7 @@ index b2589c7e9439..7be1f4421cb8 100644 return 1; return 0; } -@@ -1903,7 +1903,7 @@ static struct rq *find_lock_later_rq(struct task_struct *task, struct rq *rq) +@@ -1974,7 +1974,7 @@ static struct rq *find_lock_later_rq(str /* Retry if something changed. */ if (double_lock_balance(rq, later_rq)) { if (unlikely(task_rq(task) != rq || @@ -612,20 +533,18 @@ index b2589c7e9439..7be1f4421cb8 100644 task_running(rq, task) || !dl_task(task) || !task_on_rq_queued(task))) { -diff --git a/kernel/sched/fair.c b/kernel/sched/fair.c -index 7240bb4a4090..304a7ebc7657 100644 --- a/kernel/sched/fair.c +++ b/kernel/sched/fair.c -@@ -1598,7 +1598,7 @@ static void task_numa_compare(struct task_numa_env *env, +@@ -1630,7 +1630,7 @@ static void task_numa_compare(struct tas + * be incurred if the tasks were swapped. */ - if (cur) { - /* Skip this swap candidate if cannot move to the source cpu */ -- if (!cpumask_test_cpu(env->src_cpu, &cur->cpus_allowed)) -+ if (!cpumask_test_cpu(env->src_cpu, cur->cpus_ptr)) - goto unlock; + /* Skip this swap candidate if cannot move to the source cpu */ +- if (!cpumask_test_cpu(env->src_cpu, &cur->cpus_allowed)) ++ if (!cpumask_test_cpu(env->src_cpu, cur->cpus_ptr)) + goto unlock; - /* -@@ -1708,7 +1708,7 @@ static void task_numa_find_cpu(struct task_numa_env *env, + /* +@@ -1727,7 +1727,7 @@ static void task_numa_find_cpu(struct ta for_each_cpu(cpu, cpumask_of_node(env->dst_nid)) { /* Skip this CPU if the source task cannot migrate */ @@ -634,7 +553,7 @@ index 7240bb4a4090..304a7ebc7657 100644 continue; env->dst_cpu = cpu; -@@ -5493,7 +5493,7 @@ find_idlest_group(struct sched_domain *sd, struct task_struct *p, +@@ -5712,7 +5712,7 @@ find_idlest_group(struct sched_domain *s /* Skip over this group if it has no CPUs allowed */ if (!cpumask_intersects(sched_group_span(group), @@ -643,16 +562,25 @@ index 7240bb4a4090..304a7ebc7657 100644 continue; local_group = cpumask_test_cpu(this_cpu, -@@ -5613,7 +5613,7 @@ find_idlest_cpu(struct sched_group *group, struct task_struct *p, int this_cpu) +@@ -5844,7 +5844,7 @@ find_idlest_group_cpu(struct sched_group return cpumask_first(sched_group_span(group)); /* Traverse only the allowed CPUs */ - for_each_cpu_and(i, sched_group_span(group), &p->cpus_allowed) { + for_each_cpu_and(i, sched_group_span(group), p->cpus_ptr) { - if (idle_cpu(i)) { + if (available_idle_cpu(i)) { struct rq *rq = cpu_rq(i); struct cpuidle_state *idle = idle_get_state(rq); -@@ -5716,7 +5716,7 @@ static int select_idle_core(struct task_struct *p, struct sched_domain *sd, int +@@ -5884,7 +5884,7 @@ static inline int find_idlest_cpu(struct + { + int new_cpu = cpu; + +- if (!cpumask_intersects(sched_domain_span(sd), &p->cpus_allowed)) ++ if (!cpumask_intersects(sched_domain_span(sd), p->cpus_ptr)) + return prev_cpu; + + /* +@@ -6001,7 +6001,7 @@ static int select_idle_core(struct task_ if (!test_idle_cores(target, false)) return -1; @@ -661,25 +589,34 @@ index 7240bb4a4090..304a7ebc7657 100644 for_each_cpu_wrap(core, cpus, target) { bool idle = true; -@@ -5750,7 +5750,7 @@ static int select_idle_smt(struct task_struct *p, struct sched_domain *sd, int t +@@ -6035,7 +6035,7 @@ static int select_idle_smt(struct task_s return -1; for_each_cpu(cpu, cpu_smt_mask(target)) { - if (!cpumask_test_cpu(cpu, &p->cpus_allowed)) + if (!cpumask_test_cpu(cpu, p->cpus_ptr)) continue; - if (idle_cpu(cpu)) + if (available_idle_cpu(cpu)) return cpu; -@@ -5813,7 +5813,7 @@ static int select_idle_cpu(struct task_struct *p, struct sched_domain *sd, int t +@@ -6098,7 +6098,7 @@ static int select_idle_cpu(struct task_s for_each_cpu_wrap(cpu, sched_domain_span(sd), target) { if (!--nr) return -1; - if (!cpumask_test_cpu(cpu, &p->cpus_allowed)) + if (!cpumask_test_cpu(cpu, p->cpus_ptr)) continue; - if (idle_cpu(cpu)) + if (available_idle_cpu(cpu)) break; -@@ -5968,7 +5968,7 @@ select_task_rq_fair(struct task_struct *p, int prev_cpu, int sd_flag, int wake_f +@@ -6135,7 +6135,7 @@ static int select_idle_sibling(struct ta + recent_used_cpu != target && + cpus_share_cache(recent_used_cpu, target) && + available_idle_cpu(recent_used_cpu) && +- cpumask_test_cpu(p->recent_used_cpu, &p->cpus_allowed)) { ++ cpumask_test_cpu(p->recent_used_cpu, p->cpus_ptr)) { + /* + * Replace recent_used_cpu with prev as it is a potential + * candidate for the next wake: +@@ -6353,7 +6353,7 @@ select_task_rq_fair(struct task_struct * if (sd_flag & SD_BALANCE_WAKE) { record_wakee(p); want_affine = !wake_wide(p) && !wake_cap(p, cpu, prev_cpu) @@ -688,7 +625,7 @@ index 7240bb4a4090..304a7ebc7657 100644 } rcu_read_lock(); -@@ -6717,14 +6717,14 @@ int can_migrate_task(struct task_struct *p, struct lb_env *env) +@@ -7092,14 +7092,14 @@ int can_migrate_task(struct task_struct /* * We do not migrate tasks that are: * 1) throttled_lb_pair, or @@ -705,25 +642,25 @@ index 7240bb4a4090..304a7ebc7657 100644 int cpu; schedstat_inc(p->se.statistics.nr_failed_migrations_affine); -@@ -6744,7 +6744,7 @@ int can_migrate_task(struct task_struct *p, struct lb_env *env) +@@ -7119,7 +7119,7 @@ int can_migrate_task(struct task_struct - /* Prevent to re-select dst_cpu via env's cpus */ + /* Prevent to re-select dst_cpu via env's CPUs: */ for_each_cpu_and(cpu, env->dst_grpmask, env->cpus) { - if (cpumask_test_cpu(cpu, &p->cpus_allowed)) { + if (cpumask_test_cpu(cpu, p->cpus_ptr)) { env->flags |= LBF_DST_PINNED; env->new_dst_cpu = cpu; break; -@@ -7313,7 +7313,7 @@ check_cpu_capacity(struct rq *rq, struct sched_domain *sd) +@@ -7716,7 +7716,7 @@ check_cpu_capacity(struct rq *rq, struct /* * Group imbalance indicates (and tries to solve) the problem where balancing - * groups is inadequate due to ->cpus_allowed constraints. + * groups is inadequate due to ->cpus_ptr constraints. * - * Imagine a situation of two groups of 4 cpus each and 4 tasks each with a - * cpumask covering 1 cpu of the first group and 3 cpus of the second group. -@@ -7889,7 +7889,7 @@ static struct sched_group *find_busiest_group(struct lb_env *env) + * Imagine a situation of two groups of 4 CPUs each and 4 tasks each with a + * cpumask covering 1 CPU of the first group and 3 CPUs of the second group. +@@ -8331,7 +8331,7 @@ static struct sched_group *find_busiest_ /* * If the busiest group is imbalanced the below checks don't * work because they assume all things are equal, which typically @@ -732,29 +669,27 @@ index 7240bb4a4090..304a7ebc7657 100644 */ if (busiest->group_type == group_imbalanced) goto force_balance; -@@ -8281,7 +8281,7 @@ static int load_balance(int this_cpu, struct rq *this_rq, - * if the curr task on busiest cpu can't be - * moved to this_cpu +@@ -8727,7 +8727,7 @@ static int load_balance(int this_cpu, st + * if the curr task on busiest CPU can't be + * moved to this_cpu: */ - if (!cpumask_test_cpu(this_cpu, &busiest->curr->cpus_allowed)) { + if (!cpumask_test_cpu(this_cpu, busiest->curr->cpus_ptr)) { raw_spin_unlock_irqrestore(&busiest->lock, flags); env.flags |= LBF_ALL_PINNED; -diff --git a/kernel/sched/rt.c b/kernel/sched/rt.c -index cb9a5b8532fa..fbe1aa2bb948 100644 --- a/kernel/sched/rt.c +++ b/kernel/sched/rt.c -@@ -1596,7 +1596,7 @@ static void put_prev_task_rt(struct rq *rq, struct task_struct *p) +@@ -1611,7 +1611,7 @@ static void put_prev_task_rt(struct rq * static int pick_rt_task(struct rq *rq, struct task_struct *p, int cpu) { if (!task_running(rq, p) && - cpumask_test_cpu(cpu, &p->cpus_allowed)) + cpumask_test_cpu(cpu, p->cpus_ptr)) return 1; + return 0; - } -@@ -1731,7 +1731,7 @@ static struct rq *find_lock_lowest_rq(struct task_struct *task, struct rq *rq) +@@ -1748,7 +1748,7 @@ static struct rq *find_lock_lowest_rq(st * Also make sure that it wasn't scheduled on its rq. */ if (unlikely(task_rq(task) != rq || @@ -763,11 +698,9 @@ index cb9a5b8532fa..fbe1aa2bb948 100644 task_running(rq, task) || !rt_task(task) || !task_on_rq_queued(task))) { -diff --git a/kernel/trace/trace_hwlat.c b/kernel/trace/trace_hwlat.c -index d7c8e4ec3d9d..518c61a1bceb 100644 --- a/kernel/trace/trace_hwlat.c +++ b/kernel/trace/trace_hwlat.c -@@ -279,7 +279,7 @@ static void move_to_next_cpu(void) +@@ -277,7 +277,7 @@ static void move_to_next_cpu(void) * of this thread, than stop migrating for the duration * of the current test. */ @@ -776,11 +709,9 @@ index d7c8e4ec3d9d..518c61a1bceb 100644 goto disable; get_online_cpus(); -diff --git a/lib/smp_processor_id.c b/lib/smp_processor_id.c -index 835cc6df2776..6f4a4ae881c8 100644 --- a/lib/smp_processor_id.c +++ b/lib/smp_processor_id.c -@@ -23,7 +23,7 @@ notrace static unsigned int check_preemption_disabled(const char *what1, +@@ -22,7 +22,7 @@ notrace static unsigned int check_preemp * Kernel threads bound to a single CPU can safely use * smp_processor_id(): */ @@ -789,8 +720,6 @@ index 835cc6df2776..6f4a4ae881c8 100644 goto out; /* -diff --git a/samples/trace_events/trace-events-sample.c b/samples/trace_events/trace-events-sample.c -index 5522692100ba..8b4be8e1802a 100644 --- a/samples/trace_events/trace-events-sample.c +++ b/samples/trace_events/trace-events-sample.c @@ -33,7 +33,7 @@ static void simple_thread_func(int cnt) @@ -802,6 +731,3 @@ index 5522692100ba..8b4be8e1802a 100644 trace_foo_with_template_simple("HELLO", cnt); --- -2.19.2 - diff --git a/kernel/patches-4.14.x-rt/0069-kernel-sched-core-add-migrate_disable.patch b/kernel/patches-4.19.x-rt/0029-add_migrate_disable.patch similarity index 79% rename from kernel/patches-4.14.x-rt/0069-kernel-sched-core-add-migrate_disable.patch rename to kernel/patches-4.19.x-rt/0029-add_migrate_disable.patch index abe709e45..144e7c0a8 100644 --- a/kernel/patches-4.14.x-rt/0069-kernel-sched-core-add-migrate_disable.patch +++ b/kernel/patches-4.19.x-rt/0029-add_migrate_disable.patch @@ -1,18 +1,15 @@ -From 79690d62718a5e83b3d7fce3f4939d55b961812a Mon Sep 17 00:00:00 2001 From: Sebastian Andrzej Siewior Date: Sat, 27 May 2017 19:02:06 +0200 -Subject: [PATCH 069/450] kernel/sched/core: add migrate_disable() +Subject: kernel/sched/core: add migrate_disable() --- - include/linux/preempt.h | 23 +++++++ - include/linux/sched.h | 7 +++ - include/linux/smp.h | 3 + - kernel/sched/core.c | 130 +++++++++++++++++++++++++++++++++++++++- - kernel/sched/debug.c | 4 ++ + include/linux/preempt.h | 23 ++++++++ + include/linux/sched.h | 7 ++ + include/linux/smp.h | 3 + + kernel/sched/core.c | 130 +++++++++++++++++++++++++++++++++++++++++++++++- + kernel/sched/debug.c | 4 + 5 files changed, 165 insertions(+), 2 deletions(-) -diff --git a/include/linux/preempt.h b/include/linux/preempt.h -index 5bd3f151da78..81c69aeab662 100644 --- a/include/linux/preempt.h +++ b/include/linux/preempt.h @@ -185,6 +185,22 @@ do { \ @@ -52,11 +49,9 @@ index 5bd3f151da78..81c69aeab662 100644 #endif /* CONFIG_PREEMPT_COUNT */ #ifdef MODULE -diff --git a/include/linux/sched.h b/include/linux/sched.h -index 7a8983b9880e..b0390902a36f 100644 --- a/include/linux/sched.h +++ b/include/linux/sched.h -@@ -620,6 +620,13 @@ struct task_struct { +@@ -662,6 +662,13 @@ struct task_struct { int nr_cpus_allowed; const cpumask_t *cpus_ptr; cpumask_t cpus_mask; @@ -70,8 +65,6 @@ index 7a8983b9880e..b0390902a36f 100644 #ifdef CONFIG_PREEMPT_RCU int rcu_read_lock_nesting; -diff --git a/include/linux/smp.h b/include/linux/smp.h -index 9fb239e12b82..5801e516ba63 100644 --- a/include/linux/smp.h +++ b/include/linux/smp.h @@ -202,6 +202,9 @@ static inline int get_boot_cpu_id(void) @@ -84,11 +77,9 @@ index 9fb239e12b82..5801e516ba63 100644 /* * Callback to arch code if there's nosmp or maxcpus=0 on the * boot command line: -diff --git a/kernel/sched/core.c b/kernel/sched/core.c -index 977b32a40784..590a3a396048 100644 --- a/kernel/sched/core.c +++ b/kernel/sched/core.c -@@ -1042,7 +1042,15 @@ void set_cpus_allowed_common(struct task_struct *p, const struct cpumask *new_ma +@@ -1006,7 +1006,15 @@ void set_cpus_allowed_common(struct task p->nr_cpus_allowed = cpumask_weight(new_mask); } @@ -105,7 +96,7 @@ index 977b32a40784..590a3a396048 100644 { struct rq *rq = task_rq(p); bool queued, running; -@@ -1071,6 +1079,20 @@ void do_set_cpus_allowed(struct task_struct *p, const struct cpumask *new_mask) +@@ -1035,6 +1043,20 @@ void do_set_cpus_allowed(struct task_str set_curr_task(rq, p); } @@ -126,7 +117,7 @@ index 977b32a40784..590a3a396048 100644 /* * Change a given task's CPU affinity. Migrate the thread to a * proper CPU and schedule it away if the CPU it's executing on -@@ -1129,9 +1151,16 @@ static int __set_cpus_allowed_ptr(struct task_struct *p, +@@ -1093,9 +1115,16 @@ static int __set_cpus_allowed_ptr(struct } /* Can the task run on the task's current CPU? If so, we're done */ @@ -144,10 +135,10 @@ index 977b32a40784..590a3a396048 100644 dest_cpu = cpumask_any_and(cpu_valid_mask, new_mask); if (task_running(rq, p) || p->state == TASK_WAKING) { struct migration_arg arg = { p, dest_cpu }; -@@ -6762,3 +6791,100 @@ const u32 sched_prio_to_wmult[40] = { - /* 10 */ 39045157, 49367440, 61356676, 76695844, 95443717, - /* 15 */ 119304647, 148102320, 186737708, 238609294, 286331153, +@@ -7058,3 +7087,100 @@ const u32 sched_prio_to_wmult[40] = { }; + + #undef CREATE_TRACE_POINTS + +#if defined(CONFIG_PREEMPT_COUNT) && defined(CONFIG_SMP) + @@ -245,11 +236,9 @@ index 977b32a40784..590a3a396048 100644 +} +EXPORT_SYMBOL(migrate_enable); +#endif -diff --git a/kernel/sched/debug.c b/kernel/sched/debug.c -index 2f93e4a2d9f6..3108da1ee253 100644 --- a/kernel/sched/debug.c +++ b/kernel/sched/debug.c -@@ -1017,6 +1017,10 @@ void proc_sched_show_task(struct task_struct *p, struct pid_namespace *ns, +@@ -978,6 +978,10 @@ void proc_sched_show_task(struct task_st P(dl.runtime); P(dl.deadline); } @@ -260,6 +249,3 @@ index 2f93e4a2d9f6..3108da1ee253 100644 #undef PN_SCHEDSTAT #undef PN #undef __PN --- -2.19.2 - diff --git a/kernel/patches-4.14.x-rt/0441-sched-migrate_disable-Add-export_symbol_gpl-for-__mi.patch b/kernel/patches-4.19.x-rt/0030-sched-migrate_disable-Add-export_symbol_gpl-for-__mi.patch similarity index 67% rename from kernel/patches-4.14.x-rt/0441-sched-migrate_disable-Add-export_symbol_gpl-for-__mi.patch rename to kernel/patches-4.19.x-rt/0030-sched-migrate_disable-Add-export_symbol_gpl-for-__mi.patch index 5f824009d..274c8a0af 100644 --- a/kernel/patches-4.14.x-rt/0441-sched-migrate_disable-Add-export_symbol_gpl-for-__mi.patch +++ b/kernel/patches-4.19.x-rt/0030-sched-migrate_disable-Add-export_symbol_gpl-for-__mi.patch @@ -1,11 +1,8 @@ -From cf1c4cbecd84912e31ed592111f1a77ed54cc22f Mon Sep 17 00:00:00 2001 From: Sebastian Andrzej Siewior Date: Tue, 9 Oct 2018 17:34:50 +0200 -Subject: [PATCH 441/450] sched/migrate_disable: Add export_symbol_gpl for +Subject: [PATCH] sched/migrate_disable: Add export_symbol_gpl for __migrate_disabled -[ Upstream commit c0f0dd3ced7abe307d8e89477dae2929e488ba6c ] - Jonathan reported that lttng/modules can't use __migrate_disabled(). This function is only used by sched/core itself and the tracing infrastructure to report the migrate counter (lttng does probably the @@ -18,16 +15,13 @@ EXPORT_SYMBOL_GPL to allow the module/LTTNG usage. Reported-by: Jonathan Rajott Signed-off-by: Sebastian Andrzej Siewior -Signed-off-by: Steven Rostedt (VMware) --- - kernel/sched/core.c | 1 + + kernel/sched/core.c | 1 + 1 file changed, 1 insertion(+) -diff --git a/kernel/sched/core.c b/kernel/sched/core.c -index 6ce950f24a7f..7c960cf07e7b 100644 --- a/kernel/sched/core.c +++ b/kernel/sched/core.c -@@ -1112,6 +1112,7 @@ int __migrate_disabled(struct task_struct *p) +@@ -1011,6 +1011,7 @@ int __migrate_disabled(struct task_struc { return p->migrate_disable; } @@ -35,6 +29,3 @@ index 6ce950f24a7f..7c960cf07e7b 100644 #endif static void __do_set_cpus_allowed_tail(struct task_struct *p, --- -2.19.2 - diff --git a/kernel/patches-4.14.x-rt/0051-arm-at91-do-not-disable-enable-clocks-in-a-row.patch b/kernel/patches-4.19.x-rt/0031-at91_dont_enable_disable_clock.patch similarity index 74% rename from kernel/patches-4.14.x-rt/0051-arm-at91-do-not-disable-enable-clocks-in-a-row.patch rename to kernel/patches-4.19.x-rt/0031-at91_dont_enable_disable_clock.patch index f016c8c2c..417e2e792 100644 --- a/kernel/patches-4.14.x-rt/0051-arm-at91-do-not-disable-enable-clocks-in-a-row.patch +++ b/kernel/patches-4.19.x-rt/0031-at91_dont_enable_disable_clock.patch @@ -1,7 +1,6 @@ -From 3855ee73c8b0f26ecb2bedd2c28351c38d3882ab Mon Sep 17 00:00:00 2001 From: Sebastian Andrzej Siewior -Date: Wed, 9 Mar 2016 10:51:06 +0100 -Subject: [PATCH 051/450] arm: at91: do not disable/enable clocks in a row +Date: Wed, 09 Mar 2016 10:51:06 +0100 +Subject: arm: at91: do not disable/enable clocks in a row Currently the driver will disable the clock and enable it one line later if it is switching from periodic mode into one shot. @@ -9,11 +8,9 @@ This can be avoided and causes a needless warning on -RT. Signed-off-by: Sebastian Andrzej Siewior --- - drivers/clocksource/tcb_clksrc.c | 33 ++++++++++++++++++++++++++++---- + drivers/clocksource/tcb_clksrc.c | 33 +++++++++++++++++++++++++++++---- 1 file changed, 29 insertions(+), 4 deletions(-) -diff --git a/drivers/clocksource/tcb_clksrc.c b/drivers/clocksource/tcb_clksrc.c -index 9de47d4d2d9e..4f45be268e52 100644 --- a/drivers/clocksource/tcb_clksrc.c +++ b/drivers/clocksource/tcb_clksrc.c @@ -126,6 +126,7 @@ static struct clocksource clksrc = { @@ -24,7 +21,7 @@ index 9de47d4d2d9e..4f45be268e52 100644 void __iomem *regs; }; -@@ -143,6 +144,24 @@ static struct tc_clkevt_device *to_tc_clkevt(struct clock_event_device *clkevt) +@@ -143,6 +144,24 @@ static struct tc_clkevt_device *to_tc_cl */ static u32 timer_clock; @@ -49,7 +46,7 @@ index 9de47d4d2d9e..4f45be268e52 100644 static int tc_shutdown(struct clock_event_device *d) { struct tc_clkevt_device *tcd = to_tc_clkevt(d); -@@ -150,8 +169,14 @@ static int tc_shutdown(struct clock_event_device *d) +@@ -150,8 +169,14 @@ static int tc_shutdown(struct clock_even writel(0xff, regs + ATMEL_TC_REG(2, IDR)); writel(ATMEL_TC_CLKDIS, regs + ATMEL_TC_REG(2, CCR)); @@ -65,7 +62,7 @@ index 9de47d4d2d9e..4f45be268e52 100644 return 0; } -@@ -164,7 +189,7 @@ static int tc_set_oneshot(struct clock_event_device *d) +@@ -164,7 +189,7 @@ static int tc_set_oneshot(struct clock_e if (clockevent_state_oneshot(d) || clockevent_state_periodic(d)) tc_shutdown(d); @@ -74,7 +71,7 @@ index 9de47d4d2d9e..4f45be268e52 100644 /* slow clock, count up to RC, then irq and stop */ writel(timer_clock | ATMEL_TC_CPCSTOP | ATMEL_TC_WAVE | -@@ -186,7 +211,7 @@ static int tc_set_periodic(struct clock_event_device *d) +@@ -186,7 +211,7 @@ static int tc_set_periodic(struct clock_ /* By not making the gentime core emulate periodic mode on top * of oneshot, we get lower overhead and improved accuracy. */ @@ -83,7 +80,7 @@ index 9de47d4d2d9e..4f45be268e52 100644 /* slow clock, count up to RC, then irq and restart */ writel(timer_clock | ATMEL_TC_WAVE | ATMEL_TC_WAVESEL_UP_AUTO, -@@ -220,7 +245,7 @@ static struct tc_clkevt_device clkevt = { +@@ -220,7 +245,7 @@ static struct tc_clkevt_device clkevt = /* Should be lower than at91rm9200's system timer */ .rating = 125, .set_next_event = tc_next_event, @@ -92,6 +89,3 @@ index 9de47d4d2d9e..4f45be268e52 100644 .set_state_periodic = tc_set_periodic, .set_state_oneshot = tc_set_oneshot, }, --- -2.19.2 - diff --git a/kernel/patches-4.14.x-rt/0133-clocksource-TCLIB-Allow-higher-clock-rates-for-clock.patch b/kernel/patches-4.19.x-rt/0032-clocksource-tclib-allow-higher-clockrates.patch similarity index 79% rename from kernel/patches-4.14.x-rt/0133-clocksource-TCLIB-Allow-higher-clock-rates-for-clock.patch rename to kernel/patches-4.19.x-rt/0032-clocksource-tclib-allow-higher-clockrates.patch index 87decb679..8fba8081a 100644 --- a/kernel/patches-4.14.x-rt/0133-clocksource-TCLIB-Allow-higher-clock-rates-for-clock.patch +++ b/kernel/patches-4.19.x-rt/0032-clocksource-tclib-allow-higher-clockrates.patch @@ -1,11 +1,6 @@ -From 529e93f4547812493d1b1cd7add36cf38d43ee8c Mon Sep 17 00:00:00 2001 From: Benedikt Spranger Date: Mon, 8 Mar 2010 18:57:04 +0100 -Subject: [PATCH 133/450] clocksource: TCLIB: Allow higher clock rates for - clock events -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit +Subject: clocksource: TCLIB: Allow higher clock rates for clock events As default the TCLIB uses the 32KiHz base clock rate for clock events. Add a compile time selection to allow higher clock resulution. @@ -15,12 +10,10 @@ Add a compile time selection to allow higher clock resulution. Signed-off-by: Benedikt Spranger Signed-off-by: Thomas Gleixner --- - drivers/clocksource/tcb_clksrc.c | 36 +++++++++++++++++++------------- - drivers/misc/Kconfig | 12 +++++++++-- + drivers/clocksource/tcb_clksrc.c | 36 +++++++++++++++++++++--------------- + drivers/misc/Kconfig | 12 ++++++++++-- 2 files changed, 31 insertions(+), 17 deletions(-) -diff --git a/drivers/clocksource/tcb_clksrc.c b/drivers/clocksource/tcb_clksrc.c -index 4f45be268e52..05f4b88bb955 100644 --- a/drivers/clocksource/tcb_clksrc.c +++ b/drivers/clocksource/tcb_clksrc.c @@ -25,8 +25,7 @@ @@ -41,7 +34,7 @@ index 4f45be268e52..05f4b88bb955 100644 void __iomem *regs; }; -@@ -135,13 +135,6 @@ static struct tc_clkevt_device *to_tc_clkevt(struct clock_event_device *clkevt) +@@ -135,13 +135,6 @@ static struct tc_clkevt_device *to_tc_cl return container_of(clkevt, struct tc_clkevt_device, clkevt); } @@ -55,7 +48,7 @@ index 4f45be268e52..05f4b88bb955 100644 static u32 timer_clock; static void tc_clk_disable(struct clock_event_device *d) -@@ -191,7 +184,7 @@ static int tc_set_oneshot(struct clock_event_device *d) +@@ -191,7 +184,7 @@ static int tc_set_oneshot(struct clock_e tc_clk_enable(d); @@ -64,7 +57,7 @@ index 4f45be268e52..05f4b88bb955 100644 writel(timer_clock | ATMEL_TC_CPCSTOP | ATMEL_TC_WAVE | ATMEL_TC_WAVESEL_UP_AUTO, regs + ATMEL_TC_REG(2, CMR)); writel(ATMEL_TC_CPCS, regs + ATMEL_TC_REG(2, IER)); -@@ -213,10 +206,10 @@ static int tc_set_periodic(struct clock_event_device *d) +@@ -213,10 +206,10 @@ static int tc_set_periodic(struct clock_ */ tc_clk_enable(d); @@ -77,7 +70,7 @@ index 4f45be268e52..05f4b88bb955 100644 /* Enable clock and interrupts on RC compare */ writel(ATMEL_TC_CPCS, regs + ATMEL_TC_REG(2, IER)); -@@ -243,7 +236,11 @@ static struct tc_clkevt_device clkevt = { +@@ -243,7 +236,11 @@ static struct tc_clkevt_device clkevt = .features = CLOCK_EVT_FEAT_PERIODIC | CLOCK_EVT_FEAT_ONESHOT, /* Should be lower than at91rm9200's system timer */ @@ -89,7 +82,7 @@ index 4f45be268e52..05f4b88bb955 100644 .set_next_event = tc_next_event, .set_state_shutdown = tc_shutdown_clk_off, .set_state_periodic = tc_set_periodic, -@@ -265,8 +262,9 @@ static irqreturn_t ch2_irq(int irq, void *handle) +@@ -265,8 +262,9 @@ static irqreturn_t ch2_irq(int irq, void return IRQ_NONE; } @@ -100,7 +93,7 @@ index 4f45be268e52..05f4b88bb955 100644 int ret; struct clk *t2_clk = tc->clk[2]; int irq = tc->irq[2]; -@@ -287,7 +285,11 @@ static int __init setup_clkevents(struct atmel_tc *tc, int clk32k_divisor_idx) +@@ -287,7 +285,11 @@ static int __init setup_clkevents(struct clkevt.regs = tc->regs; clkevt.clk = t2_clk; @@ -113,7 +106,7 @@ index 4f45be268e52..05f4b88bb955 100644 clkevt.clkevt.cpumask = cpumask_of(0); -@@ -298,7 +300,7 @@ static int __init setup_clkevents(struct atmel_tc *tc, int clk32k_divisor_idx) +@@ -298,7 +300,7 @@ static int __init setup_clkevents(struct return ret; } @@ -134,8 +127,6 @@ index 4f45be268e52..05f4b88bb955 100644 if (ret) goto err_unregister_clksrc; -diff --git a/drivers/misc/Kconfig b/drivers/misc/Kconfig -index 8136dc7e863d..d2feb491e689 100644 --- a/drivers/misc/Kconfig +++ b/drivers/misc/Kconfig @@ -69,8 +69,7 @@ config ATMEL_TCB_CLKSRC @@ -148,7 +139,7 @@ index 8136dc7e863d..d2feb491e689 100644 config ATMEL_TCB_CLKSRC_BLOCK int -@@ -84,6 +83,15 @@ config ATMEL_TCB_CLKSRC_BLOCK +@@ -83,6 +82,15 @@ config ATMEL_TCB_CLKSRC_BLOCK TC can be used for other purposes, such as PWM generation and interval timing. @@ -164,6 +155,3 @@ index 8136dc7e863d..d2feb491e689 100644 config DUMMY_IRQ tristate "Dummy IRQ handler" default n --- -2.19.2 - diff --git a/kernel/patches-4.14.x-rt/0123-timekeeping-Split-jiffies-seqlock.patch b/kernel/patches-4.19.x-rt/0033-timekeeping-split-jiffies-lock.patch similarity index 73% rename from kernel/patches-4.14.x-rt/0123-timekeeping-Split-jiffies-seqlock.patch rename to kernel/patches-4.19.x-rt/0033-timekeeping-split-jiffies-lock.patch index e39b9352b..f03f9d045 100644 --- a/kernel/patches-4.14.x-rt/0123-timekeeping-Split-jiffies-seqlock.patch +++ b/kernel/patches-4.19.x-rt/0033-timekeeping-split-jiffies-lock.patch @@ -1,25 +1,22 @@ -From b4dce15b1521980b9cc0c5a8dc8fda4569e2d986 Mon Sep 17 00:00:00 2001 +Subject: timekeeping: Split jiffies seqlock From: Thomas Gleixner Date: Thu, 14 Feb 2013 22:36:59 +0100 -Subject: [PATCH 123/450] timekeeping: Split jiffies seqlock Replace jiffies_lock seqlock with a simple seqcounter and a rawlock so it can be taken in atomic context on RT. Signed-off-by: Thomas Gleixner --- - kernel/time/jiffies.c | 7 ++++--- - kernel/time/tick-common.c | 10 ++++++---- - kernel/time/tick-sched.c | 19 ++++++++++++------- - kernel/time/timekeeping.c | 6 ++++-- - kernel/time/timekeeping.h | 3 ++- + kernel/time/jiffies.c | 7 ++++--- + kernel/time/tick-common.c | 10 ++++++---- + kernel/time/tick-sched.c | 19 ++++++++++++------- + kernel/time/timekeeping.c | 6 ++++-- + kernel/time/timekeeping.h | 3 ++- 5 files changed, 28 insertions(+), 17 deletions(-) -diff --git a/kernel/time/jiffies.c b/kernel/time/jiffies.c -index 497719127bf9..62acb8914c9e 100644 --- a/kernel/time/jiffies.c +++ b/kernel/time/jiffies.c -@@ -74,7 +74,8 @@ static struct clocksource clocksource_jiffies = { +@@ -74,7 +74,8 @@ static struct clocksource clocksource_ji .max_cycles = 10, }; @@ -41,8 +38,6 @@ index 497719127bf9..62acb8914c9e 100644 return ret; } EXPORT_SYMBOL(get_jiffies_64); -diff --git a/kernel/time/tick-common.c b/kernel/time/tick-common.c -index 49edc1c4f3e6..7f5a26c3a8ee 100644 --- a/kernel/time/tick-common.c +++ b/kernel/time/tick-common.c @@ -79,13 +79,15 @@ int tick_is_oneshot_available(void) @@ -63,7 +58,7 @@ index 49edc1c4f3e6..7f5a26c3a8ee 100644 update_wall_time(); } -@@ -157,9 +159,9 @@ void tick_setup_periodic(struct clock_event_device *dev, int broadcast) +@@ -157,9 +159,9 @@ void tick_setup_periodic(struct clock_ev ktime_t next; do { @@ -75,11 +70,9 @@ index 49edc1c4f3e6..7f5a26c3a8ee 100644 clockevents_switch_state(dev, CLOCK_EVT_STATE_ONESHOT); -diff --git a/kernel/time/tick-sched.c b/kernel/time/tick-sched.c -index 67e2b79b6a9b..296b623ba045 100644 --- a/kernel/time/tick-sched.c +++ b/kernel/time/tick-sched.c -@@ -66,7 +66,8 @@ static void tick_do_update_jiffies64(ktime_t now) +@@ -67,7 +67,8 @@ static void tick_do_update_jiffies64(kti return; /* Reevaluate with jiffies_lock held */ @@ -89,7 +82,7 @@ index 67e2b79b6a9b..296b623ba045 100644 delta = ktime_sub(now, last_jiffies_update); if (delta >= tick_period) { -@@ -89,10 +90,12 @@ static void tick_do_update_jiffies64(ktime_t now) +@@ -90,10 +91,12 @@ static void tick_do_update_jiffies64(kti /* Keep the tick_next_period variable up to date */ tick_next_period = ktime_add(last_jiffies_update, tick_period); } else { @@ -104,7 +97,7 @@ index 67e2b79b6a9b..296b623ba045 100644 update_wall_time(); } -@@ -103,12 +106,14 @@ static ktime_t tick_init_jiffy_update(void) +@@ -104,12 +107,14 @@ static ktime_t tick_init_jiffy_update(vo { ktime_t period; @@ -121,7 +114,7 @@ index 67e2b79b6a9b..296b623ba045 100644 return period; } -@@ -689,10 +694,10 @@ static ktime_t tick_nohz_stop_sched_tick(struct tick_sched *ts, +@@ -652,10 +657,10 @@ static ktime_t tick_nohz_next_event(stru /* Read jiffies and the time when jiffies were updated last */ do { @@ -132,13 +125,11 @@ index 67e2b79b6a9b..296b623ba045 100644 - } while (read_seqretry(&jiffies_lock, seq)); + } while (read_seqcount_retry(&jiffies_seq, seq)); ts->last_jiffies = basejiff; + ts->timer_expires_base = basemono; - /* -diff --git a/kernel/time/timekeeping.c b/kernel/time/timekeeping.c -index 2cafb49aa65e..2720f2c29a6d 100644 --- a/kernel/time/timekeeping.c +++ b/kernel/time/timekeeping.c -@@ -2326,8 +2326,10 @@ EXPORT_SYMBOL(hardpps); +@@ -2417,8 +2417,10 @@ EXPORT_SYMBOL(hardpps); */ void xtime_update(unsigned long ticks) { @@ -151,8 +142,6 @@ index 2cafb49aa65e..2720f2c29a6d 100644 + raw_spin_unlock(&jiffies_lock); update_wall_time(); } -diff --git a/kernel/time/timekeeping.h b/kernel/time/timekeeping.h -index c9f9af339914..0c0f52bf1927 100644 --- a/kernel/time/timekeeping.h +++ b/kernel/time/timekeeping.h @@ -18,7 +18,8 @@ extern void timekeeping_resume(void); @@ -165,6 +154,3 @@ index c9f9af339914..0c0f52bf1927 100644 #define CS_NAME_LEN 32 --- -2.19.2 - diff --git a/kernel/patches-4.14.x-rt/0125-signal-Revert-ptrace-preempt-magic.patch b/kernel/patches-4.19.x-rt/0034-signal-revert-ptrace-preempt-magic.patch similarity index 68% rename from kernel/patches-4.14.x-rt/0125-signal-Revert-ptrace-preempt-magic.patch rename to kernel/patches-4.19.x-rt/0034-signal-revert-ptrace-preempt-magic.patch index dad55d961..ea0adee2f 100644 --- a/kernel/patches-4.14.x-rt/0125-signal-Revert-ptrace-preempt-magic.patch +++ b/kernel/patches-4.19.x-rt/0034-signal-revert-ptrace-preempt-magic.patch @@ -1,7 +1,6 @@ -From d29203fc540a74934cc20916290e65c691d53d25 Mon Sep 17 00:00:00 2001 +Subject: signal: Revert ptrace preempt magic From: Thomas Gleixner Date: Wed, 21 Sep 2011 19:57:12 +0200 -Subject: [PATCH 125/450] signal: Revert ptrace preempt magic Upstream commit '53da1d9456fe7f8 fix ptrace slowness' is nothing more than a bandaid around the ptrace design trainwreck. It's not a @@ -9,14 +8,12 @@ correctness issue, it's merily a cosmetic bandaid. Signed-off-by: Thomas Gleixner --- - kernel/signal.c | 8 -------- + kernel/signal.c | 8 -------- 1 file changed, 8 deletions(-) -diff --git a/kernel/signal.c b/kernel/signal.c -index 164c36ef0825..8ffd4fb0a0f2 100644 --- a/kernel/signal.c +++ b/kernel/signal.c -@@ -1888,15 +1888,7 @@ static void ptrace_stop(int exit_code, int why, int clear_code, siginfo_t *info) +@@ -2094,15 +2094,7 @@ static void ptrace_stop(int exit_code, i if (gstop_done && ptrace_reparented(current)) do_notify_parent_cldstop(current, false, why); @@ -32,6 +29,3 @@ index 164c36ef0825..8ffd4fb0a0f2 100644 freezable_schedule(); } else { /* --- -2.19.2 - diff --git a/kernel/patches-4.14.x-rt/0136-net-sched-Use-msleep-instead-of-yield.patch b/kernel/patches-4.19.x-rt/0035-net-sched-dev_deactivate_many-use-msleep-1-instead-o.patch similarity index 89% rename from kernel/patches-4.14.x-rt/0136-net-sched-Use-msleep-instead-of-yield.patch rename to kernel/patches-4.19.x-rt/0035-net-sched-dev_deactivate_many-use-msleep-1-instead-o.patch index 3c10d968a..aa00107b5 100644 --- a/kernel/patches-4.14.x-rt/0136-net-sched-Use-msleep-instead-of-yield.patch +++ b/kernel/patches-4.19.x-rt/0035-net-sched-dev_deactivate_many-use-msleep-1-instead-o.patch @@ -1,7 +1,6 @@ -From a1414bad7091191aa9dbf3dcc59a2253cf85a967 Mon Sep 17 00:00:00 2001 From: Marc Kleine-Budde Date: Wed, 5 Mar 2014 00:49:47 +0100 -Subject: [PATCH 136/450] net: sched: Use msleep() instead of yield() +Subject: net: sched: Use msleep() instead of yield() On PREEMPT_RT enabled systems the interrupt handler run as threads at prio 50 (by default). If a high priority userspace process tries to shut down a busy @@ -42,14 +41,12 @@ solution. Signed-off-by: Marc Kleine-Budde Signed-off-by: Sebastian Andrzej Siewior --- - net/sched/sch_generic.c | 2 +- + net/sched/sch_generic.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) -diff --git a/net/sched/sch_generic.c b/net/sched/sch_generic.c -index 79549baf5804..de0839491dd8 100644 --- a/net/sched/sch_generic.c +++ b/net/sched/sch_generic.c -@@ -933,7 +933,7 @@ void dev_deactivate_many(struct list_head *head) +@@ -1184,7 +1184,7 @@ void dev_deactivate_many(struct list_hea /* Wait for outstanding qdisc_run calls. */ list_for_each_entry(dev, head, close_list) { while (some_qdisc_is_busy(dev)) @@ -58,6 +55,3 @@ index 79549baf5804..de0839491dd8 100644 /* The new qdisc is assigned at this point so we can safely * unwind stale skb lists and qdisc statistics */ --- -2.19.2 - diff --git a/kernel/patches-4.19.x-rt/0036-dm-rq-remove-BUG_ON-irqs_disabled-check.patch b/kernel/patches-4.19.x-rt/0036-dm-rq-remove-BUG_ON-irqs_disabled-check.patch new file mode 100644 index 000000000..c962ab317 --- /dev/null +++ b/kernel/patches-4.19.x-rt/0036-dm-rq-remove-BUG_ON-irqs_disabled-check.patch @@ -0,0 +1,30 @@ +From: Sebastian Andrzej Siewior +Date: Tue, 27 Mar 2018 16:24:15 +0200 +Subject: [PATCH] dm rq: remove BUG_ON(!irqs_disabled) check + +In commit 052189a2ec95 ("dm: remove superfluous irq disablement in +dm_request_fn") the spin_lock_irq() was replaced with spin_lock() + a +check for disabled interrupts. Later the locking part was removed in +commit 2eb6e1e3aa87 ("dm: submit stacked requests in irq enabled +context") but the BUG_ON() check remained. + +Since the original purpose for the "are-irqs-off" check is gone (the +->queue_lock has been removed) remove it. + +Cc: Keith Busch +Cc: Mike Snitzer +Signed-off-by: Sebastian Andrzej Siewior +--- + drivers/md/dm-rq.c | 1 - + 1 file changed, 1 deletion(-) + +--- a/drivers/md/dm-rq.c ++++ b/drivers/md/dm-rq.c +@@ -688,7 +688,6 @@ static void dm_old_request_fn(struct req + /* Establish tio->ti before queuing work (map_tio_request) */ + tio->ti = ti; + kthread_queue_work(&md->kworker, &tio->work); +- BUG_ON(!irqs_disabled()); + } + } + diff --git a/kernel/patches-4.19.x-rt/0037-usb-do-not-disable-interrupts-in-giveback.patch b/kernel/patches-4.19.x-rt/0037-usb-do-not-disable-interrupts-in-giveback.patch new file mode 100644 index 000000000..bf2be250a --- /dev/null +++ b/kernel/patches-4.19.x-rt/0037-usb-do-not-disable-interrupts-in-giveback.patch @@ -0,0 +1,39 @@ +From: Sebastian Andrzej Siewior +Date: Fri, 8 Nov 2013 17:34:54 +0100 +Subject: usb: do no disable interrupts in giveback + +Since commit 94dfd7ed ("USB: HCD: support giveback of URB in tasklet +context") the USB code disables interrupts before invoking the complete +callback. +This should not be required the HCD completes the URBs either in hard-irq +context or in BH context. Lockdep may report false positives if one has two +HCDs (one completes in IRQ and the other in BH context) and is using the same +USB driver (device) with both HCDs. This is safe since the same URBs are never +mixed with those two HCDs. +Longeterm we should force all HCDs to complete in the same context. + +Signed-off-by: Sebastian Andrzej Siewior +--- + drivers/usb/core/hcd.c | 3 --- + 1 file changed, 3 deletions(-) + +--- a/drivers/usb/core/hcd.c ++++ b/drivers/usb/core/hcd.c +@@ -1738,7 +1738,6 @@ static void __usb_hcd_giveback_urb(struc + struct usb_hcd *hcd = bus_to_hcd(urb->dev->bus); + struct usb_anchor *anchor = urb->anchor; + int status = urb->unlinked; +- unsigned long flags; + + urb->hcpriv = NULL; + if (unlikely((urb->transfer_flags & URB_SHORT_NOT_OK) && +@@ -1766,9 +1765,7 @@ static void __usb_hcd_giveback_urb(struc + * and no one may trigger the above deadlock situation when + * running complete() in tasklet. + */ +- local_irq_save(flags); + urb->complete(urb); +- local_irq_restore(flags); + + usb_anchor_resume_wakeups(anchor); + atomic_dec(&urb->use_count); diff --git a/kernel/patches-4.14.x-rt/0142-rt-Provide-PREEMPT_RT_BASE-config-switch.patch b/kernel/patches-4.19.x-rt/0038-rt-preempt-base-config.patch similarity index 73% rename from kernel/patches-4.14.x-rt/0142-rt-Provide-PREEMPT_RT_BASE-config-switch.patch rename to kernel/patches-4.19.x-rt/0038-rt-preempt-base-config.patch index 7b948d340..dd7d86d8b 100644 --- a/kernel/patches-4.14.x-rt/0142-rt-Provide-PREEMPT_RT_BASE-config-switch.patch +++ b/kernel/patches-4.19.x-rt/0038-rt-preempt-base-config.patch @@ -1,7 +1,6 @@ -From 717512fc9eab7c6cb0118225b738f702c4ab7c23 Mon Sep 17 00:00:00 2001 +Subject: rt: Provide PREEMPT_RT_BASE config switch From: Thomas Gleixner Date: Fri, 17 Jun 2011 12:39:57 +0200 -Subject: [PATCH 142/450] rt: Provide PREEMPT_RT_BASE config switch Introduce PREEMPT_RT_BASE which enables parts of PREEMPT_RT_FULL. Forces interrupt threading and enables some of the RT @@ -9,11 +8,9 @@ substitutions for testing. Signed-off-by: Thomas Gleixner --- - kernel/Kconfig.preempt | 19 +++++++++++++++++-- - 1 file changed, 17 insertions(+), 2 deletions(-) + kernel/Kconfig.preempt | 21 ++++++++++++++++++--- + 1 file changed, 18 insertions(+), 3 deletions(-) -diff --git a/kernel/Kconfig.preempt b/kernel/Kconfig.preempt -index 3f9c97419f02..c669134982ec 100644 --- a/kernel/Kconfig.preempt +++ b/kernel/Kconfig.preempt @@ -1,3 +1,10 @@ @@ -27,19 +24,20 @@ index 3f9c97419f02..c669134982ec 100644 choice prompt "Preemption Model" -@@ -33,9 +40,9 @@ config PREEMPT_VOLUNTARY +@@ -34,10 +41,10 @@ config PREEMPT_VOLUNTARY Select this if you are building a kernel for a desktop system. -config PREEMPT +config PREEMPT__LL bool "Preemptible Kernel (Low-Latency Desktop)" + depends on !ARCH_NO_PREEMPT - select PREEMPT_COUNT + select PREEMPT select UNINLINE_SPIN_UNLOCK if !ARCH_INLINE_SPIN_UNLOCK help This option reduces the latency of the kernel by making -@@ -52,6 +59,14 @@ config PREEMPT +@@ -54,7 +61,15 @@ config PREEMPT embedded system with latency requirements in the milliseconds range. @@ -54,6 +52,6 @@ index 3f9c97419f02..c669134982ec 100644 endchoice config PREEMPT_COUNT --- -2.19.2 - +- bool +\ No newline at end of file ++ bool diff --git a/kernel/patches-4.14.x-rt/0359-cpumask-Disable-CONFIG_CPUMASK_OFFSTACK-for-RT.patch b/kernel/patches-4.19.x-rt/0039-cpumask-disable-offstack-on-rt.patch similarity index 84% rename from kernel/patches-4.14.x-rt/0359-cpumask-Disable-CONFIG_CPUMASK_OFFSTACK-for-RT.patch rename to kernel/patches-4.19.x-rt/0039-cpumask-disable-offstack-on-rt.patch index cde4b50f6..87887d374 100644 --- a/kernel/patches-4.14.x-rt/0359-cpumask-Disable-CONFIG_CPUMASK_OFFSTACK-for-RT.patch +++ b/kernel/patches-4.19.x-rt/0039-cpumask-disable-offstack-on-rt.patch @@ -1,7 +1,6 @@ -From 492db0fbf838a1d0864e1e8753f0a00a842dad94 Mon Sep 17 00:00:00 2001 +Subject: cpumask: Disable CONFIG_CPUMASK_OFFSTACK for RT From: Thomas Gleixner Date: Wed, 14 Dec 2011 01:03:49 +0100 -Subject: [PATCH 359/450] cpumask: Disable CONFIG_CPUMASK_OFFSTACK for RT There are "valid" GFP_ATOMIC allocations such as @@ -41,15 +40,13 @@ which forbid allocations at run-time. Signed-off-by: Thomas Gleixner --- - arch/x86/Kconfig | 2 +- - lib/Kconfig | 1 + + arch/x86/Kconfig | 2 +- + lib/Kconfig | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) -diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig -index 22a63ddf5668..0520b7003c43 100644 --- a/arch/x86/Kconfig +++ b/arch/x86/Kconfig -@@ -932,7 +932,7 @@ config IOMMU_HELPER +@@ -934,7 +934,7 @@ config CALGARY_IOMMU_ENABLED_BY_DEFAULT config MAXSMP bool "Enable Maximum number of SMP Processors and NUMA Nodes" depends on X86_64 && SMP && DEBUG_KERNEL @@ -58,11 +55,9 @@ index 22a63ddf5668..0520b7003c43 100644 ---help--- Enable maximum number of CPUS and NUMA Nodes for this architecture. If unsure, say N. -diff --git a/lib/Kconfig b/lib/Kconfig -index b1445b22a6de..9ab51b78991a 100644 --- a/lib/Kconfig +++ b/lib/Kconfig -@@ -428,6 +428,7 @@ config CHECK_SIGNATURE +@@ -441,6 +441,7 @@ config CHECK_SIGNATURE config CPUMASK_OFFSTACK bool "Force CPU masks off stack" if DEBUG_PER_CPU_MAPS @@ -70,6 +65,3 @@ index b1445b22a6de..9ab51b78991a 100644 help Use dynamic allocation for cpumask_var_t, instead of putting them on the stack. This is a bit more expensive, but avoids --- -2.19.2 - diff --git a/kernel/patches-4.14.x-rt/0312-jump-label-disable-if-stop_machine-is-used.patch b/kernel/patches-4.19.x-rt/0040-jump-label-rt.patch similarity index 75% rename from kernel/patches-4.14.x-rt/0312-jump-label-disable-if-stop_machine-is-used.patch rename to kernel/patches-4.19.x-rt/0040-jump-label-rt.patch index 1e072304d..02184b19a 100644 --- a/kernel/patches-4.14.x-rt/0312-jump-label-disable-if-stop_machine-is-used.patch +++ b/kernel/patches-4.19.x-rt/0040-jump-label-rt.patch @@ -1,7 +1,6 @@ -From 970af03df6bb4a2408523359ee340a9062597e37 Mon Sep 17 00:00:00 2001 +Subject: jump-label: disable if stop_machine() is used From: Thomas Gleixner -Date: Wed, 8 Jul 2015 17:14:48 +0200 -Subject: [PATCH 312/450] jump-label: disable if stop_machine() is used +Date: Wed, 08 Jul 2015 17:14:48 +0200 Some architectures are using stop_machine() while switching the opcode which leads to latency spikes. @@ -20,14 +19,12 @@ Signed-off-by: Thomas Gleixner [bigeasy: only ARM for now] Signed-off-by: Sebastian Andrzej Siewior --- - arch/arm/Kconfig | 2 +- + arch/arm/Kconfig | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) -diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig -index d1346a160760..e57221694d28 100644 --- a/arch/arm/Kconfig +++ b/arch/arm/Kconfig -@@ -45,7 +45,7 @@ config ARM +@@ -51,7 +51,7 @@ config ARM select HARDIRQS_SW_RESEND select HAVE_ARCH_AUDITSYSCALL if (AEABI && !OABI_COMPAT) select HAVE_ARCH_BITREVERSE if (CPU_32v7M || CPU_32v7) && !CPU_32v6 @@ -36,6 +33,3 @@ index d1346a160760..e57221694d28 100644 select HAVE_ARCH_KGDB if !CPU_ENDIAN_BE32 && MMU select HAVE_ARCH_MMAP_RND_BITS if MMU select HAVE_ARCH_SECCOMP_FILTER if (AEABI && !OABI_COMPAT) --- -2.19.2 - diff --git a/kernel/patches-4.14.x-rt/0143-kconfig-Disable-config-options-which-are-not-RT-comp.patch b/kernel/patches-4.19.x-rt/0041-kconfig-disable-a-few-options-rt.patch similarity index 61% rename from kernel/patches-4.14.x-rt/0143-kconfig-Disable-config-options-which-are-not-RT-comp.patch rename to kernel/patches-4.19.x-rt/0041-kconfig-disable-a-few-options-rt.patch index a7ef93f1a..75e518436 100644 --- a/kernel/patches-4.14.x-rt/0143-kconfig-Disable-config-options-which-are-not-RT-comp.patch +++ b/kernel/patches-4.19.x-rt/0041-kconfig-disable-a-few-options-rt.patch @@ -1,22 +1,18 @@ -From 8d96e538d166cc8dbd5af0889b59e4bc82107bf7 Mon Sep 17 00:00:00 2001 +Subject: kconfig: Disable config options which are not RT compatible From: Thomas Gleixner Date: Sun, 24 Jul 2011 12:11:43 +0200 -Subject: [PATCH 143/450] kconfig: Disable config options which are not RT - compatible Disable stuff which is known to have issues on RT Signed-off-by: Thomas Gleixner --- - arch/Kconfig | 1 + - mm/Kconfig | 2 +- + arch/Kconfig | 1 + + mm/Kconfig | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) -diff --git a/arch/Kconfig b/arch/Kconfig -index 77b3e21c4844..69d6f3793ae7 100644 --- a/arch/Kconfig +++ b/arch/Kconfig -@@ -20,6 +20,7 @@ config OPROFILE +@@ -28,6 +28,7 @@ config OPROFILE tristate "OProfile system profiling" depends on PROFILING depends on HAVE_OPROFILE @@ -24,11 +20,9 @@ index 77b3e21c4844..69d6f3793ae7 100644 select RING_BUFFER select RING_BUFFER_ALLOW_SWAP help -diff --git a/mm/Kconfig b/mm/Kconfig -index 59efbd3337e0..3df123c0bc3f 100644 --- a/mm/Kconfig +++ b/mm/Kconfig -@@ -385,7 +385,7 @@ config NOMMU_INITIAL_TRIM_EXCESS +@@ -377,7 +377,7 @@ config NOMMU_INITIAL_TRIM_EXCESS config TRANSPARENT_HUGEPAGE bool "Transparent Hugepage Support" @@ -37,6 +31,3 @@ index 59efbd3337e0..3df123c0bc3f 100644 select COMPACTION select RADIX_TREE_MULTIORDER help --- -2.19.2 - diff --git a/kernel/patches-4.14.x-rt/0228-lockdep-disable-self-test.patch b/kernel/patches-4.19.x-rt/0042-lockdep-disable-self-test.patch similarity index 75% rename from kernel/patches-4.14.x-rt/0228-lockdep-disable-self-test.patch rename to kernel/patches-4.19.x-rt/0042-lockdep-disable-self-test.patch index cd7b7dd5f..a0485fa98 100644 --- a/kernel/patches-4.14.x-rt/0228-lockdep-disable-self-test.patch +++ b/kernel/patches-4.19.x-rt/0042-lockdep-disable-self-test.patch @@ -1,7 +1,6 @@ -From c7b2d4d71641197bea5498f2264bfaf55666cda2 Mon Sep 17 00:00:00 2001 From: Sebastian Andrzej Siewior Date: Tue, 17 Oct 2017 16:36:18 +0200 -Subject: [PATCH 228/450] lockdep: disable self-test +Subject: [PATCH] lockdep: disable self-test MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit @@ -13,14 +12,12 @@ during boot and it needs to be investigated… Signed-off-by: Sebastian Andrzej Siewior --- - lib/Kconfig.debug | 2 +- + lib/Kconfig.debug | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) -diff --git a/lib/Kconfig.debug b/lib/Kconfig.debug -index 62d0e25c054c..401b7ed164b5 100644 --- a/lib/Kconfig.debug +++ b/lib/Kconfig.debug -@@ -1197,7 +1197,7 @@ config DEBUG_ATOMIC_SLEEP +@@ -1207,7 +1207,7 @@ config DEBUG_ATOMIC_SLEEP config DEBUG_LOCKING_API_SELFTESTS bool "Locking API boot-time self-tests" @@ -29,6 +26,3 @@ index 62d0e25c054c..401b7ed164b5 100644 help Say Y here if you want the kernel to run a short self-test during bootup. The self-test checks whether common types of locking bugs --- -2.19.2 - diff --git a/kernel/patches-4.14.x-rt/0177-mm-Allow-only-slub-on-RT.patch b/kernel/patches-4.19.x-rt/0043-mm-disable-sloub-rt.patch similarity index 70% rename from kernel/patches-4.14.x-rt/0177-mm-Allow-only-slub-on-RT.patch rename to kernel/patches-4.19.x-rt/0043-mm-disable-sloub-rt.patch index 4ac4582f0..b15a7471a 100644 --- a/kernel/patches-4.14.x-rt/0177-mm-Allow-only-slub-on-RT.patch +++ b/kernel/patches-4.19.x-rt/0043-mm-disable-sloub-rt.patch @@ -1,21 +1,19 @@ -From a276eb4d8b187ebb02c3edbb0cf6faf7c73f6ea2 Mon Sep 17 00:00:00 2001 From: Ingo Molnar Date: Fri, 3 Jul 2009 08:44:03 -0500 -Subject: [PATCH 177/450] mm: Allow only slub on RT +Subject: mm: Allow only slub on RT Disable SLAB and SLOB on -RT. Only SLUB is adopted to -RT needs. Signed-off-by: Ingo Molnar Signed-off-by: Thomas Gleixner + --- - init/Kconfig | 2 ++ + init/Kconfig | 2 ++ 1 file changed, 2 insertions(+) -diff --git a/init/Kconfig b/init/Kconfig -index 46075327c165..0fa1ade4351a 100644 --- a/init/Kconfig +++ b/init/Kconfig -@@ -1533,6 +1533,7 @@ choice +@@ -1634,6 +1634,7 @@ choice config SLAB bool "SLAB" @@ -23,7 +21,7 @@ index 46075327c165..0fa1ade4351a 100644 select HAVE_HARDENED_USERCOPY_ALLOCATOR help The regular slab allocator that is established and known to work -@@ -1553,6 +1554,7 @@ config SLUB +@@ -1654,6 +1655,7 @@ config SLUB config SLOB depends on EXPERT bool "SLOB (Simple Allocator)" @@ -31,6 +29,3 @@ index 46075327c165..0fa1ade4351a 100644 help SLOB replaces the stock allocator with a drastically simpler allocator. SLOB is generally more space efficient but --- -2.19.2 - diff --git a/kernel/patches-4.14.x-rt/0229-locking-Disable-spin-on-owner-for-RT.patch b/kernel/patches-4.19.x-rt/0044-mutex-no-spin-on-rt.patch similarity index 68% rename from kernel/patches-4.14.x-rt/0229-locking-Disable-spin-on-owner-for-RT.patch rename to kernel/patches-4.19.x-rt/0044-mutex-no-spin-on-rt.patch index 0fec6d5c9..6f7ca0e2e 100644 --- a/kernel/patches-4.14.x-rt/0229-locking-Disable-spin-on-owner-for-RT.patch +++ b/kernel/patches-4.19.x-rt/0044-mutex-no-spin-on-rt.patch @@ -1,21 +1,15 @@ -From 53c2268d31ab617d8f928e8133170637b0769ca6 Mon Sep 17 00:00:00 2001 From: Thomas Gleixner Date: Sun, 17 Jul 2011 21:51:45 +0200 -Subject: [PATCH 229/450] locking: Disable spin on owner for RT -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit +Subject: locking: Disable spin on owner for RT Drop spin on owner for mutex / rwsem. We are most likely not using it but… Signed-off-by: Thomas Gleixner --- - kernel/Kconfig.locks | 4 ++-- + kernel/Kconfig.locks | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) -diff --git a/kernel/Kconfig.locks b/kernel/Kconfig.locks -index 84d882f3e299..af27c4000812 100644 --- a/kernel/Kconfig.locks +++ b/kernel/Kconfig.locks @@ -225,11 +225,11 @@ config ARCH_SUPPORTS_ATOMIC_RMW @@ -32,6 +26,3 @@ index 84d882f3e299..af27c4000812 100644 config LOCK_SPIN_ON_OWNER def_bool y --- -2.19.2 - diff --git a/kernel/patches-4.14.x-rt/0377-rcu-Disable-RCU_FAST_NO_HZ-on-RT.patch b/kernel/patches-4.19.x-rt/0045-rcu-disable-rcu-fast-no-hz-on-rt.patch similarity index 72% rename from kernel/patches-4.14.x-rt/0377-rcu-Disable-RCU_FAST_NO_HZ-on-RT.patch rename to kernel/patches-4.19.x-rt/0045-rcu-disable-rcu-fast-no-hz-on-rt.patch index 56b62dd9a..13b4e6beb 100644 --- a/kernel/patches-4.14.x-rt/0377-rcu-Disable-RCU_FAST_NO_HZ-on-RT.patch +++ b/kernel/patches-4.19.x-rt/0045-rcu-disable-rcu-fast-no-hz-on-rt.patch @@ -1,18 +1,16 @@ -From 52e351d171ad9613e98b9225c454752608601c5b Mon Sep 17 00:00:00 2001 +Subject: rcu: Disable RCU_FAST_NO_HZ on RT From: Thomas Gleixner Date: Sun, 28 Oct 2012 13:26:09 +0000 -Subject: [PATCH 377/450] rcu: Disable RCU_FAST_NO_HZ on RT This uses a timer_list timer from the irq disabled guts of the idle code. Disable it for now to prevent wreckage. Signed-off-by: Thomas Gleixner + --- - kernel/rcu/Kconfig | 2 +- + kernel/rcu/Kconfig | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) -diff --git a/kernel/rcu/Kconfig b/kernel/rcu/Kconfig -index 9210379c0353..644264be90f0 100644 --- a/kernel/rcu/Kconfig +++ b/kernel/rcu/Kconfig @@ -172,7 +172,7 @@ config RCU_FANOUT_LEAF @@ -24,6 +22,3 @@ index 9210379c0353..644264be90f0 100644 default n help This option permits CPUs to enter dynticks-idle state even if --- -2.19.2 - diff --git a/kernel/patches-4.14.x-rt/0379-rcu-make-RCU_BOOST-default-on-RT.patch b/kernel/patches-4.19.x-rt/0046-rcu-make-RCU_BOOST-default-on-RT.patch similarity index 53% rename from kernel/patches-4.14.x-rt/0379-rcu-make-RCU_BOOST-default-on-RT.patch rename to kernel/patches-4.19.x-rt/0046-rcu-make-RCU_BOOST-default-on-RT.patch index 415451e13..fa1fb18b8 100644 --- a/kernel/patches-4.14.x-rt/0379-rcu-make-RCU_BOOST-default-on-RT.patch +++ b/kernel/patches-4.19.x-rt/0046-rcu-make-RCU_BOOST-default-on-RT.patch @@ -1,7 +1,6 @@ -From 247b33cc05750e8c8b687fc9f89d22067cfc6498 Mon Sep 17 00:00:00 2001 From: Sebastian Andrzej Siewior Date: Fri, 21 Mar 2014 20:19:05 +0100 -Subject: [PATCH 379/450] rcu: make RCU_BOOST default on RT +Subject: rcu: make RCU_BOOST default on RT Since it is no longer invoked from the softirq people run into OOM more often if the priority of the RCU thread is too low. Making boosting @@ -10,31 +9,19 @@ someone knows better. Signed-off-by: Sebastian Andrzej Siewior --- - kernel/rcu/Kconfig | 4 ++-- + kernel/rcu/Kconfig | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) -diff --git a/kernel/rcu/Kconfig b/kernel/rcu/Kconfig -index 644264be90f0..0be2c96fb640 100644 --- a/kernel/rcu/Kconfig +++ b/kernel/rcu/Kconfig -@@ -36,7 +36,7 @@ config TINY_RCU +@@ -190,8 +190,8 @@ config RCU_FAST_NO_HZ - config RCU_EXPERT - bool "Make expert-level adjustments to RCU configuration" -- default n -+ default y if PREEMPT_RT_FULL - help - This option needs to be enabled if you wish to make - expert-level adjustments to RCU configuration. By default, -@@ -191,7 +191,7 @@ config RCU_FAST_NO_HZ config RCU_BOOST bool "Enable RCU priority boosting" - depends on RT_MUTEXES && PREEMPT_RCU && RCU_EXPERT +- depends on RT_MUTEXES && PREEMPT_RCU && RCU_EXPERT - default n ++ depends on (RT_MUTEXES && PREEMPT_RCU && RCU_EXPERT) || PREEMPT_RT_FULL + default y if PREEMPT_RT_FULL help This option boosts the priority of preempted RCU readers that block the current preemptible RCU grace period for too long. --- -2.19.2 - diff --git a/kernel/patches-4.14.x-rt/0219-sched-Disable-CONFIG_RT_GROUP_SCHED-on-RT.patch b/kernel/patches-4.19.x-rt/0047-sched-disable-rt-group-sched-on-rt.patch similarity index 71% rename from kernel/patches-4.14.x-rt/0219-sched-Disable-CONFIG_RT_GROUP_SCHED-on-RT.patch rename to kernel/patches-4.19.x-rt/0047-sched-disable-rt-group-sched-on-rt.patch index 0cf66ed64..b752b8171 100644 --- a/kernel/patches-4.14.x-rt/0219-sched-Disable-CONFIG_RT_GROUP_SCHED-on-RT.patch +++ b/kernel/patches-4.19.x-rt/0047-sched-disable-rt-group-sched-on-rt.patch @@ -1,7 +1,6 @@ -From 15e41b750773b99b8ffb0d3c605f122375dbbdf8 Mon Sep 17 00:00:00 2001 +Subject: sched: Disable CONFIG_RT_GROUP_SCHED on RT From: Thomas Gleixner Date: Mon, 18 Jul 2011 17:03:52 +0200 -Subject: [PATCH 219/450] sched: Disable CONFIG_RT_GROUP_SCHED on RT Carsten reported problems when running: @@ -14,14 +13,12 @@ shell. Disabling CONFIG_RT_GROUP_SCHED solves that as well. Signed-off-by: Thomas Gleixner --- - init/Kconfig | 1 + + init/Kconfig | 1 + 1 file changed, 1 insertion(+) -diff --git a/init/Kconfig b/init/Kconfig -index bec5b4b82585..a7aff2c1a203 100644 --- a/init/Kconfig +++ b/init/Kconfig -@@ -744,6 +744,7 @@ config CFS_BANDWIDTH +@@ -781,6 +781,7 @@ config CFS_BANDWIDTH config RT_GROUP_SCHED bool "Group scheduling for SCHED_RR/FIFO" depends on CGROUP_SCHED @@ -29,6 +26,3 @@ index bec5b4b82585..a7aff2c1a203 100644 default n help This feature lets you explicitly allocate real CPU bandwidth --- -2.19.2 - diff --git a/kernel/patches-4.14.x-rt/0137-net-core-disable-NET_RX_BUSY_POLL.patch b/kernel/patches-4.19.x-rt/0048-net_disable_NET_RX_BUSY_POLL.patch similarity index 67% rename from kernel/patches-4.14.x-rt/0137-net-core-disable-NET_RX_BUSY_POLL.patch rename to kernel/patches-4.19.x-rt/0048-net_disable_NET_RX_BUSY_POLL.patch index af7f6c01c..910258078 100644 --- a/kernel/patches-4.14.x-rt/0137-net-core-disable-NET_RX_BUSY_POLL.patch +++ b/kernel/patches-4.19.x-rt/0048-net_disable_NET_RX_BUSY_POLL.patch @@ -1,10 +1,6 @@ -From ece96931ab4b21f8f5aaf666daff565b49dbc11a Mon Sep 17 00:00:00 2001 From: Sebastian Andrzej Siewior Date: Sat, 27 May 2017 19:02:06 +0200 -Subject: [PATCH 137/450] net/core: disable NET_RX_BUSY_POLL -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit +Subject: net/core: disable NET_RX_BUSY_POLL sk_busy_loop() does preempt_disable() followed by a few operations which can take sleeping locks and may get long. @@ -16,14 +12,12 @@ could be invoked again. Signed-off-by: Sebastian Andrzej Siewior --- - net/Kconfig | 2 +- + net/Kconfig | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) -diff --git a/net/Kconfig b/net/Kconfig -index 9dba2715919d..9c7b38379c09 100644 --- a/net/Kconfig +++ b/net/Kconfig -@@ -272,7 +272,7 @@ config CGROUP_NET_CLASSID +@@ -275,7 +275,7 @@ config CGROUP_NET_CLASSID config NET_RX_BUSY_POLL bool @@ -32,6 +26,3 @@ index 9dba2715919d..9c7b38379c09 100644 config BQL bool --- -2.19.2 - diff --git a/kernel/patches-4.14.x-rt/0356-arm-disable-NEON-in-kernel-mode.patch b/kernel/patches-4.19.x-rt/0049-arm-disable-NEON-in-kernel-mode.patch similarity index 71% rename from kernel/patches-4.14.x-rt/0356-arm-disable-NEON-in-kernel-mode.patch rename to kernel/patches-4.19.x-rt/0049-arm-disable-NEON-in-kernel-mode.patch index e308ba895..a24aedbe4 100644 --- a/kernel/patches-4.14.x-rt/0356-arm-disable-NEON-in-kernel-mode.patch +++ b/kernel/patches-4.19.x-rt/0049-arm-disable-NEON-in-kernel-mode.patch @@ -1,7 +1,6 @@ -From 1b3f3e28e0d3d164410f5da5009aeb8aa6f4379a Mon Sep 17 00:00:00 2001 From: Sebastian Andrzej Siewior Date: Fri, 1 Dec 2017 10:42:03 +0100 -Subject: [PATCH 356/450] arm*: disable NEON in kernel mode +Subject: [PATCH] arm*: disable NEON in kernel mode NEON in kernel mode is used by the crypto algorithms and raid6 code. While the raid6 code looks okay, the crypto algorithms do not: NEON @@ -14,16 +13,14 @@ stay on due to possible EFI callbacks so here I disable each algorithm. Cc: stable-rt@vger.kernel.org Signed-off-by: Sebastian Andrzej Siewior --- - arch/arm/Kconfig | 2 +- - arch/arm64/crypto/Kconfig | 20 ++++++++++---------- - arch/arm64/crypto/crc32-ce-glue.c | 3 ++- - 3 files changed, 13 insertions(+), 12 deletions(-) + arch/arm/Kconfig | 2 +- + arch/arm64/crypto/Kconfig | 28 ++++++++++++++-------------- + arch/arm64/crypto/crc32-ce-glue.c | 3 ++- + 3 files changed, 17 insertions(+), 16 deletions(-) -diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig -index e57221694d28..ac05a027539a 100644 --- a/arch/arm/Kconfig +++ b/arch/arm/Kconfig -@@ -2164,7 +2164,7 @@ config NEON +@@ -2160,7 +2160,7 @@ config NEON config KERNEL_MODE_NEON bool "Support for NEON in kernel mode" @@ -32,11 +29,9 @@ index e57221694d28..ac05a027539a 100644 help Say Y to include support for NEON in kernel mode. -diff --git a/arch/arm64/crypto/Kconfig b/arch/arm64/crypto/Kconfig -index 70c517aa4501..2a5f05b5a19a 100644 --- a/arch/arm64/crypto/Kconfig +++ b/arch/arm64/crypto/Kconfig -@@ -19,19 +19,19 @@ config CRYPTO_SHA512_ARM64 +@@ -19,43 +19,43 @@ config CRYPTO_SHA512_ARM64 config CRYPTO_SHA1_ARM64_CE tristate "SHA-1 digest algorithm (ARMv8 Crypto Extensions)" @@ -52,6 +47,34 @@ index 70c517aa4501..2a5f05b5a19a 100644 select CRYPTO_HASH select CRYPTO_SHA256_ARM64 + config CRYPTO_SHA512_ARM64_CE + tristate "SHA-384/SHA-512 digest algorithm (ARMv8 Crypto Extensions)" +- depends on KERNEL_MODE_NEON ++ depends on KERNEL_MODE_NEON && !PREEMPT_RT_BASE + select CRYPTO_HASH + select CRYPTO_SHA512_ARM64 + + config CRYPTO_SHA3_ARM64 + tristate "SHA3 digest algorithm (ARMv8.2 Crypto Extensions)" +- depends on KERNEL_MODE_NEON ++ depends on KERNEL_MODE_NEON && !PREEMPT_RT_BASE + select CRYPTO_HASH + select CRYPTO_SHA3 + + config CRYPTO_SM3_ARM64_CE + tristate "SM3 digest algorithm (ARMv8.2 Crypto Extensions)" +- depends on KERNEL_MODE_NEON ++ depends on KERNEL_MODE_NEON && !PREEMPT_RT_BASE + select CRYPTO_HASH + select CRYPTO_SM3 + + config CRYPTO_SM4_ARM64_CE + tristate "SM4 symmetric cipher (ARMv8.2 Crypto Extensions)" +- depends on KERNEL_MODE_NEON ++ depends on KERNEL_MODE_NEON && !PREEMPT_RT_BASE + select CRYPTO_ALGAPI + select CRYPTO_SM4 + config CRYPTO_GHASH_ARM64_CE tristate "GHASH/AES-GCM using ARMv8 Crypto Extensions" - depends on KERNEL_MODE_NEON @@ -59,7 +82,7 @@ index 70c517aa4501..2a5f05b5a19a 100644 select CRYPTO_HASH select CRYPTO_GF128MUL select CRYPTO_AES -@@ -39,7 +39,7 @@ config CRYPTO_GHASH_ARM64_CE +@@ -63,7 +63,7 @@ config CRYPTO_GHASH_ARM64_CE config CRYPTO_CRCT10DIF_ARM64_CE tristate "CRCT10DIF digest algorithm using PMULL instructions" @@ -68,7 +91,7 @@ index 70c517aa4501..2a5f05b5a19a 100644 select CRYPTO_HASH config CRYPTO_CRC32_ARM64_CE -@@ -53,13 +53,13 @@ config CRYPTO_AES_ARM64 +@@ -77,13 +77,13 @@ config CRYPTO_AES_ARM64 config CRYPTO_AES_ARM64_CE tristate "AES core cipher using ARMv8 Crypto Extensions" @@ -84,7 +107,7 @@ index 70c517aa4501..2a5f05b5a19a 100644 select CRYPTO_ALGAPI select CRYPTO_AES_ARM64_CE select CRYPTO_AES_ARM64 -@@ -67,7 +67,7 @@ config CRYPTO_AES_ARM64_CE_CCM +@@ -91,7 +91,7 @@ config CRYPTO_AES_ARM64_CE_CCM config CRYPTO_AES_ARM64_CE_BLK tristate "AES in ECB/CBC/CTR/XTS modes using ARMv8 Crypto Extensions" @@ -93,7 +116,7 @@ index 70c517aa4501..2a5f05b5a19a 100644 select CRYPTO_BLKCIPHER select CRYPTO_AES_ARM64_CE select CRYPTO_AES_ARM64 -@@ -75,7 +75,7 @@ config CRYPTO_AES_ARM64_CE_BLK +@@ -99,7 +99,7 @@ config CRYPTO_AES_ARM64_CE_BLK config CRYPTO_AES_ARM64_NEON_BLK tristate "AES in ECB/CBC/CTR/XTS modes using NEON instructions" @@ -102,7 +125,7 @@ index 70c517aa4501..2a5f05b5a19a 100644 select CRYPTO_BLKCIPHER select CRYPTO_AES_ARM64 select CRYPTO_AES -@@ -83,13 +83,13 @@ config CRYPTO_AES_ARM64_NEON_BLK +@@ -107,13 +107,13 @@ config CRYPTO_AES_ARM64_NEON_BLK config CRYPTO_CHACHA20_NEON tristate "NEON accelerated ChaCha20 symmetric cipher" @@ -118,11 +141,9 @@ index 70c517aa4501..2a5f05b5a19a 100644 select CRYPTO_BLKCIPHER select CRYPTO_AES_ARM64_NEON_BLK select CRYPTO_AES_ARM64 -diff --git a/arch/arm64/crypto/crc32-ce-glue.c b/arch/arm64/crypto/crc32-ce-glue.c -index 34b4e3d46aab..ae055cdad8cf 100644 --- a/arch/arm64/crypto/crc32-ce-glue.c +++ b/arch/arm64/crypto/crc32-ce-glue.c -@@ -208,7 +208,8 @@ static struct shash_alg crc32_pmull_algs[] = { { +@@ -208,7 +208,8 @@ static struct shash_alg crc32_pmull_algs static int __init crc32_pmull_mod_init(void) { @@ -132,6 +153,3 @@ index 34b4e3d46aab..ae055cdad8cf 100644 crc32_pmull_algs[0].update = crc32_pmull_update; crc32_pmull_algs[1].update = crc32c_pmull_update; --- -2.19.2 - diff --git a/kernel/patches-4.14.x-rt/0333-powerpc-Use-generic-rwsem-on-RT.patch b/kernel/patches-4.19.x-rt/0050-power-use-generic-rwsem-on-rt.patch similarity index 59% rename from kernel/patches-4.14.x-rt/0333-powerpc-Use-generic-rwsem-on-RT.patch rename to kernel/patches-4.19.x-rt/0050-power-use-generic-rwsem-on-rt.patch index 6ae53da75..46e0a5edf 100644 --- a/kernel/patches-4.14.x-rt/0333-powerpc-Use-generic-rwsem-on-RT.patch +++ b/kernel/patches-4.19.x-rt/0050-power-use-generic-rwsem-on-rt.patch @@ -1,20 +1,17 @@ -From c4f30b023108b32cdde949289c5c88ff2c768ade Mon Sep 17 00:00:00 2001 From: Thomas Gleixner Date: Tue, 14 Jul 2015 14:26:34 +0200 -Subject: [PATCH 333/450] powerpc: Use generic rwsem on RT +Subject: powerpc: Use generic rwsem on RT Use generic code which uses rtmutex Signed-off-by: Thomas Gleixner --- - arch/powerpc/Kconfig | 3 ++- + arch/powerpc/Kconfig | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) -diff --git a/arch/powerpc/Kconfig b/arch/powerpc/Kconfig -index fe418226df7f..b8525ddc4b3b 100644 --- a/arch/powerpc/Kconfig +++ b/arch/powerpc/Kconfig -@@ -111,10 +111,11 @@ config LOCKDEP_SUPPORT +@@ -105,10 +105,11 @@ config LOCKDEP_SUPPORT config RWSEM_GENERIC_SPINLOCK bool @@ -27,6 +24,3 @@ index fe418226df7f..b8525ddc4b3b 100644 config GENERIC_LOCKBREAK bool --- -2.19.2 - diff --git a/kernel/patches-4.14.x-rt/0334-powerpc-kvm-Disable-in-kernel-MPIC-emulation-for-PRE.patch b/kernel/patches-4.19.x-rt/0051-powerpc-kvm-Disable-in-kernel-MPIC-emulation-for-PRE.patch similarity index 81% rename from kernel/patches-4.14.x-rt/0334-powerpc-kvm-Disable-in-kernel-MPIC-emulation-for-PRE.patch rename to kernel/patches-4.19.x-rt/0051-powerpc-kvm-Disable-in-kernel-MPIC-emulation-for-PRE.patch index 80536387a..ddf890e5c 100644 --- a/kernel/patches-4.14.x-rt/0334-powerpc-kvm-Disable-in-kernel-MPIC-emulation-for-PRE.patch +++ b/kernel/patches-4.19.x-rt/0051-powerpc-kvm-Disable-in-kernel-MPIC-emulation-for-PRE.patch @@ -1,8 +1,6 @@ -From 3ad770b2da9426e57ddd9c91e8c28b6c5705b043 Mon Sep 17 00:00:00 2001 From: Bogdan Purcareata Date: Fri, 24 Apr 2015 15:53:13 +0000 -Subject: [PATCH 334/450] powerpc/kvm: Disable in-kernel MPIC emulation for - PREEMPT_RT_FULL +Subject: powerpc/kvm: Disable in-kernel MPIC emulation for PREEMPT_RT_FULL While converting the openpic emulation code to use a raw_spinlock_t enables guests to run on RT, there's still a performance issue. For interrupts sent in @@ -24,14 +22,12 @@ Acked-by: Scott Wood Signed-off-by: Bogdan Purcareata Signed-off-by: Sebastian Andrzej Siewior --- - arch/powerpc/kvm/Kconfig | 1 + + arch/powerpc/kvm/Kconfig | 1 + 1 file changed, 1 insertion(+) -diff --git a/arch/powerpc/kvm/Kconfig b/arch/powerpc/kvm/Kconfig -index 648160334abf..9d24331fc9b4 100644 --- a/arch/powerpc/kvm/Kconfig +++ b/arch/powerpc/kvm/Kconfig -@@ -177,6 +177,7 @@ config KVM_E500MC +@@ -178,6 +178,7 @@ config KVM_E500MC config KVM_MPIC bool "KVM in-kernel MPIC emulation" depends on KVM && E500 @@ -39,6 +35,3 @@ index 648160334abf..9d24331fc9b4 100644 select HAVE_KVM_IRQCHIP select HAVE_KVM_IRQFD select HAVE_KVM_IRQ_ROUTING --- -2.19.2 - diff --git a/kernel/patches-4.14.x-rt/0344-powerpc-Disable-highmem-on-RT.patch b/kernel/patches-4.19.x-rt/0052-power-disable-highmem-on-rt.patch similarity index 56% rename from kernel/patches-4.14.x-rt/0344-powerpc-Disable-highmem-on-RT.patch rename to kernel/patches-4.19.x-rt/0052-power-disable-highmem-on-rt.patch index 240b22fef..19eeb6ac5 100644 --- a/kernel/patches-4.14.x-rt/0344-powerpc-Disable-highmem-on-RT.patch +++ b/kernel/patches-4.19.x-rt/0052-power-disable-highmem-on-rt.patch @@ -1,20 +1,17 @@ -From b2d03980ce2daa4376d1a1144253c347af40e0f4 Mon Sep 17 00:00:00 2001 +Subject: powerpc: Disable highmem on RT From: Thomas Gleixner Date: Mon, 18 Jul 2011 17:08:34 +0200 -Subject: [PATCH 344/450] powerpc: Disable highmem on RT The current highmem handling on -RT is not compatible and needs fixups. Signed-off-by: Thomas Gleixner --- - arch/powerpc/Kconfig | 2 +- + arch/powerpc/Kconfig | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) -diff --git a/arch/powerpc/Kconfig b/arch/powerpc/Kconfig -index b8525ddc4b3b..f3201bf888ad 100644 --- a/arch/powerpc/Kconfig +++ b/arch/powerpc/Kconfig -@@ -391,7 +391,7 @@ menu "Kernel options" +@@ -398,7 +398,7 @@ menu "Kernel options" config HIGHMEM bool "High memory support" @@ -22,7 +19,4 @@ index b8525ddc4b3b..f3201bf888ad 100644 + depends on PPC32 && !PREEMPT_RT_FULL source kernel/Kconfig.hz - source kernel/Kconfig.preempt --- -2.19.2 - + diff --git a/kernel/patches-4.14.x-rt/0345-mips-Disable-highmem-on-RT.patch b/kernel/patches-4.19.x-rt/0053-mips-disable-highmem-on-rt.patch similarity index 65% rename from kernel/patches-4.14.x-rt/0345-mips-Disable-highmem-on-RT.patch rename to kernel/patches-4.19.x-rt/0053-mips-disable-highmem-on-rt.patch index be03985e1..e9c0bedfa 100644 --- a/kernel/patches-4.14.x-rt/0345-mips-Disable-highmem-on-RT.patch +++ b/kernel/patches-4.19.x-rt/0053-mips-disable-highmem-on-rt.patch @@ -1,20 +1,17 @@ -From cc90e01232b7383458e142b92a9b896ae6263d01 Mon Sep 17 00:00:00 2001 +Subject: mips: Disable highmem on RT From: Thomas Gleixner Date: Mon, 18 Jul 2011 17:10:12 +0200 -Subject: [PATCH 345/450] mips: Disable highmem on RT The current highmem handling on -RT is not compatible and needs fixups. Signed-off-by: Thomas Gleixner --- - arch/mips/Kconfig | 2 +- + arch/mips/Kconfig | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) -diff --git a/arch/mips/Kconfig b/arch/mips/Kconfig -index 23e3d3e0ee5b..1fdf8f563973 100644 --- a/arch/mips/Kconfig +++ b/arch/mips/Kconfig -@@ -2520,7 +2520,7 @@ config MIPS_ASID_BITS_VARIABLE +@@ -2517,7 +2517,7 @@ config MIPS_CRC_SUPPORT # config HIGHMEM bool "High Memory Support" @@ -23,6 +20,3 @@ index 23e3d3e0ee5b..1fdf8f563973 100644 config CPU_SUPPORTS_HIGHMEM bool --- -2.19.2 - diff --git a/kernel/patches-4.14.x-rt/0286-x86-Use-generic-rwsem_spinlocks-on-rt.patch b/kernel/patches-4.19.x-rt/0054-x86-use-gen-rwsem-spinlocks-rt.patch similarity index 64% rename from kernel/patches-4.14.x-rt/0286-x86-Use-generic-rwsem_spinlocks-on-rt.patch rename to kernel/patches-4.19.x-rt/0054-x86-use-gen-rwsem-spinlocks-rt.patch index 54f45197f..0fe3da4e8 100644 --- a/kernel/patches-4.14.x-rt/0286-x86-Use-generic-rwsem_spinlocks-on-rt.patch +++ b/kernel/patches-4.19.x-rt/0054-x86-use-gen-rwsem-spinlocks-rt.patch @@ -1,21 +1,19 @@ -From 61139c98e3538a576a9f524393ba94eaf74e0fc8 Mon Sep 17 00:00:00 2001 From: Thomas Gleixner Date: Sun, 26 Jul 2009 02:21:32 +0200 -Subject: [PATCH 286/450] x86: Use generic rwsem_spinlocks on -rt +Subject: x86: Use generic rwsem_spinlocks on -rt Simplifies the separation of anon_rw_semaphores and rw_semaphores for -rt. Signed-off-by: Thomas Gleixner + --- - arch/x86/Kconfig | 5 ++++- + arch/x86/Kconfig | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) -diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig -index 4f393eb9745f..22a63ddf5668 100644 --- a/arch/x86/Kconfig +++ b/arch/x86/Kconfig -@@ -257,8 +257,11 @@ config ARCH_MAY_HAVE_PC_FDC +@@ -264,8 +264,11 @@ config ARCH_MAY_HAVE_PC_FDC def_bool y depends on ISA_DMA_API @@ -28,6 +26,3 @@ index 4f393eb9745f..22a63ddf5668 100644 config GENERIC_CALIBRATE_DELAY def_bool y --- -2.19.2 - diff --git a/kernel/patches-4.14.x-rt/0387-leds-trigger-disable-CPU-trigger-on-RT.patch b/kernel/patches-4.19.x-rt/0055-leds-trigger-disable-CPU-trigger-on-RT.patch similarity index 75% rename from kernel/patches-4.14.x-rt/0387-leds-trigger-disable-CPU-trigger-on-RT.patch rename to kernel/patches-4.19.x-rt/0055-leds-trigger-disable-CPU-trigger-on-RT.patch index d589c3aba..68f8c113b 100644 --- a/kernel/patches-4.14.x-rt/0387-leds-trigger-disable-CPU-trigger-on-RT.patch +++ b/kernel/patches-4.19.x-rt/0055-leds-trigger-disable-CPU-trigger-on-RT.patch @@ -1,7 +1,6 @@ -From 50cf6e2ce0055e575512a80c22b66446e72f64b4 Mon Sep 17 00:00:00 2001 From: Sebastian Andrzej Siewior Date: Thu, 23 Jan 2014 14:45:59 +0100 -Subject: [PATCH 387/450] leds: trigger: disable CPU trigger on -RT +Subject: leds: trigger: disable CPU trigger on -RT as it triggers: |CPU: 0 PID: 0 Comm: swapper Not tainted 3.12.8-rt10 #141 @@ -20,22 +19,16 @@ as it triggers: Signed-off-by: Sebastian Andrzej Siewior --- - drivers/leds/trigger/Kconfig | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) + drivers/leds/trigger/Kconfig | 1 + + 1 file changed, 1 insertion(+) -diff --git a/drivers/leds/trigger/Kconfig b/drivers/leds/trigger/Kconfig -index 3f9ddb9fafa7..09da5b6b44a1 100644 --- a/drivers/leds/trigger/Kconfig +++ b/drivers/leds/trigger/Kconfig -@@ -69,7 +69,7 @@ config LEDS_TRIGGER_BACKLIGHT +@@ -63,6 +63,7 @@ config LEDS_TRIGGER_BACKLIGHT config LEDS_TRIGGER_CPU bool "LED CPU Trigger" -- depends on LEDS_TRIGGERS -+ depends on LEDS_TRIGGERS && !PREEMPT_RT_BASE ++ depends on !PREEMPT_RT_BASE help This allows LEDs to be controlled by active CPUs. This shows the active CPUs across an array of LEDs so you can see which --- -2.19.2 - diff --git a/kernel/patches-4.14.x-rt/0389-cpufreq-drop-K8-s-driver-from-beeing-selected.patch b/kernel/patches-4.19.x-rt/0056-cpufreq-drop-K8-s-driver-from-beeing-selected.patch similarity index 79% rename from kernel/patches-4.14.x-rt/0389-cpufreq-drop-K8-s-driver-from-beeing-selected.patch rename to kernel/patches-4.19.x-rt/0056-cpufreq-drop-K8-s-driver-from-beeing-selected.patch index 0ce27e144..6b60722a5 100644 --- a/kernel/patches-4.14.x-rt/0389-cpufreq-drop-K8-s-driver-from-beeing-selected.patch +++ b/kernel/patches-4.19.x-rt/0056-cpufreq-drop-K8-s-driver-from-beeing-selected.patch @@ -1,7 +1,6 @@ -From a826d8b77351a76c294bebc69d0960a886a5649d Mon Sep 17 00:00:00 2001 From: Sebastian Andrzej Siewior Date: Thu, 9 Apr 2015 15:23:01 +0200 -Subject: [PATCH 389/450] cpufreq: drop K8's driver from beeing selected +Subject: cpufreq: drop K8's driver from beeing selected Ralf posted a picture of a backtrace from @@ -17,11 +16,9 @@ I have no machine with this, I simply switch it off. Reported-by: Ralf Mardorf Signed-off-by: Sebastian Andrzej Siewior --- - drivers/cpufreq/Kconfig.x86 | 2 +- + drivers/cpufreq/Kconfig.x86 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) -diff --git a/drivers/cpufreq/Kconfig.x86 b/drivers/cpufreq/Kconfig.x86 -index 35f71825b7f3..bb4a6160d0f7 100644 --- a/drivers/cpufreq/Kconfig.x86 +++ b/drivers/cpufreq/Kconfig.x86 @@ -125,7 +125,7 @@ config X86_POWERNOW_K7_ACPI @@ -33,6 +30,3 @@ index 35f71825b7f3..bb4a6160d0f7 100644 help This adds the CPUFreq driver for K8/early Opteron/Athlon64 processors. Support for K10 and newer processors is now in acpi-cpufreq. --- -2.19.2 - diff --git a/kernel/patches-4.14.x-rt/0404-md-disable-bcache.patch b/kernel/patches-4.19.x-rt/0057-md-disable-bcache.patch similarity index 70% rename from kernel/patches-4.14.x-rt/0404-md-disable-bcache.patch rename to kernel/patches-4.19.x-rt/0057-md-disable-bcache.patch index b49567f25..6c510466c 100644 --- a/kernel/patches-4.14.x-rt/0404-md-disable-bcache.patch +++ b/kernel/patches-4.19.x-rt/0057-md-disable-bcache.patch @@ -1,10 +1,6 @@ -From caddc553410834e9233c4949d6ef6df413bbfd78 Mon Sep 17 00:00:00 2001 From: Sebastian Andrzej Siewior Date: Thu, 29 Aug 2013 11:48:57 +0200 -Subject: [PATCH 404/450] md: disable bcache -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit +Subject: md: disable bcache It uses anon semaphores |drivers/md/bcache/request.c: In function ‘cached_dev_write_complete’: @@ -20,11 +16,9 @@ either we get rid of those or we have to introduce them… Signed-off-by: Sebastian Andrzej Siewior --- - drivers/md/bcache/Kconfig | 1 + + drivers/md/bcache/Kconfig | 1 + 1 file changed, 1 insertion(+) -diff --git a/drivers/md/bcache/Kconfig b/drivers/md/bcache/Kconfig -index 4d200883c505..98b64ed5cb81 100644 --- a/drivers/md/bcache/Kconfig +++ b/drivers/md/bcache/Kconfig @@ -1,6 +1,7 @@ @@ -32,9 +26,6 @@ index 4d200883c505..98b64ed5cb81 100644 config BCACHE tristate "Block device as cache" + depends on !PREEMPT_RT_FULL - ---help--- + select CRC64 + help Allows a block device to be used as cache for other devices; uses - a btree for indexing and the layout is optimized for SSDs. --- -2.19.2 - diff --git a/kernel/patches-4.14.x-rt/0428-efi-Disable-runtime-services-on-RT.patch b/kernel/patches-4.19.x-rt/0058-efi-Disable-runtime-services-on-RT.patch similarity index 69% rename from kernel/patches-4.14.x-rt/0428-efi-Disable-runtime-services-on-RT.patch rename to kernel/patches-4.19.x-rt/0058-efi-Disable-runtime-services-on-RT.patch index d192fc5bd..30094a012 100644 --- a/kernel/patches-4.14.x-rt/0428-efi-Disable-runtime-services-on-RT.patch +++ b/kernel/patches-4.19.x-rt/0058-efi-Disable-runtime-services-on-RT.patch @@ -1,9 +1,6 @@ -From 74a94472ee3b10f3ee5a2bd59cf4a24d51f1e635 Mon Sep 17 00:00:00 2001 From: Sebastian Andrzej Siewior Date: Thu, 26 Jul 2018 15:03:16 +0200 -Subject: [PATCH 428/450] efi: Disable runtime services on RT - -[ Upstream commit 55544e1d5eb0d7608e2b41452729649c8ea1607a ] +Subject: [PATCH] efi: Disable runtime services on RT Based on meassurements the EFI functions get_variable / get_next_variable take up to 2us which looks okay. @@ -23,25 +20,20 @@ Disable EFI's runtime wrappers. This was observed on "EFI v2.60 by SoftIron Overdrive 1000". +Acked-by: Ard Biesheuvel Signed-off-by: Sebastian Andrzej Siewior -Signed-off-by: Steven Rostedt (VMware) --- - drivers/firmware/efi/efi.c | 2 +- + drivers/firmware/efi/efi.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) -diff --git a/drivers/firmware/efi/efi.c b/drivers/firmware/efi/efi.c -index 9bd749389f31..47093745a53c 100644 --- a/drivers/firmware/efi/efi.c +++ b/drivers/firmware/efi/efi.c -@@ -74,7 +74,7 @@ static unsigned long *efi_tables[] = { - &efi.mem_attr_table, - }; +@@ -87,7 +87,7 @@ struct mm_struct efi_mm = { + + struct workqueue_struct *efi_rts_wq; -static bool disable_runtime; +static bool disable_runtime = IS_ENABLED(CONFIG_PREEMPT_RT_BASE); static int __init setup_noefi(char *arg) { disable_runtime = true; --- -2.19.2 - diff --git a/kernel/patches-4.14.x-rt/0140-printk-Add-a-printk-kill-switch.patch b/kernel/patches-4.19.x-rt/0059-printk-kill.patch similarity index 65% rename from kernel/patches-4.14.x-rt/0140-printk-Add-a-printk-kill-switch.patch rename to kernel/patches-4.19.x-rt/0059-printk-kill.patch index 12a421aef..a9d397ddf 100644 --- a/kernel/patches-4.14.x-rt/0140-printk-Add-a-printk-kill-switch.patch +++ b/kernel/patches-4.19.x-rt/0059-printk-kill.patch @@ -1,24 +1,20 @@ -From 869184fcf821740992b214c288086e33015cb19f Mon Sep 17 00:00:00 2001 +Subject: printk: Add a printk kill switch From: Ingo Molnar Date: Fri, 22 Jul 2011 17:58:40 +0200 -Subject: [PATCH 140/450] printk: Add a printk kill switch Add a prinkt-kill-switch. This is used from (NMI) watchdog to ensure that it does not dead-lock with the early printk code. Signed-off-by: Thomas Gleixner --- - include/linux/printk.h | 2 ++ - kernel/printk/printk.c | 20 ------------- - kernel/printk/printk_safe.c | 60 +++++++++++++++++++++++++++++++++++++ - kernel/watchdog_hld.c | 10 +++++++ - 4 files changed, 72 insertions(+), 20 deletions(-) + include/linux/printk.h | 2 + + kernel/printk/printk.c | 79 ++++++++++++++++++++++++++++++++++++------------- + kernel/watchdog_hld.c | 10 ++++++ + 3 files changed, 71 insertions(+), 20 deletions(-) -diff --git a/include/linux/printk.h b/include/linux/printk.h -index 6106befed756..1dba9cb7b91b 100644 --- a/include/linux/printk.h +++ b/include/linux/printk.h -@@ -142,9 +142,11 @@ struct va_format { +@@ -140,9 +140,11 @@ struct va_format { #ifdef CONFIG_EARLY_PRINTK extern asmlinkage __printf(1, 2) void early_printk(const char *fmt, ...); @@ -30,52 +26,11 @@ index 6106befed756..1dba9cb7b91b 100644 #endif #ifdef CONFIG_PRINTK_NMI -diff --git a/kernel/printk/printk.c b/kernel/printk/printk.c -index a9cf2e15f6a3..9c946617baae 100644 --- a/kernel/printk/printk.c +++ b/kernel/printk/printk.c -@@ -1884,26 +1884,6 @@ static bool suppress_message_printing(int level) { return false; } - - #endif /* CONFIG_PRINTK */ - --#ifdef CONFIG_EARLY_PRINTK --struct console *early_console; -- --asmlinkage __visible void early_printk(const char *fmt, ...) --{ -- va_list ap; -- char buf[512]; -- int n; -- -- if (!early_console) -- return; -- -- va_start(ap, fmt); -- n = vscnprintf(buf, sizeof(buf), fmt, ap); -- va_end(ap); -- -- early_console->write(early_console, buf, n); --} --#endif -- - static int __add_preferred_console(char *name, int idx, char *options, - char *brl_options) - { -diff --git a/kernel/printk/printk_safe.c b/kernel/printk/printk_safe.c -index 64f8046586b6..f0855cecec9d 100644 ---- a/kernel/printk/printk_safe.c -+++ b/kernel/printk/printk_safe.c -@@ -22,6 +22,7 @@ - #include - #include - #include -+#include - - #include "internal.h" - -@@ -373,8 +374,67 @@ void __printk_safe_exit(void) - this_cpu_dec(printk_context); - } +@@ -405,6 +405,58 @@ DEFINE_RAW_SPINLOCK(logbuf_lock); + printk_safe_exit_irqrestore(flags); \ + } while (0) +#ifdef CONFIG_EARLY_PRINTK +struct console *early_console; @@ -129,8 +84,13 @@ index 64f8046586b6..f0855cecec9d 100644 +} +#endif + - __printf(1, 0) int vprintk_func(const char *fmt, va_list args) - { + #ifdef CONFIG_PRINTK + DECLARE_WAIT_QUEUE_HEAD(log_wait); + /* the next printk record to read by syslog(READ) or /proc/kmsg */ +@@ -1897,6 +1949,13 @@ asmlinkage int vprintk_emit(int facility + bool in_sched = false; + unsigned long flags; + + /* + * Fall back to early_printk if a debugging subsystem has + * killed printk output @@ -138,14 +98,39 @@ index 64f8046586b6..f0855cecec9d 100644 + if (unlikely(forced_early_printk(fmt, args))) + return 1; + - /* - * Try to use the main logbuf even in NMI. But avoid calling console - * drivers that might have their own locks. -diff --git a/kernel/watchdog_hld.c b/kernel/watchdog_hld.c -index 4ece6028007a..210dccc57c04 100644 + if (level == LOGLEVEL_SCHED) { + level = LOGLEVEL_DEFAULT; + in_sched = true; +@@ -2037,26 +2096,6 @@ static bool suppress_message_printing(in + + #endif /* CONFIG_PRINTK */ + +-#ifdef CONFIG_EARLY_PRINTK +-struct console *early_console; +- +-asmlinkage __visible void early_printk(const char *fmt, ...) +-{ +- va_list ap; +- char buf[512]; +- int n; +- +- if (!early_console) +- return; +- +- va_start(ap, fmt); +- n = vscnprintf(buf, sizeof(buf), fmt, ap); +- va_end(ap); +- +- early_console->write(early_console, buf, n); +-} +-#endif +- + static int __add_preferred_console(char *name, int idx, char *options, + char *brl_options) + { --- a/kernel/watchdog_hld.c +++ b/kernel/watchdog_hld.c -@@ -24,6 +24,8 @@ static DEFINE_PER_CPU(bool, hard_watchdog_warn); +@@ -24,6 +24,8 @@ static DEFINE_PER_CPU(bool, hard_watchdo static DEFINE_PER_CPU(bool, watchdog_nmi_touch); static DEFINE_PER_CPU(struct perf_event *, watchdog_ev); static DEFINE_PER_CPU(struct perf_event *, dead_event); @@ -154,7 +139,7 @@ index 4ece6028007a..210dccc57c04 100644 static struct cpumask dead_events_mask; static unsigned long hardlockup_allcpu_dumped; -@@ -134,6 +136,13 @@ static void watchdog_overflow_callback(struct perf_event *event, +@@ -134,6 +136,13 @@ static void watchdog_overflow_callback(s /* only print hardlockups once */ if (__this_cpu_read(hard_watchdog_warn) == true) return; @@ -168,7 +153,7 @@ index 4ece6028007a..210dccc57c04 100644 pr_emerg("Watchdog detected hard LOCKUP on cpu %d", this_cpu); print_modules(); -@@ -151,6 +160,7 @@ static void watchdog_overflow_callback(struct perf_event *event, +@@ -151,6 +160,7 @@ static void watchdog_overflow_callback(s !test_and_set_bit(0, &hardlockup_allcpu_dumped)) trigger_allbutself_cpu_backtrace(); @@ -176,6 +161,3 @@ index 4ece6028007a..210dccc57c04 100644 if (hardlockup_panic) nmi_panic(regs, "Hard LOCKUP"); --- -2.19.2 - diff --git a/kernel/patches-4.14.x-rt/0141-printk-Add-force_early_printk-boot-param-to-help-wit.patch b/kernel/patches-4.19.x-rt/0060-printk-27force_early_printk-27-boot-param-to-help-with-debugging.patch similarity index 57% rename from kernel/patches-4.14.x-rt/0141-printk-Add-force_early_printk-boot-param-to-help-wit.patch rename to kernel/patches-4.19.x-rt/0060-printk-27force_early_printk-27-boot-param-to-help-with-debugging.patch index 0286e4f04..95c2233c1 100644 --- a/kernel/patches-4.14.x-rt/0141-printk-Add-force_early_printk-boot-param-to-help-wit.patch +++ b/kernel/patches-4.19.x-rt/0060-printk-27force_early_printk-27-boot-param-to-help-with-debugging.patch @@ -1,8 +1,6 @@ -From 76ae4b91ab3d2aacab8be15d1c91bd577fc022d6 Mon Sep 17 00:00:00 2001 +Subject: printk: Add "force_early_printk" boot param to help with debugging From: Peter Zijlstra -Date: Fri, 2 Sep 2011 14:41:29 +0200 -Subject: [PATCH 141/450] printk: Add "force_early_printk" boot param to help - with debugging +Date: Fri, 02 Sep 2011 14:41:29 +0200 Gives me an option to screw printk and actually see what the machine says. @@ -12,14 +10,12 @@ Link: http://lkml.kernel.org/r/1314967289.1301.11.camel@twins Signed-off-by: Thomas Gleixner Link: http://lkml.kernel.org/n/tip-ykb97nsfmobq44xketrxs977@git.kernel.org --- - kernel/printk/printk_safe.c | 7 +++++++ + kernel/printk/printk.c | 7 +++++++ 1 file changed, 7 insertions(+) -diff --git a/kernel/printk/printk_safe.c b/kernel/printk/printk_safe.c -index f0855cecec9d..a24e16bef51c 100644 ---- a/kernel/printk/printk_safe.c -+++ b/kernel/printk/printk_safe.c -@@ -404,6 +404,13 @@ asmlinkage void early_printk(const char *fmt, ...) +--- a/kernel/printk/printk.c ++++ b/kernel/printk/printk.c +@@ -435,6 +435,13 @@ asmlinkage void early_printk(const char */ static bool __read_mostly printk_killswitch; @@ -33,6 +29,3 @@ index f0855cecec9d..a24e16bef51c 100644 void printk_kill(void) { printk_killswitch = true; --- -2.19.2 - diff --git a/kernel/patches-4.14.x-rt/0148-preempt-Provide-preempt_-_-no-rt-variants.patch b/kernel/patches-4.19.x-rt/0061-preempt-nort-rt-variants.patch similarity index 81% rename from kernel/patches-4.14.x-rt/0148-preempt-Provide-preempt_-_-no-rt-variants.patch rename to kernel/patches-4.19.x-rt/0061-preempt-nort-rt-variants.patch index 363422c1b..c9a87c546 100644 --- a/kernel/patches-4.14.x-rt/0148-preempt-Provide-preempt_-_-no-rt-variants.patch +++ b/kernel/patches-4.19.x-rt/0061-preempt-nort-rt-variants.patch @@ -1,18 +1,16 @@ -From 20d2e5cce1e67cdaac043ab7059a97a4982f8a93 Mon Sep 17 00:00:00 2001 From: Thomas Gleixner Date: Fri, 24 Jul 2009 12:38:56 +0200 -Subject: [PATCH 148/450] preempt: Provide preempt_*_(no)rt variants +Subject: preempt: Provide preempt_*_(no)rt variants RT needs a few preempt_disable/enable points which are not necessary otherwise. Implement variants to avoid #ifdeffery. Signed-off-by: Thomas Gleixner + --- - include/linux/preempt.h | 18 +++++++++++++++++- + include/linux/preempt.h | 18 +++++++++++++++++- 1 file changed, 17 insertions(+), 1 deletion(-) -diff --git a/include/linux/preempt.h b/include/linux/preempt.h -index 81c69aeab662..8681df8e1632 100644 --- a/include/linux/preempt.h +++ b/include/linux/preempt.h @@ -181,7 +181,11 @@ do { \ @@ -47,6 +45,3 @@ index 81c69aeab662..8681df8e1632 100644 #ifdef CONFIG_PREEMPT_NOTIFIERS struct preempt_notifier; --- -2.19.2 - diff --git a/kernel/patches-4.14.x-rt/0149-futex-workaround-migrate_disable-enable-in-different.patch b/kernel/patches-4.19.x-rt/0062-futex-workaround-migrate_disable-enable-in-different.patch similarity index 76% rename from kernel/patches-4.14.x-rt/0149-futex-workaround-migrate_disable-enable-in-different.patch rename to kernel/patches-4.19.x-rt/0062-futex-workaround-migrate_disable-enable-in-different.patch index c5ff68125..307166696 100644 --- a/kernel/patches-4.14.x-rt/0149-futex-workaround-migrate_disable-enable-in-different.patch +++ b/kernel/patches-4.19.x-rt/0062-futex-workaround-migrate_disable-enable-in-different.patch @@ -1,8 +1,6 @@ -From 409c9265b1416ec33879fac9864e727f03af4931 Mon Sep 17 00:00:00 2001 From: Thomas Gleixner Date: Wed, 8 Mar 2017 14:23:35 +0100 -Subject: [PATCH 149/450] futex: workaround migrate_disable/enable in different - context +Subject: [PATCH] futex: workaround migrate_disable/enable in different context migrate_disable()/migrate_enable() takes a different path in atomic() vs !atomic() context. These little hacks ensure that we don't underflow / overflow @@ -12,15 +10,13 @@ enabled and unlock it with interrupts disabled. Signed-off-by: Thomas Gleixner Signed-off-by: Sebastian Andrzej Siewior --- - kernel/futex.c | 19 +++++++++++++++++++ + kernel/futex.c | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) -diff --git a/kernel/futex.c b/kernel/futex.c -index 046cd780d057..e70b5b516371 100644 --- a/kernel/futex.c +++ b/kernel/futex.c -@@ -2816,9 +2816,18 @@ static int futex_lock_pi(u32 __user *uaddr, unsigned int flags, - * lock handoff sequence. +@@ -2856,6 +2856,14 @@ static int futex_lock_pi(u32 __user *uad + * before __rt_mutex_start_proxy_lock() is done. */ raw_spin_lock_irq(&q.pi_state->pi_mutex.wait_lock); + /* @@ -32,14 +28,18 @@ index 046cd780d057..e70b5b516371 100644 + migrate_disable(); + spin_unlock(q.lock_ptr); + /* + * __rt_mutex_start_proxy_lock() unconditionally enqueues the @rt_waiter +@@ -2864,6 +2872,7 @@ static int futex_lock_pi(u32 __user *uad + */ ret = __rt_mutex_start_proxy_lock(&q.pi_state->pi_mutex, &rt_waiter, current); raw_spin_unlock_irq(&q.pi_state->pi_mutex.wait_lock); + migrate_enable(); if (ret) { if (ret == 1) -@@ -2965,11 +2974,21 @@ static int futex_unlock_pi(u32 __user *uaddr, unsigned int flags) - * observed. +@@ -3012,11 +3021,21 @@ static int futex_unlock_pi(u32 __user *u + * rt_waiter. Also see the WARN in wake_futex_pi(). */ raw_spin_lock_irq(&pi_state->pi_mutex.wait_lock); + /* @@ -60,6 +60,3 @@ index 046cd780d057..e70b5b516371 100644 put_pi_state(pi_state); /* --- -2.19.2 - diff --git a/kernel/patches-4.14.x-rt/0150-rt-Add-local-irq-locks.patch b/kernel/patches-4.19.x-rt/0063-rt-local-irq-lock.patch similarity index 94% rename from kernel/patches-4.14.x-rt/0150-rt-Add-local-irq-locks.patch rename to kernel/patches-4.19.x-rt/0063-rt-local-irq-lock.patch index 91a45c80a..c27d96204 100644 --- a/kernel/patches-4.14.x-rt/0150-rt-Add-local-irq-locks.patch +++ b/kernel/patches-4.19.x-rt/0063-rt-local-irq-lock.patch @@ -1,7 +1,6 @@ -From e7234d5db109fa4b37ca0d789f00217574e7648a Mon Sep 17 00:00:00 2001 +Subject: rt: Add local irq locks From: Thomas Gleixner Date: Mon, 20 Jun 2011 09:03:47 +0200 -Subject: [PATCH 150/450] rt: Add local irq locks Introduce locallock. For !RT this maps to preempt_disable()/ local_irq_disable() so there is not much that changes. For RT this will @@ -13,14 +12,10 @@ is held and the owner is preempted. Signed-off-by: Thomas Gleixner --- - include/linux/locallock.h | 271 ++++++++++++++++++++++++++++++++++++++ - include/linux/percpu.h | 29 ++++ + include/linux/locallock.h | 271 ++++++++++++++++++++++++++++++++++++++++++++++ + include/linux/percpu.h | 29 ++++ 2 files changed, 300 insertions(+) - create mode 100644 include/linux/locallock.h -diff --git a/include/linux/locallock.h b/include/linux/locallock.h -new file mode 100644 -index 000000000000..d658c2552601 --- /dev/null +++ b/include/linux/locallock.h @@ -0,0 +1,271 @@ @@ -295,8 +290,6 @@ index 000000000000..d658c2552601 +#endif + +#endif -diff --git a/include/linux/percpu.h b/include/linux/percpu.h -index 296bbe49d5d1..4414796e3941 100644 --- a/include/linux/percpu.h +++ b/include/linux/percpu.h @@ -19,6 +19,35 @@ @@ -335,6 +328,3 @@ index 296bbe49d5d1..4414796e3941 100644 /* minimum unit size, also is the maximum supported allocation size */ #define PCPU_MIN_UNIT_SIZE PFN_ALIGN(32 << 10) --- -2.19.2 - diff --git a/kernel/patches-4.14.x-rt/0414-locallock-provide-get-put-_locked_ptr-variants.patch b/kernel/patches-4.19.x-rt/0064-locallock-provide-get-put-_locked_ptr-variants.patch similarity index 65% rename from kernel/patches-4.14.x-rt/0414-locallock-provide-get-put-_locked_ptr-variants.patch rename to kernel/patches-4.19.x-rt/0064-locallock-provide-get-put-_locked_ptr-variants.patch index 97cd0c0cf..14b1bf7ab 100644 --- a/kernel/patches-4.14.x-rt/0414-locallock-provide-get-put-_locked_ptr-variants.patch +++ b/kernel/patches-4.19.x-rt/0064-locallock-provide-get-put-_locked_ptr-variants.patch @@ -1,9 +1,6 @@ -From 6e1dd27911fb7da4408d81137f91d0cef5d946a9 Mon Sep 17 00:00:00 2001 From: Julia Cartwright Date: Mon, 7 May 2018 08:58:56 -0500 -Subject: [PATCH 414/450] locallock: provide {get,put}_locked_ptr() variants - -[ Upstream commit 3d45cf23db4f76cd356ebb0aa4cdaa7d92d1a64e ] +Subject: [PATCH] locallock: provide {get,put}_locked_ptr() variants Provide a set of locallocked accessors for pointers to per-CPU data; this is useful for dynamically-allocated per-CPU regions, for example. @@ -13,16 +10,13 @@ variants. Signed-off-by: Julia Cartwright Signed-off-by: Sebastian Andrzej Siewior -Signed-off-by: Steven Rostedt (VMware) --- - include/linux/locallock.h | 10 ++++++++++ + include/linux/locallock.h | 10 ++++++++++ 1 file changed, 10 insertions(+) -diff --git a/include/linux/locallock.h b/include/linux/locallock.h -index d658c2552601..921eab83cd34 100644 --- a/include/linux/locallock.h +++ b/include/linux/locallock.h -@@ -222,6 +222,14 @@ static inline int __local_unlock_irqrestore(struct local_irq_lock *lv, +@@ -222,6 +222,14 @@ static inline int __local_unlock_irqrest #define put_locked_var(lvar, var) local_unlock(lvar); @@ -37,7 +31,7 @@ index d658c2552601..921eab83cd34 100644 #define local_lock_cpu(lvar) \ ({ \ local_lock(lvar); \ -@@ -262,6 +270,8 @@ static inline void local_irq_lock_init(int lvar) { } +@@ -262,6 +270,8 @@ static inline void local_irq_lock_init(i #define get_locked_var(lvar, var) get_cpu_var(var) #define put_locked_var(lvar, var) put_cpu_var(var) @@ -46,6 +40,3 @@ index d658c2552601..921eab83cd34 100644 #define local_lock_cpu(lvar) get_cpu() #define local_unlock_cpu(lvar) put_cpu() --- -2.19.2 - diff --git a/kernel/patches-4.14.x-rt/0157-mm-scatterlist-Do-not-disable-irqs-on-RT.patch b/kernel/patches-4.19.x-rt/0065-mm-scatterlist-dont-disable-irqs-on-RT.patch similarity index 62% rename from kernel/patches-4.14.x-rt/0157-mm-scatterlist-Do-not-disable-irqs-on-RT.patch rename to kernel/patches-4.19.x-rt/0065-mm-scatterlist-dont-disable-irqs-on-RT.patch index 5d647fb4b..792b70d25 100644 --- a/kernel/patches-4.14.x-rt/0157-mm-scatterlist-Do-not-disable-irqs-on-RT.patch +++ b/kernel/patches-4.19.x-rt/0065-mm-scatterlist-dont-disable-irqs-on-RT.patch @@ -1,21 +1,18 @@ -From 6206e047bf80aa247ee5c84e46c44d067f69e0e7 Mon Sep 17 00:00:00 2001 From: Thomas Gleixner Date: Fri, 3 Jul 2009 08:44:34 -0500 -Subject: [PATCH 157/450] mm/scatterlist: Do not disable irqs on RT +Subject: mm/scatterlist: Do not disable irqs on RT For -RT it is enough to keep pagefault disabled (which is currently handled by kmap_atomic()). Signed-off-by: Thomas Gleixner --- - lib/scatterlist.c | 2 +- + lib/scatterlist.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) -diff --git a/lib/scatterlist.c b/lib/scatterlist.c -index be7b4dd6b68d..d06c15d3d186 100644 --- a/lib/scatterlist.c +++ b/lib/scatterlist.c -@@ -620,7 +620,7 @@ void sg_miter_stop(struct sg_mapping_iter *miter) +@@ -776,7 +776,7 @@ void sg_miter_stop(struct sg_mapping_ite flush_kernel_dcache_page(miter->page); if (miter->__flags & SG_MITER_ATOMIC) { @@ -24,6 +21,3 @@ index be7b4dd6b68d..d06c15d3d186 100644 kunmap_atomic(miter->addr); } else kunmap(miter->page); --- -2.19.2 - diff --git a/kernel/patches-4.14.x-rt/0160-signal-x86-Delay-calling-signals-in-atomic.patch b/kernel/patches-4.19.x-rt/0066-oleg-signal-rt-fix.patch similarity index 79% rename from kernel/patches-4.14.x-rt/0160-signal-x86-Delay-calling-signals-in-atomic.patch rename to kernel/patches-4.19.x-rt/0066-oleg-signal-rt-fix.patch index 153cc218d..60ee65ebd 100644 --- a/kernel/patches-4.14.x-rt/0160-signal-x86-Delay-calling-signals-in-atomic.patch +++ b/kernel/patches-4.19.x-rt/0066-oleg-signal-rt-fix.patch @@ -1,7 +1,6 @@ -From 4961b4ad4cf8bba0c6e80477f4d0045c51f3f2c1 Mon Sep 17 00:00:00 2001 From: Oleg Nesterov Date: Tue, 14 Jul 2015 14:26:34 +0200 -Subject: [PATCH 160/450] signal/x86: Delay calling signals in atomic +Subject: signal/x86: Delay calling signals in atomic On x86_64 we must disable preemption before we enable interrupts for stack faults, int3 and debugging, because the current task is using @@ -30,17 +29,16 @@ Signed-off-by: Oleg Nesterov Signed-off-by: Steven Rostedt Signed-off-by: Thomas Gleixner --- - arch/x86/entry/common.c | 7 +++++++ - arch/x86/include/asm/signal.h | 13 ++++++++++++ - include/linux/sched.h | 4 ++++ - kernel/signal.c | 37 +++++++++++++++++++++++++++++++++-- + + arch/x86/entry/common.c | 7 +++++++ + arch/x86/include/asm/signal.h | 13 +++++++++++++ + include/linux/sched.h | 4 ++++ + kernel/signal.c | 37 +++++++++++++++++++++++++++++++++++-- 4 files changed, 59 insertions(+), 2 deletions(-) -diff --git a/arch/x86/entry/common.c b/arch/x86/entry/common.c -index 60e21ccfb6d6..121f804a9dcb 100644 --- a/arch/x86/entry/common.c +++ b/arch/x86/entry/common.c -@@ -151,6 +151,13 @@ static void exit_to_usermode_loop(struct pt_regs *regs, u32 cached_flags) +@@ -151,6 +151,13 @@ static void exit_to_usermode_loop(struct if (cached_flags & _TIF_NEED_RESCHED) schedule(); @@ -54,8 +52,6 @@ index 60e21ccfb6d6..121f804a9dcb 100644 if (cached_flags & _TIF_UPROBE) uprobe_notify_resume(regs); -diff --git a/arch/x86/include/asm/signal.h b/arch/x86/include/asm/signal.h -index 5f9012ff52ed..7c7846cbab45 100644 --- a/arch/x86/include/asm/signal.h +++ b/arch/x86/include/asm/signal.h @@ -28,6 +28,19 @@ typedef struct { @@ -78,11 +74,9 @@ index 5f9012ff52ed..7c7846cbab45 100644 #ifndef CONFIG_COMPAT typedef sigset_t compat_sigset_t; #endif -diff --git a/include/linux/sched.h b/include/linux/sched.h -index 92f7f58d44f6..a7d48ad0fb96 100644 --- a/include/linux/sched.h +++ b/include/linux/sched.h -@@ -835,6 +835,10 @@ struct task_struct { +@@ -881,6 +881,10 @@ struct task_struct { /* Restored if set_restore_sigmask() was used: */ sigset_t saved_sigmask; struct sigpending pending; @@ -93,11 +87,9 @@ index 92f7f58d44f6..a7d48ad0fb96 100644 unsigned long sas_ss_sp; size_t sas_ss_size; unsigned int sas_ss_flags; -diff --git a/kernel/signal.c b/kernel/signal.c -index 374d60ea3699..c6266045e1b3 100644 --- a/kernel/signal.c +++ b/kernel/signal.c -@@ -1237,8 +1237,8 @@ int do_send_sig_info(int sig, struct siginfo *info, struct task_struct *p, +@@ -1268,8 +1268,8 @@ int do_send_sig_info(int sig, struct sig * We don't want to have recursive SIGSEGV's etc, for example, * that is why we also clear SIGNAL_UNKILLABLE. */ @@ -108,7 +100,7 @@ index 374d60ea3699..c6266045e1b3 100644 { unsigned long int flags; int ret, blocked, ignored; -@@ -1267,6 +1267,39 @@ force_sig_info(int sig, struct siginfo *info, struct task_struct *t) +@@ -1298,6 +1298,39 @@ force_sig_info(int sig, struct siginfo * return ret; } @@ -148,6 +140,3 @@ index 374d60ea3699..c6266045e1b3 100644 /* * Nuke all other threads in the group. */ --- -2.19.2 - diff --git a/kernel/patches-4.14.x-rt/0161-x86-signal-delay-calling-signals-on-32bit.patch b/kernel/patches-4.19.x-rt/0067-x86-signal-delay-calling-signals-on-32bit.patch similarity index 82% rename from kernel/patches-4.14.x-rt/0161-x86-signal-delay-calling-signals-on-32bit.patch rename to kernel/patches-4.19.x-rt/0067-x86-signal-delay-calling-signals-on-32bit.patch index 233c4a6a8..e41ae9db7 100644 --- a/kernel/patches-4.14.x-rt/0161-x86-signal-delay-calling-signals-on-32bit.patch +++ b/kernel/patches-4.19.x-rt/0067-x86-signal-delay-calling-signals-on-32bit.patch @@ -1,7 +1,6 @@ -From ac824740da3271352df385fb547448c4258b9b5a Mon Sep 17 00:00:00 2001 From: Yang Shi Date: Thu, 10 Dec 2015 10:58:51 -0800 -Subject: [PATCH 161/450] x86/signal: delay calling signals on 32bit +Subject: x86/signal: delay calling signals on 32bit When running some ptrace single step tests on x86-32 machine, the below problem is triggered: @@ -27,11 +26,9 @@ from IST context") which was merged in v4.1-rc1. Signed-off-by: Yang Shi Signed-off-by: Sebastian Andrzej Siewior --- - arch/x86/include/asm/signal.h | 2 +- + arch/x86/include/asm/signal.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) -diff --git a/arch/x86/include/asm/signal.h b/arch/x86/include/asm/signal.h -index 7c7846cbab45..39117e57caf2 100644 --- a/arch/x86/include/asm/signal.h +++ b/arch/x86/include/asm/signal.h @@ -37,7 +37,7 @@ typedef struct { @@ -43,6 +40,3 @@ index 7c7846cbab45..39117e57caf2 100644 #define ARCH_RT_DELAYS_SIGNAL_SEND #endif --- -2.19.2 - diff --git a/kernel/patches-4.14.x-rt/0163-buffer_head-Replace-bh_uptodate_lock-for-rt.patch b/kernel/patches-4.19.x-rt/0068-fs-replace-bh_uptodate_lock-for-rt.patch similarity index 63% rename from kernel/patches-4.14.x-rt/0163-buffer_head-Replace-bh_uptodate_lock-for-rt.patch rename to kernel/patches-4.19.x-rt/0068-fs-replace-bh_uptodate_lock-for-rt.patch index 3deba8770..b5e2a42e8 100644 --- a/kernel/patches-4.14.x-rt/0163-buffer_head-Replace-bh_uptodate_lock-for-rt.patch +++ b/kernel/patches-4.19.x-rt/0068-fs-replace-bh_uptodate_lock-for-rt.patch @@ -1,25 +1,21 @@ -From a150441aac2b4e46aac03643590279186690bd8c Mon Sep 17 00:00:00 2001 From: Thomas Gleixner Date: Fri, 18 Mar 2011 09:18:52 +0100 -Subject: [PATCH 163/450] buffer_head: Replace bh_uptodate_lock for -rt +Subject: buffer_head: Replace bh_uptodate_lock for -rt Wrap the bit_spin_lock calls into a separate inline and add the RT replacements with a real spinlock. Signed-off-by: Thomas Gleixner --- - fs/buffer.c | 21 +++++++-------------- - fs/ext4/page-io.c | 6 ++---- - fs/ntfs/aops.c | 10 +++------- - fs/xfs/xfs_aops.c | 6 ++---- - include/linux/buffer_head.h | 34 ++++++++++++++++++++++++++++++++++ - 5 files changed, 48 insertions(+), 29 deletions(-) + fs/buffer.c | 21 +++++++-------------- + fs/ext4/page-io.c | 6 ++---- + fs/ntfs/aops.c | 10 +++------- + include/linux/buffer_head.h | 34 ++++++++++++++++++++++++++++++++++ + 4 files changed, 46 insertions(+), 25 deletions(-) -diff --git a/fs/buffer.c b/fs/buffer.c -index b96f3b98a6ef..4ca5f222537a 100644 --- a/fs/buffer.c +++ b/fs/buffer.c -@@ -302,8 +302,7 @@ static void end_buffer_async_read(struct buffer_head *bh, int uptodate) +@@ -273,8 +273,7 @@ static void end_buffer_async_read(struct * decide that the page is now completely done. */ first = page_buffers(page); @@ -29,7 +25,7 @@ index b96f3b98a6ef..4ca5f222537a 100644 clear_buffer_async_read(bh); unlock_buffer(bh); tmp = bh; -@@ -316,8 +315,7 @@ static void end_buffer_async_read(struct buffer_head *bh, int uptodate) +@@ -287,8 +286,7 @@ static void end_buffer_async_read(struct } tmp = tmp->b_this_page; } while (tmp != bh); @@ -39,7 +35,7 @@ index b96f3b98a6ef..4ca5f222537a 100644 /* * If none of the buffers had errors and they are all -@@ -329,9 +327,7 @@ static void end_buffer_async_read(struct buffer_head *bh, int uptodate) +@@ -300,9 +298,7 @@ static void end_buffer_async_read(struct return; still_busy: @@ -50,7 +46,7 @@ index b96f3b98a6ef..4ca5f222537a 100644 } /* -@@ -358,8 +354,7 @@ void end_buffer_async_write(struct buffer_head *bh, int uptodate) +@@ -329,8 +325,7 @@ void end_buffer_async_write(struct buffe } first = page_buffers(page); @@ -60,7 +56,7 @@ index b96f3b98a6ef..4ca5f222537a 100644 clear_buffer_async_write(bh); unlock_buffer(bh); -@@ -371,15 +366,12 @@ void end_buffer_async_write(struct buffer_head *bh, int uptodate) +@@ -342,15 +337,12 @@ void end_buffer_async_write(struct buffe } tmp = tmp->b_this_page; } @@ -78,7 +74,7 @@ index b96f3b98a6ef..4ca5f222537a 100644 } EXPORT_SYMBOL(end_buffer_async_write); -@@ -3417,6 +3409,7 @@ struct buffer_head *alloc_buffer_head(gfp_t gfp_flags) +@@ -3360,6 +3352,7 @@ struct buffer_head *alloc_buffer_head(gf struct buffer_head *ret = kmem_cache_zalloc(bh_cachep, gfp_flags); if (ret) { INIT_LIST_HEAD(&ret->b_assoc_buffers); @@ -86,11 +82,9 @@ index b96f3b98a6ef..4ca5f222537a 100644 preempt_disable(); __this_cpu_inc(bh_accounting.nr); recalc_bh_state(); -diff --git a/fs/ext4/page-io.c b/fs/ext4/page-io.c -index db7590178dfc..d76364124443 100644 --- a/fs/ext4/page-io.c +++ b/fs/ext4/page-io.c -@@ -95,8 +95,7 @@ static void ext4_finish_bio(struct bio *bio) +@@ -95,8 +95,7 @@ static void ext4_finish_bio(struct bio * * We check all buffers in the page under BH_Uptodate_Lock * to avoid races with other end io clearing async_write flags */ @@ -100,7 +94,7 @@ index db7590178dfc..d76364124443 100644 do { if (bh_offset(bh) < bio_start || bh_offset(bh) + bh->b_size > bio_end) { -@@ -108,8 +107,7 @@ static void ext4_finish_bio(struct bio *bio) +@@ -108,8 +107,7 @@ static void ext4_finish_bio(struct bio * if (bio->bi_status) buffer_io_error(bh); } while ((bh = bh->b_this_page) != head); @@ -110,11 +104,9 @@ index db7590178dfc..d76364124443 100644 if (!under_io) { #ifdef CONFIG_EXT4_FS_ENCRYPTION if (data_page) -diff --git a/fs/ntfs/aops.c b/fs/ntfs/aops.c -index cc91856b5e2d..e11411997769 100644 --- a/fs/ntfs/aops.c +++ b/fs/ntfs/aops.c -@@ -108,8 +108,7 @@ static void ntfs_end_buffer_async_read(struct buffer_head *bh, int uptodate) +@@ -106,8 +106,7 @@ static void ntfs_end_buffer_async_read(s "0x%llx.", (unsigned long long)bh->b_blocknr); } first = page_buffers(page); @@ -124,7 +116,7 @@ index cc91856b5e2d..e11411997769 100644 clear_buffer_async_read(bh); unlock_buffer(bh); tmp = bh; -@@ -124,8 +123,7 @@ static void ntfs_end_buffer_async_read(struct buffer_head *bh, int uptodate) +@@ -122,8 +121,7 @@ static void ntfs_end_buffer_async_read(s } tmp = tmp->b_this_page; } while (tmp != bh); @@ -134,7 +126,7 @@ index cc91856b5e2d..e11411997769 100644 /* * If none of the buffers had errors then we can set the page uptodate, * but we first have to perform the post read mst fixups, if the -@@ -160,9 +158,7 @@ static void ntfs_end_buffer_async_read(struct buffer_head *bh, int uptodate) +@@ -156,9 +154,7 @@ static void ntfs_end_buffer_async_read(s unlock_page(page); return; still_busy: @@ -145,32 +137,6 @@ index cc91856b5e2d..e11411997769 100644 } /** -diff --git a/fs/xfs/xfs_aops.c b/fs/xfs/xfs_aops.c -index b0cccf8a81a8..eaa4383defec 100644 ---- a/fs/xfs/xfs_aops.c -+++ b/fs/xfs/xfs_aops.c -@@ -120,8 +120,7 @@ xfs_finish_page_writeback( - ASSERT(bvec->bv_offset + bvec->bv_len <= PAGE_SIZE); - ASSERT((bvec->bv_len & (i_blocksize(inode) - 1)) == 0); - -- local_irq_save(flags); -- bit_spin_lock(BH_Uptodate_Lock, &head->b_state); -+ flags = bh_uptodate_lock_irqsave(head); - do { - if (off >= bvec->bv_offset && - off < bvec->bv_offset + bvec->bv_len) { -@@ -143,8 +142,7 @@ xfs_finish_page_writeback( - } - off += bh->b_size; - } while ((bh = bh->b_this_page) != head); -- bit_spin_unlock(BH_Uptodate_Lock, &head->b_state); -- local_irq_restore(flags); -+ bh_uptodate_unlock_irqrestore(head, flags); - - if (!busy) - end_page_writeback(bvec->bv_page); -diff --git a/include/linux/buffer_head.h b/include/linux/buffer_head.h -index afa37f807f12..d0bd1957e8b6 100644 --- a/include/linux/buffer_head.h +++ b/include/linux/buffer_head.h @@ -76,8 +76,42 @@ struct buffer_head { @@ -216,6 +182,3 @@ index afa37f807f12..d0bd1957e8b6 100644 /* * macro tricks to expand the set_buffer_foo(), clear_buffer_foo() * and buffer_foo() functions. --- -2.19.2 - diff --git a/kernel/patches-4.14.x-rt/0164-fs-jbd-jbd2-Make-state-lock-and-journal-head-lock-rt.patch b/kernel/patches-4.19.x-rt/0069-fs-jbd-replace-bh_state-lock.patch similarity index 76% rename from kernel/patches-4.14.x-rt/0164-fs-jbd-jbd2-Make-state-lock-and-journal-head-lock-rt.patch rename to kernel/patches-4.19.x-rt/0069-fs-jbd-replace-bh_state-lock.patch index 3c4acc75b..a56bc6909 100644 --- a/kernel/patches-4.14.x-rt/0164-fs-jbd-jbd2-Make-state-lock-and-journal-head-lock-rt.patch +++ b/kernel/patches-4.19.x-rt/0069-fs-jbd-replace-bh_state-lock.patch @@ -1,8 +1,6 @@ -From 9aef918d94f719307028a7cf9c94cae820ca712e Mon Sep 17 00:00:00 2001 From: Thomas Gleixner Date: Fri, 18 Mar 2011 10:11:25 +0100 -Subject: [PATCH 164/450] fs: jbd/jbd2: Make state lock and journal head lock - rt safe +Subject: fs: jbd/jbd2: Make state lock and journal head lock rt safe bit_spin_locks break under RT. @@ -12,13 +10,7 @@ Signed-off-by: Thomas Gleixner include/linux/buffer_head.h | 8 ++++++++ include/linux/jbd2.h | 24 ++++++++++++++++++++++++ 2 files changed, 32 insertions(+) ---- - include/linux/buffer_head.h | 8 ++++++++ - include/linux/jbd2.h | 24 ++++++++++++++++++++++++ - 2 files changed, 32 insertions(+) -diff --git a/include/linux/buffer_head.h b/include/linux/buffer_head.h -index d0bd1957e8b6..48505fade7e1 100644 --- a/include/linux/buffer_head.h +++ b/include/linux/buffer_head.h @@ -78,6 +78,10 @@ struct buffer_head { @@ -32,7 +24,7 @@ index d0bd1957e8b6..48505fade7e1 100644 #endif }; -@@ -109,6 +113,10 @@ static inline void buffer_head_init_locks(struct buffer_head *bh) +@@ -109,6 +113,10 @@ static inline void buffer_head_init_lock { #ifdef CONFIG_PREEMPT_RT_BASE spin_lock_init(&bh->b_uptodate_lock); @@ -43,11 +35,9 @@ index d0bd1957e8b6..48505fade7e1 100644 #endif } -diff --git a/include/linux/jbd2.h b/include/linux/jbd2.h -index 29290bfb94a8..32379bfab9f0 100644 --- a/include/linux/jbd2.h +++ b/include/linux/jbd2.h -@@ -347,32 +347,56 @@ static inline struct journal_head *bh2jh(struct buffer_head *bh) +@@ -347,32 +347,56 @@ static inline struct journal_head *bh2jh static inline void jbd_lock_bh_state(struct buffer_head *bh) { @@ -104,6 +94,3 @@ index 29290bfb94a8..32379bfab9f0 100644 } #define J_ASSERT(assert) BUG_ON(!(assert)) --- -2.19.2 - diff --git a/kernel/patches-4.14.x-rt/0165-list_bl-Make-list-head-locking-RT-safe.patch b/kernel/patches-4.19.x-rt/0070-list_bl.h-make-list-head-locking-RT-safe.patch similarity index 90% rename from kernel/patches-4.14.x-rt/0165-list_bl-Make-list-head-locking-RT-safe.patch rename to kernel/patches-4.19.x-rt/0070-list_bl.h-make-list-head-locking-RT-safe.patch index 0210ebb2a..9ea1a600d 100644 --- a/kernel/patches-4.14.x-rt/0165-list_bl-Make-list-head-locking-RT-safe.patch +++ b/kernel/patches-4.19.x-rt/0070-list_bl.h-make-list-head-locking-RT-safe.patch @@ -1,7 +1,6 @@ -From 1e16a8872db9416915db9a87254e95be8a2d5235 Mon Sep 17 00:00:00 2001 From: Paul Gortmaker Date: Fri, 21 Jun 2013 15:07:25 -0400 -Subject: [PATCH 165/450] list_bl: Make list head locking RT safe +Subject: list_bl: Make list head locking RT safe As per changes in include/linux/jbd_common.h for avoiding the bit_spin_locks on RT ("fs: jbd/jbd2: Make state lock and journal @@ -48,11 +47,9 @@ concern. Signed-off-by: Paul Gortmaker Signed-off-by: Sebastian Andrzej Siewior --- - include/linux/list_bl.h | 28 ++++++++++++++++++++++++++-- + include/linux/list_bl.h | 28 ++++++++++++++++++++++++++-- 1 file changed, 26 insertions(+), 2 deletions(-) -diff --git a/include/linux/list_bl.h b/include/linux/list_bl.h -index 3fc2cc57ba1b..69b659259bac 100644 --- a/include/linux/list_bl.h +++ b/include/linux/list_bl.h @@ -3,6 +3,7 @@ @@ -88,7 +85,7 @@ index 3fc2cc57ba1b..69b659259bac 100644 static inline void INIT_HLIST_BL_NODE(struct hlist_bl_node *h) { -@@ -119,12 +129,26 @@ static inline void hlist_bl_del_init(struct hlist_bl_node *n) +@@ -119,12 +129,26 @@ static inline void hlist_bl_del_init(str static inline void hlist_bl_lock(struct hlist_bl_head *b) { @@ -115,6 +112,3 @@ index 3fc2cc57ba1b..69b659259bac 100644 } static inline bool hlist_bl_is_locked(struct hlist_bl_head *b) --- -2.19.2 - diff --git a/kernel/patches-4.14.x-rt/0166-list_bl-fixup-bogus-lockdep-warning.patch b/kernel/patches-4.19.x-rt/0071-list_bl-fixup-bogus-lockdep-warning.patch similarity index 90% rename from kernel/patches-4.14.x-rt/0166-list_bl-fixup-bogus-lockdep-warning.patch rename to kernel/patches-4.19.x-rt/0071-list_bl-fixup-bogus-lockdep-warning.patch index 25e050f7c..43ebad4b9 100644 --- a/kernel/patches-4.14.x-rt/0166-list_bl-fixup-bogus-lockdep-warning.patch +++ b/kernel/patches-4.19.x-rt/0071-list_bl-fixup-bogus-lockdep-warning.patch @@ -1,7 +1,6 @@ -From 1b38bd241ee47e3750c0dce98360f53cb2180acd Mon Sep 17 00:00:00 2001 From: Josh Cartwright Date: Thu, 31 Mar 2016 00:04:25 -0500 -Subject: [PATCH 166/450] list_bl: fixup bogus lockdep warning +Subject: [PATCH] list_bl: fixup bogus lockdep warning At first glance, the use of 'static inline' seems appropriate for INIT_HLIST_BL_HEAD(). @@ -70,11 +69,9 @@ Tested-by: Luis Claudio R. Goncalves Signed-off-by: Josh Cartwright Signed-off-by: Sebastian Andrzej Siewior --- - include/linux/list_bl.h | 12 +++++++----- + include/linux/list_bl.h | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) -diff --git a/include/linux/list_bl.h b/include/linux/list_bl.h -index 69b659259bac..0b5de7d9ffcf 100644 --- a/include/linux/list_bl.h +++ b/include/linux/list_bl.h @@ -43,13 +43,15 @@ struct hlist_bl_node { @@ -98,6 +95,3 @@ index 69b659259bac..0b5de7d9ffcf 100644 static inline void INIT_HLIST_BL_NODE(struct hlist_bl_node *h) { --- -2.19.2 - diff --git a/kernel/patches-4.14.x-rt/0167-genirq-Disable-irqpoll-on-rt.patch b/kernel/patches-4.19.x-rt/0072-genirq-disable-irqpoll-on-rt.patch similarity index 68% rename from kernel/patches-4.14.x-rt/0167-genirq-Disable-irqpoll-on-rt.patch rename to kernel/patches-4.19.x-rt/0072-genirq-disable-irqpoll-on-rt.patch index a10648182..4b0751e6c 100644 --- a/kernel/patches-4.14.x-rt/0167-genirq-Disable-irqpoll-on-rt.patch +++ b/kernel/patches-4.19.x-rt/0072-genirq-disable-irqpoll-on-rt.patch @@ -1,21 +1,19 @@ -From 2df832c6644a848e7f2cdf936badb72358a8daf4 Mon Sep 17 00:00:00 2001 From: Ingo Molnar Date: Fri, 3 Jul 2009 08:29:57 -0500 -Subject: [PATCH 167/450] genirq: Disable irqpoll on -rt +Subject: genirq: Disable irqpoll on -rt Creates long latencies for no value Signed-off-by: Ingo Molnar Signed-off-by: Thomas Gleixner + --- - kernel/irq/spurious.c | 8 ++++++++ + kernel/irq/spurious.c | 8 ++++++++ 1 file changed, 8 insertions(+) -diff --git a/kernel/irq/spurious.c b/kernel/irq/spurious.c -index 987d7bca4864..75347fb1dfea 100644 --- a/kernel/irq/spurious.c +++ b/kernel/irq/spurious.c -@@ -445,6 +445,10 @@ MODULE_PARM_DESC(noirqdebug, "Disable irq lockup detection when true"); +@@ -442,6 +442,10 @@ MODULE_PARM_DESC(noirqdebug, "Disable ir static int __init irqfixup_setup(char *str) { @@ -26,7 +24,7 @@ index 987d7bca4864..75347fb1dfea 100644 irqfixup = 1; printk(KERN_WARNING "Misrouted IRQ fixup support enabled.\n"); printk(KERN_WARNING "This may impact system performance.\n"); -@@ -457,6 +461,10 @@ module_param(irqfixup, int, 0644); +@@ -454,6 +458,10 @@ module_param(irqfixup, int, 0644); static int __init irqpoll_setup(char *str) { @@ -37,6 +35,3 @@ index 987d7bca4864..75347fb1dfea 100644 irqfixup = 2; printk(KERN_WARNING "Misrouted IRQ fixup and polling support " "enabled\n"); --- -2.19.2 - diff --git a/kernel/patches-4.19.x-rt/0073-genirq-force-threading.patch b/kernel/patches-4.19.x-rt/0073-genirq-force-threading.patch new file mode 100644 index 000000000..d89fe34ce --- /dev/null +++ b/kernel/patches-4.19.x-rt/0073-genirq-force-threading.patch @@ -0,0 +1,45 @@ +Subject: genirq: Force interrupt thread on RT +From: Thomas Gleixner +Date: Sun, 03 Apr 2011 11:57:29 +0200 + +Force threaded_irqs and optimize the code (force_irqthreads) in regard +to this. + +Signed-off-by: Thomas Gleixner +--- + include/linux/interrupt.h | 4 ++++ + kernel/irq/manage.c | 2 ++ + 2 files changed, 6 insertions(+) + +--- a/include/linux/interrupt.h ++++ b/include/linux/interrupt.h +@@ -427,7 +427,11 @@ extern int irq_set_irqchip_state(unsigne + bool state); + + #ifdef CONFIG_IRQ_FORCED_THREADING ++# ifdef CONFIG_PREEMPT_RT_BASE ++# define force_irqthreads (true) ++# else + extern bool force_irqthreads; ++# endif + #else + #define force_irqthreads (0) + #endif +--- a/kernel/irq/manage.c ++++ b/kernel/irq/manage.c +@@ -23,6 +23,7 @@ + #include "internals.h" + + #ifdef CONFIG_IRQ_FORCED_THREADING ++# ifndef CONFIG_PREEMPT_RT_BASE + __read_mostly bool force_irqthreads; + EXPORT_SYMBOL_GPL(force_irqthreads); + +@@ -32,6 +33,7 @@ static int __init setup_forced_irqthread + return 0; + } + early_param("threadirqs", setup_forced_irqthreads); ++# endif + #endif + + static void __synchronize_hardirq(struct irq_desc *desc) diff --git a/kernel/patches-4.19.x-rt/0074-0001-Split-IRQ-off-and-zone-lock-while-freeing-pages-from.patch b/kernel/patches-4.19.x-rt/0074-0001-Split-IRQ-off-and-zone-lock-while-freeing-pages-from.patch new file mode 100644 index 000000000..f0996b587 --- /dev/null +++ b/kernel/patches-4.19.x-rt/0074-0001-Split-IRQ-off-and-zone-lock-while-freeing-pages-from.patch @@ -0,0 +1,166 @@ +From: Peter Zijlstra +Date: Mon, 28 May 2018 15:24:20 +0200 +Subject: [PATCH 1/4] Split IRQ-off and zone->lock while freeing pages from PCP + list #1 + +Split the IRQ-off section while accessing the PCP list from zone->lock +while freeing pages. +Introcude isolate_pcp_pages() which separates the pages from the PCP +list onto a temporary list and then free the temporary list via +free_pcppages_bulk(). + +Signed-off-by: Peter Zijlstra +Signed-off-by: Sebastian Andrzej Siewior +--- + mm/page_alloc.c | 82 +++++++++++++++++++++++++++++++++++--------------------- + 1 file changed, 52 insertions(+), 30 deletions(-) + +--- a/mm/page_alloc.c ++++ b/mm/page_alloc.c +@@ -1095,7 +1095,7 @@ static inline void prefetch_buddy(struct + } + + /* +- * Frees a number of pages from the PCP lists ++ * Frees a number of pages which have been collected from the pcp lists. + * Assumes all pages on list are in same zone, and of same order. + * count is the number of pages to free. + * +@@ -1106,14 +1106,41 @@ static inline void prefetch_buddy(struct + * pinned" detection logic. + */ + static void free_pcppages_bulk(struct zone *zone, int count, +- struct per_cpu_pages *pcp) ++ struct list_head *head) ++{ ++ bool isolated_pageblocks; ++ struct page *page, *tmp; ++ unsigned long flags; ++ ++ spin_lock_irqsave(&zone->lock, flags); ++ isolated_pageblocks = has_isolate_pageblock(zone); ++ ++ /* ++ * Use safe version since after __free_one_page(), ++ * page->lru.next will not point to original list. ++ */ ++ list_for_each_entry_safe(page, tmp, head, lru) { ++ int mt = get_pcppage_migratetype(page); ++ /* MIGRATE_ISOLATE page should not go to pcplists */ ++ VM_BUG_ON_PAGE(is_migrate_isolate(mt), page); ++ /* Pageblock could have been isolated meanwhile */ ++ if (unlikely(isolated_pageblocks)) ++ mt = get_pageblock_migratetype(page); ++ ++ __free_one_page(page, page_to_pfn(page), zone, 0, mt); ++ trace_mm_page_pcpu_drain(page, 0, mt); ++ } ++ spin_unlock_irqrestore(&zone->lock, flags); ++} ++ ++static void isolate_pcp_pages(int count, struct per_cpu_pages *pcp, ++ struct list_head *dst) ++ + { + int migratetype = 0; + int batch_free = 0; + int prefetch_nr = 0; +- bool isolated_pageblocks; +- struct page *page, *tmp; +- LIST_HEAD(head); ++ struct page *page; + + while (count) { + struct list_head *list; +@@ -1145,7 +1172,7 @@ static void free_pcppages_bulk(struct zo + if (bulkfree_pcp_prepare(page)) + continue; + +- list_add_tail(&page->lru, &head); ++ list_add_tail(&page->lru, dst); + + /* + * We are going to put the page back to the global +@@ -1160,26 +1187,6 @@ static void free_pcppages_bulk(struct zo + prefetch_buddy(page); + } while (--count && --batch_free && !list_empty(list)); + } +- +- spin_lock(&zone->lock); +- isolated_pageblocks = has_isolate_pageblock(zone); +- +- /* +- * Use safe version since after __free_one_page(), +- * page->lru.next will not point to original list. +- */ +- list_for_each_entry_safe(page, tmp, &head, lru) { +- int mt = get_pcppage_migratetype(page); +- /* MIGRATE_ISOLATE page should not go to pcplists */ +- VM_BUG_ON_PAGE(is_migrate_isolate(mt), page); +- /* Pageblock could have been isolated meanwhile */ +- if (unlikely(isolated_pageblocks)) +- mt = get_pageblock_migratetype(page); +- +- __free_one_page(page, page_to_pfn(page), zone, 0, mt); +- trace_mm_page_pcpu_drain(page, 0, mt); +- } +- spin_unlock(&zone->lock); + } + + static void free_one_page(struct zone *zone, +@@ -2536,13 +2543,18 @@ void drain_zone_pages(struct zone *zone, + { + unsigned long flags; + int to_drain, batch; ++ LIST_HEAD(dst); + + local_irq_save(flags); + batch = READ_ONCE(pcp->batch); + to_drain = min(pcp->count, batch); + if (to_drain > 0) +- free_pcppages_bulk(zone, to_drain, pcp); ++ isolate_pcp_pages(to_drain, pcp, &dst); ++ + local_irq_restore(flags); ++ ++ if (to_drain > 0) ++ free_pcppages_bulk(zone, to_drain, &dst); + } + #endif + +@@ -2558,14 +2570,21 @@ static void drain_pages_zone(unsigned in + unsigned long flags; + struct per_cpu_pageset *pset; + struct per_cpu_pages *pcp; ++ LIST_HEAD(dst); ++ int count; + + local_irq_save(flags); + pset = per_cpu_ptr(zone->pageset, cpu); + + pcp = &pset->pcp; +- if (pcp->count) +- free_pcppages_bulk(zone, pcp->count, pcp); ++ count = pcp->count; ++ if (count) ++ isolate_pcp_pages(count, pcp, &dst); ++ + local_irq_restore(flags); ++ ++ if (count) ++ free_pcppages_bulk(zone, count, &dst); + } + + /* +@@ -2787,7 +2806,10 @@ static void free_unref_page_commit(struc + pcp->count++; + if (pcp->count >= pcp->high) { + unsigned long batch = READ_ONCE(pcp->batch); +- free_pcppages_bulk(zone, batch, pcp); ++ LIST_HEAD(dst); ++ ++ isolate_pcp_pages(batch, pcp, &dst); ++ free_pcppages_bulk(zone, batch, &dst); + } + } + diff --git a/kernel/patches-4.19.x-rt/0075-0002-Split-IRQ-off-and-zone-lock-while-freeing-pages-from.patch b/kernel/patches-4.19.x-rt/0075-0002-Split-IRQ-off-and-zone-lock-while-freeing-pages-from.patch new file mode 100644 index 000000000..e9b94d119 --- /dev/null +++ b/kernel/patches-4.19.x-rt/0075-0002-Split-IRQ-off-and-zone-lock-while-freeing-pages-from.patch @@ -0,0 +1,165 @@ +From: Peter Zijlstra +Date: Mon, 28 May 2018 15:24:21 +0200 +Subject: [PATCH 2/4] Split IRQ-off and zone->lock while freeing pages from PCP + list #2 + +Split the IRQ-off section while accessing the PCP list from zone->lock +while freeing pages. +Introcude isolate_pcp_pages() which separates the pages from the PCP +list onto a temporary list and then free the temporary list via +free_pcppages_bulk(). + +Signed-off-by: Peter Zijlstra +Signed-off-by: Sebastian Andrzej Siewior +--- + mm/page_alloc.c | 60 ++++++++++++++++++++++++++++++++++++++++++++++---------- + 1 file changed, 50 insertions(+), 10 deletions(-) + +--- a/mm/page_alloc.c ++++ b/mm/page_alloc.c +@@ -1105,8 +1105,8 @@ static inline void prefetch_buddy(struct + * And clear the zone's pages_scanned counter, to hold off the "all pages are + * pinned" detection logic. + */ +-static void free_pcppages_bulk(struct zone *zone, int count, +- struct list_head *head) ++static void free_pcppages_bulk(struct zone *zone, struct list_head *head, ++ bool zone_retry) + { + bool isolated_pageblocks; + struct page *page, *tmp; +@@ -1121,12 +1121,27 @@ static void free_pcppages_bulk(struct zo + */ + list_for_each_entry_safe(page, tmp, head, lru) { + int mt = get_pcppage_migratetype(page); ++ ++ if (page_zone(page) != zone) { ++ /* ++ * free_unref_page_list() sorts pages by zone. If we end ++ * up with pages from a different NUMA nodes belonging ++ * to the same ZONE index then we need to redo with the ++ * correct ZONE pointer. Skip the page for now, redo it ++ * on the next iteration. ++ */ ++ WARN_ON_ONCE(zone_retry == false); ++ if (zone_retry) ++ continue; ++ } ++ + /* MIGRATE_ISOLATE page should not go to pcplists */ + VM_BUG_ON_PAGE(is_migrate_isolate(mt), page); + /* Pageblock could have been isolated meanwhile */ + if (unlikely(isolated_pageblocks)) + mt = get_pageblock_migratetype(page); + ++ list_del(&page->lru); + __free_one_page(page, page_to_pfn(page), zone, 0, mt); + trace_mm_page_pcpu_drain(page, 0, mt); + } +@@ -2554,7 +2569,7 @@ void drain_zone_pages(struct zone *zone, + local_irq_restore(flags); + + if (to_drain > 0) +- free_pcppages_bulk(zone, to_drain, &dst); ++ free_pcppages_bulk(zone, &dst, false); + } + #endif + +@@ -2584,7 +2599,7 @@ static void drain_pages_zone(unsigned in + local_irq_restore(flags); + + if (count) +- free_pcppages_bulk(zone, count, &dst); ++ free_pcppages_bulk(zone, &dst, false); + } + + /* +@@ -2777,7 +2792,8 @@ static bool free_unref_page_prepare(stru + return true; + } + +-static void free_unref_page_commit(struct page *page, unsigned long pfn) ++static void free_unref_page_commit(struct page *page, unsigned long pfn, ++ struct list_head *dst) + { + struct zone *zone = page_zone(page); + struct per_cpu_pages *pcp; +@@ -2806,10 +2822,8 @@ static void free_unref_page_commit(struc + pcp->count++; + if (pcp->count >= pcp->high) { + unsigned long batch = READ_ONCE(pcp->batch); +- LIST_HEAD(dst); + +- isolate_pcp_pages(batch, pcp, &dst); +- free_pcppages_bulk(zone, batch, &dst); ++ isolate_pcp_pages(batch, pcp, dst); + } + } + +@@ -2820,13 +2834,17 @@ void free_unref_page(struct page *page) + { + unsigned long flags; + unsigned long pfn = page_to_pfn(page); ++ struct zone *zone = page_zone(page); ++ LIST_HEAD(dst); + + if (!free_unref_page_prepare(page, pfn)) + return; + + local_irq_save(flags); +- free_unref_page_commit(page, pfn); ++ free_unref_page_commit(page, pfn, &dst); + local_irq_restore(flags); ++ if (!list_empty(&dst)) ++ free_pcppages_bulk(zone, &dst, false); + } + + /* +@@ -2837,6 +2855,11 @@ void free_unref_page_list(struct list_he + struct page *page, *next; + unsigned long flags, pfn; + int batch_count = 0; ++ struct list_head dsts[__MAX_NR_ZONES]; ++ int i; ++ ++ for (i = 0; i < __MAX_NR_ZONES; i++) ++ INIT_LIST_HEAD(&dsts[i]); + + /* Prepare pages for freeing */ + list_for_each_entry_safe(page, next, list, lru) { +@@ -2849,10 +2872,12 @@ void free_unref_page_list(struct list_he + local_irq_save(flags); + list_for_each_entry_safe(page, next, list, lru) { + unsigned long pfn = page_private(page); ++ enum zone_type type; + + set_page_private(page, 0); + trace_mm_page_free_batched(page); +- free_unref_page_commit(page, pfn); ++ type = page_zonenum(page); ++ free_unref_page_commit(page, pfn, &dsts[type]); + + /* + * Guard against excessive IRQ disabled times when we get +@@ -2865,6 +2890,21 @@ void free_unref_page_list(struct list_he + } + } + local_irq_restore(flags); ++ ++ for (i = 0; i < __MAX_NR_ZONES; ) { ++ struct page *page; ++ struct zone *zone; ++ ++ if (list_empty(&dsts[i])) { ++ i++; ++ continue; ++ } ++ ++ page = list_first_entry(&dsts[i], struct page, lru); ++ zone = page_zone(page); ++ ++ free_pcppages_bulk(zone, &dsts[i], true); ++ } + } + + /* diff --git a/kernel/patches-4.19.x-rt/0076-0003-mm-SLxB-change-list_lock-to-raw_spinlock_t.patch b/kernel/patches-4.19.x-rt/0076-0003-mm-SLxB-change-list_lock-to-raw_spinlock_t.patch new file mode 100644 index 000000000..f0bc5d128 --- /dev/null +++ b/kernel/patches-4.19.x-rt/0076-0003-mm-SLxB-change-list_lock-to-raw_spinlock_t.patch @@ -0,0 +1,608 @@ +From: Thomas Gleixner +Date: Mon, 28 May 2018 15:24:22 +0200 +Subject: [PATCH 3/4] mm/SLxB: change list_lock to raw_spinlock_t + +The list_lock is used with used with IRQs off on RT. Make it a raw_spinlock_t +otherwise the interrupts won't be disabled on -RT. The locking rules remain +the same on !RT. +This patch changes it for SLAB and SLUB since both share the same header +file for struct kmem_cache_node defintion. + +Signed-off-by: Thomas Gleixner +Signed-off-by: Sebastian Andrzej Siewior +--- + mm/slab.c | 94 +++++++++++++++++++++++++++++++------------------------------- + mm/slab.h | 2 - + mm/slub.c | 50 ++++++++++++++++---------------- + 3 files changed, 73 insertions(+), 73 deletions(-) + +--- a/mm/slab.c ++++ b/mm/slab.c +@@ -233,7 +233,7 @@ static void kmem_cache_node_init(struct + parent->shared = NULL; + parent->alien = NULL; + parent->colour_next = 0; +- spin_lock_init(&parent->list_lock); ++ raw_spin_lock_init(&parent->list_lock); + parent->free_objects = 0; + parent->free_touched = 0; + } +@@ -600,9 +600,9 @@ static noinline void cache_free_pfmemall + page_node = page_to_nid(page); + n = get_node(cachep, page_node); + +- spin_lock(&n->list_lock); ++ raw_spin_lock(&n->list_lock); + free_block(cachep, &objp, 1, page_node, &list); +- spin_unlock(&n->list_lock); ++ raw_spin_unlock(&n->list_lock); + + slabs_destroy(cachep, &list); + } +@@ -730,7 +730,7 @@ static void __drain_alien_cache(struct k + struct kmem_cache_node *n = get_node(cachep, node); + + if (ac->avail) { +- spin_lock(&n->list_lock); ++ raw_spin_lock(&n->list_lock); + /* + * Stuff objects into the remote nodes shared array first. + * That way we could avoid the overhead of putting the objects +@@ -741,7 +741,7 @@ static void __drain_alien_cache(struct k + + free_block(cachep, ac->entry, ac->avail, node, list); + ac->avail = 0; +- spin_unlock(&n->list_lock); ++ raw_spin_unlock(&n->list_lock); + } + } + +@@ -814,9 +814,9 @@ static int __cache_free_alien(struct kme + slabs_destroy(cachep, &list); + } else { + n = get_node(cachep, page_node); +- spin_lock(&n->list_lock); ++ raw_spin_lock(&n->list_lock); + free_block(cachep, &objp, 1, page_node, &list); +- spin_unlock(&n->list_lock); ++ raw_spin_unlock(&n->list_lock); + slabs_destroy(cachep, &list); + } + return 1; +@@ -857,10 +857,10 @@ static int init_cache_node(struct kmem_c + */ + n = get_node(cachep, node); + if (n) { +- spin_lock_irq(&n->list_lock); ++ raw_spin_lock_irq(&n->list_lock); + n->free_limit = (1 + nr_cpus_node(node)) * cachep->batchcount + + cachep->num; +- spin_unlock_irq(&n->list_lock); ++ raw_spin_unlock_irq(&n->list_lock); + + return 0; + } +@@ -939,7 +939,7 @@ static int setup_kmem_cache_node(struct + goto fail; + + n = get_node(cachep, node); +- spin_lock_irq(&n->list_lock); ++ raw_spin_lock_irq(&n->list_lock); + if (n->shared && force_change) { + free_block(cachep, n->shared->entry, + n->shared->avail, node, &list); +@@ -957,7 +957,7 @@ static int setup_kmem_cache_node(struct + new_alien = NULL; + } + +- spin_unlock_irq(&n->list_lock); ++ raw_spin_unlock_irq(&n->list_lock); + slabs_destroy(cachep, &list); + + /* +@@ -996,7 +996,7 @@ static void cpuup_canceled(long cpu) + if (!n) + continue; + +- spin_lock_irq(&n->list_lock); ++ raw_spin_lock_irq(&n->list_lock); + + /* Free limit for this kmem_cache_node */ + n->free_limit -= cachep->batchcount; +@@ -1009,7 +1009,7 @@ static void cpuup_canceled(long cpu) + } + + if (!cpumask_empty(mask)) { +- spin_unlock_irq(&n->list_lock); ++ raw_spin_unlock_irq(&n->list_lock); + goto free_slab; + } + +@@ -1023,7 +1023,7 @@ static void cpuup_canceled(long cpu) + alien = n->alien; + n->alien = NULL; + +- spin_unlock_irq(&n->list_lock); ++ raw_spin_unlock_irq(&n->list_lock); + + kfree(shared); + if (alien) { +@@ -1207,7 +1207,7 @@ static void __init init_list(struct kmem + /* + * Do not assume that spinlocks can be initialized via memcpy: + */ +- spin_lock_init(&ptr->list_lock); ++ raw_spin_lock_init(&ptr->list_lock); + + MAKE_ALL_LISTS(cachep, ptr, nodeid); + cachep->node[nodeid] = ptr; +@@ -1378,11 +1378,11 @@ slab_out_of_memory(struct kmem_cache *ca + for_each_kmem_cache_node(cachep, node, n) { + unsigned long total_slabs, free_slabs, free_objs; + +- spin_lock_irqsave(&n->list_lock, flags); ++ raw_spin_lock_irqsave(&n->list_lock, flags); + total_slabs = n->total_slabs; + free_slabs = n->free_slabs; + free_objs = n->free_objects; +- spin_unlock_irqrestore(&n->list_lock, flags); ++ raw_spin_unlock_irqrestore(&n->list_lock, flags); + + pr_warn(" node %d: slabs: %ld/%ld, objs: %ld/%ld\n", + node, total_slabs - free_slabs, total_slabs, +@@ -2175,7 +2175,7 @@ static void check_spinlock_acquired(stru + { + #ifdef CONFIG_SMP + check_irq_off(); +- assert_spin_locked(&get_node(cachep, numa_mem_id())->list_lock); ++ assert_raw_spin_locked(&get_node(cachep, numa_mem_id())->list_lock); + #endif + } + +@@ -2183,7 +2183,7 @@ static void check_spinlock_acquired_node + { + #ifdef CONFIG_SMP + check_irq_off(); +- assert_spin_locked(&get_node(cachep, node)->list_lock); ++ assert_raw_spin_locked(&get_node(cachep, node)->list_lock); + #endif + } + +@@ -2223,9 +2223,9 @@ static void do_drain(void *arg) + check_irq_off(); + ac = cpu_cache_get(cachep); + n = get_node(cachep, node); +- spin_lock(&n->list_lock); ++ raw_spin_lock(&n->list_lock); + free_block(cachep, ac->entry, ac->avail, node, &list); +- spin_unlock(&n->list_lock); ++ raw_spin_unlock(&n->list_lock); + slabs_destroy(cachep, &list); + ac->avail = 0; + } +@@ -2243,9 +2243,9 @@ static void drain_cpu_caches(struct kmem + drain_alien_cache(cachep, n->alien); + + for_each_kmem_cache_node(cachep, node, n) { +- spin_lock_irq(&n->list_lock); ++ raw_spin_lock_irq(&n->list_lock); + drain_array_locked(cachep, n->shared, node, true, &list); +- spin_unlock_irq(&n->list_lock); ++ raw_spin_unlock_irq(&n->list_lock); + + slabs_destroy(cachep, &list); + } +@@ -2267,10 +2267,10 @@ static int drain_freelist(struct kmem_ca + nr_freed = 0; + while (nr_freed < tofree && !list_empty(&n->slabs_free)) { + +- spin_lock_irq(&n->list_lock); ++ raw_spin_lock_irq(&n->list_lock); + p = n->slabs_free.prev; + if (p == &n->slabs_free) { +- spin_unlock_irq(&n->list_lock); ++ raw_spin_unlock_irq(&n->list_lock); + goto out; + } + +@@ -2283,7 +2283,7 @@ static int drain_freelist(struct kmem_ca + * to the cache. + */ + n->free_objects -= cache->num; +- spin_unlock_irq(&n->list_lock); ++ raw_spin_unlock_irq(&n->list_lock); + slab_destroy(cache, page); + nr_freed++; + } +@@ -2731,7 +2731,7 @@ static void cache_grow_end(struct kmem_c + INIT_LIST_HEAD(&page->lru); + n = get_node(cachep, page_to_nid(page)); + +- spin_lock(&n->list_lock); ++ raw_spin_lock(&n->list_lock); + n->total_slabs++; + if (!page->active) { + list_add_tail(&page->lru, &(n->slabs_free)); +@@ -2741,7 +2741,7 @@ static void cache_grow_end(struct kmem_c + + STATS_INC_GROWN(cachep); + n->free_objects += cachep->num - page->active; +- spin_unlock(&n->list_lock); ++ raw_spin_unlock(&n->list_lock); + + fixup_objfreelist_debug(cachep, &list); + } +@@ -2909,7 +2909,7 @@ static struct page *get_first_slab(struc + { + struct page *page; + +- assert_spin_locked(&n->list_lock); ++ assert_raw_spin_locked(&n->list_lock); + page = list_first_entry_or_null(&n->slabs_partial, struct page, lru); + if (!page) { + n->free_touched = 1; +@@ -2935,10 +2935,10 @@ static noinline void *cache_alloc_pfmema + if (!gfp_pfmemalloc_allowed(flags)) + return NULL; + +- spin_lock(&n->list_lock); ++ raw_spin_lock(&n->list_lock); + page = get_first_slab(n, true); + if (!page) { +- spin_unlock(&n->list_lock); ++ raw_spin_unlock(&n->list_lock); + return NULL; + } + +@@ -2947,7 +2947,7 @@ static noinline void *cache_alloc_pfmema + + fixup_slab_list(cachep, n, page, &list); + +- spin_unlock(&n->list_lock); ++ raw_spin_unlock(&n->list_lock); + fixup_objfreelist_debug(cachep, &list); + + return obj; +@@ -3006,7 +3006,7 @@ static void *cache_alloc_refill(struct k + if (!n->free_objects && (!shared || !shared->avail)) + goto direct_grow; + +- spin_lock(&n->list_lock); ++ raw_spin_lock(&n->list_lock); + shared = READ_ONCE(n->shared); + + /* See if we can refill from the shared array */ +@@ -3030,7 +3030,7 @@ static void *cache_alloc_refill(struct k + must_grow: + n->free_objects -= ac->avail; + alloc_done: +- spin_unlock(&n->list_lock); ++ raw_spin_unlock(&n->list_lock); + fixup_objfreelist_debug(cachep, &list); + + direct_grow: +@@ -3255,7 +3255,7 @@ static void *____cache_alloc_node(struct + BUG_ON(!n); + + check_irq_off(); +- spin_lock(&n->list_lock); ++ raw_spin_lock(&n->list_lock); + page = get_first_slab(n, false); + if (!page) + goto must_grow; +@@ -3273,12 +3273,12 @@ static void *____cache_alloc_node(struct + + fixup_slab_list(cachep, n, page, &list); + +- spin_unlock(&n->list_lock); ++ raw_spin_unlock(&n->list_lock); + fixup_objfreelist_debug(cachep, &list); + return obj; + + must_grow: +- spin_unlock(&n->list_lock); ++ raw_spin_unlock(&n->list_lock); + page = cache_grow_begin(cachep, gfp_exact_node(flags), nodeid); + if (page) { + /* This slab isn't counted yet so don't update free_objects */ +@@ -3454,7 +3454,7 @@ static void cache_flusharray(struct kmem + + check_irq_off(); + n = get_node(cachep, node); +- spin_lock(&n->list_lock); ++ raw_spin_lock(&n->list_lock); + if (n->shared) { + struct array_cache *shared_array = n->shared; + int max = shared_array->limit - shared_array->avail; +@@ -3483,7 +3483,7 @@ static void cache_flusharray(struct kmem + STATS_SET_FREEABLE(cachep, i); + } + #endif +- spin_unlock(&n->list_lock); ++ raw_spin_unlock(&n->list_lock); + slabs_destroy(cachep, &list); + ac->avail -= batchcount; + memmove(ac->entry, &(ac->entry[batchcount]), sizeof(void *)*ac->avail); +@@ -3893,9 +3893,9 @@ static int __do_tune_cpucache(struct kme + + node = cpu_to_mem(cpu); + n = get_node(cachep, node); +- spin_lock_irq(&n->list_lock); ++ raw_spin_lock_irq(&n->list_lock); + free_block(cachep, ac->entry, ac->avail, node, &list); +- spin_unlock_irq(&n->list_lock); ++ raw_spin_unlock_irq(&n->list_lock); + slabs_destroy(cachep, &list); + } + free_percpu(prev); +@@ -4020,9 +4020,9 @@ static void drain_array(struct kmem_cach + return; + } + +- spin_lock_irq(&n->list_lock); ++ raw_spin_lock_irq(&n->list_lock); + drain_array_locked(cachep, ac, node, false, &list); +- spin_unlock_irq(&n->list_lock); ++ raw_spin_unlock_irq(&n->list_lock); + + slabs_destroy(cachep, &list); + } +@@ -4106,7 +4106,7 @@ void get_slabinfo(struct kmem_cache *cac + + for_each_kmem_cache_node(cachep, node, n) { + check_irq_on(); +- spin_lock_irq(&n->list_lock); ++ raw_spin_lock_irq(&n->list_lock); + + total_slabs += n->total_slabs; + free_slabs += n->free_slabs; +@@ -4115,7 +4115,7 @@ void get_slabinfo(struct kmem_cache *cac + if (n->shared) + shared_avail += n->shared->avail; + +- spin_unlock_irq(&n->list_lock); ++ raw_spin_unlock_irq(&n->list_lock); + } + num_objs = total_slabs * cachep->num; + active_slabs = total_slabs - free_slabs; +@@ -4330,13 +4330,13 @@ static int leaks_show(struct seq_file *m + for_each_kmem_cache_node(cachep, node, n) { + + check_irq_on(); +- spin_lock_irq(&n->list_lock); ++ raw_spin_lock_irq(&n->list_lock); + + list_for_each_entry(page, &n->slabs_full, lru) + handle_slab(x, cachep, page); + list_for_each_entry(page, &n->slabs_partial, lru) + handle_slab(x, cachep, page); +- spin_unlock_irq(&n->list_lock); ++ raw_spin_unlock_irq(&n->list_lock); + } + } while (!is_store_user_clean(cachep)); + +--- a/mm/slab.h ++++ b/mm/slab.h +@@ -453,7 +453,7 @@ static inline void slab_post_alloc_hook( + * The slab lists for all objects. + */ + struct kmem_cache_node { +- spinlock_t list_lock; ++ raw_spinlock_t list_lock; + + #ifdef CONFIG_SLAB + struct list_head slabs_partial; /* partial list first, better asm code */ +--- a/mm/slub.c ++++ b/mm/slub.c +@@ -1167,7 +1167,7 @@ static noinline int free_debug_processin + unsigned long uninitialized_var(flags); + int ret = 0; + +- spin_lock_irqsave(&n->list_lock, flags); ++ raw_spin_lock_irqsave(&n->list_lock, flags); + slab_lock(page); + + if (s->flags & SLAB_CONSISTENCY_CHECKS) { +@@ -1202,7 +1202,7 @@ static noinline int free_debug_processin + bulk_cnt, cnt); + + slab_unlock(page); +- spin_unlock_irqrestore(&n->list_lock, flags); ++ raw_spin_unlock_irqrestore(&n->list_lock, flags); + if (!ret) + slab_fix(s, "Object at 0x%p not freed", object); + return ret; +@@ -1802,7 +1802,7 @@ static void *get_partial_node(struct kme + if (!n || !n->nr_partial) + return NULL; + +- spin_lock(&n->list_lock); ++ raw_spin_lock(&n->list_lock); + list_for_each_entry_safe(page, page2, &n->partial, lru) { + void *t; + +@@ -1827,7 +1827,7 @@ static void *get_partial_node(struct kme + break; + + } +- spin_unlock(&n->list_lock); ++ raw_spin_unlock(&n->list_lock); + return object; + } + +@@ -2073,7 +2073,7 @@ static void deactivate_slab(struct kmem_ + * that acquire_slab() will see a slab page that + * is frozen + */ +- spin_lock(&n->list_lock); ++ raw_spin_lock(&n->list_lock); + } + } else { + m = M_FULL; +@@ -2084,7 +2084,7 @@ static void deactivate_slab(struct kmem_ + * slabs from diagnostic functions will not see + * any frozen slabs. + */ +- spin_lock(&n->list_lock); ++ raw_spin_lock(&n->list_lock); + } + } + +@@ -2119,7 +2119,7 @@ static void deactivate_slab(struct kmem_ + goto redo; + + if (lock) +- spin_unlock(&n->list_lock); ++ raw_spin_unlock(&n->list_lock); + + if (m == M_FREE) { + stat(s, DEACTIVATE_EMPTY); +@@ -2154,10 +2154,10 @@ static void unfreeze_partials(struct kme + n2 = get_node(s, page_to_nid(page)); + if (n != n2) { + if (n) +- spin_unlock(&n->list_lock); ++ raw_spin_unlock(&n->list_lock); + + n = n2; +- spin_lock(&n->list_lock); ++ raw_spin_lock(&n->list_lock); + } + + do { +@@ -2186,7 +2186,7 @@ static void unfreeze_partials(struct kme + } + + if (n) +- spin_unlock(&n->list_lock); ++ raw_spin_unlock(&n->list_lock); + + while (discard_page) { + page = discard_page; +@@ -2355,10 +2355,10 @@ static unsigned long count_partial(struc + unsigned long x = 0; + struct page *page; + +- spin_lock_irqsave(&n->list_lock, flags); ++ raw_spin_lock_irqsave(&n->list_lock, flags); + list_for_each_entry(page, &n->partial, lru) + x += get_count(page); +- spin_unlock_irqrestore(&n->list_lock, flags); ++ raw_spin_unlock_irqrestore(&n->list_lock, flags); + return x; + } + #endif /* CONFIG_SLUB_DEBUG || CONFIG_SYSFS */ +@@ -2793,7 +2793,7 @@ static void __slab_free(struct kmem_cach + + do { + if (unlikely(n)) { +- spin_unlock_irqrestore(&n->list_lock, flags); ++ raw_spin_unlock_irqrestore(&n->list_lock, flags); + n = NULL; + } + prior = page->freelist; +@@ -2825,7 +2825,7 @@ static void __slab_free(struct kmem_cach + * Otherwise the list_lock will synchronize with + * other processors updating the list of slabs. + */ +- spin_lock_irqsave(&n->list_lock, flags); ++ raw_spin_lock_irqsave(&n->list_lock, flags); + + } + } +@@ -2867,7 +2867,7 @@ static void __slab_free(struct kmem_cach + add_partial(n, page, DEACTIVATE_TO_TAIL); + stat(s, FREE_ADD_PARTIAL); + } +- spin_unlock_irqrestore(&n->list_lock, flags); ++ raw_spin_unlock_irqrestore(&n->list_lock, flags); + return; + + slab_empty: +@@ -2882,7 +2882,7 @@ static void __slab_free(struct kmem_cach + remove_full(s, n, page); + } + +- spin_unlock_irqrestore(&n->list_lock, flags); ++ raw_spin_unlock_irqrestore(&n->list_lock, flags); + stat(s, FREE_SLAB); + discard_slab(s, page); + } +@@ -3269,7 +3269,7 @@ static void + init_kmem_cache_node(struct kmem_cache_node *n) + { + n->nr_partial = 0; +- spin_lock_init(&n->list_lock); ++ raw_spin_lock_init(&n->list_lock); + INIT_LIST_HEAD(&n->partial); + #ifdef CONFIG_SLUB_DEBUG + atomic_long_set(&n->nr_slabs, 0); +@@ -3653,7 +3653,7 @@ static void free_partial(struct kmem_cac + struct page *page, *h; + + BUG_ON(irqs_disabled()); +- spin_lock_irq(&n->list_lock); ++ raw_spin_lock_irq(&n->list_lock); + list_for_each_entry_safe(page, h, &n->partial, lru) { + if (!page->inuse) { + remove_partial(n, page); +@@ -3663,7 +3663,7 @@ static void free_partial(struct kmem_cac + "Objects remaining in %s on __kmem_cache_shutdown()"); + } + } +- spin_unlock_irq(&n->list_lock); ++ raw_spin_unlock_irq(&n->list_lock); + + list_for_each_entry_safe(page, h, &discard, lru) + discard_slab(s, page); +@@ -3936,7 +3936,7 @@ int __kmem_cache_shrink(struct kmem_cach + for (i = 0; i < SHRINK_PROMOTE_MAX; i++) + INIT_LIST_HEAD(promote + i); + +- spin_lock_irqsave(&n->list_lock, flags); ++ raw_spin_lock_irqsave(&n->list_lock, flags); + + /* + * Build lists of slabs to discard or promote. +@@ -3967,7 +3967,7 @@ int __kmem_cache_shrink(struct kmem_cach + for (i = SHRINK_PROMOTE_MAX - 1; i >= 0; i--) + list_splice(promote + i, &n->partial); + +- spin_unlock_irqrestore(&n->list_lock, flags); ++ raw_spin_unlock_irqrestore(&n->list_lock, flags); + + /* Release empty slabs */ + list_for_each_entry_safe(page, t, &discard, lru) +@@ -4381,7 +4381,7 @@ static int validate_slab_node(struct kme + struct page *page; + unsigned long flags; + +- spin_lock_irqsave(&n->list_lock, flags); ++ raw_spin_lock_irqsave(&n->list_lock, flags); + + list_for_each_entry(page, &n->partial, lru) { + validate_slab_slab(s, page, map); +@@ -4403,7 +4403,7 @@ static int validate_slab_node(struct kme + s->name, count, atomic_long_read(&n->nr_slabs)); + + out: +- spin_unlock_irqrestore(&n->list_lock, flags); ++ raw_spin_unlock_irqrestore(&n->list_lock, flags); + return count; + } + +@@ -4593,12 +4593,12 @@ static int list_locations(struct kmem_ca + if (!atomic_long_read(&n->nr_slabs)) + continue; + +- spin_lock_irqsave(&n->list_lock, flags); ++ raw_spin_lock_irqsave(&n->list_lock, flags); + list_for_each_entry(page, &n->partial, lru) + process_slab(&t, s, page, alloc, map); + list_for_each_entry(page, &n->full, lru) + process_slab(&t, s, page, alloc, map); +- spin_unlock_irqrestore(&n->list_lock, flags); ++ raw_spin_unlock_irqrestore(&n->list_lock, flags); + } + + for (i = 0; i < t.count; i++) { diff --git a/kernel/patches-4.19.x-rt/0077-0004-mm-SLUB-delay-giving-back-empty-slubs-to-IRQ-enabled.patch b/kernel/patches-4.19.x-rt/0077-0004-mm-SLUB-delay-giving-back-empty-slubs-to-IRQ-enabled.patch new file mode 100644 index 000000000..ee9464d80 --- /dev/null +++ b/kernel/patches-4.19.x-rt/0077-0004-mm-SLUB-delay-giving-back-empty-slubs-to-IRQ-enabled.patch @@ -0,0 +1,216 @@ +From: Thomas Gleixner +Date: Thu, 21 Jun 2018 17:29:19 +0200 +Subject: [PATCH 4/4] mm/SLUB: delay giving back empty slubs to IRQ enabled + regions + +__free_slab() is invoked with disabled interrupts which increases the +irq-off time while __free_pages() is doing the work. +Allow __free_slab() to be invoked with enabled interrupts and move +everything from interrupts-off invocations to a temporary per-CPU list +so it can be processed later. + +Signed-off-by: Thomas Gleixner +Signed-off-by: Sebastian Andrzej Siewior +--- + mm/slub.c | 74 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++----- + 1 file changed, 69 insertions(+), 5 deletions(-) + +--- a/mm/slub.c ++++ b/mm/slub.c +@@ -1330,6 +1330,12 @@ static inline void dec_slabs_node(struct + + #endif /* CONFIG_SLUB_DEBUG */ + ++struct slub_free_list { ++ raw_spinlock_t lock; ++ struct list_head list; ++}; ++static DEFINE_PER_CPU(struct slub_free_list, slub_free_list); ++ + /* + * Hooks for other subsystems that check memory allocations. In a typical + * production configuration these hooks all should produce no code at all. +@@ -1684,6 +1690,16 @@ static void __free_slab(struct kmem_cach + __free_pages(page, order); + } + ++static void free_delayed(struct list_head *h) ++{ ++ while (!list_empty(h)) { ++ struct page *page = list_first_entry(h, struct page, lru); ++ ++ list_del(&page->lru); ++ __free_slab(page->slab_cache, page); ++ } ++} ++ + static void rcu_free_slab(struct rcu_head *h) + { + struct page *page = container_of(h, struct page, rcu_head); +@@ -1695,6 +1711,12 @@ static void free_slab(struct kmem_cache + { + if (unlikely(s->flags & SLAB_TYPESAFE_BY_RCU)) { + call_rcu(&page->rcu_head, rcu_free_slab); ++ } else if (irqs_disabled()) { ++ struct slub_free_list *f = this_cpu_ptr(&slub_free_list); ++ ++ raw_spin_lock(&f->lock); ++ list_add(&page->lru, &f->list); ++ raw_spin_unlock(&f->lock); + } else + __free_slab(s, page); + } +@@ -2223,14 +2245,21 @@ static void put_cpu_partial(struct kmem_ + pobjects = oldpage->pobjects; + pages = oldpage->pages; + if (drain && pobjects > s->cpu_partial) { ++ struct slub_free_list *f; + unsigned long flags; ++ LIST_HEAD(tofree); + /* + * partial array is full. Move the existing + * set to the per node partial list. + */ + local_irq_save(flags); + unfreeze_partials(s, this_cpu_ptr(s->cpu_slab)); ++ f = this_cpu_ptr(&slub_free_list); ++ raw_spin_lock(&f->lock); ++ list_splice_init(&f->list, &tofree); ++ raw_spin_unlock(&f->lock); + local_irq_restore(flags); ++ free_delayed(&tofree); + oldpage = NULL; + pobjects = 0; + pages = 0; +@@ -2300,7 +2329,22 @@ static bool has_cpu_slab(int cpu, void * + + static void flush_all(struct kmem_cache *s) + { ++ LIST_HEAD(tofree); ++ int cpu; ++ + on_each_cpu_cond(has_cpu_slab, flush_cpu_slab, s, 1, GFP_ATOMIC); ++ for_each_online_cpu(cpu) { ++ struct slub_free_list *f; ++ ++ if (!has_cpu_slab(cpu, s)) ++ continue; ++ ++ f = &per_cpu(slub_free_list, cpu); ++ raw_spin_lock_irq(&f->lock); ++ list_splice_init(&f->list, &tofree); ++ raw_spin_unlock_irq(&f->lock); ++ free_delayed(&tofree); ++ } + } + + /* +@@ -2498,8 +2542,10 @@ static inline void *get_freelist(struct + * already disabled (which is the case for bulk allocation). + */ + static void *___slab_alloc(struct kmem_cache *s, gfp_t gfpflags, int node, +- unsigned long addr, struct kmem_cache_cpu *c) ++ unsigned long addr, struct kmem_cache_cpu *c, ++ struct list_head *to_free) + { ++ struct slub_free_list *f; + void *freelist; + struct page *page; + +@@ -2555,6 +2601,13 @@ static void *___slab_alloc(struct kmem_c + VM_BUG_ON(!c->page->frozen); + c->freelist = get_freepointer(s, freelist); + c->tid = next_tid(c->tid); ++ ++out: ++ f = this_cpu_ptr(&slub_free_list); ++ raw_spin_lock(&f->lock); ++ list_splice_init(&f->list, to_free); ++ raw_spin_unlock(&f->lock); ++ + return freelist; + + new_slab: +@@ -2570,7 +2623,7 @@ static void *___slab_alloc(struct kmem_c + + if (unlikely(!freelist)) { + slab_out_of_memory(s, gfpflags, node); +- return NULL; ++ goto out; + } + + page = c->page; +@@ -2583,7 +2636,7 @@ static void *___slab_alloc(struct kmem_c + goto new_slab; /* Slab failed checks. Next slab needed */ + + deactivate_slab(s, page, get_freepointer(s, freelist), c); +- return freelist; ++ goto out; + } + + /* +@@ -2595,6 +2648,7 @@ static void *__slab_alloc(struct kmem_ca + { + void *p; + unsigned long flags; ++ LIST_HEAD(tofree); + + local_irq_save(flags); + #ifdef CONFIG_PREEMPT +@@ -2606,8 +2660,9 @@ static void *__slab_alloc(struct kmem_ca + c = this_cpu_ptr(s->cpu_slab); + #endif + +- p = ___slab_alloc(s, gfpflags, node, addr, c); ++ p = ___slab_alloc(s, gfpflags, node, addr, c, &tofree); + local_irq_restore(flags); ++ free_delayed(&tofree); + return p; + } + +@@ -3085,6 +3140,7 @@ int kmem_cache_alloc_bulk(struct kmem_ca + void **p) + { + struct kmem_cache_cpu *c; ++ LIST_HEAD(to_free); + int i; + + /* memcg and kmem_cache debug support */ +@@ -3108,7 +3164,7 @@ int kmem_cache_alloc_bulk(struct kmem_ca + * of re-populating per CPU c->freelist + */ + p[i] = ___slab_alloc(s, flags, NUMA_NO_NODE, +- _RET_IP_, c); ++ _RET_IP_, c, &to_free); + if (unlikely(!p[i])) + goto error; + +@@ -3120,6 +3176,7 @@ int kmem_cache_alloc_bulk(struct kmem_ca + } + c->tid = next_tid(c->tid); + local_irq_enable(); ++ free_delayed(&to_free); + + /* Clear memory outside IRQ disabled fastpath loop */ + if (unlikely(flags & __GFP_ZERO)) { +@@ -3134,6 +3191,7 @@ int kmem_cache_alloc_bulk(struct kmem_ca + return i; + error: + local_irq_enable(); ++ free_delayed(&to_free); + slab_post_alloc_hook(s, flags, i, p); + __kmem_cache_free_bulk(s, i, p); + return 0; +@@ -4180,6 +4238,12 @@ void __init kmem_cache_init(void) + { + static __initdata struct kmem_cache boot_kmem_cache, + boot_kmem_cache_node; ++ int cpu; ++ ++ for_each_possible_cpu(cpu) { ++ raw_spin_lock_init(&per_cpu(slub_free_list, cpu).lock); ++ INIT_LIST_HEAD(&per_cpu(slub_free_list, cpu).list); ++ } + + if (debug_guardpage_minorder()) + slub_max_order = 0; diff --git a/kernel/patches-4.14.x-rt/0170-mm-page_alloc-rt-friendly-per-cpu-pages.patch b/kernel/patches-4.19.x-rt/0078-mm-page_alloc-rt-friendly-per-cpu-pages.patch similarity index 62% rename from kernel/patches-4.14.x-rt/0170-mm-page_alloc-rt-friendly-per-cpu-pages.patch rename to kernel/patches-4.19.x-rt/0078-mm-page_alloc-rt-friendly-per-cpu-pages.patch index 8f04c3b43..612dafd9e 100644 --- a/kernel/patches-4.14.x-rt/0170-mm-page_alloc-rt-friendly-per-cpu-pages.patch +++ b/kernel/patches-4.19.x-rt/0078-mm-page_alloc-rt-friendly-per-cpu-pages.patch @@ -1,7 +1,6 @@ -From 6a175195d8db76416b4661a50698f69c190af5bc Mon Sep 17 00:00:00 2001 From: Ingo Molnar Date: Fri, 3 Jul 2009 08:29:37 -0500 -Subject: [PATCH 170/450] mm: page_alloc: rt-friendly per-cpu pages +Subject: mm: page_alloc: rt-friendly per-cpu pages rt-friendly per-cpu pages: convert the irqs-off per-cpu locking method into a preemptible, explicit-per-cpu-locks method. @@ -13,14 +12,12 @@ Contains fixes from: Signed-off-by: Ingo Molnar Signed-off-by: Thomas Gleixner --- - mm/page_alloc.c | 55 +++++++++++++++++++++++++++++++++++-------------- - 1 file changed, 39 insertions(+), 16 deletions(-) + mm/page_alloc.c | 63 ++++++++++++++++++++++++++++++++++++++------------------ + 1 file changed, 43 insertions(+), 20 deletions(-) -diff --git a/mm/page_alloc.c b/mm/page_alloc.c -index 2074f424dabf..7316ae31df8e 100644 --- a/mm/page_alloc.c +++ b/mm/page_alloc.c -@@ -61,6 +61,7 @@ +@@ -60,6 +60,7 @@ #include #include #include @@ -28,7 +25,7 @@ index 2074f424dabf..7316ae31df8e 100644 #include #include #include -@@ -286,6 +287,18 @@ EXPORT_SYMBOL(nr_node_ids); +@@ -291,6 +292,18 @@ EXPORT_SYMBOL(nr_node_ids); EXPORT_SYMBOL(nr_online_nodes); #endif @@ -36,9 +33,9 @@ index 2074f424dabf..7316ae31df8e 100644 + +#ifdef CONFIG_PREEMPT_RT_BASE +# define cpu_lock_irqsave(cpu, flags) \ -+ spin_lock_irqsave(&per_cpu(pa_lock, cpu).lock, flags) ++ local_lock_irqsave_on(pa_lock, flags, cpu) +# define cpu_unlock_irqrestore(cpu, flags) \ -+ spin_unlock_irqrestore(&per_cpu(pa_lock, cpu).lock, flags) ++ local_unlock_irqrestore_on(pa_lock, flags, cpu) +#else +# define cpu_lock_irqsave(cpu, flags) local_irq_save(flags) +# define cpu_unlock_irqrestore(cpu, flags) local_irq_restore(flags) @@ -47,7 +44,7 @@ index 2074f424dabf..7316ae31df8e 100644 int page_group_by_mobility_disabled __read_mostly; #ifdef CONFIG_DEFERRED_STRUCT_PAGE_INIT -@@ -1257,10 +1270,10 @@ static void __free_pages_ok(struct page *page, unsigned int order) +@@ -1296,10 +1309,10 @@ static void __free_pages_ok(struct page return; migratetype = get_pfnblock_migratetype(page, pfn); @@ -60,42 +57,41 @@ index 2074f424dabf..7316ae31df8e 100644 } static void __init __free_pages_boot_core(struct page *page, unsigned int order) -@@ -2380,14 +2393,14 @@ void drain_zone_pages(struct zone *zone, struct per_cpu_pages *pcp) - unsigned long flags; +@@ -2560,13 +2573,13 @@ void drain_zone_pages(struct zone *zone, int to_drain, batch; + LIST_HEAD(dst); - local_irq_save(flags); + local_lock_irqsave(pa_lock, flags); batch = READ_ONCE(pcp->batch); to_drain = min(pcp->count, batch); - if (to_drain > 0) { - free_pcppages_bulk(zone, to_drain, pcp); - pcp->count -= to_drain; - } + if (to_drain > 0) + isolate_pcp_pages(to_drain, pcp, &dst); + - local_irq_restore(flags); + local_unlock_irqrestore(pa_lock, flags); - } - #endif -@@ -2404,7 +2417,7 @@ static void drain_pages_zone(unsigned int cpu, struct zone *zone) - struct per_cpu_pageset *pset; - struct per_cpu_pages *pcp; + if (to_drain > 0) + free_pcppages_bulk(zone, &dst, false); +@@ -2588,7 +2601,7 @@ static void drain_pages_zone(unsigned in + LIST_HEAD(dst); + int count; - local_irq_save(flags); + cpu_lock_irqsave(cpu, flags); pset = per_cpu_ptr(zone->pageset, cpu); pcp = &pset->pcp; -@@ -2412,7 +2425,7 @@ static void drain_pages_zone(unsigned int cpu, struct zone *zone) - free_pcppages_bulk(zone, pcp->count, pcp); - pcp->count = 0; - } +@@ -2596,7 +2609,7 @@ static void drain_pages_zone(unsigned in + if (count) + isolate_pcp_pages(count, pcp, &dst); + - local_irq_restore(flags); + cpu_unlock_irqrestore(cpu, flags); - } - /* -@@ -2447,6 +2460,7 @@ void drain_local_pages(struct zone *zone) + if (count) + free_pcppages_bulk(zone, &dst, false); +@@ -2634,6 +2647,7 @@ void drain_local_pages(struct zone *zone drain_pages(cpu); } @@ -103,7 +99,7 @@ index 2074f424dabf..7316ae31df8e 100644 static void drain_local_pages_wq(struct work_struct *work) { /* -@@ -2460,6 +2474,7 @@ static void drain_local_pages_wq(struct work_struct *work) +@@ -2647,6 +2661,7 @@ static void drain_local_pages_wq(struct drain_local_pages(NULL); preempt_enable(); } @@ -111,7 +107,7 @@ index 2074f424dabf..7316ae31df8e 100644 /* * Spill all the per-cpu pages from all CPUs back into the buddy allocator. -@@ -2526,7 +2541,14 @@ void drain_all_pages(struct zone *zone) +@@ -2713,7 +2728,14 @@ void drain_all_pages(struct zone *zone) else cpumask_clear_cpu(cpu, &cpus_with_pcps); } @@ -127,7 +123,7 @@ index 2074f424dabf..7316ae31df8e 100644 for_each_cpu(cpu, &cpus_with_pcps) { struct work_struct *work = per_cpu_ptr(&pcpu_drain, cpu); INIT_WORK(work, drain_local_pages_wq); -@@ -2534,6 +2556,7 @@ void drain_all_pages(struct zone *zone) +@@ -2721,6 +2743,7 @@ void drain_all_pages(struct zone *zone) } for_each_cpu(cpu, &cpus_with_pcps) flush_work(per_cpu_ptr(&pcpu_drain, cpu)); @@ -135,25 +131,44 @@ index 2074f424dabf..7316ae31df8e 100644 mutex_unlock(&pcpu_drain_mutex); } -@@ -2610,7 +2633,7 @@ void free_hot_cold_page(struct page *page, bool cold) +@@ -2840,9 +2863,9 @@ void free_unref_page(struct page *page) + if (!free_unref_page_prepare(page, pfn)) + return; - migratetype = get_pfnblock_migratetype(page, pfn); - set_pcppage_migratetype(page, migratetype); - local_irq_save(flags); + local_lock_irqsave(pa_lock, flags); - __count_vm_event(PGFREE); - - /* -@@ -2641,7 +2664,7 @@ void free_hot_cold_page(struct page *page, bool cold) - } - - out: + free_unref_page_commit(page, pfn, &dst); - local_irq_restore(flags); + local_unlock_irqrestore(pa_lock, flags); + if (!list_empty(&dst)) + free_pcppages_bulk(zone, &dst, false); } +@@ -2869,7 +2892,7 @@ void free_unref_page_list(struct list_he + set_page_private(page, pfn); + } - /* -@@ -2789,7 +2812,7 @@ static struct page *rmqueue_pcplist(struct zone *preferred_zone, +- local_irq_save(flags); ++ local_lock_irqsave(pa_lock, flags); + list_for_each_entry_safe(page, next, list, lru) { + unsigned long pfn = page_private(page); + enum zone_type type; +@@ -2884,12 +2907,12 @@ void free_unref_page_list(struct list_he + * a large list of pages to free. + */ + if (++batch_count == SWAP_CLUSTER_MAX) { +- local_irq_restore(flags); ++ local_unlock_irqrestore(pa_lock, flags); + batch_count = 0; +- local_irq_save(flags); ++ local_lock_irqsave(pa_lock, flags); + } + } +- local_irq_restore(flags); ++ local_unlock_irqrestore(pa_lock, flags); + + for (i = 0; i < __MAX_NR_ZONES; ) { + struct page *page; +@@ -3038,7 +3061,7 @@ static struct page *rmqueue_pcplist(stru struct page *page; unsigned long flags; @@ -161,8 +176,8 @@ index 2074f424dabf..7316ae31df8e 100644 + local_lock_irqsave(pa_lock, flags); pcp = &this_cpu_ptr(zone->pageset)->pcp; list = &pcp->lists[migratetype]; - page = __rmqueue_pcplist(zone, migratetype, cold, pcp, list); -@@ -2797,7 +2820,7 @@ static struct page *rmqueue_pcplist(struct zone *preferred_zone, + page = __rmqueue_pcplist(zone, migratetype, pcp, list); +@@ -3046,7 +3069,7 @@ static struct page *rmqueue_pcplist(stru __count_zid_vm_events(PGALLOC, page_zonenum(page), 1 << order); zone_statistics(preferred_zone, zone); } @@ -171,7 +186,7 @@ index 2074f424dabf..7316ae31df8e 100644 return page; } -@@ -2824,7 +2847,7 @@ struct page *rmqueue(struct zone *preferred_zone, +@@ -3073,7 +3096,7 @@ struct page *rmqueue(struct zone *prefer * allocate greater than order-1 page units with __GFP_NOFAIL. */ WARN_ON_ONCE((gfp_flags & __GFP_NOFAIL) && (order > 1)); @@ -180,7 +195,7 @@ index 2074f424dabf..7316ae31df8e 100644 do { page = NULL; -@@ -2844,14 +2867,14 @@ struct page *rmqueue(struct zone *preferred_zone, +@@ -3093,14 +3116,14 @@ struct page *rmqueue(struct zone *prefer __count_zid_vm_events(PGALLOC, page_zonenum(page), 1 << order); zone_statistics(preferred_zone, zone); @@ -197,7 +212,7 @@ index 2074f424dabf..7316ae31df8e 100644 return NULL; } -@@ -7688,7 +7711,7 @@ void zone_pcp_reset(struct zone *zone) +@@ -8094,7 +8117,7 @@ void zone_pcp_reset(struct zone *zone) struct per_cpu_pageset *pset; /* avoid races with drain_pages() */ @@ -206,7 +221,7 @@ index 2074f424dabf..7316ae31df8e 100644 if (zone->pageset != &boot_pageset) { for_each_online_cpu(cpu) { pset = per_cpu_ptr(zone->pageset, cpu); -@@ -7697,7 +7720,7 @@ void zone_pcp_reset(struct zone *zone) +@@ -8103,7 +8126,7 @@ void zone_pcp_reset(struct zone *zone) free_percpu(zone->pageset); zone->pageset = &boot_pageset; } @@ -215,6 +230,3 @@ index 2074f424dabf..7316ae31df8e 100644 } #ifdef CONFIG_MEMORY_HOTREMOVE --- -2.19.2 - diff --git a/kernel/patches-4.14.x-rt/0172-mm-swap-Convert-to-percpu-locked.patch b/kernel/patches-4.19.x-rt/0079-mm-convert-swap-to-percpu-locked.patch similarity index 75% rename from kernel/patches-4.14.x-rt/0172-mm-swap-Convert-to-percpu-locked.patch rename to kernel/patches-4.19.x-rt/0079-mm-convert-swap-to-percpu-locked.patch index 0f6b5ac2a..5e8468f94 100644 --- a/kernel/patches-4.14.x-rt/0172-mm-swap-Convert-to-percpu-locked.patch +++ b/kernel/patches-4.19.x-rt/0079-mm-convert-swap-to-percpu-locked.patch @@ -1,25 +1,31 @@ -From 8e72aa5e0f006652d1fb3714091b616675754693 Mon Sep 17 00:00:00 2001 From: Ingo Molnar Date: Fri, 3 Jul 2009 08:29:51 -0500 -Subject: [PATCH 172/450] mm/swap: Convert to percpu locked +Subject: mm/swap: Convert to percpu locked Replace global locks (get_cpu + local_irq_save) with "local_locks()". Currently there is one of for "rotate" and one for "swap". Signed-off-by: Ingo Molnar Signed-off-by: Thomas Gleixner ---- - include/linux/swap.h | 1 + - mm/compaction.c | 6 ++++-- - mm/page_alloc.c | 3 ++- - mm/swap.c | 38 ++++++++++++++++++++++---------------- - 4 files changed, 29 insertions(+), 19 deletions(-) -diff --git a/include/linux/swap.h b/include/linux/swap.h -index aff4f8309f6b..6c775168df67 100644 +--- + include/linux/swap.h | 2 ++ + mm/compaction.c | 6 ++++-- + mm/page_alloc.c | 3 ++- + mm/swap.c | 38 ++++++++++++++++++++++---------------- + 4 files changed, 30 insertions(+), 19 deletions(-) + --- a/include/linux/swap.h +++ b/include/linux/swap.h -@@ -312,6 +312,7 @@ extern unsigned long nr_free_pagecache_pages(void); +@@ -12,6 +12,7 @@ + #include + #include + #include ++#include + #include + + struct notifier_block; +@@ -331,6 +332,7 @@ extern unsigned long nr_free_pagecache_p /* linux/mm/swap.c */ @@ -27,11 +33,9 @@ index aff4f8309f6b..6c775168df67 100644 extern void lru_cache_add(struct page *); extern void lru_cache_add_anon(struct page *page); extern void lru_cache_add_file(struct page *page); -diff --git a/mm/compaction.c b/mm/compaction.c -index 85395dc6eb13..d6c8ed009e93 100644 --- a/mm/compaction.c +++ b/mm/compaction.c -@@ -1634,10 +1634,12 @@ static enum compact_result compact_zone(struct zone *zone, struct compact_contro +@@ -1657,10 +1657,12 @@ static enum compact_result compact_zone( block_start_pfn(cc->migrate_pfn, cc->order); if (cc->last_migrated_pfn < current_block_start) { @@ -46,11 +50,9 @@ index 85395dc6eb13..d6c8ed009e93 100644 /* No more flushing until we migrate again */ cc->last_migrated_pfn = 0; } -diff --git a/mm/page_alloc.c b/mm/page_alloc.c -index ca19f55de422..cd81e08bb504 100644 --- a/mm/page_alloc.c +++ b/mm/page_alloc.c -@@ -6843,8 +6843,9 @@ void __init free_area_init(unsigned long *zones_size) +@@ -7205,8 +7205,9 @@ void __init free_area_init(unsigned long static int page_alloc_cpu_dead(unsigned int cpu) { @@ -61,11 +63,9 @@ index ca19f55de422..cd81e08bb504 100644 drain_pages(cpu); /* -diff --git a/mm/swap.c b/mm/swap.c -index a77d68f2c1b6..c63d649fb3a9 100644 --- a/mm/swap.c +++ b/mm/swap.c -@@ -32,6 +32,7 @@ +@@ -33,6 +33,7 @@ #include #include #include @@ -73,7 +73,7 @@ index a77d68f2c1b6..c63d649fb3a9 100644 #include #include -@@ -50,6 +51,8 @@ static DEFINE_PER_CPU(struct pagevec, lru_lazyfree_pvecs); +@@ -51,6 +52,8 @@ static DEFINE_PER_CPU(struct pagevec, lr #ifdef CONFIG_SMP static DEFINE_PER_CPU(struct pagevec, activate_page_pvecs); #endif @@ -82,7 +82,7 @@ index a77d68f2c1b6..c63d649fb3a9 100644 /* * This path almost never happens for VM activity - pages are normally -@@ -252,11 +255,11 @@ void rotate_reclaimable_page(struct page *page) +@@ -253,11 +256,11 @@ void rotate_reclaimable_page(struct page unsigned long flags; get_page(page); @@ -96,7 +96,7 @@ index a77d68f2c1b6..c63d649fb3a9 100644 } } -@@ -306,12 +309,13 @@ void activate_page(struct page *page) +@@ -307,12 +310,13 @@ void activate_page(struct page *page) { page = compound_head(page); if (PageLRU(page) && !PageActive(page) && !PageUnevictable(page)) { @@ -112,7 +112,7 @@ index a77d68f2c1b6..c63d649fb3a9 100644 } } -@@ -338,7 +342,7 @@ void activate_page(struct page *page) +@@ -339,7 +343,7 @@ void activate_page(struct page *page) static void __lru_cache_activate_page(struct page *page) { @@ -121,7 +121,7 @@ index a77d68f2c1b6..c63d649fb3a9 100644 int i; /* -@@ -360,7 +364,7 @@ static void __lru_cache_activate_page(struct page *page) +@@ -361,7 +365,7 @@ static void __lru_cache_activate_page(st } } @@ -130,7 +130,7 @@ index a77d68f2c1b6..c63d649fb3a9 100644 } /* -@@ -402,12 +406,12 @@ EXPORT_SYMBOL(mark_page_accessed); +@@ -403,12 +407,12 @@ EXPORT_SYMBOL(mark_page_accessed); static void __lru_cache_add(struct page *page) { @@ -145,7 +145,7 @@ index a77d68f2c1b6..c63d649fb3a9 100644 } /** -@@ -613,9 +617,9 @@ void lru_add_drain_cpu(int cpu) +@@ -586,9 +590,9 @@ void lru_add_drain_cpu(int cpu) unsigned long flags; /* No harm done if a racing interrupt already did this */ @@ -157,7 +157,7 @@ index a77d68f2c1b6..c63d649fb3a9 100644 } pvec = &per_cpu(lru_deactivate_file_pvecs, cpu); -@@ -647,11 +651,12 @@ void deactivate_file_page(struct page *page) +@@ -620,11 +624,12 @@ void deactivate_file_page(struct page *p return; if (likely(get_page_unless_zero(page))) { @@ -172,7 +172,7 @@ index a77d68f2c1b6..c63d649fb3a9 100644 } } -@@ -666,19 +671,20 @@ void mark_page_lazyfree(struct page *page) +@@ -639,19 +644,20 @@ void mark_page_lazyfree(struct page *pag { if (PageLRU(page) && PageAnon(page) && PageSwapBacked(page) && !PageSwapCache(page) && !PageUnevictable(page)) { @@ -197,6 +197,3 @@ index a77d68f2c1b6..c63d649fb3a9 100644 } static void lru_add_drain_per_cpu(struct work_struct *dummy) --- -2.19.2 - diff --git a/kernel/patches-4.14.x-rt/0173-mm-perform-lru_add_drain_all-remotely.patch b/kernel/patches-4.19.x-rt/0080-mm-perform-lru_add_drain_all-remotely.patch similarity index 82% rename from kernel/patches-4.14.x-rt/0173-mm-perform-lru_add_drain_all-remotely.patch rename to kernel/patches-4.19.x-rt/0080-mm-perform-lru_add_drain_all-remotely.patch index 4d986705f..28d23636d 100644 --- a/kernel/patches-4.14.x-rt/0173-mm-perform-lru_add_drain_all-remotely.patch +++ b/kernel/patches-4.19.x-rt/0080-mm-perform-lru_add_drain_all-remotely.patch @@ -1,7 +1,6 @@ -From 9341ed82cb232da1f37223870cb2b0ff38713be2 Mon Sep 17 00:00:00 2001 From: Luiz Capitulino Date: Fri, 27 May 2016 15:03:28 +0200 -Subject: [PATCH 173/450] mm: perform lru_add_drain_all() remotely +Subject: [PATCH] mm: perform lru_add_drain_all() remotely lru_add_drain_all() works by scheduling lru_add_drain_cpu() to run on all CPUs that have non-empty LRU pagevecs and then waiting for @@ -20,14 +19,12 @@ Signed-off-by: Rik van Riel Signed-off-by: Luiz Capitulino Signed-off-by: Sebastian Andrzej Siewior --- - mm/swap.c | 36 ++++++++++++++++++++++++++++++------ + mm/swap.c | 36 ++++++++++++++++++++++++++++++------ 1 file changed, 30 insertions(+), 6 deletions(-) -diff --git a/mm/swap.c b/mm/swap.c -index c63d649fb3a9..30d62efe001b 100644 --- a/mm/swap.c +++ b/mm/swap.c -@@ -617,9 +617,15 @@ void lru_add_drain_cpu(int cpu) +@@ -590,9 +590,15 @@ void lru_add_drain_cpu(int cpu) unsigned long flags; /* No harm done if a racing interrupt already did this */ @@ -43,7 +40,7 @@ index c63d649fb3a9..30d62efe001b 100644 } pvec = &per_cpu(lru_deactivate_file_pvecs, cpu); -@@ -687,6 +693,16 @@ void lru_add_drain(void) +@@ -660,6 +666,16 @@ void lru_add_drain(void) local_unlock_cpu(swapvec_lock); } @@ -60,7 +57,7 @@ index c63d649fb3a9..30d62efe001b 100644 static void lru_add_drain_per_cpu(struct work_struct *dummy) { lru_add_drain(); -@@ -694,6 +710,16 @@ static void lru_add_drain_per_cpu(struct work_struct *dummy) +@@ -667,6 +683,16 @@ static void lru_add_drain_per_cpu(struct static DEFINE_PER_CPU(struct work_struct, lru_add_drain_work); @@ -74,10 +71,10 @@ index c63d649fb3a9..30d62efe001b 100644 +} +#endif + - void lru_add_drain_all_cpuslocked(void) - { - static DEFINE_MUTEX(lock); -@@ -711,21 +737,19 @@ void lru_add_drain_all_cpuslocked(void) + /* + * Doesn't need any cpu hotplug locking because we do rely on per-cpu + * kworkers being shut down before our page_alloc_cpu_dead callback is +@@ -691,21 +717,19 @@ void lru_add_drain_all(void) cpumask_clear(&has_work); for_each_online_cpu(cpu) { @@ -103,6 +100,3 @@ index c63d649fb3a9..30d62efe001b 100644 mutex_unlock(&lock); } --- -2.19.2 - diff --git a/kernel/patches-4.14.x-rt/0174-mm-vmstat-Protect-per-cpu-variables-with-preempt-dis.patch b/kernel/patches-4.19.x-rt/0081-mm-make-vmstat-rt-aware.patch similarity index 63% rename from kernel/patches-4.14.x-rt/0174-mm-vmstat-Protect-per-cpu-variables-with-preempt-dis.patch rename to kernel/patches-4.19.x-rt/0081-mm-make-vmstat-rt-aware.patch index 59c11b3e8..ae673e318 100644 --- a/kernel/patches-4.14.x-rt/0174-mm-vmstat-Protect-per-cpu-variables-with-preempt-dis.patch +++ b/kernel/patches-4.19.x-rt/0081-mm-make-vmstat-rt-aware.patch @@ -1,8 +1,6 @@ -From b42713ade1cf103b333bc937b8304b2a6195791d Mon Sep 17 00:00:00 2001 From: Ingo Molnar Date: Fri, 3 Jul 2009 08:30:13 -0500 -Subject: [PATCH 174/450] mm/vmstat: Protect per cpu variables with preempt - disable on RT +Subject: mm/vmstat: Protect per cpu variables with preempt disable on RT Disable preemption on -RT for the vmstat code. On vanila the code runs in IRQ-off regions while on -RT it is not. "preempt_disable" ensures that the @@ -10,16 +8,15 @@ same ressources is not updated in parallel due to preemption. Signed-off-by: Ingo Molnar Signed-off-by: Thomas Gleixner + --- - include/linux/vmstat.h | 4 ++++ - mm/vmstat.c | 12 ++++++++++++ + include/linux/vmstat.h | 4 ++++ + mm/vmstat.c | 12 ++++++++++++ 2 files changed, 16 insertions(+) -diff --git a/include/linux/vmstat.h b/include/linux/vmstat.h -index 1e0cb72e0598..87ab0996a9b0 100644 --- a/include/linux/vmstat.h +++ b/include/linux/vmstat.h -@@ -33,7 +33,9 @@ DECLARE_PER_CPU(struct vm_event_state, vm_event_states); +@@ -54,7 +54,9 @@ DECLARE_PER_CPU(struct vm_event_state, v */ static inline void __count_vm_event(enum vm_event_item item) { @@ -29,7 +26,7 @@ index 1e0cb72e0598..87ab0996a9b0 100644 } static inline void count_vm_event(enum vm_event_item item) -@@ -43,7 +45,9 @@ static inline void count_vm_event(enum vm_event_item item) +@@ -64,7 +66,9 @@ static inline void count_vm_event(enum v static inline void __count_vm_events(enum vm_event_item item, long delta) { @@ -39,11 +36,9 @@ index 1e0cb72e0598..87ab0996a9b0 100644 } static inline void count_vm_events(enum vm_event_item item, long delta) -diff --git a/mm/vmstat.c b/mm/vmstat.c -index 6389e876c7a7..203bc6d3be75 100644 --- a/mm/vmstat.c +++ b/mm/vmstat.c -@@ -249,6 +249,7 @@ void __mod_zone_page_state(struct zone *zone, enum zone_stat_item item, +@@ -320,6 +320,7 @@ void __mod_zone_page_state(struct zone * long x; long t; @@ -51,7 +46,7 @@ index 6389e876c7a7..203bc6d3be75 100644 x = delta + __this_cpu_read(*p); t = __this_cpu_read(pcp->stat_threshold); -@@ -258,6 +259,7 @@ void __mod_zone_page_state(struct zone *zone, enum zone_stat_item item, +@@ -329,6 +330,7 @@ void __mod_zone_page_state(struct zone * x = 0; } __this_cpu_write(*p, x); @@ -59,7 +54,7 @@ index 6389e876c7a7..203bc6d3be75 100644 } EXPORT_SYMBOL(__mod_zone_page_state); -@@ -269,6 +271,7 @@ void __mod_node_page_state(struct pglist_data *pgdat, enum node_stat_item item, +@@ -340,6 +342,7 @@ void __mod_node_page_state(struct pglist long x; long t; @@ -67,7 +62,7 @@ index 6389e876c7a7..203bc6d3be75 100644 x = delta + __this_cpu_read(*p); t = __this_cpu_read(pcp->stat_threshold); -@@ -278,6 +281,7 @@ void __mod_node_page_state(struct pglist_data *pgdat, enum node_stat_item item, +@@ -349,6 +352,7 @@ void __mod_node_page_state(struct pglist x = 0; } __this_cpu_write(*p, x); @@ -75,7 +70,7 @@ index 6389e876c7a7..203bc6d3be75 100644 } EXPORT_SYMBOL(__mod_node_page_state); -@@ -310,6 +314,7 @@ void __inc_zone_state(struct zone *zone, enum zone_stat_item item) +@@ -381,6 +385,7 @@ void __inc_zone_state(struct zone *zone, s8 __percpu *p = pcp->vm_stat_diff + item; s8 v, t; @@ -83,7 +78,7 @@ index 6389e876c7a7..203bc6d3be75 100644 v = __this_cpu_inc_return(*p); t = __this_cpu_read(pcp->stat_threshold); if (unlikely(v > t)) { -@@ -318,6 +323,7 @@ void __inc_zone_state(struct zone *zone, enum zone_stat_item item) +@@ -389,6 +394,7 @@ void __inc_zone_state(struct zone *zone, zone_page_state_add(v + overstep, zone, item); __this_cpu_write(*p, -overstep); } @@ -91,7 +86,7 @@ index 6389e876c7a7..203bc6d3be75 100644 } void __inc_node_state(struct pglist_data *pgdat, enum node_stat_item item) -@@ -326,6 +332,7 @@ void __inc_node_state(struct pglist_data *pgdat, enum node_stat_item item) +@@ -397,6 +403,7 @@ void __inc_node_state(struct pglist_data s8 __percpu *p = pcp->vm_node_stat_diff + item; s8 v, t; @@ -99,7 +94,7 @@ index 6389e876c7a7..203bc6d3be75 100644 v = __this_cpu_inc_return(*p); t = __this_cpu_read(pcp->stat_threshold); if (unlikely(v > t)) { -@@ -334,6 +341,7 @@ void __inc_node_state(struct pglist_data *pgdat, enum node_stat_item item) +@@ -405,6 +412,7 @@ void __inc_node_state(struct pglist_data node_page_state_add(v + overstep, pgdat, item); __this_cpu_write(*p, -overstep); } @@ -107,7 +102,7 @@ index 6389e876c7a7..203bc6d3be75 100644 } void __inc_zone_page_state(struct page *page, enum zone_stat_item item) -@@ -354,6 +362,7 @@ void __dec_zone_state(struct zone *zone, enum zone_stat_item item) +@@ -425,6 +433,7 @@ void __dec_zone_state(struct zone *zone, s8 __percpu *p = pcp->vm_stat_diff + item; s8 v, t; @@ -115,7 +110,7 @@ index 6389e876c7a7..203bc6d3be75 100644 v = __this_cpu_dec_return(*p); t = __this_cpu_read(pcp->stat_threshold); if (unlikely(v < - t)) { -@@ -362,6 +371,7 @@ void __dec_zone_state(struct zone *zone, enum zone_stat_item item) +@@ -433,6 +442,7 @@ void __dec_zone_state(struct zone *zone, zone_page_state_add(v - overstep, zone, item); __this_cpu_write(*p, overstep); } @@ -123,7 +118,7 @@ index 6389e876c7a7..203bc6d3be75 100644 } void __dec_node_state(struct pglist_data *pgdat, enum node_stat_item item) -@@ -370,6 +380,7 @@ void __dec_node_state(struct pglist_data *pgdat, enum node_stat_item item) +@@ -441,6 +451,7 @@ void __dec_node_state(struct pglist_data s8 __percpu *p = pcp->vm_node_stat_diff + item; s8 v, t; @@ -131,7 +126,7 @@ index 6389e876c7a7..203bc6d3be75 100644 v = __this_cpu_dec_return(*p); t = __this_cpu_read(pcp->stat_threshold); if (unlikely(v < - t)) { -@@ -378,6 +389,7 @@ void __dec_node_state(struct pglist_data *pgdat, enum node_stat_item item) +@@ -449,6 +460,7 @@ void __dec_node_state(struct pglist_data node_page_state_add(v - overstep, pgdat, item); __this_cpu_write(*p, overstep); } @@ -139,6 +134,3 @@ index 6389e876c7a7..203bc6d3be75 100644 } void __dec_zone_page_state(struct page *page, enum zone_stat_item item) --- -2.19.2 - diff --git a/kernel/patches-4.14.x-rt/0175-ARM-Initialize-split-page-table-locks-for-vector-pag.patch b/kernel/patches-4.19.x-rt/0082-re-preempt_rt_full-arm-coredump-fails-for-cpu-3e-3d-4.patch similarity index 82% rename from kernel/patches-4.14.x-rt/0175-ARM-Initialize-split-page-table-locks-for-vector-pag.patch rename to kernel/patches-4.19.x-rt/0082-re-preempt_rt_full-arm-coredump-fails-for-cpu-3e-3d-4.patch index ca7cc31d7..293ef2d04 100644 --- a/kernel/patches-4.14.x-rt/0175-ARM-Initialize-split-page-table-locks-for-vector-pag.patch +++ b/kernel/patches-4.19.x-rt/0082-re-preempt_rt_full-arm-coredump-fails-for-cpu-3e-3d-4.patch @@ -1,8 +1,6 @@ -From 661bc1dee47a1d175214165b121893c3b15138d8 Mon Sep 17 00:00:00 2001 +Subject: ARM: Initialize split page table locks for vector page From: Frank Rowand Date: Sat, 1 Oct 2011 18:58:13 -0700 -Subject: [PATCH 175/450] ARM: Initialize split page table locks for vector - page Without this patch, ARM can not use SPLIT_PTLOCK_CPUS if PREEMPT_RT_FULL=y because vectors_user_mapping() creates a @@ -32,14 +30,12 @@ Cc: Peter Zijlstra Link: http://lkml.kernel.org/r/4E87C535.2030907@am.sony.com Signed-off-by: Thomas Gleixner --- - arch/arm/kernel/process.c | 24 ++++++++++++++++++++++++ + arch/arm/kernel/process.c | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) -diff --git a/arch/arm/kernel/process.c b/arch/arm/kernel/process.c -index d96714e1858c..cf4e1452d4b4 100644 --- a/arch/arm/kernel/process.c +++ b/arch/arm/kernel/process.c -@@ -325,6 +325,30 @@ unsigned long arch_randomize_brk(struct mm_struct *mm) +@@ -324,6 +324,30 @@ unsigned long arch_randomize_brk(struct } #ifdef CONFIG_MMU @@ -70,6 +66,3 @@ index d96714e1858c..cf4e1452d4b4 100644 #ifdef CONFIG_KUSER_HELPERS /* * The vectors page is always readable from user space for the --- -2.19.2 - diff --git a/kernel/patches-4.19.x-rt/0083-mm-enable-slub.patch b/kernel/patches-4.19.x-rt/0083-mm-enable-slub.patch new file mode 100644 index 000000000..78657d755 --- /dev/null +++ b/kernel/patches-4.19.x-rt/0083-mm-enable-slub.patch @@ -0,0 +1,35 @@ +Subject: mm: Enable SLUB for RT +From: Thomas Gleixner +Date: Thu, 25 Oct 2012 10:32:35 +0100 + +Avoid the memory allocation in IRQ section + +Signed-off-by: Thomas Gleixner +[bigeasy: factor out everything except the kcalloc() workaorund ] +Signed-off-by: Sebastian Andrzej Siewior +--- + mm/slub.c | 6 ++++++ + 1 file changed, 6 insertions(+) + +--- a/mm/slub.c ++++ b/mm/slub.c +@@ -3677,6 +3677,11 @@ static void list_slab_objects(struct kme + const char *text) + { + #ifdef CONFIG_SLUB_DEBUG ++#ifdef CONFIG_PREEMPT_RT_BASE ++ /* XXX move out of irq-off section */ ++ slab_err(s, page, text, s->name); ++#else ++ + void *addr = page_address(page); + void *p; + unsigned long *map = kcalloc(BITS_TO_LONGS(page->objects), +@@ -3698,6 +3703,7 @@ static void list_slab_objects(struct kme + slab_unlock(page); + kfree(map); + #endif ++#endif + } + + /* diff --git a/kernel/patches-4.19.x-rt/0084-slub-enable-irqs-for-no-wait.patch b/kernel/patches-4.19.x-rt/0084-slub-enable-irqs-for-no-wait.patch new file mode 100644 index 000000000..7ff4785d7 --- /dev/null +++ b/kernel/patches-4.19.x-rt/0084-slub-enable-irqs-for-no-wait.patch @@ -0,0 +1,41 @@ +Subject: slub: Enable irqs for __GFP_WAIT +From: Thomas Gleixner +Date: Wed, 09 Jan 2013 12:08:15 +0100 + +SYSTEM_RUNNING might be too late for enabling interrupts. Allocations +with GFP_WAIT can happen before that. So use this as an indicator. + +Signed-off-by: Thomas Gleixner +--- + mm/slub.c | 9 ++++++++- + 1 file changed, 8 insertions(+), 1 deletion(-) + +--- a/mm/slub.c ++++ b/mm/slub.c +@@ -1570,10 +1570,17 @@ static struct page *allocate_slab(struct + void *start, *p; + int idx, order; + bool shuffle; ++ bool enableirqs = false; + + flags &= gfp_allowed_mask; + + if (gfpflags_allow_blocking(flags)) ++ enableirqs = true; ++#ifdef CONFIG_PREEMPT_RT_FULL ++ if (system_state > SYSTEM_BOOTING) ++ enableirqs = true; ++#endif ++ if (enableirqs) + local_irq_enable(); + + flags |= s->allocflags; +@@ -1632,7 +1639,7 @@ static struct page *allocate_slab(struct + page->frozen = 1; + + out: +- if (gfpflags_allow_blocking(flags)) ++ if (enableirqs) + local_irq_disable(); + if (!page) + return NULL; diff --git a/kernel/patches-4.14.x-rt/0181-slub-Disable-SLUB_CPU_PARTIAL.patch b/kernel/patches-4.19.x-rt/0085-slub-disable-SLUB_CPU_PARTIAL.patch similarity index 86% rename from kernel/patches-4.14.x-rt/0181-slub-Disable-SLUB_CPU_PARTIAL.patch rename to kernel/patches-4.19.x-rt/0085-slub-disable-SLUB_CPU_PARTIAL.patch index 92c3f06b6..998b4533a 100644 --- a/kernel/patches-4.14.x-rt/0181-slub-Disable-SLUB_CPU_PARTIAL.patch +++ b/kernel/patches-4.19.x-rt/0085-slub-disable-SLUB_CPU_PARTIAL.patch @@ -1,7 +1,6 @@ -From 79ba188c2f1651cb18a4276a0c27e3131c132488 Mon Sep 17 00:00:00 2001 From: Sebastian Andrzej Siewior Date: Wed, 15 Apr 2015 19:00:47 +0200 -Subject: [PATCH 181/450] slub: Disable SLUB_CPU_PARTIAL +Subject: slub: Disable SLUB_CPU_PARTIAL |BUG: sleeping function called from invalid context at kernel/locking/rtmutex.c:915 |in_atomic(): 1, irqs_disabled(): 0, pid: 87, name: rcuop/7 @@ -32,14 +31,12 @@ Subject: [PATCH 181/450] slub: Disable SLUB_CPU_PARTIAL Signed-off-by: Sebastian Andrzej Siewior --- - init/Kconfig | 2 +- + init/Kconfig | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) -diff --git a/init/Kconfig b/init/Kconfig -index 0fa1ade4351a..bec5b4b82585 100644 --- a/init/Kconfig +++ b/init/Kconfig -@@ -1596,7 +1596,7 @@ config SLAB_FREELIST_HARDENED +@@ -1698,7 +1698,7 @@ config SLAB_FREELIST_HARDENED config SLUB_CPU_PARTIAL default y @@ -48,6 +45,3 @@ index 0fa1ade4351a..bec5b4b82585 100644 bool "SLUB per cpu partial cache" help Per cpu partial caches accellerate objects allocation and freeing --- -2.19.2 - diff --git a/kernel/patches-4.14.x-rt/0183-mm-memcontrol-Don-t-call-schedule_work_on-in-preempt.patch b/kernel/patches-4.19.x-rt/0086-mm-memcontrol-Don-t-call-schedule_work_on-in-preempt.patch similarity index 84% rename from kernel/patches-4.14.x-rt/0183-mm-memcontrol-Don-t-call-schedule_work_on-in-preempt.patch rename to kernel/patches-4.19.x-rt/0086-mm-memcontrol-Don-t-call-schedule_work_on-in-preempt.patch index 5d0e8b2a9..1d870ba2a 100644 --- a/kernel/patches-4.14.x-rt/0183-mm-memcontrol-Don-t-call-schedule_work_on-in-preempt.patch +++ b/kernel/patches-4.19.x-rt/0086-mm-memcontrol-Don-t-call-schedule_work_on-in-preempt.patch @@ -1,8 +1,6 @@ -From 5806765157114c70826afc4a306f9398ff55969f Mon Sep 17 00:00:00 2001 From: Yang Shi +Subject: mm/memcontrol: Don't call schedule_work_on in preemption disabled context Date: Wed, 30 Oct 2013 11:48:33 -0700 -Subject: [PATCH 183/450] mm/memcontrol: Don't call schedule_work_on in - preemption disabled context The following trace is triggered when running ltp oom test cases: @@ -44,14 +42,13 @@ replace the pair of get/put_cpu() to get/put_cpu_light(). Signed-off-by: Yang Shi Signed-off-by: Sebastian Andrzej Siewior --- - mm/memcontrol.c | 4 ++-- + + mm/memcontrol.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) -diff --git a/mm/memcontrol.c b/mm/memcontrol.c -index 6a9a7e1066ef..92139e87df28 100644 --- a/mm/memcontrol.c +++ b/mm/memcontrol.c -@@ -1831,7 +1831,7 @@ static void drain_all_stock(struct mem_cgroup *root_memcg) +@@ -2052,7 +2052,7 @@ static void drain_all_stock(struct mem_c * as well as workers from this path always operate on the local * per-cpu data. CPU up doesn't touch memcg_stock at all. */ @@ -60,7 +57,7 @@ index 6a9a7e1066ef..92139e87df28 100644 for_each_online_cpu(cpu) { struct memcg_stock_pcp *stock = &per_cpu(memcg_stock, cpu); struct mem_cgroup *memcg; -@@ -1851,7 +1851,7 @@ static void drain_all_stock(struct mem_cgroup *root_memcg) +@@ -2072,7 +2072,7 @@ static void drain_all_stock(struct mem_c } css_put(&memcg->css); } @@ -69,6 +66,3 @@ index 6a9a7e1066ef..92139e87df28 100644 mutex_unlock(&percpu_charge_mutex); } --- -2.19.2 - diff --git a/kernel/patches-4.14.x-rt/0184-mm-memcontrol-Replace-local_irq_disable-with-local-l.patch b/kernel/patches-4.19.x-rt/0087-mm-memcontrol-do_not_disable_irq.patch similarity index 68% rename from kernel/patches-4.14.x-rt/0184-mm-memcontrol-Replace-local_irq_disable-with-local-l.patch rename to kernel/patches-4.19.x-rt/0087-mm-memcontrol-do_not_disable_irq.patch index a8e12c245..b0c12fd04 100644 --- a/kernel/patches-4.14.x-rt/0184-mm-memcontrol-Replace-local_irq_disable-with-local-l.patch +++ b/kernel/patches-4.19.x-rt/0087-mm-memcontrol-do_not_disable_irq.patch @@ -1,19 +1,15 @@ -From 0abe0410fbd8c10569c75d8674b36445cbf3f9d3 Mon Sep 17 00:00:00 2001 From: Sebastian Andrzej Siewior +Subject: mm/memcontrol: Replace local_irq_disable with local locks Date: Wed, 28 Jan 2015 17:14:16 +0100 -Subject: [PATCH 184/450] mm/memcontrol: Replace local_irq_disable with local - locks There are a few local_irq_disable() which then take sleeping locks. This patch converts them local locks. Signed-off-by: Sebastian Andrzej Siewior --- - mm/memcontrol.c | 24 ++++++++++++++++-------- + mm/memcontrol.c | 24 ++++++++++++++++-------- 1 file changed, 16 insertions(+), 8 deletions(-) -diff --git a/mm/memcontrol.c b/mm/memcontrol.c -index 92139e87df28..3cc297730103 100644 --- a/mm/memcontrol.c +++ b/mm/memcontrol.c @@ -69,6 +69,7 @@ @@ -33,7 +29,7 @@ index 92139e87df28..3cc297730103 100644 /* Whether legacy memory+swap accounting is active */ static bool do_memsw_account(void) { -@@ -4631,12 +4634,12 @@ static int mem_cgroup_move_account(struct page *page, +@@ -4859,12 +4862,12 @@ static int mem_cgroup_move_account(struc ret = 0; @@ -48,7 +44,7 @@ index 92139e87df28..3cc297730103 100644 out_unlock: unlock_page(page); out: -@@ -5579,10 +5582,10 @@ void mem_cgroup_commit_charge(struct page *page, struct mem_cgroup *memcg, +@@ -5983,10 +5986,10 @@ void mem_cgroup_commit_charge(struct pag commit_charge(page, memcg, lrucare); @@ -61,25 +57,25 @@ index 92139e87df28..3cc297730103 100644 if (do_memsw_account() && PageSwapCache(page)) { swp_entry_t entry = { .val = page_private(page) }; -@@ -5651,7 +5654,7 @@ static void uncharge_batch(const struct uncharge_gather *ug) +@@ -6055,7 +6058,7 @@ static void uncharge_batch(const struct memcg_oom_recover(ug->memcg); } - local_irq_save(flags); + local_lock_irqsave(event_lock, flags); - __this_cpu_sub(ug->memcg->stat->count[MEMCG_RSS], ug->nr_anon); - __this_cpu_sub(ug->memcg->stat->count[MEMCG_CACHE], ug->nr_file); - __this_cpu_sub(ug->memcg->stat->count[MEMCG_RSS_HUGE], ug->nr_huge); -@@ -5659,7 +5662,7 @@ static void uncharge_batch(const struct uncharge_gather *ug) - __this_cpu_add(ug->memcg->stat->events[PGPGOUT], ug->pgpgout); - __this_cpu_add(ug->memcg->stat->nr_page_events, nr_pages); + __mod_memcg_state(ug->memcg, MEMCG_RSS, -ug->nr_anon); + __mod_memcg_state(ug->memcg, MEMCG_CACHE, -ug->nr_file); + __mod_memcg_state(ug->memcg, MEMCG_RSS_HUGE, -ug->nr_huge); +@@ -6063,7 +6066,7 @@ static void uncharge_batch(const struct + __count_memcg_events(ug->memcg, PGPGOUT, ug->pgpgout); + __this_cpu_add(ug->memcg->stat_cpu->nr_page_events, nr_pages); memcg_check_events(ug->memcg, ug->dummy_page); - local_irq_restore(flags); + local_unlock_irqrestore(event_lock, flags); if (!mem_cgroup_is_root(ug->memcg)) css_put_many(&ug->memcg->css, nr_pages); -@@ -5822,10 +5825,10 @@ void mem_cgroup_migrate(struct page *oldpage, struct page *newpage) +@@ -6226,10 +6229,10 @@ void mem_cgroup_migrate(struct page *old commit_charge(newpage, memcg, false); @@ -92,7 +88,7 @@ index 92139e87df28..3cc297730103 100644 } DEFINE_STATIC_KEY_FALSE(memcg_sockets_enabled_key); -@@ -6017,6 +6020,7 @@ void mem_cgroup_swapout(struct page *page, swp_entry_t entry) +@@ -6421,6 +6424,7 @@ void mem_cgroup_swapout(struct page *pag struct mem_cgroup *memcg, *swap_memcg; unsigned int nr_entries; unsigned short oldid; @@ -100,9 +96,9 @@ index 92139e87df28..3cc297730103 100644 VM_BUG_ON_PAGE(PageLRU(page), page); VM_BUG_ON_PAGE(page_count(page), page); -@@ -6062,13 +6066,17 @@ void mem_cgroup_swapout(struct page *page, swp_entry_t entry) +@@ -6466,13 +6470,17 @@ void mem_cgroup_swapout(struct page *pag * important here to have the interrupts disabled because it is the - * only synchronisation we have for udpating the per-CPU variables. + * only synchronisation we have for updating the per-CPU variables. */ + local_lock_irqsave(event_lock, flags); +#ifndef CONFIG_PREEMPT_RT_BASE @@ -118,6 +114,3 @@ index 92139e87df28..3cc297730103 100644 } /** --- -2.19.2 - diff --git a/kernel/patches-4.14.x-rt/0186-mm-zsmalloc-copy-with-get_cpu_var-and-locking.patch b/kernel/patches-4.19.x-rt/0088-mm_zsmalloc_copy_with_get_cpu_var_and_locking.patch similarity index 82% rename from kernel/patches-4.14.x-rt/0186-mm-zsmalloc-copy-with-get_cpu_var-and-locking.patch rename to kernel/patches-4.19.x-rt/0088-mm_zsmalloc_copy_with_get_cpu_var_and_locking.patch index 990a94ea4..b3b14d392 100644 --- a/kernel/patches-4.14.x-rt/0186-mm-zsmalloc-copy-with-get_cpu_var-and-locking.patch +++ b/kernel/patches-4.19.x-rt/0088-mm_zsmalloc_copy_with_get_cpu_var_and_locking.patch @@ -1,7 +1,6 @@ -From 7258f2ed88bb2f780f2252e46fad1c6c7475ead0 Mon Sep 17 00:00:00 2001 From: Mike Galbraith Date: Tue, 22 Mar 2016 11:16:09 +0100 -Subject: [PATCH 186/450] mm/zsmalloc: copy with get_cpu_var() and locking +Subject: [PATCH] mm/zsmalloc: copy with get_cpu_var() and locking get_cpu_var() disables preemption and triggers a might_sleep() splat later. This is replaced with get_locked_var(). @@ -13,22 +12,20 @@ Signed-off-by: Mike Galbraith fixed the size magic] Signed-off-by: Sebastian Andrzej Siewior --- - mm/zsmalloc.c | 80 +++++++++++++++++++++++++++++++++++++++++++++++---- + mm/zsmalloc.c | 80 +++++++++++++++++++++++++++++++++++++++++++++++++++++----- 1 file changed, 74 insertions(+), 6 deletions(-) -diff --git a/mm/zsmalloc.c b/mm/zsmalloc.c -index 685049a9048d..8d1489fd1dbc 100644 --- a/mm/zsmalloc.c +++ b/mm/zsmalloc.c -@@ -53,6 +53,7 @@ - #include +@@ -55,6 +55,7 @@ #include #include + #include +#include #define ZSPAGE_MAGIC 0x58 -@@ -70,9 +71,22 @@ +@@ -72,9 +73,22 @@ */ #define ZS_MAX_ZSPAGE_ORDER 2 #define ZS_MAX_PAGES_PER_ZSPAGE (_AC(1, UL) << ZS_MAX_ZSPAGE_ORDER) @@ -52,7 +49,7 @@ index 685049a9048d..8d1489fd1dbc 100644 /* * Object location (, ) is encoded as * as single (unsigned long) handle value. -@@ -320,7 +334,7 @@ static void SetZsPageMovable(struct zs_pool *pool, struct zspage *zspage) {} +@@ -320,7 +334,7 @@ static void SetZsPageMovable(struct zs_p static int create_cache(struct zs_pool *pool) { @@ -61,7 +58,7 @@ index 685049a9048d..8d1489fd1dbc 100644 0, 0, NULL); if (!pool->handle_cachep) return 1; -@@ -344,10 +358,27 @@ static void destroy_cache(struct zs_pool *pool) +@@ -344,10 +358,27 @@ static void destroy_cache(struct zs_pool static unsigned long cache_alloc_handle(struct zs_pool *pool, gfp_t gfp) { @@ -91,7 +88,7 @@ index 685049a9048d..8d1489fd1dbc 100644 static void cache_free_handle(struct zs_pool *pool, unsigned long handle) { kmem_cache_free(pool->handle_cachep, (void *)handle); -@@ -366,12 +397,18 @@ static void cache_free_zspage(struct zs_pool *pool, struct zspage *zspage) +@@ -366,12 +397,18 @@ static void cache_free_zspage(struct zs_ static void record_obj(unsigned long handle, unsigned long obj) { @@ -110,7 +107,7 @@ index 685049a9048d..8d1489fd1dbc 100644 } /* zpool driver */ -@@ -460,6 +497,7 @@ MODULE_ALIAS("zpool-zsmalloc"); +@@ -453,6 +490,7 @@ MODULE_ALIAS("zpool-zsmalloc"); /* per-cpu VM mapping areas for zspage accesses that cross page boundaries */ static DEFINE_PER_CPU(struct mapping_area, zs_map_area); @@ -118,7 +115,7 @@ index 685049a9048d..8d1489fd1dbc 100644 static bool is_zspage_isolated(struct zspage *zspage) { -@@ -898,7 +936,13 @@ static unsigned long location_to_obj(struct page *page, unsigned int obj_idx) +@@ -882,7 +920,13 @@ static unsigned long location_to_obj(str static unsigned long handle_to_obj(unsigned long handle) { @@ -132,7 +129,7 @@ index 685049a9048d..8d1489fd1dbc 100644 } static unsigned long obj_to_head(struct page *page, void *obj) -@@ -912,22 +956,46 @@ static unsigned long obj_to_head(struct page *page, void *obj) +@@ -896,22 +940,46 @@ static unsigned long obj_to_head(struct static inline int testpin_tag(unsigned long handle) { @@ -179,7 +176,7 @@ index 685049a9048d..8d1489fd1dbc 100644 } static void reset_page(struct page *page) -@@ -1365,7 +1433,7 @@ void *zs_map_object(struct zs_pool *pool, unsigned long handle, +@@ -1337,7 +1405,7 @@ void *zs_map_object(struct zs_pool *pool class = pool->size_class[class_idx]; off = (class->size * obj_idx) & ~PAGE_MASK; @@ -188,7 +185,7 @@ index 685049a9048d..8d1489fd1dbc 100644 area->vm_mm = mm; if (off + class->size <= PAGE_SIZE) { /* this object is contained entirely within a page */ -@@ -1419,7 +1487,7 @@ void zs_unmap_object(struct zs_pool *pool, unsigned long handle) +@@ -1391,7 +1459,7 @@ void zs_unmap_object(struct zs_pool *poo __zs_unmap_object(area, pages, off, class->size); } @@ -197,6 +194,3 @@ index 685049a9048d..8d1489fd1dbc 100644 migrate_read_unlock(zspage); unpin_tag(handle); --- -2.19.2 - diff --git a/kernel/patches-4.14.x-rt/0447-x86-mm-pat-disable-preemption-__split_large_page-aft.patch b/kernel/patches-4.19.x-rt/0089-x86-mm-pat-disable-preemption-__split_large_page-aft.patch similarity index 62% rename from kernel/patches-4.14.x-rt/0447-x86-mm-pat-disable-preemption-__split_large_page-aft.patch rename to kernel/patches-4.19.x-rt/0089-x86-mm-pat-disable-preemption-__split_large_page-aft.patch index 7537f3cd4..ec5c42533 100644 --- a/kernel/patches-4.14.x-rt/0447-x86-mm-pat-disable-preemption-__split_large_page-aft.patch +++ b/kernel/patches-4.19.x-rt/0089-x86-mm-pat-disable-preemption-__split_large_page-aft.patch @@ -1,10 +1,7 @@ -From 7a6b6bada1be92517ce32ff55a5cfe2fb2e0166a Mon Sep 17 00:00:00 2001 From: Sebastian Andrzej Siewior Date: Tue, 11 Dec 2018 21:53:43 +0100 -Subject: [PATCH 447/450] x86/mm/pat: disable preemption __split_large_page() - after spin_lock() - -[ Upstream commit 45c6ff4811878e5c1c2ae31303cd95cdc6ae2ab4 ] +Subject: [PATCH] x86/mm/pat: disable preemption __split_large_page() after + spin_lock() Commit "x86/mm/pat: Disable preemption around __flush_tlb_all()" added a warning if __flush_tlb_all() is invoked in preemptible context. On !RT @@ -15,25 +12,21 @@ so the warning is seen. Disable preemption to avoid the warning __flush_tlb_all(). Signed-off-by: Sebastian Andrzej Siewior -Signed-off-by: Steven Rostedt (VMware) --- - arch/x86/mm/pageattr.c | 8 ++++++++ + arch/x86/mm/pageattr.c | 8 ++++++++ 1 file changed, 8 insertions(+) -diff --git a/arch/x86/mm/pageattr.c b/arch/x86/mm/pageattr.c -index 835620ab435f..57a04ef6fe47 100644 --- a/arch/x86/mm/pageattr.c +++ b/arch/x86/mm/pageattr.c -@@ -661,12 +661,18 @@ __split_large_page(struct cpa_data *cpa, pte_t *kpte, unsigned long address, - pgprot_t ref_prot; +@@ -688,11 +688,17 @@ static int spin_lock(&pgd_lock); -+ /* + /* + * Keep preemption disabled after __flush_tlb_all() which expects not be + * preempted during the flush of the local TLB. + */ + preempt_disable(); - /* ++ /* * Check for races, another CPU might have split this page * up for us already: */ @@ -43,7 +36,7 @@ index 835620ab435f..57a04ef6fe47 100644 spin_unlock(&pgd_lock); return 1; } -@@ -696,6 +702,7 @@ __split_large_page(struct cpa_data *cpa, pte_t *kpte, unsigned long address, +@@ -726,6 +732,7 @@ static int break; default: @@ -51,7 +44,7 @@ index 835620ab435f..57a04ef6fe47 100644 spin_unlock(&pgd_lock); return 1; } -@@ -743,6 +750,7 @@ __split_large_page(struct cpa_data *cpa, pte_t *kpte, unsigned long address, +@@ -764,6 +771,7 @@ static int * going on. */ __flush_tlb_all(); @@ -59,6 +52,3 @@ index 835620ab435f..57a04ef6fe47 100644 spin_unlock(&pgd_lock); return 0; --- -2.19.2 - diff --git a/kernel/patches-4.14.x-rt/0187-radix-tree-use-local-locks.patch b/kernel/patches-4.19.x-rt/0090-radix-tree-use-local-locks.patch similarity index 72% rename from kernel/patches-4.14.x-rt/0187-radix-tree-use-local-locks.patch rename to kernel/patches-4.19.x-rt/0090-radix-tree-use-local-locks.patch index 0b0e5196c..8cde3957b 100644 --- a/kernel/patches-4.14.x-rt/0187-radix-tree-use-local-locks.patch +++ b/kernel/patches-4.19.x-rt/0090-radix-tree-use-local-locks.patch @@ -1,7 +1,6 @@ -From 7a812202fba4c9526a865a31afd555c8a57a5549 Mon Sep 17 00:00:00 2001 From: Sebastian Andrzej Siewior Date: Wed, 25 Jan 2017 16:34:27 +0100 -Subject: [PATCH 187/450] radix-tree: use local locks +Subject: [PATCH] radix-tree: use local locks The preload functionality uses per-CPU variables and preempt-disable to ensure that it does not switch CPUs during its usage. This patch adds @@ -12,16 +11,14 @@ Cc: stable-rt@vger.kernel.org Reported-and-debugged-by: Mike Galbraith Signed-off-by: Sebastian Andrzej Siewior --- - include/linux/idr.h | 5 +---- - include/linux/radix-tree.h | 7 ++----- - lib/radix-tree.c | 32 +++++++++++++++++++++++--------- + include/linux/idr.h | 5 +---- + include/linux/radix-tree.h | 7 ++----- + lib/radix-tree.c | 32 +++++++++++++++++++++++--------- 3 files changed, 26 insertions(+), 18 deletions(-) -diff --git a/include/linux/idr.h b/include/linux/idr.h -index 7c3a365f7e12..a922d984d9b6 100644 --- a/include/linux/idr.h +++ b/include/linux/idr.h -@@ -167,10 +167,7 @@ static inline bool idr_is_empty(const struct idr *idr) +@@ -169,10 +169,7 @@ static inline bool idr_is_empty(const st * Each idr_preload() should be matched with an invocation of this * function. See idr_preload() for details. */ @@ -32,12 +29,10 @@ index 7c3a365f7e12..a922d984d9b6 100644 +void idr_preload_end(void); /** - * idr_find - return pointer for given id -diff --git a/include/linux/radix-tree.h b/include/linux/radix-tree.h -index 567ebb5eaab0..9da7ea957399 100644 + * idr_for_each_entry() - Iterate over an IDR's elements of a given type. --- a/include/linux/radix-tree.h +++ b/include/linux/radix-tree.h -@@ -328,6 +328,8 @@ unsigned int radix_tree_gang_lookup_slot(const struct radix_tree_root *, +@@ -330,6 +330,8 @@ unsigned int radix_tree_gang_lookup_slot int radix_tree_preload(gfp_t gfp_mask); int radix_tree_maybe_preload(gfp_t gfp_mask); int radix_tree_maybe_preload_order(gfp_t gfp_mask, int order); @@ -46,7 +41,7 @@ index 567ebb5eaab0..9da7ea957399 100644 void radix_tree_init(void); void *radix_tree_tag_set(struct radix_tree_root *, unsigned long index, unsigned int tag); -@@ -347,11 +349,6 @@ unsigned int radix_tree_gang_lookup_tag_slot(const struct radix_tree_root *, +@@ -349,11 +351,6 @@ unsigned int radix_tree_gang_lookup_tag_ unsigned int max_items, unsigned int tag); int radix_tree_tagged(const struct radix_tree_root *, unsigned int tag); @@ -58,11 +53,9 @@ index 567ebb5eaab0..9da7ea957399 100644 int radix_tree_split_preload(unsigned old_order, unsigned new_order, gfp_t); int radix_tree_split(struct radix_tree_root *, unsigned long index, unsigned new_order); -diff --git a/lib/radix-tree.c b/lib/radix-tree.c -index d172f0341b80..c1da1109a107 100644 --- a/lib/radix-tree.c +++ b/lib/radix-tree.c -@@ -37,7 +37,7 @@ +@@ -38,7 +38,7 @@ #include #include #include @@ -71,7 +64,7 @@ index d172f0341b80..c1da1109a107 100644 /* Number of nodes in fully populated tree of given height */ static unsigned long height_to_maxnodes[RADIX_TREE_MAX_PATH + 1] __read_mostly; -@@ -86,6 +86,7 @@ struct radix_tree_preload { +@@ -87,6 +87,7 @@ struct radix_tree_preload { struct radix_tree_node *nodes; }; static DEFINE_PER_CPU(struct radix_tree_preload, radix_tree_preloads) = { 0, }; @@ -79,7 +72,7 @@ index d172f0341b80..c1da1109a107 100644 static inline struct radix_tree_node *entry_to_node(void *ptr) { -@@ -404,12 +405,13 @@ radix_tree_node_alloc(gfp_t gfp_mask, struct radix_tree_node *parent, +@@ -405,12 +406,13 @@ radix_tree_node_alloc(gfp_t gfp_mask, st * succeed in getting a node here (and never reach * kmem_cache_alloc) */ @@ -94,7 +87,7 @@ index d172f0341b80..c1da1109a107 100644 /* * Update the allocation stack trace as this is more useful * for debugging. -@@ -475,14 +477,14 @@ static __must_check int __radix_tree_preload(gfp_t gfp_mask, unsigned nr) +@@ -476,14 +478,14 @@ static __must_check int __radix_tree_pre */ gfp_mask &= ~__GFP_ACCOUNT; @@ -112,7 +105,7 @@ index d172f0341b80..c1da1109a107 100644 rtp = this_cpu_ptr(&radix_tree_preloads); if (rtp->nr < nr) { node->parent = rtp->nodes; -@@ -524,7 +526,7 @@ int radix_tree_maybe_preload(gfp_t gfp_mask) +@@ -525,7 +527,7 @@ int radix_tree_maybe_preload(gfp_t gfp_m if (gfpflags_allow_blocking(gfp_mask)) return __radix_tree_preload(gfp_mask, RADIX_TREE_PRELOAD_SIZE); /* Preloading doesn't help anything with this gfp mask, skip it */ @@ -121,7 +114,7 @@ index d172f0341b80..c1da1109a107 100644 return 0; } EXPORT_SYMBOL(radix_tree_maybe_preload); -@@ -562,7 +564,7 @@ int radix_tree_maybe_preload_order(gfp_t gfp_mask, int order) +@@ -563,7 +565,7 @@ int radix_tree_maybe_preload_order(gfp_t /* Preloading doesn't help anything with this gfp mask, skip it */ if (!gfpflags_allow_blocking(gfp_mask)) { @@ -130,7 +123,7 @@ index d172f0341b80..c1da1109a107 100644 return 0; } -@@ -596,6 +598,12 @@ int radix_tree_maybe_preload_order(gfp_t gfp_mask, int order) +@@ -597,6 +599,12 @@ int radix_tree_maybe_preload_order(gfp_t return __radix_tree_preload(gfp_mask, nr_nodes); } @@ -143,7 +136,7 @@ index d172f0341b80..c1da1109a107 100644 static unsigned radix_tree_load_root(const struct radix_tree_root *root, struct radix_tree_node **nodep, unsigned long *maxindex) { -@@ -2105,10 +2113,16 @@ EXPORT_SYMBOL(radix_tree_tagged); +@@ -2102,10 +2110,16 @@ EXPORT_SYMBOL(radix_tree_tagged); void idr_preload(gfp_t gfp_mask) { if (__radix_tree_preload(gfp_mask, IDR_PRELOAD_SIZE)) @@ -158,10 +151,10 @@ index d172f0341b80..c1da1109a107 100644 +} +EXPORT_SYMBOL(idr_preload_end); + - /** - * ida_pre_get - reserve resources for ida allocation - * @ida: ida handle -@@ -2125,7 +2139,7 @@ int ida_pre_get(struct ida *ida, gfp_t gfp) + int ida_pre_get(struct ida *ida, gfp_t gfp) + { + /* +@@ -2114,7 +2128,7 @@ int ida_pre_get(struct ida *ida, gfp_t g * to return to the ida_pre_get() step. */ if (!__radix_tree_preload(gfp, IDA_PRELOAD_SIZE)) @@ -169,7 +162,4 @@ index d172f0341b80..c1da1109a107 100644 + local_unlock(radix_tree_preloads_lock); if (!this_cpu_read(ida_bitmap)) { - struct ida_bitmap *bitmap = kmalloc(sizeof(*bitmap), gfp); --- -2.19.2 - + struct ida_bitmap *bitmap = kzalloc(sizeof(*bitmap), gfp); diff --git a/kernel/patches-4.14.x-rt/0189-timers-Prepare-for-full-preemption.patch b/kernel/patches-4.19.x-rt/0091-timers-prepare-for-full-preemption.patch similarity index 69% rename from kernel/patches-4.14.x-rt/0189-timers-Prepare-for-full-preemption.patch rename to kernel/patches-4.19.x-rt/0091-timers-prepare-for-full-preemption.patch index eb6120730..f8a40a25b 100644 --- a/kernel/patches-4.14.x-rt/0189-timers-Prepare-for-full-preemption.patch +++ b/kernel/patches-4.19.x-rt/0091-timers-prepare-for-full-preemption.patch @@ -1,7 +1,6 @@ -From 10ac2a3a86592c59cd652aef2a60100d1efeca7c Mon Sep 17 00:00:00 2001 From: Ingo Molnar Date: Fri, 3 Jul 2009 08:29:34 -0500 -Subject: [PATCH 189/450] timers: Prepare for full preemption +Subject: timers: Prepare for full preemption When softirqs can be preempted we need to make sure that cancelling the timer from the active thread can not deadlock vs. a running timer @@ -9,17 +8,16 @@ callback. Add a waitqueue to resolve that. Signed-off-by: Ingo Molnar Signed-off-by: Thomas Gleixner + --- - include/linux/timer.h | 2 +- - kernel/sched/core.c | 9 +++++++-- - kernel/time/timer.c | 45 +++++++++++++++++++++++++++++++++++++++---- + include/linux/timer.h | 2 +- + kernel/sched/core.c | 9 +++++++-- + kernel/time/timer.c | 45 +++++++++++++++++++++++++++++++++++++++++---- 3 files changed, 49 insertions(+), 7 deletions(-) -diff --git a/include/linux/timer.h b/include/linux/timer.h -index e0ea1fe87572..df3085ddf662 100644 --- a/include/linux/timer.h +++ b/include/linux/timer.h -@@ -213,7 +213,7 @@ extern void add_timer(struct timer_list *timer); +@@ -172,7 +172,7 @@ extern void add_timer(struct timer_list extern int try_to_del_timer_sync(struct timer_list *timer); @@ -28,11 +26,9 @@ index e0ea1fe87572..df3085ddf662 100644 extern int del_timer_sync(struct timer_list *timer); #else # define del_timer_sync(t) del_timer(t) -diff --git a/kernel/sched/core.c b/kernel/sched/core.c -index 5b1a76112243..90b83937a338 100644 --- a/kernel/sched/core.c +++ b/kernel/sched/core.c -@@ -523,11 +523,14 @@ void resched_cpu(int cpu) +@@ -496,11 +496,14 @@ void resched_cpu(int cpu) */ int get_nohz_timer_target(void) { @@ -43,14 +39,14 @@ index 5b1a76112243..90b83937a338 100644 + preempt_disable_rt(); + cpu = smp_processor_id(); + - if (!idle_cpu(cpu) && is_housekeeping_cpu(cpu)) + if (!idle_cpu(cpu) && housekeeping_cpu(cpu, HK_FLAG_TIMER)) - return cpu; + goto preempt_en_rt; rcu_read_lock(); for_each_domain(cpu, sd) { -@@ -546,6 +549,8 @@ int get_nohz_timer_target(void) - cpu = housekeeping_any_cpu(); +@@ -519,6 +522,8 @@ int get_nohz_timer_target(void) + cpu = housekeeping_any_cpu(HK_FLAG_TIMER); unlock: rcu_read_unlock(); +preempt_en_rt: @@ -58,8 +54,6 @@ index 5b1a76112243..90b83937a338 100644 return cpu; } -diff --git a/kernel/time/timer.c b/kernel/time/timer.c -index 3b6c7e287f23..97c28b96aeb1 100644 --- a/kernel/time/timer.c +++ b/kernel/time/timer.c @@ -44,6 +44,7 @@ @@ -80,7 +74,7 @@ index 3b6c7e287f23..97c28b96aeb1 100644 unsigned long clk; unsigned long next_expiry; unsigned int cpu; -@@ -1140,6 +1144,33 @@ void add_timer_on(struct timer_list *timer, int cpu) +@@ -1178,6 +1182,33 @@ void add_timer_on(struct timer_list *tim } EXPORT_SYMBOL_GPL(add_timer_on); @@ -97,8 +91,8 @@ index 3b6c7e287f23..97c28b96aeb1 100644 + return; + + base = get_timer_base(tf); -+ swait_event(base->wait_for_running_timer, -+ base->running_timer != timer); ++ swait_event_exclusive(base->wait_for_running_timer, ++ base->running_timer != timer); +} + +# define wakeup_timer_waiters(b) swake_up_all(&(b)->wait_for_running_timer) @@ -114,7 +108,7 @@ index 3b6c7e287f23..97c28b96aeb1 100644 /** * del_timer - deactivate a timer. * @timer: the timer to be deactivated -@@ -1195,7 +1226,7 @@ int try_to_del_timer_sync(struct timer_list *timer) +@@ -1233,7 +1264,7 @@ int try_to_del_timer_sync(struct timer_l } EXPORT_SYMBOL(try_to_del_timer_sync); @@ -123,7 +117,7 @@ index 3b6c7e287f23..97c28b96aeb1 100644 /** * del_timer_sync - deactivate a timer and wait for the handler to finish. * @timer: the timer to be deactivated -@@ -1255,7 +1286,7 @@ int del_timer_sync(struct timer_list *timer) +@@ -1293,7 +1324,7 @@ int del_timer_sync(struct timer_list *ti int ret = try_to_del_timer_sync(timer); if (ret >= 0) return ret; @@ -132,25 +126,25 @@ index 3b6c7e287f23..97c28b96aeb1 100644 } } EXPORT_SYMBOL(del_timer_sync); -@@ -1319,13 +1350,16 @@ static void expire_timers(struct timer_base *base, struct hlist_head *head) +@@ -1354,13 +1385,16 @@ static void expire_timers(struct timer_b + fn = timer->function; - data = timer->data; - if (timer->flags & TIMER_IRQSAFE) { + if (!IS_ENABLED(CONFIG_PREEMPT_RT_FULL) && + timer->flags & TIMER_IRQSAFE) { raw_spin_unlock(&base->lock); - call_timer_fn(timer, fn, data); + call_timer_fn(timer, fn); + base->running_timer = NULL; raw_spin_lock(&base->lock); } else { raw_spin_unlock_irq(&base->lock); - call_timer_fn(timer, fn, data); + call_timer_fn(timer, fn); + base->running_timer = NULL; raw_spin_lock_irq(&base->lock); } } -@@ -1643,8 +1677,8 @@ static inline void __run_timers(struct timer_base *base) +@@ -1681,8 +1715,8 @@ static inline void __run_timers(struct t while (levels--) expire_timers(base, heads + levels); } @@ -160,7 +154,7 @@ index 3b6c7e287f23..97c28b96aeb1 100644 } /* -@@ -1877,6 +1911,9 @@ static void __init init_timer_cpu(int cpu) +@@ -1927,6 +1961,9 @@ static void __init init_timer_cpu(int cp base->cpu = cpu; raw_spin_lock_init(&base->lock); base->clk = jiffies; @@ -170,6 +164,3 @@ index 3b6c7e287f23..97c28b96aeb1 100644 } } --- -2.19.2 - diff --git a/kernel/patches-4.14.x-rt/0192-x86-kvm-Require-const-tsc-for-RT.patch b/kernel/patches-4.19.x-rt/0092-x86-kvm-require-const-tsc-for-rt.patch similarity index 65% rename from kernel/patches-4.14.x-rt/0192-x86-kvm-Require-const-tsc-for-RT.patch rename to kernel/patches-4.19.x-rt/0092-x86-kvm-require-const-tsc-for-rt.patch index 07bef2254..b04b7841c 100644 --- a/kernel/patches-4.14.x-rt/0192-x86-kvm-Require-const-tsc-for-RT.patch +++ b/kernel/patches-4.19.x-rt/0092-x86-kvm-require-const-tsc-for-rt.patch @@ -1,7 +1,6 @@ -From 9109effb72a0964511b0c3a06980bf05a8e7d16d Mon Sep 17 00:00:00 2001 +Subject: x86: kvm Require const tsc for RT From: Thomas Gleixner -Date: Sun, 6 Nov 2011 12:26:18 +0100 -Subject: [PATCH 192/450] x86: kvm Require const tsc for RT +Date: Sun, 06 Nov 2011 12:26:18 +0100 Non constant TSC is a nightmare on bare metal already, but with virtualization it becomes a complete disaster because the workarounds @@ -10,14 +9,12 @@ a guest on top of a RT host. Signed-off-by: Thomas Gleixner --- - arch/x86/kvm/x86.c | 7 +++++++ + arch/x86/kvm/x86.c | 7 +++++++ 1 file changed, 7 insertions(+) -diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c -index f24329659bea..1934203b6fc5 100644 --- a/arch/x86/kvm/x86.c +++ b/arch/x86/kvm/x86.c -@@ -6287,6 +6287,13 @@ int kvm_arch_init(void *opaque) +@@ -6698,6 +6698,13 @@ int kvm_arch_init(void *opaque) goto out; } @@ -31,6 +28,3 @@ index f24329659bea..1934203b6fc5 100644 r = kvm_mmu_module_init(); if (r) goto out_free_percpu; --- -2.19.2 - diff --git a/kernel/patches-4.14.x-rt/0395-pci-switchtec-Don-t-use-completion-s-wait-queue.patch b/kernel/patches-4.19.x-rt/0093-pci-switchtec-Don-t-use-completion-s-wait-queue.patch similarity index 73% rename from kernel/patches-4.14.x-rt/0395-pci-switchtec-Don-t-use-completion-s-wait-queue.patch rename to kernel/patches-4.19.x-rt/0093-pci-switchtec-Don-t-use-completion-s-wait-queue.patch index 29558d312..006169578 100644 --- a/kernel/patches-4.14.x-rt/0395-pci-switchtec-Don-t-use-completion-s-wait-queue.patch +++ b/kernel/patches-4.19.x-rt/0093-pci-switchtec-Don-t-use-completion-s-wait-queue.patch @@ -1,7 +1,6 @@ -From 275b4646cd942674533ee907cf94b2d37731d9f1 Mon Sep 17 00:00:00 2001 From: Sebastian Andrzej Siewior Date: Wed, 4 Oct 2017 10:24:23 +0200 -Subject: [PATCH 395/450] pci/switchtec: Don't use completion's wait queue +Subject: [PATCH] pci/switchtec: Don't use completion's wait queue The poll callback is using completion's wait_queue_head_t member and puts it in poll_wait() so the poll() caller gets a wakeup after command @@ -19,14 +18,12 @@ Cc: Kurt Schwemmer Cc: Logan Gunthorpe Signed-off-by: Sebastian Andrzej Siewior --- - drivers/pci/switch/switchtec.c | 22 +++++++++++++--------- + drivers/pci/switch/switchtec.c | 22 +++++++++++++--------- 1 file changed, 13 insertions(+), 9 deletions(-) -diff --git a/drivers/pci/switch/switchtec.c b/drivers/pci/switch/switchtec.c -index 620f5b995a12..7fd1548a2905 100644 --- a/drivers/pci/switch/switchtec.c +++ b/drivers/pci/switch/switchtec.c -@@ -308,10 +308,11 @@ struct switchtec_user { +@@ -43,10 +43,11 @@ struct switchtec_user { enum mrpc_state state; @@ -39,7 +36,7 @@ index 620f5b995a12..7fd1548a2905 100644 u32 cmd; u32 status; u32 return_code; -@@ -333,7 +334,7 @@ static struct switchtec_user *stuser_create(struct switchtec_dev *stdev) +@@ -68,7 +69,7 @@ static struct switchtec_user *stuser_cre stuser->stdev = stdev; kref_init(&stuser->kref); INIT_LIST_HEAD(&stuser->list); @@ -48,7 +45,7 @@ index 620f5b995a12..7fd1548a2905 100644 stuser->event_cnt = atomic_read(&stdev->event_cnt); dev_dbg(&stdev->dev, "%s: %p\n", __func__, stuser); -@@ -416,7 +417,7 @@ static int mrpc_queue_cmd(struct switchtec_user *stuser) +@@ -151,7 +152,7 @@ static int mrpc_queue_cmd(struct switcht kref_get(&stuser->kref); stuser->read_len = sizeof(stuser->data); stuser_set_state(stuser, MRPC_QUEUED); @@ -57,7 +54,7 @@ index 620f5b995a12..7fd1548a2905 100644 list_add_tail(&stuser->list, &stdev->mrpc_queue); mrpc_cmd_submit(stdev); -@@ -453,7 +454,8 @@ static void mrpc_complete_cmd(struct switchtec_dev *stdev) +@@ -188,7 +189,8 @@ static void mrpc_complete_cmd(struct swi stuser->read_len); out: @@ -67,7 +64,7 @@ index 620f5b995a12..7fd1548a2905 100644 list_del_init(&stuser->list); stuser_put(stuser); stdev->mrpc_busy = 0; -@@ -723,10 +725,11 @@ static ssize_t switchtec_dev_read(struct file *filp, char __user *data, +@@ -458,10 +460,11 @@ static ssize_t switchtec_dev_read(struct mutex_unlock(&stdev->mrpc_mutex); if (filp->f_flags & O_NONBLOCK) { @@ -81,25 +78,25 @@ index 620f5b995a12..7fd1548a2905 100644 if (rc < 0) return rc; } -@@ -774,7 +777,7 @@ static unsigned int switchtec_dev_poll(struct file *filp, poll_table *wait) +@@ -509,7 +512,7 @@ static __poll_t switchtec_dev_poll(struc struct switchtec_dev *stdev = stuser->stdev; - int ret = 0; + __poll_t ret = 0; - poll_wait(filp, &stuser->comp.wait, wait); + poll_wait(filp, &stuser->cmd_comp, wait); poll_wait(filp, &stdev->event_wq, wait); if (lock_mutex_and_test_alive(stdev)) -@@ -782,7 +785,7 @@ static unsigned int switchtec_dev_poll(struct file *filp, poll_table *wait) +@@ -517,7 +520,7 @@ static __poll_t switchtec_dev_poll(struc mutex_unlock(&stdev->mrpc_mutex); - if (try_wait_for_completion(&stuser->comp)) + if (READ_ONCE(stuser->cmd_done)) - ret |= POLLIN | POLLRDNORM; + ret |= EPOLLIN | EPOLLRDNORM; if (stuser->event_cnt != atomic_read(&stdev->event_cnt)) -@@ -1259,7 +1262,8 @@ static void stdev_kill(struct switchtec_dev *stdev) +@@ -1041,7 +1044,8 @@ static void stdev_kill(struct switchtec_ /* Wake up and kill any users waiting on an MRPC request */ list_for_each_entry_safe(stuser, tmpuser, &stdev->mrpc_queue, list) { @@ -109,6 +106,3 @@ index 620f5b995a12..7fd1548a2905 100644 list_del_init(&stuser->list); stuser_put(stuser); } --- -2.19.2 - diff --git a/kernel/patches-4.14.x-rt/0193-wait.h-include-atomic.h.patch b/kernel/patches-4.19.x-rt/0094-wait.h-include-atomic.h.patch similarity index 73% rename from kernel/patches-4.14.x-rt/0193-wait.h-include-atomic.h.patch rename to kernel/patches-4.19.x-rt/0094-wait.h-include-atomic.h.patch index ea9fa9718..0a04f7859 100644 --- a/kernel/patches-4.14.x-rt/0193-wait.h-include-atomic.h.patch +++ b/kernel/patches-4.19.x-rt/0094-wait.h-include-atomic.h.patch @@ -1,10 +1,6 @@ -From 14f4c4246705a01739d7f73fc76b083a0157737e Mon Sep 17 00:00:00 2001 From: Sebastian Andrzej Siewior Date: Mon, 28 Oct 2013 12:19:57 +0100 -Subject: [PATCH 193/450] wait.h: include atomic.h -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit +Subject: wait.h: include atomic.h | CC init/main.o |In file included from include/linux/mmzone.h:9:0, @@ -21,11 +17,9 @@ This pops up on ARM. Non-RT gets its atomic.h include from spinlock.h Signed-off-by: Sebastian Andrzej Siewior --- - include/linux/wait.h | 1 + + include/linux/wait.h | 1 + 1 file changed, 1 insertion(+) -diff --git a/include/linux/wait.h b/include/linux/wait.h -index 158715445ffb..49543ae3dc5f 100644 --- a/include/linux/wait.h +++ b/include/linux/wait.h @@ -10,6 +10,7 @@ @@ -36,6 +30,3 @@ index 158715445ffb..49543ae3dc5f 100644 typedef struct wait_queue_entry wait_queue_entry_t; --- -2.19.2 - diff --git a/kernel/patches-4.14.x-rt/0194-work-simple-Simple-work-queue-implemenation.patch b/kernel/patches-4.19.x-rt/0095-work-simple-Simple-work-queue-implemenation.patch similarity index 82% rename from kernel/patches-4.14.x-rt/0194-work-simple-Simple-work-queue-implemenation.patch rename to kernel/patches-4.19.x-rt/0095-work-simple-Simple-work-queue-implemenation.patch index 272ebe724..3aa8f7b5a 100644 --- a/kernel/patches-4.14.x-rt/0194-work-simple-Simple-work-queue-implemenation.patch +++ b/kernel/patches-4.19.x-rt/0095-work-simple-Simple-work-queue-implemenation.patch @@ -1,7 +1,6 @@ -From 0462e7e9afb6c97aae1210255720e67dadc2b08d Mon Sep 17 00:00:00 2001 From: Daniel Wagner Date: Fri, 11 Jul 2014 15:26:11 +0200 -Subject: [PATCH 194/450] work-simple: Simple work queue implemenation +Subject: work-simple: Simple work queue implemenation Provides a framework for enqueuing callbacks from irq context PREEMPT_RT_FULL safe. The callbacks are executed in kthread context. @@ -11,16 +10,11 @@ Bases on wait-simple. Cc: Sebastian Andrzej Siewior Signed-off-by: Daniel Wagner --- - include/linux/swork.h | 24 ++++++ - kernel/sched/Makefile | 2 +- - kernel/sched/swork.c | 173 ++++++++++++++++++++++++++++++++++++++++++ + include/linux/swork.h | 24 ++++++ + kernel/sched/Makefile | 2 + kernel/sched/swork.c | 173 ++++++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 198 insertions(+), 1 deletion(-) - create mode 100644 include/linux/swork.h - create mode 100644 kernel/sched/swork.c -diff --git a/include/linux/swork.h b/include/linux/swork.h -new file mode 100644 -index 000000000000..f175fa9a6016 --- /dev/null +++ b/include/linux/swork.h @@ -0,0 +1,24 @@ @@ -48,22 +42,17 @@ index 000000000000..f175fa9a6016 +void swork_put(void); + +#endif /* _LINUX_SWORK_H */ -diff --git a/kernel/sched/Makefile b/kernel/sched/Makefile -index a9ee16bbc693..9943019095e9 100644 --- a/kernel/sched/Makefile +++ b/kernel/sched/Makefile @@ -18,7 +18,7 @@ endif obj-y += core.o loadavg.o clock.o cputime.o - obj-y += idle_task.o fair.o rt.o deadline.o --obj-y += wait.o wait_bit.o swait.o completion.o idle.o -+obj-y += wait.o wait_bit.o swait.o swork.o completion.o idle.o - obj-$(CONFIG_SMP) += cpupri.o cpudeadline.o topology.o stop_task.o + obj-y += idle.o fair.o rt.o deadline.o +-obj-y += wait.o wait_bit.o swait.o completion.o ++obj-y += wait.o wait_bit.o swait.o swork.o completion.o + + obj-$(CONFIG_SMP) += cpupri.o cpudeadline.o topology.o stop_task.o pelt.o obj-$(CONFIG_SCHED_AUTOGROUP) += autogroup.o - obj-$(CONFIG_SCHEDSTATS) += stats.o -diff --git a/kernel/sched/swork.c b/kernel/sched/swork.c -new file mode 100644 -index 000000000000..1950f40ca725 --- /dev/null +++ b/kernel/sched/swork.c @@ -0,0 +1,173 @@ @@ -115,8 +104,8 @@ index 000000000000..1950f40ca725 + struct sworker *worker = arg; + + for (;;) { -+ swait_event_interruptible(worker->wq, -+ swork_readable(worker)); ++ swait_event_interruptible_exclusive(worker->wq, ++ swork_readable(worker)); + if (kthread_should_stop()) + break; + @@ -186,7 +175,7 @@ index 000000000000..1950f40ca725 + list_add_tail(&sev->item, &glob_worker->events); + raw_spin_unlock_irqrestore(&glob_worker->lock, flags); + -+ swake_up(&glob_worker->wq); ++ swake_up_one(&glob_worker->wq); + return true; +} +EXPORT_SYMBOL_GPL(swork_queue); @@ -240,6 +229,3 @@ index 000000000000..1950f40ca725 + mutex_unlock(&worker_mutex); +} +EXPORT_SYMBOL_GPL(swork_put); --- -2.19.2 - diff --git a/kernel/patches-4.14.x-rt/0437-work-simple-drop-a-shit-statement-in-SWORK_EVENT_PEN.patch b/kernel/patches-4.19.x-rt/0096-work-simple-drop-a-shit-statement-in-SWORK_EVENT_PEN.patch similarity index 66% rename from kernel/patches-4.14.x-rt/0437-work-simple-drop-a-shit-statement-in-SWORK_EVENT_PEN.patch rename to kernel/patches-4.19.x-rt/0096-work-simple-drop-a-shit-statement-in-SWORK_EVENT_PEN.patch index bcb80b171..28dcceea5 100644 --- a/kernel/patches-4.14.x-rt/0437-work-simple-drop-a-shit-statement-in-SWORK_EVENT_PEN.patch +++ b/kernel/patches-4.19.x-rt/0096-work-simple-drop-a-shit-statement-in-SWORK_EVENT_PEN.patch @@ -1,10 +1,6 @@ -From 7b506395063ec5de54a495dfd2e5e9a650bf7160 Mon Sep 17 00:00:00 2001 From: Sebastian Andrzej Siewior Date: Mon, 10 Sep 2018 18:00:31 +0200 -Subject: [PATCH 437/450] work-simple: drop a shit statement in - SWORK_EVENT_PENDING - -[ Upstream commit 22f41ebe5579cc847a7bb6c71916be92c8926216 ] +Subject: [PATCH] work-simple: drop a shit statement in SWORK_EVENT_PENDING Dan Carpenter reported | smatch warnings: @@ -16,13 +12,10 @@ Nevertheless I'm dropping that shift by zero to keep smatch quiet. Cc: Daniel Wagner Signed-off-by: Sebastian Andrzej Siewior -Signed-off-by: Steven Rostedt (VMware) --- - kernel/sched/swork.c | 2 +- + kernel/sched/swork.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) -diff --git a/kernel/sched/swork.c b/kernel/sched/swork.c -index 1950f40ca725..5559c22f664c 100644 --- a/kernel/sched/swork.c +++ b/kernel/sched/swork.c @@ -12,7 +12,7 @@ @@ -34,6 +27,3 @@ index 1950f40ca725..5559c22f664c 100644 static DEFINE_MUTEX(worker_mutex); static struct sworker *glob_worker; --- -2.19.2 - diff --git a/kernel/patches-4.14.x-rt/0195-completion-Use-simple-wait-queues.patch b/kernel/patches-4.19.x-rt/0097-completion-use-simple-wait-queues.patch similarity index 60% rename from kernel/patches-4.14.x-rt/0195-completion-Use-simple-wait-queues.patch rename to kernel/patches-4.19.x-rt/0097-completion-use-simple-wait-queues.patch index 57c9f9c91..73bf7cf14 100644 --- a/kernel/patches-4.14.x-rt/0195-completion-Use-simple-wait-queues.patch +++ b/kernel/patches-4.19.x-rt/0097-completion-use-simple-wait-queues.patch @@ -1,7 +1,6 @@ -From 54cdce8b41456443fa2e99c989878ea1f4c58523 Mon Sep 17 00:00:00 2001 +Subject: completion: Use simple wait queues From: Thomas Gleixner Date: Fri, 11 Jan 2013 11:23:51 +0100 -Subject: [PATCH 195/450] completion: Use simple wait queues Completions have no long lasting callbacks and therefor do not need the complex waitqueue variant. Use simple waitqueues which reduces the @@ -9,37 +8,49 @@ contention on the waitqueue lock. Signed-off-by: Thomas Gleixner --- - .../wireless/intersil/orinoco/orinoco_usb.c | 2 +- - drivers/usb/gadget/function/f_fs.c | 2 +- - drivers/usb/gadget/legacy/inode.c | 4 +-- - include/linux/completion.h | 10 +++--- - include/linux/suspend.h | 6 ++++ - include/linux/swait.h | 1 + - kernel/power/hibernate.c | 7 ++++ - kernel/power/suspend.c | 4 +++ - kernel/sched/completion.c | 34 +++++++++---------- - kernel/sched/core.c | 10 ++++-- - kernel/sched/swait.c | 20 +++++++++++ - 11 files changed, 72 insertions(+), 28 deletions(-) + arch/powerpc/platforms/ps3/device-init.c | 4 +- + drivers/net/wireless/intersil/orinoco/orinoco_usb.c | 4 +- + drivers/usb/gadget/function/f_fs.c | 2 - + drivers/usb/gadget/legacy/inode.c | 4 +- + include/linux/completion.h | 8 ++-- + include/linux/suspend.h | 6 +++ + include/linux/swait.h | 2 + + kernel/power/hibernate.c | 7 ++++ + kernel/power/suspend.c | 4 ++ + kernel/sched/completion.c | 34 ++++++++++---------- + kernel/sched/core.c | 10 ++++- + kernel/sched/swait.c | 21 +++++++++++- + 12 files changed, 75 insertions(+), 31 deletions(-) -diff --git a/drivers/net/wireless/intersil/orinoco/orinoco_usb.c b/drivers/net/wireless/intersil/orinoco/orinoco_usb.c -index 56f6e3b71f48..a50350d01a80 100644 +--- a/arch/powerpc/platforms/ps3/device-init.c ++++ b/arch/powerpc/platforms/ps3/device-init.c +@@ -752,8 +752,8 @@ static int ps3_notification_read_write(s + } + pr_debug("%s:%u: notification %s issued\n", __func__, __LINE__, op); + +- res = wait_event_interruptible(dev->done.wait, +- dev->done.done || kthread_should_stop()); ++ res = swait_event_interruptible_exclusive(dev->done.wait, ++ dev->done.done || kthread_should_stop()); + if (kthread_should_stop()) + res = -EINTR; + if (res) { --- a/drivers/net/wireless/intersil/orinoco/orinoco_usb.c +++ b/drivers/net/wireless/intersil/orinoco/orinoco_usb.c -@@ -697,7 +697,7 @@ static void ezusb_req_ctx_wait(struct ezusb_priv *upriv, +@@ -697,8 +697,8 @@ static void ezusb_req_ctx_wait(struct ez while (!ctx->done.done && msecs--) udelay(1000); } else { - wait_event_interruptible(ctx->done.wait, -+ swait_event_interruptible(ctx->done.wait, - ctx->done.done); +- ctx->done.done); ++ swait_event_interruptible_exclusive(ctx->done.wait, ++ ctx->done.done); } break; -diff --git a/drivers/usb/gadget/function/f_fs.c b/drivers/usb/gadget/function/f_fs.c -index 17467545391b..42ec6f2db6a9 100644 + default: --- a/drivers/usb/gadget/function/f_fs.c +++ b/drivers/usb/gadget/function/f_fs.c -@@ -1623,7 +1623,7 @@ static void ffs_data_put(struct ffs_data *ffs) +@@ -1623,7 +1623,7 @@ static void ffs_data_put(struct ffs_data pr_info("%s(): freeing\n", __func__); ffs_data_clear(ffs); BUG_ON(waitqueue_active(&ffs->ev.waitq) || @@ -48,30 +59,26 @@ index 17467545391b..42ec6f2db6a9 100644 waitqueue_active(&ffs->wait)); destroy_workqueue(ffs->io_completion_wq); kfree(ffs->dev_name); -diff --git a/drivers/usb/gadget/legacy/inode.c b/drivers/usb/gadget/legacy/inode.c -index 5c28bee327e1..ed49dba4704d 100644 --- a/drivers/usb/gadget/legacy/inode.c +++ b/drivers/usb/gadget/legacy/inode.c -@@ -347,7 +347,7 @@ ep_io (struct ep_data *epdata, void *buf, unsigned len) +@@ -343,7 +343,7 @@ ep_io (struct ep_data *epdata, void *buf spin_unlock_irq (&epdata->dev->lock); if (likely (value == 0)) { - value = wait_event_interruptible (done.wait, done.done); -+ value = swait_event_interruptible (done.wait, done.done); ++ value = swait_event_interruptible_exclusive(done.wait, done.done); if (value != 0) { spin_lock_irq (&epdata->dev->lock); if (likely (epdata->ep != NULL)) { -@@ -356,7 +356,7 @@ ep_io (struct ep_data *epdata, void *buf, unsigned len) +@@ -352,7 +352,7 @@ ep_io (struct ep_data *epdata, void *buf usb_ep_dequeue (epdata->ep, epdata->req); spin_unlock_irq (&epdata->dev->lock); - wait_event (done.wait, done.done); -+ swait_event (done.wait, done.done); ++ swait_event_exclusive(done.wait, done.done); if (epdata->status == -ECONNRESET) epdata->status = -EINTR; } else { -diff --git a/include/linux/completion.h b/include/linux/completion.h -index 7828451e161a..f5838b10cf84 100644 --- a/include/linux/completion.h +++ b/include/linux/completion.h @@ -9,7 +9,7 @@ @@ -80,33 +87,28 @@ index 7828451e161a..f5838b10cf84 100644 -#include +#include - #ifdef CONFIG_LOCKDEP_COMPLETIONS - #include - #endif -@@ -28,7 +28,7 @@ + + /* + * struct completion - structure used to maintain state for a "completion" +@@ -25,7 +25,7 @@ */ struct completion { unsigned int done; - wait_queue_head_t wait; + struct swait_queue_head wait; - #ifdef CONFIG_LOCKDEP_COMPLETIONS - struct lockdep_map_cross map; - #endif -@@ -67,11 +67,11 @@ static inline void complete_release_commit(struct completion *x) {} + }; + + #define init_completion_map(x, m) __init_completion(x) +@@ -34,7 +34,7 @@ static inline void complete_acquire(stru + static inline void complete_release(struct completion *x) {} - #ifdef CONFIG_LOCKDEP_COMPLETIONS - #define COMPLETION_INITIALIZER(work) \ -- { 0, __WAIT_QUEUE_HEAD_INITIALIZER((work).wait), \ -+ { 0, __SWAIT_QUEUE_HEAD_INITIALIZER((work).wait), \ - STATIC_CROSS_LOCKDEP_MAP_INIT("(complete)" #work, &(work)) } - #else #define COMPLETION_INITIALIZER(work) \ - { 0, __WAIT_QUEUE_HEAD_INITIALIZER((work).wait) } + { 0, __SWAIT_QUEUE_HEAD_INITIALIZER((work).wait) } - #endif - #define COMPLETION_INITIALIZER_ONSTACK(work) \ -@@ -117,7 +117,7 @@ static inline void complete_release_commit(struct completion *x) {} + #define COMPLETION_INITIALIZER_ONSTACK_MAP(work, map) \ + (*({ init_completion_map(&(work), &(map)); &(work); })) +@@ -85,7 +85,7 @@ static inline void complete_release(stru static inline void __init_completion(struct completion *x) { x->done = 0; @@ -115,8 +117,6 @@ index 7828451e161a..f5838b10cf84 100644 } /** -diff --git a/include/linux/suspend.h b/include/linux/suspend.h -index 8544357d92d0..616ea66cd283 100644 --- a/include/linux/suspend.h +++ b/include/linux/suspend.h @@ -196,6 +196,12 @@ struct platform_s2idle_ops { @@ -132,23 +132,21 @@ index 8544357d92d0..616ea66cd283 100644 #ifdef CONFIG_SUSPEND extern suspend_state_t mem_sleep_current; extern suspend_state_t mem_sleep_default; -diff --git a/include/linux/swait.h b/include/linux/swait.h -index 84f9745365ff..853f3e61a9f4 100644 --- a/include/linux/swait.h +++ b/include/linux/swait.h -@@ -148,6 +148,7 @@ static inline bool swq_has_sleeper(struct swait_queue_head *wq) - extern void swake_up(struct swait_queue_head *q); +@@ -160,7 +160,9 @@ static inline bool swq_has_sleeper(struc + extern void swake_up_one(struct swait_queue_head *q); extern void swake_up_all(struct swait_queue_head *q); extern void swake_up_locked(struct swait_queue_head *q); +extern void swake_up_all_locked(struct swait_queue_head *q); - extern void __prepare_to_swait(struct swait_queue_head *q, struct swait_queue *wait); - extern void prepare_to_swait(struct swait_queue_head *q, struct swait_queue *wait, int state); -diff --git a/kernel/power/hibernate.c b/kernel/power/hibernate.c -index 7c7dbbf23f37..a4b83cb0c6e5 100644 ++extern void __prepare_to_swait(struct swait_queue_head *q, struct swait_queue *wait); + extern void prepare_to_swait_exclusive(struct swait_queue_head *q, struct swait_queue *wait, int state); + extern long prepare_to_swait_event(struct swait_queue_head *q, struct swait_queue *wait, int state); + --- a/kernel/power/hibernate.c +++ b/kernel/power/hibernate.c -@@ -679,6 +679,10 @@ static int load_image_and_restore(void) +@@ -681,6 +681,10 @@ static int load_image_and_restore(void) return error; } @@ -159,7 +157,7 @@ index 7c7dbbf23f37..a4b83cb0c6e5 100644 /** * hibernate - Carry out system hibernation, including saving the image. */ -@@ -692,6 +696,8 @@ int hibernate(void) +@@ -694,6 +698,8 @@ int hibernate(void) return -EPERM; } @@ -168,7 +166,7 @@ index 7c7dbbf23f37..a4b83cb0c6e5 100644 lock_system_sleep(); /* The snapshot device should not be opened while we're running */ if (!atomic_add_unless(&snapshot_device_available, -1, 0)) { -@@ -770,6 +776,7 @@ int hibernate(void) +@@ -772,6 +778,7 @@ int hibernate(void) atomic_inc(&snapshot_device_available); Unlock: unlock_system_sleep(); @@ -176,11 +174,9 @@ index 7c7dbbf23f37..a4b83cb0c6e5 100644 pr_info("hibernation exit\n"); return error; -diff --git a/kernel/power/suspend.c b/kernel/power/suspend.c -index 0d3dab53c527..999236413460 100644 --- a/kernel/power/suspend.c +++ b/kernel/power/suspend.c -@@ -593,6 +593,8 @@ static int enter_state(suspend_state_t state) +@@ -600,6 +600,8 @@ static int enter_state(suspend_state_t s return error; } @@ -189,7 +185,7 @@ index 0d3dab53c527..999236413460 100644 /** * pm_suspend - Externally visible function for suspending the system. * @state: System sleep state to enter. -@@ -607,6 +609,7 @@ int pm_suspend(suspend_state_t state) +@@ -614,6 +616,7 @@ int pm_suspend(suspend_state_t state) if (state <= PM_SUSPEND_ON || state >= PM_SUSPEND_MAX) return -EINVAL; @@ -197,7 +193,7 @@ index 0d3dab53c527..999236413460 100644 pr_info("suspend entry (%s)\n", mem_sleep_labels[state]); error = enter_state(state); if (error) { -@@ -616,6 +619,7 @@ int pm_suspend(suspend_state_t state) +@@ -623,6 +626,7 @@ int pm_suspend(suspend_state_t state) suspend_stats.success++; } pr_info("suspend exit\n"); @@ -205,21 +201,15 @@ index 0d3dab53c527..999236413460 100644 return error; } EXPORT_SYMBOL(pm_suspend); -diff --git a/kernel/sched/completion.c b/kernel/sched/completion.c -index 2ddaec40956f..0fe2982e46a0 100644 --- a/kernel/sched/completion.c +++ b/kernel/sched/completion.c -@@ -32,7 +32,7 @@ void complete(struct completion *x) +@@ -29,12 +29,12 @@ void complete(struct completion *x) { unsigned long flags; - spin_lock_irqsave(&x->wait.lock, flags); + raw_spin_lock_irqsave(&x->wait.lock, flags); - /* - * Perform commit of crossrelease here. -@@ -41,8 +41,8 @@ void complete(struct completion *x) - if (x->done != UINT_MAX) x->done++; - __wake_up_locked(&x->wait, TASK_NORMAL, 1); @@ -229,7 +219,7 @@ index 2ddaec40956f..0fe2982e46a0 100644 } EXPORT_SYMBOL(complete); -@@ -66,10 +66,10 @@ void complete_all(struct completion *x) +@@ -58,10 +58,10 @@ void complete_all(struct completion *x) { unsigned long flags; @@ -243,7 +233,7 @@ index 2ddaec40956f..0fe2982e46a0 100644 } EXPORT_SYMBOL(complete_all); -@@ -78,20 +78,20 @@ do_wait_for_common(struct completion *x, +@@ -70,20 +70,20 @@ do_wait_for_common(struct completion *x, long (*action)(long), long timeout, int state) { if (!x->done) { @@ -269,7 +259,7 @@ index 2ddaec40956f..0fe2982e46a0 100644 if (!x->done) return timeout; } -@@ -108,9 +108,9 @@ __wait_for_common(struct completion *x, +@@ -100,9 +100,9 @@ static inline long __sched complete_acquire(x); @@ -281,14 +271,14 @@ index 2ddaec40956f..0fe2982e46a0 100644 complete_release(x); -@@ -299,12 +299,12 @@ bool try_wait_for_completion(struct completion *x) +@@ -291,12 +291,12 @@ bool try_wait_for_completion(struct comp if (!READ_ONCE(x->done)) - return 0; + return false; - spin_lock_irqsave(&x->wait.lock, flags); + raw_spin_lock_irqsave(&x->wait.lock, flags); if (!x->done) - ret = 0; + ret = false; else if (x->done != UINT_MAX) x->done--; - spin_unlock_irqrestore(&x->wait.lock, flags); @@ -296,7 +286,7 @@ index 2ddaec40956f..0fe2982e46a0 100644 return ret; } EXPORT_SYMBOL(try_wait_for_completion); -@@ -330,8 +330,8 @@ bool completion_done(struct completion *x) +@@ -322,8 +322,8 @@ bool completion_done(struct completion * * otherwise we can end up freeing the completion before complete() * is done referencing it. */ @@ -307,11 +297,9 @@ index 2ddaec40956f..0fe2982e46a0 100644 return true; } EXPORT_SYMBOL(completion_done); -diff --git a/kernel/sched/core.c b/kernel/sched/core.c -index 90b83937a338..694bdd953270 100644 --- a/kernel/sched/core.c +++ b/kernel/sched/core.c -@@ -6819,7 +6819,10 @@ void migrate_disable(void) +@@ -7107,7 +7107,10 @@ void migrate_disable(void) return; } #ifdef CONFIG_SCHED_DEBUG @@ -323,7 +311,7 @@ index 90b83937a338..694bdd953270 100644 #endif if (p->migrate_disable) { -@@ -6849,7 +6852,10 @@ void migrate_enable(void) +@@ -7137,7 +7140,10 @@ void migrate_enable(void) } #ifdef CONFIG_SCHED_DEBUG @@ -335,19 +323,9 @@ index 90b83937a338..694bdd953270 100644 #endif WARN_ON_ONCE(p->migrate_disable <= 0); -diff --git a/kernel/sched/swait.c b/kernel/sched/swait.c -index 9ff1555341ed..7006375949c2 100644 --- a/kernel/sched/swait.c +++ b/kernel/sched/swait.c -@@ -1,6 +1,7 @@ - // SPDX-License-Identifier: GPL-2.0 - #include - #include -+#include - - void __init_swait_queue_head(struct swait_queue_head *q, const char *name, - struct lock_class_key *key) -@@ -30,6 +31,25 @@ void swake_up_locked(struct swait_queue_head *q) +@@ -32,6 +32,25 @@ void swake_up_locked(struct swait_queue_ } EXPORT_SYMBOL(swake_up_locked); @@ -370,9 +348,15 @@ index 9ff1555341ed..7006375949c2 100644 +} +EXPORT_SYMBOL(swake_up_all_locked); + - void swake_up(struct swait_queue_head *q) + void swake_up_one(struct swait_queue_head *q) { unsigned long flags; --- -2.19.2 - +@@ -69,7 +88,7 @@ void swake_up_all(struct swait_queue_hea + } + EXPORT_SYMBOL(swake_up_all); + +-static void __prepare_to_swait(struct swait_queue_head *q, struct swait_queue *wait) ++void __prepare_to_swait(struct swait_queue_head *q, struct swait_queue *wait) + { + wait->task = current; + if (list_empty(&wait->task_list)) diff --git a/kernel/patches-4.14.x-rt/0196-fs-aio-simple-simple-work.patch b/kernel/patches-4.19.x-rt/0098-fs-aio-simple-simple-work.patch similarity index 81% rename from kernel/patches-4.14.x-rt/0196-fs-aio-simple-simple-work.patch rename to kernel/patches-4.19.x-rt/0098-fs-aio-simple-simple-work.patch index b1b8a9532..948376a9e 100644 --- a/kernel/patches-4.14.x-rt/0196-fs-aio-simple-simple-work.patch +++ b/kernel/patches-4.19.x-rt/0098-fs-aio-simple-simple-work.patch @@ -1,7 +1,6 @@ -From 251a0495ea9e42f32d656ee371261456f9e73f21 Mon Sep 17 00:00:00 2001 From: Sebastian Andrzej Siewior Date: Mon, 16 Feb 2015 18:49:10 +0100 -Subject: [PATCH 196/450] fs/aio: simple simple work +Subject: fs/aio: simple simple work |BUG: sleeping function called from invalid context at kernel/locking/rtmutex.c:768 |in_atomic(): 1, irqs_disabled(): 0, pid: 26, name: rcuos/2 @@ -25,14 +24,12 @@ Reported-By: Mike Galbraith Suggested-by: Benjamin LaHaise Signed-off-by: Sebastian Andrzej Siewior --- - fs/aio.c | 15 +++++++++++++-- + fs/aio.c | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) -diff --git a/fs/aio.c b/fs/aio.c -index 3a749c3a92e3..24c6ceadaae6 100644 --- a/fs/aio.c +++ b/fs/aio.c -@@ -40,6 +40,7 @@ +@@ -42,6 +42,7 @@ #include #include #include @@ -40,15 +37,15 @@ index 3a749c3a92e3..24c6ceadaae6 100644 #include #include -@@ -117,6 +118,7 @@ struct kioctx { +@@ -121,6 +122,7 @@ struct kioctx { + long nr_pages; - struct rcu_head free_rcu; - struct work_struct free_work; /* see free_ioctx() */ + struct rcu_work free_rwork; /* see free_ioctx() */ + struct swork_event free_swork; /* see free_ioctx() */ /* * signals when all in-flight requests are done -@@ -259,6 +261,7 @@ static int __init aio_setup(void) +@@ -255,6 +257,7 @@ static int __init aio_setup(void) .mount = aio_mount, .kill_sb = kill_anon_super, }; @@ -56,7 +53,7 @@ index 3a749c3a92e3..24c6ceadaae6 100644 aio_mnt = kern_mount(&aio_fs); if (IS_ERR(aio_mnt)) panic("Failed to create aio fs mount."); -@@ -633,9 +636,9 @@ static void free_ioctx_reqs(struct percpu_ref *ref) +@@ -596,9 +599,9 @@ static void free_ioctx_reqs(struct percp * and ctx->users has dropped to 0, so we know no more kiocbs can be submitted - * now it's safe to cancel any that need to be. */ @@ -68,7 +65,7 @@ index 3a749c3a92e3..24c6ceadaae6 100644 struct aio_kiocb *req; spin_lock_irq(&ctx->ctx_lock); -@@ -653,6 +656,14 @@ static void free_ioctx_users(struct percpu_ref *ref) +@@ -616,6 +619,14 @@ static void free_ioctx_users(struct perc percpu_ref_put(&ctx->reqs); } @@ -83,6 +80,3 @@ index 3a749c3a92e3..24c6ceadaae6 100644 static int ioctx_add_table(struct kioctx *ctx, struct mm_struct *mm) { unsigned i, new_nr; --- -2.19.2 - diff --git a/kernel/patches-4.14.x-rt/0197-genirq-Do-not-invoke-the-affinity-callback-via-a-wor.patch b/kernel/patches-4.19.x-rt/0099-genirq-do-not-invoke-the-affinity-callback-via-a-wor.patch similarity index 75% rename from kernel/patches-4.14.x-rt/0197-genirq-Do-not-invoke-the-affinity-callback-via-a-wor.patch rename to kernel/patches-4.19.x-rt/0099-genirq-do-not-invoke-the-affinity-callback-via-a-wor.patch index 06ea6ad7c..0756a713a 100644 --- a/kernel/patches-4.14.x-rt/0197-genirq-Do-not-invoke-the-affinity-callback-via-a-wor.patch +++ b/kernel/patches-4.19.x-rt/0099-genirq-do-not-invoke-the-affinity-callback-via-a-wor.patch @@ -1,8 +1,6 @@ -From 674f8ce0de7f72664c12cf56c4b8ac1d34c605e3 Mon Sep 17 00:00:00 2001 From: Sebastian Andrzej Siewior Date: Wed, 21 Aug 2013 17:48:46 +0200 -Subject: [PATCH 197/450] genirq: Do not invoke the affinity callback via a - workqueue on RT +Subject: genirq: Do not invoke the affinity callback via a workqueue on RT Joe Korty reported, that __irq_set_affinity_locked() schedules a workqueue while holding a rawlock which results in a might_sleep() @@ -11,15 +9,13 @@ This patch uses swork_queue() instead. Signed-off-by: Sebastian Andrzej Siewior --- - include/linux/interrupt.h | 6 ++++++ - kernel/irq/manage.c | 43 ++++++++++++++++++++++++++++++++++++--- + include/linux/interrupt.h | 6 ++++++ + kernel/irq/manage.c | 43 ++++++++++++++++++++++++++++++++++++++++--- 2 files changed, 46 insertions(+), 3 deletions(-) -diff --git a/include/linux/interrupt.h b/include/linux/interrupt.h -index 2395ebb443b9..172376b9a049 100644 --- a/include/linux/interrupt.h +++ b/include/linux/interrupt.h -@@ -15,6 +15,7 @@ +@@ -13,6 +13,7 @@ #include #include #include @@ -27,7 +23,7 @@ index 2395ebb443b9..172376b9a049 100644 #include #include -@@ -227,6 +228,7 @@ extern void resume_device_irqs(void); +@@ -225,6 +226,7 @@ extern void resume_device_irqs(void); * struct irq_affinity_notify - context for notification of IRQ affinity changes * @irq: Interrupt to which notification applies * @kref: Reference count, for internal use @@ -35,7 +31,7 @@ index 2395ebb443b9..172376b9a049 100644 * @work: Work item, for internal use * @notify: Function to be called on change. This will be * called in process context. -@@ -238,7 +240,11 @@ extern void resume_device_irqs(void); +@@ -236,7 +238,11 @@ extern void resume_device_irqs(void); struct irq_affinity_notify { unsigned int irq; struct kref kref; @@ -47,11 +43,9 @@ index 2395ebb443b9..172376b9a049 100644 void (*notify)(struct irq_affinity_notify *, const cpumask_t *mask); void (*release)(struct kref *ref); }; -diff --git a/kernel/irq/manage.c b/kernel/irq/manage.c -index f9934b6d879e..ead9da12c26a 100644 --- a/kernel/irq/manage.c +++ b/kernel/irq/manage.c -@@ -226,7 +226,12 @@ int irq_set_affinity_locked(struct irq_data *data, const struct cpumask *mask, +@@ -259,7 +259,12 @@ int irq_set_affinity_locked(struct irq_d if (desc->affinity_notify) { kref_get(&desc->affinity_notify->kref); @@ -64,7 +58,7 @@ index f9934b6d879e..ead9da12c26a 100644 } irqd_set(data, IRQD_AFFINITY_SET); -@@ -264,10 +269,8 @@ int irq_set_affinity_hint(unsigned int irq, const struct cpumask *m) +@@ -297,10 +302,8 @@ int irq_set_affinity_hint(unsigned int i } EXPORT_SYMBOL_GPL(irq_set_affinity_hint); @@ -76,7 +70,7 @@ index f9934b6d879e..ead9da12c26a 100644 struct irq_desc *desc = irq_to_desc(notify->irq); cpumask_var_t cpumask; unsigned long flags; -@@ -289,6 +292,35 @@ static void irq_affinity_notify(struct work_struct *work) +@@ -322,6 +325,35 @@ static void irq_affinity_notify(struct w kref_put(¬ify->kref, notify->release); } @@ -112,7 +106,7 @@ index f9934b6d879e..ead9da12c26a 100644 /** * irq_set_affinity_notifier - control notification of IRQ affinity changes * @irq: Interrupt for which to enable/disable notification -@@ -317,7 +349,12 @@ irq_set_affinity_notifier(unsigned int irq, struct irq_affinity_notify *notify) +@@ -350,7 +382,12 @@ irq_set_affinity_notifier(unsigned int i if (notify) { notify->irq = irq; kref_init(¬ify->kref); @@ -125,6 +119,3 @@ index f9934b6d879e..ead9da12c26a 100644 } raw_spin_lock_irqsave(&desc->lock, flags); --- -2.19.2 - diff --git a/kernel/patches-4.14.x-rt/0198-time-hrtimer-avoid-schedule_work-with-interrupts-dis.patch b/kernel/patches-4.19.x-rt/0100-time-hrtimer-avoid-schedule_work-with-interrupts-dis.patch similarity index 72% rename from kernel/patches-4.14.x-rt/0198-time-hrtimer-avoid-schedule_work-with-interrupts-dis.patch rename to kernel/patches-4.19.x-rt/0100-time-hrtimer-avoid-schedule_work-with-interrupts-dis.patch index 2483c0e29..e108d70f7 100644 --- a/kernel/patches-4.14.x-rt/0198-time-hrtimer-avoid-schedule_work-with-interrupts-dis.patch +++ b/kernel/patches-4.19.x-rt/0100-time-hrtimer-avoid-schedule_work-with-interrupts-dis.patch @@ -1,22 +1,18 @@ -From 99f37ca964eaf9bbf602221d3afb82c22586e778 Mon Sep 17 00:00:00 2001 From: Sebastian Andrzej Siewior Date: Wed, 15 Nov 2017 17:29:51 +0100 -Subject: [PATCH 198/450] time/hrtimer: avoid schedule_work() with interrupts - disabled +Subject: [PATCH] time/hrtimer: avoid schedule_work() with interrupts disabled The NOHZ code tries to schedule a workqueue with interrupts disabled. Since this does not work -RT I am switching it to swork instead. Signed-off-by: Sebastian Andrzej Siewior --- - kernel/time/timer.c | 15 +++++++++++---- + kernel/time/timer.c | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) -diff --git a/kernel/time/timer.c b/kernel/time/timer.c -index 807133c1bc20..9b08190ff65a 100644 --- a/kernel/time/timer.c +++ b/kernel/time/timer.c -@@ -217,8 +217,7 @@ static DEFINE_PER_CPU(struct timer_base, timer_bases[NR_BASES]); +@@ -217,8 +217,7 @@ static DEFINE_PER_CPU(struct timer_base, static DEFINE_STATIC_KEY_FALSE(timers_nohz_active); static DEFINE_MUTEX(timer_keys_mutex); @@ -26,7 +22,7 @@ index 807133c1bc20..9b08190ff65a 100644 #ifdef CONFIG_SMP unsigned int sysctl_timer_migration = 1; -@@ -238,7 +237,7 @@ static void timers_update_migration(void) +@@ -236,7 +235,7 @@ static void timers_update_migration(void static inline void timers_update_migration(void) { } #endif /* !CONFIG_SMP */ @@ -35,7 +31,7 @@ index 807133c1bc20..9b08190ff65a 100644 { mutex_lock(&timer_keys_mutex); timers_update_migration(); -@@ -248,9 +247,17 @@ static void timer_update_keys(struct work_struct *work) +@@ -246,9 +245,17 @@ static void timer_update_keys(struct wor void timers_update_nohz(void) { @@ -54,6 +50,3 @@ index 807133c1bc20..9b08190ff65a 100644 int timer_migration_handler(struct ctl_table *table, int write, void __user *buffer, size_t *lenp, loff_t *ppos) --- -2.19.2 - diff --git a/kernel/patches-4.14.x-rt/0199-hrtimer-consolidate-hrtimer_init-hrtimer_init_sleepe.patch b/kernel/patches-4.19.x-rt/0101-hrtimer-consolidate-hrtimer_init-hrtimer_init_sleepe.patch similarity index 73% rename from kernel/patches-4.14.x-rt/0199-hrtimer-consolidate-hrtimer_init-hrtimer_init_sleepe.patch rename to kernel/patches-4.19.x-rt/0101-hrtimer-consolidate-hrtimer_init-hrtimer_init_sleepe.patch index 7ce57be61..54a6a1002 100644 --- a/kernel/patches-4.14.x-rt/0199-hrtimer-consolidate-hrtimer_init-hrtimer_init_sleepe.patch +++ b/kernel/patches-4.19.x-rt/0101-hrtimer-consolidate-hrtimer_init-hrtimer_init_sleepe.patch @@ -1,28 +1,32 @@ -From 96e3bf1d2cdf9a751c29c974bfb3e523dfdacc8f Mon Sep 17 00:00:00 2001 From: Sebastian Andrzej Siewior -Date: Mon, 4 Sep 2017 18:31:50 +0200 -Subject: [PATCH 199/450] hrtimer: consolidate hrtimer_init() + - hrtimer_init_sleeper() calls +Date: Tue, 3 Jul 2018 11:25:41 +0200 +Subject: [PATCH v2] hrtimer: consolidate hrtimer_init() + hrtimer_init_sleeper() calls hrtimer_init_sleeper() calls require a prior initialisation of the -hrtimer object with hrtimer_init(). Lets make the initialisation of the -hrtimer object part of hrtimer_init_sleeper(). +hrtimer object with hrtimer_init(). Lets make the initialisation of +the hrtimer object part of hrtimer_init_sleeper(). To remain +consistent consider init_on_stack as well. +Beside adapting the hrtimer_init_sleeper[_on_stack]() functions, call +sites need to be updated as well. + +Link: http://lkml.kernel.org/r/20180703092541.2870-1-anna-maria@linutronix.de Signed-off-by: Sebastian Andrzej Siewior +[anna-maria: Updating the commit message, add staging/android/vsoc.c] +Signed-off-by: Anna-Maria Gleixner --- - block/blk-mq.c | 3 +-- - include/linux/hrtimer.h | 19 ++++++++++++++--- - include/linux/wait.h | 4 ++-- - kernel/futex.c | 19 +++++++---------- - kernel/time/hrtimer.c | 46 ++++++++++++++++++++++++++++++++--------- - net/core/pktgen.c | 4 ++-- - 6 files changed, 65 insertions(+), 30 deletions(-) + block/blk-mq.c | 3 -- + drivers/staging/android/vsoc.c | 6 +---- + include/linux/hrtimer.h | 19 ++++++++++++++-- + include/linux/wait.h | 4 +-- + kernel/futex.c | 19 +++++++--------- + kernel/time/hrtimer.c | 46 ++++++++++++++++++++++++++++++++--------- + net/core/pktgen.c | 4 +-- + 7 files changed, 67 insertions(+), 34 deletions(-) -diff --git a/block/blk-mq.c b/block/blk-mq.c -index eac444804736..5a572127c7af 100644 --- a/block/blk-mq.c +++ b/block/blk-mq.c -@@ -2863,10 +2863,9 @@ static bool blk_mq_poll_hybrid_sleep(struct request_queue *q, +@@ -3116,10 +3116,9 @@ static bool blk_mq_poll_hybrid_sleep(str kt = nsecs; mode = HRTIMER_MODE_REL; @@ -32,13 +36,28 @@ index eac444804736..5a572127c7af 100644 - hrtimer_init_sleeper(&hs, current); do { - if (test_bit(REQ_ATOM_COMPLETE, &rq->atomic_flags)) + if (blk_mq_rq_state(rq) == MQ_RQ_COMPLETE) break; -diff --git a/include/linux/hrtimer.h b/include/linux/hrtimer.h -index c7902ca7c9f4..1f2002260208 100644 +--- a/drivers/staging/android/vsoc.c ++++ b/drivers/staging/android/vsoc.c +@@ -437,12 +437,10 @@ static int handle_vsoc_cond_wait(struct + return -EINVAL; + wake_time = ktime_set(arg->wake_time_sec, arg->wake_time_nsec); + +- hrtimer_init_on_stack(&to->timer, CLOCK_MONOTONIC, +- HRTIMER_MODE_ABS); ++ hrtimer_init_sleeper_on_stack(to, CLOCK_MONOTONIC, ++ HRTIMER_MODE_ABS, current); + hrtimer_set_expires_range_ns(&to->timer, wake_time, + current->timer_slack_ns); +- +- hrtimer_init_sleeper(to, current); + } + + while (1) { --- a/include/linux/hrtimer.h +++ b/include/linux/hrtimer.h -@@ -364,10 +364,17 @@ DECLARE_PER_CPU(struct tick_device, tick_cpu_device); +@@ -364,10 +364,17 @@ DECLARE_PER_CPU(struct tick_device, tick /* Initialize timers: */ extern void hrtimer_init(struct hrtimer *timer, clockid_t which_clock, enum hrtimer_mode mode); @@ -56,7 +75,7 @@ index c7902ca7c9f4..1f2002260208 100644 extern void destroy_hrtimer_on_stack(struct hrtimer *timer); #else -@@ -377,6 +384,15 @@ static inline void hrtimer_init_on_stack(struct hrtimer *timer, +@@ -377,6 +384,15 @@ static inline void hrtimer_init_on_stack { hrtimer_init(timer, which_clock, mode); } @@ -72,7 +91,7 @@ index c7902ca7c9f4..1f2002260208 100644 static inline void destroy_hrtimer_on_stack(struct hrtimer *timer) { } #endif -@@ -479,9 +495,6 @@ extern long hrtimer_nanosleep(const struct timespec64 *rqtp, +@@ -480,9 +496,6 @@ extern long hrtimer_nanosleep(const stru const enum hrtimer_mode mode, const clockid_t clockid); @@ -82,11 +101,9 @@ index c7902ca7c9f4..1f2002260208 100644 extern int schedule_hrtimeout_range(ktime_t *expires, u64 delta, const enum hrtimer_mode mode); extern int schedule_hrtimeout_range_clock(ktime_t *expires, -diff --git a/include/linux/wait.h b/include/linux/wait.h -index 49543ae3dc5f..3451706a3074 100644 --- a/include/linux/wait.h +++ b/include/linux/wait.h -@@ -487,8 +487,8 @@ do { \ +@@ -489,8 +489,8 @@ do { \ int __ret = 0; \ struct hrtimer_sleeper __t; \ \ @@ -97,11 +114,9 @@ index 49543ae3dc5f..3451706a3074 100644 if ((timeout) != KTIME_MAX) \ hrtimer_start_range_ns(&__t.timer, timeout, \ current->timer_slack_ns, \ -diff --git a/kernel/futex.c b/kernel/futex.c -index e70b5b516371..1d87da84b2a2 100644 --- a/kernel/futex.c +++ b/kernel/futex.c -@@ -2642,10 +2642,9 @@ static int futex_wait(u32 __user *uaddr, unsigned int flags, u32 val, +@@ -2681,10 +2681,9 @@ static int futex_wait(u32 __user *uaddr, if (abs_time) { to = &timeout; @@ -115,7 +130,7 @@ index e70b5b516371..1d87da84b2a2 100644 hrtimer_set_expires_range_ns(&to->timer, *abs_time, current->timer_slack_ns); } -@@ -2744,9 +2743,8 @@ static int futex_lock_pi(u32 __user *uaddr, unsigned int flags, +@@ -2783,9 +2782,8 @@ static int futex_lock_pi(u32 __user *uad if (time) { to = &timeout; @@ -127,7 +142,7 @@ index e70b5b516371..1d87da84b2a2 100644 hrtimer_set_expires(&to->timer, *time); } -@@ -3162,10 +3160,9 @@ static int futex_wait_requeue_pi(u32 __user *uaddr, unsigned int flags, +@@ -3209,10 +3207,9 @@ static int futex_wait_requeue_pi(u32 __u if (abs_time) { to = &timeout; @@ -141,11 +156,9 @@ index e70b5b516371..1d87da84b2a2 100644 hrtimer_set_expires_range_ns(&to->timer, *abs_time, current->timer_slack_ns); } -diff --git a/kernel/time/hrtimer.c b/kernel/time/hrtimer.c -index 9947480ad731..c2e8503f20cb 100644 --- a/kernel/time/hrtimer.c +++ b/kernel/time/hrtimer.c -@@ -1603,13 +1603,44 @@ static enum hrtimer_restart hrtimer_wakeup(struct hrtimer *timer) +@@ -1648,13 +1648,44 @@ static enum hrtimer_restart hrtimer_wake return HRTIMER_NORESTART; } @@ -191,7 +204,7 @@ index 9947480ad731..c2e8503f20cb 100644 int nanosleep_copyout(struct restart_block *restart, struct timespec64 *ts) { switch(restart->nanosleep.type) { -@@ -1633,8 +1664,6 @@ static int __sched do_nanosleep(struct hrtimer_sleeper *t, enum hrtimer_mode mod +@@ -1678,8 +1709,6 @@ static int __sched do_nanosleep(struct h { struct restart_block *restart; @@ -200,7 +213,7 @@ index 9947480ad731..c2e8503f20cb 100644 do { set_current_state(TASK_INTERRUPTIBLE); hrtimer_start_expires(&t->timer, mode); -@@ -1671,10 +1700,9 @@ static long __sched hrtimer_nanosleep_restart(struct restart_block *restart) +@@ -1716,10 +1745,9 @@ static long __sched hrtimer_nanosleep_re struct hrtimer_sleeper t; int ret; @@ -213,7 +226,7 @@ index 9947480ad731..c2e8503f20cb 100644 ret = do_nanosleep(&t, HRTIMER_MODE_ABS); destroy_hrtimer_on_stack(&t.timer); return ret; -@@ -1692,7 +1720,7 @@ long hrtimer_nanosleep(const struct timespec64 *rqtp, +@@ -1737,7 +1765,7 @@ long hrtimer_nanosleep(const struct time if (dl_task(current) || rt_task(current)) slack = 0; @@ -222,7 +235,7 @@ index 9947480ad731..c2e8503f20cb 100644 hrtimer_set_expires_range_ns(&t.timer, timespec64_to_ktime(*rqtp), slack); ret = do_nanosleep(&t, mode); if (ret != -ERESTART_RESTARTBLOCK) -@@ -1887,11 +1915,9 @@ schedule_hrtimeout_range_clock(ktime_t *expires, u64 delta, +@@ -1936,11 +1964,9 @@ schedule_hrtimeout_range_clock(ktime_t * return -EINTR; } @@ -235,11 +248,9 @@ index 9947480ad731..c2e8503f20cb 100644 hrtimer_start_expires(&t.timer, mode); if (likely(t.task)) -diff --git a/net/core/pktgen.c b/net/core/pktgen.c -index 6e1e10ff433a..c1ae4075e0ed 100644 --- a/net/core/pktgen.c +++ b/net/core/pktgen.c -@@ -2252,7 +2252,8 @@ static void spin(struct pktgen_dev *pkt_dev, ktime_t spin_until) +@@ -2160,7 +2160,8 @@ static void spin(struct pktgen_dev *pkt_ s64 remaining; struct hrtimer_sleeper t; @@ -249,7 +260,7 @@ index 6e1e10ff433a..c1ae4075e0ed 100644 hrtimer_set_expires(&t.timer, spin_until); remaining = ktime_to_ns(hrtimer_expires_remaining(&t.timer)); -@@ -2267,7 +2268,6 @@ static void spin(struct pktgen_dev *pkt_dev, ktime_t spin_until) +@@ -2175,7 +2176,6 @@ static void spin(struct pktgen_dev *pkt_ } while (ktime_compare(end_time, spin_until) < 0); } else { /* see do_nanosleep */ @@ -257,6 +268,3 @@ index 6e1e10ff433a..c1ae4075e0ed 100644 do { set_current_state(TASK_INTERRUPTIBLE); hrtimer_start_expires(&t.timer, HRTIMER_MODE_ABS); --- -2.19.2 - diff --git a/kernel/patches-4.14.x-rt/0200-hrtimers-Prepare-full-preemption.patch b/kernel/patches-4.19.x-rt/0102-hrtimers-prepare-full-preemption.patch similarity index 61% rename from kernel/patches-4.14.x-rt/0200-hrtimers-Prepare-full-preemption.patch rename to kernel/patches-4.19.x-rt/0102-hrtimers-prepare-full-preemption.patch index caf4cdde0..7bf4bd295 100644 --- a/kernel/patches-4.14.x-rt/0200-hrtimers-Prepare-full-preemption.patch +++ b/kernel/patches-4.19.x-rt/0102-hrtimers-prepare-full-preemption.patch @@ -1,22 +1,37 @@ -From 68221ff1a692859d71eca4c47c58f47fd4034f38 Mon Sep 17 00:00:00 2001 From: Ingo Molnar Date: Fri, 3 Jul 2009 08:29:34 -0500 -Subject: [PATCH 200/450] hrtimers: Prepare full preemption +Subject: hrtimers: Prepare full preemption Make cancellation of a running callback in softirq context safe against preemption. Signed-off-by: Ingo Molnar Signed-off-by: Thomas Gleixner ---- - include/linux/hrtimer.h | 13 ++++++++++++- - kernel/time/hrtimer.c | 33 ++++++++++++++++++++++++++++++++- - kernel/time/itimer.c | 1 + - kernel/time/posix-timers.c | 33 +++++++++++++++++++++++++++++++++ - 4 files changed, 78 insertions(+), 2 deletions(-) -diff --git a/include/linux/hrtimer.h b/include/linux/hrtimer.h -index 1f2002260208..3de1b8cf4d2a 100644 +--- + fs/timerfd.c | 5 ++++- + include/linux/hrtimer.h | 13 ++++++++++++- + include/linux/posix-timers.h | 2 +- + kernel/time/alarmtimer.c | 2 +- + kernel/time/hrtimer.c | 33 ++++++++++++++++++++++++++++++++- + kernel/time/itimer.c | 1 + + kernel/time/posix-timers.c | 39 +++++++++++++++++++++++++++++++++++++-- + 7 files changed, 88 insertions(+), 7 deletions(-) + +--- a/fs/timerfd.c ++++ b/fs/timerfd.c +@@ -471,7 +471,10 @@ static int do_timerfd_settime(int ufd, i + break; + } + spin_unlock_irq(&ctx->wqh.lock); +- cpu_relax(); ++ if (isalarm(ctx)) ++ hrtimer_wait_for_timer(&ctx->t.alarm.timer); ++ else ++ hrtimer_wait_for_timer(&ctx->t.tmr); + } + + /* --- a/include/linux/hrtimer.h +++ b/include/linux/hrtimer.h @@ -22,6 +22,7 @@ @@ -37,7 +52,7 @@ index 1f2002260208..3de1b8cf4d2a 100644 struct hrtimer *softirq_next_timer; struct hrtimer_clock_base clock_base[HRTIMER_MAX_CLOCK_BASES]; } ____cacheline_aligned; -@@ -433,6 +437,13 @@ static inline void hrtimer_restart(struct hrtimer *timer) +@@ -433,6 +437,13 @@ static inline void hrtimer_restart(struc hrtimer_start_expires(timer, HRTIMER_MODE_ABS); } @@ -51,7 +66,7 @@ index 1f2002260208..3de1b8cf4d2a 100644 /* Query timers: */ extern ktime_t __hrtimer_get_remaining(const struct hrtimer *timer, bool adjust); -@@ -457,7 +468,7 @@ static inline int hrtimer_is_queued(struct hrtimer *timer) +@@ -458,7 +469,7 @@ static inline int hrtimer_is_queued(stru * Helper function to check, whether the timer is running the callback * function */ @@ -60,11 +75,32 @@ index 1f2002260208..3de1b8cf4d2a 100644 { return timer->base->running == timer; } -diff --git a/kernel/time/hrtimer.c b/kernel/time/hrtimer.c -index c2e8503f20cb..8c3c0dff5184 100644 +--- a/include/linux/posix-timers.h ++++ b/include/linux/posix-timers.h +@@ -114,8 +114,8 @@ struct k_itimer { + struct { + struct alarm alarmtimer; + } alarm; +- struct rcu_head rcu; + } it; ++ struct rcu_head rcu; + }; + + void run_posix_cpu_timers(struct task_struct *task); +--- a/kernel/time/alarmtimer.c ++++ b/kernel/time/alarmtimer.c +@@ -436,7 +436,7 @@ int alarm_cancel(struct alarm *alarm) + int ret = alarm_try_to_cancel(alarm); + if (ret >= 0) + return ret; +- cpu_relax(); ++ hrtimer_wait_for_timer(&alarm->timer); + } + } + EXPORT_SYMBOL_GPL(alarm_cancel); --- a/kernel/time/hrtimer.c +++ b/kernel/time/hrtimer.c -@@ -926,6 +926,33 @@ u64 hrtimer_forward(struct hrtimer *timer, ktime_t now, ktime_t interval) +@@ -939,6 +939,33 @@ u64 hrtimer_forward(struct hrtimer *time } EXPORT_SYMBOL_GPL(hrtimer_forward); @@ -98,7 +134,7 @@ index c2e8503f20cb..8c3c0dff5184 100644 /* * enqueue_hrtimer - internal function to (re)start a timer * -@@ -1158,7 +1185,7 @@ int hrtimer_cancel(struct hrtimer *timer) +@@ -1171,7 +1198,7 @@ int hrtimer_cancel(struct hrtimer *timer if (ret >= 0) return ret; @@ -107,7 +143,7 @@ index c2e8503f20cb..8c3c0dff5184 100644 } } EXPORT_SYMBOL_GPL(hrtimer_cancel); -@@ -1431,6 +1458,7 @@ static __latent_entropy void hrtimer_run_softirq(struct softirq_action *h) +@@ -1477,6 +1504,7 @@ static __latent_entropy void hrtimer_run hrtimer_update_softirq_timer(cpu_base, true); raw_spin_unlock_irqrestore(&cpu_base->lock, flags); @@ -115,7 +151,7 @@ index c2e8503f20cb..8c3c0dff5184 100644 } #ifdef CONFIG_HIGH_RES_TIMERS -@@ -1797,6 +1825,9 @@ int hrtimers_prepare_cpu(unsigned int cpu) +@@ -1846,6 +1874,9 @@ int hrtimers_prepare_cpu(unsigned int cp cpu_base->softirq_next_timer = NULL; cpu_base->expires_next = KTIME_MAX; cpu_base->softirq_expires_next = KTIME_MAX; @@ -125,11 +161,9 @@ index c2e8503f20cb..8c3c0dff5184 100644 return 0; } -diff --git a/kernel/time/itimer.c b/kernel/time/itimer.c -index f26acef5d7b4..760f38528365 100644 --- a/kernel/time/itimer.c +++ b/kernel/time/itimer.c -@@ -214,6 +214,7 @@ int do_setitimer(int which, struct itimerval *value, struct itimerval *ovalue) +@@ -215,6 +215,7 @@ int do_setitimer(int which, struct itime /* We are sharing ->siglock with it_real_fn() */ if (hrtimer_try_to_cancel(timer) < 0) { spin_unlock_irq(&tsk->sighand->siglock); @@ -137,12 +171,28 @@ index f26acef5d7b4..760f38528365 100644 goto again; } expires = timeval_to_ktime(value->it_value); -diff --git a/kernel/time/posix-timers.c b/kernel/time/posix-timers.c -index dff86a0157db..27186326723f 100644 --- a/kernel/time/posix-timers.c +++ b/kernel/time/posix-timers.c -@@ -806,6 +806,20 @@ SYSCALL_DEFINE1(timer_getoverrun, timer_t, timer_id) - return overrun; +@@ -463,7 +463,7 @@ static struct k_itimer * alloc_posix_tim + + static void k_itimer_rcu_free(struct rcu_head *head) + { +- struct k_itimer *tmr = container_of(head, struct k_itimer, it.rcu); ++ struct k_itimer *tmr = container_of(head, struct k_itimer, rcu); + + kmem_cache_free(posix_timers_cache, tmr); + } +@@ -480,7 +480,7 @@ static void release_posix_timer(struct k + } + put_pid(tmr->it_pid); + sigqueue_free(tmr->sigq); +- call_rcu(&tmr->it.rcu, k_itimer_rcu_free); ++ call_rcu(&tmr->rcu, k_itimer_rcu_free); + } + + static int common_timer_create(struct k_itimer *new_timer) +@@ -821,6 +821,22 @@ static void common_hrtimer_arm(struct k_ + hrtimer_start_expires(timer, HRTIMER_MODE_ABS); } +/* @@ -151,18 +201,20 @@ index dff86a0157db..27186326723f 100644 +static void timer_wait_for_callback(const struct k_clock *kc, struct k_itimer *timr) +{ +#ifdef CONFIG_PREEMPT_RT_FULL -+ if (kc->timer_set == common_timer_set) ++ if (kc->timer_arm == common_hrtimer_arm) + hrtimer_wait_for_timer(&timr->it.real.timer); ++ else if (kc == &alarm_clock) ++ hrtimer_wait_for_timer(&timr->it.alarm.alarmtimer.timer); + else + /* FIXME: Whacky hack for posix-cpu-timers */ + schedule_timeout(1); +#endif +} + - static void common_hrtimer_arm(struct k_itimer *timr, ktime_t expires, - bool absolute, bool sigev_none) + static int common_hrtimer_try_to_cancel(struct k_itimer *timr) { -@@ -900,6 +914,7 @@ static int do_timer_settime(timer_t timer_id, int flags, + return hrtimer_try_to_cancel(&timr->it.real.timer); +@@ -885,6 +901,7 @@ static int do_timer_settime(timer_t time if (!timr) return -EINVAL; @@ -170,7 +222,7 @@ index dff86a0157db..27186326723f 100644 kc = timr->kclock; if (WARN_ON_ONCE(!kc || !kc->timer_set)) error = -EINVAL; -@@ -908,9 +923,12 @@ static int do_timer_settime(timer_t timer_id, int flags, +@@ -893,9 +910,12 @@ static int do_timer_settime(timer_t time unlock_timer(timr, flag); if (error == TIMER_RETRY) { @@ -183,7 +235,7 @@ index dff86a0157db..27186326723f 100644 return error; } -@@ -992,10 +1010,15 @@ SYSCALL_DEFINE1(timer_delete, timer_t, timer_id) +@@ -977,10 +997,15 @@ SYSCALL_DEFINE1(timer_delete, timer_t, t if (!timer) return -EINVAL; @@ -199,7 +251,7 @@ index dff86a0157db..27186326723f 100644 spin_lock(¤t->sighand->siglock); list_del(&timer->list); -@@ -1021,8 +1044,18 @@ static void itimer_delete(struct k_itimer *timer) +@@ -1006,8 +1031,18 @@ static void itimer_delete(struct k_itime retry_delete: spin_lock_irqsave(&timer->it_lock, flags); @@ -218,6 +270,3 @@ index dff86a0157db..27186326723f 100644 goto retry_delete; } list_del(&timer->list); --- -2.19.2 - diff --git a/kernel/patches-4.14.x-rt/0201-hrtimer-by-timers-by-default-into-the-softirq-contex.patch b/kernel/patches-4.19.x-rt/0103-hrtimer-by-timers-by-default-into-the-softirq-context.patch similarity index 64% rename from kernel/patches-4.14.x-rt/0201-hrtimer-by-timers-by-default-into-the-softirq-contex.patch rename to kernel/patches-4.19.x-rt/0103-hrtimer-by-timers-by-default-into-the-softirq-context.patch index 05daf08ad..93167770f 100644 --- a/kernel/patches-4.14.x-rt/0201-hrtimer-by-timers-by-default-into-the-softirq-contex.patch +++ b/kernel/patches-4.19.x-rt/0103-hrtimer-by-timers-by-default-into-the-softirq-context.patch @@ -1,8 +1,6 @@ -From 750cdd1103515b61fe606f2df482df386ba0ebb1 Mon Sep 17 00:00:00 2001 From: Sebastian Andrzej Siewior Date: Fri, 3 Jul 2009 08:44:31 -0500 -Subject: [PATCH 201/450] hrtimer: by timers by default into the softirq - context +Subject: hrtimer: by timers by default into the softirq context We can't have hrtimers callbacks running in hardirq context on RT. Therefore the timers are deferred to the softirq context by default. @@ -14,23 +12,22 @@ Those are: Signed-off-by: Sebastian Andrzej Siewior --- - arch/x86/kvm/lapic.c | 2 +- - include/linux/hrtimer.h | 6 +++++ - kernel/events/core.c | 4 ++-- - kernel/sched/core.c | 2 +- - kernel/sched/deadline.c | 2 +- - kernel/sched/rt.c | 4 ++-- - kernel/time/hrtimer.c | 34 ++++++++++++++++++++++++++-- - kernel/time/tick-broadcast-hrtimer.c | 2 +- - kernel/time/tick-sched.c | 2 +- - kernel/watchdog.c | 2 +- - 10 files changed, 48 insertions(+), 12 deletions(-) + arch/x86/kvm/lapic.c | 2 +- + include/linux/hrtimer.h | 6 ++++++ + kernel/events/core.c | 4 ++-- + kernel/sched/core.c | 2 +- + kernel/sched/deadline.c | 2 +- + kernel/sched/fair.c | 4 ++-- + kernel/sched/rt.c | 4 ++-- + kernel/time/hrtimer.c | 21 +++++++++++++++++++-- + kernel/time/tick-broadcast-hrtimer.c | 2 +- + kernel/time/tick-sched.c | 2 +- + kernel/watchdog.c | 2 +- + 11 files changed, 37 insertions(+), 14 deletions(-) -diff --git a/arch/x86/kvm/lapic.c b/arch/x86/kvm/lapic.c -index 13dfb55b84db..dd66f629d1d0 100644 --- a/arch/x86/kvm/lapic.c +++ b/arch/x86/kvm/lapic.c -@@ -2136,7 +2136,7 @@ int kvm_create_lapic(struct kvm_vcpu *vcpu) +@@ -2250,7 +2250,7 @@ int kvm_create_lapic(struct kvm_vcpu *vc apic->vcpu = vcpu; hrtimer_init(&apic->lapic_timer.timer, CLOCK_MONOTONIC, @@ -39,8 +36,6 @@ index 13dfb55b84db..dd66f629d1d0 100644 apic->lapic_timer.timer.function = apic_timer_fn; /* -diff --git a/include/linux/hrtimer.h b/include/linux/hrtimer.h -index 3de1b8cf4d2a..3bd606859b0a 100644 --- a/include/linux/hrtimer.h +++ b/include/linux/hrtimer.h @@ -42,6 +42,7 @@ enum hrtimer_mode { @@ -63,11 +58,9 @@ index 3de1b8cf4d2a..3bd606859b0a 100644 }; /* -diff --git a/kernel/events/core.c b/kernel/events/core.c -index 991af683ef9e..add11dbf28e9 100644 --- a/kernel/events/core.c +++ b/kernel/events/core.c -@@ -1065,7 +1065,7 @@ static void __perf_mux_hrtimer_init(struct perf_cpu_context *cpuctx, int cpu) +@@ -1102,7 +1102,7 @@ static void __perf_mux_hrtimer_init(stru cpuctx->hrtimer_interval = ns_to_ktime(NSEC_PER_MSEC * interval); raw_spin_lock_init(&cpuctx->hrtimer_lock); @@ -76,7 +69,7 @@ index 991af683ef9e..add11dbf28e9 100644 timer->function = perf_mux_hrtimer_handler; } -@@ -8762,7 +8762,7 @@ static void perf_swevent_init_hrtimer(struct perf_event *event) +@@ -9181,7 +9181,7 @@ static void perf_swevent_init_hrtimer(st if (!is_sampling_event(event)) return; @@ -85,11 +78,9 @@ index 991af683ef9e..add11dbf28e9 100644 hwc->hrtimer.function = perf_swevent_hrtimer; /* -diff --git a/kernel/sched/core.c b/kernel/sched/core.c -index 694bdd953270..9526621d97e3 100644 --- a/kernel/sched/core.c +++ b/kernel/sched/core.c -@@ -341,7 +341,7 @@ static void init_rq_hrtick(struct rq *rq) +@@ -314,7 +314,7 @@ static void hrtick_rq_init(struct rq *rq rq->hrtick_csd.info = rq; #endif @@ -98,11 +89,9 @@ index 694bdd953270..9526621d97e3 100644 rq->hrtick_timer.function = hrtick; } #else /* CONFIG_SCHED_HRTICK */ -diff --git a/kernel/sched/deadline.c b/kernel/sched/deadline.c -index 7be1f4421cb8..28a75a9526ac 100644 --- a/kernel/sched/deadline.c +++ b/kernel/sched/deadline.c -@@ -1020,7 +1020,7 @@ void init_dl_task_timer(struct sched_dl_entity *dl_se) +@@ -1054,7 +1054,7 @@ void init_dl_task_timer(struct sched_dl_ { struct hrtimer *timer = &dl_se->dl_timer; @@ -111,11 +100,23 @@ index 7be1f4421cb8..28a75a9526ac 100644 timer->function = dl_task_timer; } -diff --git a/kernel/sched/rt.c b/kernel/sched/rt.c -index fbe1aa2bb948..6c72332dab3f 100644 +--- a/kernel/sched/fair.c ++++ b/kernel/sched/fair.c +@@ -4879,9 +4879,9 @@ void init_cfs_bandwidth(struct cfs_bandw + cfs_b->period = ns_to_ktime(default_cfs_period()); + + INIT_LIST_HEAD(&cfs_b->throttled_cfs_rq); +- hrtimer_init(&cfs_b->period_timer, CLOCK_MONOTONIC, HRTIMER_MODE_ABS_PINNED); ++ hrtimer_init(&cfs_b->period_timer, CLOCK_MONOTONIC, HRTIMER_MODE_ABS_PINNED_HARD); + cfs_b->period_timer.function = sched_cfs_period_timer; +- hrtimer_init(&cfs_b->slack_timer, CLOCK_MONOTONIC, HRTIMER_MODE_REL); ++ hrtimer_init(&cfs_b->slack_timer, CLOCK_MONOTONIC, HRTIMER_MODE_REL_HARD); + cfs_b->slack_timer.function = sched_cfs_slack_timer; + cfs_b->distribute_running = 0; + } --- a/kernel/sched/rt.c +++ b/kernel/sched/rt.c -@@ -47,8 +47,8 @@ void init_rt_bandwidth(struct rt_bandwidth *rt_b, u64 period, u64 runtime) +@@ -45,8 +45,8 @@ void init_rt_bandwidth(struct rt_bandwid raw_spin_lock_init(&rt_b->rt_runtime_lock); @@ -126,11 +127,9 @@ index fbe1aa2bb948..6c72332dab3f 100644 rt_b->rt_period_timer.function = sched_rt_period_timer; } -diff --git a/kernel/time/hrtimer.c b/kernel/time/hrtimer.c -index 8c3c0dff5184..ec9f271aa437 100644 --- a/kernel/time/hrtimer.c +++ b/kernel/time/hrtimer.c -@@ -1122,7 +1122,9 @@ void hrtimer_start_range_ns(struct hrtimer *timer, ktime_t tim, +@@ -1135,7 +1135,9 @@ void hrtimer_start_range_ns(struct hrtim * Check whether the HRTIMER_MODE_SOFT bit and hrtimer.is_soft * match. */ @@ -140,7 +139,7 @@ index 8c3c0dff5184..ec9f271aa437 100644 base = lock_hrtimer_base(timer, &flags); -@@ -1249,10 +1251,17 @@ static inline int hrtimer_clockid_to_base(clockid_t clock_id) +@@ -1295,10 +1297,17 @@ static inline int hrtimer_clockid_to_bas static void __hrtimer_init(struct hrtimer *timer, clockid_t clock_id, enum hrtimer_mode mode) { @@ -160,25 +159,7 @@ index 8c3c0dff5184..ec9f271aa437 100644 memset(timer, 0, sizeof(struct hrtimer)); cpu_base = raw_cpu_ptr(&hrtimer_bases); -@@ -1631,11 +1640,32 @@ static enum hrtimer_restart hrtimer_wakeup(struct hrtimer *timer) - return HRTIMER_NORESTART; - } - -+#ifdef CONFIG_PREEMPT_RT_FULL -+static bool task_is_realtime(struct task_struct *tsk) -+{ -+ int policy = tsk->policy; -+ -+ if (policy == SCHED_FIFO || policy == SCHED_RR) -+ return true; -+ if (policy == SCHED_DEADLINE) -+ return true; -+ return false; -+} -+#endif -+ - static void __hrtimer_init_sleeper(struct hrtimer_sleeper *sl, - clockid_t clock_id, +@@ -1681,6 +1690,14 @@ static void __hrtimer_init_sleeper(struc enum hrtimer_mode mode, struct task_struct *task) { @@ -193,11 +174,9 @@ index 8c3c0dff5184..ec9f271aa437 100644 __hrtimer_init(&sl->timer, clock_id, mode); sl->timer.function = hrtimer_wakeup; sl->task = task; -diff --git a/kernel/time/tick-broadcast-hrtimer.c b/kernel/time/tick-broadcast-hrtimer.c -index 58045eb976c3..f0a34afbc252 100644 --- a/kernel/time/tick-broadcast-hrtimer.c +++ b/kernel/time/tick-broadcast-hrtimer.c -@@ -106,7 +106,7 @@ static enum hrtimer_restart bc_handler(struct hrtimer *t) +@@ -106,7 +106,7 @@ static enum hrtimer_restart bc_handler(s void tick_setup_hrtimer_broadcast(void) { @@ -206,11 +185,9 @@ index 58045eb976c3..f0a34afbc252 100644 bctimer.function = bc_handler; clockevents_register_device(&ce_broadcast_hrtimer); } -diff --git a/kernel/time/tick-sched.c b/kernel/time/tick-sched.c -index 296b623ba045..c21fd6a16870 100644 --- a/kernel/time/tick-sched.c +++ b/kernel/time/tick-sched.c -@@ -1255,7 +1255,7 @@ void tick_setup_sched_timer(void) +@@ -1310,7 +1310,7 @@ void tick_setup_sched_timer(void) /* * Emulate tick processing via per-CPU hrtimers: */ @@ -219,11 +196,9 @@ index 296b623ba045..c21fd6a16870 100644 ts->sched_timer.function = tick_sched_timer; /* Get the next period (per-CPU) */ -diff --git a/kernel/watchdog.c b/kernel/watchdog.c -index 087994b23f8b..ea4c09109ce4 100644 --- a/kernel/watchdog.c +++ b/kernel/watchdog.c -@@ -462,7 +462,7 @@ static void watchdog_enable(unsigned int cpu) +@@ -483,7 +483,7 @@ static void watchdog_enable(unsigned int * Start the timer first to prevent the NMI watchdog triggering * before the timer has a chance to fire. */ @@ -232,6 +207,3 @@ index 087994b23f8b..ea4c09109ce4 100644 hrtimer->function = watchdog_timer_fn; hrtimer_start(hrtimer, ns_to_ktime(sample_period), HRTIMER_MODE_REL_PINNED); --- -2.19.2 - diff --git a/kernel/patches-4.19.x-rt/0104-sched-fair-Make-the-hrtimers-non-hard-again.patch b/kernel/patches-4.19.x-rt/0104-sched-fair-Make-the-hrtimers-non-hard-again.patch new file mode 100644 index 000000000..c63feecab --- /dev/null +++ b/kernel/patches-4.19.x-rt/0104-sched-fair-Make-the-hrtimers-non-hard-again.patch @@ -0,0 +1,27 @@ +From: Sebastian Andrzej Siewior +Date: Tue, 8 Jan 2019 12:31:06 +0100 +Subject: [PATCH] sched/fair: Make the hrtimers non-hard again + +Since commit "sched/fair: Robustify CFS-bandwidth timer locking" both +hrtimer can run in softirq context because now interrupts are disabled +as part of the locking procedure. + +Signed-off-by: Sebastian Andrzej Siewior +--- + kernel/sched/fair.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +--- a/kernel/sched/fair.c ++++ b/kernel/sched/fair.c +@@ -4879,9 +4879,9 @@ void init_cfs_bandwidth(struct cfs_bandw + cfs_b->period = ns_to_ktime(default_cfs_period()); + + INIT_LIST_HEAD(&cfs_b->throttled_cfs_rq); +- hrtimer_init(&cfs_b->period_timer, CLOCK_MONOTONIC, HRTIMER_MODE_ABS_PINNED_HARD); ++ hrtimer_init(&cfs_b->period_timer, CLOCK_MONOTONIC, HRTIMER_MODE_ABS_PINNED); + cfs_b->period_timer.function = sched_cfs_period_timer; +- hrtimer_init(&cfs_b->slack_timer, CLOCK_MONOTONIC, HRTIMER_MODE_REL_HARD); ++ hrtimer_init(&cfs_b->slack_timer, CLOCK_MONOTONIC, HRTIMER_MODE_REL); + cfs_b->slack_timer.function = sched_cfs_slack_timer; + cfs_b->distribute_running = 0; + } diff --git a/kernel/patches-4.14.x-rt/0205-hrtimer-Move-schedule_work-call-to-helper-thread.patch b/kernel/patches-4.19.x-rt/0105-hrtimer-Move-schedule_work-call-to-helper-thread.patch similarity index 87% rename from kernel/patches-4.14.x-rt/0205-hrtimer-Move-schedule_work-call-to-helper-thread.patch rename to kernel/patches-4.19.x-rt/0105-hrtimer-Move-schedule_work-call-to-helper-thread.patch index cc9191474..029d45a5c 100644 --- a/kernel/patches-4.14.x-rt/0205-hrtimer-Move-schedule_work-call-to-helper-thread.patch +++ b/kernel/patches-4.19.x-rt/0105-hrtimer-Move-schedule_work-call-to-helper-thread.patch @@ -1,7 +1,6 @@ -From 568b9c5ae7869762a8542d01cc003747610ac928 Mon Sep 17 00:00:00 2001 From: Yang Shi Date: Mon, 16 Sep 2013 14:09:19 -0700 -Subject: [PATCH 205/450] hrtimer: Move schedule_work call to helper thread +Subject: hrtimer: Move schedule_work call to helper thread When run ltp leapsec_timer test, the following call trace is caught: @@ -47,14 +46,12 @@ Signed-off-by: Yang Shi [bigeasy: use swork_queue() instead a helper thread] Signed-off-by: Sebastian Andrzej Siewior --- - kernel/time/hrtimer.c | 24 ++++++++++++++++++++++++ + kernel/time/hrtimer.c | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) -diff --git a/kernel/time/hrtimer.c b/kernel/time/hrtimer.c -index ec9f271aa437..f824b9721ce7 100644 --- a/kernel/time/hrtimer.c +++ b/kernel/time/hrtimer.c -@@ -715,6 +715,29 @@ static void hrtimer_switch_to_hres(void) +@@ -730,6 +730,29 @@ static void hrtimer_switch_to_hres(void) retrigger_next_event(NULL); } @@ -84,7 +81,7 @@ index ec9f271aa437..f824b9721ce7 100644 static void clock_was_set_work(struct work_struct *work) { clock_was_set(); -@@ -730,6 +753,7 @@ void clock_was_set_delayed(void) +@@ -745,6 +768,7 @@ void clock_was_set_delayed(void) { schedule_work(&hrtimer_work); } @@ -92,6 +89,3 @@ index ec9f271aa437..f824b9721ce7 100644 #else --- -2.19.2 - diff --git a/kernel/patches-4.14.x-rt/0445-hrtimer-move-state-change-before-hrtimer_cancel-in-d.patch b/kernel/patches-4.19.x-rt/0106-hrtimer-move-state-change-before-hrtimer_cancel-in-d.patch similarity index 74% rename from kernel/patches-4.14.x-rt/0445-hrtimer-move-state-change-before-hrtimer_cancel-in-d.patch rename to kernel/patches-4.19.x-rt/0106-hrtimer-move-state-change-before-hrtimer_cancel-in-d.patch index 853283557..dbfcc1623 100644 --- a/kernel/patches-4.14.x-rt/0445-hrtimer-move-state-change-before-hrtimer_cancel-in-d.patch +++ b/kernel/patches-4.19.x-rt/0106-hrtimer-move-state-change-before-hrtimer_cancel-in-d.patch @@ -1,11 +1,8 @@ -From 3a0236430f31c068a0c17410f46fa85acd57b85a Mon Sep 17 00:00:00 2001 From: Sebastian Andrzej Siewior Date: Thu, 6 Dec 2018 10:15:13 +0100 -Subject: [PATCH 445/450] hrtimer: move state change before hrtimer_cancel in +Subject: [PATCH] hrtimer: move state change before hrtimer_cancel in do_nanosleep() -[ Upstream commit 8115ac730fd5aa27134f002cf710204b5dd7cd5e ] - There is a small window between setting t->task to NULL and waking the task up (which would set TASK_RUNNING). So the timer would fire, run and set ->task to NULL while the other side/do_nanosleep() wouldn't enter @@ -25,16 +22,13 @@ are no complains from might_sleep() about wrong state. Cc: stable-rt@vger.kernel.org Reviewed-by: Daniel Bristot de Oliveira Signed-off-by: Sebastian Andrzej Siewior -Signed-off-by: Steven Rostedt (VMware) --- - kernel/time/hrtimer.c | 2 +- + kernel/time/hrtimer.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) -diff --git a/kernel/time/hrtimer.c b/kernel/time/hrtimer.c -index b59e009087a9..c8d806126381 100644 --- a/kernel/time/hrtimer.c +++ b/kernel/time/hrtimer.c -@@ -1753,12 +1753,12 @@ static int __sched do_nanosleep(struct hrtimer_sleeper *t, enum hrtimer_mode mod +@@ -1785,12 +1785,12 @@ static int __sched do_nanosleep(struct h if (likely(t->task)) freezable_schedule(); @@ -48,6 +42,3 @@ index b59e009087a9..c8d806126381 100644 if (!t->task) return 0; --- -2.19.2 - diff --git a/kernel/patches-4.14.x-rt/0207-posix-timers-Thread-posix-cpu-timers-on-rt.patch b/kernel/patches-4.19.x-rt/0107-posix-timers-thread-posix-cpu-timers-on-rt.patch similarity index 70% rename from kernel/patches-4.14.x-rt/0207-posix-timers-Thread-posix-cpu-timers-on-rt.patch rename to kernel/patches-4.19.x-rt/0107-posix-timers-thread-posix-cpu-timers-on-rt.patch index a4a048a3d..a516023d7 100644 --- a/kernel/patches-4.14.x-rt/0207-posix-timers-Thread-posix-cpu-timers-on-rt.patch +++ b/kernel/patches-4.19.x-rt/0107-posix-timers-thread-posix-cpu-timers-on-rt.patch @@ -1,7 +1,6 @@ -From 4df2f4bb9dd44886b2c0e3687873500886f721fd Mon Sep 17 00:00:00 2001 From: John Stultz Date: Fri, 3 Jul 2009 08:29:58 -0500 -Subject: [PATCH 207/450] posix-timers: Thread posix-cpu-timers on -rt +Subject: posix-timers: Thread posix-cpu-timers on -rt posix-cpu-timer code takes non -rt safe locks in hard irq context. Move it to a thread. @@ -10,43 +9,17 @@ context. Move it to a thread. Signed-off-by: John Stultz Signed-off-by: Thomas Gleixner ---- - include/linux/init_task.h | 7 ++ - include/linux/sched.h | 3 + - kernel/fork.c | 3 + - kernel/time/posix-cpu-timers.c | 157 ++++++++++++++++++++++++++++++++- - 4 files changed, 166 insertions(+), 4 deletions(-) -diff --git a/include/linux/init_task.h b/include/linux/init_task.h -index 53ee20e0b168..ee3ff961b84c 100644 ---- a/include/linux/init_task.h -+++ b/include/linux/init_task.h -@@ -163,6 +163,12 @@ extern struct cred init_cred; - # define INIT_PERF_EVENTS(tsk) - #endif - -+#if defined(CONFIG_POSIX_TIMERS) && defined(CONFIG_PREEMPT_RT_BASE) -+# define INIT_TIMER_LIST .posix_timer_list = NULL, -+#else -+# define INIT_TIMER_LIST -+#endif -+ - #ifdef CONFIG_VIRT_CPU_ACCOUNTING_GEN - # define INIT_VTIME(tsk) \ - .vtime.seqcount = SEQCNT_ZERO(tsk.vtime.seqcount), \ -@@ -277,6 +283,7 @@ extern struct cred init_cred; - INIT_CPU_TIMERS(tsk) \ - .pi_lock = __RAW_SPIN_LOCK_UNLOCKED(tsk.pi_lock), \ - .timer_slack_ns = 50000, /* 50 usec default slack */ \ -+ INIT_TIMER_LIST \ - .pids = { \ - [PIDTYPE_PID] = INIT_PID_LINK(PIDTYPE_PID), \ - [PIDTYPE_PGID] = INIT_PID_LINK(PIDTYPE_PGID), \ -diff --git a/include/linux/sched.h b/include/linux/sched.h -index a7d48ad0fb96..086c1913a441 100644 +--- + include/linux/sched.h | 3 + init/init_task.c | 7 + + kernel/fork.c | 3 + kernel/time/posix-cpu-timers.c | 154 ++++++++++++++++++++++++++++++++++++++++- + 4 files changed, 164 insertions(+), 3 deletions(-) + --- a/include/linux/sched.h +++ b/include/linux/sched.h -@@ -785,6 +785,9 @@ struct task_struct { +@@ -832,6 +832,9 @@ struct task_struct { #ifdef CONFIG_POSIX_TIMERS struct task_cputime cputime_expires; struct list_head cpu_timers[3]; @@ -56,11 +29,32 @@ index a7d48ad0fb96..086c1913a441 100644 #endif /* Process credentials: */ -diff --git a/kernel/fork.c b/kernel/fork.c -index c66167f0bba6..d7f20bdbb465 100644 +--- a/init/init_task.c ++++ b/init/init_task.c +@@ -50,6 +50,12 @@ static struct sighand_struct init_sighan + .signalfd_wqh = __WAIT_QUEUE_HEAD_INITIALIZER(init_sighand.signalfd_wqh), + }; + ++#if defined(CONFIG_POSIX_TIMERS) && defined(CONFIG_PREEMPT_RT_BASE) ++# define INIT_TIMER_LIST .posix_timer_list = NULL, ++#else ++# define INIT_TIMER_LIST ++#endif ++ + /* + * Set up the first task table, touch at your own risk!. Base=0, + * limit=0x1fffff (=2MB) +@@ -119,6 +125,7 @@ struct task_struct init_task + INIT_CPU_TIMERS(init_task) + .pi_lock = __RAW_SPIN_LOCK_UNLOCKED(init_task.pi_lock), + .timer_slack_ns = 50000, /* 50 usec default slack */ ++ INIT_TIMER_LIST + .thread_pid = &init_struct_pid, + .thread_group = LIST_HEAD_INIT(init_task.thread_group), + .thread_node = LIST_HEAD_INIT(init_signals.thread_head), --- a/kernel/fork.c +++ b/kernel/fork.c -@@ -1497,6 +1497,9 @@ static void rt_mutex_init_task(struct task_struct *p) +@@ -1575,6 +1575,9 @@ static void rt_mutex_init_task(struct ta */ static void posix_cpu_timers_init(struct task_struct *tsk) { @@ -70,8 +64,6 @@ index c66167f0bba6..d7f20bdbb465 100644 tsk->cputime_expires.prof_exp = 0; tsk->cputime_expires.virt_exp = 0; tsk->cputime_expires.sched_exp = 0; -diff --git a/kernel/time/posix-cpu-timers.c b/kernel/time/posix-cpu-timers.c -index 2da660d53a4b..c7b7d047d12e 100644 --- a/kernel/time/posix-cpu-timers.c +++ b/kernel/time/posix-cpu-timers.c @@ -3,8 +3,10 @@ @@ -85,33 +77,15 @@ index 2da660d53a4b..c7b7d047d12e 100644 #include #include #include -@@ -14,6 +16,7 @@ - #include +@@ -15,6 +17,7 @@ #include #include + #include +#include #include "posix-timers.h" -@@ -603,7 +606,7 @@ static int posix_cpu_timer_set(struct k_itimer *timer, int timer_flags, - /* - * Disarm any old timer after extracting its expiry time. - */ -- WARN_ON_ONCE(!irqs_disabled()); -+ WARN_ON_ONCE_NONRT(!irqs_disabled()); - - ret = 0; - old_incr = timer->it.cpu.incr; -@@ -1034,7 +1037,7 @@ static void posix_cpu_timer_rearm(struct k_itimer *timer) - /* - * Now re-arm for the new expiry time. - */ -- WARN_ON_ONCE(!irqs_disabled()); -+ WARN_ON_ONCE_NONRT(!irqs_disabled()); - arm_timer(timer); - unlock: - unlock_task_sighand(p, &flags); -@@ -1119,13 +1122,13 @@ static inline int fastpath_timer_check(struct task_struct *tsk) +@@ -1136,14 +1139,12 @@ static inline int fastpath_timer_check(s * already updated our counts. We need to check if any timers fire now. * Interrupts are disabled. */ @@ -122,12 +96,12 @@ index 2da660d53a4b..c7b7d047d12e 100644 struct k_itimer *timer, *next; unsigned long flags; -- WARN_ON_ONCE(!irqs_disabled()); -+ WARN_ON_ONCE_NONRT(!irqs_disabled()); - +- lockdep_assert_irqs_disabled(); +- /* * The fast path checks that there are no expired thread or thread -@@ -1179,6 +1182,152 @@ void run_posix_cpu_timers(struct task_struct *tsk) + * group timers. If that's so, just return. +@@ -1196,6 +1197,153 @@ void run_posix_cpu_timers(struct task_st } } @@ -273,6 +247,7 @@ index 2da660d53a4b..c7b7d047d12e 100644 +#else /* CONFIG_PREEMPT_RT_BASE */ +void run_posix_cpu_timers(struct task_struct *tsk) +{ ++ lockdep_assert_irqs_disabled(); + __run_posix_cpu_timers(tsk); +} +#endif /* CONFIG_PREEMPT_RT_BASE */ @@ -280,6 +255,3 @@ index 2da660d53a4b..c7b7d047d12e 100644 /* * Set one of the process-wide special case CPU timers or RLIMIT_CPU. * The tsk->sighand->siglock must be held by the caller. --- -2.19.2 - diff --git a/kernel/patches-4.14.x-rt/0208-sched-Move-task_struct-cleanup-to-RCU.patch b/kernel/patches-4.19.x-rt/0108-sched-delay-put-task.patch similarity index 69% rename from kernel/patches-4.14.x-rt/0208-sched-Move-task_struct-cleanup-to-RCU.patch rename to kernel/patches-4.19.x-rt/0108-sched-delay-put-task.patch index a9b5cb37a..9dd233ca3 100644 --- a/kernel/patches-4.14.x-rt/0208-sched-Move-task_struct-cleanup-to-RCU.patch +++ b/kernel/patches-4.19.x-rt/0108-sched-delay-put-task.patch @@ -1,23 +1,20 @@ -From 4e0c0cf0c61f3c059b8836923edda1afca0e46e1 Mon Sep 17 00:00:00 2001 +Subject: sched: Move task_struct cleanup to RCU From: Thomas Gleixner Date: Tue, 31 May 2011 16:59:16 +0200 -Subject: [PATCH 208/450] sched: Move task_struct cleanup to RCU __put_task_struct() does quite some expensive work. We don't want to burden random tasks with that. Signed-off-by: Thomas Gleixner --- - include/linux/sched.h | 3 +++ - include/linux/sched/task.h | 11 ++++++++++- - kernel/fork.c | 15 ++++++++++++++- + include/linux/sched.h | 3 +++ + include/linux/sched/task.h | 11 ++++++++++- + kernel/fork.c | 15 ++++++++++++++- 3 files changed, 27 insertions(+), 2 deletions(-) -diff --git a/include/linux/sched.h b/include/linux/sched.h -index 086c1913a441..8281cf6d97cd 100644 --- a/include/linux/sched.h +++ b/include/linux/sched.h -@@ -1133,6 +1133,9 @@ struct task_struct { +@@ -1186,6 +1186,9 @@ struct task_struct { unsigned int sequential_io; unsigned int sequential_io_avg; #endif @@ -27,8 +24,6 @@ index 086c1913a441..8281cf6d97cd 100644 #ifdef CONFIG_DEBUG_ATOMIC_SLEEP unsigned long task_state_change; #endif -diff --git a/include/linux/sched/task.h b/include/linux/sched/task.h -index a74ec619ac51..8e7f741370c5 100644 --- a/include/linux/sched/task.h +++ b/include/linux/sched/task.h @@ -88,6 +88,15 @@ extern void sched_exec(void); @@ -47,7 +42,7 @@ index a74ec619ac51..8e7f741370c5 100644 extern void __put_task_struct(struct task_struct *t); static inline void put_task_struct(struct task_struct *t) -@@ -95,7 +104,7 @@ static inline void put_task_struct(struct task_struct *t) +@@ -95,7 +104,7 @@ static inline void put_task_struct(struc if (atomic_dec_and_test(&t->usage)) __put_task_struct(t); } @@ -56,11 +51,9 @@ index a74ec619ac51..8e7f741370c5 100644 struct task_struct *task_rcu_dereference(struct task_struct **ptask); #ifdef CONFIG_ARCH_WANTS_DYNAMIC_TASK_STRUCT -diff --git a/kernel/fork.c b/kernel/fork.c -index d7f20bdbb465..677d17d7efb5 100644 --- a/kernel/fork.c +++ b/kernel/fork.c -@@ -407,7 +407,9 @@ static inline void put_signal_struct(struct signal_struct *sig) +@@ -671,7 +671,9 @@ static inline void put_signal_struct(str if (atomic_dec_and_test(&sig->sigcnt)) free_signal_struct(sig); } @@ -71,7 +64,7 @@ index d7f20bdbb465..677d17d7efb5 100644 void __put_task_struct(struct task_struct *tsk) { WARN_ON(!tsk->exit_state); -@@ -424,7 +426,18 @@ void __put_task_struct(struct task_struct *tsk) +@@ -688,7 +690,18 @@ void __put_task_struct(struct task_struc if (!profile_handoff_task(tsk)) free_task(tsk); } @@ -90,6 +83,3 @@ index d7f20bdbb465..677d17d7efb5 100644 void __init __weak arch_task_cache_init(void) { } --- -2.19.2 - diff --git a/kernel/patches-4.14.x-rt/0209-sched-Limit-the-number-of-task-migrations-per-batch.patch b/kernel/patches-4.19.x-rt/0109-sched-limit-nr-migrate.patch similarity index 51% rename from kernel/patches-4.14.x-rt/0209-sched-Limit-the-number-of-task-migrations-per-batch.patch rename to kernel/patches-4.19.x-rt/0109-sched-limit-nr-migrate.patch index 41febbf31..ba1947d2a 100644 --- a/kernel/patches-4.14.x-rt/0209-sched-Limit-the-number-of-task-migrations-per-batch.patch +++ b/kernel/patches-4.19.x-rt/0109-sched-limit-nr-migrate.patch @@ -1,32 +1,26 @@ -From 6ce72272f2af8f6056b5cdd5fe70ab000cdb2f37 Mon Sep 17 00:00:00 2001 +Subject: sched: Limit the number of task migrations per batch From: Thomas Gleixner -Date: Mon, 6 Jun 2011 12:12:51 +0200 -Subject: [PATCH 209/450] sched: Limit the number of task migrations per batch +Date: Mon, 06 Jun 2011 12:12:51 +0200 Put an upper limit on the number of tasks which are migrated per batch to avoid large latencies. Signed-off-by: Thomas Gleixner --- - kernel/sched/core.c | 4 ++++ + kernel/sched/core.c | 4 ++++ 1 file changed, 4 insertions(+) -diff --git a/kernel/sched/core.c b/kernel/sched/core.c -index 9526621d97e3..1608faf5d08e 100644 --- a/kernel/sched/core.c +++ b/kernel/sched/core.c -@@ -59,7 +59,11 @@ const_debug unsigned int sysctl_sched_features = +@@ -44,7 +44,11 @@ const_debug unsigned int sysctl_sched_fe * Number of tasks to iterate in a single balance run. * Limited because this is done with IRQs disabled. */ -+#ifndef CONFIG_PREEMPT_RT_FULL - const_debug unsigned int sysctl_sched_nr_migrate = 32; -+#else ++#ifdef CONFIG_PREEMPT_RT_FULL +const_debug unsigned int sysctl_sched_nr_migrate = 8; ++#else + const_debug unsigned int sysctl_sched_nr_migrate = 32; +#endif /* - * period over which we average the RT time consumption, measured --- -2.19.2 - + * period over which we measure -rt task CPU usage in us. diff --git a/kernel/patches-4.14.x-rt/0210-sched-Move-mmdrop-to-RCU-on-RT.patch b/kernel/patches-4.19.x-rt/0110-sched-mmdrop-delayed.patch similarity index 56% rename from kernel/patches-4.14.x-rt/0210-sched-Move-mmdrop-to-RCU-on-RT.patch rename to kernel/patches-4.19.x-rt/0110-sched-mmdrop-delayed.patch index 5754c4236..ce90eb91a 100644 --- a/kernel/patches-4.14.x-rt/0210-sched-Move-mmdrop-to-RCU-on-RT.patch +++ b/kernel/patches-4.19.x-rt/0110-sched-mmdrop-delayed.patch @@ -1,21 +1,18 @@ -From 41156d65040c20950b51b8f9c52403188f998187 Mon Sep 17 00:00:00 2001 +Subject: sched: Move mmdrop to RCU on RT From: Thomas Gleixner -Date: Mon, 6 Jun 2011 12:20:33 +0200 -Subject: [PATCH 210/450] sched: Move mmdrop to RCU on RT +Date: Mon, 06 Jun 2011 12:20:33 +0200 Takes sleeping locks and calls into the memory allocator, so nothing we want to do in task switch and oder atomic contexts. Signed-off-by: Thomas Gleixner --- - include/linux/mm_types.h | 4 ++++ - include/linux/sched/mm.h | 11 +++++++++++ - kernel/fork.c | 13 +++++++++++++ - kernel/sched/core.c | 19 +++++++++++++++++-- - 4 files changed, 45 insertions(+), 2 deletions(-) + include/linux/mm_types.h | 4 ++++ + include/linux/sched/mm.h | 11 +++++++++++ + kernel/fork.c | 13 +++++++++++++ + kernel/sched/core.c | 18 ++++++++++++++++-- + 4 files changed, 44 insertions(+), 2 deletions(-) -diff --git a/include/linux/mm_types.h b/include/linux/mm_types.h -index e41ef532c4ce..63317710311e 100644 --- a/include/linux/mm_types.h +++ b/include/linux/mm_types.h @@ -12,6 +12,7 @@ @@ -26,21 +23,19 @@ index e41ef532c4ce..63317710311e 100644 #include #include -@@ -496,6 +497,9 @@ struct mm_struct { - bool tlb_flush_batched; +@@ -482,6 +483,9 @@ struct mm_struct { + bool tlb_flush_batched; #endif - struct uprobes_state uprobes_state; + struct uprobes_state uprobes_state; +#ifdef CONFIG_PREEMPT_RT_BASE -+ struct rcu_head delayed_drop; ++ struct rcu_head delayed_drop; +#endif #ifdef CONFIG_HUGETLB_PAGE - atomic_long_t hugetlb_usage; + atomic_long_t hugetlb_usage; #endif -diff --git a/include/linux/sched/mm.h b/include/linux/sched/mm.h -index 3d49b91b674d..d8f2fa8f500c 100644 --- a/include/linux/sched/mm.h +++ b/include/linux/sched/mm.h -@@ -43,6 +43,17 @@ static inline void mmdrop(struct mm_struct *mm) +@@ -49,6 +49,17 @@ static inline void mmdrop(struct mm_stru __mmdrop(mm); } @@ -55,14 +50,12 @@ index 3d49b91b674d..d8f2fa8f500c 100644 +# define mmdrop_delayed(mm) mmdrop(mm) +#endif + - static inline void mmdrop_async_fn(struct work_struct *work) - { - struct mm_struct *mm = container_of(work, struct mm_struct, async_put_work); -diff --git a/kernel/fork.c b/kernel/fork.c -index 677d17d7efb5..2c53e56ac3e3 100644 + /** + * mmget() - Pin the address space associated with a &struct mm_struct. + * @mm: The address space to pin. --- a/kernel/fork.c +++ b/kernel/fork.c -@@ -929,6 +929,19 @@ void __mmdrop(struct mm_struct *mm) +@@ -637,6 +637,19 @@ void __mmdrop(struct mm_struct *mm) } EXPORT_SYMBOL_GPL(__mmdrop); @@ -79,28 +72,27 @@ index 677d17d7efb5..2c53e56ac3e3 100644 +} +#endif + - static inline void __mmput(struct mm_struct *mm) + static void mmdrop_async_fn(struct work_struct *work) { - VM_BUG_ON(atomic_read(&mm->mm_users)); -diff --git a/kernel/sched/core.c b/kernel/sched/core.c -index 1608faf5d08e..0d854e75e16a 100644 + struct mm_struct *mm; --- a/kernel/sched/core.c +++ b/kernel/sched/core.c -@@ -2713,8 +2713,12 @@ static struct rq *finish_task_switch(struct task_struct *prev) - finish_arch_post_lock_switch(); - - fire_sched_in_preempt_notifiers(current); +@@ -2727,9 +2727,13 @@ static struct rq *finish_task_switch(str + * provided by mmdrop(), + * - a sync_core for SYNC_CORE. + */ + /* + * We use mmdrop_delayed() here so we don't have to do the + * full __mmdrop() when we are the last user. + */ - if (mm) + if (mm) { + membarrier_mm_sync_core_before_usermode(mm); - mmdrop(mm); + mmdrop_delayed(mm); + } if (unlikely(prev_state == TASK_DEAD)) { if (prev->sched_class->task_dead) - prev->sched_class->task_dead(prev); -@@ -5436,6 +5440,8 @@ void sched_setnuma(struct task_struct *p, int nid) +@@ -5557,6 +5561,8 @@ void sched_setnuma(struct task_struct *p #endif /* CONFIG_NUMA_BALANCING */ #ifdef CONFIG_HOTPLUG_CPU @@ -109,8 +101,8 @@ index 1608faf5d08e..0d854e75e16a 100644 /* * Ensure that the idle task is using init_mm right before its CPU goes * offline. -@@ -5450,7 +5456,12 @@ void idle_task_exit(void) - switch_mm(mm, &init_mm, current); +@@ -5572,7 +5578,11 @@ void idle_task_exit(void) + current->active_mm = &init_mm; finish_arch_post_lock_switch(); } - mmdrop(mm); @@ -119,13 +111,12 @@ index 1608faf5d08e..0d854e75e16a 100644 + * call mmdrop() nor mmdrop_delayed() from here. + */ + per_cpu(idle_last_mm, smp_processor_id()) = mm; -+ } /* -@@ -5768,6 +5779,10 @@ int sched_cpu_dying(unsigned int cpu) +@@ -5884,6 +5894,10 @@ int sched_cpu_dying(unsigned int cpu) update_max_interval(); - nohz_balance_exit_idle(cpu); + nohz_balance_exit_idle(rq); hrtick_clear(rq); + if (per_cpu(idle_last_mm, cpu)) { + mmdrop_delayed(per_cpu(idle_last_mm, cpu)); @@ -134,6 +125,3 @@ index 1608faf5d08e..0d854e75e16a 100644 return 0; } #endif --- -2.19.2 - diff --git a/kernel/patches-4.14.x-rt/0211-kernel-sched-move-stack-kprobe-clean-up-to-__put_tas.patch b/kernel/patches-4.19.x-rt/0111-kernel-sched-move-stack-kprobe-clean-up-to-__put_tas.patch similarity index 64% rename from kernel/patches-4.14.x-rt/0211-kernel-sched-move-stack-kprobe-clean-up-to-__put_tas.patch rename to kernel/patches-4.19.x-rt/0111-kernel-sched-move-stack-kprobe-clean-up-to-__put_tas.patch index f824ed5f6..65db86c3b 100644 --- a/kernel/patches-4.14.x-rt/0211-kernel-sched-move-stack-kprobe-clean-up-to-__put_tas.patch +++ b/kernel/patches-4.19.x-rt/0111-kernel-sched-move-stack-kprobe-clean-up-to-__put_tas.patch @@ -1,22 +1,20 @@ -From 5a4b7b821bd9bfa7af1f44dc2956655be2c0cfa6 Mon Sep 17 00:00:00 2001 From: Sebastian Andrzej Siewior Date: Mon, 21 Nov 2016 19:31:08 +0100 -Subject: [PATCH 211/450] kernel/sched: move stack + kprobe clean up to +Subject: [PATCH] kernel/sched: move stack + kprobe clean up to __put_task_struct() -There is no need to free the stack before the task struct. This also -comes handy on -RT because we can't free memory in preempt disabled -region. +There is no need to free the stack before the task struct (except for reasons +mentioned in commit 68f24b08ee89 ("sched/core: Free the stack early if +CONFIG_THREAD_INFO_IN_TASK")). This also comes handy on -RT because we can't +free memory in preempt disabled region. Cc: stable-rt@vger.kernel.org #for kprobe_flush_task() Signed-off-by: Sebastian Andrzej Siewior --- - kernel/fork.c | 10 ++++++++++ - kernel/sched/core.c | 9 --------- + kernel/fork.c | 10 ++++++++++ + kernel/sched/core.c | 9 --------- 2 files changed, 10 insertions(+), 9 deletions(-) -diff --git a/kernel/fork.c b/kernel/fork.c -index 2c53e56ac3e3..787105e3bf1b 100644 --- a/kernel/fork.c +++ b/kernel/fork.c @@ -40,6 +40,7 @@ @@ -27,7 +25,7 @@ index 2c53e56ac3e3..787105e3bf1b 100644 #include #include #include -@@ -416,6 +417,15 @@ void __put_task_struct(struct task_struct *tsk) +@@ -693,6 +694,15 @@ void __put_task_struct(struct task_struc WARN_ON(atomic_read(&tsk->usage)); WARN_ON(tsk == current); @@ -43,11 +41,9 @@ index 2c53e56ac3e3..787105e3bf1b 100644 cgroup_free(tsk); task_numa_free(tsk); security_task_free(tsk); -diff --git a/kernel/sched/core.c b/kernel/sched/core.c -index 0d854e75e16a..8bdfb648b900 100644 --- a/kernel/sched/core.c +++ b/kernel/sched/core.c -@@ -2723,15 +2723,6 @@ static struct rq *finish_task_switch(struct task_struct *prev) +@@ -2739,15 +2739,6 @@ static struct rq *finish_task_switch(str if (prev->sched_class->task_dead) prev->sched_class->task_dead(prev); @@ -63,6 +59,3 @@ index 0d854e75e16a..8bdfb648b900 100644 put_task_struct(prev); } --- -2.19.2 - diff --git a/kernel/patches-4.14.x-rt/0212-sched-Add-saved_state-for-tasks-blocked-on-sleeping-.patch b/kernel/patches-4.19.x-rt/0112-sched-rt-mutex-wakeup.patch similarity index 62% rename from kernel/patches-4.14.x-rt/0212-sched-Add-saved_state-for-tasks-blocked-on-sleeping-.patch rename to kernel/patches-4.19.x-rt/0112-sched-rt-mutex-wakeup.patch index afb6f7bd1..0127fdc75 100644 --- a/kernel/patches-4.14.x-rt/0212-sched-Add-saved_state-for-tasks-blocked-on-sleeping-.patch +++ b/kernel/patches-4.19.x-rt/0112-sched-rt-mutex-wakeup.patch @@ -1,8 +1,6 @@ -From 38d8f2b7ebebc2376194de04e69fc39cc8a505f4 Mon Sep 17 00:00:00 2001 +Subject: sched: Add saved_state for tasks blocked on sleeping locks From: Thomas Gleixner Date: Sat, 25 Jun 2011 09:21:04 +0200 -Subject: [PATCH 212/450] sched: Add saved_state for tasks blocked on sleeping - locks Spinlocks are state preserving in !RT. RT changes the state when a task gets blocked on a lock. So we need to remember the state before @@ -12,16 +10,14 @@ sleep is done, the saved state is restored. Signed-off-by: Thomas Gleixner --- - include/linux/sched.h | 3 +++ - kernel/sched/core.c | 31 ++++++++++++++++++++++++++++++- - kernel/sched/sched.h | 1 + - 3 files changed, 34 insertions(+), 1 deletion(-) + include/linux/sched.h | 3 +++ + kernel/sched/core.c | 33 ++++++++++++++++++++++++++++++++- + kernel/sched/sched.h | 1 + + 3 files changed, 36 insertions(+), 1 deletion(-) -diff --git a/include/linux/sched.h b/include/linux/sched.h -index 8281cf6d97cd..962c3e6e8979 100644 --- a/include/linux/sched.h +++ b/include/linux/sched.h -@@ -566,6 +566,8 @@ struct task_struct { +@@ -600,6 +600,8 @@ struct task_struct { #endif /* -1 unrunnable, 0 runnable, >0 stopped: */ volatile long state; @@ -30,7 +26,7 @@ index 8281cf6d97cd..962c3e6e8979 100644 /* * This begins the randomizable portion of task_struct. Only -@@ -1564,6 +1566,7 @@ extern struct task_struct *find_task_by_pid_ns(pid_t nr, struct pid_namespace *n +@@ -1613,6 +1615,7 @@ extern struct task_struct *find_get_task extern int wake_up_state(struct task_struct *tsk, unsigned int state); extern int wake_up_process(struct task_struct *tsk); @@ -38,11 +34,9 @@ index 8281cf6d97cd..962c3e6e8979 100644 extern void wake_up_new_task(struct task_struct *tsk); #ifdef CONFIG_SMP -diff --git a/kernel/sched/core.c b/kernel/sched/core.c -index 8bdfb648b900..d5210a7dae70 100644 --- a/kernel/sched/core.c +++ b/kernel/sched/core.c -@@ -2033,8 +2033,25 @@ try_to_wake_up(struct task_struct *p, unsigned int state, int wake_flags) +@@ -1997,8 +1997,27 @@ try_to_wake_up(struct task_struct *p, un */ raw_spin_lock_irqsave(&p->pi_lock, flags); smp_mb__after_spinlock(); @@ -54,8 +48,10 @@ index 8bdfb648b900..d5210a7dae70 100644 + * if the wakeup condition is true. + */ + if (!(wake_flags & WF_LOCK_SLEEPER)) { -+ if (p->saved_state & state) ++ if (p->saved_state & state) { + p->saved_state = TASK_RUNNING; ++ success = 1; ++ } + } goto out; + } @@ -69,7 +65,7 @@ index 8bdfb648b900..d5210a7dae70 100644 trace_sched_waking(p); -@@ -2198,6 +2215,18 @@ int wake_up_process(struct task_struct *p) +@@ -2162,6 +2181,18 @@ int wake_up_process(struct task_struct * } EXPORT_SYMBOL(wake_up_process); @@ -82,24 +78,19 @@ index 8bdfb648b900..d5210a7dae70 100644 + */ +int wake_up_lock_sleeper(struct task_struct *p) +{ -+ return try_to_wake_up(p, TASK_ALL, WF_LOCK_SLEEPER); ++ return try_to_wake_up(p, TASK_UNINTERRUPTIBLE, WF_LOCK_SLEEPER); +} + int wake_up_state(struct task_struct *p, unsigned int state) { return try_to_wake_up(p, state, 0); -diff --git a/kernel/sched/sched.h b/kernel/sched/sched.h -index b3ba6e5e99f2..bd6363799cf6 100644 --- a/kernel/sched/sched.h +++ b/kernel/sched/sched.h -@@ -1354,6 +1354,7 @@ static inline void finish_lock_switch(struct rq *rq, struct task_struct *prev) - #define WF_SYNC 0x01 /* waker goes to sleep after wakeup */ - #define WF_FORK 0x02 /* child wakeup after fork */ - #define WF_MIGRATED 0x4 /* internal use, task got migrated */ -+#define WF_LOCK_SLEEPER 0x08 /* wakeup spinlock "sleeper" */ +@@ -1443,6 +1443,7 @@ static inline int task_on_rq_migrating(s + #define WF_SYNC 0x01 /* Waker goes to sleep after wakeup */ + #define WF_FORK 0x02 /* Child wakeup after fork */ + #define WF_MIGRATED 0x4 /* Internal use, task got migrated */ ++#define WF_LOCK_SLEEPER 0x08 /* wakeup spinlock "sleeper" */ /* * To aid in avoiding the subversion of "niceness" due to uneven distribution --- -2.19.2 - diff --git a/kernel/patches-4.14.x-rt/0215-sched-Do-not-account-rcu_preempt_depth-on-RT-in-migh.patch b/kernel/patches-4.19.x-rt/0113-sched-might-sleep-do-not-account-rcu-depth.patch similarity index 63% rename from kernel/patches-4.14.x-rt/0215-sched-Do-not-account-rcu_preempt_depth-on-RT-in-migh.patch rename to kernel/patches-4.19.x-rt/0113-sched-might-sleep-do-not-account-rcu-depth.patch index 3dce6e77a..48a9957fe 100644 --- a/kernel/patches-4.14.x-rt/0215-sched-Do-not-account-rcu_preempt_depth-on-RT-in-migh.patch +++ b/kernel/patches-4.19.x-rt/0113-sched-might-sleep-do-not-account-rcu-depth.patch @@ -1,23 +1,19 @@ -From 90071a4339a4dbe5d353b164ae986152146c4c45 Mon Sep 17 00:00:00 2001 +Subject: sched: Do not account rcu_preempt_depth on RT in might_sleep() From: Thomas Gleixner -Date: Tue, 7 Jun 2011 09:19:06 +0200 -Subject: [PATCH 215/450] sched: Do not account rcu_preempt_depth on RT in - might_sleep() +Date: Tue, 07 Jun 2011 09:19:06 +0200 RT changes the rcu_preempt_depth semantics, so we cannot check for it in might_sleep(). Signed-off-by: Thomas Gleixner --- - include/linux/rcupdate.h | 7 +++++++ - kernel/sched/core.c | 2 +- + include/linux/rcupdate.h | 7 +++++++ + kernel/sched/core.c | 2 +- 2 files changed, 8 insertions(+), 1 deletion(-) -diff --git a/include/linux/rcupdate.h b/include/linux/rcupdate.h -index a6ddc42f87a5..dbadbdbc8643 100644 --- a/include/linux/rcupdate.h +++ b/include/linux/rcupdate.h -@@ -74,6 +74,11 @@ void synchronize_rcu(void); +@@ -73,6 +73,11 @@ void synchronize_rcu(void); * types of kernel builds, the rcu_read_lock() nesting depth is unknowable. */ #define rcu_preempt_depth() (current->rcu_read_lock_nesting) @@ -29,7 +25,7 @@ index a6ddc42f87a5..dbadbdbc8643 100644 #else /* #ifdef CONFIG_PREEMPT_RCU */ -@@ -99,6 +104,8 @@ static inline int rcu_preempt_depth(void) +@@ -98,6 +103,8 @@ static inline int rcu_preempt_depth(void return 0; } @@ -38,11 +34,9 @@ index a6ddc42f87a5..dbadbdbc8643 100644 #endif /* #else #ifdef CONFIG_PREEMPT_RCU */ /* Internal to kernel */ -diff --git a/kernel/sched/core.c b/kernel/sched/core.c -index 840f5fe684d5..bcb5ea038266 100644 --- a/kernel/sched/core.c +++ b/kernel/sched/core.c -@@ -6052,7 +6052,7 @@ void __init sched_init(void) +@@ -6154,7 +6154,7 @@ void __init sched_init(void) #ifdef CONFIG_DEBUG_ATOMIC_SLEEP static inline int preempt_count_equals(int preempt_offset) { @@ -51,6 +45,3 @@ index 840f5fe684d5..bcb5ea038266 100644 return (nested == preempt_offset); } --- -2.19.2 - diff --git a/kernel/patches-4.14.x-rt/0217-sched-Use-the-proper-LOCK_OFFSET-for-cond_resched.patch b/kernel/patches-4.19.x-rt/0114-cond-resched-lock-rt-tweak.patch similarity index 67% rename from kernel/patches-4.14.x-rt/0217-sched-Use-the-proper-LOCK_OFFSET-for-cond_resched.patch rename to kernel/patches-4.19.x-rt/0114-cond-resched-lock-rt-tweak.patch index b3c0e5aee..c3caef32f 100644 --- a/kernel/patches-4.14.x-rt/0217-sched-Use-the-proper-LOCK_OFFSET-for-cond_resched.patch +++ b/kernel/patches-4.19.x-rt/0114-cond-resched-lock-rt-tweak.patch @@ -1,18 +1,15 @@ -From d52d23eebda645e4aa9676623b93eb933d00237a Mon Sep 17 00:00:00 2001 +Subject: sched: Use the proper LOCK_OFFSET for cond_resched() From: Thomas Gleixner Date: Sun, 17 Jul 2011 22:51:33 +0200 -Subject: [PATCH 217/450] sched: Use the proper LOCK_OFFSET for cond_resched() RT does not increment preempt count when a 'sleeping' spinlock is locked. Update PREEMPT_LOCK_OFFSET for that case. Signed-off-by: Thomas Gleixner --- - include/linux/preempt.h | 4 ++++ + include/linux/preempt.h | 4 ++++ 1 file changed, 4 insertions(+) -diff --git a/include/linux/preempt.h b/include/linux/preempt.h -index 8681df8e1632..2d5d002e06c2 100644 --- a/include/linux/preempt.h +++ b/include/linux/preempt.h @@ -118,7 +118,11 @@ @@ -27,6 +24,3 @@ index 8681df8e1632..2d5d002e06c2 100644 /* * The preempt_count offset needed for things like: --- -2.19.2 - diff --git a/kernel/patches-4.14.x-rt/0218-sched-Disable-TTWU_QUEUE-on-RT.patch b/kernel/patches-4.19.x-rt/0115-sched-disable-ttwu-queue.patch similarity index 73% rename from kernel/patches-4.14.x-rt/0218-sched-Disable-TTWU_QUEUE-on-RT.patch rename to kernel/patches-4.19.x-rt/0115-sched-disable-ttwu-queue.patch index 434210836..95221e680 100644 --- a/kernel/patches-4.14.x-rt/0218-sched-Disable-TTWU_QUEUE-on-RT.patch +++ b/kernel/patches-4.19.x-rt/0115-sched-disable-ttwu-queue.patch @@ -1,18 +1,15 @@ -From 3b52a98bf8264a3eb8b28a035de27bc50ef58ea8 Mon Sep 17 00:00:00 2001 +Subject: sched: Disable TTWU_QUEUE on RT From: Thomas Gleixner Date: Tue, 13 Sep 2011 16:42:35 +0200 -Subject: [PATCH 218/450] sched: Disable TTWU_QUEUE on RT The queued remote wakeup mechanism can introduce rather large latencies if the number of migrated tasks is high. Disable it for RT. Signed-off-by: Thomas Gleixner --- - kernel/sched/features.h | 5 +++++ + kernel/sched/features.h | 5 +++++ 1 file changed, 5 insertions(+) -diff --git a/kernel/sched/features.h b/kernel/sched/features.h -index 9552fd5854bf..c675ee1694f5 100644 --- a/kernel/sched/features.h +++ b/kernel/sched/features.h @@ -46,11 +46,16 @@ SCHED_FEAT(LB_BIAS, true) @@ -32,6 +29,3 @@ index 9552fd5854bf..c675ee1694f5 100644 /* * When doing wakeups, attempt to limit superfluous scans of the LLC domain. --- -2.19.2 - diff --git a/kernel/patches-4.14.x-rt/0221-sched-workqueue-Only-wake-up-idle-workers-if-not-blo.patch b/kernel/patches-4.19.x-rt/0116-sched-workqueue-Only-wake-up-idle-workers-if-not-blo.patch similarity index 77% rename from kernel/patches-4.14.x-rt/0221-sched-workqueue-Only-wake-up-idle-workers-if-not-blo.patch rename to kernel/patches-4.19.x-rt/0116-sched-workqueue-Only-wake-up-idle-workers-if-not-blo.patch index c37ebce23..7c3a3860d 100644 --- a/kernel/patches-4.14.x-rt/0221-sched-workqueue-Only-wake-up-idle-workers-if-not-blo.patch +++ b/kernel/patches-4.19.x-rt/0116-sched-workqueue-Only-wake-up-idle-workers-if-not-blo.patch @@ -1,8 +1,6 @@ -From 64da8c818609427bd7dca604fde6217f536a8509 Mon Sep 17 00:00:00 2001 From: Steven Rostedt Date: Mon, 18 Mar 2013 15:12:49 -0400 -Subject: [PATCH 221/450] sched/workqueue: Only wake up idle workers if not - blocked on sleeping spin lock +Subject: sched/workqueue: Only wake up idle workers if not blocked on sleeping spin lock In -rt, most spin_locks() turn into mutexes. One of these spin_lock conversions is performed on the workqueue gcwq->lock. When the idle @@ -20,14 +18,12 @@ Check the saved_state too before waking up new workers. Signed-off-by: Steven Rostedt Signed-off-by: Sebastian Andrzej Siewior --- - kernel/sched/core.c | 4 +++- + kernel/sched/core.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) -diff --git a/kernel/sched/core.c b/kernel/sched/core.c -index 75c7bd31cba4..82da2b9facc9 100644 --- a/kernel/sched/core.c +++ b/kernel/sched/core.c -@@ -3405,8 +3405,10 @@ static void __sched notrace __schedule(bool preempt) +@@ -3496,8 +3496,10 @@ static void __sched notrace __schedule(b * If a worker went to sleep, notify and ask workqueue * whether it wants to wake up a task to maintain * concurrency. @@ -39,6 +35,3 @@ index 75c7bd31cba4..82da2b9facc9 100644 struct task_struct *to_wakeup; to_wakeup = wq_worker_sleeping(prev); --- -2.19.2 - diff --git a/kernel/patches-4.14.x-rt/0222-rt-Increase-decrease-the-nr-of-migratory-tasks-when-.patch b/kernel/patches-4.19.x-rt/0117-rt-Increase-decrease-the-nr-of-migratory-tasks-when-.patch similarity index 90% rename from kernel/patches-4.14.x-rt/0222-rt-Increase-decrease-the-nr-of-migratory-tasks-when-.patch rename to kernel/patches-4.19.x-rt/0117-rt-Increase-decrease-the-nr-of-migratory-tasks-when-.patch index 4a64606cd..9bae25ddb 100644 --- a/kernel/patches-4.14.x-rt/0222-rt-Increase-decrease-the-nr-of-migratory-tasks-when-.patch +++ b/kernel/patches-4.19.x-rt/0117-rt-Increase-decrease-the-nr-of-migratory-tasks-when-.patch @@ -1,8 +1,6 @@ -From 683b12cfb28b91fbb49cddbdbb8c1962d17cd855 Mon Sep 17 00:00:00 2001 From: Daniel Bristot de Oliveira Date: Mon, 26 Jun 2017 17:07:15 +0200 -Subject: [PATCH 222/450] rt: Increase/decrease the nr of migratory tasks when - enabling/disabling migration +Subject: rt: Increase/decrease the nr of migratory tasks when enabling/disabling migration There is a problem in the migrate_disable()/enable() implementation regarding the number of migratory tasks in the rt/dl RQs. The problem @@ -77,14 +75,12 @@ Cc: LKML Cc: linux-rt-users Signed-off-by: Sebastian Andrzej Siewior --- - kernel/sched/core.c | 49 ++++++++++++++++++++++++++++++++++++++++----- + kernel/sched/core.c | 49 ++++++++++++++++++++++++++++++++++++++++++++----- 1 file changed, 44 insertions(+), 5 deletions(-) -diff --git a/kernel/sched/core.c b/kernel/sched/core.c -index 82da2b9facc9..b5738acc4bf1 100644 --- a/kernel/sched/core.c +++ b/kernel/sched/core.c -@@ -6853,6 +6853,47 @@ const u32 sched_prio_to_wmult[40] = { +@@ -7138,6 +7138,47 @@ const u32 sched_prio_to_wmult[40] = { #if defined(CONFIG_PREEMPT_COUNT) && defined(CONFIG_SMP) @@ -132,7 +128,7 @@ index 82da2b9facc9..b5738acc4bf1 100644 void migrate_disable(void) { struct task_struct *p = current; -@@ -6876,10 +6917,9 @@ void migrate_disable(void) +@@ -7161,10 +7202,9 @@ void migrate_disable(void) } preempt_disable(); @@ -145,7 +141,7 @@ index 82da2b9facc9..b5738acc4bf1 100644 preempt_enable(); } -@@ -6911,9 +6951,8 @@ void migrate_enable(void) +@@ -7196,9 +7236,8 @@ void migrate_enable(void) preempt_disable(); @@ -156,6 +152,3 @@ index 82da2b9facc9..b5738acc4bf1 100644 if (p->migrate_disable_update) { struct rq *rq; --- -2.19.2 - diff --git a/kernel/patches-4.14.x-rt/0225-hotplug-Lightweight-get-online-cpus.patch b/kernel/patches-4.19.x-rt/0118-hotplug-light-get-online-cpus.patch similarity index 71% rename from kernel/patches-4.14.x-rt/0225-hotplug-Lightweight-get-online-cpus.patch rename to kernel/patches-4.19.x-rt/0118-hotplug-light-get-online-cpus.patch index 9e384be90..bf5a3a6b7 100644 --- a/kernel/patches-4.14.x-rt/0225-hotplug-Lightweight-get-online-cpus.patch +++ b/kernel/patches-4.19.x-rt/0118-hotplug-light-get-online-cpus.patch @@ -1,7 +1,6 @@ -From bbeeb3d6b7c54f8bc6c3b96adcc16444961e23e1 Mon Sep 17 00:00:00 2001 +Subject: hotplug: Lightweight get online cpus From: Thomas Gleixner Date: Wed, 15 Jun 2011 12:36:06 +0200 -Subject: [PATCH 225/450] hotplug: Lightweight get online cpus get_online_cpus() is a heavy weight function which involves a global mutex. migrate_disable() wants a simpler construct which prevents only @@ -13,16 +12,14 @@ tasks on the cpu which should be brought down. Signed-off-by: Thomas Gleixner --- - include/linux/cpu.h | 5 +++++ - kernel/cpu.c | 15 +++++++++++++++ - kernel/sched/core.c | 4 ++++ + include/linux/cpu.h | 5 +++++ + kernel/cpu.c | 15 +++++++++++++++ + kernel/sched/core.c | 4 ++++ 3 files changed, 24 insertions(+) -diff --git a/include/linux/cpu.h b/include/linux/cpu.h -index 2a378d261914..b418d3c5159d 100644 --- a/include/linux/cpu.h +++ b/include/linux/cpu.h -@@ -120,6 +120,8 @@ extern void cpu_hotplug_disable(void); +@@ -111,6 +111,8 @@ extern void cpu_hotplug_disable(void); extern void cpu_hotplug_enable(void); void clear_tasks_mm_cpumask(int cpu); int cpu_down(unsigned int cpu); @@ -31,7 +28,7 @@ index 2a378d261914..b418d3c5159d 100644 #else /* CONFIG_HOTPLUG_CPU */ -@@ -130,6 +132,9 @@ static inline void cpus_read_unlock(void) { } +@@ -122,6 +124,9 @@ static inline int cpus_read_trylock(voi static inline void lockdep_assert_cpus_held(void) { } static inline void cpu_hotplug_disable(void) { } static inline void cpu_hotplug_enable(void) { } @@ -41,11 +38,9 @@ index 2a378d261914..b418d3c5159d 100644 #endif /* !CONFIG_HOTPLUG_CPU */ /* Wrappers which go away once all code is converted */ -diff --git a/kernel/cpu.c b/kernel/cpu.c -index 5c907d96e3dd..92a1e437e777 100644 --- a/kernel/cpu.c +++ b/kernel/cpu.c -@@ -288,6 +288,21 @@ static int cpu_hotplug_disabled; +@@ -281,6 +281,21 @@ static int cpu_hotplug_disabled; #ifdef CONFIG_HOTPLUG_CPU @@ -67,11 +62,9 @@ index 5c907d96e3dd..92a1e437e777 100644 DEFINE_STATIC_PERCPU_RWSEM(cpu_hotplug_lock); void cpus_read_lock(void) -diff --git a/kernel/sched/core.c b/kernel/sched/core.c -index b5738acc4bf1..e4c9a2f745cf 100644 --- a/kernel/sched/core.c +++ b/kernel/sched/core.c -@@ -6917,6 +6917,7 @@ void migrate_disable(void) +@@ -7202,6 +7202,7 @@ void migrate_disable(void) } preempt_disable(); @@ -79,7 +72,7 @@ index b5738acc4bf1..e4c9a2f745cf 100644 migrate_disable_update_cpus_allowed(p); p->migrate_disable = 1; -@@ -6982,12 +6983,15 @@ void migrate_enable(void) +@@ -7267,12 +7268,15 @@ void migrate_enable(void) arg.task = p; arg.dest_cpu = dest_cpu; @@ -95,6 +88,3 @@ index b5738acc4bf1..e4c9a2f745cf 100644 preempt_enable(); } EXPORT_SYMBOL(migrate_enable); --- -2.19.2 - diff --git a/kernel/patches-4.14.x-rt/0226-trace-Add-migrate-disabled-counter-to-tracing-output.patch b/kernel/patches-4.19.x-rt/0119-ftrace-migrate-disable-tracing.patch similarity index 65% rename from kernel/patches-4.14.x-rt/0226-trace-Add-migrate-disabled-counter-to-tracing-output.patch rename to kernel/patches-4.19.x-rt/0119-ftrace-migrate-disable-tracing.patch index d568d076f..15e60523d 100644 --- a/kernel/patches-4.14.x-rt/0226-trace-Add-migrate-disabled-counter-to-tracing-output.patch +++ b/kernel/patches-4.19.x-rt/0119-ftrace-migrate-disable-tracing.patch @@ -1,18 +1,15 @@ -From 5590a85f742ef9adfea2559e265bf36d04576de3 Mon Sep 17 00:00:00 2001 From: Thomas Gleixner Date: Sun, 17 Jul 2011 21:56:42 +0200 -Subject: [PATCH 226/450] trace: Add migrate-disabled counter to tracing output +Subject: trace: Add migrate-disabled counter to tracing output Signed-off-by: Thomas Gleixner --- - include/linux/trace_events.h | 2 ++ - kernel/trace/trace.c | 9 ++++++--- - kernel/trace/trace_events.c | 2 ++ - kernel/trace/trace_output.c | 5 +++++ + include/linux/trace_events.h | 2 ++ + kernel/trace/trace.c | 9 ++++++--- + kernel/trace/trace_events.c | 2 ++ + kernel/trace/trace_output.c | 5 +++++ 4 files changed, 15 insertions(+), 3 deletions(-) -diff --git a/include/linux/trace_events.h b/include/linux/trace_events.h -index aefc80f2909b..ffd595ab5008 100644 --- a/include/linux/trace_events.h +++ b/include/linux/trace_events.h @@ -62,6 +62,8 @@ struct trace_entry { @@ -24,11 +21,9 @@ index aefc80f2909b..ffd595ab5008 100644 }; #define TRACE_EVENT_TYPE_MAX \ -diff --git a/kernel/trace/trace.c b/kernel/trace/trace.c -index 6c2aae7629a7..e6c7395840b4 100644 --- a/kernel/trace/trace.c +++ b/kernel/trace/trace.c -@@ -2147,6 +2147,8 @@ tracing_generic_entry_update(struct trace_entry *entry, unsigned long flags, +@@ -2146,6 +2146,8 @@ tracing_generic_entry_update(struct trac ((pc & SOFTIRQ_OFFSET) ? TRACE_FLAG_SOFTIRQ : 0) | (tif_need_resched() ? TRACE_FLAG_NEED_RESCHED : 0) | (test_preempt_need_resched() ? TRACE_FLAG_PREEMPT_RESCHED : 0); @@ -37,7 +32,7 @@ index 6c2aae7629a7..e6c7395840b4 100644 } EXPORT_SYMBOL_GPL(tracing_generic_entry_update); -@@ -3355,9 +3357,10 @@ static void print_lat_help_header(struct seq_file *m) +@@ -3349,9 +3351,10 @@ static void print_lat_help_header(struct "# | / _----=> need-resched \n" "# || / _---=> hardirq/softirq \n" "# ||| / _--=> preempt-depth \n" @@ -51,11 +46,9 @@ index 6c2aae7629a7..e6c7395840b4 100644 } static void print_event_info(struct trace_buffer *buf, struct seq_file *m) -diff --git a/kernel/trace/trace_events.c b/kernel/trace/trace_events.c -index 1b87157edbff..9ba230a4052f 100644 --- a/kernel/trace/trace_events.c +++ b/kernel/trace/trace_events.c -@@ -187,6 +187,8 @@ static int trace_define_common_fields(void) +@@ -188,6 +188,8 @@ static int trace_define_common_fields(vo __common_field(unsigned char, flags); __common_field(unsigned char, preempt_count); __common_field(int, pid); @@ -64,11 +57,9 @@ index 1b87157edbff..9ba230a4052f 100644 return ret; } -diff --git a/kernel/trace/trace_output.c b/kernel/trace/trace_output.c -index 4500b00e4e36..dfbe55f3e6ac 100644 --- a/kernel/trace/trace_output.c +++ b/kernel/trace/trace_output.c -@@ -493,6 +493,11 @@ int trace_print_lat_fmt(struct trace_seq *s, struct trace_entry *entry) +@@ -494,6 +494,11 @@ int trace_print_lat_fmt(struct trace_seq else trace_seq_putc(s, '.'); @@ -80,6 +71,3 @@ index 4500b00e4e36..dfbe55f3e6ac 100644 return !trace_seq_has_overflowed(s); } --- -2.19.2 - diff --git a/kernel/patches-4.14.x-rt/0227-lockdep-Make-it-RT-aware.patch b/kernel/patches-4.19.x-rt/0120-lockdep-no-softirq-accounting-on-rt.patch similarity index 53% rename from kernel/patches-4.14.x-rt/0227-lockdep-Make-it-RT-aware.patch rename to kernel/patches-4.19.x-rt/0120-lockdep-no-softirq-accounting-on-rt.patch index c5705cb51..027a811cc 100644 --- a/kernel/patches-4.14.x-rt/0227-lockdep-Make-it-RT-aware.patch +++ b/kernel/patches-4.19.x-rt/0120-lockdep-no-softirq-accounting-on-rt.patch @@ -1,67 +1,57 @@ -From 67472f6754cc2e0cafb055c2a43c13aef8d7996e Mon Sep 17 00:00:00 2001 +Subject: lockdep: Make it RT aware From: Thomas Gleixner Date: Sun, 17 Jul 2011 18:51:23 +0200 -Subject: [PATCH 227/450] lockdep: Make it RT aware teach lockdep that we don't really do softirqs on -RT. Signed-off-by: Thomas Gleixner --- - include/linux/irqflags.h | 26 +++++++++++++++----------- - kernel/locking/lockdep.c | 2 ++ - 2 files changed, 17 insertions(+), 11 deletions(-) + include/linux/irqflags.h | 23 +++++++++++++++-------- + kernel/locking/lockdep.c | 2 ++ + 2 files changed, 17 insertions(+), 8 deletions(-) -diff --git a/include/linux/irqflags.h b/include/linux/irqflags.h -index 7834117a1ef5..2e023bfe45af 100644 --- a/include/linux/irqflags.h +++ b/include/linux/irqflags.h -@@ -34,16 +34,6 @@ do { \ +@@ -43,14 +43,6 @@ do { \ + do { \ current->hardirq_context--; \ - crossrelease_hist_end(XHLOCK_HARD); \ } while (0) -# define lockdep_softirq_enter() \ -do { \ - current->softirq_context++; \ -- crossrelease_hist_start(XHLOCK_SOFT); \ -} while (0) -# define lockdep_softirq_exit() \ -do { \ - current->softirq_context--; \ -- crossrelease_hist_end(XHLOCK_SOFT); \ -} while (0) - # define INIT_TRACE_IRQFLAGS .softirqs_enabled = 1, #else # define trace_hardirqs_on() do { } while (0) -@@ -56,9 +46,23 @@ do { \ - # define trace_softirqs_enabled(p) 0 - # define trace_hardirq_enter() do { } while (0) - # define trace_hardirq_exit() do { } while (0) -+# define INIT_TRACE_IRQFLAGS -+#endif + # define trace_hardirqs_off() do { } while (0) +@@ -63,6 +55,21 @@ do { \ + # define lockdep_softirq_enter() do { } while (0) + # define lockdep_softirq_exit() do { } while (0) + #endif + +#if defined(CONFIG_TRACE_IRQFLAGS) && !defined(CONFIG_PREEMPT_RT_FULL) +# define lockdep_softirq_enter() \ +do { \ + current->softirq_context++; \ -+ crossrelease_hist_start(XHLOCK_SOFT); \ +} while (0) +# define lockdep_softirq_exit() \ +do { \ + current->softirq_context--; \ -+ crossrelease_hist_end(XHLOCK_SOFT); \ +} while (0) ++ +#else - # define lockdep_softirq_enter() do { } while (0) - # define lockdep_softirq_exit() do { } while (0) --# define INIT_TRACE_IRQFLAGS - #endif ++# define lockdep_softirq_enter() do { } while (0) ++# define lockdep_softirq_exit() do { } while (0) ++#endif #if defined(CONFIG_IRQSOFF_TRACER) || \ -diff --git a/kernel/locking/lockdep.c b/kernel/locking/lockdep.c -index bf694c709b96..8012378b7445 100644 + defined(CONFIG_PREEMPT_TRACER) --- a/kernel/locking/lockdep.c +++ b/kernel/locking/lockdep.c -@@ -3914,6 +3914,7 @@ static void check_flags(unsigned long flags) +@@ -3823,6 +3823,7 @@ static void check_flags(unsigned long fl } } @@ -69,7 +59,7 @@ index bf694c709b96..8012378b7445 100644 /* * We dont accurately track softirq state in e.g. * hardirq contexts (such as on 4KSTACKS), so only -@@ -3928,6 +3929,7 @@ static void check_flags(unsigned long flags) +@@ -3837,6 +3838,7 @@ static void check_flags(unsigned long fl DEBUG_LOCKS_WARN_ON(!current->softirqs_enabled); } } @@ -77,6 +67,3 @@ index bf694c709b96..8012378b7445 100644 if (!debug_locks) print_irqtrace_events(current); --- -2.19.2 - diff --git a/kernel/patches-4.14.x-rt/0230-tasklet-Prevent-tasklets-from-going-into-infinite-sp.patch b/kernel/patches-4.19.x-rt/0121-tasklet-rt-prevent-tasklets-from-going-into-infinite-spin-in-rt.patch similarity index 58% rename from kernel/patches-4.14.x-rt/0230-tasklet-Prevent-tasklets-from-going-into-infinite-sp.patch rename to kernel/patches-4.19.x-rt/0121-tasklet-rt-prevent-tasklets-from-going-into-infinite-spin-in-rt.patch index 0081a0501..451c7923a 100644 --- a/kernel/patches-4.14.x-rt/0230-tasklet-Prevent-tasklets-from-going-into-infinite-sp.patch +++ b/kernel/patches-4.19.x-rt/0121-tasklet-rt-prevent-tasklets-from-going-into-infinite-spin-in-rt.patch @@ -1,8 +1,6 @@ -From b0398bec6b370691cff81570250a931a1516dc18 Mon Sep 17 00:00:00 2001 +Subject: tasklet: Prevent tasklets from going into infinite spin in RT From: Ingo Molnar -Date: Tue, 29 Nov 2011 20:18:22 -0500 -Subject: [PATCH 230/450] tasklet: Prevent tasklets from going into infinite - spin in RT +Date: Tue Nov 29 20:18:22 2011 -0500 When CONFIG_PREEMPT_RT_FULL is enabled, tasklets run as threads, and spinlocks turn are mutexes. But this can cause issues with @@ -11,21 +9,21 @@ if a tasklets are disabled with tasklet_disable(), the tasklet count is increased. When a tasklet runs, it checks this counter and if it is set, it adds itself back on the softirq queue and returns. - + The problem arises in RT because ksoftirq will see that a softirq is ready to run (the tasklet softirq just re-armed itself), and will not sleep, but instead run the softirqs again. The tasklet softirq will still see that the count is non-zero and will not execute the tasklet and requeue itself on the softirq again, which will cause ksoftirqd to run it again and again and again. - + It gets worse because ksoftirqd runs as a real-time thread. If it preempted the task that disabled tasklets, and that task has migration disabled, or can't run for other reasons, the tasklet softirq will never run because the count will never be zero, and ksoftirqd will go into an infinite loop. As an RT task, it this becomes a big problem. - + This is a hack solution to have tasklet_disable stop tasklets, and when a tasklet runs, instead of requeueing the tasklet softirqd it delays it. When tasklet_enable() is called, and tasklets are @@ -33,20 +31,19 @@ waiting, then the tasklet_enable() will kick the tasklets to continue. This prevents the lock up from ksoftirq going into an infinite loop. [ rostedt@goodmis.org: ported to 3.0-rt ] - + Signed-off-by: Ingo Molnar Signed-off-by: Steven Rostedt Signed-off-by: Thomas Gleixner ---- - include/linux/interrupt.h | 33 ++++--- - kernel/softirq.c | 193 +++++++++++++++++++++++++++----------- - 2 files changed, 157 insertions(+), 69 deletions(-) -diff --git a/include/linux/interrupt.h b/include/linux/interrupt.h -index 172376b9a049..e53ff6a143e0 100644 +--- + include/linux/interrupt.h | 33 ++++++------ + kernel/softirq.c | 126 ++++++++++++++++++++++++++++++++++++++-------- + 2 files changed, 125 insertions(+), 34 deletions(-) + --- a/include/linux/interrupt.h +++ b/include/linux/interrupt.h -@@ -537,8 +537,9 @@ static inline struct task_struct *this_cpu_ksoftirqd(void) +@@ -542,8 +542,9 @@ static inline struct task_struct *this_c to be executed on some cpu at least once after this. * If the tasklet is already scheduled, but its execution is still not started, it will be executed only once. @@ -58,7 +55,7 @@ index 172376b9a049..e53ff6a143e0 100644 * Tasklet is strictly serialized wrt itself, but not wrt another tasklets. If client needs some intertask synchronization, he makes it with spinlocks. -@@ -563,27 +564,36 @@ struct tasklet_struct name = { NULL, 0, ATOMIC_INIT(1), func, data } +@@ -568,27 +569,36 @@ struct tasklet_struct name = { NULL, 0, enum { TASKLET_STATE_SCHED, /* Tasklet is scheduled for execution */ @@ -101,7 +98,7 @@ index 172376b9a049..e53ff6a143e0 100644 #define tasklet_unlock_wait(t) do { } while (0) #define tasklet_unlock(t) do { } while (0) #endif -@@ -617,12 +627,7 @@ static inline void tasklet_disable(struct tasklet_struct *t) +@@ -622,12 +632,7 @@ static inline void tasklet_disable(struc smp_mb(); } @@ -115,8 +112,6 @@ index 172376b9a049..e53ff6a143e0 100644 extern void tasklet_kill(struct tasklet_struct *t); extern void tasklet_kill_immediate(struct tasklet_struct *t, unsigned int cpu); extern void tasklet_init(struct tasklet_struct *t, -diff --git a/kernel/softirq.c b/kernel/softirq.c -index 36092932c532..7f8629d8ee57 100644 --- a/kernel/softirq.c +++ b/kernel/softirq.c @@ -21,6 +21,7 @@ @@ -127,105 +122,75 @@ index 36092932c532..7f8629d8ee57 100644 #include #include #include -@@ -470,15 +471,45 @@ struct tasklet_head { - static DEFINE_PER_CPU(struct tasklet_head, tasklet_vec); - static DEFINE_PER_CPU(struct tasklet_head, tasklet_hi_vec); - -+static void inline -+__tasklet_common_schedule(struct tasklet_struct *t, struct tasklet_head *head, unsigned int nr) -+{ -+ if (tasklet_trylock(t)) { -+again: -+ /* We may have been preempted before tasklet_trylock -+ * and __tasklet_action may have already run. -+ * So double check the sched bit while the takslet -+ * is locked before adding it to the list. -+ */ -+ if (test_bit(TASKLET_STATE_SCHED, &t->state)) { -+ t->next = NULL; -+ *head->tail = t; -+ head->tail = &(t->next); -+ raise_softirq_irqoff(nr); -+ tasklet_unlock(t); -+ } else { -+ /* This is subtle. If we hit the corner case above -+ * It is possible that we get preempted right here, -+ * and another task has successfully called -+ * tasklet_schedule(), then this function, and -+ * failed on the trylock. Thus we must be sure -+ * before releasing the tasklet lock, that the -+ * SCHED_BIT is clear. Otherwise the tasklet -+ * may get its SCHED_BIT set, but not added to the -+ * list -+ */ -+ if (!tasklet_tryunlock(t)) -+ goto again; -+ } -+ } -+} -+ - void __tasklet_schedule(struct tasklet_struct *t) - { +@@ -475,11 +476,38 @@ static void __tasklet_schedule_common(st unsigned long flags; local_irq_save(flags); ++ if (!tasklet_trylock(t)) { ++ local_irq_restore(flags); ++ return; ++ } ++ + head = this_cpu_ptr(headp); - t->next = NULL; -- *__this_cpu_read(tasklet_vec.tail) = t; -- __this_cpu_write(tasklet_vec.tail, &(t->next)); -- raise_softirq_irqoff(TASKLET_SOFTIRQ); -+ __tasklet_common_schedule(t, this_cpu_ptr(&tasklet_vec), TASKLET_SOFTIRQ); +- *head->tail = t; +- head->tail = &(t->next); +- raise_softirq_irqoff(softirq_nr); ++again: ++ /* We may have been preempted before tasklet_trylock ++ * and __tasklet_action may have already run. ++ * So double check the sched bit while the takslet ++ * is locked before adding it to the list. ++ */ ++ if (test_bit(TASKLET_STATE_SCHED, &t->state)) { ++ t->next = NULL; ++ *head->tail = t; ++ head->tail = &(t->next); ++ raise_softirq_irqoff(softirq_nr); ++ tasklet_unlock(t); ++ } else { ++ /* This is subtle. If we hit the corner case above ++ * It is possible that we get preempted right here, ++ * and another task has successfully called ++ * tasklet_schedule(), then this function, and ++ * failed on the trylock. Thus we must be sure ++ * before releasing the tasklet lock, that the ++ * SCHED_BIT is clear. Otherwise the tasklet ++ * may get its SCHED_BIT set, but not added to the ++ * list ++ */ ++ if (!tasklet_tryunlock(t)) ++ goto again; ++ } local_irq_restore(flags); } - EXPORT_SYMBOL(__tasklet_schedule); -@@ -488,50 +519,108 @@ void __tasklet_hi_schedule(struct tasklet_struct *t) - unsigned long flags; - local_irq_save(flags); -- t->next = NULL; -- *__this_cpu_read(tasklet_hi_vec.tail) = t; -- __this_cpu_write(tasklet_hi_vec.tail, &(t->next)); -- raise_softirq_irqoff(HI_SOFTIRQ); -+ __tasklet_common_schedule(t, this_cpu_ptr(&tasklet_hi_vec), HI_SOFTIRQ); - local_irq_restore(flags); +@@ -497,11 +525,21 @@ void __tasklet_hi_schedule(struct taskle } EXPORT_SYMBOL(__tasklet_hi_schedule); --static __latent_entropy void tasklet_action(struct softirq_action *a) +void tasklet_enable(struct tasklet_struct *t) - { -- struct tasklet_struct *list; ++{ + if (!atomic_dec_and_test(&t->count)) + return; + if (test_and_clear_bit(TASKLET_STATE_PENDING, &t->state)) + tasklet_schedule(t); +} +EXPORT_SYMBOL(tasklet_enable); - -- local_irq_disable(); -- list = __this_cpu_read(tasklet_vec.head); -- __this_cpu_write(tasklet_vec.head, NULL); -- __this_cpu_write(tasklet_vec.tail, this_cpu_ptr(&tasklet_vec.head)); -- local_irq_enable(); -+static void __tasklet_action(struct softirq_action *a, -+ struct tasklet_struct *list) -+{ ++ + static void tasklet_action_common(struct softirq_action *a, + struct tasklet_head *tl_head, + unsigned int softirq_nr) + { + struct tasklet_struct *list; + int loops = 1000000; - while (list) { + local_irq_disable(); + list = tl_head->head; +@@ -513,25 +551,56 @@ static void tasklet_action_common(struct struct tasklet_struct *t = list; list = list->next; - -- if (tasklet_trylock(t)) { -- if (!atomic_read(&t->count)) { -- if (!test_and_clear_bit(TASKLET_STATE_SCHED, -- &t->state)) -- BUG(); -- t->func(t->data); -- tasklet_unlock(t); -- continue; -- } -- tasklet_unlock(t); + /* + * Should always succeed - after a tasklist got on the + * list (after getting the SCHED bit set from 0 to 1), @@ -235,20 +200,16 @@ index 36092932c532..7f8629d8ee57 100644 + if (!tasklet_trylock(t)) { + WARN_ON(1); + continue; - } ++ } -- local_irq_disable(); - t->next = NULL; -- *__this_cpu_read(tasklet_vec.tail) = t; -- __this_cpu_write(tasklet_vec.tail, &(t->next)); -- __raise_softirq_irqoff(TASKLET_SOFTIRQ); -- local_irq_enable(); +- if (tasklet_trylock(t)) { +- if (!atomic_read(&t->count)) { +- if (!test_and_clear_bit(TASKLET_STATE_SCHED, +- &t->state)) +- BUG(); +- t->func(t->data); ++ t->next = NULL; + -+ /* -+ * If we cannot handle the tasklet because it's disabled, -+ * mark it as pending. tasklet_enable() will later -+ * re-schedule the tasklet. -+ */ + if (unlikely(atomic_read(&t->count))) { +out_disabled: + /* implicit unlock: */ @@ -256,7 +217,6 @@ index 36092932c532..7f8629d8ee57 100644 + t->state = TASKLET_STATEF_PENDING; + continue; + } -+ + /* + * After this point on the tasklet might be rescheduled + * on another CPU, but it can only be added to another @@ -265,15 +225,9 @@ index 36092932c532..7f8629d8ee57 100644 + */ + if (!test_and_clear_bit(TASKLET_STATE_SCHED, &t->state)) + WARN_ON(1); -+ +again: + t->func(t->data); + -+ /* -+ * Try to unlock the tasklet. We must use cmpxchg, because -+ * another CPU might have scheduled or disabled the tasklet. -+ * We only allow the STATE_RUN -> 0 transition here. -+ */ + while (!tasklet_tryunlock(t)) { + /* + * If it got disabled meanwhile, bail out: @@ -289,62 +243,23 @@ index 36092932c532..7f8629d8ee57 100644 + if (!--loops) { + printk("hm, tasklet state: %08lx\n", t->state); + WARN_ON(1); -+ tasklet_unlock(t); -+ break; -+ } -+ } - } - } - -+static __latent_entropy void tasklet_action(struct softirq_action *a) -+{ -+ struct tasklet_struct *list; -+ -+ local_irq_disable(); -+ list = __this_cpu_read(tasklet_vec.head); -+ __this_cpu_write(tasklet_vec.head, NULL); -+ __this_cpu_write(tasklet_vec.tail, this_cpu_ptr(&tasklet_vec.head)); -+ local_irq_enable(); -+ -+ __tasklet_action(a, list); -+} -+ - static __latent_entropy void tasklet_hi_action(struct softirq_action *a) - { - struct tasklet_struct *list; -@@ -542,30 +631,7 @@ static __latent_entropy void tasklet_hi_action(struct softirq_action *a) - __this_cpu_write(tasklet_hi_vec.tail, this_cpu_ptr(&tasklet_hi_vec.head)); - local_irq_enable(); - -- while (list) { -- struct tasklet_struct *t = list; -- -- list = list->next; -- -- if (tasklet_trylock(t)) { -- if (!atomic_read(&t->count)) { -- if (!test_and_clear_bit(TASKLET_STATE_SCHED, -- &t->state)) -- BUG(); -- t->func(t->data); -- tasklet_unlock(t); + tasklet_unlock(t); - continue; -- } ++ break; + } - tasklet_unlock(t); -- } + } - - local_irq_disable(); - t->next = NULL; -- *__this_cpu_read(tasklet_hi_vec.tail) = t; -- __this_cpu_write(tasklet_hi_vec.tail, &(t->next)); -- __raise_softirq_irqoff(HI_SOFTIRQ); +- *tl_head->tail = t; +- tl_head->tail = &t->next; +- __raise_softirq_irqoff(softirq_nr); - local_irq_enable(); -- } -+ __tasklet_action(a, list); + } } - void tasklet_init(struct tasklet_struct *t, -@@ -586,7 +652,7 @@ void tasklet_kill(struct tasklet_struct *t) +@@ -563,7 +632,7 @@ void tasklet_kill(struct tasklet_struct while (test_and_set_bit(TASKLET_STATE_SCHED, &t->state)) { do { @@ -353,7 +268,7 @@ index 36092932c532..7f8629d8ee57 100644 } while (test_bit(TASKLET_STATE_SCHED, &t->state)); } tasklet_unlock_wait(t); -@@ -609,6 +675,23 @@ void __init softirq_init(void) +@@ -637,6 +706,23 @@ void __init softirq_init(void) open_softirq(HI_SOFTIRQ, tasklet_hi_action); } @@ -377,6 +292,3 @@ index 36092932c532..7f8629d8ee57 100644 static int ksoftirqd_should_run(unsigned int cpu) { return local_softirq_pending(); --- -2.19.2 - diff --git a/kernel/patches-4.14.x-rt/0231-softirq-Check-preemption-after-reenabling-interrupts.patch b/kernel/patches-4.19.x-rt/0122-softirq-preempt-fix-3-re.patch similarity index 68% rename from kernel/patches-4.14.x-rt/0231-softirq-Check-preemption-after-reenabling-interrupts.patch rename to kernel/patches-4.19.x-rt/0122-softirq-preempt-fix-3-re.patch index ef478aed7..c860215d5 100644 --- a/kernel/patches-4.14.x-rt/0231-softirq-Check-preemption-after-reenabling-interrupts.patch +++ b/kernel/patches-4.19.x-rt/0122-softirq-preempt-fix-3-re.patch @@ -1,7 +1,6 @@ -From 520d969b45300be63d4bb5af9e697edbadfb50f6 Mon Sep 17 00:00:00 2001 +Subject: softirq: Check preemption after reenabling interrupts From: Thomas Gleixner -Date: Sun, 13 Nov 2011 17:17:09 +0100 -Subject: [PATCH 231/450] softirq: Check preemption after reenabling interrupts +Date: Sun, 13 Nov 2011 17:17:09 +0100 (CET) raise_softirq_irqoff() disables interrupts and wakes the softirq daemon, but after reenabling interrupts there is no preemption check, @@ -13,15 +12,14 @@ ones which show this behaviour. Reported-by: Carsten Emde Signed-off-by: Thomas Gleixner + --- - block/blk-softirq.c | 3 +++ - include/linux/preempt.h | 3 +++ - lib/irq_poll.c | 5 +++++ - net/core/dev.c | 7 +++++++ + block/blk-softirq.c | 3 +++ + include/linux/preempt.h | 3 +++ + lib/irq_poll.c | 5 +++++ + net/core/dev.c | 7 +++++++ 4 files changed, 18 insertions(+) -diff --git a/block/blk-softirq.c b/block/blk-softirq.c -index 01e2b353a2b9..e8c0d4945f5a 100644 --- a/block/blk-softirq.c +++ b/block/blk-softirq.c @@ -53,6 +53,7 @@ static void trigger_softirq(void *data) @@ -32,7 +30,7 @@ index 01e2b353a2b9..e8c0d4945f5a 100644 } /* -@@ -91,6 +92,7 @@ static int blk_softirq_cpu_dead(unsigned int cpu) +@@ -91,6 +92,7 @@ static int blk_softirq_cpu_dead(unsigned this_cpu_ptr(&blk_cpu_done)); raise_softirq_irqoff(BLOCK_SOFTIRQ); local_irq_enable(); @@ -40,16 +38,14 @@ index 01e2b353a2b9..e8c0d4945f5a 100644 return 0; } -@@ -143,6 +145,7 @@ void __blk_complete_request(struct request *req) +@@ -143,6 +145,7 @@ void __blk_complete_request(struct reque goto do_local; local_irq_restore(flags); + preempt_check_resched_rt(); } + EXPORT_SYMBOL(__blk_complete_request); - /** -diff --git a/include/linux/preempt.h b/include/linux/preempt.h -index 2d5d002e06c2..a3b19af35e3d 100644 --- a/include/linux/preempt.h +++ b/include/linux/preempt.h @@ -187,8 +187,10 @@ do { \ @@ -71,11 +67,9 @@ index 2d5d002e06c2..a3b19af35e3d 100644 #define preemptible() 0 #define migrate_disable() barrier() -diff --git a/lib/irq_poll.c b/lib/irq_poll.c -index 86a709954f5a..9c069ef83d6d 100644 --- a/lib/irq_poll.c +++ b/lib/irq_poll.c -@@ -37,6 +37,7 @@ void irq_poll_sched(struct irq_poll *iop) +@@ -37,6 +37,7 @@ void irq_poll_sched(struct irq_poll *iop list_add_tail(&iop->list, this_cpu_ptr(&blk_cpu_iopoll)); __raise_softirq_irqoff(IRQ_POLL_SOFTIRQ); local_irq_restore(flags); @@ -83,7 +77,7 @@ index 86a709954f5a..9c069ef83d6d 100644 } EXPORT_SYMBOL(irq_poll_sched); -@@ -72,6 +73,7 @@ void irq_poll_complete(struct irq_poll *iop) +@@ -72,6 +73,7 @@ void irq_poll_complete(struct irq_poll * local_irq_save(flags); __irq_poll_complete(iop); local_irq_restore(flags); @@ -91,7 +85,7 @@ index 86a709954f5a..9c069ef83d6d 100644 } EXPORT_SYMBOL(irq_poll_complete); -@@ -96,6 +98,7 @@ static void __latent_entropy irq_poll_softirq(struct softirq_action *h) +@@ -96,6 +98,7 @@ static void __latent_entropy irq_poll_so } local_irq_enable(); @@ -99,7 +93,7 @@ index 86a709954f5a..9c069ef83d6d 100644 /* Even though interrupts have been re-enabled, this * access is safe because interrupts can only add new -@@ -133,6 +136,7 @@ static void __latent_entropy irq_poll_softirq(struct softirq_action *h) +@@ -133,6 +136,7 @@ static void __latent_entropy irq_poll_so __raise_softirq_irqoff(IRQ_POLL_SOFTIRQ); local_irq_enable(); @@ -107,7 +101,7 @@ index 86a709954f5a..9c069ef83d6d 100644 } /** -@@ -196,6 +200,7 @@ static int irq_poll_cpu_dead(unsigned int cpu) +@@ -196,6 +200,7 @@ static int irq_poll_cpu_dead(unsigned in this_cpu_ptr(&blk_cpu_iopoll)); __raise_softirq_irqoff(IRQ_POLL_SOFTIRQ); local_irq_enable(); @@ -115,11 +109,9 @@ index 86a709954f5a..9c069ef83d6d 100644 return 0; } -diff --git a/net/core/dev.c b/net/core/dev.c -index 4337450a5fdb..49812d1dba8e 100644 --- a/net/core/dev.c +++ b/net/core/dev.c -@@ -2460,6 +2460,7 @@ static void __netif_reschedule(struct Qdisc *q) +@@ -2712,6 +2712,7 @@ static void __netif_reschedule(struct Qd sd->output_queue_tailp = &q->next_sched; raise_softirq_irqoff(NET_TX_SOFTIRQ); local_irq_restore(flags); @@ -127,7 +119,7 @@ index 4337450a5fdb..49812d1dba8e 100644 } void __netif_schedule(struct Qdisc *q) -@@ -2522,6 +2523,7 @@ void __dev_kfree_skb_irq(struct sk_buff *skb, enum skb_free_reason reason) +@@ -2774,6 +2775,7 @@ void __dev_kfree_skb_irq(struct sk_buff __this_cpu_write(softnet_data.completion_queue, skb); raise_softirq_irqoff(NET_TX_SOFTIRQ); local_irq_restore(flags); @@ -135,7 +127,7 @@ index 4337450a5fdb..49812d1dba8e 100644 } EXPORT_SYMBOL(__dev_kfree_skb_irq); -@@ -3904,6 +3906,7 @@ static int enqueue_to_backlog(struct sk_buff *skb, int cpu, +@@ -4246,6 +4248,7 @@ static int enqueue_to_backlog(struct sk_ rps_unlock(sd); local_irq_restore(flags); @@ -143,7 +135,7 @@ index 4337450a5fdb..49812d1dba8e 100644 atomic_long_inc(&skb->dev->rx_dropped); kfree_skb(skb); -@@ -5157,12 +5160,14 @@ static void net_rps_action_and_irq_enable(struct softnet_data *sd) +@@ -5799,12 +5802,14 @@ static void net_rps_action_and_irq_enabl sd->rps_ipi_list = NULL; local_irq_enable(); @@ -158,7 +150,7 @@ index 4337450a5fdb..49812d1dba8e 100644 } static bool sd_has_rps_ipi_waiting(struct softnet_data *sd) -@@ -5240,6 +5245,7 @@ void __napi_schedule(struct napi_struct *n) +@@ -5882,6 +5887,7 @@ void __napi_schedule(struct napi_struct local_irq_save(flags); ____napi_schedule(this_cpu_ptr(&softnet_data), n); local_irq_restore(flags); @@ -166,7 +158,7 @@ index 4337450a5fdb..49812d1dba8e 100644 } EXPORT_SYMBOL(__napi_schedule); -@@ -8446,6 +8452,7 @@ static int dev_cpu_dead(unsigned int oldcpu) +@@ -9289,6 +9295,7 @@ static int dev_cpu_dead(unsigned int old raise_softirq_irqoff(NET_TX_SOFTIRQ); local_irq_enable(); @@ -174,6 +166,3 @@ index 4337450a5fdb..49812d1dba8e 100644 #ifdef CONFIG_RPS remsd = oldsd->rps_ipi_list; --- -2.19.2 - diff --git a/kernel/patches-4.14.x-rt/0232-softirq-Disable-softirq-stacks-for-RT.patch b/kernel/patches-4.19.x-rt/0123-softirq-disable-softirq-stacks-for-rt.patch similarity index 63% rename from kernel/patches-4.14.x-rt/0232-softirq-Disable-softirq-stacks-for-RT.patch rename to kernel/patches-4.19.x-rt/0123-softirq-disable-softirq-stacks-for-rt.patch index 5d4efdf40..0160ba746 100644 --- a/kernel/patches-4.14.x-rt/0232-softirq-Disable-softirq-stacks-for-RT.patch +++ b/kernel/patches-4.19.x-rt/0123-softirq-disable-softirq-stacks-for-rt.patch @@ -1,28 +1,25 @@ -From dc3447f8dfafd632399cef0d395385b1d020b205 Mon Sep 17 00:00:00 2001 +Subject: softirq: Disable softirq stacks for RT From: Thomas Gleixner Date: Mon, 18 Jul 2011 13:59:17 +0200 -Subject: [PATCH 232/450] softirq: Disable softirq stacks for RT Disable extra stacks for softirqs. We want to preempt softirqs and having them on special IRQ-stack does not make this easier. Signed-off-by: Thomas Gleixner --- - arch/powerpc/kernel/irq.c | 2 ++ - arch/powerpc/kernel/misc_32.S | 2 ++ - arch/powerpc/kernel/misc_64.S | 2 ++ - arch/sh/kernel/irq.c | 2 ++ - arch/sparc/kernel/irq_64.c | 2 ++ - arch/x86/entry/entry_64.S | 2 ++ - arch/x86/kernel/irq_32.c | 2 ++ - include/linux/interrupt.h | 2 +- + arch/powerpc/kernel/irq.c | 2 ++ + arch/powerpc/kernel/misc_32.S | 2 ++ + arch/powerpc/kernel/misc_64.S | 2 ++ + arch/sh/kernel/irq.c | 2 ++ + arch/sparc/kernel/irq_64.c | 2 ++ + arch/x86/entry/entry_64.S | 2 ++ + arch/x86/kernel/irq_32.c | 2 ++ + include/linux/interrupt.h | 2 +- 8 files changed, 15 insertions(+), 1 deletion(-) -diff --git a/arch/powerpc/kernel/irq.c b/arch/powerpc/kernel/irq.c -index 0ce8b0e5d7ba..375adb3048fc 100644 --- a/arch/powerpc/kernel/irq.c +++ b/arch/powerpc/kernel/irq.c -@@ -693,6 +693,7 @@ void irq_ctx_init(void) +@@ -766,6 +766,7 @@ void irq_ctx_init(void) } } @@ -30,7 +27,7 @@ index 0ce8b0e5d7ba..375adb3048fc 100644 void do_softirq_own_stack(void) { struct thread_info *curtp, *irqtp; -@@ -710,6 +711,7 @@ void do_softirq_own_stack(void) +@@ -783,6 +784,7 @@ void do_softirq_own_stack(void) if (irqtp->flags) set_bits(irqtp->flags, &curtp->flags); } @@ -38,11 +35,9 @@ index 0ce8b0e5d7ba..375adb3048fc 100644 irq_hw_number_t virq_to_hw(unsigned int virq) { -diff --git a/arch/powerpc/kernel/misc_32.S b/arch/powerpc/kernel/misc_32.S -index 3f7a9a2d2435..1795359d27b6 100644 --- a/arch/powerpc/kernel/misc_32.S +++ b/arch/powerpc/kernel/misc_32.S -@@ -41,6 +41,7 @@ +@@ -42,6 +42,7 @@ * We store the saved ksp_limit in the unused part * of the STACK_FRAME_OVERHEAD */ @@ -50,7 +45,7 @@ index 3f7a9a2d2435..1795359d27b6 100644 _GLOBAL(call_do_softirq) mflr r0 stw r0,4(r1) -@@ -57,6 +58,7 @@ _GLOBAL(call_do_softirq) +@@ -58,6 +59,7 @@ stw r10,THREAD+KSP_LIMIT(r2) mtlr r0 blr @@ -58,11 +53,9 @@ index 3f7a9a2d2435..1795359d27b6 100644 /* * void call_do_irq(struct pt_regs *regs, struct thread_info *irqtp); -diff --git a/arch/powerpc/kernel/misc_64.S b/arch/powerpc/kernel/misc_64.S -index 3280953a82cf..dd2a80d190c4 100644 --- a/arch/powerpc/kernel/misc_64.S +++ b/arch/powerpc/kernel/misc_64.S -@@ -31,6 +31,7 @@ +@@ -32,6 +32,7 @@ .text @@ -70,7 +63,7 @@ index 3280953a82cf..dd2a80d190c4 100644 _GLOBAL(call_do_softirq) mflr r0 std r0,16(r1) -@@ -41,6 +42,7 @@ _GLOBAL(call_do_softirq) +@@ -42,6 +43,7 @@ ld r0,16(r1) mtlr r0 blr @@ -78,8 +71,6 @@ index 3280953a82cf..dd2a80d190c4 100644 _GLOBAL(call_do_irq) mflr r0 -diff --git a/arch/sh/kernel/irq.c b/arch/sh/kernel/irq.c -index 245dbeb20afe..e298c82d2a69 100644 --- a/arch/sh/kernel/irq.c +++ b/arch/sh/kernel/irq.c @@ -148,6 +148,7 @@ void irq_ctx_exit(int cpu) @@ -98,11 +89,9 @@ index 245dbeb20afe..e298c82d2a69 100644 #else static inline void handle_one_irq(unsigned int irq) { -diff --git a/arch/sparc/kernel/irq_64.c b/arch/sparc/kernel/irq_64.c -index d66dde833f5e..f87b3f8f4d43 100644 --- a/arch/sparc/kernel/irq_64.c +++ b/arch/sparc/kernel/irq_64.c -@@ -855,6 +855,7 @@ void __irq_entry handler_irq(int pil, struct pt_regs *regs) +@@ -854,6 +854,7 @@ void __irq_entry handler_irq(int pil, st set_irq_regs(old_regs); } @@ -110,7 +99,7 @@ index d66dde833f5e..f87b3f8f4d43 100644 void do_softirq_own_stack(void) { void *orig_sp, *sp = softirq_stack[smp_processor_id()]; -@@ -869,6 +870,7 @@ void do_softirq_own_stack(void) +@@ -868,6 +869,7 @@ void do_softirq_own_stack(void) __asm__ __volatile__("mov %0, %%sp" : : "r" (orig_sp)); } @@ -118,11 +107,9 @@ index d66dde833f5e..f87b3f8f4d43 100644 #ifdef CONFIG_HOTPLUG_CPU void fixup_irqs(void) -diff --git a/arch/x86/entry/entry_64.S b/arch/x86/entry/entry_64.S -index 164cd7529f0b..8192e87963b5 100644 --- a/arch/x86/entry/entry_64.S +++ b/arch/x86/entry/entry_64.S -@@ -988,6 +988,7 @@ bad_gs: +@@ -1039,6 +1039,7 @@ EXPORT_SYMBOL(native_load_gs_index) jmp 2b .previous @@ -130,7 +117,7 @@ index 164cd7529f0b..8192e87963b5 100644 /* Call softirq on interrupt stack. Interrupts are off. */ ENTRY(do_softirq_own_stack) pushq %rbp -@@ -998,6 +999,7 @@ ENTRY(do_softirq_own_stack) +@@ -1049,6 +1050,7 @@ ENTRY(do_softirq_own_stack) leaveq ret ENDPROC(do_softirq_own_stack) @@ -138,8 +125,6 @@ index 164cd7529f0b..8192e87963b5 100644 #ifdef CONFIG_XEN idtentry hypervisor_callback xen_do_hypervisor_callback has_error_code=0 -diff --git a/arch/x86/kernel/irq_32.c b/arch/x86/kernel/irq_32.c -index 95600a99ae93..9192d76085ba 100644 --- a/arch/x86/kernel/irq_32.c +++ b/arch/x86/kernel/irq_32.c @@ -130,6 +130,7 @@ void irq_ctx_init(int cpu) @@ -158,11 +143,9 @@ index 95600a99ae93..9192d76085ba 100644 bool handle_irq(struct irq_desc *desc, struct pt_regs *regs) { -diff --git a/include/linux/interrupt.h b/include/linux/interrupt.h -index e53ff6a143e0..c77f7a9ba836 100644 --- a/include/linux/interrupt.h +++ b/include/linux/interrupt.h -@@ -501,7 +501,7 @@ struct softirq_action +@@ -506,7 +506,7 @@ struct softirq_action asmlinkage void do_softirq(void); asmlinkage void __do_softirq(void); @@ -171,6 +154,3 @@ index e53ff6a143e0..c77f7a9ba836 100644 void do_softirq_own_stack(void); #else static inline void do_softirq_own_stack(void) --- -2.19.2 - diff --git a/kernel/patches-4.14.x-rt/0233-softirq-Split-softirq-locks.patch b/kernel/patches-4.19.x-rt/0124-softirq-split-locks.patch similarity index 85% rename from kernel/patches-4.14.x-rt/0233-softirq-Split-softirq-locks.patch rename to kernel/patches-4.19.x-rt/0124-softirq-split-locks.patch index be95c4fbb..fe46eb113 100644 --- a/kernel/patches-4.14.x-rt/0233-softirq-Split-softirq-locks.patch +++ b/kernel/patches-4.19.x-rt/0124-softirq-split-locks.patch @@ -1,7 +1,6 @@ -From caa51304cafba2c42f71347845f0d7f3aa7f32a7 Mon Sep 17 00:00:00 2001 From: Thomas Gleixner -Date: Thu, 4 Oct 2012 14:20:47 +0100 -Subject: [PATCH 233/450] softirq: Split softirq locks +Date: Thu, 04 Oct 2012 14:20:47 +0100 +Subject: softirq: Split softirq locks The 3.x RT series removed the split softirq implementation in favour of pushing softirq processing into the context of the thread which @@ -25,18 +24,15 @@ threads. Signed-off-by: Thomas Gleixner --- - include/linux/bottom_half.h | 34 +++ - include/linux/interrupt.h | 15 +- - include/linux/preempt.h | 15 +- - include/linux/sched.h | 3 + - init/main.c | 1 + - kernel/softirq.c | 492 ++++++++++++++++++++++++++++++------ - kernel/time/tick-sched.c | 9 +- - net/core/dev.c | 6 +- - 8 files changed, 480 insertions(+), 95 deletions(-) + include/linux/bottom_half.h | 34 +++ + include/linux/interrupt.h | 15 + + include/linux/preempt.h | 15 + + include/linux/sched.h | 3 + init/main.c | 1 + kernel/softirq.c | 491 +++++++++++++++++++++++++++++++++++++------- + kernel/time/tick-sched.c | 9 + 7 files changed, 478 insertions(+), 90 deletions(-) -diff --git a/include/linux/bottom_half.h b/include/linux/bottom_half.h -index a19519f4241d..40dd5ef9c154 100644 --- a/include/linux/bottom_half.h +++ b/include/linux/bottom_half.h @@ -4,6 +4,39 @@ @@ -86,11 +82,9 @@ index a19519f4241d..40dd5ef9c154 100644 +#endif #endif /* _LINUX_BH_H */ -diff --git a/include/linux/interrupt.h b/include/linux/interrupt.h -index c77f7a9ba836..0003b88de96f 100644 --- a/include/linux/interrupt.h +++ b/include/linux/interrupt.h -@@ -498,10 +498,11 @@ struct softirq_action +@@ -503,10 +503,11 @@ struct softirq_action void (*action)(struct softirq_action *); }; @@ -104,7 +98,7 @@ index c77f7a9ba836..0003b88de96f 100644 void do_softirq_own_stack(void); #else static inline void do_softirq_own_stack(void) -@@ -509,6 +510,9 @@ static inline void do_softirq_own_stack(void) +@@ -514,6 +515,9 @@ static inline void do_softirq_own_stack( __do_softirq(); } #endif @@ -114,7 +108,7 @@ index c77f7a9ba836..0003b88de96f 100644 extern void open_softirq(int nr, void (*action)(struct softirq_action *)); extern void softirq_init(void); -@@ -516,6 +520,7 @@ extern void __raise_softirq_irqoff(unsigned int nr); +@@ -521,6 +525,7 @@ extern void __raise_softirq_irqoff(unsig extern void raise_softirq_irqoff(unsigned int nr); extern void raise_softirq(unsigned int nr); @@ -122,7 +116,7 @@ index c77f7a9ba836..0003b88de96f 100644 DECLARE_PER_CPU(struct task_struct *, ksoftirqd); -@@ -633,6 +638,12 @@ extern void tasklet_kill_immediate(struct tasklet_struct *t, unsigned int cpu); +@@ -638,6 +643,12 @@ extern void tasklet_kill_immediate(struc extern void tasklet_init(struct tasklet_struct *t, void (*func)(unsigned long), unsigned long data); @@ -132,11 +126,9 @@ index c77f7a9ba836..0003b88de96f 100644 +static inline void softirq_early_init(void) { } +#endif + - /* - * Autoprobing for irqs: - * -diff --git a/include/linux/preempt.h b/include/linux/preempt.h -index a3b19af35e3d..2983043d2194 100644 + struct tasklet_hrtimer { + struct hrtimer timer; + struct tasklet_struct tasklet; --- a/include/linux/preempt.h +++ b/include/linux/preempt.h @@ -51,7 +51,11 @@ @@ -163,7 +155,7 @@ index a3b19af35e3d..2983043d2194 100644 +# define softirq_count() (preempt_count() & SOFTIRQ_MASK) +# define in_serving_softirq() (softirq_count() & SOFTIRQ_OFFSET) +#else -+# define softirq_count() (0UL) ++# define softirq_count() ((unsigned long)current->softirq_nestcnt) +extern int in_serving_softirq(void); +#endif @@ -177,11 +169,9 @@ index a3b19af35e3d..2983043d2194 100644 #define in_nmi() (preempt_count() & NMI_MASK) #define in_task() (!(preempt_count() & \ (NMI_MASK | HARDIRQ_MASK | SOFTIRQ_OFFSET))) -diff --git a/include/linux/sched.h b/include/linux/sched.h -index ea110a4dea9b..ee6f6d3501de 100644 --- a/include/linux/sched.h +++ b/include/linux/sched.h -@@ -1136,6 +1136,8 @@ struct task_struct { +@@ -1190,6 +1190,8 @@ struct task_struct { #endif #ifdef CONFIG_PREEMPT_RT_BASE struct rcu_head put_rcu; @@ -190,7 +180,7 @@ index ea110a4dea9b..ee6f6d3501de 100644 #endif #ifdef CONFIG_DEBUG_ATOMIC_SLEEP unsigned long task_state_change; -@@ -1353,6 +1355,7 @@ extern struct pid *cad_pid; +@@ -1387,6 +1389,7 @@ extern struct pid *cad_pid; /* * Per process flags */ @@ -198,11 +188,9 @@ index ea110a4dea9b..ee6f6d3501de 100644 #define PF_IDLE 0x00000002 /* I am an IDLE thread */ #define PF_EXITING 0x00000004 /* Getting shut down */ #define PF_EXITPIDONE 0x00000008 /* PI exit done on shut down */ -diff --git a/init/main.c b/init/main.c -index c4a45145e102..c86f3d3b9a72 100644 --- a/init/main.c +++ b/init/main.c -@@ -543,6 +543,7 @@ asmlinkage __visible void __init start_kernel(void) +@@ -561,6 +561,7 @@ asmlinkage __visible void __init start_k setup_command_line(command_line); setup_nr_cpu_ids(); setup_per_cpu_areas(); @@ -210,19 +198,19 @@ index c4a45145e102..c86f3d3b9a72 100644 smp_prepare_boot_cpu(); /* arch-specific boot-cpu hooks */ boot_cpu_hotplug_init(); -diff --git a/kernel/softirq.c b/kernel/softirq.c -index 7f8629d8ee57..92fbc06bce6f 100644 --- a/kernel/softirq.c +++ b/kernel/softirq.c -@@ -26,6 +26,7 @@ +@@ -26,7 +26,9 @@ #include #include #include +#include #include ++#include #define CREATE_TRACE_POINTS -@@ -63,6 +64,98 @@ const char * const softirq_to_name[NR_SOFTIRQS] = { + #include +@@ -63,6 +65,98 @@ const char * const softirq_to_name[NR_SO "TASKLET", "SCHED", "HRTIMER", "RCU" }; @@ -304,7 +292,7 @@ index 7f8629d8ee57..92fbc06bce6f 100644 +{ + static int rate_limit; + -+ if (rate_limit < 10 && !in_softirq() && ++ if (rate_limit < 10 && + (local_softirq_pending() & SOFTIRQ_STOP_IDLE_MASK)) { + printk(KERN_ERR "NOHZ: local_softirq_pending %02x\n", + local_softirq_pending()); @@ -321,7 +309,7 @@ index 7f8629d8ee57..92fbc06bce6f 100644 /* * we cannot loop indefinitely here to avoid userspace starvation, * but we also don't want to introduce a worst case 1/HZ latency -@@ -78,6 +171,26 @@ static void wakeup_softirqd(void) +@@ -78,6 +172,27 @@ static void wakeup_softirqd(void) wake_up_process(tsk); } @@ -345,14 +333,14 @@ index 7f8629d8ee57..92fbc06bce6f 100644 + } +} + ++#ifndef CONFIG_PREEMPT_RT_FULL /* * If ksoftirqd is scheduled, we do not want to process pending softirqs * right now. Let ksoftirqd handle this at its own rate, to get fairness, -@@ -93,6 +206,48 @@ static bool ksoftirqd_running(unsigned long pending) +@@ -93,6 +208,47 @@ static bool ksoftirqd_running(unsigned l return tsk && (tsk->state == TASK_RUNNING); } -+#ifndef CONFIG_PREEMPT_RT_FULL +static inline int ksoftirqd_softirq_pending(void) +{ + return local_softirq_pending(); @@ -388,7 +376,7 @@ index 7f8629d8ee57..92fbc06bce6f 100644 + if (ksoftirqd_softirq_pending()) { + __do_softirq(); + local_irq_enable(); -+ cond_resched_rcu_qs(); ++ cond_resched(); + return; + } + local_irq_enable(); @@ -397,7 +385,7 @@ index 7f8629d8ee57..92fbc06bce6f 100644 /* * preempt_count and SOFTIRQ_OFFSET usage: * - preempt_count is changed by SOFTIRQ_OFFSET on entering or leaving -@@ -248,10 +403,8 @@ asmlinkage __visible void __softirq_entry __do_softirq(void) +@@ -252,10 +408,8 @@ asmlinkage __visible void __softirq_entr unsigned long end = jiffies + MAX_SOFTIRQ_TIME; unsigned long old_flags = current->flags; int max_restart = MAX_SOFTIRQ_RESTART; @@ -408,7 +396,7 @@ index 7f8629d8ee57..92fbc06bce6f 100644 /* * Mask out PF_MEMALLOC s current task context is borrowed for the -@@ -270,36 +423,7 @@ asmlinkage __visible void __softirq_entry __do_softirq(void) +@@ -274,36 +428,7 @@ asmlinkage __visible void __softirq_entr /* Reset the pending bitmask before enabling irqs */ set_softirq_pending(0); @@ -446,11 +434,10 @@ index 7f8629d8ee57..92fbc06bce6f 100644 pending = local_softirq_pending(); if (pending) { -@@ -335,6 +459,246 @@ asmlinkage __visible void do_softirq(void) - local_irq_restore(flags); +@@ -340,6 +465,248 @@ asmlinkage __visible void do_softirq(voi } -+/* + /* + * This function must run with irqs disabled! + */ +void raise_softirq_irqoff(unsigned int nr) @@ -555,8 +542,10 @@ index 7f8629d8ee57..92fbc06bce6f 100644 + do_single_softirq(i); + } + softirq_clr_runner(i); -+ unlock_softirq(i); + WARN_ON(current->softirq_nestcnt != 1); ++ local_irq_enable(); ++ unlock_softirq(i); ++ local_irq_disable(); + } +} + @@ -597,7 +586,7 @@ index 7f8629d8ee57..92fbc06bce6f 100644 + do_current_softirqs(); + current->softirq_nestcnt--; + local_irq_enable(); -+ cond_resched_rcu_qs(); ++ cond_resched(); +} + +/* @@ -690,10 +679,11 @@ index 7f8629d8ee57..92fbc06bce6f 100644 +} + +#endif /* PREEMPT_RT_FULL */ - /* ++/* * Enter an interrupt context. */ -@@ -346,9 +710,9 @@ void irq_enter(void) + void irq_enter(void) +@@ -350,9 +717,9 @@ void irq_enter(void) * Prevent raise_softirq from needlessly waking up ksoftirqd * here, as softirq will be serviced on return from interrupt. */ @@ -705,26 +695,20 @@ index 7f8629d8ee57..92fbc06bce6f 100644 } __irq_enter(); -@@ -356,9 +720,13 @@ void irq_enter(void) +@@ -360,6 +727,7 @@ void irq_enter(void) static inline void invoke_softirq(void) { -+#ifdef CONFIG_PREEMPT_RT_FULL -+ unsigned long flags; -+#endif -+ ++#ifndef CONFIG_PREEMPT_RT_FULL if (ksoftirqd_running(local_softirq_pending())) return; -- -+#ifndef CONFIG_PREEMPT_RT_FULL - if (!force_irqthreads) { - #ifdef CONFIG_HAVE_IRQ_EXIT_ON_IRQ_STACK - /* -@@ -378,6 +746,14 @@ static inline void invoke_softirq(void) + +@@ -382,6 +750,15 @@ static inline void invoke_softirq(void) } else { wakeup_softirqd(); } +#else /* PREEMPT_RT_FULL */ ++ unsigned long flags; + + local_irq_save(flags); + if (__this_cpu_read(ksoftirqd) && @@ -735,7 +719,7 @@ index 7f8629d8ee57..92fbc06bce6f 100644 } static inline void tick_irq_exit(void) -@@ -420,26 +796,6 @@ void irq_exit(void) +@@ -417,26 +794,6 @@ void irq_exit(void) trace_hardirq_exit(); /* must be last! */ } @@ -762,7 +746,7 @@ index 7f8629d8ee57..92fbc06bce6f 100644 void raise_softirq(unsigned int nr) { unsigned long flags; -@@ -449,12 +805,6 @@ void raise_softirq(unsigned int nr) +@@ -446,12 +803,6 @@ void raise_softirq(unsigned int nr) local_irq_restore(flags); } @@ -775,7 +759,7 @@ index 7f8629d8ee57..92fbc06bce6f 100644 void open_softirq(int nr, void (*action)(struct softirq_action *)) { softirq_vec[nr].action = action; -@@ -694,23 +1044,7 @@ EXPORT_SYMBOL(tasklet_unlock_wait); +@@ -725,23 +1076,7 @@ EXPORT_SYMBOL(tasklet_unlock_wait); static int ksoftirqd_should_run(unsigned int cpu) { @@ -792,7 +776,7 @@ index 7f8629d8ee57..92fbc06bce6f 100644 - */ - __do_softirq(); - local_irq_enable(); -- cond_resched_rcu_qs(); +- cond_resched(); - return; - } - local_irq_enable(); @@ -800,7 +784,7 @@ index 7f8629d8ee57..92fbc06bce6f 100644 } #ifdef CONFIG_HOTPLUG_CPU -@@ -777,6 +1111,8 @@ static int takeover_tasklets(unsigned int cpu) +@@ -808,6 +1143,8 @@ static int takeover_tasklets(unsigned in static struct smp_hotplug_thread softirq_threads = { .store = &ksoftirqd, @@ -809,17 +793,15 @@ index 7f8629d8ee57..92fbc06bce6f 100644 .thread_should_run = ksoftirqd_should_run, .thread_fn = run_ksoftirqd, .thread_comm = "ksoftirqd/%u", -diff --git a/kernel/time/tick-sched.c b/kernel/time/tick-sched.c -index c21fd6a16870..92222682dfce 100644 --- a/kernel/time/tick-sched.c +++ b/kernel/time/tick-sched.c -@@ -911,14 +911,7 @@ static bool can_stop_idle_tick(int cpu, struct tick_sched *ts) +@@ -891,14 +891,7 @@ static bool can_stop_idle_tick(int cpu, return false; if (unlikely(local_softirq_pending() && cpu_online(cpu))) { - static int ratelimit; - -- if (ratelimit < 10 && !in_softirq() && +- if (ratelimit < 10 && - (local_softirq_pending() & SOFTIRQ_STOP_IDLE_MASK)) { - pr_warn("NOHZ: local_softirq_pending %02x\n", - (unsigned int) local_softirq_pending()); @@ -829,24 +811,3 @@ index c21fd6a16870..92222682dfce 100644 return false; } -diff --git a/net/core/dev.c b/net/core/dev.c -index 49812d1dba8e..8972786d17de 100644 ---- a/net/core/dev.c -+++ b/net/core/dev.c -@@ -4110,11 +4110,9 @@ int netif_rx_ni(struct sk_buff *skb) - - trace_netif_rx_ni_entry(skb); - -- preempt_disable(); -+ local_bh_disable(); - err = netif_rx_internal(skb); -- if (local_softirq_pending()) -- do_softirq(); -- preempt_enable(); -+ local_bh_enable(); - - return err; - } --- -2.19.2 - diff --git a/kernel/patches-4.19.x-rt/0125-net-core-use-local_bh_disable-in-netif_rx_ni.patch b/kernel/patches-4.19.x-rt/0125-net-core-use-local_bh_disable-in-netif_rx_ni.patch new file mode 100644 index 000000000..422a6251d --- /dev/null +++ b/kernel/patches-4.19.x-rt/0125-net-core-use-local_bh_disable-in-netif_rx_ni.patch @@ -0,0 +1,34 @@ +From: Sebastian Andrzej Siewior +Date: Fri, 16 Jun 2017 19:03:16 +0200 +Subject: [PATCH] net/core: use local_bh_disable() in netif_rx_ni() + +In 2004 netif_rx_ni() gained a preempt_disable() section around +netif_rx() and its do_softirq() + testing for it. The do_softirq() part +is required because netif_rx() raises the softirq but does not invoke +it. The preempt_disable() is required to remain on the same CPU which added the +skb to the per-CPU list. +All this can be avoided be putting this into a local_bh_disable()ed +section. The local_bh_enable() part will invoke do_softirq() if +required. + +Signed-off-by: Sebastian Andrzej Siewior +--- + net/core/dev.c | 6 ++---- + 1 file changed, 2 insertions(+), 4 deletions(-) + +--- a/net/core/dev.c ++++ b/net/core/dev.c +@@ -4512,11 +4512,9 @@ int netif_rx_ni(struct sk_buff *skb) + + trace_netif_rx_ni_entry(skb); + +- preempt_disable(); ++ local_bh_disable(); + err = netif_rx_internal(skb); +- if (local_softirq_pending()) +- do_softirq(); +- preempt_enable(); ++ local_bh_enable(); + + return err; + } diff --git a/kernel/patches-4.14.x-rt/0235-genirq-Allow-disabling-of-softirq-processing-in-irq-.patch b/kernel/patches-4.19.x-rt/0126-irq-allow-disabling-of-softirq-processing-in-irq-thread-context.patch similarity index 75% rename from kernel/patches-4.14.x-rt/0235-genirq-Allow-disabling-of-softirq-processing-in-irq-.patch rename to kernel/patches-4.19.x-rt/0126-irq-allow-disabling-of-softirq-processing-in-irq-thread-context.patch index 5658439ba..9d490d7cb 100644 --- a/kernel/patches-4.14.x-rt/0235-genirq-Allow-disabling-of-softirq-processing-in-irq-.patch +++ b/kernel/patches-4.19.x-rt/0126-irq-allow-disabling-of-softirq-processing-in-irq-thread-context.patch @@ -1,8 +1,6 @@ -From c06fca93b5e4b5e39b98319fe5febfe78ab7b5a0 Mon Sep 17 00:00:00 2001 +Subject: genirq: Allow disabling of softirq processing in irq thread context From: Thomas Gleixner Date: Tue, 31 Jan 2012 13:01:27 +0100 -Subject: [PATCH 235/450] genirq: Allow disabling of softirq processing in irq - thread context The processing of softirqs in irq thread context is a performance gain for the non-rt workloads of a system, but it's counterproductive for @@ -11,19 +9,18 @@ workload. Allow such interrupts to prevent softirq processing in their thread context. Signed-off-by: Thomas Gleixner + --- - include/linux/interrupt.h | 2 ++ - include/linux/irq.h | 4 +++- - kernel/irq/manage.c | 13 ++++++++++++- - kernel/irq/settings.h | 12 ++++++++++++ - kernel/softirq.c | 9 +++++++++ + include/linux/interrupt.h | 2 ++ + include/linux/irq.h | 4 +++- + kernel/irq/manage.c | 13 ++++++++++++- + kernel/irq/settings.h | 12 ++++++++++++ + kernel/softirq.c | 9 +++++++++ 5 files changed, 38 insertions(+), 2 deletions(-) -diff --git a/include/linux/interrupt.h b/include/linux/interrupt.h -index 0003b88de96f..326af722c5ee 100644 --- a/include/linux/interrupt.h +++ b/include/linux/interrupt.h -@@ -64,6 +64,7 @@ +@@ -62,6 +62,7 @@ * interrupt handler after suspending interrupts. For system * wakeup devices users need to implement wakeup detection in * their interrupt handlers. @@ -31,7 +28,7 @@ index 0003b88de96f..326af722c5ee 100644 */ #define IRQF_SHARED 0x00000080 #define IRQF_PROBE_SHARED 0x00000100 -@@ -77,6 +78,7 @@ +@@ -75,6 +76,7 @@ #define IRQF_NO_THREAD 0x00010000 #define IRQF_EARLY_RESUME 0x00020000 #define IRQF_COND_SUSPEND 0x00040000 @@ -39,11 +36,9 @@ index 0003b88de96f..326af722c5ee 100644 #define IRQF_TIMER (__IRQF_TIMER | IRQF_NO_SUSPEND | IRQF_NO_THREAD) -diff --git a/include/linux/irq.h b/include/linux/irq.h -index 0d53626405bf..ddd23c6e2e55 100644 --- a/include/linux/irq.h +++ b/include/linux/irq.h -@@ -74,6 +74,7 @@ enum irqchip_irq_state; +@@ -69,6 +69,7 @@ enum irqchip_irq_state; * IRQ_IS_POLLED - Always polled by another interrupt. Exclude * it from the spurious interrupt detection * mechanism and from core side polling. @@ -51,7 +46,7 @@ index 0d53626405bf..ddd23c6e2e55 100644 * IRQ_DISABLE_UNLAZY - Disable lazy irq disable */ enum { -@@ -101,13 +102,14 @@ enum { +@@ -96,13 +97,14 @@ enum { IRQ_PER_CPU_DEVID = (1 << 17), IRQ_IS_POLLED = (1 << 18), IRQ_DISABLE_UNLAZY = (1 << 19), @@ -67,11 +62,9 @@ index 0d53626405bf..ddd23c6e2e55 100644 #define IRQ_NO_BALANCING_MASK (IRQ_PER_CPU | IRQ_NO_BALANCING) -diff --git a/kernel/irq/manage.c b/kernel/irq/manage.c -index ead9da12c26a..d4d993c27ac0 100644 --- a/kernel/irq/manage.c +++ b/kernel/irq/manage.c -@@ -925,7 +925,15 @@ irq_forced_thread_fn(struct irq_desc *desc, struct irqaction *action) +@@ -970,7 +970,15 @@ irq_forced_thread_fn(struct irq_desc *de atomic_inc(&desc->threads_handled); irq_finalize_oneshot(desc, action); @@ -88,7 +81,7 @@ index ead9da12c26a..d4d993c27ac0 100644 return ret; } -@@ -1421,6 +1429,9 @@ __setup_irq(unsigned int irq, struct irq_desc *desc, struct irqaction *new) +@@ -1480,6 +1488,9 @@ static int irqd_set(&desc->irq_data, IRQD_NO_BALANCING); } @@ -98,8 +91,6 @@ index ead9da12c26a..d4d993c27ac0 100644 if (irq_settings_can_autoenable(desc)) { irq_startup(desc, IRQ_RESEND, IRQ_START_COND); } else { -diff --git a/kernel/irq/settings.h b/kernel/irq/settings.h -index e43795cd2ccf..47e2f9e23586 100644 --- a/kernel/irq/settings.h +++ b/kernel/irq/settings.h @@ -17,6 +17,7 @@ enum { @@ -118,7 +109,7 @@ index e43795cd2ccf..47e2f9e23586 100644 #undef IRQF_MODIFY_MASK #define IRQF_MODIFY_MASK GOT_YOU_MORON -@@ -41,6 +43,16 @@ irq_settings_clr_and_set(struct irq_desc *desc, u32 clr, u32 set) +@@ -41,6 +43,16 @@ irq_settings_clr_and_set(struct irq_desc desc->status_use_accessors |= (set & _IRQF_MODIFY_MASK); } @@ -135,11 +126,9 @@ index e43795cd2ccf..47e2f9e23586 100644 static inline bool irq_settings_is_per_cpu(struct irq_desc *desc) { return desc->status_use_accessors & _IRQ_PER_CPU; -diff --git a/kernel/softirq.c b/kernel/softirq.c -index 9b56981ccc8d..5650395b8d6a 100644 --- a/kernel/softirq.c +++ b/kernel/softirq.c -@@ -593,6 +593,15 @@ void __local_bh_enable(void) +@@ -598,6 +598,15 @@ void __local_bh_enable(void) } EXPORT_SYMBOL(__local_bh_enable); @@ -155,6 +144,3 @@ index 9b56981ccc8d..5650395b8d6a 100644 int in_serving_softirq(void) { return current->flags & PF_IN_SOFTIRQ; --- -2.19.2 - diff --git a/kernel/patches-4.14.x-rt/0236-softirq-split-timer-softirqs-out-of-ksoftirqd.patch b/kernel/patches-4.19.x-rt/0127-softirq-split-timer-softirqs-out-of-ksoftirqd.patch similarity index 86% rename from kernel/patches-4.14.x-rt/0236-softirq-split-timer-softirqs-out-of-ksoftirqd.patch rename to kernel/patches-4.19.x-rt/0127-softirq-split-timer-softirqs-out-of-ksoftirqd.patch index 9d4db5313..9ffce3fc6 100644 --- a/kernel/patches-4.14.x-rt/0236-softirq-split-timer-softirqs-out-of-ksoftirqd.patch +++ b/kernel/patches-4.19.x-rt/0127-softirq-split-timer-softirqs-out-of-ksoftirqd.patch @@ -1,7 +1,6 @@ -From 6683d5da8223ddf11782866fce26ff38e56da578 Mon Sep 17 00:00:00 2001 From: Sebastian Andrzej Siewior Date: Wed, 20 Jan 2016 16:34:17 +0100 -Subject: [PATCH 236/450] softirq: split timer softirqs out of ksoftirqd +Subject: softirq: split timer softirqs out of ksoftirqd The softirqd runs in -RT with SCHED_FIFO (prio 1) and deals mostly with timer wakeup which can not happen in hardirq context. The prio has been @@ -23,14 +22,12 @@ SCHED_OTHER priority and it won't defer RCU anymore. Cc: stable-rt@vger.kernel.org Signed-off-by: Sebastian Andrzej Siewior --- - kernel/softirq.c | 85 +++++++++++++++++++++++++++++++++++++++++------- + kernel/softirq.c | 85 +++++++++++++++++++++++++++++++++++++++++++++++-------- 1 file changed, 73 insertions(+), 12 deletions(-) -diff --git a/kernel/softirq.c b/kernel/softirq.c -index 5650395b8d6a..ff8471aa1c0b 100644 --- a/kernel/softirq.c +++ b/kernel/softirq.c -@@ -58,6 +58,10 @@ EXPORT_SYMBOL(irq_stat); +@@ -59,6 +59,10 @@ EXPORT_PER_CPU_SYMBOL(irq_stat); static struct softirq_action softirq_vec[NR_SOFTIRQS] __cacheline_aligned_in_smp; DEFINE_PER_CPU(struct task_struct *, ksoftirqd); @@ -41,7 +38,7 @@ index 5650395b8d6a..ff8471aa1c0b 100644 const char * const softirq_to_name[NR_SOFTIRQS] = { "HI", "TIMER", "NET_TX", "NET_RX", "BLOCK", "IRQ_POLL", -@@ -171,6 +175,17 @@ static void wakeup_softirqd(void) +@@ -172,6 +176,17 @@ static void wakeup_softirqd(void) wake_up_process(tsk); } @@ -59,7 +56,7 @@ index 5650395b8d6a..ff8471aa1c0b 100644 static void handle_softirq(unsigned int vec_nr) { struct softirq_action *h = softirq_vec + vec_nr; -@@ -488,7 +503,6 @@ void __raise_softirq_irqoff(unsigned int nr) +@@ -493,7 +508,6 @@ void __raise_softirq_irqoff(unsigned int static inline void local_bh_disable_nort(void) { local_bh_disable(); } static inline void _local_bh_enable_nort(void) { _local_bh_enable(); } static void ksoftirqd_set_sched_params(unsigned int cpu) { } @@ -67,7 +64,7 @@ index 5650395b8d6a..ff8471aa1c0b 100644 #else /* !PREEMPT_RT_FULL */ -@@ -635,8 +649,12 @@ void thread_do_softirq(void) +@@ -640,8 +654,12 @@ void thread_do_softirq(void) static void do_raise_softirq_irqoff(unsigned int nr) { @@ -81,7 +78,7 @@ index 5650395b8d6a..ff8471aa1c0b 100644 /* * If we are not in a hard interrupt and inside a bh disabled -@@ -645,16 +663,29 @@ static void do_raise_softirq_irqoff(unsigned int nr) +@@ -650,16 +668,29 @@ static void do_raise_softirq_irqoff(unsi * delegate it to ksoftirqd. */ if (!in_irq() && current->softirq_nestcnt) @@ -115,7 +112,7 @@ index 5650395b8d6a..ff8471aa1c0b 100644 } /* -@@ -680,7 +711,7 @@ void raise_softirq_irqoff(unsigned int nr) +@@ -685,7 +716,7 @@ void raise_softirq_irqoff(unsigned int n * raise a WARN() if the condition is met. */ if (!current->softirq_nestcnt) @@ -124,11 +121,10 @@ index 5650395b8d6a..ff8471aa1c0b 100644 } static inline int ksoftirqd_softirq_pending(void) -@@ -692,23 +723,38 @@ static inline void local_bh_disable_nort(void) { } - static inline void _local_bh_enable_nort(void) { } +@@ -698,22 +729,37 @@ static inline void _local_bh_enable_nort static inline void ksoftirqd_set_sched_params(unsigned int cpu) -+{ + { + /* Take over all but timer pending softirqs when starting */ + local_irq_disable(); + current->softirqs_raised = local_softirq_pending() & ~TIMER_SOFTIRQS; @@ -136,7 +132,7 @@ index 5650395b8d6a..ff8471aa1c0b 100644 +} + +static inline void ktimer_softirqd_set_sched_params(unsigned int cpu) - { ++{ struct sched_param param = { .sched_priority = 1 }; sched_setscheduler(current, SCHED_FIFO, ¶m); @@ -166,7 +162,7 @@ index 5650395b8d6a..ff8471aa1c0b 100644 #endif /* PREEMPT_RT_FULL */ /* * Enter an interrupt context. -@@ -763,6 +809,9 @@ static inline void invoke_softirq(void) +@@ -766,6 +812,9 @@ static inline void invoke_softirq(void) if (__this_cpu_read(ksoftirqd) && __this_cpu_read(ksoftirqd)->softirqs_raised) wakeup_softirqd(); @@ -176,7 +172,7 @@ index 5650395b8d6a..ff8471aa1c0b 100644 local_irq_restore(flags); #endif } -@@ -1123,18 +1172,30 @@ static int takeover_tasklets(unsigned int cpu) +@@ -1153,18 +1202,30 @@ static int takeover_tasklets(unsigned in static struct smp_hotplug_thread softirq_threads = { .store = &ksoftirqd, .setup = ksoftirqd_set_sched_params, @@ -209,6 +205,3 @@ index 5650395b8d6a..ff8471aa1c0b 100644 return 0; } early_initcall(spawn_ksoftirqd); --- -2.19.2 - diff --git a/kernel/patches-4.19.x-rt/0128-softirq-Avoid-local_softirq_pending-messages-if-ksof.patch b/kernel/patches-4.19.x-rt/0128-softirq-Avoid-local_softirq_pending-messages-if-ksof.patch new file mode 100644 index 000000000..81bf75165 --- /dev/null +++ b/kernel/patches-4.19.x-rt/0128-softirq-Avoid-local_softirq_pending-messages-if-ksof.patch @@ -0,0 +1,105 @@ +From: Sebastian Andrzej Siewior +Date: Mon, 18 Feb 2019 13:19:59 +0100 +Subject: [PATCH] softirq: Avoid "local_softirq_pending" messages if + ksoftirqd is blocked + +If the ksoftirqd thread has a softirq pending and is blocked on the +`local_softirq_locks' lock then softirq_check_pending_idle() won't +complain because the "lock owner" will mask away this softirq from the +mask of pending softirqs. +If ksoftirqd has an additional softirq pending then it won't be masked +out because we never look at ksoftirqd's mask. + +If there are still pending softirqs while going to idle check +ksoftirqd's and ktimersfotd's mask before complaining about unhandled +softirqs. + +Cc: stable-rt@vger.kernel.org +Tested-by: Juri Lelli +Signed-off-by: Sebastian Andrzej Siewior +--- + kernel/softirq.c | 57 +++++++++++++++++++++++++++++++++++++++---------------- + 1 file changed, 41 insertions(+), 16 deletions(-) + +--- a/kernel/softirq.c ++++ b/kernel/softirq.c +@@ -92,6 +92,31 @@ static inline void softirq_clr_runner(un + sr->runner[sirq] = NULL; + } + ++static bool softirq_check_runner_tsk(struct task_struct *tsk, ++ unsigned int *pending) ++{ ++ bool ret = false; ++ ++ if (!tsk) ++ return ret; ++ ++ /* ++ * The wakeup code in rtmutex.c wakes up the task ++ * _before_ it sets pi_blocked_on to NULL under ++ * tsk->pi_lock. So we need to check for both: state ++ * and pi_blocked_on. ++ */ ++ raw_spin_lock(&tsk->pi_lock); ++ if (tsk->pi_blocked_on || tsk->state == TASK_RUNNING) { ++ /* Clear all bits pending in that task */ ++ *pending &= ~(tsk->softirqs_raised); ++ ret = true; ++ } ++ raw_spin_unlock(&tsk->pi_lock); ++ ++ return ret; ++} ++ + /* + * On preempt-rt a softirq running context might be blocked on a + * lock. There might be no other runnable task on this CPU because the +@@ -104,6 +129,7 @@ static inline void softirq_clr_runner(un + */ + void softirq_check_pending_idle(void) + { ++ struct task_struct *tsk; + static int rate_limit; + struct softirq_runner *sr = this_cpu_ptr(&softirq_runners); + u32 warnpending; +@@ -113,24 +139,23 @@ void softirq_check_pending_idle(void) + return; + + warnpending = local_softirq_pending() & SOFTIRQ_STOP_IDLE_MASK; ++ if (!warnpending) ++ return; + for (i = 0; i < NR_SOFTIRQS; i++) { +- struct task_struct *tsk = sr->runner[i]; ++ tsk = sr->runner[i]; ++ ++ if (softirq_check_runner_tsk(tsk, &warnpending)) ++ warnpending &= ~(1 << i); ++ } + +- /* +- * The wakeup code in rtmutex.c wakes up the task +- * _before_ it sets pi_blocked_on to NULL under +- * tsk->pi_lock. So we need to check for both: state +- * and pi_blocked_on. +- */ +- if (tsk) { +- raw_spin_lock(&tsk->pi_lock); +- if (tsk->pi_blocked_on || tsk->state == TASK_RUNNING) { +- /* Clear all bits pending in that task */ +- warnpending &= ~(tsk->softirqs_raised); +- warnpending &= ~(1 << i); +- } +- raw_spin_unlock(&tsk->pi_lock); +- } ++ if (warnpending) { ++ tsk = __this_cpu_read(ksoftirqd); ++ softirq_check_runner_tsk(tsk, &warnpending); ++ } ++ ++ if (warnpending) { ++ tsk = __this_cpu_read(ktimer_softirqd); ++ softirq_check_runner_tsk(tsk, &warnpending); + } + + if (warnpending) { diff --git a/kernel/patches-4.19.x-rt/0129-softirq-Avoid-local_softirq_pending-messages-if-task.patch b/kernel/patches-4.19.x-rt/0129-softirq-Avoid-local_softirq_pending-messages-if-task.patch new file mode 100644 index 000000000..2dc189782 --- /dev/null +++ b/kernel/patches-4.19.x-rt/0129-softirq-Avoid-local_softirq_pending-messages-if-task.patch @@ -0,0 +1,34 @@ +From: Sebastian Andrzej Siewior +Date: Tue, 19 Feb 2019 16:49:29 +0100 +Subject: [PATCH] softirq: Avoid "local_softirq_pending" messages if task + is in cpu_chill() + +If the softirq thread enters cpu_chill() then ->state is UNINTERRUPTIBLE +and has no ->pi_blocked_on set and so its mask is not taken into account. + +->sleeping_lock is increased by cpu_chill() since it is also requried to +avoid a splat by RCU in case cpu_chill() is used while a RCU-read lock +is held. Use the same mechanism for the softirq-pending check. + +Cc: stable-rt@vger.kernel.org +Signed-off-by: Sebastian Andrzej Siewior +--- + kernel/softirq.c | 5 ++++- + 1 file changed, 4 insertions(+), 1 deletion(-) + +--- a/kernel/softirq.c ++++ b/kernel/softirq.c +@@ -105,9 +105,12 @@ static bool softirq_check_runner_tsk(str + * _before_ it sets pi_blocked_on to NULL under + * tsk->pi_lock. So we need to check for both: state + * and pi_blocked_on. ++ * The test against UNINTERRUPTIBLE + ->sleeping_lock is in case the ++ * task does cpu_chill(). + */ + raw_spin_lock(&tsk->pi_lock); +- if (tsk->pi_blocked_on || tsk->state == TASK_RUNNING) { ++ if (tsk->pi_blocked_on || tsk->state == TASK_RUNNING || ++ (tsk->state == TASK_UNINTERRUPTIBLE && tsk->sleeping_lock)) { + /* Clear all bits pending in that task */ + *pending &= ~(tsk->softirqs_raised); + ret = true; diff --git a/kernel/patches-4.14.x-rt/0238-rtmutex-trylock-is-okay-on-RT.patch b/kernel/patches-4.19.x-rt/0130-rtmutex-trylock-is-okay-on-RT.patch similarity index 61% rename from kernel/patches-4.14.x-rt/0238-rtmutex-trylock-is-okay-on-RT.patch rename to kernel/patches-4.19.x-rt/0130-rtmutex-trylock-is-okay-on-RT.patch index 514837772..91c8a4633 100644 --- a/kernel/patches-4.14.x-rt/0238-rtmutex-trylock-is-okay-on-RT.patch +++ b/kernel/patches-4.19.x-rt/0130-rtmutex-trylock-is-okay-on-RT.patch @@ -1,7 +1,6 @@ -From 01a71c577984ae0f1ef7e3289cc64f44385f32bf Mon Sep 17 00:00:00 2001 From: Sebastian Andrzej Siewior -Date: Wed, 2 Dec 2015 11:34:07 +0100 -Subject: [PATCH 238/450] rtmutex: trylock is okay on -RT +Date: Wed 02 Dec 2015 11:34:07 +0100 +Subject: rtmutex: trylock is okay on -RT non-RT kernel could deadlock on rt_mutex_trylock() in softirq context. On -RT we don't run softirqs in IRQ context but in thread context so it is @@ -9,14 +8,12 @@ not a issue here. Signed-off-by: Sebastian Andrzej Siewior --- - kernel/locking/rtmutex.c | 4 ++++ + kernel/locking/rtmutex.c | 4 ++++ 1 file changed, 4 insertions(+) -diff --git a/kernel/locking/rtmutex.c b/kernel/locking/rtmutex.c -index a8119deef92e..205a0e2ca730 100644 --- a/kernel/locking/rtmutex.c +++ b/kernel/locking/rtmutex.c -@@ -1584,7 +1584,11 @@ int __sched rt_mutex_trylock(struct rt_mutex *lock) +@@ -1583,7 +1583,11 @@ int __sched rt_mutex_trylock(struct rt_m { int ret; @@ -28,6 +25,3 @@ index a8119deef92e..205a0e2ca730 100644 return 0; ret = rt_mutex_fasttrylock(lock, rt_mutex_slowtrylock); --- -2.19.2 - diff --git a/kernel/patches-4.14.x-rt/0239-fs-nfs-turn-rmdir_sem-into-a-semaphore.patch b/kernel/patches-4.19.x-rt/0131-fs-nfs-turn-rmdir_sem-into-a-semaphore.patch similarity index 73% rename from kernel/patches-4.14.x-rt/0239-fs-nfs-turn-rmdir_sem-into-a-semaphore.patch rename to kernel/patches-4.19.x-rt/0131-fs-nfs-turn-rmdir_sem-into-a-semaphore.patch index ba675e80f..4ac463250 100644 --- a/kernel/patches-4.14.x-rt/0239-fs-nfs-turn-rmdir_sem-into-a-semaphore.patch +++ b/kernel/patches-4.19.x-rt/0131-fs-nfs-turn-rmdir_sem-into-a-semaphore.patch @@ -1,7 +1,6 @@ -From 16af2853f220161370f6b388994987940ae8d544 Mon Sep 17 00:00:00 2001 From: Sebastian Andrzej Siewior Date: Thu, 15 Sep 2016 10:51:27 +0200 -Subject: [PATCH 239/450] fs/nfs: turn rmdir_sem into a semaphore +Subject: [PATCH] fs/nfs: turn rmdir_sem into a semaphore The RW semaphore had a reader side which used the _non_owner version because it most likely took the reader lock in one thread and released it @@ -14,17 +13,15 @@ multiple readers anyway so that is not a loss. Signed-off-by: Sebastian Andrzej Siewior --- - fs/nfs/dir.c | 8 ++++++++ - fs/nfs/inode.c | 4 ++++ - fs/nfs/unlink.c | 31 +++++++++++++++++++++++++++---- - include/linux/nfs_fs.h | 4 ++++ + fs/nfs/dir.c | 8 ++++++++ + fs/nfs/inode.c | 4 ++++ + fs/nfs/unlink.c | 31 +++++++++++++++++++++++++++---- + include/linux/nfs_fs.h | 4 ++++ 4 files changed, 43 insertions(+), 4 deletions(-) -diff --git a/fs/nfs/dir.c b/fs/nfs/dir.c -index bf2c43635062..1f3818580413 100644 --- a/fs/nfs/dir.c +++ b/fs/nfs/dir.c -@@ -1763,7 +1763,11 @@ int nfs_rmdir(struct inode *dir, struct dentry *dentry) +@@ -1786,7 +1786,11 @@ int nfs_rmdir(struct inode *dir, struct trace_nfs_rmdir_enter(dir, dentry); if (d_really_is_positive(dentry)) { @@ -36,7 +33,7 @@ index bf2c43635062..1f3818580413 100644 error = NFS_PROTO(dir)->rmdir(dir, &dentry->d_name); /* Ensure the VFS deletes this inode */ switch (error) { -@@ -1773,7 +1777,11 @@ int nfs_rmdir(struct inode *dir, struct dentry *dentry) +@@ -1796,7 +1800,11 @@ int nfs_rmdir(struct inode *dir, struct case -ENOENT: nfs_dentry_handle_enoent(dentry); } @@ -48,11 +45,9 @@ index bf2c43635062..1f3818580413 100644 } else error = NFS_PROTO(dir)->rmdir(dir, &dentry->d_name); trace_nfs_rmdir_exit(dir, dentry, error); -diff --git a/fs/nfs/inode.c b/fs/nfs/inode.c -index 134d9f560240..ff64167f9811 100644 --- a/fs/nfs/inode.c +++ b/fs/nfs/inode.c -@@ -2014,7 +2014,11 @@ static void init_once(void *foo) +@@ -2103,7 +2103,11 @@ static void init_once(void *foo) atomic_long_set(&nfsi->nrequests, 0); atomic_long_set(&nfsi->commit_info.ncommit, 0); atomic_set(&nfsi->commit_info.rpcs_out, 0); @@ -64,11 +59,9 @@ index 134d9f560240..ff64167f9811 100644 mutex_init(&nfsi->commit_mutex); nfs4_init_once(nfsi); } -diff --git a/fs/nfs/unlink.c b/fs/nfs/unlink.c -index 630b4a3c1a93..2e78bc25bcea 100644 --- a/fs/nfs/unlink.c +++ b/fs/nfs/unlink.c -@@ -52,6 +52,29 @@ static void nfs_async_unlink_done(struct rpc_task *task, void *calldata) +@@ -52,6 +52,29 @@ static void nfs_async_unlink_done(struct rpc_restart_call_prepare(task); } @@ -98,7 +91,7 @@ index 630b4a3c1a93..2e78bc25bcea 100644 /** * nfs_async_unlink_release - Release the sillydelete data. * @task: rpc_task of the sillydelete -@@ -65,7 +88,7 @@ static void nfs_async_unlink_release(void *calldata) +@@ -65,7 +88,7 @@ static void nfs_async_unlink_release(voi struct dentry *dentry = data->dentry; struct super_block *sb = dentry->d_sb; @@ -107,7 +100,7 @@ index 630b4a3c1a93..2e78bc25bcea 100644 d_lookup_done(dentry); nfs_free_unlinkdata(data); dput(dentry); -@@ -118,10 +141,10 @@ static int nfs_call_unlink(struct dentry *dentry, struct nfs_unlinkdata *data) +@@ -118,10 +141,10 @@ static int nfs_call_unlink(struct dentry struct inode *dir = d_inode(dentry->d_parent); struct dentry *alias; @@ -120,7 +113,7 @@ index 630b4a3c1a93..2e78bc25bcea 100644 return 0; } if (!d_in_lookup(alias)) { -@@ -143,7 +166,7 @@ static int nfs_call_unlink(struct dentry *dentry, struct nfs_unlinkdata *data) +@@ -143,7 +166,7 @@ static int nfs_call_unlink(struct dentry ret = 0; spin_unlock(&alias->d_lock); dput(alias); @@ -129,11 +122,9 @@ index 630b4a3c1a93..2e78bc25bcea 100644 /* * If we'd displaced old cached devname, free it. At that * point dentry is definitely not a root, so we won't need -diff --git a/include/linux/nfs_fs.h b/include/linux/nfs_fs.h -index f0015f801a78..c38288622819 100644 --- a/include/linux/nfs_fs.h +++ b/include/linux/nfs_fs.h -@@ -162,7 +162,11 @@ struct nfs_inode { +@@ -163,7 +163,11 @@ struct nfs_inode { /* Readers: in-flight sillydelete RPC calls */ /* Writers: rmdir */ @@ -145,6 +136,3 @@ index f0015f801a78..c38288622819 100644 struct mutex commit_mutex; #if IS_ENABLED(CONFIG_NFS_V4) --- -2.19.2 - diff --git a/kernel/patches-4.14.x-rt/0240-rtmutex-Handle-the-various-new-futex-race-conditions.patch b/kernel/patches-4.19.x-rt/0132-rtmutex-futex-prepare-rt.patch similarity index 80% rename from kernel/patches-4.14.x-rt/0240-rtmutex-Handle-the-various-new-futex-race-conditions.patch rename to kernel/patches-4.19.x-rt/0132-rtmutex-futex-prepare-rt.patch index 836e9f5b6..7a68754de 100644 --- a/kernel/patches-4.14.x-rt/0240-rtmutex-Handle-the-various-new-futex-race-conditions.patch +++ b/kernel/patches-4.19.x-rt/0132-rtmutex-futex-prepare-rt.patch @@ -1,7 +1,6 @@ -From d1a3ef81abb1a72e4d70db2f6fd3691c2d679457 Mon Sep 17 00:00:00 2001 +Subject: rtmutex: Handle the various new futex race conditions From: Thomas Gleixner Date: Fri, 10 Jun 2011 11:04:15 +0200 -Subject: [PATCH 240/450] rtmutex: Handle the various new futex race conditions RT opens a few new interesting race conditions in the rtmutex/futex combo due to futex hash bucket lock being a 'sleeping' spinlock and @@ -9,16 +8,14 @@ therefor not disabling preemption. Signed-off-by: Thomas Gleixner --- - kernel/futex.c | 77 ++++++++++++++++++++++++++------- - kernel/locking/rtmutex.c | 36 ++++++++++++--- - kernel/locking/rtmutex_common.h | 2 + + kernel/futex.c | 77 ++++++++++++++++++++++++++++++++-------- + kernel/locking/rtmutex.c | 36 +++++++++++++++--- + kernel/locking/rtmutex_common.h | 2 + 3 files changed, 94 insertions(+), 21 deletions(-) -diff --git a/kernel/futex.c b/kernel/futex.c -index 1d87da84b2a2..207e10a1791a 100644 --- a/kernel/futex.c +++ b/kernel/futex.c -@@ -2104,6 +2104,16 @@ static int futex_requeue(u32 __user *uaddr1, unsigned int flags, +@@ -2143,6 +2143,16 @@ static int futex_requeue(u32 __user *uad requeue_pi_wake_futex(this, &key2, hb2); drop_count++; continue; @@ -35,7 +32,7 @@ index 1d87da84b2a2..207e10a1791a 100644 } else if (ret) { /* * rt_mutex_start_proxy_lock() detected a -@@ -3144,7 +3154,7 @@ static int futex_wait_requeue_pi(u32 __user *uaddr, unsigned int flags, +@@ -3191,7 +3201,7 @@ static int futex_wait_requeue_pi(u32 __u struct hrtimer_sleeper timeout, *to = NULL; struct futex_pi_state *pi_state = NULL; struct rt_mutex_waiter rt_waiter; @@ -44,7 +41,7 @@ index 1d87da84b2a2..207e10a1791a 100644 union futex_key key2 = FUTEX_KEY_INIT; struct futex_q q = futex_q_init; int res, ret; -@@ -3202,20 +3212,55 @@ static int futex_wait_requeue_pi(u32 __user *uaddr, unsigned int flags, +@@ -3249,20 +3259,55 @@ static int futex_wait_requeue_pi(u32 __u /* Queue the futex_q, drop the hb lock, wait for wakeup. */ futex_wait_queue_me(hb, &q, to); @@ -111,7 +108,7 @@ index 1d87da84b2a2..207e10a1791a 100644 /* Check if the requeue code acquired the second futex for us. */ if (!q.rt_waiter) { -@@ -3224,7 +3269,8 @@ static int futex_wait_requeue_pi(u32 __user *uaddr, unsigned int flags, +@@ -3271,7 +3316,8 @@ static int futex_wait_requeue_pi(u32 __u * did a lock-steal - fix up the PI-state in that case. */ if (q.pi_state && (q.pi_state->owner != current)) { @@ -121,7 +118,7 @@ index 1d87da84b2a2..207e10a1791a 100644 ret = fixup_pi_state_owner(uaddr2, &q, current); if (ret && rt_mutex_owner(&q.pi_state->pi_mutex) == current) { pi_state = q.pi_state; -@@ -3235,7 +3281,7 @@ static int futex_wait_requeue_pi(u32 __user *uaddr, unsigned int flags, +@@ -3282,7 +3328,7 @@ static int futex_wait_requeue_pi(u32 __u * the requeue_pi() code acquired for us. */ put_pi_state(q.pi_state); @@ -130,7 +127,7 @@ index 1d87da84b2a2..207e10a1791a 100644 } } else { struct rt_mutex *pi_mutex; -@@ -3249,7 +3295,8 @@ static int futex_wait_requeue_pi(u32 __user *uaddr, unsigned int flags, +@@ -3296,7 +3342,8 @@ static int futex_wait_requeue_pi(u32 __u pi_mutex = &q.pi_state->pi_mutex; ret = rt_mutex_wait_proxy_lock(pi_mutex, to, &rt_waiter); @@ -140,11 +137,9 @@ index 1d87da84b2a2..207e10a1791a 100644 if (ret && !rt_mutex_cleanup_proxy_lock(pi_mutex, &rt_waiter)) ret = 0; -diff --git a/kernel/locking/rtmutex.c b/kernel/locking/rtmutex.c -index 205a0e2ca730..65c50c893513 100644 --- a/kernel/locking/rtmutex.c +++ b/kernel/locking/rtmutex.c -@@ -135,6 +135,11 @@ static void fixup_rt_mutex_waiters(struct rt_mutex *lock) +@@ -135,6 +135,11 @@ static void fixup_rt_mutex_waiters(struc WRITE_ONCE(*p, owner & ~RT_MUTEX_HAS_WAITERS); } @@ -166,7 +161,7 @@ index 205a0e2ca730..65c50c893513 100644 } /* -@@ -515,7 +521,7 @@ static int rt_mutex_adjust_prio_chain(struct task_struct *task, +@@ -515,7 +521,7 @@ static int rt_mutex_adjust_prio_chain(st * reached or the state of the chain has changed while we * dropped the locks. */ @@ -175,7 +170,7 @@ index 205a0e2ca730..65c50c893513 100644 goto out_unlock_pi; /* -@@ -951,6 +957,22 @@ static int task_blocks_on_rt_mutex(struct rt_mutex *lock, +@@ -951,6 +957,22 @@ static int task_blocks_on_rt_mutex(struc return -EDEADLK; raw_spin_lock(&task->pi_lock); @@ -198,7 +193,7 @@ index 205a0e2ca730..65c50c893513 100644 waiter->task = task; waiter->lock = lock; waiter->prio = task->prio; -@@ -974,7 +996,7 @@ static int task_blocks_on_rt_mutex(struct rt_mutex *lock, +@@ -974,7 +996,7 @@ static int task_blocks_on_rt_mutex(struc rt_mutex_enqueue_pi(owner, waiter); rt_mutex_adjust_prio(owner); @@ -207,7 +202,7 @@ index 205a0e2ca730..65c50c893513 100644 chain_walk = 1; } else if (rt_mutex_cond_detect_deadlock(waiter, chwalk)) { chain_walk = 1; -@@ -1070,7 +1092,7 @@ static void remove_waiter(struct rt_mutex *lock, +@@ -1070,7 +1092,7 @@ static void remove_waiter(struct rt_mute { bool is_top_waiter = (waiter == rt_mutex_top_waiter(lock)); struct task_struct *owner = rt_mutex_owner(lock); @@ -216,7 +211,7 @@ index 205a0e2ca730..65c50c893513 100644 lockdep_assert_held(&lock->wait_lock); -@@ -1096,7 +1118,8 @@ static void remove_waiter(struct rt_mutex *lock, +@@ -1096,7 +1118,8 @@ static void remove_waiter(struct rt_mute rt_mutex_adjust_prio(owner); /* Store the lock on which owner is blocked or NULL */ @@ -226,7 +221,7 @@ index 205a0e2ca730..65c50c893513 100644 raw_spin_unlock(&owner->pi_lock); -@@ -1132,7 +1155,8 @@ void rt_mutex_adjust_pi(struct task_struct *task) +@@ -1132,7 +1155,8 @@ void rt_mutex_adjust_pi(struct task_stru raw_spin_lock_irqsave(&task->pi_lock, flags); waiter = task->pi_blocked_on; @@ -236,11 +231,9 @@ index 205a0e2ca730..65c50c893513 100644 raw_spin_unlock_irqrestore(&task->pi_lock, flags); return; } -diff --git a/kernel/locking/rtmutex_common.h b/kernel/locking/rtmutex_common.h -index 68686b3ec3c1..fa218cdff5eb 100644 --- a/kernel/locking/rtmutex_common.h +++ b/kernel/locking/rtmutex_common.h -@@ -129,6 +129,8 @@ enum rtmutex_chainwalk { +@@ -130,6 +130,8 @@ enum rtmutex_chainwalk { /* * PI-futex support (proxy locking functions, etc.): */ @@ -249,6 +242,3 @@ index 68686b3ec3c1..fa218cdff5eb 100644 extern struct task_struct *rt_mutex_next_owner(struct rt_mutex *lock); extern void rt_mutex_init_proxy_locked(struct rt_mutex *lock, struct task_struct *proxy_owner); --- -2.19.2 - diff --git a/kernel/patches-4.14.x-rt/0241-futex-Fix-bug-on-when-a-requeued-RT-task-times-out.patch b/kernel/patches-4.19.x-rt/0133-futex-requeue-pi-fix.patch similarity index 80% rename from kernel/patches-4.14.x-rt/0241-futex-Fix-bug-on-when-a-requeued-RT-task-times-out.patch rename to kernel/patches-4.19.x-rt/0133-futex-requeue-pi-fix.patch index d8c08486d..7522ec9ce 100644 --- a/kernel/patches-4.14.x-rt/0241-futex-Fix-bug-on-when-a-requeued-RT-task-times-out.patch +++ b/kernel/patches-4.19.x-rt/0133-futex-requeue-pi-fix.patch @@ -1,7 +1,6 @@ -From 00ab1614b16480152f071b950a12b5bfd52e3a1f Mon Sep 17 00:00:00 2001 From: Steven Rostedt Date: Tue, 14 Jul 2015 14:26:34 +0200 -Subject: [PATCH 241/450] futex: Fix bug on when a requeued RT task times out +Subject: futex: Fix bug on when a requeued RT task times out Requeue with timeout causes a bug with PREEMPT_RT_FULL. @@ -17,7 +16,7 @@ The bug comes from a timed out condition. double_lock_hb(); raw_spin_lock(pi_lock); - if (current->pi_blocked_on) { + if (current->pi_blocked_on) { } else { current->pi_blocked_on = PI_WAKE_INPROGRESS; run_spin_unlock(pi_lock); @@ -50,15 +49,13 @@ appropriately. Signed-off-by: Steven Rostedt Signed-off-by: Thomas Gleixner --- - kernel/locking/rtmutex.c | 32 +++++++++++++++++++++++++++++++- - kernel/locking/rtmutex_common.h | 1 + - 2 files changed, 32 insertions(+), 1 deletion(-) + kernel/locking/rtmutex.c | 31 ++++++++++++++++++++++++++++++- + kernel/locking/rtmutex_common.h | 1 + + 2 files changed, 31 insertions(+), 1 deletion(-) -diff --git a/kernel/locking/rtmutex.c b/kernel/locking/rtmutex.c -index 65c50c893513..ea8dd82835c9 100644 --- a/kernel/locking/rtmutex.c +++ b/kernel/locking/rtmutex.c -@@ -137,7 +137,8 @@ static void fixup_rt_mutex_waiters(struct rt_mutex *lock) +@@ -137,7 +137,8 @@ static void fixup_rt_mutex_waiters(struc static int rt_mutex_real_waiter(struct rt_mutex_waiter *waiter) { @@ -68,7 +65,7 @@ index 65c50c893513..ea8dd82835c9 100644 } /* -@@ -1764,6 +1765,35 @@ int __rt_mutex_start_proxy_lock(struct rt_mutex *lock, +@@ -1784,6 +1785,34 @@ int __rt_mutex_start_proxy_lock(struct r if (try_to_take_rt_mutex(lock, task, NULL)) return 1; @@ -94,7 +91,6 @@ index 65c50c893513..ea8dd82835c9 100644 + raw_spin_lock(&task->pi_lock); + if (task->pi_blocked_on) { + raw_spin_unlock(&task->pi_lock); -+ raw_spin_unlock_irq(&lock->wait_lock); + return -EAGAIN; + } + task->pi_blocked_on = PI_REQUEUE_INPROGRESS; @@ -104,11 +100,9 @@ index 65c50c893513..ea8dd82835c9 100644 /* We enforce deadlock detection for futexes */ ret = task_blocks_on_rt_mutex(lock, waiter, task, RT_MUTEX_FULL_CHAINWALK); -diff --git a/kernel/locking/rtmutex_common.h b/kernel/locking/rtmutex_common.h -index fa218cdff5eb..509df18215f8 100644 --- a/kernel/locking/rtmutex_common.h +++ b/kernel/locking/rtmutex_common.h -@@ -130,6 +130,7 @@ enum rtmutex_chainwalk { +@@ -131,6 +131,7 @@ enum rtmutex_chainwalk { * PI-futex support (proxy locking functions, etc.): */ #define PI_WAKEUP_INPROGRESS ((struct rt_mutex_waiter *) 1) @@ -116,6 +110,3 @@ index fa218cdff5eb..509df18215f8 100644 extern struct task_struct *rt_mutex_next_owner(struct rt_mutex *lock); extern void rt_mutex_init_proxy_locked(struct rt_mutex *lock, --- -2.19.2 - diff --git a/kernel/patches-4.14.x-rt/0243-futex-Ensure-lock-unlock-symetry-versus-pi_lock-and-.patch b/kernel/patches-4.19.x-rt/0134-futex-Ensure-lock-unlock-symetry-versus-pi_lock-and-.patch similarity index 78% rename from kernel/patches-4.14.x-rt/0243-futex-Ensure-lock-unlock-symetry-versus-pi_lock-and-.patch rename to kernel/patches-4.19.x-rt/0134-futex-Ensure-lock-unlock-symetry-versus-pi_lock-and-.patch index 6377ace4a..af6fd47d7 100644 --- a/kernel/patches-4.14.x-rt/0243-futex-Ensure-lock-unlock-symetry-versus-pi_lock-and-.patch +++ b/kernel/patches-4.19.x-rt/0134-futex-Ensure-lock-unlock-symetry-versus-pi_lock-and-.patch @@ -1,8 +1,6 @@ -From c2eb8f9ce166e98cf66975faa274895220a19d95 Mon Sep 17 00:00:00 2001 From: Thomas Gleixner Date: Fri, 1 Mar 2013 11:17:42 +0100 -Subject: [PATCH 243/450] futex: Ensure lock/unlock symetry versus pi_lock and - hash bucket lock +Subject: futex: Ensure lock/unlock symetry versus pi_lock and hash bucket lock In exit_pi_state_list() we have the following locking construct: @@ -27,14 +25,12 @@ Reported-by: Yong Zhang Signed-off-by: Thomas Gleixner Signed-off-by: Sebastian Andrzej Siewior --- - kernel/futex.c | 2 ++ + kernel/futex.c | 2 ++ 1 file changed, 2 insertions(+) -diff --git a/kernel/futex.c b/kernel/futex.c -index 207e10a1791a..7540d5c425ac 100644 --- a/kernel/futex.c +++ b/kernel/futex.c -@@ -936,7 +936,9 @@ void exit_pi_state_list(struct task_struct *curr) +@@ -918,7 +918,9 @@ void exit_pi_state_list(struct task_stru if (head->next != next) { /* retain curr->pi_lock for the loop invariant */ raw_spin_unlock(&pi_state->pi_mutex.wait_lock); @@ -44,6 +40,3 @@ index 207e10a1791a..7540d5c425ac 100644 put_pi_state(pi_state); continue; } --- -2.19.2 - diff --git a/kernel/patches-4.14.x-rt/0244-pid.h-include-atomic.h.patch b/kernel/patches-4.19.x-rt/0135-pid.h-include-atomic.h.patch similarity index 78% rename from kernel/patches-4.14.x-rt/0244-pid.h-include-atomic.h.patch rename to kernel/patches-4.19.x-rt/0135-pid.h-include-atomic.h.patch index fe686db35..9510164b0 100644 --- a/kernel/patches-4.14.x-rt/0244-pid.h-include-atomic.h.patch +++ b/kernel/patches-4.19.x-rt/0135-pid.h-include-atomic.h.patch @@ -1,7 +1,6 @@ -From 167e150e3cc71b6a510c88fee049096c843ec415 Mon Sep 17 00:00:00 2001 From: Grygorii Strashko Date: Tue, 21 Jul 2015 19:43:56 +0300 -Subject: [PATCH 244/450] pid.h: include atomic.h +Subject: pid.h: include atomic.h This patch fixes build error: CC kernel/pid_namespace.o @@ -22,11 +21,9 @@ Vanilla gets this via spinlock.h. Signed-off-by: Grygorii Strashko Signed-off-by: Sebastian Andrzej Siewior --- - include/linux/pid.h | 1 + + include/linux/pid.h | 1 + 1 file changed, 1 insertion(+) -diff --git a/include/linux/pid.h b/include/linux/pid.h -index dfd684ce0787..bc954a99aa70 100644 --- a/include/linux/pid.h +++ b/include/linux/pid.h @@ -3,6 +3,7 @@ @@ -37,6 +34,3 @@ index dfd684ce0787..bc954a99aa70 100644 enum pid_type { --- -2.19.2 - diff --git a/kernel/patches-4.14.x-rt/0245-arm-include-definition-for-cpumask_t.patch b/kernel/patches-4.19.x-rt/0136-arm-include-definition-for-cpumask_t.patch similarity index 67% rename from kernel/patches-4.14.x-rt/0245-arm-include-definition-for-cpumask_t.patch rename to kernel/patches-4.19.x-rt/0136-arm-include-definition-for-cpumask_t.patch index 96932e4cd..4bb2672be 100644 --- a/kernel/patches-4.14.x-rt/0245-arm-include-definition-for-cpumask_t.patch +++ b/kernel/patches-4.19.x-rt/0136-arm-include-definition-for-cpumask_t.patch @@ -1,7 +1,6 @@ -From 79365b011a093dfb4e2b3c27764bac5dc522dd97 Mon Sep 17 00:00:00 2001 From: Sebastian Andrzej Siewior Date: Thu, 22 Dec 2016 17:28:33 +0100 -Subject: [PATCH 245/450] arm: include definition for cpumask_t +Subject: [PATCH] arm: include definition for cpumask_t This definition gets pulled in by other files. With the (later) split of RCU and spinlock.h it won't compile anymore. @@ -9,11 +8,9 @@ The split is done in ("rbtree: don't include the rcu header"). Signed-off-by: Sebastian Andrzej Siewior --- - arch/arm/include/asm/irq.h | 2 ++ + arch/arm/include/asm/irq.h | 2 ++ 1 file changed, 2 insertions(+) -diff --git a/arch/arm/include/asm/irq.h b/arch/arm/include/asm/irq.h -index b6f319606e30..ad377ef73739 100644 --- a/arch/arm/include/asm/irq.h +++ b/arch/arm/include/asm/irq.h @@ -23,6 +23,8 @@ @@ -25,6 +22,3 @@ index b6f319606e30..ad377ef73739 100644 struct irqaction; struct pt_regs; extern void migrate_irqs(void); --- -2.19.2 - diff --git a/kernel/patches-4.14.x-rt/0246-locking-locktorture-Do-NOT-include-rwlock.h-directly.patch b/kernel/patches-4.19.x-rt/0137-locking-locktorture-Do-NOT-include-rwlock.h-directly.patch similarity index 69% rename from kernel/patches-4.14.x-rt/0246-locking-locktorture-Do-NOT-include-rwlock.h-directly.patch rename to kernel/patches-4.19.x-rt/0137-locking-locktorture-Do-NOT-include-rwlock.h-directly.patch index ddea534c0..20855d74f 100644 --- a/kernel/patches-4.14.x-rt/0246-locking-locktorture-Do-NOT-include-rwlock.h-directly.patch +++ b/kernel/patches-4.19.x-rt/0137-locking-locktorture-Do-NOT-include-rwlock.h-directly.patch @@ -1,8 +1,6 @@ -From b3539c486f64958c3530a286e06202850398caf1 Mon Sep 17 00:00:00 2001 From: "Wolfgang M. Reimer" Date: Tue, 21 Jul 2015 16:20:07 +0200 -Subject: [PATCH 246/450] locking: locktorture: Do NOT include rwlock.h - directly +Subject: locking: locktorture: Do NOT include rwlock.h directly Including rwlock.h directly will cause kernel builds to fail if CONFIG_PREEMPT_RT_FULL is defined. The correct header file @@ -13,14 +11,12 @@ Cc: stable-rt@vger.kernel.org Signed-off-by: Wolfgang M. Reimer Signed-off-by: Sebastian Andrzej Siewior --- - kernel/locking/locktorture.c | 1 - + kernel/locking/locktorture.c | 1 - 1 file changed, 1 deletion(-) -diff --git a/kernel/locking/locktorture.c b/kernel/locking/locktorture.c -index 6dca260eeccf..5d01ac590d4c 100644 --- a/kernel/locking/locktorture.c +++ b/kernel/locking/locktorture.c -@@ -26,7 +26,6 @@ +@@ -29,7 +29,6 @@ #include #include #include @@ -28,6 +24,3 @@ index 6dca260eeccf..5d01ac590d4c 100644 #include #include #include --- -2.19.2 - diff --git a/kernel/patches-4.14.x-rt/0247-rtmutex-Add-rtmutex_lock_killable.patch b/kernel/patches-4.19.x-rt/0138-rtmutex-lock-killable.patch similarity index 65% rename from kernel/patches-4.14.x-rt/0247-rtmutex-Add-rtmutex_lock_killable.patch rename to kernel/patches-4.19.x-rt/0138-rtmutex-lock-killable.patch index 3ddaf5ab9..bad59d2de 100644 --- a/kernel/patches-4.14.x-rt/0247-rtmutex-Add-rtmutex_lock_killable.patch +++ b/kernel/patches-4.19.x-rt/0138-rtmutex-lock-killable.patch @@ -1,22 +1,19 @@ -From da8f518ac576fd0130fccdad0517bc0f228fddd7 Mon Sep 17 00:00:00 2001 +Subject: rtmutex: Add rtmutex_lock_killable() From: Thomas Gleixner -Date: Thu, 9 Jun 2011 11:43:52 +0200 -Subject: [PATCH 247/450] rtmutex: Add rtmutex_lock_killable() +Date: Thu, 09 Jun 2011 11:43:52 +0200 Add "killable" type to rtmutex. We need this since rtmutex are used as "normal" mutexes which do use this type. Signed-off-by: Thomas Gleixner --- - include/linux/rtmutex.h | 1 + - kernel/locking/rtmutex.c | 19 +++++++++++++++++++ + include/linux/rtmutex.h | 1 + + kernel/locking/rtmutex.c | 19 +++++++++++++++++++ 2 files changed, 20 insertions(+) -diff --git a/include/linux/rtmutex.h b/include/linux/rtmutex.h -index 6fd615a0eea9..81ece6a8291a 100644 --- a/include/linux/rtmutex.h +++ b/include/linux/rtmutex.h -@@ -115,6 +115,7 @@ extern void rt_mutex_lock(struct rt_mutex *lock); +@@ -115,6 +115,7 @@ extern void rt_mutex_lock(struct rt_mute #endif extern int rt_mutex_lock_interruptible(struct rt_mutex *lock); @@ -24,15 +21,12 @@ index 6fd615a0eea9..81ece6a8291a 100644 extern int rt_mutex_timed_lock(struct rt_mutex *lock, struct hrtimer_sleeper *timeout); -diff --git a/kernel/locking/rtmutex.c b/kernel/locking/rtmutex.c -index 935adbbe08f1..fb6bb56ac33d 100644 --- a/kernel/locking/rtmutex.c +++ b/kernel/locking/rtmutex.c -@@ -1563,6 +1563,25 @@ int __sched __rt_mutex_futex_trylock(struct rt_mutex *lock) - return __rt_mutex_slowtrylock(lock); +@@ -1563,6 +1563,25 @@ int __sched __rt_mutex_futex_trylock(str } -+/** + /** + * rt_mutex_lock_killable - lock a rt_mutex killable + * + * @lock: the rt_mutex to be locked @@ -51,9 +45,7 @@ index 935adbbe08f1..fb6bb56ac33d 100644 +} +EXPORT_SYMBOL_GPL(rt_mutex_lock_killable); + - /** ++/** * rt_mutex_timed_lock - lock a rt_mutex interruptible * the timeout structure is provided --- -2.19.2 - + * by the caller diff --git a/kernel/patches-4.14.x-rt/0248-rtmutex-Make-lock_killable-work.patch b/kernel/patches-4.19.x-rt/0139-rtmutex-Make-lock_killable-work.patch similarity index 73% rename from kernel/patches-4.14.x-rt/0248-rtmutex-Make-lock_killable-work.patch rename to kernel/patches-4.19.x-rt/0139-rtmutex-Make-lock_killable-work.patch index 336a890c2..cc50d7ea5 100644 --- a/kernel/patches-4.14.x-rt/0248-rtmutex-Make-lock_killable-work.patch +++ b/kernel/patches-4.19.x-rt/0139-rtmutex-Make-lock_killable-work.patch @@ -1,7 +1,6 @@ -From 33c51e680680205d86caa10e4283a3982df4d43c Mon Sep 17 00:00:00 2001 From: Thomas Gleixner Date: Sat, 1 Apr 2017 12:50:59 +0200 -Subject: [PATCH 248/450] rtmutex: Make lock_killable work +Subject: [PATCH] rtmutex: Make lock_killable work Locking an rt mutex killable does not work because signal handling is restricted to TASK_INTERRUPTIBLE. @@ -12,14 +11,12 @@ Cc: stable-rt@vger.kernel.org Signed-off-by: Thomas Gleixner Signed-off-by: Sebastian Andrzej Siewior --- - kernel/locking/rtmutex.c | 19 +++++++------------ + kernel/locking/rtmutex.c | 19 +++++++------------ 1 file changed, 7 insertions(+), 12 deletions(-) -diff --git a/kernel/locking/rtmutex.c b/kernel/locking/rtmutex.c -index fb6bb56ac33d..5f2b7609693f 100644 --- a/kernel/locking/rtmutex.c +++ b/kernel/locking/rtmutex.c -@@ -1201,18 +1201,13 @@ __rt_mutex_slowlock(struct rt_mutex *lock, int state, +@@ -1201,18 +1201,13 @@ static int __sched if (try_to_take_rt_mutex(lock, current, waiter)) break; @@ -45,6 +42,3 @@ index fb6bb56ac33d..5f2b7609693f 100644 } raw_spin_unlock_irq(&lock->wait_lock); --- -2.19.2 - diff --git a/kernel/patches-4.14.x-rt/0249-spinlock-Split-the-lock-types-header.patch b/kernel/patches-4.19.x-rt/0140-spinlock-types-separate-raw.patch similarity index 79% rename from kernel/patches-4.14.x-rt/0249-spinlock-Split-the-lock-types-header.patch rename to kernel/patches-4.19.x-rt/0140-spinlock-types-separate-raw.patch index 98ae47716..e2291eac0 100644 --- a/kernel/patches-4.14.x-rt/0249-spinlock-Split-the-lock-types-header.patch +++ b/kernel/patches-4.19.x-rt/0140-spinlock-types-separate-raw.patch @@ -1,7 +1,6 @@ -From f9c80a2e865e12db3fd0bb30d5338efb22a4cbe7 Mon Sep 17 00:00:00 2001 +Subject: spinlock: Split the lock types header From: Thomas Gleixner Date: Wed, 29 Jun 2011 19:34:01 +0200 -Subject: [PATCH 249/450] spinlock: Split the lock types header Split raw_spinlock into its own file and the remaining spinlock_t into its own non-RT header. The non-RT header will be replaced later by sleeping @@ -9,16 +8,12 @@ spinlocks. Signed-off-by: Thomas Gleixner --- - include/linux/rwlock_types.h | 4 ++ - include/linux/spinlock_types.h | 74 +---------------------------- - include/linux/spinlock_types_nort.h | 33 +++++++++++++ - include/linux/spinlock_types_raw.h | 58 ++++++++++++++++++++++ - 4 files changed, 97 insertions(+), 72 deletions(-) - create mode 100644 include/linux/spinlock_types_nort.h - create mode 100644 include/linux/spinlock_types_raw.h + include/linux/rwlock_types.h | 4 ++ + include/linux/spinlock_types.h | 71 +----------------------------------- + include/linux/spinlock_types_nort.h | 33 ++++++++++++++++ + include/linux/spinlock_types_raw.h | 55 +++++++++++++++++++++++++++ + 4 files changed, 94 insertions(+), 69 deletions(-) -diff --git a/include/linux/rwlock_types.h b/include/linux/rwlock_types.h -index cc0072e93e36..5317cd957292 100644 --- a/include/linux/rwlock_types.h +++ b/include/linux/rwlock_types.h @@ -1,6 +1,10 @@ @@ -32,11 +27,9 @@ index cc0072e93e36..5317cd957292 100644 /* * include/linux/rwlock_types.h - generic rwlock type definitions * and initializers -diff --git a/include/linux/spinlock_types.h b/include/linux/spinlock_types.h -index 73548eb13a5d..5c8664d57fb8 100644 --- a/include/linux/spinlock_types.h +++ b/include/linux/spinlock_types.h -@@ -9,79 +9,9 @@ +@@ -9,76 +9,9 @@ * Released under the General Public License (GPL). */ @@ -51,9 +44,6 @@ index 73548eb13a5d..5c8664d57fb8 100644 - -typedef struct raw_spinlock { - arch_spinlock_t raw_lock; --#ifdef CONFIG_GENERIC_LOCKBREAK -- unsigned int break_lock; --#endif -#ifdef CONFIG_DEBUG_SPINLOCK - unsigned int magic, owner_cpu; - void *owner; @@ -118,9 +108,6 @@ index 73548eb13a5d..5c8664d57fb8 100644 #include -diff --git a/include/linux/spinlock_types_nort.h b/include/linux/spinlock_types_nort.h -new file mode 100644 -index 000000000000..f1dac1fb1d6a --- /dev/null +++ b/include/linux/spinlock_types_nort.h @@ -0,0 +1,33 @@ @@ -157,12 +144,9 @@ index 000000000000..f1dac1fb1d6a +#define DEFINE_SPINLOCK(x) spinlock_t x = __SPIN_LOCK_UNLOCKED(x) + +#endif -diff --git a/include/linux/spinlock_types_raw.h b/include/linux/spinlock_types_raw.h -new file mode 100644 -index 000000000000..03235b475b77 --- /dev/null +++ b/include/linux/spinlock_types_raw.h -@@ -0,0 +1,58 @@ +@@ -0,0 +1,55 @@ +#ifndef __LINUX_SPINLOCK_TYPES_RAW_H +#define __LINUX_SPINLOCK_TYPES_RAW_H + @@ -178,9 +162,6 @@ index 000000000000..03235b475b77 + +typedef struct raw_spinlock { + arch_spinlock_t raw_lock; -+#ifdef CONFIG_GENERIC_LOCKBREAK -+ unsigned int break_lock; -+#endif +#ifdef CONFIG_DEBUG_SPINLOCK + unsigned int magic, owner_cpu; + void *owner; @@ -221,6 +202,3 @@ index 000000000000..03235b475b77 +#define DEFINE_RAW_SPINLOCK(x) raw_spinlock_t x = __RAW_SPIN_LOCK_UNLOCKED(x) + +#endif --- -2.19.2 - diff --git a/kernel/patches-4.14.x-rt/0250-rtmutex-Avoid-include-hell.patch b/kernel/patches-4.19.x-rt/0141-rtmutex-avoid-include-hell.patch similarity index 68% rename from kernel/patches-4.14.x-rt/0250-rtmutex-Avoid-include-hell.patch rename to kernel/patches-4.19.x-rt/0141-rtmutex-avoid-include-hell.patch index 3edeaac06..a3b55f5b7 100644 --- a/kernel/patches-4.14.x-rt/0250-rtmutex-Avoid-include-hell.patch +++ b/kernel/patches-4.19.x-rt/0141-rtmutex-avoid-include-hell.patch @@ -1,18 +1,15 @@ -From eb8c7a8a2dc15dd4c8783fda5340857dea64c171 Mon Sep 17 00:00:00 2001 +Subject: rtmutex: Avoid include hell From: Thomas Gleixner Date: Wed, 29 Jun 2011 20:06:39 +0200 -Subject: [PATCH 250/450] rtmutex: Avoid include hell Include only the required raw types. This avoids pulling in the complete spinlock header which in turn requires rtmutex.h at some point. Signed-off-by: Thomas Gleixner --- - include/linux/rtmutex.h | 2 +- + include/linux/rtmutex.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) -diff --git a/include/linux/rtmutex.h b/include/linux/rtmutex.h -index 81ece6a8291a..a355289b1fa1 100644 --- a/include/linux/rtmutex.h +++ b/include/linux/rtmutex.h @@ -15,7 +15,7 @@ @@ -24,6 +21,3 @@ index 81ece6a8291a..a355289b1fa1 100644 extern int max_lock_depth; /* for sysctl */ --- -2.19.2 - diff --git a/kernel/patches-4.14.x-rt/0251-rbtree-don-t-include-the-rcu-header.patch b/kernel/patches-4.19.x-rt/0142-rtmutex_dont_include_rcu.patch similarity index 85% rename from kernel/patches-4.14.x-rt/0251-rbtree-don-t-include-the-rcu-header.patch rename to kernel/patches-4.19.x-rt/0142-rtmutex_dont_include_rcu.patch index d25b07b00..d63e678a0 100644 --- a/kernel/patches-4.14.x-rt/0251-rbtree-don-t-include-the-rcu-header.patch +++ b/kernel/patches-4.19.x-rt/0142-rtmutex_dont_include_rcu.patch @@ -1,10 +1,5 @@ -From 9fdfae1b4d52c2db110dd6c8558833d7417b1e74 Mon Sep 17 00:00:00 2001 From: Sebastian Andrzej Siewior -Date: Thu, 3 May 2018 17:46:31 +0200 -Subject: [PATCH 251/450] rbtree: don't include the rcu header -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit +Subject: rbtree: don't include the rcu header The RCU header pulls in spinlock.h and fails due not yet defined types: @@ -23,14 +18,11 @@ a new header file which can be included by both users. Signed-off-by: Sebastian Andrzej Siewior --- - include/linux/rbtree.h | 2 +- - include/linux/rcu_assign_pointer.h | 54 ++++++++++++++++++++++++++++++ - include/linux/rcupdate.h | 49 +-------------------------- + include/linux/rbtree.h | 2 - + include/linux/rcu_assign_pointer.h | 54 +++++++++++++++++++++++++++++++++++++ + include/linux/rcupdate.h | 49 --------------------------------- 3 files changed, 56 insertions(+), 49 deletions(-) - create mode 100644 include/linux/rcu_assign_pointer.h -diff --git a/include/linux/rbtree.h b/include/linux/rbtree.h -index d574361943ea..0a9f442409b9 100644 --- a/include/linux/rbtree.h +++ b/include/linux/rbtree.h @@ -31,7 +31,7 @@ @@ -42,9 +34,6 @@ index d574361943ea..0a9f442409b9 100644 struct rb_node { unsigned long __rb_parent_color; -diff --git a/include/linux/rcu_assign_pointer.h b/include/linux/rcu_assign_pointer.h -new file mode 100644 -index 000000000000..7066962a4379 --- /dev/null +++ b/include/linux/rcu_assign_pointer.h @@ -0,0 +1,54 @@ @@ -102,8 +91,6 @@ index 000000000000..7066962a4379 +}) + +#endif -diff --git a/include/linux/rcupdate.h b/include/linux/rcupdate.h -index dbadbdbc8643..a2dc82b3118a 100644 --- a/include/linux/rcupdate.h +++ b/include/linux/rcupdate.h @@ -42,6 +42,7 @@ @@ -114,11 +101,10 @@ index dbadbdbc8643..a2dc82b3118a 100644 #define ULONG_CMP_GE(a, b) (ULONG_MAX / 2 >= (a) - (b)) #define ULONG_CMP_LT(a, b) (ULONG_MAX / 2 < (a) - (b)) -@@ -371,54 +372,6 @@ static inline void rcu_preempt_sleep_check(void) { } - ((typeof(*p) __force __kernel *)(________p1)); \ +@@ -372,54 +373,6 @@ static inline void rcu_preempt_sleep_che }) --/** + /** - * RCU_INITIALIZER() - statically initialize an RCU-protected global variable - * @v: The value to statically initialize with. - */ @@ -166,9 +152,7 @@ index dbadbdbc8643..a2dc82b3118a 100644 - _r_a_p__v; \ -}) - - /** +-/** * rcu_swap_protected() - swap an RCU and a regular pointer * @rcu_ptr: RCU pointer --- -2.19.2 - + * @ptr: regular pointer diff --git a/kernel/patches-4.14.x-rt/0252-rtmutex-Provide-rt_mutex_slowlock_locked.patch b/kernel/patches-4.19.x-rt/0143-rtmutex-Provide-rt_mutex_slowlock_locked.patch similarity index 77% rename from kernel/patches-4.14.x-rt/0252-rtmutex-Provide-rt_mutex_slowlock_locked.patch rename to kernel/patches-4.19.x-rt/0143-rtmutex-Provide-rt_mutex_slowlock_locked.patch index db00912bf..7bef86044 100644 --- a/kernel/patches-4.14.x-rt/0252-rtmutex-Provide-rt_mutex_slowlock_locked.patch +++ b/kernel/patches-4.19.x-rt/0143-rtmutex-Provide-rt_mutex_slowlock_locked.patch @@ -1,22 +1,19 @@ -From 4fbcfcdb022d94fcd81bd7139552627582c55ea9 Mon Sep 17 00:00:00 2001 From: Thomas Gleixner Date: Thu, 12 Oct 2017 16:14:22 +0200 -Subject: [PATCH 252/450] rtmutex: Provide rt_mutex_slowlock_locked() +Subject: rtmutex: Provide rt_mutex_slowlock_locked() This is the inner-part of rt_mutex_slowlock(), required for rwsem-rt. Signed-off-by: Thomas Gleixner Signed-off-by: Sebastian Andrzej Siewior --- - kernel/locking/rtmutex.c | 70 +++++++++++++++++++-------------- - kernel/locking/rtmutex_common.h | 6 +++ - 2 files changed, 46 insertions(+), 30 deletions(-) + kernel/locking/rtmutex.c | 67 ++++++++++++++++++++++------------------ + kernel/locking/rtmutex_common.h | 7 ++++ + 2 files changed, 45 insertions(+), 29 deletions(-) -diff --git a/kernel/locking/rtmutex.c b/kernel/locking/rtmutex.c -index 5f2b7609693f..1ae8d883c439 100644 --- a/kernel/locking/rtmutex.c +++ b/kernel/locking/rtmutex.c -@@ -1244,35 +1244,16 @@ static void rt_mutex_handle_deadlock(int res, int detect_deadlock, +@@ -1244,35 +1244,16 @@ static void rt_mutex_handle_deadlock(int } } @@ -58,31 +55,28 @@ index 5f2b7609693f..1ae8d883c439 100644 set_current_state(state); -@@ -1280,17 +1261,18 @@ rt_mutex_slowlock(struct rt_mutex *lock, int state, +@@ -1280,16 +1261,16 @@ rt_mutex_slowlock(struct rt_mutex *lock, if (unlikely(timeout)) hrtimer_start_expires(&timeout->timer, HRTIMER_MODE_ABS); - ret = task_blocks_on_rt_mutex(lock, &waiter, current, chwalk); + ret = task_blocks_on_rt_mutex(lock, waiter, current, chwalk); -- if (likely(!ret)) -+ if (likely(!ret)) { + if (likely(!ret)) /* sleep on the mutex */ - ret = __rt_mutex_slowlock(lock, state, timeout, &waiter); + ret = __rt_mutex_slowlock(lock, state, timeout, waiter); -+ } if (unlikely(ret)) { __set_current_state(TASK_RUNNING); - if (rt_mutex_has_waiters(lock)) -- remove_waiter(lock, &waiter); +- remove_waiter(lock, &waiter); - rt_mutex_handle_deadlock(ret, chwalk, &waiter); -+ remove_waiter(lock, waiter); -+ /* ww_mutex want to report EDEADLK/EALREADY, let them */ ++ remove_waiter(lock, waiter); ++ rt_mutex_handle_deadlock(ret, chwalk, waiter); } /* -@@ -1298,6 +1280,34 @@ rt_mutex_slowlock(struct rt_mutex *lock, int state, +@@ -1297,6 +1278,34 @@ rt_mutex_slowlock(struct rt_mutex *lock, * unconditionally. We might have to fix that up. */ fixup_rt_mutex_waiters(lock); @@ -117,11 +111,17 @@ index 5f2b7609693f..1ae8d883c439 100644 raw_spin_unlock_irqrestore(&lock->wait_lock, flags); -diff --git a/kernel/locking/rtmutex_common.h b/kernel/locking/rtmutex_common.h -index 509df18215f8..3b10fde6fd1f 100644 --- a/kernel/locking/rtmutex_common.h +++ b/kernel/locking/rtmutex_common.h -@@ -158,6 +158,12 @@ extern bool __rt_mutex_futex_unlock(struct rt_mutex *lock, +@@ -15,6 +15,7 @@ + + #include + #include ++#include + + /* + * This is the control structure for tasks blocked on a rt_mutex, +@@ -159,6 +160,12 @@ extern bool __rt_mutex_futex_unlock(stru struct wake_q_head *wqh); extern void rt_mutex_postunlock(struct wake_q_head *wake_q); @@ -134,6 +134,3 @@ index 509df18215f8..3b10fde6fd1f 100644 #ifdef CONFIG_DEBUG_RT_MUTEXES # include "rtmutex-debug.h" --- -2.19.2 - diff --git a/kernel/patches-4.14.x-rt/0253-rtmutex-export-lockdep-less-version-of-rt_mutex-s-lo.patch b/kernel/patches-4.19.x-rt/0144-rtmutex-export-lockdep-less-version-of-rt_mutex-s-lo.patch similarity index 61% rename from kernel/patches-4.14.x-rt/0253-rtmutex-export-lockdep-less-version-of-rt_mutex-s-lo.patch rename to kernel/patches-4.19.x-rt/0144-rtmutex-export-lockdep-less-version-of-rt_mutex-s-lo.patch index 3a08f7f45..aa364eeb2 100644 --- a/kernel/patches-4.14.x-rt/0253-rtmutex-export-lockdep-less-version-of-rt_mutex-s-lo.patch +++ b/kernel/patches-4.19.x-rt/0144-rtmutex-export-lockdep-less-version-of-rt_mutex-s-lo.patch @@ -1,23 +1,20 @@ -From d04ec21118f4a3360a274c5bbb3d7c39c9b09e63 Mon Sep 17 00:00:00 2001 From: Thomas Gleixner Date: Thu, 12 Oct 2017 16:36:39 +0200 -Subject: [PATCH 253/450] rtmutex: export lockdep-less version of rt_mutex's - lock, trylock and unlock +Subject: rtmutex: export lockdep-less version of rt_mutex's lock, + trylock and unlock Required for lock implementation ontop of rtmutex. Signed-off-by: Thomas Gleixner Signed-off-by: Sebastian Andrzej Siewior --- - kernel/locking/rtmutex.c | 65 ++++++++++++++++++++------------- - kernel/locking/rtmutex_common.h | 3 ++ - 2 files changed, 42 insertions(+), 26 deletions(-) + kernel/locking/rtmutex.c | 67 +++++++++++++++++++++++++--------------- + kernel/locking/rtmutex_common.h | 3 + + 2 files changed, 46 insertions(+), 24 deletions(-) -diff --git a/kernel/locking/rtmutex.c b/kernel/locking/rtmutex.c -index 1ae8d883c439..2367afc60405 100644 --- a/kernel/locking/rtmutex.c +++ b/kernel/locking/rtmutex.c -@@ -1496,12 +1496,27 @@ rt_mutex_fastunlock(struct rt_mutex *lock, +@@ -1494,12 +1494,33 @@ rt_mutex_fastunlock(struct rt_mutex *loc rt_mutex_postunlock(&wake_q); } @@ -25,7 +22,7 @@ index 1ae8d883c439..2367afc60405 100644 +int __sched __rt_mutex_lock_state(struct rt_mutex *lock, int state) { might_sleep(); -+ return rt_mutex_fastlock(lock, state, NULL, rt_mutex_slowlock); ++ return rt_mutex_fastlock(lock, state, rt_mutex_slowlock); +} + +/** @@ -34,7 +31,8 @@ index 1ae8d883c439..2367afc60405 100644 + * @lock: The rt_mutex to be locked + * @state: The state to set when blocking on the rt_mutex + */ -+static int __sched rt_mutex_lock_state(struct rt_mutex *lock, int state, unsigned int subclass) ++static inline int __sched rt_mutex_lock_state(struct rt_mutex *lock, ++ unsigned int subclass, int state) +{ + int ret; @@ -44,28 +42,15 @@ index 1ae8d883c439..2367afc60405 100644 + if (ret) + mutex_release(&lock->dep_map, 1, _RET_IP_); + return ret; ++} ++ ++static inline void __rt_mutex_lock(struct rt_mutex *lock, unsigned int subclass) ++{ ++ rt_mutex_lock_state(lock, subclass, TASK_UNINTERRUPTIBLE); } #ifdef CONFIG_DEBUG_LOCK_ALLOC -@@ -1513,7 +1528,7 @@ static inline void __rt_mutex_lock(struct rt_mutex *lock, unsigned int subclass) - */ - void __sched rt_mutex_lock_nested(struct rt_mutex *lock, unsigned int subclass) - { -- __rt_mutex_lock(lock, subclass); -+ rt_mutex_lock_state(lock, TASK_UNINTERRUPTIBLE, subclass); - } - EXPORT_SYMBOL_GPL(rt_mutex_lock_nested); - #endif -@@ -1526,7 +1541,7 @@ EXPORT_SYMBOL_GPL(rt_mutex_lock_nested); - */ - void __sched rt_mutex_lock(struct rt_mutex *lock) - { -- __rt_mutex_lock(lock, 0); -+ rt_mutex_lock_state(lock, TASK_UNINTERRUPTIBLE, 0); - } - EXPORT_SYMBOL_GPL(rt_mutex_lock); - #endif -@@ -1542,16 +1557,7 @@ EXPORT_SYMBOL_GPL(rt_mutex_lock); +@@ -1540,16 +1561,7 @@ EXPORT_SYMBOL_GPL(rt_mutex_lock); */ int __sched rt_mutex_lock_interruptible(struct rt_mutex *lock) { @@ -79,11 +64,11 @@ index 1ae8d883c439..2367afc60405 100644 - mutex_release(&lock->dep_map, 1, _RET_IP_); - - return ret; -+ return rt_mutex_lock_state(lock, TASK_INTERRUPTIBLE, 0); ++ return rt_mutex_lock_state(lock, 0, TASK_INTERRUPTIBLE); } EXPORT_SYMBOL_GPL(rt_mutex_lock_interruptible); -@@ -1577,13 +1583,10 @@ int __sched __rt_mutex_futex_trylock(struct rt_mutex *lock) +@@ -1575,13 +1587,10 @@ int __sched __rt_mutex_futex_trylock(str * Returns: * 0 on success * -EINTR when interrupted by a signal @@ -94,11 +79,11 @@ index 1ae8d883c439..2367afc60405 100644 - might_sleep(); - - return rt_mutex_fastlock(lock, TASK_KILLABLE, rt_mutex_slowlock); -+ return rt_mutex_lock_state(lock, TASK_KILLABLE, 0); ++ return rt_mutex_lock_state(lock, 0, TASK_KILLABLE); } EXPORT_SYMBOL_GPL(rt_mutex_lock_killable); -@@ -1618,6 +1621,18 @@ rt_mutex_timed_lock(struct rt_mutex *lock, struct hrtimer_sleeper *timeout) +@@ -1616,6 +1625,18 @@ rt_mutex_timed_lock(struct rt_mutex *loc } EXPORT_SYMBOL_GPL(rt_mutex_timed_lock); @@ -117,7 +102,7 @@ index 1ae8d883c439..2367afc60405 100644 /** * rt_mutex_trylock - try to lock a rt_mutex * -@@ -1633,14 +1648,7 @@ int __sched rt_mutex_trylock(struct rt_mutex *lock) +@@ -1631,14 +1652,7 @@ int __sched rt_mutex_trylock(struct rt_m { int ret; @@ -133,7 +118,7 @@ index 1ae8d883c439..2367afc60405 100644 if (ret) mutex_acquire(&lock->dep_map, 0, 1, _RET_IP_); -@@ -1648,6 +1656,11 @@ int __sched rt_mutex_trylock(struct rt_mutex *lock) +@@ -1646,6 +1660,11 @@ int __sched rt_mutex_trylock(struct rt_m } EXPORT_SYMBOL_GPL(rt_mutex_trylock); @@ -145,11 +130,9 @@ index 1ae8d883c439..2367afc60405 100644 /** * rt_mutex_unlock - unlock a rt_mutex * -diff --git a/kernel/locking/rtmutex_common.h b/kernel/locking/rtmutex_common.h -index 3b10fde6fd1f..ff17912f869c 100644 --- a/kernel/locking/rtmutex_common.h +++ b/kernel/locking/rtmutex_common.h -@@ -160,6 +160,9 @@ extern bool __rt_mutex_futex_unlock(struct rt_mutex *lock, +@@ -162,6 +162,9 @@ extern bool __rt_mutex_futex_unlock(stru extern void rt_mutex_postunlock(struct wake_q_head *wake_q); /* RW semaphore special interface */ @@ -159,6 +142,3 @@ index 3b10fde6fd1f..ff17912f869c 100644 int __sched rt_mutex_slowlock_locked(struct rt_mutex *lock, int state, struct hrtimer_sleeper *timeout, enum rtmutex_chainwalk chwalk, --- -2.19.2 - diff --git a/kernel/patches-4.14.x-rt/0254-rtmutex-add-sleeping-lock-implementation.patch b/kernel/patches-4.19.x-rt/0145-rtmutex-add-sleeping-lock-implementation.patch similarity index 83% rename from kernel/patches-4.14.x-rt/0254-rtmutex-add-sleeping-lock-implementation.patch rename to kernel/patches-4.19.x-rt/0145-rtmutex-add-sleeping-lock-implementation.patch index bf35d53a9..915dc6e99 100644 --- a/kernel/patches-4.14.x-rt/0254-rtmutex-add-sleeping-lock-implementation.patch +++ b/kernel/patches-4.19.x-rt/0145-rtmutex-add-sleeping-lock-implementation.patch @@ -1,31 +1,28 @@ -From 64f504e34e6123f04c506325bbb231e879a03390 Mon Sep 17 00:00:00 2001 From: Thomas Gleixner Date: Thu, 12 Oct 2017 17:11:19 +0200 -Subject: [PATCH 254/450] rtmutex: add sleeping lock implementation +Subject: rtmutex: add sleeping lock implementation Signed-off-by: Thomas Gleixner Signed-off-by: Sebastian Andrzej Siewior --- - include/linux/kernel.h | 4 + - include/linux/rtmutex.h | 21 +- - include/linux/sched.h | 9 + - include/linux/sched/wake_q.h | 27 +- - include/linux/spinlock_rt.h | 159 +++++++++++ - include/linux/spinlock_types_rt.h | 48 ++++ - kernel/fork.c | 1 + - kernel/futex.c | 11 +- - kernel/locking/rtmutex.c | 449 +++++++++++++++++++++++++++--- - kernel/locking/rtmutex_common.h | 15 +- - kernel/sched/core.c | 28 +- - 11 files changed, 713 insertions(+), 59 deletions(-) + include/linux/kernel.h | 4 + include/linux/rtmutex.h | 21 + + include/linux/sched.h | 8 + include/linux/sched/wake_q.h | 27 ++ + include/linux/spinlock_rt.h | 156 +++++++++++++ + include/linux/spinlock_types_rt.h | 48 ++++ + kernel/fork.c | 1 + kernel/futex.c | 11 + kernel/locking/rtmutex.c | 436 ++++++++++++++++++++++++++++++++++---- + kernel/locking/rtmutex_common.h | 14 - + kernel/sched/core.c | 28 +- + 11 files changed, 695 insertions(+), 59 deletions(-) create mode 100644 include/linux/spinlock_rt.h create mode 100644 include/linux/spinlock_types_rt.h -diff --git a/include/linux/kernel.h b/include/linux/kernel.h -index f696993c052c..74feebf9d82c 100644 --- a/include/linux/kernel.h +++ b/include/linux/kernel.h -@@ -225,6 +225,9 @@ extern int _cond_resched(void); +@@ -259,6 +259,9 @@ extern int _cond_resched(void); */ # define might_sleep() \ do { __might_sleep(__FILE__, __LINE__, 0); might_resched(); } while (0) @@ -35,7 +32,7 @@ index f696993c052c..74feebf9d82c 100644 # define sched_annotate_sleep() (current->task_state_change = 0) #else static inline void ___might_sleep(const char *file, int line, -@@ -232,6 +235,7 @@ extern int _cond_resched(void); +@@ -266,6 +269,7 @@ extern int _cond_resched(void); static inline void __might_sleep(const char *file, int line, int preempt_offset) { } # define might_sleep() do { might_resched(); } while (0) @@ -43,8 +40,6 @@ index f696993c052c..74feebf9d82c 100644 # define sched_annotate_sleep() do { } while (0) #endif -diff --git a/include/linux/rtmutex.h b/include/linux/rtmutex.h -index a355289b1fa1..138bd1e183e0 100644 --- a/include/linux/rtmutex.h +++ b/include/linux/rtmutex.h @@ -14,11 +14,15 @@ @@ -101,33 +96,37 @@ index a355289b1fa1..138bd1e183e0 100644 /** * rt_mutex_is_locked - is the mutex locked * @lock: the mutex to be queried -diff --git a/include/linux/sched.h b/include/linux/sched.h -index ee6f6d3501de..1b5cc9f148d6 100644 --- a/include/linux/sched.h +++ b/include/linux/sched.h -@@ -133,6 +133,11 @@ struct task_group; +@@ -134,6 +134,9 @@ struct task_group; smp_store_mb(current->state, (state_value)); \ } while (0) +#define __set_current_state_no_track(state_value) \ -+ current->state = (state_value); -+#define set_current_state_no_track(state_value) \ -+ smp_store_mb(current->state, (state_value)); ++ current->state = (state_value); + #define set_special_state(state_value) \ do { \ unsigned long flags; /* may shadow */ \ -@@ -186,6 +191,9 @@ struct task_group; +@@ -143,6 +146,7 @@ struct task_group; + current->state = (state_value); \ + raw_spin_unlock_irqrestore(¤t->pi_lock, flags); \ + } while (0) ++ + #else + /* + * set_current_state() includes a barrier so that the write of current->state +@@ -187,6 +191,9 @@ struct task_group; #define set_current_state(state_value) \ smp_store_mb(current->state, (state_value)) -+#define __set_current_state_no_track(state_value) __set_current_state(state_value) -+#define set_current_state_no_track(state_value) set_current_state(state_value) ++#define __set_current_state_no_track(state_value) \ ++ __set_current_state(state_value) + /* * set_special_state() should be used for those states when the blocking task * can not use the regular condition based wait-loop. In that case we must -@@ -867,6 +875,7 @@ struct task_struct { +@@ -914,6 +921,7 @@ struct task_struct { raw_spinlock_t pi_lock; struct wake_q_node wake_q; @@ -135,11 +134,9 @@ index ee6f6d3501de..1b5cc9f148d6 100644 #ifdef CONFIG_RT_MUTEXES /* PI waiters blocked on a rt_mutex held by this task: */ -diff --git a/include/linux/sched/wake_q.h b/include/linux/sched/wake_q.h -index 10b19a192b2d..ce3ccff3d9d8 100644 --- a/include/linux/sched/wake_q.h +++ b/include/linux/sched/wake_q.h -@@ -47,8 +47,29 @@ static inline void wake_q_init(struct wake_q_head *head) +@@ -47,8 +47,29 @@ static inline void wake_q_init(struct wa head->lastp = &head->first; } @@ -172,12 +169,9 @@ index 10b19a192b2d..ce3ccff3d9d8 100644 +} #endif /* _LINUX_SCHED_WAKE_Q_H */ -diff --git a/include/linux/spinlock_rt.h b/include/linux/spinlock_rt.h -new file mode 100644 -index 000000000000..c95e1f5145ac --- /dev/null +++ b/include/linux/spinlock_rt.h -@@ -0,0 +1,159 @@ +@@ -0,0 +1,156 @@ +#ifndef __LINUX_SPINLOCK_RT_H +#define __LINUX_SPINLOCK_RT_H + @@ -333,13 +327,7 @@ index 000000000000..c95e1f5145ac + BUG_ON(!spin_is_locked(lock)); +} + -+#define atomic_dec_and_lock(atomic, lock) \ -+ atomic_dec_and_spin_lock(atomic, lock) -+ +#endif -diff --git a/include/linux/spinlock_types_rt.h b/include/linux/spinlock_types_rt.h -new file mode 100644 -index 000000000000..3e3d8c5f7a9a --- /dev/null +++ b/include/linux/spinlock_types_rt.h @@ -0,0 +1,48 @@ @@ -391,11 +379,9 @@ index 000000000000..3e3d8c5f7a9a + spinlock_t name = __SPIN_LOCK_UNLOCKED(name) + +#endif -diff --git a/kernel/fork.c b/kernel/fork.c -index 787105e3bf1b..bc849ac60aa6 100644 --- a/kernel/fork.c +++ b/kernel/fork.c -@@ -599,6 +599,7 @@ static struct task_struct *dup_task_struct(struct task_struct *orig, int node) +@@ -895,6 +895,7 @@ static struct task_struct *dup_task_stru tsk->splice_pipe = NULL; tsk->task_frag.page = NULL; tsk->wake_q.next = NULL; @@ -403,11 +389,9 @@ index 787105e3bf1b..bc849ac60aa6 100644 account_kernel_stack(tsk, 1); -diff --git a/kernel/futex.c b/kernel/futex.c -index 7540d5c425ac..2ba7fb04a107 100644 --- a/kernel/futex.c +++ b/kernel/futex.c -@@ -1432,6 +1432,7 @@ static int wake_futex_pi(u32 __user *uaddr, u32 uval, struct futex_pi_state *pi_ +@@ -1471,6 +1471,7 @@ static int wake_futex_pi(u32 __user *uad struct task_struct *new_owner; bool postunlock = false; DEFINE_WAKE_Q(wake_q); @@ -415,7 +399,7 @@ index 7540d5c425ac..2ba7fb04a107 100644 int ret = 0; new_owner = rt_mutex_next_owner(&pi_state->pi_mutex); -@@ -1493,13 +1494,13 @@ static int wake_futex_pi(u32 __user *uaddr, u32 uval, struct futex_pi_state *pi_ +@@ -1532,13 +1533,13 @@ static int wake_futex_pi(u32 __user *uad pi_state->owner = new_owner; raw_spin_unlock(&new_owner->pi_lock); @@ -432,7 +416,7 @@ index 7540d5c425ac..2ba7fb04a107 100644 return ret; } -@@ -2811,7 +2812,7 @@ static int futex_lock_pi(u32 __user *uaddr, unsigned int flags, +@@ -2850,7 +2851,7 @@ static int futex_lock_pi(u32 __user *uad goto no_block; } @@ -441,7 +425,7 @@ index 7540d5c425ac..2ba7fb04a107 100644 /* * On PREEMPT_RT_FULL, when hb->lock becomes an rt_mutex, we must not -@@ -3183,7 +3184,7 @@ static int futex_wait_requeue_pi(u32 __user *uaddr, unsigned int flags, +@@ -3230,7 +3231,7 @@ static int futex_wait_requeue_pi(u32 __u * The waiter is allocated on our stack, manipulated by the requeue * code while we sleep on uaddr. */ @@ -450,8 +434,6 @@ index 7540d5c425ac..2ba7fb04a107 100644 ret = get_futex_key(uaddr2, flags & FLAGS_SHARED, &key2, VERIFY_WRITE); if (unlikely(ret != 0)) -diff --git a/kernel/locking/rtmutex.c b/kernel/locking/rtmutex.c -index 2367afc60405..827546ba5a47 100644 --- a/kernel/locking/rtmutex.c +++ b/kernel/locking/rtmutex.c @@ -7,6 +7,11 @@ @@ -466,7 +448,7 @@ index 2367afc60405..827546ba5a47 100644 * * See Documentation/locking/rt-mutex-design.txt for details. */ -@@ -234,7 +239,7 @@ static inline bool unlock_rt_mutex_safe(struct rt_mutex *lock, +@@ -234,7 +239,7 @@ static inline bool unlock_rt_mutex_safe( * Only use with rt_mutex_waiter_{less,equal}() */ #define task_to_waiter(p) \ @@ -475,7 +457,7 @@ index 2367afc60405..827546ba5a47 100644 static inline int rt_mutex_waiter_less(struct rt_mutex_waiter *left, -@@ -274,6 +279,27 @@ rt_mutex_waiter_equal(struct rt_mutex_waiter *left, +@@ -274,6 +279,27 @@ rt_mutex_waiter_equal(struct rt_mutex_wa return 1; } @@ -503,7 +485,7 @@ index 2367afc60405..827546ba5a47 100644 static void rt_mutex_enqueue(struct rt_mutex *lock, struct rt_mutex_waiter *waiter) { -@@ -378,6 +404,14 @@ static bool rt_mutex_cond_detect_deadlock(struct rt_mutex_waiter *waiter, +@@ -378,6 +404,14 @@ static bool rt_mutex_cond_detect_deadloc return debug_rt_mutex_detect_deadlock(waiter, chwalk); } @@ -518,7 +500,7 @@ index 2367afc60405..827546ba5a47 100644 /* * Max number of times we'll walk the boosting chain: */ -@@ -703,13 +737,16 @@ static int rt_mutex_adjust_prio_chain(struct task_struct *task, +@@ -703,13 +737,16 @@ static int rt_mutex_adjust_prio_chain(st * follow here. This is the end of the chain we are walking. */ if (!rt_mutex_owner(lock)) { @@ -537,7 +519,7 @@ index 2367afc60405..827546ba5a47 100644 raw_spin_unlock_irq(&lock->wait_lock); return 0; } -@@ -811,9 +848,11 @@ static int rt_mutex_adjust_prio_chain(struct task_struct *task, +@@ -811,9 +848,11 @@ static int rt_mutex_adjust_prio_chain(st * @task: The task which wants to acquire the lock * @waiter: The waiter that is queued to the lock's wait tree if the * callsite called task_blocked_on_lock(), otherwise NULL @@ -551,7 +533,7 @@ index 2367afc60405..827546ba5a47 100644 { lockdep_assert_held(&lock->wait_lock); -@@ -849,12 +888,11 @@ static int try_to_take_rt_mutex(struct rt_mutex *lock, struct task_struct *task, +@@ -849,12 +888,11 @@ static int try_to_take_rt_mutex(struct r */ if (waiter) { /* @@ -567,7 +549,7 @@ index 2367afc60405..827546ba5a47 100644 /* * We can acquire the lock. Remove the waiter from the * lock waiters tree. -@@ -872,14 +910,12 @@ static int try_to_take_rt_mutex(struct rt_mutex *lock, struct task_struct *task, +@@ -872,14 +910,12 @@ static int try_to_take_rt_mutex(struct r */ if (rt_mutex_has_waiters(lock)) { /* @@ -586,7 +568,7 @@ index 2367afc60405..827546ba5a47 100644 /* * The current top waiter stays enqueued. We * don't have to change anything in the lock -@@ -926,6 +962,309 @@ static int try_to_take_rt_mutex(struct rt_mutex *lock, struct task_struct *task, +@@ -926,6 +962,296 @@ static int try_to_take_rt_mutex(struct r return 1; } @@ -858,19 +840,6 @@ index 2367afc60405..827546ba5a47 100644 +} +EXPORT_SYMBOL(rt_spin_trylock_irqsave); + -+int atomic_dec_and_spin_lock(atomic_t *atomic, spinlock_t *lock) -+{ -+ /* Subtract 1 from counter unless that drops it to 0 (ie. it was 1) */ -+ if (atomic_add_unless(atomic, -1, 1)) -+ return 0; -+ rt_spin_lock(lock); -+ if (atomic_dec_and_test(atomic)) -+ return 1; -+ rt_spin_unlock(lock); -+ return 0; -+} -+EXPORT_SYMBOL(atomic_dec_and_spin_lock); -+ +void +__rt_spin_lock_init(spinlock_t *lock, const char *name, struct lock_class_key *key) +{ @@ -896,7 +865,7 @@ index 2367afc60405..827546ba5a47 100644 /* * Task blocks on lock. * -@@ -1039,6 +1378,7 @@ static int task_blocks_on_rt_mutex(struct rt_mutex *lock, +@@ -1039,6 +1365,7 @@ static int task_blocks_on_rt_mutex(struc * Called with lock->wait_lock held and interrupts disabled. */ static void mark_wakeup_next_waiter(struct wake_q_head *wake_q, @@ -904,7 +873,7 @@ index 2367afc60405..827546ba5a47 100644 struct rt_mutex *lock) { struct rt_mutex_waiter *waiter; -@@ -1078,7 +1418,10 @@ static void mark_wakeup_next_waiter(struct wake_q_head *wake_q, +@@ -1078,7 +1405,10 @@ static void mark_wakeup_next_waiter(stru * Pairs with preempt_enable() in rt_mutex_postunlock(); */ preempt_disable(); @@ -916,7 +885,7 @@ index 2367afc60405..827546ba5a47 100644 raw_spin_unlock(¤t->pi_lock); } -@@ -1162,21 +1505,22 @@ void rt_mutex_adjust_pi(struct task_struct *task) +@@ -1162,21 +1492,22 @@ void rt_mutex_adjust_pi(struct task_stru return; } next_lock = waiter->lock; @@ -941,7 +910,7 @@ index 2367afc60405..827546ba5a47 100644 } /** -@@ -1295,7 +1639,7 @@ rt_mutex_slowlock(struct rt_mutex *lock, int state, +@@ -1293,7 +1624,7 @@ rt_mutex_slowlock(struct rt_mutex *lock, unsigned long flags; int ret = 0; @@ -950,7 +919,7 @@ index 2367afc60405..827546ba5a47 100644 /* * Technically we could use raw_spin_[un]lock_irq() here, but this can -@@ -1368,7 +1712,8 @@ static inline int rt_mutex_slowtrylock(struct rt_mutex *lock) +@@ -1366,7 +1697,8 @@ static inline int rt_mutex_slowtrylock(s * Return whether the current task needs to call rt_mutex_postunlock(). */ static bool __sched rt_mutex_slowunlock(struct rt_mutex *lock, @@ -960,7 +929,7 @@ index 2367afc60405..827546ba5a47 100644 { unsigned long flags; -@@ -1422,7 +1767,7 @@ static bool __sched rt_mutex_slowunlock(struct rt_mutex *lock, +@@ -1420,7 +1752,7 @@ static bool __sched rt_mutex_slowunlock( * * Queue the next waiter for wakeup once we release the wait_lock. */ @@ -969,7 +938,7 @@ index 2367afc60405..827546ba5a47 100644 raw_spin_unlock_irqrestore(&lock->wait_lock, flags); return true; /* call rt_mutex_postunlock() */ -@@ -1474,9 +1819,11 @@ rt_mutex_fasttrylock(struct rt_mutex *lock, +@@ -1472,9 +1804,11 @@ rt_mutex_fasttrylock(struct rt_mutex *lo /* * Performs the wakeup of the the top-waiter and re-enables preemption. */ @@ -982,7 +951,7 @@ index 2367afc60405..827546ba5a47 100644 /* Pairs with preempt_disable() in rt_mutex_slowunlock() */ preempt_enable(); -@@ -1485,15 +1832,17 @@ void rt_mutex_postunlock(struct wake_q_head *wake_q) +@@ -1483,15 +1817,17 @@ void rt_mutex_postunlock(struct wake_q_h static inline void rt_mutex_fastunlock(struct rt_mutex *lock, bool (*slowfn)(struct rt_mutex *lock, @@ -1003,7 +972,7 @@ index 2367afc60405..827546ba5a47 100644 } int __sched __rt_mutex_lock_state(struct rt_mutex *lock, int state) -@@ -1669,16 +2018,13 @@ void __sched __rt_mutex_unlock(struct rt_mutex *lock) +@@ -1673,16 +2009,13 @@ void __sched __rt_mutex_unlock(struct rt void __sched rt_mutex_unlock(struct rt_mutex *lock) { mutex_release(&lock->dep_map, 1, _RET_IP_); @@ -1024,7 +993,7 @@ index 2367afc60405..827546ba5a47 100644 { lockdep_assert_held(&lock->wait_lock); -@@ -1695,23 +2041,35 @@ bool __sched __rt_mutex_futex_unlock(struct rt_mutex *lock, +@@ -1699,23 +2032,35 @@ bool __sched __rt_mutex_futex_unlock(str * avoid inversion prior to the wakeup. preempt_disable() * therein pairs with rt_mutex_postunlock(). */ @@ -1039,8 +1008,8 @@ index 2367afc60405..827546ba5a47 100644 + * simple and will not need to retry. + */ +bool __sched __rt_mutex_futex_unlock(struct rt_mutex *lock, -+ struct wake_q_head *wake_q, -+ struct wake_q_head *wq_sleeper) ++ struct wake_q_head *wake_q, ++ struct wake_q_head *wq_sleeper) +{ + return __rt_mutex_unlock_common(lock, wake_q, wq_sleeper); +} @@ -1063,7 +1032,7 @@ index 2367afc60405..827546ba5a47 100644 } /** -@@ -1750,7 +2108,7 @@ void __rt_mutex_init(struct rt_mutex *lock, const char *name, +@@ -1754,7 +2099,7 @@ void __rt_mutex_init(struct rt_mutex *lo if (name && key) debug_rt_mutex_init(lock, name, key); } @@ -1072,7 +1041,7 @@ index 2367afc60405..827546ba5a47 100644 /** * rt_mutex_init_proxy_locked - initialize and lock a rt_mutex on behalf of a -@@ -1919,6 +2277,7 @@ int rt_mutex_wait_proxy_lock(struct rt_mutex *lock, +@@ -1949,6 +2294,7 @@ int rt_mutex_wait_proxy_lock(struct rt_m struct hrtimer_sleeper *to, struct rt_mutex_waiter *waiter) { @@ -1080,7 +1049,7 @@ index 2367afc60405..827546ba5a47 100644 int ret; raw_spin_lock_irq(&lock->wait_lock); -@@ -1930,6 +2289,24 @@ int rt_mutex_wait_proxy_lock(struct rt_mutex *lock, +@@ -1960,6 +2306,24 @@ int rt_mutex_wait_proxy_lock(struct rt_m * have to fix that up. */ fixup_rt_mutex_waiters(lock); @@ -1105,19 +1074,9 @@ index 2367afc60405..827546ba5a47 100644 raw_spin_unlock_irq(&lock->wait_lock); return ret; -diff --git a/kernel/locking/rtmutex_common.h b/kernel/locking/rtmutex_common.h -index ff17912f869c..2d822a08c87d 100644 --- a/kernel/locking/rtmutex_common.h +++ b/kernel/locking/rtmutex_common.h -@@ -15,6 +15,7 @@ - - #include - #include -+#include - - /* - * This is the control structure for tasks blocked on a rt_mutex, -@@ -29,6 +30,7 @@ struct rt_mutex_waiter { +@@ -30,6 +30,7 @@ struct rt_mutex_waiter { struct rb_node pi_tree_entry; struct task_struct *task; struct rt_mutex *lock; @@ -1125,7 +1084,7 @@ index ff17912f869c..2d822a08c87d 100644 #ifdef CONFIG_DEBUG_RT_MUTEXES unsigned long ip; struct pid *deadlock_task_pid; -@@ -137,7 +139,7 @@ extern void rt_mutex_init_proxy_locked(struct rt_mutex *lock, +@@ -139,7 +140,7 @@ extern void rt_mutex_init_proxy_locked(s struct task_struct *proxy_owner); extern void rt_mutex_proxy_unlock(struct rt_mutex *lock, struct task_struct *proxy_owner); @@ -1134,7 +1093,7 @@ index ff17912f869c..2d822a08c87d 100644 extern int __rt_mutex_start_proxy_lock(struct rt_mutex *lock, struct rt_mutex_waiter *waiter, struct task_struct *task); -@@ -155,9 +157,12 @@ extern int __rt_mutex_futex_trylock(struct rt_mutex *l); +@@ -157,9 +158,12 @@ extern int __rt_mutex_futex_trylock(stru extern void rt_mutex_futex_unlock(struct rt_mutex *lock); extern bool __rt_mutex_futex_unlock(struct rt_mutex *lock, @@ -1149,7 +1108,7 @@ index ff17912f869c..2d822a08c87d 100644 /* RW semaphore special interface */ extern int __rt_mutex_lock_state(struct rt_mutex *lock, int state); -@@ -167,6 +172,10 @@ int __sched rt_mutex_slowlock_locked(struct rt_mutex *lock, int state, +@@ -169,6 +173,10 @@ int __sched rt_mutex_slowlock_locked(str struct hrtimer_sleeper *timeout, enum rtmutex_chainwalk chwalk, struct rt_mutex_waiter *waiter); @@ -1160,11 +1119,9 @@ index ff17912f869c..2d822a08c87d 100644 #ifdef CONFIG_DEBUG_RT_MUTEXES # include "rtmutex-debug.h" -diff --git a/kernel/sched/core.c b/kernel/sched/core.c -index e4c9a2f745cf..b34002b6c91b 100644 --- a/kernel/sched/core.c +++ b/kernel/sched/core.c -@@ -427,9 +427,15 @@ static bool set_nr_if_polling(struct task_struct *p) +@@ -400,9 +400,15 @@ static bool set_nr_if_polling(struct tas #endif #endif @@ -1182,7 +1139,7 @@ index e4c9a2f745cf..b34002b6c91b 100644 /* * Atomically grab the task, if ->wake_q is !nil already it means -@@ -451,24 +457,32 @@ void wake_q_add(struct wake_q_head *head, struct task_struct *task) +@@ -424,24 +430,32 @@ void wake_q_add(struct wake_q_head *head head->lastp = &node->next; } @@ -1209,8 +1166,8 @@ index e4c9a2f745cf..b34002b6c91b 100644 + else + task->wake_q.next = NULL; /* - * wake_up_process() implies a wmb() to pair with the queueing - * in wake_q_add() so as not to miss wakeups. + * wake_up_process() executes a full barrier, which pairs with + * the queueing in wake_q_add() so as not to miss wakeups. */ - wake_up_process(task); + if (sleeper) @@ -1220,6 +1177,3 @@ index e4c9a2f745cf..b34002b6c91b 100644 put_task_struct(task); } } --- -2.19.2 - diff --git a/kernel/patches-4.14.x-rt/0255-rtmutex-add-mutex-implementation-based-on-rtmutex.patch b/kernel/patches-4.19.x-rt/0146-rtmutex-add-mutex-implementation-based-on-rtmutex.patch similarity index 95% rename from kernel/patches-4.14.x-rt/0255-rtmutex-add-mutex-implementation-based-on-rtmutex.patch rename to kernel/patches-4.19.x-rt/0146-rtmutex-add-mutex-implementation-based-on-rtmutex.patch index 0817d9c90..783831268 100644 --- a/kernel/patches-4.14.x-rt/0255-rtmutex-add-mutex-implementation-based-on-rtmutex.patch +++ b/kernel/patches-4.19.x-rt/0146-rtmutex-add-mutex-implementation-based-on-rtmutex.patch @@ -1,20 +1,16 @@ -From 218562664afcb7a8d6439e04cbe06fb2e4a322f6 Mon Sep 17 00:00:00 2001 From: Thomas Gleixner Date: Thu, 12 Oct 2017 17:17:03 +0200 -Subject: [PATCH 255/450] rtmutex: add mutex implementation based on rtmutex +Subject: rtmutex: add mutex implementation based on rtmutex Signed-off-by: Thomas Gleixner Signed-off-by: Sebastian Andrzej Siewior --- - include/linux/mutex_rt.h | 130 ++++++++++++++++++++++ - kernel/locking/mutex-rt.c | 223 ++++++++++++++++++++++++++++++++++++++ + include/linux/mutex_rt.h | 130 ++++++++++++++++++++++++++ + kernel/locking/mutex-rt.c | 223 ++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 353 insertions(+) create mode 100644 include/linux/mutex_rt.h create mode 100644 kernel/locking/mutex-rt.c -diff --git a/include/linux/mutex_rt.h b/include/linux/mutex_rt.h -new file mode 100644 -index 000000000000..3fcb5edb1d2b --- /dev/null +++ b/include/linux/mutex_rt.h @@ -0,0 +1,130 @@ @@ -148,9 +144,6 @@ index 000000000000..3fcb5edb1d2b +extern int atomic_dec_and_mutex_lock(atomic_t *cnt, struct mutex *lock); + +#endif -diff --git a/kernel/locking/mutex-rt.c b/kernel/locking/mutex-rt.c -new file mode 100644 -index 000000000000..4f81595c0f52 --- /dev/null +++ b/kernel/locking/mutex-rt.c @@ -0,0 +1,223 @@ @@ -377,6 +370,3 @@ index 000000000000..4f81595c0f52 + return 1; +} +EXPORT_SYMBOL(atomic_dec_and_mutex_lock); --- -2.19.2 - diff --git a/kernel/patches-4.14.x-rt/0256-rtmutex-add-rwsem-implementation-based-on-rtmutex.patch b/kernel/patches-4.19.x-rt/0147-rtmutex-add-rwsem-implementation-based-on-rtmutex.patch similarity index 89% rename from kernel/patches-4.14.x-rt/0256-rtmutex-add-rwsem-implementation-based-on-rtmutex.patch rename to kernel/patches-4.19.x-rt/0147-rtmutex-add-rwsem-implementation-based-on-rtmutex.patch index a1a2f14a7..21d1c44da 100644 --- a/kernel/patches-4.14.x-rt/0256-rtmutex-add-rwsem-implementation-based-on-rtmutex.patch +++ b/kernel/patches-4.19.x-rt/0147-rtmutex-add-rwsem-implementation-based-on-rtmutex.patch @@ -1,7 +1,6 @@ -From 4029732510cb67246a845e4c9d329eaf9c94b402 Mon Sep 17 00:00:00 2001 From: Thomas Gleixner Date: Thu, 12 Oct 2017 17:28:34 +0200 -Subject: [PATCH 256/450] rtmutex: add rwsem implementation based on rtmutex +Subject: rtmutex: add rwsem implementation based on rtmutex The RT specific R/W semaphore implementation restricts the number of readers to one because a writer cannot block on multiple readers and inherit its @@ -42,18 +41,15 @@ the approach. Signed-off-by: Thomas Gleixner Signed-off-by: Sebastian Andrzej Siewior --- - include/linux/rwsem_rt.h | 67 ++++++++++ - kernel/locking/rwsem-rt.c | 269 ++++++++++++++++++++++++++++++++++++++ - 2 files changed, 336 insertions(+) + include/linux/rwsem_rt.h | 68 ++++++++++ + kernel/locking/rwsem-rt.c | 293 ++++++++++++++++++++++++++++++++++++++++++++++ + 2 files changed, 361 insertions(+) create mode 100644 include/linux/rwsem_rt.h create mode 100644 kernel/locking/rwsem-rt.c -diff --git a/include/linux/rwsem_rt.h b/include/linux/rwsem_rt.h -new file mode 100644 -index 000000000000..2ffbf093ae92 --- /dev/null +++ b/include/linux/rwsem_rt.h -@@ -0,0 +1,67 @@ +@@ -0,0 +1,68 @@ +#ifndef _LINUX_RWSEM_RT_H +#define _LINUX_RWSEM_RT_H + @@ -112,6 +108,7 @@ index 000000000000..2ffbf093ae92 +} + +extern void __down_read(struct rw_semaphore *sem); ++extern int __down_read_killable(struct rw_semaphore *sem); +extern int __down_read_trylock(struct rw_semaphore *sem); +extern void __down_write(struct rw_semaphore *sem); +extern int __must_check __down_write_killable(struct rw_semaphore *sem); @@ -121,12 +118,9 @@ index 000000000000..2ffbf093ae92 +extern void __downgrade_write(struct rw_semaphore *sem); + +#endif -diff --git a/kernel/locking/rwsem-rt.c b/kernel/locking/rwsem-rt.c -new file mode 100644 -index 000000000000..a8f7ce5be989 --- /dev/null +++ b/kernel/locking/rwsem-rt.c -@@ -0,0 +1,269 @@ +@@ -0,0 +1,293 @@ +/* + */ +#include @@ -208,13 +202,14 @@ index 000000000000..a8f7ce5be989 + return 0; +} + -+void __sched __down_read(struct rw_semaphore *sem) ++static int __sched __down_read_common(struct rw_semaphore *sem, int state) +{ + struct rt_mutex *m = &sem->rtmutex; + struct rt_mutex_waiter waiter; ++ int ret; + + if (__down_read_trylock(sem)) -+ return; ++ return 0; + + might_sleep(); + raw_spin_lock_irq(&m->wait_lock); @@ -225,7 +220,7 @@ index 000000000000..a8f7ce5be989 + if (atomic_read(&sem->readers) != WRITER_BIAS) { + atomic_inc(&sem->readers); + raw_spin_unlock_irq(&m->wait_lock); -+ return; ++ return 0; + } + + /* @@ -258,19 +253,42 @@ index 000000000000..a8f7ce5be989 + * Reader2 to call up_read() which might be unbound. + */ + rt_mutex_init_waiter(&waiter, false); -+ rt_mutex_slowlock_locked(m, TASK_UNINTERRUPTIBLE, NULL, -+ RT_MUTEX_MIN_CHAINWALK, -+ &waiter); ++ ret = rt_mutex_slowlock_locked(m, state, NULL, RT_MUTEX_MIN_CHAINWALK, ++ &waiter); + /* -+ * The slowlock() above is guaranteed to return with the rtmutex is -+ * now held, so there can't be a writer active. Increment the reader -+ * count and immediately drop the rtmutex again. ++ * The slowlock() above is guaranteed to return with the rtmutex (for ++ * ret = 0) is now held, so there can't be a writer active. Increment ++ * the reader count and immediately drop the rtmutex again. ++ * For ret != 0 we don't hold the rtmutex and need unlock the wait_lock. ++ * We don't own the lock then. + */ -+ atomic_inc(&sem->readers); ++ if (!ret) ++ atomic_inc(&sem->readers); + raw_spin_unlock_irq(&m->wait_lock); -+ __rt_mutex_unlock(m); ++ if (!ret) ++ __rt_mutex_unlock(m); + + debug_rt_mutex_free_waiter(&waiter); ++ return ret; ++} ++ ++void __down_read(struct rw_semaphore *sem) ++{ ++ int ret; ++ ++ ret = __down_read_common(sem, TASK_UNINTERRUPTIBLE); ++ WARN_ON_ONCE(ret); ++} ++ ++int __down_read_killable(struct rw_semaphore *sem) ++{ ++ int ret; ++ ++ ret = __down_read_common(sem, TASK_KILLABLE); ++ if (likely(!ret)) ++ return ret; ++ WARN_ONCE(ret != -EINTR, "Unexpected state: %d\n", ret); ++ return -EINTR; +} + +void __up_read(struct rw_semaphore *sem) @@ -396,6 +414,3 @@ index 000000000000..a8f7ce5be989 + /* Release it and account current as reader */ + __up_write_unlock(sem, WRITER_BIAS - 1, flags); +} --- -2.19.2 - diff --git a/kernel/patches-4.14.x-rt/0257-rtmutex-add-rwlock-implementation-based-on-rtmutex.patch b/kernel/patches-4.19.x-rt/0148-rtmutex-add-rwlock-implementation-based-on-rtmutex.patch similarity index 95% rename from kernel/patches-4.14.x-rt/0257-rtmutex-add-rwlock-implementation-based-on-rtmutex.patch rename to kernel/patches-4.19.x-rt/0148-rtmutex-add-rwlock-implementation-based-on-rtmutex.patch index e2a57c267..35ac0af12 100644 --- a/kernel/patches-4.14.x-rt/0257-rtmutex-add-rwlock-implementation-based-on-rtmutex.patch +++ b/kernel/patches-4.19.x-rt/0148-rtmutex-add-rwlock-implementation-based-on-rtmutex.patch @@ -1,24 +1,20 @@ -From 527069affcb77c76bae2cce18e9c67dfae4b25ea Mon Sep 17 00:00:00 2001 From: Thomas Gleixner Date: Thu, 12 Oct 2017 17:18:06 +0200 -Subject: [PATCH 257/450] rtmutex: add rwlock implementation based on rtmutex +Subject: rtmutex: add rwlock implementation based on rtmutex The implementation is bias-based, similar to the rwsem implementation. Signed-off-by: Thomas Gleixner Signed-off-by: Sebastian Andrzej Siewior --- - include/linux/rwlock_rt.h | 119 +++++++++++ - include/linux/rwlock_types_rt.h | 55 +++++ - kernel/locking/rwlock-rt.c | 368 ++++++++++++++++++++++++++++++++ + include/linux/rwlock_rt.h | 119 ++++++++++++ + include/linux/rwlock_types_rt.h | 55 +++++ + kernel/locking/rwlock-rt.c | 368 ++++++++++++++++++++++++++++++++++++++++ 3 files changed, 542 insertions(+) create mode 100644 include/linux/rwlock_rt.h create mode 100644 include/linux/rwlock_types_rt.h create mode 100644 kernel/locking/rwlock-rt.c -diff --git a/include/linux/rwlock_rt.h b/include/linux/rwlock_rt.h -new file mode 100644 -index 000000000000..a9c4c2ac4d1f --- /dev/null +++ b/include/linux/rwlock_rt.h @@ -0,0 +1,119 @@ @@ -141,9 +137,6 @@ index 000000000000..a9c4c2ac4d1f +void __write_rt_unlock(struct rt_rw_lock *lock); + +#endif -diff --git a/include/linux/rwlock_types_rt.h b/include/linux/rwlock_types_rt.h -new file mode 100644 -index 000000000000..546a1f8f1274 --- /dev/null +++ b/include/linux/rwlock_types_rt.h @@ -0,0 +1,55 @@ @@ -202,9 +195,6 @@ index 000000000000..546a1f8f1274 + } while (0) + +#endif -diff --git a/kernel/locking/rwlock-rt.c b/kernel/locking/rwlock-rt.c -new file mode 100644 -index 000000000000..aebb7ce25bc6 --- /dev/null +++ b/kernel/locking/rwlock-rt.c @@ -0,0 +1,368 @@ @@ -576,6 +566,3 @@ index 000000000000..aebb7ce25bc6 + do_rwlock_rt_init(rwlock, name, key); +} +EXPORT_SYMBOL(__rt_rwlock_init); --- -2.19.2 - diff --git a/kernel/patches-4.19.x-rt/0149-rtmutex-rwlock-preserve-state-like-a-sleeping-lock.patch b/kernel/patches-4.19.x-rt/0149-rtmutex-rwlock-preserve-state-like-a-sleeping-lock.patch new file mode 100644 index 000000000..894bfd9c1 --- /dev/null +++ b/kernel/patches-4.19.x-rt/0149-rtmutex-rwlock-preserve-state-like-a-sleeping-lock.patch @@ -0,0 +1,26 @@ +From: Sebastian Andrzej Siewior +Date: Fri, 11 Jan 2019 21:16:31 +0100 +Subject: [PATCH] rtmutex/rwlock: preserve state like a sleeping lock + +The rwlock is spinning while acquiring a lock. Therefore it must become +a sleeping lock on RT and preserve its task state while sleeping and +waiting for the lock to become available. + +Reported-by: Joe Korty +Cc: stable-rt@vger.kernel.org +Signed-off-by: Sebastian Andrzej Siewior +--- + kernel/locking/rwlock-rt.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/kernel/locking/rwlock-rt.c ++++ b/kernel/locking/rwlock-rt.c +@@ -128,7 +128,7 @@ void __sched __read_rt_lock(struct rt_rw + * That would put Reader1 behind the writer waiting on + * Reader2 to call read_unlock() which might be unbound. + */ +- rt_mutex_init_waiter(&waiter, false); ++ rt_mutex_init_waiter(&waiter, true); + rt_spin_lock_slowlock_locked(m, &waiter, flags); + /* + * The slowlock() above is guaranteed to return with the rtmutex is diff --git a/kernel/patches-4.14.x-rt/0258-rtmutex-wire-up-RT-s-locking.patch b/kernel/patches-4.19.x-rt/0150-rtmutex-wire-up-RT-s-locking.patch similarity index 66% rename from kernel/patches-4.14.x-rt/0258-rtmutex-wire-up-RT-s-locking.patch rename to kernel/patches-4.19.x-rt/0150-rtmutex-wire-up-RT-s-locking.patch index 95f869e73..0040b7ecf 100644 --- a/kernel/patches-4.14.x-rt/0258-rtmutex-wire-up-RT-s-locking.patch +++ b/kernel/patches-4.19.x-rt/0150-rtmutex-wire-up-RT-s-locking.patch @@ -1,26 +1,23 @@ -From 126b97b0b8bf74ba9a4820d51fa1c16c01822c92 Mon Sep 17 00:00:00 2001 From: Thomas Gleixner Date: Thu, 12 Oct 2017 17:31:14 +0200 -Subject: [PATCH 258/450] rtmutex: wire up RT's locking +Subject: rtmutex: wire up RT's locking Signed-off-by: Thomas Gleixner Signed-off-by: Sebastian Andrzej Siewior --- - include/linux/mutex.h | 20 +++++++++++++------- - include/linux/rwsem.h | 11 +++++++++++ - include/linux/spinlock.h | 12 +++++++++++- - include/linux/spinlock_api_smp.h | 4 +++- - include/linux/spinlock_types.h | 11 ++++++++--- - kernel/locking/Makefile | 9 ++++++++- - kernel/locking/spinlock.c | 7 +++++++ - kernel/locking/spinlock_debug.c | 5 +++++ + include/linux/mutex.h | 20 +++++++++++++------- + include/linux/rwsem.h | 11 +++++++++++ + include/linux/spinlock.h | 12 +++++++++++- + include/linux/spinlock_api_smp.h | 4 +++- + include/linux/spinlock_types.h | 11 ++++++++--- + kernel/locking/Makefile | 9 ++++++++- + kernel/locking/spinlock.c | 7 +++++++ + kernel/locking/spinlock_debug.c | 5 +++++ 8 files changed, 66 insertions(+), 13 deletions(-) -diff --git a/include/linux/mutex.h b/include/linux/mutex.h -index 153274f78402..dbb52857b25b 100644 --- a/include/linux/mutex.h +++ b/include/linux/mutex.h -@@ -23,6 +23,17 @@ +@@ -22,6 +22,17 @@ struct ww_acquire_ctx; @@ -38,7 +35,7 @@ index 153274f78402..dbb52857b25b 100644 /* * Simple, straightforward mutexes with strict semantics: * -@@ -114,13 +125,6 @@ do { \ +@@ -118,13 +129,6 @@ do { \ __mutex_init((mutex), #mutex, &__key); \ } while (0) @@ -52,15 +49,13 @@ index 153274f78402..dbb52857b25b 100644 #define __MUTEX_INITIALIZER(lockname) \ { .owner = ATOMIC_LONG_INIT(0) \ , .wait_lock = __SPIN_LOCK_UNLOCKED(lockname.wait_lock) \ -@@ -228,4 +232,6 @@ mutex_trylock_recursive(struct mutex *lock) +@@ -229,4 +233,6 @@ mutex_trylock_recursive(struct mutex *lo return mutex_trylock(lock); } +#endif /* !PREEMPT_RT_FULL */ + #endif /* __LINUX_MUTEX_H */ -diff --git a/include/linux/rwsem.h b/include/linux/rwsem.h -index c427ffaa4904..513df11a364e 100644 --- a/include/linux/rwsem.h +++ b/include/linux/rwsem.h @@ -20,6 +20,10 @@ @@ -74,7 +69,7 @@ index c427ffaa4904..513df11a364e 100644 struct rw_semaphore; #ifdef CONFIG_RWSEM_GENERIC_SPINLOCK -@@ -114,6 +118,13 @@ static inline int rwsem_is_contended(struct rw_semaphore *sem) +@@ -114,6 +118,13 @@ static inline int rwsem_is_contended(str return !list_empty(&sem->wait_list); } @@ -88,12 +83,10 @@ index c427ffaa4904..513df11a364e 100644 /* * lock for reading */ -diff --git a/include/linux/spinlock.h b/include/linux/spinlock.h -index 341e1a12bfc7..7c8f0a985b9e 100644 --- a/include/linux/spinlock.h +++ b/include/linux/spinlock.h -@@ -286,7 +286,11 @@ static inline void do_raw_spin_unlock(raw_spinlock_t *lock) __releases(lock) - #define raw_spin_can_lock(lock) (!raw_spin_is_locked(lock)) +@@ -298,7 +298,11 @@ static inline void do_raw_spin_unlock(ra + }) /* Include rwlock functions */ -#include @@ -105,7 +98,7 @@ index 341e1a12bfc7..7c8f0a985b9e 100644 /* * Pull the _spin_*()/_read_*()/_write_*() functions/declarations: -@@ -297,6 +301,10 @@ static inline void do_raw_spin_unlock(raw_spinlock_t *lock) __releases(lock) +@@ -309,6 +313,10 @@ static inline void do_raw_spin_unlock(ra # include #endif @@ -116,18 +109,18 @@ index 341e1a12bfc7..7c8f0a985b9e 100644 /* * Map the spin_lock functions to the raw variants for PREEMPT_RT=n */ -@@ -421,4 +429,6 @@ extern int _atomic_dec_and_lock(atomic_t *atomic, spinlock_t *lock); - #define atomic_dec_and_lock(atomic, lock) \ - __cond_lock(lock, _atomic_dec_and_lock(atomic, lock)) +@@ -429,6 +437,8 @@ static __always_inline int spin_is_conte + + #define assert_spin_locked(lock) assert_raw_spin_locked(&(lock)->rlock) +#endif /* !PREEMPT_RT_FULL */ + - #endif /* __LINUX_SPINLOCK_H */ -diff --git a/include/linux/spinlock_api_smp.h b/include/linux/spinlock_api_smp.h -index 42dfab89e740..29d99ae5a8ab 100644 + /* + * Pull the atomic_t declaration: + * (asm-mips/atomic.h needs above definitions) --- a/include/linux/spinlock_api_smp.h +++ b/include/linux/spinlock_api_smp.h -@@ -187,6 +187,8 @@ static inline int __raw_spin_trylock_bh(raw_spinlock_t *lock) +@@ -187,6 +187,8 @@ static inline int __raw_spin_trylock_bh( return 0; } @@ -137,8 +130,6 @@ index 42dfab89e740..29d99ae5a8ab 100644 +#endif #endif /* __LINUX_SPINLOCK_API_SMP_H */ -diff --git a/include/linux/spinlock_types.h b/include/linux/spinlock_types.h -index 5c8664d57fb8..10bac715ea96 100644 --- a/include/linux/spinlock_types.h +++ b/include/linux/spinlock_types.h @@ -11,8 +11,13 @@ @@ -158,8 +149,6 @@ index 5c8664d57fb8..10bac715ea96 100644 +#endif #endif /* __LINUX_SPINLOCK_TYPES_H */ -diff --git a/kernel/locking/Makefile b/kernel/locking/Makefile -index 392c7f23af76..c0bf04b6b965 100644 --- a/kernel/locking/Makefile +++ b/kernel/locking/Makefile @@ -3,7 +3,7 @@ @@ -171,7 +160,7 @@ index 392c7f23af76..c0bf04b6b965 100644 ifdef CONFIG_FUNCTION_TRACER CFLAGS_REMOVE_lockdep.o = $(CC_FLAGS_FTRACE) -@@ -12,7 +12,11 @@ CFLAGS_REMOVE_mutex-debug.o = $(CC_FLAGS_FTRACE) +@@ -12,7 +12,11 @@ CFLAGS_REMOVE_mutex-debug.o = $(CC_FLAGS CFLAGS_REMOVE_rtmutex-debug.o = $(CC_FLAGS_FTRACE) endif @@ -195,11 +184,9 @@ index 392c7f23af76..c0bf04b6b965 100644 obj-$(CONFIG_QUEUED_RWLOCKS) += qrwlock.o obj-$(CONFIG_LOCK_TORTURE_TEST) += locktorture.o obj-$(CONFIG_WW_MUTEX_SELFTEST) += test-ww_mutex.o -diff --git a/kernel/locking/spinlock.c b/kernel/locking/spinlock.c -index 6e40fdfba326..401bda23f786 100644 --- a/kernel/locking/spinlock.c +++ b/kernel/locking/spinlock.c -@@ -125,8 +125,11 @@ void __lockfunc __raw_##op##_lock_bh(locktype##_t *lock) \ +@@ -117,8 +117,11 @@ void __lockfunc __raw_##op##_lock_bh(loc * __[spin|read|write]_lock_bh() */ BUILD_LOCK_OPS(spin, raw_spinlock); @@ -211,7 +198,7 @@ index 6e40fdfba326..401bda23f786 100644 #endif -@@ -210,6 +213,8 @@ void __lockfunc _raw_spin_unlock_bh(raw_spinlock_t *lock) +@@ -202,6 +205,8 @@ void __lockfunc _raw_spin_unlock_bh(raw_ EXPORT_SYMBOL(_raw_spin_unlock_bh); #endif @@ -220,7 +207,7 @@ index 6e40fdfba326..401bda23f786 100644 #ifndef CONFIG_INLINE_READ_TRYLOCK int __lockfunc _raw_read_trylock(rwlock_t *lock) { -@@ -354,6 +359,8 @@ void __lockfunc _raw_write_unlock_bh(rwlock_t *lock) +@@ -346,6 +351,8 @@ void __lockfunc _raw_write_unlock_bh(rwl EXPORT_SYMBOL(_raw_write_unlock_bh); #endif @@ -229,11 +216,9 @@ index 6e40fdfba326..401bda23f786 100644 #ifdef CONFIG_DEBUG_LOCK_ALLOC void __lockfunc _raw_spin_lock_nested(raw_spinlock_t *lock, int subclass) -diff --git a/kernel/locking/spinlock_debug.c b/kernel/locking/spinlock_debug.c -index 9aa0fccd5d43..76d0b40d9193 100644 --- a/kernel/locking/spinlock_debug.c +++ b/kernel/locking/spinlock_debug.c -@@ -31,6 +31,7 @@ void __raw_spin_lock_init(raw_spinlock_t *lock, const char *name, +@@ -31,6 +31,7 @@ void __raw_spin_lock_init(raw_spinlock_t EXPORT_SYMBOL(__raw_spin_lock_init); @@ -241,7 +226,7 @@ index 9aa0fccd5d43..76d0b40d9193 100644 void __rwlock_init(rwlock_t *lock, const char *name, struct lock_class_key *key) { -@@ -48,6 +49,7 @@ void __rwlock_init(rwlock_t *lock, const char *name, +@@ -48,6 +49,7 @@ void __rwlock_init(rwlock_t *lock, const } EXPORT_SYMBOL(__rwlock_init); @@ -249,7 +234,7 @@ index 9aa0fccd5d43..76d0b40d9193 100644 static void spin_dump(raw_spinlock_t *lock, const char *msg) { -@@ -135,6 +137,7 @@ void do_raw_spin_unlock(raw_spinlock_t *lock) +@@ -135,6 +137,7 @@ void do_raw_spin_unlock(raw_spinlock_t * arch_spin_unlock(&lock->raw_lock); } @@ -263,6 +248,3 @@ index 9aa0fccd5d43..76d0b40d9193 100644 } + +#endif --- -2.19.2 - diff --git a/kernel/patches-4.14.x-rt/0259-rtmutex-add-ww_mutex-addon-for-mutex-rt.patch b/kernel/patches-4.19.x-rt/0151-rtmutex-add-ww_mutex-addon-for-mutex-rt.patch similarity index 81% rename from kernel/patches-4.14.x-rt/0259-rtmutex-add-ww_mutex-addon-for-mutex-rt.patch rename to kernel/patches-4.19.x-rt/0151-rtmutex-add-ww_mutex-addon-for-mutex-rt.patch index f5db20753..f06eb9031 100644 --- a/kernel/patches-4.14.x-rt/0259-rtmutex-add-ww_mutex-addon-for-mutex-rt.patch +++ b/kernel/patches-4.19.x-rt/0151-rtmutex-add-ww_mutex-addon-for-mutex-rt.patch @@ -1,17 +1,14 @@ -From 283bca2faa9abc1a7f3cac94fb3e6c01da391bd5 Mon Sep 17 00:00:00 2001 From: Sebastian Andrzej Siewior Date: Thu, 12 Oct 2017 17:34:38 +0200 -Subject: [PATCH 259/450] rtmutex: add ww_mutex addon for mutex-rt +Subject: rtmutex: add ww_mutex addon for mutex-rt Signed-off-by: Sebastian Andrzej Siewior --- - kernel/locking/rtmutex.c | 264 ++++++++++++++++++++++++++++++-- - kernel/locking/rtmutex_common.h | 2 + - kernel/locking/rwsem-rt.c | 2 +- - 3 files changed, 257 insertions(+), 11 deletions(-) + kernel/locking/rtmutex.c | 271 ++++++++++++++++++++++++++++++++++++++-- + kernel/locking/rtmutex_common.h | 2 + kernel/locking/rwsem-rt.c | 2 + 3 files changed, 261 insertions(+), 14 deletions(-) -diff --git a/kernel/locking/rtmutex.c b/kernel/locking/rtmutex.c -index 827546ba5a47..5772283ebd17 100644 --- a/kernel/locking/rtmutex.c +++ b/kernel/locking/rtmutex.c @@ -23,6 +23,7 @@ @@ -22,7 +19,7 @@ index 827546ba5a47..5772283ebd17 100644 #include "rtmutex_common.h" -@@ -1258,6 +1259,40 @@ EXPORT_SYMBOL(__rt_spin_lock_init); +@@ -1245,6 +1246,40 @@ EXPORT_SYMBOL(__rt_spin_lock_init); #endif /* PREEMPT_RT_FULL */ @@ -31,7 +28,7 @@ index 827546ba5a47..5772283ebd17 100644 +__mutex_lock_check_stamp(struct rt_mutex *lock, struct ww_acquire_ctx *ctx) +{ + struct ww_mutex *ww = container_of(lock, struct ww_mutex, base.lock); -+ struct ww_acquire_ctx *hold_ctx = ACCESS_ONCE(ww->ctx); ++ struct ww_acquire_ctx *hold_ctx = READ_ONCE(ww->ctx); + + if (!hold_ctx) + return 0; @@ -63,7 +60,7 @@ index 827546ba5a47..5772283ebd17 100644 static inline int try_to_take_rt_mutex(struct rt_mutex *lock, struct task_struct *task, struct rt_mutex_waiter *waiter) -@@ -1536,7 +1571,8 @@ void rt_mutex_init_waiter(struct rt_mutex_waiter *waiter, bool savestate) +@@ -1523,7 +1558,8 @@ void rt_mutex_init_waiter(struct rt_mute static int __sched __rt_mutex_slowlock(struct rt_mutex *lock, int state, struct hrtimer_sleeper *timeout, @@ -73,7 +70,7 @@ index 827546ba5a47..5772283ebd17 100644 { int ret = 0; -@@ -1554,6 +1590,12 @@ __rt_mutex_slowlock(struct rt_mutex *lock, int state, +@@ -1541,6 +1577,12 @@ static int __sched break; } @@ -86,7 +83,7 @@ index 827546ba5a47..5772283ebd17 100644 raw_spin_unlock_irq(&lock->wait_lock); debug_rt_mutex_print_deadlock(waiter); -@@ -1588,16 +1630,106 @@ static void rt_mutex_handle_deadlock(int res, int detect_deadlock, +@@ -1575,16 +1617,106 @@ static void rt_mutex_handle_deadlock(int } } @@ -194,9 +191,12 @@ index 827546ba5a47..5772283ebd17 100644 set_current_state(state); -@@ -1609,7 +1741,12 @@ int __sched rt_mutex_slowlock_locked(struct rt_mutex *lock, int state, +@@ -1594,14 +1726,24 @@ int __sched rt_mutex_slowlock_locked(str - if (likely(!ret)) { + ret = task_blocks_on_rt_mutex(lock, waiter, current, chwalk); + +- if (likely(!ret)) ++ if (likely(!ret)) { /* sleep on the mutex */ - ret = __rt_mutex_slowlock(lock, state, timeout, waiter); + ret = __rt_mutex_slowlock(lock, state, timeout, waiter, @@ -205,13 +205,13 @@ index 827546ba5a47..5772283ebd17 100644 + /* ww_mutex received EDEADLK, let it become EALREADY */ + ret = __mutex_lock_check_stamp(lock, ww_ctx); + BUG_ON(!ret); - } ++ } if (unlikely(ret)) { -@@ -1617,6 +1754,10 @@ int __sched rt_mutex_slowlock_locked(struct rt_mutex *lock, int state, - if (rt_mutex_has_waiters(lock)) - remove_waiter(lock, waiter); - /* ww_mutex want to report EDEADLK/EALREADY, let them */ + __set_current_state(TASK_RUNNING); + remove_waiter(lock, waiter); +- rt_mutex_handle_deadlock(ret, chwalk, waiter); ++ /* ww_mutex wants to report EDEADLK/EALREADY, let it */ + if (!ww_ctx) + rt_mutex_handle_deadlock(ret, chwalk, waiter); + } else if (ww_ctx) { @@ -219,7 +219,7 @@ index 827546ba5a47..5772283ebd17 100644 } /* -@@ -1633,7 +1774,8 @@ int __sched rt_mutex_slowlock_locked(struct rt_mutex *lock, int state, +@@ -1618,7 +1760,8 @@ int __sched rt_mutex_slowlock_locked(str static int __sched rt_mutex_slowlock(struct rt_mutex *lock, int state, struct hrtimer_sleeper *timeout, @@ -229,7 +229,7 @@ index 827546ba5a47..5772283ebd17 100644 { struct rt_mutex_waiter waiter; unsigned long flags; -@@ -1651,7 +1793,8 @@ rt_mutex_slowlock(struct rt_mutex *lock, int state, +@@ -1636,7 +1779,8 @@ rt_mutex_slowlock(struct rt_mutex *lock, */ raw_spin_lock_irqsave(&lock->wait_lock, flags); @@ -239,7 +239,7 @@ index 827546ba5a47..5772283ebd17 100644 raw_spin_unlock_irqrestore(&lock->wait_lock, flags); -@@ -1781,29 +1924,33 @@ static bool __sched rt_mutex_slowunlock(struct rt_mutex *lock, +@@ -1766,29 +1910,33 @@ static bool __sched rt_mutex_slowunlock( */ static inline int rt_mutex_fastlock(struct rt_mutex *lock, int state, @@ -277,7 +277,16 @@ index 827546ba5a47..5772283ebd17 100644 } static inline int -@@ -1962,6 +2109,7 @@ rt_mutex_timed_lock(struct rt_mutex *lock, struct hrtimer_sleeper *timeout) +@@ -1833,7 +1981,7 @@ rt_mutex_fastunlock(struct rt_mutex *loc + int __sched __rt_mutex_lock_state(struct rt_mutex *lock, int state) + { + might_sleep(); +- return rt_mutex_fastlock(lock, state, rt_mutex_slowlock); ++ return rt_mutex_fastlock(lock, state, NULL, rt_mutex_slowlock); + } + + /** +@@ -1953,6 +2101,7 @@ rt_mutex_timed_lock(struct rt_mutex *loc mutex_acquire(&lock->dep_map, 0, 0, _RET_IP_); ret = rt_mutex_timed_fastlock(lock, TASK_INTERRUPTIBLE, timeout, RT_MUTEX_MIN_CHAINWALK, @@ -285,7 +294,7 @@ index 827546ba5a47..5772283ebd17 100644 rt_mutex_slowlock); if (ret) mutex_release(&lock->dep_map, 1, _RET_IP_); -@@ -2283,7 +2431,7 @@ int rt_mutex_wait_proxy_lock(struct rt_mutex *lock, +@@ -2300,7 +2449,7 @@ int rt_mutex_wait_proxy_lock(struct rt_m raw_spin_lock_irq(&lock->wait_lock); /* sleep on the mutex */ set_current_state(TASK_INTERRUPTIBLE); @@ -294,7 +303,7 @@ index 827546ba5a47..5772283ebd17 100644 /* * try_to_take_rt_mutex() sets the waiter bit unconditionally. We might * have to fix that up. -@@ -2367,3 +2515,99 @@ bool rt_mutex_cleanup_proxy_lock(struct rt_mutex *lock, +@@ -2385,3 +2534,99 @@ bool rt_mutex_cleanup_proxy_lock(struct return cleanup; } @@ -394,11 +403,9 @@ index 827546ba5a47..5772283ebd17 100644 +} +EXPORT_SYMBOL(__rt_mutex_owner_current); +#endif -diff --git a/kernel/locking/rtmutex_common.h b/kernel/locking/rtmutex_common.h -index 2d822a08c87d..2a157c78e18c 100644 --- a/kernel/locking/rtmutex_common.h +++ b/kernel/locking/rtmutex_common.h -@@ -164,6 +164,7 @@ extern void rt_mutex_postunlock(struct wake_q_head *wake_q, +@@ -165,6 +165,7 @@ extern void rt_mutex_postunlock(struct w struct wake_q_head *wake_sleeper_q); /* RW semaphore special interface */ @@ -406,7 +413,7 @@ index 2d822a08c87d..2a157c78e18c 100644 extern int __rt_mutex_lock_state(struct rt_mutex *lock, int state); extern int __rt_mutex_trylock(struct rt_mutex *lock); -@@ -171,6 +172,7 @@ extern void __rt_mutex_unlock(struct rt_mutex *lock); +@@ -172,6 +173,7 @@ extern void __rt_mutex_unlock(struct rt_ int __sched rt_mutex_slowlock_locked(struct rt_mutex *lock, int state, struct hrtimer_sleeper *timeout, enum rtmutex_chainwalk chwalk, @@ -414,19 +421,14 @@ index 2d822a08c87d..2a157c78e18c 100644 struct rt_mutex_waiter *waiter); void __sched rt_spin_lock_slowlock_locked(struct rt_mutex *lock, struct rt_mutex_waiter *waiter, -diff --git a/kernel/locking/rwsem-rt.c b/kernel/locking/rwsem-rt.c -index a8f7ce5be989..26991ddb6c5a 100644 --- a/kernel/locking/rwsem-rt.c +++ b/kernel/locking/rwsem-rt.c -@@ -130,7 +130,7 @@ void __sched __down_read(struct rw_semaphore *sem) +@@ -131,7 +131,7 @@ static int __sched __down_read_common(st */ rt_mutex_init_waiter(&waiter, false); - rt_mutex_slowlock_locked(m, TASK_UNINTERRUPTIBLE, NULL, -- RT_MUTEX_MIN_CHAINWALK, -+ RT_MUTEX_MIN_CHAINWALK, NULL, - &waiter); + ret = rt_mutex_slowlock_locked(m, state, NULL, RT_MUTEX_MIN_CHAINWALK, +- &waiter); ++ NULL, &waiter); /* - * The slowlock() above is guaranteed to return with the rtmutex is --- -2.19.2 - + * The slowlock() above is guaranteed to return with the rtmutex (for + * ret = 0) is now held, so there can't be a writer active. Increment diff --git a/kernel/patches-4.14.x-rt/0144-kconfig-Add-PREEMPT_RT_FULL.patch b/kernel/patches-4.19.x-rt/0152-kconfig-preempt-rt-full.patch similarity index 68% rename from kernel/patches-4.14.x-rt/0144-kconfig-Add-PREEMPT_RT_FULL.patch rename to kernel/patches-4.19.x-rt/0152-kconfig-preempt-rt-full.patch index f22f52210..d1d7a5865 100644 --- a/kernel/patches-4.14.x-rt/0144-kconfig-Add-PREEMPT_RT_FULL.patch +++ b/kernel/patches-4.19.x-rt/0152-kconfig-preempt-rt-full.patch @@ -1,32 +1,27 @@ -From 5a5f5c742ce8e4fd3f596a06fca0e44e9fe20d23 Mon Sep 17 00:00:00 2001 +Subject: kconfig: Add PREEMPT_RT_FULL From: Thomas Gleixner Date: Wed, 29 Jun 2011 14:58:57 +0200 -Subject: [PATCH 144/450] kconfig: Add PREEMPT_RT_FULL Introduce the final symbol for PREEMPT_RT_FULL. Signed-off-by: Thomas Gleixner --- - init/Makefile | 2 +- - kernel/Kconfig.preempt | 8 ++++++++ - scripts/mkcompile_h | 4 +++- + init/Makefile | 2 +- + kernel/Kconfig.preempt | 8 ++++++++ + scripts/mkcompile_h | 4 +++- 3 files changed, 12 insertions(+), 2 deletions(-) -diff --git a/init/Makefile b/init/Makefile -index 1dbb23787290..eabf3f1b14be 100644 --- a/init/Makefile +++ b/init/Makefile -@@ -36,4 +36,4 @@ silent_chk_compile.h = : +@@ -34,4 +34,4 @@ mounts-$(CONFIG_BLK_DEV_MD) += do_mounts include/generated/compile.h: FORCE @$($(quiet)chk_compile.h) $(Q)$(CONFIG_SHELL) $(srctree)/scripts/mkcompile_h $@ \ - "$(UTS_MACHINE)" "$(CONFIG_SMP)" "$(CONFIG_PREEMPT)" "$(CC) $(KBUILD_CFLAGS)" + "$(UTS_MACHINE)" "$(CONFIG_SMP)" "$(CONFIG_PREEMPT)" "$(CONFIG_PREEMPT_RT_FULL)" "$(CC) $(KBUILD_CFLAGS)" -diff --git a/kernel/Kconfig.preempt b/kernel/Kconfig.preempt -index c669134982ec..f8a2982bdbde 100644 --- a/kernel/Kconfig.preempt +++ b/kernel/Kconfig.preempt -@@ -67,6 +67,14 @@ config PREEMPT_RTB +@@ -69,6 +69,14 @@ config PREEMPT_RTB enables changes which are preliminary for the full preemptible RT kernel. @@ -41,8 +36,6 @@ index c669134982ec..f8a2982bdbde 100644 endchoice config PREEMPT_COUNT -diff --git a/scripts/mkcompile_h b/scripts/mkcompile_h -index 959199c3147e..3e68004ed345 100755 --- a/scripts/mkcompile_h +++ b/scripts/mkcompile_h @@ -5,7 +5,8 @@ TARGET=$1 @@ -55,7 +48,7 @@ index 959199c3147e..3e68004ed345 100755 vecho() { [ "${quiet}" = "silent_" ] || echo "$@" ; } -@@ -58,6 +59,7 @@ UTS_VERSION="#$VERSION" +@@ -53,6 +54,7 @@ UTS_VERSION="#$VERSION" CONFIG_FLAGS="" if [ -n "$SMP" ] ; then CONFIG_FLAGS="SMP"; fi if [ -n "$PREEMPT" ] ; then CONFIG_FLAGS="$CONFIG_FLAGS PREEMPT"; fi @@ -63,6 +56,3 @@ index 959199c3147e..3e68004ed345 100755 UTS_VERSION="$UTS_VERSION $CONFIG_FLAGS $TIMESTAMP" # Truncate to maximum length --- -2.19.2 - diff --git a/kernel/patches-4.14.x-rt/0260-locking-rt-mutex-fix-deadlock-in-device-mapper-block.patch b/kernel/patches-4.19.x-rt/0153-locking-rt-mutex-fix-deadlock-in-device-mapper-block.patch similarity index 82% rename from kernel/patches-4.14.x-rt/0260-locking-rt-mutex-fix-deadlock-in-device-mapper-block.patch rename to kernel/patches-4.19.x-rt/0153-locking-rt-mutex-fix-deadlock-in-device-mapper-block.patch index caf993218..69e54df77 100644 --- a/kernel/patches-4.14.x-rt/0260-locking-rt-mutex-fix-deadlock-in-device-mapper-block.patch +++ b/kernel/patches-4.19.x-rt/0153-locking-rt-mutex-fix-deadlock-in-device-mapper-block.patch @@ -1,8 +1,6 @@ -From e4b3c20d9a121637bfd50ccb71fbcd2d0f2d8d24 Mon Sep 17 00:00:00 2001 From: Mikulas Patocka Date: Mon, 13 Nov 2017 12:56:53 -0500 -Subject: [PATCH 260/450] locking/rt-mutex: fix deadlock in device mapper / - block-IO +Subject: [PATCH] locking/rt-mutex: fix deadlock in device mapper / block-IO When some block device driver creates a bio and submits it to another block device driver, the bio is added to current->bio_list (in order to @@ -34,11 +32,9 @@ CC: stable-rt@vger.kernel.org Signed-off-by: Mikulas Patocka Signed-off-by: Sebastian Andrzej Siewior --- - kernel/locking/rtmutex.c | 13 +++++++++++++ + kernel/locking/rtmutex.c | 13 +++++++++++++ 1 file changed, 13 insertions(+) -diff --git a/kernel/locking/rtmutex.c b/kernel/locking/rtmutex.c -index 5772283ebd17..070cd952a3e8 100644 --- a/kernel/locking/rtmutex.c +++ b/kernel/locking/rtmutex.c @@ -24,6 +24,7 @@ @@ -49,7 +45,7 @@ index 5772283ebd17..070cd952a3e8 100644 #include "rtmutex_common.h" -@@ -1933,6 +1934,15 @@ rt_mutex_fastlock(struct rt_mutex *lock, int state, +@@ -1919,6 +1920,15 @@ rt_mutex_fastlock(struct rt_mutex *lock, if (likely(rt_mutex_cmpxchg_acquire(lock, NULL, current))) return 0; @@ -57,7 +53,7 @@ index 5772283ebd17..070cd952a3e8 100644 + * If rt_mutex blocks, the function sched_submit_work will not call + * blk_schedule_flush_plug (because tsk_is_pi_blocked would be true). + * We must call blk_schedule_flush_plug here, if we don't call it, -+ * a deadlock in device mapper may happen. ++ * a deadlock in I/O may happen. + */ + if (unlikely(blk_needs_flush_plug(current))) + blk_schedule_flush_plug(current); @@ -65,7 +61,7 @@ index 5772283ebd17..070cd952a3e8 100644 return slowfn(lock, state, NULL, RT_MUTEX_MIN_CHAINWALK, ww_ctx); } -@@ -1950,6 +1960,9 @@ rt_mutex_timed_fastlock(struct rt_mutex *lock, int state, +@@ -1936,6 +1946,9 @@ rt_mutex_timed_fastlock(struct rt_mutex likely(rt_mutex_cmpxchg_acquire(lock, NULL, current))) return 0; @@ -75,6 +71,3 @@ index 5772283ebd17..070cd952a3e8 100644 return slowfn(lock, state, timeout, chwalk, ww_ctx); } --- -2.19.2 - diff --git a/kernel/patches-4.19.x-rt/0154-locking-rt-mutex-Flush-block-plug-on-__down_read.patch b/kernel/patches-4.19.x-rt/0154-locking-rt-mutex-Flush-block-plug-on-__down_read.patch new file mode 100644 index 000000000..6fe10914c --- /dev/null +++ b/kernel/patches-4.19.x-rt/0154-locking-rt-mutex-Flush-block-plug-on-__down_read.patch @@ -0,0 +1,39 @@ +From: Scott Wood +Date: Fri, 4 Jan 2019 15:33:21 -0500 +Subject: [PATCH] locking/rt-mutex: Flush block plug on __down_read() + +__down_read() bypasses the rtmutex frontend to call +rt_mutex_slowlock_locked() directly, and thus it needs to call +blk_schedule_flush_flug() itself. + +Cc: stable-rt@vger.kernel.org +Signed-off-by: Scott Wood +Signed-off-by: Sebastian Andrzej Siewior +--- + kernel/locking/rwsem-rt.c | 9 +++++++++ + 1 file changed, 9 insertions(+) + +--- a/kernel/locking/rwsem-rt.c ++++ b/kernel/locking/rwsem-rt.c +@@ -1,5 +1,6 @@ + /* + */ ++#include + #include + #include + #include +@@ -87,6 +88,14 @@ static int __sched __down_read_common(st + + if (__down_read_trylock(sem)) + return 0; ++ /* ++ * If rt_mutex blocks, the function sched_submit_work will not call ++ * blk_schedule_flush_plug (because tsk_is_pi_blocked would be true). ++ * We must call blk_schedule_flush_plug here, if we don't call it, ++ * a deadlock in I/O may happen. ++ */ ++ if (unlikely(blk_needs_flush_plug(current))) ++ blk_schedule_flush_plug(current); + + might_sleep(); + raw_spin_lock_irq(&m->wait_lock); diff --git a/kernel/patches-4.14.x-rt/0261-locking-rtmutex-re-init-the-wait_lock-in-rt_mutex_in.patch b/kernel/patches-4.19.x-rt/0155-locking-rtmutex-re-init-the-wait_lock-in-rt_mutex_in.patch similarity index 71% rename from kernel/patches-4.14.x-rt/0261-locking-rtmutex-re-init-the-wait_lock-in-rt_mutex_in.patch rename to kernel/patches-4.19.x-rt/0155-locking-rtmutex-re-init-the-wait_lock-in-rt_mutex_in.patch index cbe0f82c5..6212718cf 100644 --- a/kernel/patches-4.14.x-rt/0261-locking-rtmutex-re-init-the-wait_lock-in-rt_mutex_in.patch +++ b/kernel/patches-4.19.x-rt/0155-locking-rtmutex-re-init-the-wait_lock-in-rt_mutex_in.patch @@ -1,7 +1,6 @@ -From 4baea1a4408f0fad249dc24ee1f8b3eafd793595 Mon Sep 17 00:00:00 2001 From: Sebastian Andrzej Siewior Date: Thu, 16 Nov 2017 16:48:48 +0100 -Subject: [PATCH 261/450] locking/rtmutex: re-init the wait_lock in +Subject: [PATCH] locking/rtmutex: re-init the wait_lock in rt_mutex_init_proxy_locked() We could provide a key-class for the lockdep (and fixup all callers) or @@ -11,14 +10,12 @@ seeing a double-lock of the wait_lock. Reported-by: Fernando Lopez-Lezcano Signed-off-by: Sebastian Andrzej Siewior --- - kernel/locking/rtmutex.c | 8 ++++++++ + kernel/locking/rtmutex.c | 8 ++++++++ 1 file changed, 8 insertions(+) -diff --git a/kernel/locking/rtmutex.c b/kernel/locking/rtmutex.c -index 070cd952a3e8..53b510d29a3a 100644 --- a/kernel/locking/rtmutex.c +++ b/kernel/locking/rtmutex.c -@@ -2289,6 +2289,14 @@ void rt_mutex_init_proxy_locked(struct rt_mutex *lock, +@@ -2281,6 +2281,14 @@ void rt_mutex_init_proxy_locked(struct r struct task_struct *proxy_owner) { __rt_mutex_init(lock, NULL, NULL); @@ -33,6 +30,3 @@ index 070cd952a3e8..53b510d29a3a 100644 debug_rt_mutex_proxy_lock(lock, proxy_owner); rt_mutex_set_owner(lock, proxy_owner); } --- -2.19.2 - diff --git a/kernel/patches-4.14.x-rt/0262-ptrace-fix-ptrace-vs-tasklist_lock-race.patch b/kernel/patches-4.19.x-rt/0156-ptrace-fix-ptrace-vs-tasklist_lock-race.patch similarity index 80% rename from kernel/patches-4.14.x-rt/0262-ptrace-fix-ptrace-vs-tasklist_lock-race.patch rename to kernel/patches-4.19.x-rt/0156-ptrace-fix-ptrace-vs-tasklist_lock-race.patch index d72e73183..6a81b2669 100644 --- a/kernel/patches-4.14.x-rt/0262-ptrace-fix-ptrace-vs-tasklist_lock-race.patch +++ b/kernel/patches-4.19.x-rt/0156-ptrace-fix-ptrace-vs-tasklist_lock-race.patch @@ -1,7 +1,6 @@ -From 2c72b0a19b6f6dcfe4dacb756e598410054e718e Mon Sep 17 00:00:00 2001 From: Sebastian Andrzej Siewior Date: Thu, 29 Aug 2013 18:21:04 +0200 -Subject: [PATCH 262/450] ptrace: fix ptrace vs tasklist_lock race +Subject: ptrace: fix ptrace vs tasklist_lock race As explained by Alexander Fyodorov : @@ -24,16 +23,14 @@ taken in case the caller is interrupted between looking into ->state and Signed-off-by: Sebastian Andrzej Siewior --- - include/linux/sched.h | 49 +++++++++++++++++++++++++++++++++++++++---- - kernel/ptrace.c | 9 +++++++- - kernel/sched/core.c | 17 +++++++++++++-- + include/linux/sched.h | 49 +++++++++++++++++++++++++++++++++++++++++++++---- + kernel/ptrace.c | 9 ++++++++- + kernel/sched/core.c | 17 +++++++++++++++-- 3 files changed, 68 insertions(+), 7 deletions(-) -diff --git a/include/linux/sched.h b/include/linux/sched.h -index 1b5cc9f148d6..04403a5a34f1 100644 --- a/include/linux/sched.h +++ b/include/linux/sched.h -@@ -100,12 +100,8 @@ struct task_group; +@@ -101,12 +101,8 @@ struct task_group; __TASK_TRACED | EXIT_DEAD | EXIT_ZOMBIE | \ TASK_PARKED) @@ -46,7 +43,7 @@ index 1b5cc9f148d6..04403a5a34f1 100644 #define task_contributes_to_load(task) ((task->state & TASK_UNINTERRUPTIBLE) != 0 && \ (task->flags & PF_FROZEN) == 0 && \ (task->state & TASK_NOLOAD) == 0) -@@ -1654,6 +1650,51 @@ static inline int test_tsk_need_resched(struct task_struct *tsk) +@@ -1709,6 +1705,51 @@ static inline int test_tsk_need_resched( return unlikely(test_tsk_thread_flag(tsk,TIF_NEED_RESCHED)); } @@ -98,11 +95,9 @@ index 1b5cc9f148d6..04403a5a34f1 100644 /* * cond_resched() and cond_resched_lock(): latency reduction via * explicit rescheduling in places that are safe. The return -diff --git a/kernel/ptrace.c b/kernel/ptrace.c -index 84b1367935e4..b32a86f63522 100644 --- a/kernel/ptrace.c +++ b/kernel/ptrace.c -@@ -175,7 +175,14 @@ static bool ptrace_freeze_traced(struct task_struct *task) +@@ -175,7 +175,14 @@ static bool ptrace_freeze_traced(struct spin_lock_irq(&task->sighand->siglock); if (task_is_traced(task) && !__fatal_signal_pending(task)) { @@ -118,13 +113,11 @@ index 84b1367935e4..b32a86f63522 100644 ret = true; } spin_unlock_irq(&task->sighand->siglock); -diff --git a/kernel/sched/core.c b/kernel/sched/core.c -index b34002b6c91b..c9f8f0699885 100644 --- a/kernel/sched/core.c +++ b/kernel/sched/core.c -@@ -1378,6 +1378,18 @@ int migrate_swap(struct task_struct *cur, struct task_struct *p) - return ret; +@@ -1347,6 +1347,18 @@ int migrate_swap(struct task_struct *cur } + #endif /* CONFIG_NUMA_BALANCING */ +static bool check_task_state(struct task_struct *p, long match_state) +{ @@ -141,7 +134,7 @@ index b34002b6c91b..c9f8f0699885 100644 /* * wait_task_inactive - wait for a thread to unschedule. * -@@ -1422,7 +1434,7 @@ unsigned long wait_task_inactive(struct task_struct *p, long match_state) +@@ -1391,7 +1403,7 @@ unsigned long wait_task_inactive(struct * is actually now running somewhere else! */ while (task_running(rq, p)) { @@ -150,7 +143,7 @@ index b34002b6c91b..c9f8f0699885 100644 return 0; cpu_relax(); } -@@ -1437,7 +1449,8 @@ unsigned long wait_task_inactive(struct task_struct *p, long match_state) +@@ -1406,7 +1418,8 @@ unsigned long wait_task_inactive(struct running = task_running(rq, p); queued = task_on_rq_queued(p); ncsw = 0; @@ -160,6 +153,3 @@ index b34002b6c91b..c9f8f0699885 100644 ncsw = p->nvcsw | LONG_MIN; /* sets MSB */ task_rq_unlock(rq, p, &rf); --- -2.19.2 - diff --git a/kernel/patches-4.14.x-rt/0300-rtmutex-annotate-sleeping-lock-context.patch b/kernel/patches-4.19.x-rt/0157-rtmutex-annotate-sleeping-lock-context.patch similarity index 61% rename from kernel/patches-4.14.x-rt/0300-rtmutex-annotate-sleeping-lock-context.patch rename to kernel/patches-4.19.x-rt/0157-rtmutex-annotate-sleeping-lock-context.patch index a56f861c5..fb25f58a7 100644 --- a/kernel/patches-4.14.x-rt/0300-rtmutex-annotate-sleeping-lock-context.patch +++ b/kernel/patches-4.19.x-rt/0157-rtmutex-annotate-sleeping-lock-context.patch @@ -1,7 +1,6 @@ -From bbe072eda000ee970b84bf71ff4935f03c5b60af Mon Sep 17 00:00:00 2001 From: Sebastian Andrzej Siewior -Date: Thu, 3 May 2018 17:16:26 +0200 -Subject: [PATCH 300/450] rtmutex: annotate sleeping lock context +Date: Thu, 21 Sep 2017 14:25:13 +0200 +Subject: [PATCH] rtmutex: annotate sleeping lock context The RCU code complains on schedule() within a rcu_readlock() section. The valid scenario on -RT is if a sleeping is held. In order to suppress @@ -24,28 +23,51 @@ cpu_chill() to avoid the RCU warning from there. Reported-by: Grygorii Strashko Signed-off-by: Sebastian Andrzej Siewior --- - include/linux/sched.h | 20 ++++++++++++++++++++ - kernel/locking/rtmutex.c | 12 ++++++++++-- - kernel/locking/rwlock-rt.c | 18 ++++++++++++++---- - kernel/rcu/tree_plugin.h | 8 ++++---- - kernel/time/hrtimer.c | 2 ++ - 5 files changed, 50 insertions(+), 10 deletions(-) + include/linux/preempt.h | 9 +++++++++ + include/linux/sched.h | 26 ++++++++++++++++++++++++++ + kernel/locking/rtmutex.c | 12 ++++++++++-- + kernel/locking/rwlock-rt.c | 18 ++++++++++++++---- + kernel/rcu/tree_plugin.h | 6 +++++- + kernel/sched/core.c | 45 +++++++++++++++++++++++++++++++++++++++++++++ + 6 files changed, 109 insertions(+), 7 deletions(-) -diff --git a/include/linux/sched.h b/include/linux/sched.h -index 1689c832ffb3..675cbae7adfb 100644 +--- a/include/linux/preempt.h ++++ b/include/linux/preempt.h +@@ -211,6 +211,15 @@ extern void migrate_enable(void); + + int __migrate_disabled(struct task_struct *p); + ++#elif !defined(CONFIG_SMP) && defined(CONFIG_PREEMPT_RT_BASE) ++ ++extern void migrate_disable(void); ++extern void migrate_enable(void); ++static inline int __migrate_disabled(struct task_struct *p) ++{ ++ return 0; ++} ++ + #else + #define migrate_disable() barrier() + #define migrate_enable() barrier() --- a/include/linux/sched.h +++ b/include/linux/sched.h -@@ -638,6 +638,9 @@ struct task_struct { +@@ -673,6 +673,15 @@ struct task_struct { + # ifdef CONFIG_SCHED_DEBUG int migrate_disable_atomic; # endif - #endif ++ ++#elif !defined(CONFIG_SMP) && defined(CONFIG_PREEMPT_RT_BASE) ++ int migrate_disable; ++# ifdef CONFIG_SCHED_DEBUG ++ int migrate_disable_atomic; ++# endif ++#endif +#ifdef CONFIG_PREEMPT_RT_FULL + int sleeping_lock; -+#endif + #endif #ifdef CONFIG_PREEMPT_RCU - int rcu_read_lock_nesting; -@@ -1765,6 +1768,23 @@ static __always_inline bool need_resched(void) +@@ -1802,6 +1811,23 @@ static __always_inline bool need_resched return unlikely(tif_need_resched()); } @@ -69,11 +91,9 @@ index 1689c832ffb3..675cbae7adfb 100644 /* * Wrappers for p->thread_info->cpu access. No-op on UP. */ -diff --git a/kernel/locking/rtmutex.c b/kernel/locking/rtmutex.c -index 53b510d29a3a..08e233b7dc21 100644 --- a/kernel/locking/rtmutex.c +++ b/kernel/locking/rtmutex.c -@@ -1141,6 +1141,7 @@ void __sched rt_spin_lock_slowunlock(struct rt_mutex *lock) +@@ -1141,6 +1141,7 @@ void __sched rt_spin_lock_slowunlock(str void __lockfunc rt_spin_lock(spinlock_t *lock) { @@ -81,7 +101,7 @@ index 53b510d29a3a..08e233b7dc21 100644 migrate_disable(); spin_acquire(&lock->dep_map, 0, 0, _RET_IP_); rt_spin_lock_fastlock(&lock->lock, rt_spin_lock_slowlock); -@@ -1155,6 +1156,7 @@ void __lockfunc __rt_spin_lock(struct rt_mutex *lock) +@@ -1155,6 +1156,7 @@ void __lockfunc __rt_spin_lock(struct rt #ifdef CONFIG_DEBUG_LOCK_ALLOC void __lockfunc rt_spin_lock_nested(spinlock_t *lock, int subclass) { @@ -89,7 +109,7 @@ index 53b510d29a3a..08e233b7dc21 100644 migrate_disable(); spin_acquire(&lock->dep_map, subclass, 0, _RET_IP_); rt_spin_lock_fastlock(&lock->lock, rt_spin_lock_slowlock); -@@ -1168,6 +1170,7 @@ void __lockfunc rt_spin_unlock(spinlock_t *lock) +@@ -1168,6 +1170,7 @@ void __lockfunc rt_spin_unlock(spinlock_ spin_release(&lock->dep_map, 1, _RET_IP_); rt_spin_lock_fastunlock(&lock->lock, rt_spin_lock_slowunlock); migrate_enable(); @@ -97,7 +117,7 @@ index 53b510d29a3a..08e233b7dc21 100644 } EXPORT_SYMBOL(rt_spin_unlock); -@@ -1193,12 +1196,15 @@ int __lockfunc rt_spin_trylock(spinlock_t *lock) +@@ -1193,12 +1196,15 @@ int __lockfunc rt_spin_trylock(spinlock_ { int ret; @@ -115,7 +135,7 @@ index 53b510d29a3a..08e233b7dc21 100644 return ret; } EXPORT_SYMBOL(rt_spin_trylock); -@@ -1210,6 +1216,7 @@ int __lockfunc rt_spin_trylock_bh(spinlock_t *lock) +@@ -1210,6 +1216,7 @@ int __lockfunc rt_spin_trylock_bh(spinlo local_bh_disable(); ret = __rt_mutex_trylock(&lock->lock); if (ret) { @@ -123,7 +143,7 @@ index 53b510d29a3a..08e233b7dc21 100644 migrate_disable(); spin_acquire(&lock->dep_map, 0, 1, _RET_IP_); } else -@@ -1225,6 +1232,7 @@ int __lockfunc rt_spin_trylock_irqsave(spinlock_t *lock, unsigned long *flags) +@@ -1225,6 +1232,7 @@ int __lockfunc rt_spin_trylock_irqsave(s *flags = 0; ret = __rt_mutex_trylock(&lock->lock); if (ret) { @@ -131,11 +151,9 @@ index 53b510d29a3a..08e233b7dc21 100644 migrate_disable(); spin_acquire(&lock->dep_map, 0, 1, _RET_IP_); } -diff --git a/kernel/locking/rwlock-rt.c b/kernel/locking/rwlock-rt.c -index aebb7ce25bc6..f2e155b2c4a8 100644 --- a/kernel/locking/rwlock-rt.c +++ b/kernel/locking/rwlock-rt.c -@@ -305,12 +305,15 @@ int __lockfunc rt_read_trylock(rwlock_t *rwlock) +@@ -305,12 +305,15 @@ int __lockfunc rt_read_trylock(rwlock_t { int ret; @@ -153,7 +171,7 @@ index aebb7ce25bc6..f2e155b2c4a8 100644 return ret; } EXPORT_SYMBOL(rt_read_trylock); -@@ -319,18 +322,22 @@ int __lockfunc rt_write_trylock(rwlock_t *rwlock) +@@ -319,18 +322,22 @@ int __lockfunc rt_write_trylock(rwlock_t { int ret; @@ -186,7 +204,7 @@ index aebb7ce25bc6..f2e155b2c4a8 100644 migrate_disable(); rwlock_acquire(&rwlock->dep_map, 0, 0, _RET_IP_); do_write_rt_lock(rwlock); -@@ -350,6 +358,7 @@ void __lockfunc rt_read_unlock(rwlock_t *rwlock) +@@ -350,6 +358,7 @@ void __lockfunc rt_read_unlock(rwlock_t rwlock_release(&rwlock->dep_map, 1, _RET_IP_); do_read_rt_unlock(rwlock); migrate_enable(); @@ -194,7 +212,7 @@ index aebb7ce25bc6..f2e155b2c4a8 100644 } EXPORT_SYMBOL(rt_read_unlock); -@@ -358,6 +367,7 @@ void __lockfunc rt_write_unlock(rwlock_t *rwlock) +@@ -358,6 +367,7 @@ void __lockfunc rt_write_unlock(rwlock_t rwlock_release(&rwlock->dep_map, 1, _RET_IP_); do_write_rt_unlock(rwlock); migrate_enable(); @@ -202,42 +220,72 @@ index aebb7ce25bc6..f2e155b2c4a8 100644 } EXPORT_SYMBOL(rt_write_unlock); -diff --git a/kernel/rcu/tree_plugin.h b/kernel/rcu/tree_plugin.h -index 65efae0cf087..09c739703533 100644 --- a/kernel/rcu/tree_plugin.h +++ b/kernel/rcu/tree_plugin.h -@@ -324,13 +324,13 @@ static void rcu_preempt_note_context_switch(bool preempt) +@@ -337,9 +337,13 @@ static void rcu_preempt_note_context_swi struct task_struct *t = current; struct rcu_data *rdp; struct rcu_node *rnp; -- int mg_counter = 0; + int sleeping_l = 0; - RCU_LOCKDEP_WARN(!irqs_disabled(), "rcu_preempt_note_context_switch() invoked with interrupts enabled!!!\n"); --#if defined(CONFIG_PREEMPT_RT_BASE) -- mg_counter = t->migrate_disable; + lockdep_assert_irqs_disabled(); +- WARN_ON_ONCE(!preempt && t->rcu_read_lock_nesting > 0); +#if defined(CONFIG_PREEMPT_RT_FULL) + sleeping_l = t->sleeping_lock; - #endif -- WARN_ON_ONCE(!preempt && t->rcu_read_lock_nesting > 0 && !mg_counter); ++#endif + WARN_ON_ONCE(!preempt && t->rcu_read_lock_nesting > 0 && !sleeping_l); if (t->rcu_read_lock_nesting > 0 && !t->rcu_read_unlock_special.b.blocked) { -diff --git a/kernel/time/hrtimer.c b/kernel/time/hrtimer.c -index ce2c2d04cbaa..b59e009087a9 100644 ---- a/kernel/time/hrtimer.c -+++ b/kernel/time/hrtimer.c -@@ -1870,7 +1870,9 @@ void cpu_chill(void) - chill_time = ktime_set(0, NSEC_PER_MSEC); - set_current_state(TASK_UNINTERRUPTIBLE); - current->flags |= PF_NOFREEZE; -+ sleeping_lock_inc(); - schedule_hrtimeout(&chill_time, HRTIMER_MODE_REL_HARD); -+ sleeping_lock_dec(); - if (!freeze_flag) - current->flags &= ~PF_NOFREEZE; +--- a/kernel/sched/core.c ++++ b/kernel/sched/core.c +@@ -7307,4 +7307,49 @@ void migrate_enable(void) + preempt_enable(); } --- -2.19.2 - + EXPORT_SYMBOL(migrate_enable); ++ ++#elif !defined(CONFIG_SMP) && defined(CONFIG_PREEMPT_RT_BASE) ++void migrate_disable(void) ++{ ++ struct task_struct *p = current; ++ ++ if (in_atomic() || irqs_disabled()) { ++#ifdef CONFIG_SCHED_DEBUG ++ p->migrate_disable_atomic++; ++#endif ++ return; ++ } ++#ifdef CONFIG_SCHED_DEBUG ++ if (unlikely(p->migrate_disable_atomic)) { ++ tracing_off(); ++ WARN_ON_ONCE(1); ++ } ++#endif ++ ++ p->migrate_disable++; ++} ++EXPORT_SYMBOL(migrate_disable); ++ ++void migrate_enable(void) ++{ ++ struct task_struct *p = current; ++ ++ if (in_atomic() || irqs_disabled()) { ++#ifdef CONFIG_SCHED_DEBUG ++ p->migrate_disable_atomic--; ++#endif ++ return; ++ } ++ ++#ifdef CONFIG_SCHED_DEBUG ++ if (unlikely(p->migrate_disable_atomic)) { ++ tracing_off(); ++ WARN_ON_ONCE(1); ++ } ++#endif ++ ++ WARN_ON_ONCE(p->migrate_disable <= 0); ++ p->migrate_disable--; ++} ++EXPORT_SYMBOL(migrate_enable); + #endif diff --git a/kernel/patches-4.14.x-rt/0423-sched-migrate_disable-fallback-to-preempt_disable-in.patch b/kernel/patches-4.19.x-rt/0158-sched-migrate_disable-fallback-to-preempt_disable-in.patch similarity index 75% rename from kernel/patches-4.14.x-rt/0423-sched-migrate_disable-fallback-to-preempt_disable-in.patch rename to kernel/patches-4.19.x-rt/0158-sched-migrate_disable-fallback-to-preempt_disable-in.patch index 7b84b153d..3b9f2326e 100644 --- a/kernel/patches-4.14.x-rt/0423-sched-migrate_disable-fallback-to-preempt_disable-in.patch +++ b/kernel/patches-4.19.x-rt/0158-sched-migrate_disable-fallback-to-preempt_disable-in.patch @@ -1,10 +1,7 @@ -From db458c25559ed124e7b2dd0feeb8161f925fd4c2 Mon Sep 17 00:00:00 2001 From: Sebastian Andrzej Siewior Date: Thu, 5 Jul 2018 14:44:51 +0200 -Subject: [PATCH 423/450] sched/migrate_disable: fallback to preempt_disable() - instead barrier() - -[ Upstream commit 10e90c155bbc7cab420f47694404f8f9fe33c2b2 ] +Subject: [PATCH] sched/migrate_disable: fallback to preempt_disable() instead + barrier() On SMP + !RT migrate_disable() is still around. It is not part of spin_lock() anymore so it has almost no users. However the futex code has a workaround for @@ -40,19 +37,16 @@ This means we can now: Cc: stable-rt@vger.kernel.org Reported-by: joe.korty@concurrent-rt.com Signed-off-by: Sebastian Andrzej Siewior -Signed-off-by: Steven Rostedt (VMware) --- - include/linux/preempt.h | 6 +++--- - include/linux/sched.h | 4 ++-- - kernel/sched/core.c | 23 +++++++++++------------ - kernel/sched/debug.c | 2 +- + include/linux/preempt.h | 6 +++--- + include/linux/sched.h | 4 ++-- + kernel/sched/core.c | 23 +++++++++++------------ + kernel/sched/debug.c | 2 +- 4 files changed, 17 insertions(+), 18 deletions(-) -diff --git a/include/linux/preempt.h b/include/linux/preempt.h -index 0591df500e9d..6728662a81e8 100644 --- a/include/linux/preempt.h +++ b/include/linux/preempt.h -@@ -224,7 +224,7 @@ do { \ +@@ -204,7 +204,7 @@ do { \ #define preemptible() (preempt_count() == 0 && !irqs_disabled()) @@ -61,7 +55,7 @@ index 0591df500e9d..6728662a81e8 100644 extern void migrate_disable(void); extern void migrate_enable(void); -@@ -241,8 +241,8 @@ static inline int __migrate_disabled(struct task_struct *p) +@@ -221,8 +221,8 @@ static inline int __migrate_disabled(str } #else @@ -72,11 +66,9 @@ index 0591df500e9d..6728662a81e8 100644 static inline int __migrate_disabled(struct task_struct *p) { return 0; -diff --git a/include/linux/sched.h b/include/linux/sched.h -index 462baf19cf41..5d069426cbea 100644 --- a/include/linux/sched.h +++ b/include/linux/sched.h -@@ -626,7 +626,7 @@ struct task_struct { +@@ -667,7 +667,7 @@ struct task_struct { int nr_cpus_allowed; const cpumask_t *cpus_ptr; cpumask_t cpus_mask; @@ -84,8 +76,8 @@ index 462baf19cf41..5d069426cbea 100644 +#if defined(CONFIG_SMP) && defined(CONFIG_PREEMPT_RT_BASE) int migrate_disable; int migrate_disable_update; - int pinned_on_cpu; -@@ -635,8 +635,8 @@ struct task_struct { + # ifdef CONFIG_SCHED_DEBUG +@@ -675,8 +675,8 @@ struct task_struct { # endif #elif !defined(CONFIG_SMP) && defined(CONFIG_PREEMPT_RT_BASE) @@ -95,11 +87,9 @@ index 462baf19cf41..5d069426cbea 100644 int migrate_disable_atomic; # endif #endif -diff --git a/kernel/sched/core.c b/kernel/sched/core.c -index d7bfa2dd53e4..97b690d741f4 100644 --- a/kernel/sched/core.c +++ b/kernel/sched/core.c -@@ -1107,7 +1107,7 @@ void set_cpus_allowed_common(struct task_struct *p, const struct cpumask *new_ma +@@ -1029,7 +1029,7 @@ void set_cpus_allowed_common(struct task p->nr_cpus_allowed = cpumask_weight(new_mask); } @@ -108,7 +98,7 @@ index d7bfa2dd53e4..97b690d741f4 100644 int __migrate_disabled(struct task_struct *p) { return p->migrate_disable; -@@ -1146,7 +1146,7 @@ static void __do_set_cpus_allowed_tail(struct task_struct *p, +@@ -1069,7 +1069,7 @@ static void __do_set_cpus_allowed_tail(s void do_set_cpus_allowed(struct task_struct *p, const struct cpumask *new_mask) { @@ -117,7 +107,7 @@ index d7bfa2dd53e4..97b690d741f4 100644 if (__migrate_disabled(p)) { lockdep_assert_held(&p->pi_lock); -@@ -1219,7 +1219,7 @@ static int __set_cpus_allowed_ptr(struct task_struct *p, +@@ -1142,7 +1142,7 @@ static int __set_cpus_allowed_ptr(struct if (cpumask_test_cpu(task_cpu(p), new_mask) || __migrate_disabled(p)) goto out; @@ -126,16 +116,16 @@ index d7bfa2dd53e4..97b690d741f4 100644 if (__migrate_disabled(p)) { p->migrate_disable_update = 1; goto out; -@@ -6903,7 +6903,7 @@ const u32 sched_prio_to_wmult[40] = { - /* 15 */ 119304647, 148102320, 186737708, 238609294, 286331153, - }; +@@ -7163,7 +7163,7 @@ const u32 sched_prio_to_wmult[40] = { + + #undef CREATE_TRACE_POINTS -#if defined(CONFIG_PREEMPT_COUNT) && defined(CONFIG_SMP) +#if defined(CONFIG_SMP) && defined(CONFIG_PREEMPT_RT_BASE) static inline void update_nr_migratory(struct task_struct *p, long delta) -@@ -7054,45 +7054,44 @@ EXPORT_SYMBOL(migrate_enable); +@@ -7311,45 +7311,44 @@ EXPORT_SYMBOL(migrate_enable); #elif !defined(CONFIG_SMP) && defined(CONFIG_PREEMPT_RT_BASE) void migrate_disable(void) { @@ -188,11 +178,9 @@ index d7bfa2dd53e4..97b690d741f4 100644 } EXPORT_SYMBOL(migrate_enable); #endif -diff --git a/kernel/sched/debug.c b/kernel/sched/debug.c -index 3108da1ee253..b5b43861c2b6 100644 --- a/kernel/sched/debug.c +++ b/kernel/sched/debug.c -@@ -1017,7 +1017,7 @@ void proc_sched_show_task(struct task_struct *p, struct pid_namespace *ns, +@@ -978,7 +978,7 @@ void proc_sched_show_task(struct task_st P(dl.runtime); P(dl.deadline); } @@ -201,6 +189,3 @@ index 3108da1ee253..b5b43861c2b6 100644 P(migrate_disable); #endif P(nr_cpus_allowed); --- -2.19.2 - diff --git a/kernel/patches-4.19.x-rt/0159-locking-don-t-check-for-__LINUX_SPINLOCK_TYPES_H-on-.patch b/kernel/patches-4.19.x-rt/0159-locking-don-t-check-for-__LINUX_SPINLOCK_TYPES_H-on-.patch new file mode 100644 index 000000000..6cd8d3f31 --- /dev/null +++ b/kernel/patches-4.19.x-rt/0159-locking-don-t-check-for-__LINUX_SPINLOCK_TYPES_H-on-.patch @@ -0,0 +1,157 @@ +From: Sebastian Andrzej Siewior +Date: Fri, 4 Aug 2017 17:40:42 +0200 +Subject: [PATCH 1/2] locking: don't check for __LINUX_SPINLOCK_TYPES_H on -RT + archs + +Upstream uses arch_spinlock_t within spinlock_t and requests that +spinlock_types.h header file is included first. +On -RT we have the rt_mutex with its raw_lock wait_lock which needs +architectures' spinlock_types.h header file for its definition. However +we need rt_mutex first because it is used to build the spinlock_t so +that check does not work for us. +Therefore I am dropping that check. + +Signed-off-by: Sebastian Andrzej Siewior +--- + arch/alpha/include/asm/spinlock_types.h | 4 ---- + arch/arm/include/asm/spinlock_types.h | 4 ---- + arch/arm64/include/asm/spinlock_types.h | 4 ---- + arch/hexagon/include/asm/spinlock_types.h | 4 ---- + arch/ia64/include/asm/spinlock_types.h | 4 ---- + arch/powerpc/include/asm/spinlock_types.h | 4 ---- + arch/s390/include/asm/spinlock_types.h | 4 ---- + arch/sh/include/asm/spinlock_types.h | 4 ---- + arch/xtensa/include/asm/spinlock_types.h | 4 ---- + include/linux/spinlock_types_up.h | 4 ---- + 10 files changed, 40 deletions(-) + +--- a/arch/alpha/include/asm/spinlock_types.h ++++ b/arch/alpha/include/asm/spinlock_types.h +@@ -2,10 +2,6 @@ + #ifndef _ALPHA_SPINLOCK_TYPES_H + #define _ALPHA_SPINLOCK_TYPES_H + +-#ifndef __LINUX_SPINLOCK_TYPES_H +-# error "please don't include this file directly" +-#endif +- + typedef struct { + volatile unsigned int lock; + } arch_spinlock_t; +--- a/arch/arm/include/asm/spinlock_types.h ++++ b/arch/arm/include/asm/spinlock_types.h +@@ -2,10 +2,6 @@ + #ifndef __ASM_SPINLOCK_TYPES_H + #define __ASM_SPINLOCK_TYPES_H + +-#ifndef __LINUX_SPINLOCK_TYPES_H +-# error "please don't include this file directly" +-#endif +- + #define TICKET_SHIFT 16 + + typedef struct { +--- a/arch/arm64/include/asm/spinlock_types.h ++++ b/arch/arm64/include/asm/spinlock_types.h +@@ -16,10 +16,6 @@ + #ifndef __ASM_SPINLOCK_TYPES_H + #define __ASM_SPINLOCK_TYPES_H + +-#if !defined(__LINUX_SPINLOCK_TYPES_H) && !defined(__ASM_SPINLOCK_H) +-# error "please don't include this file directly" +-#endif +- + #include + #include + +--- a/arch/hexagon/include/asm/spinlock_types.h ++++ b/arch/hexagon/include/asm/spinlock_types.h +@@ -21,10 +21,6 @@ + #ifndef _ASM_SPINLOCK_TYPES_H + #define _ASM_SPINLOCK_TYPES_H + +-#ifndef __LINUX_SPINLOCK_TYPES_H +-# error "please don't include this file directly" +-#endif +- + typedef struct { + volatile unsigned int lock; + } arch_spinlock_t; +--- a/arch/ia64/include/asm/spinlock_types.h ++++ b/arch/ia64/include/asm/spinlock_types.h +@@ -2,10 +2,6 @@ + #ifndef _ASM_IA64_SPINLOCK_TYPES_H + #define _ASM_IA64_SPINLOCK_TYPES_H + +-#ifndef __LINUX_SPINLOCK_TYPES_H +-# error "please don't include this file directly" +-#endif +- + typedef struct { + volatile unsigned int lock; + } arch_spinlock_t; +--- a/arch/powerpc/include/asm/spinlock_types.h ++++ b/arch/powerpc/include/asm/spinlock_types.h +@@ -2,10 +2,6 @@ + #ifndef _ASM_POWERPC_SPINLOCK_TYPES_H + #define _ASM_POWERPC_SPINLOCK_TYPES_H + +-#ifndef __LINUX_SPINLOCK_TYPES_H +-# error "please don't include this file directly" +-#endif +- + typedef struct { + volatile unsigned int slock; + } arch_spinlock_t; +--- a/arch/s390/include/asm/spinlock_types.h ++++ b/arch/s390/include/asm/spinlock_types.h +@@ -2,10 +2,6 @@ + #ifndef __ASM_SPINLOCK_TYPES_H + #define __ASM_SPINLOCK_TYPES_H + +-#ifndef __LINUX_SPINLOCK_TYPES_H +-# error "please don't include this file directly" +-#endif +- + typedef struct { + int lock; + } __attribute__ ((aligned (4))) arch_spinlock_t; +--- a/arch/sh/include/asm/spinlock_types.h ++++ b/arch/sh/include/asm/spinlock_types.h +@@ -2,10 +2,6 @@ + #ifndef __ASM_SH_SPINLOCK_TYPES_H + #define __ASM_SH_SPINLOCK_TYPES_H + +-#ifndef __LINUX_SPINLOCK_TYPES_H +-# error "please don't include this file directly" +-#endif +- + typedef struct { + volatile unsigned int lock; + } arch_spinlock_t; +--- a/arch/xtensa/include/asm/spinlock_types.h ++++ b/arch/xtensa/include/asm/spinlock_types.h +@@ -2,10 +2,6 @@ + #ifndef __ASM_SPINLOCK_TYPES_H + #define __ASM_SPINLOCK_TYPES_H + +-#ifndef __LINUX_SPINLOCK_TYPES_H +-# error "please don't include this file directly" +-#endif +- + typedef struct { + volatile unsigned int slock; + } arch_spinlock_t; +--- a/include/linux/spinlock_types_up.h ++++ b/include/linux/spinlock_types_up.h +@@ -1,10 +1,6 @@ + #ifndef __LINUX_SPINLOCK_TYPES_UP_H + #define __LINUX_SPINLOCK_TYPES_UP_H + +-#ifndef __LINUX_SPINLOCK_TYPES_H +-# error "please don't include this file directly" +-#endif +- + /* + * include/linux/spinlock_types_up.h - spinlock type definitions for UP + * diff --git a/kernel/patches-4.14.x-rt/0266-rcu-Frob-softirq-test.patch b/kernel/patches-4.19.x-rt/0160-peter_zijlstra-frob-rcu.patch similarity index 93% rename from kernel/patches-4.14.x-rt/0266-rcu-Frob-softirq-test.patch rename to kernel/patches-4.19.x-rt/0160-peter_zijlstra-frob-rcu.patch index fdcb18aa3..13f262ca1 100644 --- a/kernel/patches-4.14.x-rt/0266-rcu-Frob-softirq-test.patch +++ b/kernel/patches-4.19.x-rt/0160-peter_zijlstra-frob-rcu.patch @@ -1,7 +1,6 @@ -From b4d56c6e48e33fe18861b55552fd5375cbae4b67 Mon Sep 17 00:00:00 2001 +Subject: rcu: Frob softirq test From: Peter Zijlstra -Date: Sat, 13 Aug 2011 00:23:17 +0200 -Subject: [PATCH 266/450] rcu: Frob softirq test +Date: Sat Aug 13 00:23:17 CEST 2011 With RT_FULL we get the below wreckage: @@ -11,15 +10,15 @@ With RT_FULL we get the below wreckage: [ 126.060490] ------------------------------------------------------- [ 126.060492] irq/24-eth0/1235 is trying to acquire lock: [ 126.060495] (&(lock)->wait_lock#2){+.+...}, at: [] rt_mutex_slowunlock+0x16/0x55 -[ 126.060503] +[ 126.060503] [ 126.060504] but task is already holding lock: [ 126.060506] (&p->pi_lock){-...-.}, at: [] try_to_wake_up+0x35/0x429 -[ 126.060511] +[ 126.060511] [ 126.060511] which lock already depends on the new lock. -[ 126.060513] -[ 126.060514] +[ 126.060513] +[ 126.060514] [ 126.060514] the existing dependency chain (in reverse order) is: -[ 126.060516] +[ 126.060516] [ 126.060516] -> #1 (&p->pi_lock){-...-.}: [ 126.060519] [] lock_acquire+0x145/0x18a [ 126.060524] [] _raw_spin_lock_irqsave+0x4b/0x85 @@ -30,7 +29,7 @@ With RT_FULL we get the below wreckage: [ 126.060541] [] rcu_boost_kthread+0x7d/0x9b [ 126.060544] [] kthread+0x99/0xa1 [ 126.060547] [] kernel_thread_helper+0x4/0x10 -[ 126.060551] +[ 126.060551] [ 126.060552] -> #0 (&(lock)->wait_lock#2){+.+...}: [ 126.060555] [] __lock_acquire+0x1157/0x1816 [ 126.060558] [] lock_acquire+0x145/0x18a @@ -50,23 +49,23 @@ With RT_FULL we get the below wreckage: [ 126.060603] [] irq_thread+0xde/0x1af [ 126.060606] [] kthread+0x99/0xa1 [ 126.060608] [] kernel_thread_helper+0x4/0x10 -[ 126.060611] +[ 126.060611] [ 126.060612] other info that might help us debug this: -[ 126.060614] +[ 126.060614] [ 126.060615] Possible unsafe locking scenario: -[ 126.060616] +[ 126.060616] [ 126.060617] CPU0 CPU1 [ 126.060619] ---- ---- [ 126.060620] lock(&p->pi_lock); [ 126.060623] lock(&(lock)->wait_lock); [ 126.060625] lock(&p->pi_lock); [ 126.060627] lock(&(lock)->wait_lock); -[ 126.060629] +[ 126.060629] [ 126.060629] *** DEADLOCK *** -[ 126.060630] +[ 126.060630] [ 126.060632] 1 lock held by irq/24-eth0/1235: [ 126.060633] #0: (&p->pi_lock){-...-.}, at: [] try_to_wake_up+0x35/0x429 -[ 126.060638] +[ 126.060638] [ 126.060638] stack backtrace: [ 126.060641] Pid: 1235, comm: irq/24-eth0 Not tainted 3.0.1-rt10+ #30 [ 126.060643] Call Trace: @@ -151,14 +150,12 @@ here... so this is very likely a bandaid and more thought is required. Cc: Paul E. McKenney Signed-off-by: Peter Zijlstra --- - kernel/rcu/tree_plugin.h | 2 +- + kernel/rcu/tree_plugin.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) -diff --git a/kernel/rcu/tree_plugin.h b/kernel/rcu/tree_plugin.h -index 18b98ae934a2..157593d080c5 100644 --- a/kernel/rcu/tree_plugin.h +++ b/kernel/rcu/tree_plugin.h -@@ -466,7 +466,7 @@ void rcu_read_unlock_special(struct task_struct *t) +@@ -524,7 +524,7 @@ static void rcu_read_unlock_special(stru } /* Hardware IRQ handlers cannot block, complain if they get here. */ @@ -167,6 +164,3 @@ index 18b98ae934a2..157593d080c5 100644 lockdep_rcu_suspicious(__FILE__, __LINE__, "rcu_read_unlock() from irq or softirq with blocking in critical section!!!\n"); pr_alert("->rcu_read_unlock_special: %#x (b: %d, enq: %d nq: %d)\n", --- -2.19.2 - diff --git a/kernel/patches-4.14.x-rt/0267-rcu-Merge-RCU-bh-into-RCU-preempt.patch b/kernel/patches-4.19.x-rt/0161-rcu-merge-rcu-bh-into-rcu-preempt-for-rt.patch similarity index 59% rename from kernel/patches-4.14.x-rt/0267-rcu-Merge-RCU-bh-into-RCU-preempt.patch rename to kernel/patches-4.19.x-rt/0161-rcu-merge-rcu-bh-into-rcu-preempt-for-rt.patch index ce59b8f12..c2f60ca7d 100644 --- a/kernel/patches-4.14.x-rt/0267-rcu-Merge-RCU-bh-into-RCU-preempt.patch +++ b/kernel/patches-4.19.x-rt/0161-rcu-merge-rcu-bh-into-rcu-preempt-for-rt.patch @@ -1,7 +1,6 @@ -From 483b81787aca812ec731a33fbb0356a133c193f9 Mon Sep 17 00:00:00 2001 -From: Thomas Gleixner +Subject: rcu: Merge RCU-bh into RCU-preempt Date: Wed, 5 Oct 2011 11:59:38 -0700 -Subject: [PATCH 267/450] rcu: Merge RCU-bh into RCU-preempt +From: Thomas Gleixner The Linux kernel has long RCU-bh read-side critical sections that intolerably increase scheduling latency under mainline's RCU-bh rules, @@ -23,21 +22,20 @@ Signed-off-by: Thomas Gleixner Signed-off-by: Paul E. McKenney Link: http://lkml.kernel.org/r/20111005185938.GA20403@linux.vnet.ibm.com Signed-off-by: Thomas Gleixner ---- - include/linux/rcupdate.h | 23 +++++++++++++++++++++++ - include/linux/rcutree.h | 8 ++++++++ - kernel/rcu/rcu.h | 14 +++++++++++--- - kernel/rcu/rcutorture.c | 7 +++++++ - kernel/rcu/tree.c | 24 ++++++++++++++++++++++++ - kernel/rcu/tree.h | 2 ++ - kernel/rcu/update.c | 2 ++ - 7 files changed, 77 insertions(+), 3 deletions(-) -diff --git a/include/linux/rcupdate.h b/include/linux/rcupdate.h -index a2dc82b3118a..104fa2bdf127 100644 +--- + include/linux/rcupdate.h | 19 +++++++++++++++++++ + include/linux/rcutree.h | 8 ++++++++ + kernel/rcu/rcu.h | 11 +++++++++-- + kernel/rcu/rcutorture.c | 7 +++++++ + kernel/rcu/tree.c | 26 ++++++++++++++++++++++++++ + kernel/rcu/tree.h | 2 ++ + kernel/rcu/update.c | 2 ++ + 7 files changed, 73 insertions(+), 2 deletions(-) + --- a/include/linux/rcupdate.h +++ b/include/linux/rcupdate.h -@@ -56,7 +56,11 @@ void call_rcu(struct rcu_head *head, rcu_callback_t func); +@@ -56,7 +56,11 @@ void call_rcu(struct rcu_head *head, rcu #define call_rcu call_rcu_sched #endif /* #else #ifdef CONFIG_PREEMPT_RCU */ @@ -49,19 +47,7 @@ index a2dc82b3118a..104fa2bdf127 100644 void call_rcu_sched(struct rcu_head *head, rcu_callback_t func); void synchronize_sched(void); void rcu_barrier_tasks(void); -@@ -113,7 +117,11 @@ static inline int rcu_preempt_depth(void) - void rcu_init(void); - extern int rcu_scheduler_active __read_mostly; - void rcu_sched_qs(void); -+#ifdef CONFIG_PREEMPT_RT_FULL -+static inline void rcu_bh_qs(void) { } -+#else - void rcu_bh_qs(void); -+#endif - void rcu_check_callbacks(int user); - void rcu_report_dead(unsigned int cpu); - void rcu_cpu_starting(unsigned int cpu); -@@ -263,7 +271,14 @@ extern struct lockdep_map rcu_sched_lock_map; +@@ -263,7 +267,14 @@ extern struct lockdep_map rcu_sched_lock extern struct lockdep_map rcu_callback_map; int debug_lockdep_rcu_enabled(void); int rcu_read_lock_held(void); @@ -76,7 +62,7 @@ index a2dc82b3118a..104fa2bdf127 100644 int rcu_read_lock_sched_held(void); #else /* #ifdef CONFIG_DEBUG_LOCK_ALLOC */ -@@ -667,10 +682,14 @@ static inline void rcu_read_unlock(void) +@@ -663,10 +674,14 @@ static inline void rcu_read_unlock(void) static inline void rcu_read_lock_bh(void) { local_bh_disable(); @@ -91,7 +77,7 @@ index a2dc82b3118a..104fa2bdf127 100644 } /* -@@ -680,10 +699,14 @@ static inline void rcu_read_lock_bh(void) +@@ -676,10 +691,14 @@ static inline void rcu_read_lock_bh(void */ static inline void rcu_read_unlock_bh(void) { @@ -106,11 +92,9 @@ index a2dc82b3118a..104fa2bdf127 100644 local_bh_enable(); } -diff --git a/include/linux/rcutree.h b/include/linux/rcutree.h -index 37d6fd3b7ff8..a082fde7d6bc 100644 --- a/include/linux/rcutree.h +++ b/include/linux/rcutree.h -@@ -44,7 +44,11 @@ static inline void rcu_virt_note_context_switch(int cpu) +@@ -44,7 +44,11 @@ static inline void rcu_virt_note_context rcu_note_context_switch(false); } @@ -122,57 +106,51 @@ index 37d6fd3b7ff8..a082fde7d6bc 100644 void synchronize_sched_expedited(void); void synchronize_rcu_expedited(void); -@@ -72,7 +76,11 @@ static inline void synchronize_rcu_bh_expedited(void) +@@ -72,7 +76,11 @@ static inline void synchronize_rcu_bh_ex } void rcu_barrier(void); +#ifdef CONFIG_PREEMPT_RT_FULL -+# define rcu_barrier_bh rcu_barrier ++# define rcu_barrier_bh rcu_barrier +#else void rcu_barrier_bh(void); +#endif void rcu_barrier_sched(void); + bool rcu_eqs_special_set(int cpu); unsigned long get_state_synchronize_rcu(void); - void cond_synchronize_rcu(unsigned long oldstate); -diff --git a/kernel/rcu/rcu.h b/kernel/rcu/rcu.h -index e4b43fef89f5..0b056c30e9b1 100644 --- a/kernel/rcu/rcu.h +++ b/kernel/rcu/rcu.h -@@ -462,18 +462,26 @@ static inline void show_rcu_gp_kthreads(void) { } - extern unsigned long rcutorture_testseq; - extern unsigned long rcutorture_vernum; - unsigned long rcu_batches_started(void); --unsigned long rcu_batches_started_bh(void); - unsigned long rcu_batches_started_sched(void); - unsigned long rcu_batches_completed(void); --unsigned long rcu_batches_completed_bh(void); - unsigned long rcu_batches_completed_sched(void); +@@ -528,7 +528,6 @@ static inline void show_rcu_gp_kthreads( + static inline int rcu_get_gp_kthreads_prio(void) { return 0; } + #else /* #ifdef CONFIG_TINY_RCU */ + unsigned long rcu_get_gp_seq(void); +-unsigned long rcu_bh_get_gp_seq(void); + unsigned long rcu_sched_get_gp_seq(void); unsigned long rcu_exp_batches_completed(void); unsigned long rcu_exp_batches_completed_sched(void); - unsigned long srcu_batches_completed(struct srcu_struct *sp); +@@ -536,10 +535,18 @@ unsigned long srcu_batches_completed(str void show_rcu_gp_kthreads(void); + int rcu_get_gp_kthreads_prio(void); void rcu_force_quiescent_state(void); -void rcu_bh_force_quiescent_state(void); void rcu_sched_force_quiescent_state(void); + extern struct workqueue_struct *rcu_gp_wq; + extern struct workqueue_struct *rcu_par_gp_wq; + -+#ifndef CONFIG_PREEMPT_RT_FULL -+void rcu_bh_force_quiescent_state(void); -+unsigned long rcu_batches_started_bh(void); -+unsigned long rcu_batches_completed_bh(void); ++#ifdef CONFIG_PREEMPT_RT_FULL ++#define rcu_bh_get_gp_seq rcu_get_gp_seq ++#define rcu_bh_force_quiescent_state rcu_force_quiescent_state +#else -+# define rcu_bh_force_quiescent_state rcu_force_quiescent_state -+# define rcu_batches_completed_bh rcu_batches_completed -+# define rcu_batches_started_bh rcu_batches_completed ++unsigned long rcu_bh_get_gp_seq(void); ++void rcu_bh_force_quiescent_state(void); +#endif + #endif /* #else #ifdef CONFIG_TINY_RCU */ #ifdef CONFIG_RCU_NOCB_CPU -diff --git a/kernel/rcu/rcutorture.c b/kernel/rcu/rcutorture.c -index 45f2ffbc1e78..2e9dbb734d5a 100644 --- a/kernel/rcu/rcutorture.c +++ b/kernel/rcu/rcutorture.c -@@ -417,6 +417,7 @@ static struct rcu_torture_ops rcu_ops = { +@@ -434,6 +434,7 @@ static struct rcu_torture_ops rcu_ops = .name = "rcu" }; @@ -180,7 +158,7 @@ index 45f2ffbc1e78..2e9dbb734d5a 100644 /* * Definitions for rcu_bh torture testing. */ -@@ -456,6 +457,12 @@ static struct rcu_torture_ops rcu_bh_ops = { +@@ -475,6 +476,12 @@ static struct rcu_torture_ops rcu_bh_ops .name = "rcu_bh" }; @@ -193,11 +171,9 @@ index 45f2ffbc1e78..2e9dbb734d5a 100644 /* * Don't even think about trying any of these in real life!!! * The names includes "busted", and they really means it! -diff --git a/kernel/rcu/tree.c b/kernel/rcu/tree.c -index 710ce1d6b982..f9d942d18e86 100644 --- a/kernel/rcu/tree.c +++ b/kernel/rcu/tree.c -@@ -243,6 +243,7 @@ void rcu_sched_qs(void) +@@ -244,6 +244,7 @@ void rcu_sched_qs(void) this_cpu_ptr(&rcu_sched_data), true); } @@ -205,45 +181,35 @@ index 710ce1d6b982..f9d942d18e86 100644 void rcu_bh_qs(void) { RCU_LOCKDEP_WARN(preemptible(), "rcu_bh_qs() invoked with preemption enabled!!!"); -@@ -253,6 +254,7 @@ void rcu_bh_qs(void) +@@ -254,6 +255,11 @@ void rcu_bh_qs(void) __this_cpu_write(rcu_bh_data.cpu_no_qs.b.norm, false); } } ++#else ++void rcu_bh_qs(void) ++{ ++} +#endif /* * Steal a bit from the bottom of ->dynticks for idle entry/exit -@@ -564,11 +566,13 @@ EXPORT_SYMBOL_GPL(rcu_batches_started_sched); - /* - * Return the number of RCU BH batches started thus far for debug & stats. - */ -+#ifndef CONFIG_PREEMPT_RT_FULL - unsigned long rcu_batches_started_bh(void) - { - return rcu_bh_state.gpnum; +@@ -568,6 +574,7 @@ unsigned long rcu_sched_get_gp_seq(void) } - EXPORT_SYMBOL_GPL(rcu_batches_started_bh); -+#endif - - /* - * Return the number of RCU batches completed thus far for debug & stats. -@@ -588,6 +592,7 @@ unsigned long rcu_batches_completed_sched(void) - } - EXPORT_SYMBOL_GPL(rcu_batches_completed_sched); + EXPORT_SYMBOL_GPL(rcu_sched_get_gp_seq); +#ifndef CONFIG_PREEMPT_RT_FULL /* - * Return the number of RCU BH batches completed thus far for debug & stats. + * Return the number of RCU-bh GPs completed thus far for debug & stats. */ -@@ -596,6 +601,7 @@ unsigned long rcu_batches_completed_bh(void) - return rcu_bh_state.completed; +@@ -576,6 +583,7 @@ unsigned long rcu_bh_get_gp_seq(void) + return READ_ONCE(rcu_bh_state.gp_seq); } - EXPORT_SYMBOL_GPL(rcu_batches_completed_bh); + EXPORT_SYMBOL_GPL(rcu_bh_get_gp_seq); +#endif /* * Return the number of RCU expedited batches completed thus far for -@@ -619,6 +625,7 @@ unsigned long rcu_exp_batches_completed_sched(void) +@@ -599,6 +607,7 @@ unsigned long rcu_exp_batches_completed_ } EXPORT_SYMBOL_GPL(rcu_exp_batches_completed_sched); @@ -251,7 +217,7 @@ index 710ce1d6b982..f9d942d18e86 100644 /* * Force a quiescent state. */ -@@ -637,6 +644,13 @@ void rcu_bh_force_quiescent_state(void) +@@ -617,6 +626,13 @@ void rcu_bh_force_quiescent_state(void) } EXPORT_SYMBOL_GPL(rcu_bh_force_quiescent_state); @@ -265,7 +231,7 @@ index 710ce1d6b982..f9d942d18e86 100644 /* * Force a quiescent state for RCU-sched. */ -@@ -687,9 +701,11 @@ void rcutorture_get_gp_data(enum rcutorture_type test_type, int *flags, +@@ -674,9 +690,11 @@ void rcutorture_get_gp_data(enum rcutort case RCU_FLAVOR: rsp = rcu_state_p; break; @@ -277,7 +243,7 @@ index 710ce1d6b982..f9d942d18e86 100644 case RCU_SCHED_FLAVOR: rsp = &rcu_sched_state; break; -@@ -3122,6 +3138,7 @@ void call_rcu_sched(struct rcu_head *head, rcu_callback_t func) +@@ -3049,6 +3067,7 @@ void call_rcu_sched(struct rcu_head *hea } EXPORT_SYMBOL_GPL(call_rcu_sched); @@ -285,7 +251,7 @@ index 710ce1d6b982..f9d942d18e86 100644 /** * call_rcu_bh() - Queue an RCU for invocation after a quicker grace period. * @head: structure to be used for queueing the RCU updates. -@@ -3149,6 +3166,7 @@ void call_rcu_bh(struct rcu_head *head, rcu_callback_t func) +@@ -3076,6 +3095,7 @@ void call_rcu_bh(struct rcu_head *head, __call_rcu(head, func, &rcu_bh_state, -1, 0); } EXPORT_SYMBOL_GPL(call_rcu_bh); @@ -293,7 +259,7 @@ index 710ce1d6b982..f9d942d18e86 100644 /* * Queue an RCU callback for lazy invocation after a grace period. -@@ -3234,6 +3252,7 @@ void synchronize_sched(void) +@@ -3161,6 +3181,7 @@ void synchronize_sched(void) } EXPORT_SYMBOL_GPL(synchronize_sched); @@ -301,7 +267,7 @@ index 710ce1d6b982..f9d942d18e86 100644 /** * synchronize_rcu_bh - wait until an rcu_bh grace period has elapsed. * -@@ -3260,6 +3279,7 @@ void synchronize_rcu_bh(void) +@@ -3187,6 +3208,7 @@ void synchronize_rcu_bh(void) wait_rcu_gp(call_rcu_bh); } EXPORT_SYMBOL_GPL(synchronize_rcu_bh); @@ -309,7 +275,7 @@ index 710ce1d6b982..f9d942d18e86 100644 /** * get_state_synchronize_rcu - Snapshot current RCU state -@@ -3610,6 +3630,7 @@ static void _rcu_barrier(struct rcu_state *rsp) +@@ -3494,6 +3516,7 @@ static void _rcu_barrier(struct rcu_stat mutex_unlock(&rsp->barrier_mutex); } @@ -317,7 +283,7 @@ index 710ce1d6b982..f9d942d18e86 100644 /** * rcu_barrier_bh - Wait until all in-flight call_rcu_bh() callbacks complete. */ -@@ -3618,6 +3639,7 @@ void rcu_barrier_bh(void) +@@ -3502,6 +3525,7 @@ void rcu_barrier_bh(void) _rcu_barrier(&rcu_bh_state); } EXPORT_SYMBOL_GPL(rcu_barrier_bh); @@ -325,7 +291,7 @@ index 710ce1d6b982..f9d942d18e86 100644 /** * rcu_barrier_sched - Wait for in-flight call_rcu_sched() callbacks. -@@ -4193,7 +4215,9 @@ void __init rcu_init(void) +@@ -4149,7 +4173,9 @@ void __init rcu_init(void) rcu_bootup_announce(); rcu_init_geometry(); @@ -335,11 +301,9 @@ index 710ce1d6b982..f9d942d18e86 100644 rcu_init_one(&rcu_sched_state); if (dump_tree) rcu_dump_rcu_node_tree(&rcu_sched_state); -diff --git a/kernel/rcu/tree.h b/kernel/rcu/tree.h -index 8e1f285f0a70..ac4296f85278 100644 --- a/kernel/rcu/tree.h +++ b/kernel/rcu/tree.h -@@ -427,7 +427,9 @@ extern struct list_head rcu_struct_flavors; +@@ -413,7 +413,9 @@ extern struct list_head rcu_struct_flavo */ extern struct rcu_state rcu_sched_state; @@ -349,11 +313,9 @@ index 8e1f285f0a70..ac4296f85278 100644 #ifdef CONFIG_PREEMPT_RCU extern struct rcu_state rcu_preempt_state; -diff --git a/kernel/rcu/update.c b/kernel/rcu/update.c -index 7a577bd989a4..c63c88a0de7e 100644 --- a/kernel/rcu/update.c +++ b/kernel/rcu/update.c -@@ -333,6 +333,7 @@ int rcu_read_lock_held(void) +@@ -286,6 +286,7 @@ int rcu_read_lock_held(void) } EXPORT_SYMBOL_GPL(rcu_read_lock_held); @@ -361,7 +323,7 @@ index 7a577bd989a4..c63c88a0de7e 100644 /** * rcu_read_lock_bh_held() - might we be in RCU-bh read-side critical section? * -@@ -359,6 +360,7 @@ int rcu_read_lock_bh_held(void) +@@ -312,6 +313,7 @@ int rcu_read_lock_bh_held(void) return in_softirq() || irqs_disabled(); } EXPORT_SYMBOL_GPL(rcu_read_lock_bh_held); @@ -369,6 +331,3 @@ index 7a577bd989a4..c63c88a0de7e 100644 #endif /* #ifdef CONFIG_DEBUG_LOCK_ALLOC */ --- -2.19.2 - diff --git a/kernel/patches-4.14.x-rt/0268-rcu-Make-ksoftirqd-do-RCU-quiescent-states.patch b/kernel/patches-4.19.x-rt/0162-patch-to-introduce-rcu-bh-qs-where-safe-from-softirq.patch similarity index 66% rename from kernel/patches-4.14.x-rt/0268-rcu-Make-ksoftirqd-do-RCU-quiescent-states.patch rename to kernel/patches-4.19.x-rt/0162-patch-to-introduce-rcu-bh-qs-where-safe-from-softirq.patch index 254be5ce0..29d27889e 100644 --- a/kernel/patches-4.14.x-rt/0268-rcu-Make-ksoftirqd-do-RCU-quiescent-states.patch +++ b/kernel/patches-4.19.x-rt/0162-patch-to-introduce-rcu-bh-qs-where-safe-from-softirq.patch @@ -1,7 +1,6 @@ -From 12e204e731465f1517223971e9046dd70de7ae59 Mon Sep 17 00:00:00 2001 +Subject: rcu: Make ksoftirqd do RCU quiescent states From: "Paul E. McKenney" Date: Wed, 5 Oct 2011 11:45:18 -0700 -Subject: [PATCH 268/450] rcu: Make ksoftirqd do RCU quiescent states Implementing RCU-bh in terms of RCU-preempt makes the system vulnerable to network-based denial-of-service attacks. This patch therefore @@ -22,33 +21,15 @@ in cases where __do_softirq() is invoked directly from ksoftirqd. Signed-off-by: Paul E. McKenney Link: http://lkml.kernel.org/r/20111005184518.GA21601@linux.vnet.ibm.com Signed-off-by: Thomas Gleixner ---- - include/linux/rcupdate.h | 4 ---- - kernel/rcu/tree.c | 9 ++++++++- - kernel/rcu/tree_plugin.h | 8 +++++++- - 3 files changed, 15 insertions(+), 6 deletions(-) -diff --git a/include/linux/rcupdate.h b/include/linux/rcupdate.h -index 104fa2bdf127..70996e134818 100644 ---- a/include/linux/rcupdate.h -+++ b/include/linux/rcupdate.h -@@ -117,11 +117,7 @@ static inline int rcu_preempt_depth(void) - void rcu_init(void); - extern int rcu_scheduler_active __read_mostly; - void rcu_sched_qs(void); --#ifdef CONFIG_PREEMPT_RT_FULL --static inline void rcu_bh_qs(void) { } --#else - void rcu_bh_qs(void); --#endif - void rcu_check_callbacks(int user); - void rcu_report_dead(unsigned int cpu); - void rcu_cpu_starting(unsigned int cpu); -diff --git a/kernel/rcu/tree.c b/kernel/rcu/tree.c -index f9d942d18e86..5e991041f50a 100644 +--- + kernel/rcu/tree.c | 18 +++++++++++++----- + kernel/rcu/tree_plugin.h | 8 +++++++- + 2 files changed, 20 insertions(+), 6 deletions(-) + --- a/kernel/rcu/tree.c +++ b/kernel/rcu/tree.c -@@ -243,7 +243,14 @@ void rcu_sched_qs(void) +@@ -244,7 +244,19 @@ void rcu_sched_qs(void) this_cpu_ptr(&rcu_sched_data), true); } @@ -58,14 +39,28 @@ index f9d942d18e86..5e991041f50a 100644 + +void rcu_bh_qs(void) +{ ++ unsigned long flags; ++ ++ /* Callers to this function, rcu_preempt_qs(), must disable irqs. */ ++ local_irq_save(flags); + rcu_preempt_qs(); ++ local_irq_restore(flags); +} +#else void rcu_bh_qs(void) { RCU_LOCKDEP_WARN(preemptible(), "rcu_bh_qs() invoked with preemption enabled!!!"); -diff --git a/kernel/rcu/tree_plugin.h b/kernel/rcu/tree_plugin.h -index 157593d080c5..65efae0cf087 100644 +@@ -255,10 +267,6 @@ void rcu_bh_qs(void) + __this_cpu_write(rcu_bh_data.cpu_no_qs.b.norm, false); + } + } +-#else +-void rcu_bh_qs(void) +-{ +-} + #endif + + /* --- a/kernel/rcu/tree_plugin.h +++ b/kernel/rcu/tree_plugin.h @@ -29,6 +29,7 @@ @@ -73,10 +68,10 @@ index 157593d080c5..65efae0cf087 100644 #include #include +#include + #include #include #include "../time/tick-internal.h" - #include "../locking/rtmutex_common.h" -@@ -1305,7 +1306,7 @@ static void rcu_prepare_kthreads(int cpu) +@@ -1407,7 +1408,7 @@ static void rcu_prepare_kthreads(int cpu #endif /* #else #ifdef CONFIG_RCU_BOOST */ @@ -85,7 +80,7 @@ index 157593d080c5..65efae0cf087 100644 /* * Check to see if any future RCU-related work will need to be done -@@ -1321,7 +1322,9 @@ int rcu_needs_cpu(u64 basemono, u64 *nextevt) +@@ -1423,7 +1424,9 @@ int rcu_needs_cpu(u64 basemono, u64 *nex *nextevt = KTIME_MAX; return rcu_cpu_has_callbacks(NULL); } @@ -95,7 +90,7 @@ index 157593d080c5..65efae0cf087 100644 /* * Because we do not have RCU_FAST_NO_HZ, don't bother cleaning up * after it. -@@ -1417,6 +1420,8 @@ static bool __maybe_unused rcu_try_advance_all_cbs(void) +@@ -1520,6 +1523,8 @@ static bool __maybe_unused rcu_try_advan return cbs_ready; } @@ -104,7 +99,7 @@ index 157593d080c5..65efae0cf087 100644 /* * Allow the CPU to enter dyntick-idle mode unless it has callbacks ready * to invoke. If the CPU has callbacks, try to advance them. Tell the -@@ -1459,6 +1464,7 @@ int rcu_needs_cpu(u64 basemono, u64 *nextevt) +@@ -1562,6 +1567,7 @@ int rcu_needs_cpu(u64 basemono, u64 *nex *nextevt = basemono + dj * TICK_NSEC; return 0; } @@ -112,6 +107,3 @@ index 157593d080c5..65efae0cf087 100644 /* * Prepare a CPU for idle from an RCU perspective. The first major task --- -2.19.2 - diff --git a/kernel/patches-4.14.x-rt/0378-rcu-Eliminate-softirq-processing-from-rcutree.patch b/kernel/patches-4.19.x-rt/0163-rcu-Eliminate-softirq-processing-from-rcutree.patch similarity index 82% rename from kernel/patches-4.14.x-rt/0378-rcu-Eliminate-softirq-processing-from-rcutree.patch rename to kernel/patches-4.19.x-rt/0163-rcu-Eliminate-softirq-processing-from-rcutree.patch index 6d26c4d55..68d378818 100644 --- a/kernel/patches-4.14.x-rt/0378-rcu-Eliminate-softirq-processing-from-rcutree.patch +++ b/kernel/patches-4.19.x-rt/0163-rcu-Eliminate-softirq-processing-from-rcutree.patch @@ -1,7 +1,6 @@ -From e8988263ff2200f395d64cd7155fbd509a10c203 Mon Sep 17 00:00:00 2001 From: "Paul E. McKenney" Date: Mon, 4 Nov 2013 13:21:10 -0800 -Subject: [PATCH 378/450] rcu: Eliminate softirq processing from rcutree +Subject: rcu: Eliminate softirq processing from rcutree Running RCU out of softirq is a problem for some workloads that would like to manage RCU core processing independently of other softirq work, @@ -17,16 +16,14 @@ Tested-by: Mike Galbraith Signed-off-by: Paul E. McKenney Signed-off-by: Sebastian Andrzej Siewior --- - kernel/rcu/tree.c | 112 ++++++++++++++++++++++++++--- - kernel/rcu/tree.h | 5 +- - kernel/rcu/tree_plugin.h | 152 ++++----------------------------------- - 3 files changed, 115 insertions(+), 154 deletions(-) + kernel/rcu/tree.c | 112 +++++++++++++++++++++++++++++++++---- + kernel/rcu/tree.h | 4 - + kernel/rcu/tree_plugin.h | 142 +++-------------------------------------------- + 3 files changed, 114 insertions(+), 144 deletions(-) -diff --git a/kernel/rcu/tree.c b/kernel/rcu/tree.c -index 9eb9cfc9c9c1..06bd35fe8f9c 100644 --- a/kernel/rcu/tree.c +++ b/kernel/rcu/tree.c -@@ -58,6 +58,11 @@ +@@ -61,6 +61,13 @@ #include #include #include @@ -34,11 +31,13 @@ index 9eb9cfc9c9c1..06bd35fe8f9c 100644 +#include +#include +#include ++#include ++#include +#include "../time/tick-internal.h" #include "tree.h" #include "rcu.h" -@@ -2955,18 +2960,17 @@ __rcu_process_callbacks(struct rcu_state *rsp) +@@ -2888,18 +2895,17 @@ static void /* * Do RCU core processing for the current CPU. */ @@ -59,15 +58,12 @@ index 9eb9cfc9c9c1..06bd35fe8f9c 100644 /* * Schedule RCU callback invocation. If the specified type of RCU * does not support RCU priority boosting, just do a direct call, -@@ -2978,18 +2982,105 @@ static void invoke_rcu_callbacks(struct rcu_state *rsp, struct rcu_data *rdp) +@@ -2911,18 +2917,105 @@ static void invoke_rcu_callbacks(struct { if (unlikely(!READ_ONCE(rcu_scheduler_fully_active))) return; - if (likely(!rsp->boost)) { - rcu_do_batch(rsp, rdp); -- return; -- } -- invoke_rcu_callbacks_kthread(); + rcu_do_batch(rsp, rdp); +} + @@ -79,20 +75,18 @@ index 9eb9cfc9c9c1..06bd35fe8f9c 100644 + */ + if (t && (status != RCU_KTHREAD_YIELDING || is_idle_task(current))) + wake_up_process(t); - } - ++} ++ +/* + * Wake up this CPU's rcuc kthread to do RCU core processing. + */ - static void invoke_rcu_core(void) - { -- if (cpu_online(smp_processor_id())) -- raise_softirq(RCU_SOFTIRQ); ++static void invoke_rcu_core(void) ++{ + unsigned long flags; + struct task_struct *t; + + if (!cpu_online(smp_processor_id())) -+ return; + return; + local_irq_save(flags); + __this_cpu_write(rcu_cpu_has_work, 1); + t = __this_cpu_read(rcu_cpu_kthread_task); @@ -139,14 +133,16 @@ index 9eb9cfc9c9c1..06bd35fe8f9c 100644 + *statusp = RCU_KTHREAD_WAITING; + return; + } -+ } + } +- invoke_rcu_callbacks_kthread(); + *statusp = RCU_KTHREAD_YIELDING; + trace_rcu_utilization(TPS("Start CPU kthread@rcu_yield")); + schedule_timeout_interruptible(2); + trace_rcu_utilization(TPS("End CPU kthread@rcu_yield")); + *statusp = RCU_KTHREAD_WAITING; -+} -+ + } + +-static void invoke_rcu_core(void) +static struct smp_hotplug_thread rcu_cpu_thread_spec = { + .store = &rcu_cpu_kthread_task, + .thread_should_run = rcu_cpu_kthread_should_run, @@ -160,7 +156,9 @@ index 9eb9cfc9c9c1..06bd35fe8f9c 100644 + * Spawn per-CPU RCU core processing kthreads. + */ +static int __init rcu_spawn_core_kthreads(void) -+{ + { +- if (cpu_online(smp_processor_id())) +- raise_softirq(RCU_SOFTIRQ); + int cpu; + + for_each_possible_cpu(cpu) @@ -172,7 +170,7 @@ index 9eb9cfc9c9c1..06bd35fe8f9c 100644 /* * Handle any core-RCU processing required by a call_rcu() invocation. -@@ -4230,7 +4321,6 @@ void __init rcu_init(void) +@@ -4188,7 +4281,6 @@ void __init rcu_init(void) if (dump_tree) rcu_dump_rcu_node_tree(&rcu_sched_state); __rcu_init_preempt(); @@ -180,13 +178,11 @@ index 9eb9cfc9c9c1..06bd35fe8f9c 100644 /* * We don't need protection against CPU-hotplug here because -diff --git a/kernel/rcu/tree.h b/kernel/rcu/tree.h -index ac4296f85278..7acc23da94e2 100644 --- a/kernel/rcu/tree.h +++ b/kernel/rcu/tree.h -@@ -438,12 +438,10 @@ extern struct rcu_state rcu_preempt_state; +@@ -423,12 +423,10 @@ extern struct rcu_state rcu_preempt_stat + int rcu_dynticks_snap(struct rcu_dynticks *rdtp); - bool rcu_eqs_special_set(int cpu); -#ifdef CONFIG_RCU_BOOST DECLARE_PER_CPU(unsigned int, rcu_cpu_kthread_status); @@ -197,23 +193,19 @@ index ac4296f85278..7acc23da94e2 100644 #ifndef RCU_TREE_NONCORE -@@ -463,10 +461,9 @@ void call_rcu(struct rcu_head *head, rcu_callback_t func); - static void __init __rcu_init_preempt(void); +@@ -451,8 +449,8 @@ static void dump_blkd_tasks(struct rcu_s + int ncheck); static void rcu_initiate_boost(struct rcu_node *rnp, unsigned long flags); static void rcu_preempt_boost_start_gp(struct rcu_node *rnp); -static void invoke_rcu_callbacks_kthread(void); static bool rcu_is_callbacks_kthread(void); +static void rcu_cpu_kthread_setup(unsigned int cpu); #ifdef CONFIG_RCU_BOOST --static void rcu_preempt_do_callbacks(void); static int rcu_spawn_one_boost_kthread(struct rcu_state *rsp, struct rcu_node *rnp); - #endif /* #ifdef CONFIG_RCU_BOOST */ -diff --git a/kernel/rcu/tree_plugin.h b/kernel/rcu/tree_plugin.h -index 09c739703533..17ee8d1f38c4 100644 --- a/kernel/rcu/tree_plugin.h +++ b/kernel/rcu/tree_plugin.h -@@ -24,39 +24,16 @@ +@@ -24,42 +24,16 @@ * Paul E. McKenney */ @@ -223,12 +215,14 @@ index 09c739703533..17ee8d1f38c4 100644 -#include -#include -#include +-#include -#include -#include "../time/tick-internal.h" - #include "../locking/rtmutex_common.h" - +- -#ifdef CONFIG_RCU_BOOST - + #include "../locking/rtmutex_common.h" + /* * Control variables for per-CPU and per-rcu_node kthreads. These * handle all flavors of RCU. @@ -247,29 +241,14 @@ index 09c739703533..17ee8d1f38c4 100644 - * This probably needs to be excluded from -rt builds. - */ -#define rt_mutex_owner(a) ({ WARN_ON_ONCE(1); NULL; }) +-#define rt_mutex_futex_unlock(x) WARN_ON_ONCE(1) - -#endif /* #else #ifdef CONFIG_RCU_BOOST */ - #ifdef CONFIG_RCU_NOCB_CPU static cpumask_var_t rcu_nocb_mask; /* CPUs to have callbacks offloaded. */ - static bool have_rcu_nocb_mask; /* Was rcu_nocb_mask allocated? */ -@@ -688,15 +665,6 @@ static void rcu_preempt_check_callbacks(void) - t->rcu_read_unlock_special.b.need_qs = true; - } - --#ifdef CONFIG_RCU_BOOST -- --static void rcu_preempt_do_callbacks(void) --{ -- rcu_do_batch(rcu_state_p, this_cpu_ptr(rcu_data_p)); --} -- --#endif /* #ifdef CONFIG_RCU_BOOST */ -- - /** - * call_rcu() - Queue an RCU callback for invocation after a grace period. - * @head: structure to be used for queueing the RCU updates. -@@ -919,20 +887,23 @@ void exit_rcu(void) + static bool __read_mostly rcu_nocb_poll; /* Offload kthread are to poll. */ +@@ -1027,18 +1001,21 @@ dump_blkd_tasks(struct rcu_state *rsp, s #endif /* #else #ifdef CONFIG_PREEMPT_RCU */ @@ -278,17 +257,8 @@ index 09c739703533..17ee8d1f38c4 100644 + */ +static void rcu_cpu_kthread_setup(unsigned int cpu) +{ -+#ifdef CONFIG_RCU_BOOST -+ struct sched_param sp; -+ -+ sp.sched_priority = kthread_prio; -+ sched_setscheduler_nocheck(current, SCHED_FIFO, &sp); -+#endif /* #ifdef CONFIG_RCU_BOOST */ -+} -+ #ifdef CONFIG_RCU_BOOST - - #include "../locking/rtmutex_common.h" ++ struct sched_param sp; -static void rcu_wake_cond(struct task_struct *t, int status) -{ @@ -298,16 +268,20 @@ index 09c739703533..17ee8d1f38c4 100644 - */ - if (status != RCU_KTHREAD_YIELDING || is_idle_task(current)) - wake_up_process(t); --} -- ++ sp.sched_priority = kthread_prio; ++ sched_setscheduler_nocheck(current, SCHED_FIFO, &sp); ++#endif /* #ifdef CONFIG_RCU_BOOST */ + } + ++#ifdef CONFIG_RCU_BOOST ++ /* * Carry out RCU priority boosting on the task indicated by ->exp_tasks * or ->boost_tasks, advancing the pointer to the next task in the -@@ -1074,23 +1045,6 @@ static void rcu_initiate_boost(struct rcu_node *rnp, unsigned long flags) - } +@@ -1177,23 +1154,6 @@ static void rcu_initiate_boost(struct rc } --/* + /* - * Wake up the per-CPU kthread to invoke RCU callbacks. - */ -static void invoke_rcu_callbacks_kthread(void) @@ -324,10 +298,11 @@ index 09c739703533..17ee8d1f38c4 100644 - local_irq_restore(flags); -} - - /* +-/* * Is the current CPU running the RCU-callbacks kthread? * Caller must have preemption disabled. -@@ -1145,67 +1099,6 @@ static int rcu_spawn_one_boost_kthread(struct rcu_state *rsp, + */ +@@ -1247,67 +1207,6 @@ static int rcu_spawn_one_boost_kthread(s return 0; } @@ -335,7 +310,7 @@ index 09c739703533..17ee8d1f38c4 100644 -{ - rcu_do_batch(&rcu_sched_state, this_cpu_ptr(&rcu_sched_data)); - rcu_do_batch(&rcu_bh_state, this_cpu_ptr(&rcu_bh_data)); -- rcu_preempt_do_callbacks(); +- rcu_do_batch(&rcu_preempt_state, this_cpu_ptr(&rcu_preempt_data)); -} - -static void rcu_cpu_kthread_setup(unsigned int cpu) @@ -395,7 +370,7 @@ index 09c739703533..17ee8d1f38c4 100644 /* * Set the per-rcu_node kthread's affinity to cover all CPUs that are * served by the rcu_node in question. The CPU hotplug lock is still -@@ -1236,26 +1129,12 @@ static void rcu_boost_kthread_setaffinity(struct rcu_node *rnp, int outgoingcpu) +@@ -1338,26 +1237,12 @@ static void rcu_boost_kthread_setaffinit free_cpumask_var(cm); } @@ -422,7 +397,7 @@ index 09c739703533..17ee8d1f38c4 100644 rcu_for_each_leaf_node(rcu_state_p, rnp) (void)rcu_spawn_one_boost_kthread(rcu_state_p, rnp); } -@@ -1278,11 +1157,6 @@ static void rcu_initiate_boost(struct rcu_node *rnp, unsigned long flags) +@@ -1380,11 +1265,6 @@ static void rcu_initiate_boost(struct rc raw_spin_unlock_irqrestore_rcu_node(rnp, flags); } @@ -434,6 +409,3 @@ index 09c739703533..17ee8d1f38c4 100644 static bool rcu_is_callbacks_kthread(void) { return false; --- -2.19.2 - diff --git a/kernel/patches-4.14.x-rt/0374-srcu-use-cpu_online-instead-custom-check.patch b/kernel/patches-4.19.x-rt/0164-srcu-use-cpu_online-instead-custom-check.patch similarity index 60% rename from kernel/patches-4.14.x-rt/0374-srcu-use-cpu_online-instead-custom-check.patch rename to kernel/patches-4.19.x-rt/0164-srcu-use-cpu_online-instead-custom-check.patch index 3ba858a92..7528bdafa 100644 --- a/kernel/patches-4.14.x-rt/0374-srcu-use-cpu_online-instead-custom-check.patch +++ b/kernel/patches-4.19.x-rt/0164-srcu-use-cpu_online-instead-custom-check.patch @@ -1,7 +1,6 @@ -From caaa4d10322908e9a347914745e83e2a55078869 Mon Sep 17 00:00:00 2001 From: Sebastian Andrzej Siewior Date: Wed, 13 Sep 2017 14:43:41 +0200 -Subject: [PATCH 374/450] srcu: use cpu_online() instead custom check +Subject: [PATCH] srcu: use cpu_online() instead custom check The current check via srcu_online is slightly racy because after looking at srcu_online there could be an interrupt that interrupted us long @@ -12,20 +11,15 @@ on a specific CPU or not. queue_work_on() itself can handle if something is enqueued on an offline CPU but a timer which is enqueued on an offline CPU won't fire until the CPU is back online. -I am not sure if the removal in rcu_init() is okay or not. I assume that -SRCU won't enqueue a work item before SRCU is up and ready. - Signed-off-by: Sebastian Andrzej Siewior --- - kernel/rcu/srcutree.c | 22 ++++------------------ - kernel/rcu/tree.c | 6 ------ - 2 files changed, 4 insertions(+), 24 deletions(-) + kernel/rcu/srcutree.c | 22 ++++------------------ + kernel/rcu/tree.c | 4 ---- + 2 files changed, 4 insertions(+), 22 deletions(-) -diff --git a/kernel/rcu/srcutree.c b/kernel/rcu/srcutree.c -index 6d5880089ff6..b72d8c552604 100644 --- a/kernel/rcu/srcutree.c +++ b/kernel/rcu/srcutree.c -@@ -36,6 +36,7 @@ +@@ -38,6 +38,7 @@ #include #include #include @@ -33,11 +27,10 @@ index 6d5880089ff6..b72d8c552604 100644 #include "rcu.h" #include "rcu_segcblist.h" -@@ -424,21 +425,6 @@ static void srcu_gp_start(struct srcu_struct *sp) - WARN_ON_ONCE(state != SRCU_STATE_SCAN1); +@@ -461,21 +462,6 @@ static void srcu_gp_start(struct srcu_st } --/* + /* - * Track online CPUs to guide callback workqueue placement. - */ -DEFINE_PER_CPU(bool, srcu_online); @@ -52,10 +45,11 @@ index 6d5880089ff6..b72d8c552604 100644 - WRITE_ONCE(per_cpu(srcu_online, cpu), false); -} - - /* +-/* * Place the workqueue handler on the specified CPU if online, otherwise * just run it whereever. This is useful for placing workqueue handlers -@@ -450,12 +436,12 @@ static bool srcu_queue_delayed_work_on(int cpu, struct workqueue_struct *wq, + * that are to invoke the specified CPU's callbacks. +@@ -486,12 +472,12 @@ static bool srcu_queue_delayed_work_on(i { bool ret; @@ -71,37 +65,23 @@ index 6d5880089ff6..b72d8c552604 100644 return ret; } -diff --git a/kernel/rcu/tree.c b/kernel/rcu/tree.c -index f37d06ec5ee1..9eb9cfc9c9c1 100644 --- a/kernel/rcu/tree.c +++ b/kernel/rcu/tree.c -@@ -3784,8 +3784,6 @@ int rcutree_online_cpu(unsigned int cpu) - { - sync_sched_exp_online_cleanup(cpu); - rcutree_affinity_setting(cpu, -1); +@@ -3776,8 +3776,6 @@ int rcutree_online_cpu(unsigned int cpu) + rnp->ffmask |= rdp->grpmask; + raw_spin_unlock_irqrestore_rcu_node(rnp, flags); + } - if (IS_ENABLED(CONFIG_TREE_SRCU)) - srcu_online_cpu(cpu); - return 0; - } + if (rcu_scheduler_active == RCU_SCHEDULER_INACTIVE) + return 0; /* Too early in boot for scheduler work. */ + sync_sched_exp_online_cleanup(cpu); +@@ -3805,8 +3803,6 @@ int rcutree_offline_cpu(unsigned int cpu + } -@@ -3796,8 +3794,6 @@ int rcutree_online_cpu(unsigned int cpu) - int rcutree_offline_cpu(unsigned int cpu) - { rcutree_affinity_setting(cpu, cpu); - if (IS_ENABLED(CONFIG_TREE_SRCU)) - srcu_offline_cpu(cpu); return 0; } -@@ -4245,8 +4241,6 @@ void __init rcu_init(void) - for_each_online_cpu(cpu) { - rcutree_prepare_cpu(cpu); - rcu_cpu_starting(cpu); -- if (IS_ENABLED(CONFIG_TREE_SRCU)) -- srcu_online_cpu(cpu); - } - } - --- -2.19.2 - diff --git a/kernel/patches-4.14.x-rt/0376-srcu-replace-local_irqsave-with-a-locallock.patch b/kernel/patches-4.19.x-rt/0165-srcu-replace-local_irqsave-with-a-locallock.patch similarity index 75% rename from kernel/patches-4.14.x-rt/0376-srcu-replace-local_irqsave-with-a-locallock.patch rename to kernel/patches-4.19.x-rt/0165-srcu-replace-local_irqsave-with-a-locallock.patch index 4af189925..2e65e8a57 100644 --- a/kernel/patches-4.14.x-rt/0376-srcu-replace-local_irqsave-with-a-locallock.patch +++ b/kernel/patches-4.19.x-rt/0165-srcu-replace-local_irqsave-with-a-locallock.patch @@ -1,7 +1,6 @@ -From 9187b49972fb5e3dd39648dbe291367f4c6301ec Mon Sep 17 00:00:00 2001 From: Sebastian Andrzej Siewior Date: Thu, 12 Oct 2017 18:37:12 +0200 -Subject: [PATCH 376/450] srcu: replace local_irqsave() with a locallock +Subject: [PATCH] srcu: replace local_irqsave() with a locallock There are two instances which disable interrupts in order to become a stable this_cpu_ptr() pointer. The restore part is coupled with @@ -11,14 +10,12 @@ version of it. Signed-off-by: Sebastian Andrzej Siewior --- - kernel/rcu/srcutree.c | 14 +++++++++----- + kernel/rcu/srcutree.c | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) -diff --git a/kernel/rcu/srcutree.c b/kernel/rcu/srcutree.c -index c9d1f0e5f899..0e3b2bd3f2ac 100644 --- a/kernel/rcu/srcutree.c +++ b/kernel/rcu/srcutree.c -@@ -37,6 +37,7 @@ +@@ -39,6 +39,7 @@ #include #include #include @@ -26,7 +23,7 @@ index c9d1f0e5f899..0e3b2bd3f2ac 100644 #include "rcu.h" #include "rcu_segcblist.h" -@@ -749,6 +750,8 @@ static void srcu_flip(struct srcu_struct *sp) +@@ -760,6 +761,8 @@ static void srcu_flip(struct srcu_struct * negligible when amoritized over that time period, and the extra latency * of a needlessly non-expedited grace period is similarly negligible. */ @@ -35,7 +32,7 @@ index c9d1f0e5f899..0e3b2bd3f2ac 100644 static bool srcu_might_be_idle(struct srcu_struct *sp) { unsigned long curseq; -@@ -757,13 +760,13 @@ static bool srcu_might_be_idle(struct srcu_struct *sp) +@@ -768,13 +771,13 @@ static bool srcu_might_be_idle(struct sr unsigned long t; /* If the local srcu_data structure has callbacks, not idle. */ @@ -52,7 +49,7 @@ index c9d1f0e5f899..0e3b2bd3f2ac 100644 /* * No local callbacks, so probabalistically probe global state. -@@ -841,7 +844,7 @@ void __call_srcu(struct srcu_struct *sp, struct rcu_head *rhp, +@@ -852,7 +855,7 @@ void __call_srcu(struct srcu_struct *sp, return; } rhp->func = func; @@ -61,7 +58,7 @@ index c9d1f0e5f899..0e3b2bd3f2ac 100644 sdp = this_cpu_ptr(sp->sda); spin_lock_rcu_node(sdp); rcu_segcblist_enqueue(&sdp->srcu_cblist, rhp, false); -@@ -857,7 +860,8 @@ void __call_srcu(struct srcu_struct *sp, struct rcu_head *rhp, +@@ -868,7 +871,8 @@ void __call_srcu(struct srcu_struct *sp, sdp->srcu_gp_seq_needed_exp = s; needexp = true; } @@ -71,6 +68,3 @@ index c9d1f0e5f899..0e3b2bd3f2ac 100644 if (needgp) srcu_funnel_gp_start(sp, sdp, s, do_norm); else if (needexp) --- -2.19.2 - diff --git a/kernel/patches-4.14.x-rt/0380-rcu-enable-rcu_normal_after_boot-by-default-for-RT.patch b/kernel/patches-4.19.x-rt/0166-rcu-enable-rcu_normal_after_boot-by-default-for-RT.patch similarity index 74% rename from kernel/patches-4.14.x-rt/0380-rcu-enable-rcu_normal_after_boot-by-default-for-RT.patch rename to kernel/patches-4.19.x-rt/0166-rcu-enable-rcu_normal_after_boot-by-default-for-RT.patch index 557f61f8c..962fe570d 100644 --- a/kernel/patches-4.14.x-rt/0380-rcu-enable-rcu_normal_after_boot-by-default-for-RT.patch +++ b/kernel/patches-4.19.x-rt/0166-rcu-enable-rcu_normal_after_boot-by-default-for-RT.patch @@ -1,7 +1,6 @@ -From 9ceb8105da087da29f94ffe4403cc2010158c4d5 Mon Sep 17 00:00:00 2001 From: Julia Cartwright Date: Wed, 12 Oct 2016 11:21:14 -0500 -Subject: [PATCH 380/450] rcu: enable rcu_normal_after_boot by default for RT +Subject: [PATCH] rcu: enable rcu_normal_after_boot by default for RT The forcing of an expedited grace period is an expensive and very RT-application unfriendly operation, as it forcibly preempts all running @@ -11,17 +10,16 @@ By default, as a policy decision, disable the expediting of grace periods (after boot) on configurations which enable PREEMPT_RT_FULL. Suggested-by: Luiz Capitulino +Acked-by: Paul E. McKenney Signed-off-by: Julia Cartwright Signed-off-by: Sebastian Andrzej Siewior --- - kernel/rcu/update.c | 2 +- + kernel/rcu/update.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) -diff --git a/kernel/rcu/update.c b/kernel/rcu/update.c -index c63c88a0de7e..2006a09680aa 100644 --- a/kernel/rcu/update.c +++ b/kernel/rcu/update.c -@@ -66,7 +66,7 @@ extern int rcu_expedited; /* from sysctl */ +@@ -67,7 +67,7 @@ extern int rcu_expedited; /* from sysctl module_param(rcu_expedited, int, 0); extern int rcu_normal; /* from sysctl */ module_param(rcu_normal, int, 0); @@ -30,6 +28,3 @@ index c63c88a0de7e..2006a09680aa 100644 module_param(rcu_normal_after_boot, int, 0); #endif /* #ifndef CONFIG_TINY_RCU */ --- -2.19.2 - diff --git a/kernel/patches-4.14.x-rt/0270-tty-serial-omap-Make-the-locking-RT-aware.patch b/kernel/patches-4.19.x-rt/0167-drivers-tty-fix-omap-lock-crap.patch similarity index 67% rename from kernel/patches-4.14.x-rt/0270-tty-serial-omap-Make-the-locking-RT-aware.patch rename to kernel/patches-4.19.x-rt/0167-drivers-tty-fix-omap-lock-crap.patch index f01261be0..f70e9198d 100644 --- a/kernel/patches-4.14.x-rt/0270-tty-serial-omap-Make-the-locking-RT-aware.patch +++ b/kernel/patches-4.19.x-rt/0167-drivers-tty-fix-omap-lock-crap.patch @@ -1,7 +1,6 @@ -From af1af66664f2b89686a49fdb5dc2d8cbc5022681 Mon Sep 17 00:00:00 2001 +Subject: tty/serial/omap: Make the locking RT aware From: Thomas Gleixner Date: Thu, 28 Jul 2011 13:32:57 +0200 -Subject: [PATCH 270/450] tty/serial/omap: Make the locking RT aware The lock is a sleeping lock and local_irq_save() is not the optimsation we are looking for. Redo it to make it work on -RT and @@ -9,14 +8,12 @@ non-RT. Signed-off-by: Thomas Gleixner --- - drivers/tty/serial/omap-serial.c | 12 ++++-------- + drivers/tty/serial/omap-serial.c | 12 ++++-------- 1 file changed, 4 insertions(+), 8 deletions(-) -diff --git a/drivers/tty/serial/omap-serial.c b/drivers/tty/serial/omap-serial.c -index 26a22b100df1..69117e355bcd 100644 --- a/drivers/tty/serial/omap-serial.c +++ b/drivers/tty/serial/omap-serial.c -@@ -1311,13 +1311,10 @@ serial_omap_console_write(struct console *co, const char *s, +@@ -1307,13 +1307,10 @@ serial_omap_console_write(struct console pm_runtime_get_sync(up->dev); @@ -33,7 +30,7 @@ index 26a22b100df1..69117e355bcd 100644 /* * First save the IER then disable the interrupts -@@ -1346,8 +1343,7 @@ serial_omap_console_write(struct console *co, const char *s, +@@ -1342,8 +1339,7 @@ serial_omap_console_write(struct console pm_runtime_mark_last_busy(up->dev); pm_runtime_put_autosuspend(up->dev); if (locked) @@ -43,6 +40,3 @@ index 26a22b100df1..69117e355bcd 100644 } static int __init --- -2.19.2 - diff --git a/kernel/patches-4.14.x-rt/0271-tty-serial-pl011-Make-the-locking-work-on-RT.patch b/kernel/patches-4.19.x-rt/0168-drivers-tty-pl011-irq-disable-madness.patch similarity index 67% rename from kernel/patches-4.14.x-rt/0271-tty-serial-pl011-Make-the-locking-work-on-RT.patch rename to kernel/patches-4.19.x-rt/0168-drivers-tty-pl011-irq-disable-madness.patch index 8b4ef9010..1558a8766 100644 --- a/kernel/patches-4.14.x-rt/0271-tty-serial-pl011-Make-the-locking-work-on-RT.patch +++ b/kernel/patches-4.19.x-rt/0168-drivers-tty-pl011-irq-disable-madness.patch @@ -1,21 +1,18 @@ -From b3ec94145219700a0db30e5ac54e5eaa53911c93 Mon Sep 17 00:00:00 2001 +Subject: tty/serial/pl011: Make the locking work on RT From: Thomas Gleixner -Date: Tue, 8 Jan 2013 21:36:51 +0100 -Subject: [PATCH 271/450] tty/serial/pl011: Make the locking work on RT +Date: Tue, 08 Jan 2013 21:36:51 +0100 The lock is a sleeping lock and local_irq_save() is not the optimsation we are looking for. Redo it to make it work on -RT and non-RT. Signed-off-by: Thomas Gleixner --- - drivers/tty/serial/amba-pl011.c | 15 ++++++++++----- + drivers/tty/serial/amba-pl011.c | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) -diff --git a/drivers/tty/serial/amba-pl011.c b/drivers/tty/serial/amba-pl011.c -index c9f701aca677..81d6b15fb80a 100644 --- a/drivers/tty/serial/amba-pl011.c +++ b/drivers/tty/serial/amba-pl011.c -@@ -2236,13 +2236,19 @@ pl011_console_write(struct console *co, const char *s, unsigned int count) +@@ -2216,13 +2216,19 @@ pl011_console_write(struct console *co, clk_enable(uap->clk); @@ -38,7 +35,7 @@ index c9f701aca677..81d6b15fb80a 100644 /* * First save the CR then disable the interrupts -@@ -2268,8 +2274,7 @@ pl011_console_write(struct console *co, const char *s, unsigned int count) +@@ -2248,8 +2254,7 @@ pl011_console_write(struct console *co, pl011_write(old_cr, uap, REG_CR); if (locked) @@ -48,6 +45,3 @@ index c9f701aca677..81d6b15fb80a 100644 clk_disable(uap->clk); } --- -2.19.2 - diff --git a/kernel/patches-4.14.x-rt/0440-tty-serial-pl011-explicitly-initialize-the-flags-var.patch b/kernel/patches-4.19.x-rt/0169-tty-serial-pl011-warning-about-uninitialized.patch similarity index 67% rename from kernel/patches-4.14.x-rt/0440-tty-serial-pl011-explicitly-initialize-the-flags-var.patch rename to kernel/patches-4.19.x-rt/0169-tty-serial-pl011-warning-about-uninitialized.patch index e7ebf373a..76f39fd86 100644 --- a/kernel/patches-4.14.x-rt/0440-tty-serial-pl011-explicitly-initialize-the-flags-var.patch +++ b/kernel/patches-4.19.x-rt/0169-tty-serial-pl011-warning-about-uninitialized.patch @@ -1,14 +1,10 @@ -From 4bdd62f77e1bd7dbe4ee749e301cb9c3eafd62b1 Mon Sep 17 00:00:00 2001 From: Kurt Kanzenbach Date: Mon, 24 Sep 2018 10:29:01 +0200 -Subject: [PATCH 440/450] tty: serial: pl011: explicitly initialize the flags - variable +Subject: [PATCH] tty: serial: pl011: explicitly initialize the flags variable MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit -[ Upstream commit 3260983a587d528811a15fc00fa2a9e4473c4453 ] - Silence the following gcc warning: drivers/tty/serial/amba-pl011.c: In function ‘pl011_console_write’: @@ -24,16 +20,13 @@ behavior and resolves the warning. Signed-off-by: Kurt Kanzenbach Signed-off-by: Sebastian Andrzej Siewior -Signed-off-by: Steven Rostedt (VMware) --- - drivers/tty/serial/amba-pl011.c | 2 +- + drivers/tty/serial/amba-pl011.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) -diff --git a/drivers/tty/serial/amba-pl011.c b/drivers/tty/serial/amba-pl011.c -index 81d6b15fb80a..9379db8aec9a 100644 --- a/drivers/tty/serial/amba-pl011.c +++ b/drivers/tty/serial/amba-pl011.c -@@ -2231,7 +2231,7 @@ pl011_console_write(struct console *co, const char *s, unsigned int count) +@@ -2211,7 +2211,7 @@ pl011_console_write(struct console *co, { struct uart_amba_port *uap = amba_ports[co->index]; unsigned int old_cr = 0, new_cr; @@ -42,6 +35,3 @@ index 81d6b15fb80a..9379db8aec9a 100644 int locked = 1; clk_enable(uap->clk); --- -2.19.2 - diff --git a/kernel/patches-4.14.x-rt/0272-rt-Improve-the-serial-console-PASS_LIMIT.patch b/kernel/patches-4.19.x-rt/0170-rt-serial-warn-fix.patch similarity index 63% rename from kernel/patches-4.14.x-rt/0272-rt-Improve-the-serial-console-PASS_LIMIT.patch rename to kernel/patches-4.19.x-rt/0170-rt-serial-warn-fix.patch index e8c661e02..9119b686b 100644 --- a/kernel/patches-4.14.x-rt/0272-rt-Improve-the-serial-console-PASS_LIMIT.patch +++ b/kernel/patches-4.19.x-rt/0170-rt-serial-warn-fix.patch @@ -1,10 +1,6 @@ -From d6558a1e2a9ef9404d0612e3e266b7e173f28c2d Mon Sep 17 00:00:00 2001 +Subject: rt: Improve the serial console PASS_LIMIT From: Ingo Molnar -Date: Wed, 14 Dec 2011 13:05:54 +0100 -Subject: [PATCH 272/450] rt: Improve the serial console PASS_LIMIT -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit +Date: Wed Dec 14 13:05:54 CET 2011 Beyond the warning: @@ -16,14 +12,12 @@ give it a chance to continue in some really ugly situation. Signed-off-by: Ingo Molnar Signed-off-by: Thomas Gleixner --- - drivers/tty/serial/8250/8250_core.c | 11 ++++++++++- + drivers/tty/serial/8250/8250_core.c | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) -diff --git a/drivers/tty/serial/8250/8250_core.c b/drivers/tty/serial/8250/8250_core.c -index d29b512a7d9f..bc8cbb995b29 100644 --- a/drivers/tty/serial/8250/8250_core.c +++ b/drivers/tty/serial/8250/8250_core.c -@@ -58,7 +58,16 @@ static struct uart_driver serial8250_reg; +@@ -54,7 +54,16 @@ static struct uart_driver serial8250_reg static unsigned int skip_txen_test; /* force skip of txen test at init time */ @@ -41,6 +35,3 @@ index d29b512a7d9f..bc8cbb995b29 100644 #include /* --- -2.19.2 - diff --git a/kernel/patches-4.14.x-rt/0273-tty-serial-8250-don-t-take-the-trylock-during-oops.patch b/kernel/patches-4.19.x-rt/0171-tty-serial-8250-don-t-take-the-trylock-during-oops.patch similarity index 63% rename from kernel/patches-4.14.x-rt/0273-tty-serial-8250-don-t-take-the-trylock-during-oops.patch rename to kernel/patches-4.19.x-rt/0171-tty-serial-8250-don-t-take-the-trylock-during-oops.patch index 195c8cb64..f883ac294 100644 --- a/kernel/patches-4.14.x-rt/0273-tty-serial-8250-don-t-take-the-trylock-during-oops.patch +++ b/kernel/patches-4.19.x-rt/0171-tty-serial-8250-don-t-take-the-trylock-during-oops.patch @@ -1,7 +1,6 @@ -From 886def17e5e3d5ef96f1179e1ea15be0e89d80b0 Mon Sep 17 00:00:00 2001 From: Sebastian Andrzej Siewior Date: Mon, 11 Apr 2016 16:55:02 +0200 -Subject: [PATCH 273/450] tty: serial: 8250: don't take the trylock during oops +Subject: [PATCH] tty: serial: 8250: don't take the trylock during oops An oops with irqs off (panic() from irqsafe hrtimer like the watchdog timer) will lead to a lockdep warning on each invocation and as such @@ -10,14 +9,12 @@ Therefore we skip the trylock in the oops case. Signed-off-by: Sebastian Andrzej Siewior --- - drivers/tty/serial/8250/8250_port.c | 4 +--- + drivers/tty/serial/8250/8250_port.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) -diff --git a/drivers/tty/serial/8250/8250_port.c b/drivers/tty/serial/8250/8250_port.c -index ecf3d631bc09..c331434ce443 100644 --- a/drivers/tty/serial/8250/8250_port.c +++ b/drivers/tty/serial/8250/8250_port.c -@@ -3224,10 +3224,8 @@ void serial8250_console_write(struct uart_8250_port *up, const char *s, +@@ -3239,10 +3239,8 @@ void serial8250_console_write(struct uar serial8250_rpm_get(up); @@ -29,6 +26,3 @@ index ecf3d631bc09..c331434ce443 100644 else spin_lock_irqsave(&port->lock, flags); --- -2.19.2 - diff --git a/kernel/patches-4.14.x-rt/0274-locking-percpu-rwsem-Remove-preempt_disable-variants.patch b/kernel/patches-4.19.x-rt/0172-peterz-percpu-rwsem-rt.patch similarity index 72% rename from kernel/patches-4.14.x-rt/0274-locking-percpu-rwsem-Remove-preempt_disable-variants.patch rename to kernel/patches-4.19.x-rt/0172-peterz-percpu-rwsem-rt.patch index 7bc185bee..4b832db88 100644 --- a/kernel/patches-4.14.x-rt/0274-locking-percpu-rwsem-Remove-preempt_disable-variants.patch +++ b/kernel/patches-4.19.x-rt/0172-peterz-percpu-rwsem-rt.patch @@ -1,7 +1,6 @@ -From efbadaf7db20d954980f8a2382f23d24bc71d34b Mon Sep 17 00:00:00 2001 +Subject: locking/percpu-rwsem: Remove preempt_disable variants From: Peter Zijlstra -Date: Wed, 23 Nov 2016 16:29:32 +0100 -Subject: [PATCH 274/450] locking/percpu-rwsem: Remove preempt_disable variants +Date: Wed Nov 23 16:29:32 CET 2016 Effective revert commit: @@ -12,15 +11,14 @@ performance issue for PREEMPT=y. Signed-off-by: Peter Zijlstra (Intel) --- - fs/locks.c | 32 ++++++++++++++++---------------- - include/linux/percpu-rwsem.h | 24 ++++-------------------- +--- + fs/locks.c | 32 ++++++++++++++++---------------- + include/linux/percpu-rwsem.h | 24 ++++-------------------- 2 files changed, 20 insertions(+), 36 deletions(-) -diff --git a/fs/locks.c b/fs/locks.c -index 665e3ce9ab47..47b66bfc4fa3 100644 --- a/fs/locks.c +++ b/fs/locks.c -@@ -945,7 +945,7 @@ static int flock_lock_inode(struct inode *inode, struct file_lock *request) +@@ -936,7 +936,7 @@ static int flock_lock_inode(struct inode return -ENOMEM; } @@ -29,7 +27,7 @@ index 665e3ce9ab47..47b66bfc4fa3 100644 spin_lock(&ctx->flc_lock); if (request->fl_flags & FL_ACCESS) goto find_conflict; -@@ -986,7 +986,7 @@ static int flock_lock_inode(struct inode *inode, struct file_lock *request) +@@ -977,7 +977,7 @@ static int flock_lock_inode(struct inode out: spin_unlock(&ctx->flc_lock); @@ -38,7 +36,7 @@ index 665e3ce9ab47..47b66bfc4fa3 100644 if (new_fl) locks_free_lock(new_fl); locks_dispose_list(&dispose); -@@ -1023,7 +1023,7 @@ static int posix_lock_inode(struct inode *inode, struct file_lock *request, +@@ -1015,7 +1015,7 @@ static int posix_lock_inode(struct inode new_fl2 = locks_alloc_lock(); } @@ -47,7 +45,7 @@ index 665e3ce9ab47..47b66bfc4fa3 100644 spin_lock(&ctx->flc_lock); /* * New lock request. Walk all POSIX locks and look for conflicts. If -@@ -1195,7 +1195,7 @@ static int posix_lock_inode(struct inode *inode, struct file_lock *request, +@@ -1187,7 +1187,7 @@ static int posix_lock_inode(struct inode } out: spin_unlock(&ctx->flc_lock); @@ -56,7 +54,7 @@ index 665e3ce9ab47..47b66bfc4fa3 100644 /* * Free any unused locks. */ -@@ -1470,7 +1470,7 @@ int __break_lease(struct inode *inode, unsigned int mode, unsigned int type) +@@ -1462,7 +1462,7 @@ int __break_lease(struct inode *inode, u return error; } @@ -65,7 +63,7 @@ index 665e3ce9ab47..47b66bfc4fa3 100644 spin_lock(&ctx->flc_lock); time_out_leases(inode, &dispose); -@@ -1522,13 +1522,13 @@ int __break_lease(struct inode *inode, unsigned int mode, unsigned int type) +@@ -1514,13 +1514,13 @@ int __break_lease(struct inode *inode, u locks_insert_block(fl, new_fl); trace_break_lease_block(inode, new_fl); spin_unlock(&ctx->flc_lock); @@ -81,7 +79,7 @@ index 665e3ce9ab47..47b66bfc4fa3 100644 spin_lock(&ctx->flc_lock); trace_break_lease_unblock(inode, new_fl); locks_delete_block(new_fl); -@@ -1545,7 +1545,7 @@ int __break_lease(struct inode *inode, unsigned int mode, unsigned int type) +@@ -1537,7 +1537,7 @@ int __break_lease(struct inode *inode, u } out: spin_unlock(&ctx->flc_lock); @@ -90,7 +88,7 @@ index 665e3ce9ab47..47b66bfc4fa3 100644 locks_dispose_list(&dispose); locks_free_lock(new_fl); return error; -@@ -1619,7 +1619,7 @@ int fcntl_getlease(struct file *filp) +@@ -1609,7 +1609,7 @@ int fcntl_getlease(struct file *filp) ctx = smp_load_acquire(&inode->i_flctx); if (ctx && !list_empty_careful(&ctx->flc_lease)) { @@ -99,7 +97,7 @@ index 665e3ce9ab47..47b66bfc4fa3 100644 spin_lock(&ctx->flc_lock); time_out_leases(inode, &dispose); list_for_each_entry(fl, &ctx->flc_lease, fl_list) { -@@ -1629,7 +1629,7 @@ int fcntl_getlease(struct file *filp) +@@ -1619,7 +1619,7 @@ int fcntl_getlease(struct file *filp) break; } spin_unlock(&ctx->flc_lock); @@ -108,7 +106,7 @@ index 665e3ce9ab47..47b66bfc4fa3 100644 locks_dispose_list(&dispose); } -@@ -1704,7 +1704,7 @@ generic_add_lease(struct file *filp, long arg, struct file_lock **flp, void **pr +@@ -1693,7 +1693,7 @@ generic_add_lease(struct file *filp, lon return -EINVAL; } @@ -117,7 +115,7 @@ index 665e3ce9ab47..47b66bfc4fa3 100644 spin_lock(&ctx->flc_lock); time_out_leases(inode, &dispose); error = check_conflicting_open(dentry, arg, lease->fl_flags); -@@ -1775,7 +1775,7 @@ generic_add_lease(struct file *filp, long arg, struct file_lock **flp, void **pr +@@ -1764,7 +1764,7 @@ generic_add_lease(struct file *filp, lon lease->fl_lmops->lm_setup(lease, priv); out: spin_unlock(&ctx->flc_lock); @@ -126,7 +124,7 @@ index 665e3ce9ab47..47b66bfc4fa3 100644 locks_dispose_list(&dispose); if (is_deleg) inode_unlock(inode); -@@ -1798,7 +1798,7 @@ static int generic_delete_lease(struct file *filp, void *owner) +@@ -1787,7 +1787,7 @@ static int generic_delete_lease(struct f return error; } @@ -135,7 +133,7 @@ index 665e3ce9ab47..47b66bfc4fa3 100644 spin_lock(&ctx->flc_lock); list_for_each_entry(fl, &ctx->flc_lease, fl_list) { if (fl->fl_file == filp && -@@ -1811,7 +1811,7 @@ static int generic_delete_lease(struct file *filp, void *owner) +@@ -1800,7 +1800,7 @@ static int generic_delete_lease(struct f if (victim) error = fl->fl_lmops->lm_change(victim, F_UNLCK, &dispose); spin_unlock(&ctx->flc_lock); @@ -144,7 +142,7 @@ index 665e3ce9ab47..47b66bfc4fa3 100644 locks_dispose_list(&dispose); return error; } -@@ -2542,13 +2542,13 @@ locks_remove_lease(struct file *filp, struct file_lock_context *ctx) +@@ -2531,13 +2531,13 @@ locks_remove_lease(struct file *filp, st if (list_empty(&ctx->flc_lease)) return; @@ -160,11 +158,9 @@ index 665e3ce9ab47..47b66bfc4fa3 100644 locks_dispose_list(&dispose); } -diff --git a/include/linux/percpu-rwsem.h b/include/linux/percpu-rwsem.h -index 79b99d653e03..fb44e237316d 100644 --- a/include/linux/percpu-rwsem.h +++ b/include/linux/percpu-rwsem.h -@@ -29,7 +29,7 @@ static struct percpu_rw_semaphore name = { \ +@@ -29,7 +29,7 @@ static struct percpu_rw_semaphore name = extern int __percpu_down_read(struct percpu_rw_semaphore *, int); extern void __percpu_up_read(struct percpu_rw_semaphore *); @@ -173,7 +169,7 @@ index 79b99d653e03..fb44e237316d 100644 { might_sleep(); -@@ -47,16 +47,10 @@ static inline void percpu_down_read_preempt_disable(struct percpu_rw_semaphore * +@@ -47,16 +47,10 @@ static inline void percpu_down_read_pree __this_cpu_inc(*sem->read_count); if (unlikely(!rcu_sync_is_idle(&sem->rss))) __percpu_down_read(sem, false); /* Unconditional memory barrier */ @@ -191,7 +187,7 @@ index 79b99d653e03..fb44e237316d 100644 preempt_enable(); } -@@ -83,13 +77,9 @@ static inline int percpu_down_read_trylock(struct percpu_rw_semaphore *sem) +@@ -83,13 +77,9 @@ static inline int percpu_down_read_trylo return ret; } @@ -207,7 +203,7 @@ index 79b99d653e03..fb44e237316d 100644 /* * Same as in percpu_down_read(). */ -@@ -102,12 +92,6 @@ static inline void percpu_up_read_preempt_enable(struct percpu_rw_semaphore *sem +@@ -102,12 +92,6 @@ static inline void percpu_up_read_preemp rwsem_release(&sem->rw_sem.dep_map, 1, _RET_IP_); } @@ -220,6 +216,3 @@ index 79b99d653e03..fb44e237316d 100644 extern void percpu_down_write(struct percpu_rw_semaphore *); extern void percpu_up_write(struct percpu_rw_semaphore *); --- -2.19.2 - diff --git a/kernel/patches-4.14.x-rt/0276-mm-Protect-activate_mm-by-preempt_-disable-enable-_r.patch b/kernel/patches-4.19.x-rt/0173-mm-protect-activate-switch-mm.patch similarity index 85% rename from kernel/patches-4.14.x-rt/0276-mm-Protect-activate_mm-by-preempt_-disable-enable-_r.patch rename to kernel/patches-4.19.x-rt/0173-mm-protect-activate-switch-mm.patch index bbf75ab51..e22f28f17 100644 --- a/kernel/patches-4.14.x-rt/0276-mm-Protect-activate_mm-by-preempt_-disable-enable-_r.patch +++ b/kernel/patches-4.19.x-rt/0173-mm-protect-activate-switch-mm.patch @@ -1,8 +1,6 @@ -From 5f2d9ad05796dd05af4d407521cb3e347d6f6e2b Mon Sep 17 00:00:00 2001 From: Yong Zhang Date: Tue, 15 May 2012 13:53:56 +0800 -Subject: [PATCH 276/450] mm: Protect activate_mm() by - preempt_[disable&enable]_rt() +Subject: mm: Protect activate_mm() by preempt_[disable&enable]_rt() User preempt_*_rt instead of local_irq_*_rt or otherwise there will be warning on ARM like below: @@ -32,15 +30,13 @@ Cc: Steven Rostedt Link: http://lkml.kernel.org/r/1337061236-1766-1-git-send-email-yong.zhang0@gmail.com Signed-off-by: Thomas Gleixner --- - fs/exec.c | 2 ++ - mm/mmu_context.c | 2 ++ + fs/exec.c | 2 ++ + mm/mmu_context.c | 2 ++ 2 files changed, 4 insertions(+) -diff --git a/fs/exec.c b/fs/exec.c -index 0da4d748b4e6..609aee4dbfa9 100644 --- a/fs/exec.c +++ b/fs/exec.c -@@ -1024,12 +1024,14 @@ static int exec_mmap(struct mm_struct *mm) +@@ -1028,12 +1028,14 @@ static int exec_mmap(struct mm_struct *m } } task_lock(tsk); @@ -55,8 +51,6 @@ index 0da4d748b4e6..609aee4dbfa9 100644 task_unlock(tsk); if (old_mm) { up_read(&old_mm->mmap_sem); -diff --git a/mm/mmu_context.c b/mm/mmu_context.c -index 3e612ae748e9..d0ccc070979f 100644 --- a/mm/mmu_context.c +++ b/mm/mmu_context.c @@ -25,6 +25,7 @@ void use_mm(struct mm_struct *mm) @@ -75,6 +69,3 @@ index 3e612ae748e9..d0ccc070979f 100644 task_unlock(tsk); #ifdef finish_arch_post_lock_switch finish_arch_post_lock_switch(); --- -2.19.2 - diff --git a/kernel/patches-4.14.x-rt/0281-fs-dcache-bringt-back-explicit-INIT_HLIST_BL_HEAD-in.patch b/kernel/patches-4.19.x-rt/0174-fs-dcache-bring-back-explicit-INIT_HLIST_BL_HEAD-in.patch similarity index 64% rename from kernel/patches-4.14.x-rt/0281-fs-dcache-bringt-back-explicit-INIT_HLIST_BL_HEAD-in.patch rename to kernel/patches-4.19.x-rt/0174-fs-dcache-bring-back-explicit-INIT_HLIST_BL_HEAD-in.patch index 2c3eb19ad..6c2589977 100644 --- a/kernel/patches-4.14.x-rt/0281-fs-dcache-bringt-back-explicit-INIT_HLIST_BL_HEAD-in.patch +++ b/kernel/patches-4.19.x-rt/0174-fs-dcache-bring-back-explicit-INIT_HLIST_BL_HEAD-in.patch @@ -1,8 +1,6 @@ -From dc1bd887cefe3fb7209f0cd93ae7070053bad798 Mon Sep 17 00:00:00 2001 From: Sebastian Andrzej Siewior Date: Wed, 13 Sep 2017 12:32:34 +0200 -Subject: [PATCH 281/450] fs/dcache: bringt back explicit INIT_HLIST_BL_HEAD - init +Subject: [PATCH] fs/dcache: bring back explicit INIT_HLIST_BL_HEAD init Commit 3d375d78593c ("mm: update callers to use HASH_ZERO flag") removed INIT_HLIST_BL_HEAD and uses the ZERO flag instead for the init. However @@ -11,14 +9,12 @@ that. Signed-off-by: Sebastian Andrzej Siewior --- - fs/dcache.c | 10 ++++++++++ - 1 file changed, 10 insertions(+) + fs/dcache.c | 11 +++++++++++ + 1 file changed, 11 insertions(+) -diff --git a/fs/dcache.c b/fs/dcache.c -index 28b2e770bb69..f93b5570bc99 100644 --- a/fs/dcache.c +++ b/fs/dcache.c -@@ -3638,6 +3638,8 @@ __setup("dhash_entries=", set_dhash_entries); +@@ -3058,6 +3058,8 @@ static int __init set_dhash_entries(char static void __init dcache_init_early(void) { @@ -27,13 +23,15 @@ index 28b2e770bb69..f93b5570bc99 100644 /* If hashes are distributed across NUMA nodes, defer * hash allocation until vmalloc space is available. */ -@@ -3654,10 +3656,14 @@ static void __init dcache_init_early(void) - &d_hash_mask, +@@ -3074,11 +3076,16 @@ static void __init dcache_init_early(voi + NULL, 0, 0); + + for (loop = 0; loop < (1U << d_hash_shift); loop++) + INIT_HLIST_BL_HEAD(dentry_hashtable + loop); ++ + d_hash_shift = 32 - d_hash_shift; } static void __init dcache_init(void) @@ -42,17 +40,14 @@ index 28b2e770bb69..f93b5570bc99 100644 /* * A constructor could be added for stable state like the lists, * but it is probably not worth it because of the cache nature -@@ -3680,6 +3686,10 @@ static void __init dcache_init(void) - &d_hash_mask, +@@ -3102,6 +3109,10 @@ static void __init dcache_init(void) + NULL, 0, 0); + + for (loop = 0; loop < (1U << d_hash_shift); loop++) + INIT_HLIST_BL_HEAD(dentry_hashtable + loop); + + d_hash_shift = 32 - d_hash_shift; } - /* SLAB cache for __getname() consumers */ --- -2.19.2 - diff --git a/kernel/patches-4.14.x-rt/0282-fs-dcache-disable-preemption-on-i_dir_seq-s-write-si.patch b/kernel/patches-4.19.x-rt/0175-fs-dcache-disable-preemption-on-i_dir_seq-s-write-si.patch similarity index 70% rename from kernel/patches-4.14.x-rt/0282-fs-dcache-disable-preemption-on-i_dir_seq-s-write-si.patch rename to kernel/patches-4.19.x-rt/0175-fs-dcache-disable-preemption-on-i_dir_seq-s-write-si.patch index 49243aed5..063fe84a6 100644 --- a/kernel/patches-4.14.x-rt/0282-fs-dcache-disable-preemption-on-i_dir_seq-s-write-si.patch +++ b/kernel/patches-4.19.x-rt/0175-fs-dcache-disable-preemption-on-i_dir_seq-s-write-si.patch @@ -1,8 +1,6 @@ -From a97e1866677bb396b2034a3ae3cd882234452caf Mon Sep 17 00:00:00 2001 From: Sebastian Andrzej Siewior Date: Fri, 20 Oct 2017 11:29:53 +0200 -Subject: [PATCH 282/450] fs/dcache: disable preemption on i_dir_seq's write - side +Subject: [PATCH] fs/dcache: disable preemption on i_dir_seq's write side i_dir_seq is an opencoded seqcounter. Based on the code it looks like we could have two writers in parallel despite the fact that the d_lock is @@ -17,17 +15,15 @@ Cc: stable-rt@vger.kernel.org Reported-by: Oleg.Karfich@wago.com Signed-off-by: Sebastian Andrzej Siewior --- - fs/dcache.c | 12 +++++++----- - fs/inode.c | 2 +- - fs/libfs.c | 6 ++++-- - include/linux/fs.h | 2 +- + fs/dcache.c | 12 +++++++----- + fs/inode.c | 2 +- + fs/libfs.c | 6 ++++-- + include/linux/fs.h | 2 +- 4 files changed, 13 insertions(+), 9 deletions(-) -diff --git a/fs/dcache.c b/fs/dcache.c -index f93b5570bc99..8aa63a9d18cd 100644 --- a/fs/dcache.c +++ b/fs/dcache.c -@@ -2459,9 +2459,10 @@ EXPORT_SYMBOL(d_rehash); +@@ -2400,9 +2400,10 @@ EXPORT_SYMBOL(d_rehash); static inline unsigned start_dir_add(struct inode *dir) { @@ -40,7 +36,7 @@ index f93b5570bc99..8aa63a9d18cd 100644 return n; cpu_relax(); } -@@ -2469,7 +2470,8 @@ static inline unsigned start_dir_add(struct inode *dir) +@@ -2410,7 +2411,8 @@ static inline unsigned start_dir_add(str static inline void end_dir_add(struct inode *dir, unsigned n) { @@ -50,7 +46,7 @@ index f93b5570bc99..8aa63a9d18cd 100644 } static void d_wait_lookup(struct dentry *dentry) -@@ -2502,7 +2504,7 @@ struct dentry *d_alloc_parallel(struct dentry *parent, +@@ -2443,7 +2445,7 @@ struct dentry *d_alloc_parallel(struct d retry: rcu_read_lock(); @@ -59,7 +55,7 @@ index f93b5570bc99..8aa63a9d18cd 100644 r_seq = read_seqbegin(&rename_lock); dentry = __d_lookup_rcu(parent, name, &d_seq); if (unlikely(dentry)) { -@@ -2530,7 +2532,7 @@ struct dentry *d_alloc_parallel(struct dentry *parent, +@@ -2471,7 +2473,7 @@ struct dentry *d_alloc_parallel(struct d } hlist_bl_lock(b); @@ -68,11 +64,9 @@ index f93b5570bc99..8aa63a9d18cd 100644 hlist_bl_unlock(b); rcu_read_unlock(); goto retry; -diff --git a/fs/inode.c b/fs/inode.c -index cfc36d11bcb3..b77ce179798a 100644 --- a/fs/inode.c +++ b/fs/inode.c -@@ -154,7 +154,7 @@ int inode_init_always(struct super_block *sb, struct inode *inode) +@@ -155,7 +155,7 @@ int inode_init_always(struct super_block inode->i_bdev = NULL; inode->i_cdev = NULL; inode->i_link = NULL; @@ -81,11 +75,9 @@ index cfc36d11bcb3..b77ce179798a 100644 inode->i_rdev = 0; inode->dirtied_when = 0; -diff --git a/fs/libfs.c b/fs/libfs.c -index 3aabe553fc45..b5d63bf1ad8e 100644 --- a/fs/libfs.c +++ b/fs/libfs.c -@@ -90,7 +90,7 @@ static struct dentry *next_positive(struct dentry *parent, +@@ -90,7 +90,7 @@ static struct dentry *next_positive(stru struct list_head *from, int count) { @@ -94,7 +86,7 @@ index 3aabe553fc45..b5d63bf1ad8e 100644 struct dentry *res; struct list_head *p; bool skipped; -@@ -123,8 +123,9 @@ static struct dentry *next_positive(struct dentry *parent, +@@ -123,8 +123,9 @@ static struct dentry *next_positive(stru static void move_cursor(struct dentry *cursor, struct list_head *after) { struct dentry *parent = cursor->d_parent; @@ -105,7 +97,7 @@ index 3aabe553fc45..b5d63bf1ad8e 100644 for (;;) { n = *seq; if (!(n & 1) && cmpxchg(seq, n, n + 1) == n) -@@ -137,6 +138,7 @@ static void move_cursor(struct dentry *cursor, struct list_head *after) +@@ -137,6 +138,7 @@ static void move_cursor(struct dentry *c else list_add_tail(&cursor->d_child, &parent->d_subdirs); smp_store_release(seq, n + 2); @@ -113,11 +105,9 @@ index 3aabe553fc45..b5d63bf1ad8e 100644 spin_unlock(&parent->d_lock); } -diff --git a/include/linux/fs.h b/include/linux/fs.h -index f6a577edec67..10cdd9dbbf84 100644 --- a/include/linux/fs.h +++ b/include/linux/fs.h -@@ -657,7 +657,7 @@ struct inode { +@@ -669,7 +669,7 @@ struct inode { struct block_device *i_bdev; struct cdev *i_cdev; char *i_link; @@ -126,6 +116,3 @@ index f6a577edec67..10cdd9dbbf84 100644 }; __u32 i_generation; --- -2.19.2 - diff --git a/kernel/patches-4.14.x-rt/0415-squashfs-make-use-of-local-lock-in-multi_cpu-decompr.patch b/kernel/patches-4.19.x-rt/0176-squashfs-make-use-of-local-lock-in-multi_cpu-decompr.patch similarity index 77% rename from kernel/patches-4.14.x-rt/0415-squashfs-make-use-of-local-lock-in-multi_cpu-decompr.patch rename to kernel/patches-4.19.x-rt/0176-squashfs-make-use-of-local-lock-in-multi_cpu-decompr.patch index 81045af12..9265989bb 100644 --- a/kernel/patches-4.14.x-rt/0415-squashfs-make-use-of-local-lock-in-multi_cpu-decompr.patch +++ b/kernel/patches-4.19.x-rt/0176-squashfs-make-use-of-local-lock-in-multi_cpu-decompr.patch @@ -1,11 +1,8 @@ -From 0eced237e47c220bbf17a7acad60f4f34328becb Mon Sep 17 00:00:00 2001 From: Julia Cartwright Date: Mon, 7 May 2018 08:58:57 -0500 -Subject: [PATCH 415/450] squashfs: make use of local lock in multi_cpu +Subject: [PATCH] squashfs: make use of local lock in multi_cpu decompressor -[ Upstream commit c160736542d7b3d67da32848d2f028b8e35730e5 ] - Currently, the squashfs multi_cpu decompressor makes use of get_cpu_ptr()/put_cpu_ptr(), which unconditionally disable preemption during decompression. @@ -23,13 +20,10 @@ Reported-by: Alexander Stein Tested-by: Alexander Stein Signed-off-by: Julia Cartwright Signed-off-by: Sebastian Andrzej Siewior -Signed-off-by: Steven Rostedt (VMware) --- - fs/squashfs/decompressor_multi_percpu.c | 16 ++++++++++++---- + fs/squashfs/decompressor_multi_percpu.c | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) -diff --git a/fs/squashfs/decompressor_multi_percpu.c b/fs/squashfs/decompressor_multi_percpu.c -index 23a9c28ad8ea..6a73c4fa88e7 100644 --- a/fs/squashfs/decompressor_multi_percpu.c +++ b/fs/squashfs/decompressor_multi_percpu.c @@ -10,6 +10,7 @@ @@ -49,7 +43,7 @@ index 23a9c28ad8ea..6a73c4fa88e7 100644 void *squashfs_decompressor_create(struct squashfs_sb_info *msblk, void *comp_opts) { -@@ -79,10 +82,15 @@ int squashfs_decompress(struct squashfs_sb_info *msblk, struct buffer_head **bh, +@@ -79,10 +82,15 @@ int squashfs_decompress(struct squashfs_ { struct squashfs_stream __percpu *percpu = (struct squashfs_stream __percpu *) msblk->stream; @@ -69,6 +63,3 @@ index 23a9c28ad8ea..6a73c4fa88e7 100644 if (res < 0) ERROR("%s decompression failed, data probably corrupt\n", --- -2.19.2 - diff --git a/kernel/patches-4.14.x-rt/0288-thermal-Defer-thermal-wakups-to-threads.patch b/kernel/patches-4.19.x-rt/0177-thermal-Defer-thermal-wakups-to-threads.patch similarity index 79% rename from kernel/patches-4.14.x-rt/0288-thermal-Defer-thermal-wakups-to-threads.patch rename to kernel/patches-4.19.x-rt/0177-thermal-Defer-thermal-wakups-to-threads.patch index d20eeb458..f7067c4a0 100644 --- a/kernel/patches-4.14.x-rt/0288-thermal-Defer-thermal-wakups-to-threads.patch +++ b/kernel/patches-4.19.x-rt/0177-thermal-Defer-thermal-wakups-to-threads.patch @@ -1,7 +1,6 @@ -From 9c801faae3ec149a11c6d6b38c320198cb2eff87 Mon Sep 17 00:00:00 2001 From: Daniel Wagner Date: Tue, 17 Feb 2015 09:37:44 +0100 -Subject: [PATCH 288/450] thermal: Defer thermal wakups to threads +Subject: thermal: Defer thermal wakups to threads On RT the spin lock in pkg_temp_thermal_platfrom_thermal_notify will call schedule while we run in irq context. @@ -24,11 +23,9 @@ Signed-off-by: Daniel Wagner [bigeasy: reoder init/denit position. TODO: flush swork on exit] Signed-off-by: Sebastian Andrzej Siewior --- - drivers/thermal/x86_pkg_temp_thermal.c | 52 ++++++++++++++++++++++++-- + drivers/thermal/x86_pkg_temp_thermal.c | 52 +++++++++++++++++++++++++++++++-- 1 file changed, 49 insertions(+), 3 deletions(-) -diff --git a/drivers/thermal/x86_pkg_temp_thermal.c b/drivers/thermal/x86_pkg_temp_thermal.c -index d93eee2f101b..0287333b1f3c 100644 --- a/drivers/thermal/x86_pkg_temp_thermal.c +++ b/drivers/thermal/x86_pkg_temp_thermal.c @@ -29,6 +29,7 @@ @@ -39,7 +36,7 @@ index d93eee2f101b..0287333b1f3c 100644 #include #include -@@ -329,7 +330,7 @@ static void pkg_thermal_schedule_work(int cpu, struct delayed_work *work) +@@ -329,7 +330,7 @@ static void pkg_thermal_schedule_work(in schedule_delayed_work_on(cpu, work, ms); } @@ -48,7 +45,7 @@ index d93eee2f101b..0287333b1f3c 100644 { int cpu = smp_processor_id(); struct pkg_device *pkgdev; -@@ -348,9 +349,47 @@ static int pkg_thermal_notify(u64 msr_val) +@@ -348,9 +349,47 @@ static int pkg_thermal_notify(u64 msr_va } spin_unlock_irqrestore(&pkg_temp_lock, flags); @@ -96,7 +93,7 @@ index d93eee2f101b..0287333b1f3c 100644 static int pkg_temp_thermal_device_add(unsigned int cpu) { int pkgid = topology_logical_package_id(cpu); -@@ -515,10 +554,15 @@ static int __init pkg_temp_thermal_init(void) +@@ -515,11 +554,16 @@ static int __init pkg_temp_thermal_init( if (!x86_match_cpu(pkg_temp_thermal_ids)) return -ENODEV; @@ -104,7 +101,8 @@ index d93eee2f101b..0287333b1f3c 100644 + return -ENODEV; + max_packages = topology_max_packages(); - packages = kzalloc(max_packages * sizeof(struct pkg_device *), GFP_KERNEL); + packages = kcalloc(max_packages, sizeof(struct pkg_device *), + GFP_KERNEL); - if (!packages) - return -ENOMEM; + if (!packages) { @@ -114,7 +112,7 @@ index d93eee2f101b..0287333b1f3c 100644 ret = cpuhp_setup_state(CPUHP_AP_ONLINE_DYN, "thermal/x86_pkg:online", pkg_thermal_cpu_online, pkg_thermal_cpu_offline); -@@ -536,6 +580,7 @@ static int __init pkg_temp_thermal_init(void) +@@ -537,6 +581,7 @@ static int __init pkg_temp_thermal_init( return 0; err: @@ -122,7 +120,7 @@ index d93eee2f101b..0287333b1f3c 100644 kfree(packages); return ret; } -@@ -549,6 +594,7 @@ static void __exit pkg_temp_thermal_exit(void) +@@ -550,6 +595,7 @@ static void __exit pkg_temp_thermal_exit cpuhp_remove_state(pkg_thermal_hp_state); debugfs_remove_recursive(debugfs); kfree(packages); @@ -130,6 +128,3 @@ index d93eee2f101b..0287333b1f3c 100644 } module_exit(pkg_temp_thermal_exit) --- -2.19.2 - diff --git a/kernel/patches-4.14.x-rt/0444-x86-fpu-Disable-preemption-around-local_bh_disable.patch b/kernel/patches-4.19.x-rt/0178-x86-fpu-Disable-preemption-around-local_bh_disable.patch similarity index 59% rename from kernel/patches-4.14.x-rt/0444-x86-fpu-Disable-preemption-around-local_bh_disable.patch rename to kernel/patches-4.19.x-rt/0178-x86-fpu-Disable-preemption-around-local_bh_disable.patch index 48d8fc704..39ea6a637 100644 --- a/kernel/patches-4.14.x-rt/0444-x86-fpu-Disable-preemption-around-local_bh_disable.patch +++ b/kernel/patches-4.19.x-rt/0178-x86-fpu-Disable-preemption-around-local_bh_disable.patch @@ -1,9 +1,6 @@ -From af6eb3df73f38f4c10653bae3ae8b627ea6f71fb Mon Sep 17 00:00:00 2001 From: Sebastian Andrzej Siewior Date: Tue, 11 Dec 2018 15:10:33 +0100 -Subject: [PATCH 444/450] x86/fpu: Disable preemption around local_bh_disable() - -[ Upstream commit f70ac4a5ca5df1d84dae809453464eca16b54f51 ] +Subject: [PATCH] x86/fpu: Disable preemption around local_bh_disable() __fpu__restore_sig() restores the content of the FPU state in the CPUs and in order to avoid concurency it disbles BH. On !RT it also disables @@ -13,16 +10,13 @@ Add preempt_disable() while the FPU state is restored. Cc: stable-rt@vger.kernel.org Signed-off-by: Sebastian Andrzej Siewior -Signed-off-by: Steven Rostedt (VMware) --- - arch/x86/kernel/fpu/signal.c | 2 ++ + arch/x86/kernel/fpu/signal.c | 2 ++ 1 file changed, 2 insertions(+) -diff --git a/arch/x86/kernel/fpu/signal.c b/arch/x86/kernel/fpu/signal.c -index d99a8ee9e185..5e0274a94133 100644 --- a/arch/x86/kernel/fpu/signal.c +++ b/arch/x86/kernel/fpu/signal.c -@@ -344,10 +344,12 @@ static int __fpu__restore_sig(void __user *buf, void __user *buf_fx, int size) +@@ -344,10 +344,12 @@ static int __fpu__restore_sig(void __use sanitize_restored_xstate(tsk, &env, xfeatures, fx_only); } @@ -35,6 +29,3 @@ index d99a8ee9e185..5e0274a94133 100644 return err; } else { --- -2.19.2 - diff --git a/kernel/patches-4.14.x-rt/0289-fs-epoll-Do-not-disable-preemption-on-RT.patch b/kernel/patches-4.19.x-rt/0179-epoll-use-get-cpu-light.patch similarity index 58% rename from kernel/patches-4.14.x-rt/0289-fs-epoll-Do-not-disable-preemption-on-RT.patch rename to kernel/patches-4.19.x-rt/0179-epoll-use-get-cpu-light.patch index 3f2dddb3c..79e571153 100644 --- a/kernel/patches-4.14.x-rt/0289-fs-epoll-Do-not-disable-preemption-on-RT.patch +++ b/kernel/patches-4.19.x-rt/0179-epoll-use-get-cpu-light.patch @@ -1,7 +1,6 @@ -From 96d894a2de5c48a0cf700df45140e530d30987ed Mon Sep 17 00:00:00 2001 +Subject: fs/epoll: Do not disable preemption on RT From: Thomas Gleixner -Date: Fri, 8 Jul 2011 16:35:35 +0200 -Subject: [PATCH 289/450] fs/epoll: Do not disable preemption on RT +Date: Fri, 08 Jul 2011 16:35:35 +0200 ep_call_nested() takes a sleeping lock so we can't disable preemption. The light version is enough since ep_call_nested() doesn't mind beeing @@ -9,15 +8,13 @@ invoked twice on the same CPU. Signed-off-by: Thomas Gleixner --- - fs/eventpoll.c | 4 ++-- + fs/eventpoll.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) -diff --git a/fs/eventpoll.c b/fs/eventpoll.c -index 2fabd19cdeea..b768c32631eb 100644 --- a/fs/eventpoll.c +++ b/fs/eventpoll.c -@@ -587,12 +587,12 @@ static int ep_poll_wakeup_proc(void *priv, void *cookie, int call_nests) - */ +@@ -571,12 +571,12 @@ static int ep_poll_wakeup_proc(void *pri + static void ep_poll_safewake(wait_queue_head_t *wq) { - int this_cpu = get_cpu(); @@ -30,7 +27,4 @@ index 2fabd19cdeea..b768c32631eb 100644 + put_cpu_light(); } - static void ep_remove_wait_queue(struct eppoll_entry *pwq) --- -2.19.2 - + #else diff --git a/kernel/patches-4.14.x-rt/0290-mm-vmalloc-Another-preempt-disable-region-which-suck.patch b/kernel/patches-4.19.x-rt/0180-mm-vmalloc-use-get-cpu-light.patch similarity index 66% rename from kernel/patches-4.14.x-rt/0290-mm-vmalloc-Another-preempt-disable-region-which-suck.patch rename to kernel/patches-4.19.x-rt/0180-mm-vmalloc-use-get-cpu-light.patch index 040a79482..d874456ca 100644 --- a/kernel/patches-4.14.x-rt/0290-mm-vmalloc-Another-preempt-disable-region-which-suck.patch +++ b/kernel/patches-4.19.x-rt/0180-mm-vmalloc-use-get-cpu-light.patch @@ -1,22 +1,18 @@ -From 3b5b7590e56263ba80198ae916802d69e5696f06 Mon Sep 17 00:00:00 2001 +Subject: mm/vmalloc: Another preempt disable region which sucks From: Thomas Gleixner Date: Tue, 12 Jul 2011 11:39:36 +0200 -Subject: [PATCH 290/450] mm/vmalloc: Another preempt disable region which - sucks Avoid the preempt disable version of get_cpu_var(). The inner-lock should provide enough serialisation. Signed-off-by: Thomas Gleixner --- - mm/vmalloc.c | 13 ++++++++----- + mm/vmalloc.c | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) -diff --git a/mm/vmalloc.c b/mm/vmalloc.c -index 9ff21a12ea00..95c83b291548 100644 --- a/mm/vmalloc.c +++ b/mm/vmalloc.c -@@ -865,7 +865,7 @@ static void *new_vmap_block(unsigned int order, gfp_t gfp_mask) +@@ -848,7 +848,7 @@ static void *new_vmap_block(unsigned int struct vmap_block *vb; struct vmap_area *va; unsigned long vb_idx; @@ -25,7 +21,7 @@ index 9ff21a12ea00..95c83b291548 100644 void *vaddr; node = numa_node_id(); -@@ -908,11 +908,12 @@ static void *new_vmap_block(unsigned int order, gfp_t gfp_mask) +@@ -891,11 +891,12 @@ static void *new_vmap_block(unsigned int BUG_ON(err); radix_tree_preload_end(); @@ -40,7 +36,7 @@ index 9ff21a12ea00..95c83b291548 100644 return vaddr; } -@@ -981,6 +982,7 @@ static void *vb_alloc(unsigned long size, gfp_t gfp_mask) +@@ -964,6 +965,7 @@ static void *vb_alloc(unsigned long size struct vmap_block *vb; void *vaddr = NULL; unsigned int order; @@ -48,7 +44,7 @@ index 9ff21a12ea00..95c83b291548 100644 BUG_ON(offset_in_page(size)); BUG_ON(size > PAGE_SIZE*VMAP_MAX_ALLOC); -@@ -995,7 +997,8 @@ static void *vb_alloc(unsigned long size, gfp_t gfp_mask) +@@ -978,7 +980,8 @@ static void *vb_alloc(unsigned long size order = get_order(size); rcu_read_lock(); @@ -58,7 +54,7 @@ index 9ff21a12ea00..95c83b291548 100644 list_for_each_entry_rcu(vb, &vbq->free, free_list) { unsigned long pages_off; -@@ -1018,7 +1021,7 @@ static void *vb_alloc(unsigned long size, gfp_t gfp_mask) +@@ -1001,7 +1004,7 @@ static void *vb_alloc(unsigned long size break; } @@ -67,6 +63,3 @@ index 9ff21a12ea00..95c83b291548 100644 rcu_read_unlock(); /* Allocate new block if nothing was found */ --- -2.19.2 - diff --git a/kernel/patches-4.14.x-rt/0291-block-mq-use-cpu_light.patch b/kernel/patches-4.19.x-rt/0181-block-mq-use-cpu_light.patch similarity index 67% rename from kernel/patches-4.14.x-rt/0291-block-mq-use-cpu_light.patch rename to kernel/patches-4.19.x-rt/0181-block-mq-use-cpu_light.patch index 604a2d8fb..ddcd4e826 100644 --- a/kernel/patches-4.14.x-rt/0291-block-mq-use-cpu_light.patch +++ b/kernel/patches-4.19.x-rt/0181-block-mq-use-cpu_light.patch @@ -1,21 +1,18 @@ -From 1c4826faee5ea60271487ad1c212e84e55e04370 Mon Sep 17 00:00:00 2001 From: Sebastian Andrzej Siewior Date: Wed, 9 Apr 2014 10:37:23 +0200 -Subject: [PATCH 291/450] block: mq: use cpu_light() +Subject: block: mq: use cpu_light() there is a might sleep splat because get_cpu() disables preemption and later we grab a lock. As a workaround for this we use get_cpu_light(). Signed-off-by: Sebastian Andrzej Siewior --- - block/blk-mq.h | 4 ++-- + block/blk-mq.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) -diff --git a/block/blk-mq.h b/block/blk-mq.h -index 877237e09083..d944750bade0 100644 --- a/block/blk-mq.h +++ b/block/blk-mq.h -@@ -98,12 +98,12 @@ static inline struct blk_mq_ctx *__blk_mq_get_ctx(struct request_queue *q, +@@ -113,12 +113,12 @@ static inline struct blk_mq_ctx *__blk_m */ static inline struct blk_mq_ctx *blk_mq_get_ctx(struct request_queue *q) { @@ -30,6 +27,3 @@ index 877237e09083..d944750bade0 100644 } struct blk_mq_alloc_data { --- -2.19.2 - diff --git a/kernel/patches-4.14.x-rt/0292-block-mq-do-not-invoke-preempt_disable.patch b/kernel/patches-4.19.x-rt/0182-block-mq-drop-preempt-disable.patch similarity index 62% rename from kernel/patches-4.14.x-rt/0292-block-mq-do-not-invoke-preempt_disable.patch rename to kernel/patches-4.19.x-rt/0182-block-mq-drop-preempt-disable.patch index d3869916e..8f28f7118 100644 --- a/kernel/patches-4.14.x-rt/0292-block-mq-do-not-invoke-preempt_disable.patch +++ b/kernel/patches-4.19.x-rt/0182-block-mq-drop-preempt-disable.patch @@ -1,7 +1,6 @@ -From 9c3c6a9a4eb5d1376582274d4a3e22c6000f6bcc Mon Sep 17 00:00:00 2001 From: Sebastian Andrzej Siewior Date: Tue, 14 Jul 2015 14:26:34 +0200 -Subject: [PATCH 292/450] block/mq: do not invoke preempt_disable() +Subject: block/mq: do not invoke preempt_disable() preempt_disable() and get_cpu() don't play well together with the sleeping locks it tries to allocate later. @@ -9,14 +8,12 @@ It seems to be enough to replace it with get_cpu_light() and migrate_disable(). Signed-off-by: Sebastian Andrzej Siewior --- - block/blk-mq.c | 10 +++++----- + block/blk-mq.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) -diff --git a/block/blk-mq.c b/block/blk-mq.c -index 5a572127c7af..d6dc746eeab1 100644 --- a/block/blk-mq.c +++ b/block/blk-mq.c -@@ -558,7 +558,7 @@ static void __blk_mq_complete_request(struct request *rq) +@@ -570,7 +570,7 @@ static void __blk_mq_complete_request(st return; } @@ -25,7 +22,7 @@ index 5a572127c7af..d6dc746eeab1 100644 if (!test_bit(QUEUE_FLAG_SAME_FORCE, &rq->q->queue_flags)) shared = cpus_share_cache(cpu, ctx->cpu); -@@ -570,7 +570,7 @@ static void __blk_mq_complete_request(struct request *rq) +@@ -582,7 +582,7 @@ static void __blk_mq_complete_request(st } else { rq->q->softirq_done_fn(rq); } @@ -33,8 +30,8 @@ index 5a572127c7af..d6dc746eeab1 100644 + put_cpu_light(); } - /** -@@ -1238,14 +1238,14 @@ static void __blk_mq_delay_run_hw_queue(struct blk_mq_hw_ctx *hctx, bool async, + static void hctx_unlock(struct blk_mq_hw_ctx *hctx, int srcu_idx) +@@ -1360,14 +1360,14 @@ static void __blk_mq_delay_run_hw_queue( return; if (!async && !(hctx->flags & BLK_MQ_F_BLOCKING)) { @@ -51,7 +48,4 @@ index 5a572127c7af..d6dc746eeab1 100644 + put_cpu_light(); } - kblockd_schedule_delayed_work_on(blk_mq_hctx_next_cpu(hctx), --- -2.19.2 - + kblockd_mod_delayed_work_on(blk_mq_hctx_next_cpu(hctx), &hctx->run_work, diff --git a/kernel/patches-4.14.x-rt/0293-block-mq-don-t-complete-requests-via-IPI.patch b/kernel/patches-4.19.x-rt/0183-block-mq-don-t-complete-requests-via-IPI.patch similarity index 64% rename from kernel/patches-4.14.x-rt/0293-block-mq-don-t-complete-requests-via-IPI.patch rename to kernel/patches-4.19.x-rt/0183-block-mq-don-t-complete-requests-via-IPI.patch index 0c811fd12..f0edb21b8 100644 --- a/kernel/patches-4.14.x-rt/0293-block-mq-don-t-complete-requests-via-IPI.patch +++ b/kernel/patches-4.19.x-rt/0183-block-mq-don-t-complete-requests-via-IPI.patch @@ -1,24 +1,21 @@ -From 3f2ef2cd1efd2df737cef1d41dfc030ea882d83c Mon Sep 17 00:00:00 2001 From: Sebastian Andrzej Siewior Date: Thu, 29 Jan 2015 15:10:08 +0100 -Subject: [PATCH 293/450] block/mq: don't complete requests via IPI +Subject: block/mq: don't complete requests via IPI The IPI runs in hardirq context and there are sleeping locks. This patch moves the completion into a workqueue. Signed-off-by: Sebastian Andrzej Siewior --- - block/blk-core.c | 3 +++ - block/blk-mq.c | 23 +++++++++++++++++++++++ - include/linux/blk-mq.h | 2 +- - include/linux/blkdev.h | 3 +++ + block/blk-core.c | 3 +++ + block/blk-mq.c | 23 +++++++++++++++++++++++ + include/linux/blk-mq.h | 2 +- + include/linux/blkdev.h | 3 +++ 4 files changed, 30 insertions(+), 1 deletion(-) -diff --git a/block/blk-core.c b/block/blk-core.c -index b3edf248d148..ec5c206bfbe5 100644 --- a/block/blk-core.c +++ b/block/blk-core.c -@@ -116,6 +116,9 @@ void blk_rq_init(struct request_queue *q, struct request *rq) +@@ -189,6 +189,9 @@ void blk_rq_init(struct request_queue *q INIT_LIST_HEAD(&rq->queuelist); INIT_LIST_HEAD(&rq->timeout_list); @@ -28,13 +25,11 @@ index b3edf248d148..ec5c206bfbe5 100644 rq->cpu = -1; rq->q = q; rq->__sector = (sector_t) -1; -diff --git a/block/blk-mq.c b/block/blk-mq.c -index d6dc746eeab1..a6314b82273e 100644 --- a/block/blk-mq.c +++ b/block/blk-mq.c -@@ -339,6 +339,9 @@ static struct request *blk_mq_rq_ctx_init(struct blk_mq_alloc_data *data, - /* tag was already set */ +@@ -320,6 +320,9 @@ static struct request *blk_mq_rq_ctx_ini rq->extra_len = 0; + rq->__deadline = 0; +#ifdef CONFIG_PREEMPT_RT_FULL + INIT_WORK(&rq->work, __blk_mq_complete_request_remote_work); @@ -42,7 +37,7 @@ index d6dc746eeab1..a6314b82273e 100644 INIT_LIST_HEAD(&rq->timeout_list); rq->timeout = 0; -@@ -533,12 +536,24 @@ void blk_mq_end_request(struct request *rq, blk_status_t error) +@@ -547,12 +550,24 @@ void blk_mq_end_request(struct request * } EXPORT_SYMBOL(blk_mq_end_request); @@ -67,7 +62,7 @@ index d6dc746eeab1..a6314b82273e 100644 static void __blk_mq_complete_request(struct request *rq) { -@@ -563,10 +578,18 @@ static void __blk_mq_complete_request(struct request *rq) +@@ -575,10 +590,18 @@ static void __blk_mq_complete_request(st shared = cpus_share_cache(cpu, ctx->cpu); if (cpu != ctx->cpu && !shared && cpu_online(ctx->cpu)) { @@ -86,11 +81,9 @@ index d6dc746eeab1..a6314b82273e 100644 } else { rq->q->softirq_done_fn(rq); } -diff --git a/include/linux/blk-mq.h b/include/linux/blk-mq.h -index 994cbb0f7ffc..0d4b7e3489a9 100644 --- a/include/linux/blk-mq.h +++ b/include/linux/blk-mq.h -@@ -226,7 +226,7 @@ static inline u16 blk_mq_unique_tag_to_tag(u32 unique_tag) +@@ -249,7 +249,7 @@ static inline u16 blk_mq_unique_tag_to_t return unique_tag & BLK_MQ_UNIQUE_TAG_MASK; } @@ -99,20 +92,15 @@ index 994cbb0f7ffc..0d4b7e3489a9 100644 int blk_mq_request_started(struct request *rq); void blk_mq_start_request(struct request *rq); void blk_mq_end_request(struct request *rq, blk_status_t error); -diff --git a/include/linux/blkdev.h b/include/linux/blkdev.h -index 4d4af0e94059..a32b7ad032cb 100644 --- a/include/linux/blkdev.h +++ b/include/linux/blkdev.h -@@ -134,6 +134,9 @@ typedef __u32 __bitwise req_flags_t; +@@ -149,6 +149,9 @@ enum mq_rq_state { */ struct request { - struct list_head queuelist; + struct request_queue *q; +#ifdef CONFIG_PREEMPT_RT_FULL + struct work_struct work; +#endif - union { - struct __call_single_data csd; - u64 fifo_time; --- -2.19.2 - + struct blk_mq_ctx *mq_ctx; + + int cpu; diff --git a/kernel/patches-4.14.x-rt/0294-md-raid5-Make-raid5_percpu-handling-RT-aware.patch b/kernel/patches-4.19.x-rt/0184-md-raid5-percpu-handling-rt-aware.patch similarity index 68% rename from kernel/patches-4.14.x-rt/0294-md-raid5-Make-raid5_percpu-handling-RT-aware.patch rename to kernel/patches-4.19.x-rt/0184-md-raid5-percpu-handling-rt-aware.patch index 8a099951f..81991cdfa 100644 --- a/kernel/patches-4.14.x-rt/0294-md-raid5-Make-raid5_percpu-handling-RT-aware.patch +++ b/kernel/patches-4.19.x-rt/0184-md-raid5-percpu-handling-rt-aware.patch @@ -1,7 +1,6 @@ -From b75ca677f946ade7c7cc82676cd903939960b896 Mon Sep 17 00:00:00 2001 From: Thomas Gleixner Date: Tue, 6 Apr 2010 16:51:31 +0200 -Subject: [PATCH 294/450] md: raid5: Make raid5_percpu handling RT aware +Subject: md: raid5: Make raid5_percpu handling RT aware __raid_run_ops() disables preemption with get_cpu() around the access to the raid5_percpu variables. That causes scheduling while atomic @@ -13,16 +12,15 @@ preemptible. Reported-by: Udo van den Heuvel Signed-off-by: Thomas Gleixner Tested-by: Udo van den Heuvel + --- - drivers/md/raid5.c | 8 +++++--- - drivers/md/raid5.h | 1 + + drivers/md/raid5.c | 8 +++++--- + drivers/md/raid5.h | 1 + 2 files changed, 6 insertions(+), 3 deletions(-) -diff --git a/drivers/md/raid5.c b/drivers/md/raid5.c -index dbf51b4c21b3..dd0c17736633 100644 --- a/drivers/md/raid5.c +++ b/drivers/md/raid5.c -@@ -2067,8 +2067,9 @@ static void raid_run_ops(struct stripe_head *sh, unsigned long ops_request) +@@ -2069,8 +2069,9 @@ static void raid_run_ops(struct stripe_h struct raid5_percpu *percpu; unsigned long cpu; @@ -33,7 +31,7 @@ index dbf51b4c21b3..dd0c17736633 100644 if (test_bit(STRIPE_OP_BIOFILL, &ops_request)) { ops_run_biofill(sh); overlap_clear++; -@@ -2127,7 +2128,8 @@ static void raid_run_ops(struct stripe_head *sh, unsigned long ops_request) +@@ -2129,7 +2130,8 @@ static void raid_run_ops(struct stripe_h if (test_and_clear_bit(R5_Overlap, &dev->flags)) wake_up(&sh->raid_conf->wait_for_overlap); } @@ -43,7 +41,7 @@ index dbf51b4c21b3..dd0c17736633 100644 } static void free_stripe(struct kmem_cache *sc, struct stripe_head *sh) -@@ -6781,6 +6783,7 @@ static int raid456_cpu_up_prepare(unsigned int cpu, struct hlist_node *node) +@@ -6803,6 +6805,7 @@ static int raid456_cpu_up_prepare(unsign __func__, cpu); return -ENOMEM; } @@ -51,7 +49,7 @@ index dbf51b4c21b3..dd0c17736633 100644 return 0; } -@@ -6791,7 +6794,6 @@ static int raid5_alloc_percpu(struct r5conf *conf) +@@ -6813,7 +6816,6 @@ static int raid5_alloc_percpu(struct r5c conf->percpu = alloc_percpu(struct raid5_percpu); if (!conf->percpu) return -ENOMEM; @@ -59,11 +57,9 @@ index dbf51b4c21b3..dd0c17736633 100644 err = cpuhp_state_add_instance(CPUHP_MD_RAID5_PREPARE, &conf->node); if (!err) { conf->scribble_disks = max(conf->raid_disks, -diff --git a/drivers/md/raid5.h b/drivers/md/raid5.h -index 2e6123825095..37a6021418a2 100644 --- a/drivers/md/raid5.h +++ b/drivers/md/raid5.h -@@ -624,6 +624,7 @@ struct r5conf { +@@ -637,6 +637,7 @@ struct r5conf { int recovery_disabled; /* per cpu variables */ struct raid5_percpu { @@ -71,6 +67,3 @@ index 2e6123825095..37a6021418a2 100644 struct page *spare_page; /* Used when checking P/Q in raid6 */ struct flex_array *scribble; /* space for constructing buffer * lists and performing address --- -2.19.2 - diff --git a/kernel/patches-4.14.x-rt/0296-rt-Introduce-cpu_chill.patch b/kernel/patches-4.19.x-rt/0185-rt-introduce-cpu-chill.patch similarity index 51% rename from kernel/patches-4.14.x-rt/0296-rt-Introduce-cpu_chill.patch rename to kernel/patches-4.19.x-rt/0185-rt-introduce-cpu-chill.patch index 63f60a255..f96cff930 100644 --- a/kernel/patches-4.14.x-rt/0296-rt-Introduce-cpu_chill.patch +++ b/kernel/patches-4.19.x-rt/0185-rt-introduce-cpu-chill.patch @@ -1,7 +1,6 @@ -From 4989629587968edeece6338a9f20f6ebd07f4ada Mon Sep 17 00:00:00 2001 +Subject: rt: Introduce cpu_chill() From: Thomas Gleixner -Date: Wed, 7 Mar 2012 20:51:03 +0100 -Subject: [PATCH 296/450] rt: Introduce cpu_chill() +Date: Wed, 07 Mar 2012 20:51:03 +0100 Retry loops on RT might loop forever when the modifying side was preempted. Add cpu_chill() to replace cpu_relax(). cpu_chill() @@ -14,40 +13,14 @@ Steven Rostedt changed it to use a hrtimer instead of msleep(): |up by the ksoftirqd running the TIMER softirq. But as the cpu_chill() is |called from softirq context, it may block the ksoftirqd() from running, in |which case, it may never wake up the msleep() causing the deadlock. -| -|I checked the vmcore, and irq/74-qla2xxx is stuck in the msleep() call, -|running on CPU 8. The one ksoftirqd that is stuck, happens to be the one that -|runs on CPU 8, and it is blocked on a lock held by irq/74-qla2xxx. As that -|ksoftirqd is the one that will wake up irq/74-qla2xxx, and it happens to be -|blocked on a lock that irq/74-qla2xxx holds, we have our deadlock. -| -|The solution is not to convert the cpu_chill() back to a cpu_relax() as that -|will re-create a possible live lock that the cpu_chill() fixed earlier, and may -|also leave this bug open on other softirqs. The fix is to remove the -|dependency on ksoftirqd from cpu_chill(). That is, instead of calling -|msleep() that requires ksoftirqd to wake it up, use the -|hrtimer_nanosleep() code that does the wakeup from hard irq context. -| -||Looks to be the lock of the block softirq. I don't have the core dump -||anymore, but from what I could tell the ksoftirqd was blocked on the -||block softirq lock, where the block softirq handler did a msleep -||(called by the qla2xxx interrupt handler). -|| -||Looking at trigger_softirq() in block/blk-softirq.c, it can do a -||smp_callfunction() to another cpu to run the block softirq. If that -||happens to be the cpu where the qla2xx irq handler is doing the block -||softirq and is in a middle of a msleep(), I believe the ksoftirqd will -||try to run the softirq. If it does that, then BOOM, it's deadlocked -||because the ksoftirqd will never run the timer softirq either. -| -||I should have also stated that it was only one lock that was involved. -||But the lock owner was doing a msleep() that requires a wakeup by -||ksoftirqd to continue. If ksoftirqd happens to be blocked on a lock -||held by the msleep() caller, then you have your deadlock. -|| -||It's best not to have any softirqs going to sleep requiring another -||softirq to wake it up. Note, if we ever require a timer softirq to do a -||cpu_chill() it will most definitely hit this deadlock. + ++ bigeasy later changed to schedule_hrtimeout() +|If a task calls cpu_chill() and gets woken up by a regular or spurious +|wakeup and has a signal pending, then it exits the sleep loop in +|do_nanosleep() and sets up the restart block. If restart->nanosleep.type is +|not TI_NONE then this results in accessing a stale user pointer from a +|previously interrupted syscall and a copy to user based on the stale +|pointer or a BUG() when 'type' is not supported in nanosleep_copyout(). + bigeasy: add PF_NOFREEZE: | [....] Waiting for /dev to be fully populated... @@ -82,15 +55,13 @@ Signed-off-by: Thomas Gleixner Signed-off-by: Steven Rostedt Signed-off-by: Sebastian Andrzej Siewior --- - include/linux/delay.h | 6 ++++++ - kernel/time/hrtimer.c | 19 +++++++++++++++++++ - 2 files changed, 25 insertions(+) + include/linux/delay.h | 6 ++++++ + kernel/time/hrtimer.c | 21 +++++++++++++++++++++ + 2 files changed, 27 insertions(+) -diff --git a/include/linux/delay.h b/include/linux/delay.h -index b78bab4395d8..7c4bc414a504 100644 --- a/include/linux/delay.h +++ b/include/linux/delay.h -@@ -64,4 +64,10 @@ static inline void ssleep(unsigned int seconds) +@@ -64,4 +64,10 @@ static inline void ssleep(unsigned int s msleep(seconds * 1000); } @@ -101,11 +72,9 @@ index b78bab4395d8..7c4bc414a504 100644 +#endif + #endif /* defined(_LINUX_DELAY_H) */ -diff --git a/kernel/time/hrtimer.c b/kernel/time/hrtimer.c -index f824b9721ce7..ad67ac12d6b6 100644 --- a/kernel/time/hrtimer.c +++ b/kernel/time/hrtimer.c -@@ -1858,6 +1858,25 @@ COMPAT_SYSCALL_DEFINE2(nanosleep, struct compat_timespec __user *, rqtp, +@@ -1894,6 +1894,27 @@ COMPAT_SYSCALL_DEFINE2(nanosleep, struct } #endif @@ -115,13 +84,15 @@ index f824b9721ce7..ad67ac12d6b6 100644 + */ +void cpu_chill(void) +{ -+ struct timespec64 tu = { -+ .tv_nsec = NSEC_PER_MSEC, -+ }; ++ ktime_t chill_time; + unsigned int freeze_flag = current->flags & PF_NOFREEZE; + ++ chill_time = ktime_set(0, NSEC_PER_MSEC); ++ set_current_state(TASK_UNINTERRUPTIBLE); + current->flags |= PF_NOFREEZE; -+ hrtimer_nanosleep(&tu, HRTIMER_MODE_REL_HARD, CLOCK_MONOTONIC); ++ sleeping_lock_inc(); ++ schedule_hrtimeout(&chill_time, HRTIMER_MODE_REL_HARD); ++ sleeping_lock_dec(); + if (!freeze_flag) + current->flags &= ~PF_NOFREEZE; +} @@ -131,6 +102,3 @@ index f824b9721ce7..ad67ac12d6b6 100644 /* * Functions related to boot-time initialization: */ --- -2.19.2 - diff --git a/kernel/patches-4.19.x-rt/0186-hrtimer-Don-t-lose-state-in-cpu_chill.patch b/kernel/patches-4.19.x-rt/0186-hrtimer-Don-t-lose-state-in-cpu_chill.patch new file mode 100644 index 000000000..482fe7452 --- /dev/null +++ b/kernel/patches-4.19.x-rt/0186-hrtimer-Don-t-lose-state-in-cpu_chill.patch @@ -0,0 +1,41 @@ +From: Sebastian Andrzej Siewior +Date: Tue, 19 Feb 2019 16:59:15 +0100 +Subject: [PATCH] hrtimer: Don't lose state in cpu_chill() + +In cpu_chill() the state is set to TASK_UNINTERRUPTIBLE and a timer is +programmed. On return the state is always TASK_RUNNING which means we +lose the state if it was something other than RUNNING. Also +set_current_state() sets ->task_state_change to within cpu_chill() which +is not expected. + +Save the task state on entry and restore it on return. Simply set the +state in order to avoid updating ->task_state_change. + +Cc: stable-rt@vger.kernel.org +Signed-off-by: Sebastian Andrzej Siewior +--- + kernel/time/hrtimer.c | 5 ++++- + 1 file changed, 4 insertions(+), 1 deletion(-) + +--- a/kernel/time/hrtimer.c ++++ b/kernel/time/hrtimer.c +@@ -1902,15 +1902,18 @@ void cpu_chill(void) + { + ktime_t chill_time; + unsigned int freeze_flag = current->flags & PF_NOFREEZE; ++ long saved_state; + ++ saved_state = current->state; + chill_time = ktime_set(0, NSEC_PER_MSEC); +- set_current_state(TASK_UNINTERRUPTIBLE); ++ __set_current_state_no_track(TASK_UNINTERRUPTIBLE); + current->flags |= PF_NOFREEZE; + sleeping_lock_inc(); + schedule_hrtimeout(&chill_time, HRTIMER_MODE_REL_HARD); + sleeping_lock_dec(); + if (!freeze_flag) + current->flags &= ~PF_NOFREEZE; ++ __set_current_state_no_track(saved_state); + } + EXPORT_SYMBOL(cpu_chill); + #endif diff --git a/kernel/patches-4.19.x-rt/0187-hrtimer-cpu_chill-save-task-state-in-saved_state.patch b/kernel/patches-4.19.x-rt/0187-hrtimer-cpu_chill-save-task-state-in-saved_state.patch new file mode 100644 index 000000000..350e7762a --- /dev/null +++ b/kernel/patches-4.19.x-rt/0187-hrtimer-cpu_chill-save-task-state-in-saved_state.patch @@ -0,0 +1,55 @@ +From: Sebastian Andrzej Siewior +Date: Tue, 26 Feb 2019 12:31:10 +0100 +Subject: [PATCH] hrtimer: cpu_chill(): save task state in ->saved_state() + +In the previous change I saved the current task state on stack. This was +bad because while the task is scheduled-out it might receive a wake-up. +The wake up changes the task state and we must not destroy it. + +Save the task-state in ->saved_state under a PI-lock to unsure that +state changes during are not missed while the task temporary scheduled +out. + +Reported-by: Mike Galbraith +Tested-by: Mike Galbraith +Signed-off-by: Sebastian Andrzej Siewior +--- + kernel/time/hrtimer.c | 18 +++++++++++++----- + 1 file changed, 13 insertions(+), 5 deletions(-) + +--- a/kernel/time/hrtimer.c ++++ b/kernel/time/hrtimer.c +@@ -1900,20 +1900,28 @@ COMPAT_SYSCALL_DEFINE2(nanosleep, struct + */ + void cpu_chill(void) + { +- ktime_t chill_time; + unsigned int freeze_flag = current->flags & PF_NOFREEZE; +- long saved_state; ++ struct task_struct *self = current; ++ ktime_t chill_time; + +- saved_state = current->state; +- chill_time = ktime_set(0, NSEC_PER_MSEC); ++ raw_spin_lock_irq(&self->pi_lock); ++ self->saved_state = self->state; + __set_current_state_no_track(TASK_UNINTERRUPTIBLE); ++ raw_spin_unlock_irq(&self->pi_lock); ++ ++ chill_time = ktime_set(0, NSEC_PER_MSEC); ++ + current->flags |= PF_NOFREEZE; + sleeping_lock_inc(); + schedule_hrtimeout(&chill_time, HRTIMER_MODE_REL_HARD); + sleeping_lock_dec(); + if (!freeze_flag) + current->flags &= ~PF_NOFREEZE; +- __set_current_state_no_track(saved_state); ++ ++ raw_spin_lock_irq(&self->pi_lock); ++ __set_current_state_no_track(self->saved_state); ++ self->saved_state = TASK_RUNNING; ++ raw_spin_unlock_irq(&self->pi_lock); + } + EXPORT_SYMBOL(cpu_chill); + #endif diff --git a/kernel/patches-4.14.x-rt/0301-block-blk-mq-move-blk_queue_usage_counter_release-in.patch b/kernel/patches-4.19.x-rt/0188-block-blk-mq-move-blk_queue_usage_counter_release-in.patch similarity index 82% rename from kernel/patches-4.14.x-rt/0301-block-blk-mq-move-blk_queue_usage_counter_release-in.patch rename to kernel/patches-4.19.x-rt/0188-block-blk-mq-move-blk_queue_usage_counter_release-in.patch index 0e6e30433..a23254b1a 100644 --- a/kernel/patches-4.14.x-rt/0301-block-blk-mq-move-blk_queue_usage_counter_release-in.patch +++ b/kernel/patches-4.19.x-rt/0188-block-blk-mq-move-blk_queue_usage_counter_release-in.patch @@ -1,7 +1,6 @@ -From 223b2527af397368f3e5f2077b52fdb268896ccb Mon Sep 17 00:00:00 2001 From: Sebastian Andrzej Siewior Date: Tue, 13 Mar 2018 13:49:16 +0100 -Subject: [PATCH 301/450] block: blk-mq: move blk_queue_usage_counter_release() +Subject: [PATCH] block: blk-mq: move blk_queue_usage_counter_release() into process context | BUG: sleeping function called from invalid context at kernel/locking/rtmutex.c:914 @@ -44,18 +43,15 @@ wake_up_all() usage and disabled interrupts in !RT configs (as reported by Corey Minyard). The wq_has_sleeper() check has been suggested by Peter Zijlstra. -Cc: stable-rt@vger.kernel.org Signed-off-by: Sebastian Andrzej Siewior --- - block/blk-core.c | 14 +++++++++++++- - include/linux/blkdev.h | 2 ++ + block/blk-core.c | 14 +++++++++++++- + include/linux/blkdev.h | 2 ++ 2 files changed, 15 insertions(+), 1 deletion(-) -diff --git a/block/blk-core.c b/block/blk-core.c -index ec5c206bfbe5..0aa5a80acb29 100644 --- a/block/blk-core.c +++ b/block/blk-core.c -@@ -814,12 +814,21 @@ void blk_queue_exit(struct request_queue *q) +@@ -968,12 +968,21 @@ void blk_queue_exit(struct request_queue percpu_ref_put(&q->q_usage_counter); } @@ -77,16 +73,16 @@ index ec5c206bfbe5..0aa5a80acb29 100644 + swork_queue(&q->mq_pcpu_wake); } - static void blk_rq_timed_out_timer(unsigned long data) -@@ -896,6 +905,7 @@ struct request_queue *blk_alloc_queue_node(gfp_t gfp_mask, int node_id) - __set_bit(QUEUE_FLAG_BYPASS, &q->queue_flags); + static void blk_rq_timed_out_timer(struct timer_list *t) +@@ -1066,6 +1075,7 @@ struct request_queue *blk_alloc_queue_no + queue_flag_set_unlocked(QUEUE_FLAG_BYPASS, q); init_waitqueue_head(&q->mq_freeze_wq); + INIT_SWORK(&q->mq_pcpu_wake, blk_queue_usage_counter_release_swork); /* * Init percpu_ref in atomic mode so that it's faster to shutdown. -@@ -3632,6 +3642,8 @@ int __init blk_dev_init(void) +@@ -3956,6 +3966,8 @@ int __init blk_dev_init(void) if (!kblockd_workqueue) panic("Failed to create kblockd\n"); @@ -95,8 +91,6 @@ index ec5c206bfbe5..0aa5a80acb29 100644 request_cachep = kmem_cache_create("blkdev_requests", sizeof(struct request), 0, SLAB_PANIC, NULL); -diff --git a/include/linux/blkdev.h b/include/linux/blkdev.h -index a32b7ad032cb..cbf9d5730dd3 100644 --- a/include/linux/blkdev.h +++ b/include/linux/blkdev.h @@ -27,6 +27,7 @@ @@ -107,7 +101,7 @@ index a32b7ad032cb..cbf9d5730dd3 100644 struct module; struct scsi_ioctl_command; -@@ -599,6 +600,7 @@ struct request_queue { +@@ -649,6 +650,7 @@ struct request_queue { #endif struct rcu_head rcu_head; wait_queue_head_t mq_freeze_wq; @@ -115,6 +109,3 @@ index a32b7ad032cb..cbf9d5730dd3 100644 struct percpu_ref q_usage_counter; struct list_head all_q_node; --- -2.19.2 - diff --git a/kernel/patches-4.14.x-rt/0302-block-Use-cpu_chill-for-retry-loops.patch b/kernel/patches-4.19.x-rt/0189-block-use-cpu-chill.patch similarity index 70% rename from kernel/patches-4.14.x-rt/0302-block-Use-cpu_chill-for-retry-loops.patch rename to kernel/patches-4.19.x-rt/0189-block-use-cpu-chill.patch index ab2600d49..83b2351bd 100644 --- a/kernel/patches-4.14.x-rt/0302-block-Use-cpu_chill-for-retry-loops.patch +++ b/kernel/patches-4.19.x-rt/0189-block-use-cpu-chill.patch @@ -1,7 +1,6 @@ -From d6aea246f760b8cec55422e14f9c32d88c374b9a Mon Sep 17 00:00:00 2001 +Subject: block: Use cpu_chill() for retry loops From: Thomas Gleixner Date: Thu, 20 Dec 2012 18:28:26 +0100 -Subject: [PATCH 302/450] block: Use cpu_chill() for retry loops Retry loops on RT might loop forever when the modifying side was preempted. Steven also observed a live lock when there was a @@ -11,12 +10,11 @@ Use cpu_chill() instead of cpu_relax() to let the system make progress. Signed-off-by: Thomas Gleixner + --- - block/blk-ioc.c | 5 +++-- + block/blk-ioc.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) -diff --git a/block/blk-ioc.c b/block/blk-ioc.c -index f23311e4b201..ca9ea624f159 100644 --- a/block/blk-ioc.c +++ b/block/blk-ioc.c @@ -9,6 +9,7 @@ @@ -27,7 +25,7 @@ index f23311e4b201..ca9ea624f159 100644 #include "blk.h" -@@ -118,7 +119,7 @@ static void ioc_release_fn(struct work_struct *work) +@@ -118,7 +119,7 @@ static void ioc_release_fn(struct work_s spin_unlock(q->queue_lock); } else { spin_unlock_irqrestore(&ioc->lock, flags); @@ -36,7 +34,7 @@ index f23311e4b201..ca9ea624f159 100644 spin_lock_irqsave_nested(&ioc->lock, flags, 1); } } -@@ -202,7 +203,7 @@ void put_io_context_active(struct io_context *ioc) +@@ -202,7 +203,7 @@ void put_io_context_active(struct io_con spin_unlock(icq->q->queue_lock); } else { spin_unlock_irqrestore(&ioc->lock, flags); @@ -45,6 +43,3 @@ index f23311e4b201..ca9ea624f159 100644 goto retry; } } --- -2.19.2 - diff --git a/kernel/patches-4.19.x-rt/0190-fs-dcache-use-cpu-chill-in-trylock-loops.patch b/kernel/patches-4.19.x-rt/0190-fs-dcache-use-cpu-chill-in-trylock-loops.patch new file mode 100644 index 000000000..a027688b9 --- /dev/null +++ b/kernel/patches-4.19.x-rt/0190-fs-dcache-use-cpu-chill-in-trylock-loops.patch @@ -0,0 +1,58 @@ +Subject: fs: dcache: Use cpu_chill() in trylock loops +From: Thomas Gleixner +Date: Wed, 07 Mar 2012 21:00:34 +0100 + +Retry loops on RT might loop forever when the modifying side was +preempted. Use cpu_chill() instead of cpu_relax() to let the system +make progress. + +Signed-off-by: Thomas Gleixner + +--- + fs/autofs/expire.c | 3 ++- + fs/namespace.c | 8 ++++++-- + 2 files changed, 8 insertions(+), 3 deletions(-) + +--- a/fs/autofs/expire.c ++++ b/fs/autofs/expire.c +@@ -8,6 +8,7 @@ + * option, any later version, incorporated herein by reference. + */ + ++#include + #include "autofs_i.h" + + /* Check if a dentry can be expired */ +@@ -153,7 +154,7 @@ static struct dentry *get_next_positive_ + parent = p->d_parent; + if (!spin_trylock(&parent->d_lock)) { + spin_unlock(&p->d_lock); +- cpu_relax(); ++ cpu_chill(); + goto relock; + } + spin_unlock(&p->d_lock); +--- a/fs/namespace.c ++++ b/fs/namespace.c +@@ -14,6 +14,7 @@ + #include + #include + #include ++#include + #include + #include + #include +@@ -327,8 +328,11 @@ int __mnt_want_write(struct vfsmount *m) + * incremented count after it has set MNT_WRITE_HOLD. + */ + smp_mb(); +- while (READ_ONCE(mnt->mnt.mnt_flags) & MNT_WRITE_HOLD) +- cpu_relax(); ++ while (READ_ONCE(mnt->mnt.mnt_flags) & MNT_WRITE_HOLD) { ++ preempt_enable(); ++ cpu_chill(); ++ preempt_disable(); ++ } + /* + * After the slowpath clears MNT_WRITE_HOLD, mnt_is_readonly will + * be set to match its requirements. So we must not load that until diff --git a/kernel/patches-4.14.x-rt/0304-net-Use-cpu_chill-instead-of-cpu_relax.patch b/kernel/patches-4.19.x-rt/0191-net-use-cpu-chill.patch similarity index 66% rename from kernel/patches-4.14.x-rt/0304-net-Use-cpu_chill-instead-of-cpu_relax.patch rename to kernel/patches-4.19.x-rt/0191-net-use-cpu-chill.patch index 15cd5ca6c..e82598515 100644 --- a/kernel/patches-4.14.x-rt/0304-net-Use-cpu_chill-instead-of-cpu_relax.patch +++ b/kernel/patches-4.19.x-rt/0191-net-use-cpu-chill.patch @@ -1,20 +1,18 @@ -From 14d569f6fbc1999e18cc2797ddcd081b35e96f69 Mon Sep 17 00:00:00 2001 +Subject: net: Use cpu_chill() instead of cpu_relax() From: Thomas Gleixner -Date: Wed, 7 Mar 2012 21:10:04 +0100 -Subject: [PATCH 304/450] net: Use cpu_chill() instead of cpu_relax() +Date: Wed, 07 Mar 2012 21:10:04 +0100 Retry loops on RT might loop forever when the modifying side was preempted. Use cpu_chill() instead of cpu_relax() to let the system make progress. Signed-off-by: Thomas Gleixner + --- - net/packet/af_packet.c | 5 +++-- - net/rds/ib_rdma.c | 3 ++- + net/packet/af_packet.c | 5 +++-- + net/rds/ib_rdma.c | 3 ++- 2 files changed, 5 insertions(+), 3 deletions(-) -diff --git a/net/packet/af_packet.c b/net/packet/af_packet.c -index 88d5b2645bb0..02e6ec558a58 100644 --- a/net/packet/af_packet.c +++ b/net/packet/af_packet.c @@ -63,6 +63,7 @@ @@ -25,7 +23,7 @@ index 88d5b2645bb0..02e6ec558a58 100644 #include #include #include -@@ -707,7 +708,7 @@ static void prb_retire_rx_blk_timer_expired(unsigned long data) +@@ -667,7 +668,7 @@ static void prb_retire_rx_blk_timer_expi if (BLOCK_NUM_PKTS(pbd)) { while (atomic_read(&pkc->blk_fill_in_prog)) { /* Waiting for skb_copy_bits to finish... */ @@ -34,7 +32,7 @@ index 88d5b2645bb0..02e6ec558a58 100644 } } -@@ -969,7 +970,7 @@ static void prb_retire_current_block(struct tpacket_kbdq_core *pkc, +@@ -929,7 +930,7 @@ static void prb_retire_current_block(str if (!(status & TP_STATUS_BLK_TMO)) { while (atomic_read(&pkc->blk_fill_in_prog)) { /* Waiting for skb_copy_bits to finish... */ @@ -43,8 +41,6 @@ index 88d5b2645bb0..02e6ec558a58 100644 } } prb_close_block(pkc, pbd, po, status); -diff --git a/net/rds/ib_rdma.c b/net/rds/ib_rdma.c -index 9a3c54e659e9..2a95f1d587ac 100644 --- a/net/rds/ib_rdma.c +++ b/net/rds/ib_rdma.c @@ -34,6 +34,7 @@ @@ -55,7 +51,7 @@ index 9a3c54e659e9..2a95f1d587ac 100644 #include "rds_single_path.h" #include "ib_mr.h" -@@ -210,7 +211,7 @@ static inline void wait_clean_list_grace(void) +@@ -222,7 +223,7 @@ static inline void wait_clean_list_grace for_each_online_cpu(cpu) { flag = &per_cpu(clean_list_grace, cpu); while (test_bit(CLEAN_LIST_BUSY_BIT, flag)) @@ -64,6 +60,3 @@ index 9a3c54e659e9..2a95f1d587ac 100644 } } --- -2.19.2 - diff --git a/kernel/patches-4.14.x-rt/0305-fs-dcache-use-swait_queue-instead-of-waitqueue.patch b/kernel/patches-4.19.x-rt/0192-fs-dcache-use-swait_queue-instead-of-waitqueue.patch similarity index 65% rename from kernel/patches-4.14.x-rt/0305-fs-dcache-use-swait_queue-instead-of-waitqueue.patch rename to kernel/patches-4.19.x-rt/0192-fs-dcache-use-swait_queue-instead-of-waitqueue.patch index 303561df9..c056af3ea 100644 --- a/kernel/patches-4.14.x-rt/0305-fs-dcache-use-swait_queue-instead-of-waitqueue.patch +++ b/kernel/patches-4.19.x-rt/0192-fs-dcache-use-swait_queue-instead-of-waitqueue.patch @@ -1,31 +1,28 @@ -From 8c595a9fc23f592ba05a3f15f845c66465baa0e4 Mon Sep 17 00:00:00 2001 From: Sebastian Andrzej Siewior Date: Wed, 14 Sep 2016 14:35:49 +0200 -Subject: [PATCH 305/450] fs/dcache: use swait_queue instead of waitqueue +Subject: [PATCH] fs/dcache: use swait_queue instead of waitqueue __d_lookup_done() invokes wake_up_all() while holding a hlist_bl_lock() which disables preemption. As a workaround convert it to swait. Signed-off-by: Sebastian Andrzej Siewior --- - fs/cifs/readdir.c | 2 +- - fs/dcache.c | 27 +++++++++++++++------------ - fs/fuse/dir.c | 2 +- - fs/namei.c | 4 ++-- - fs/nfs/dir.c | 4 ++-- - fs/nfs/unlink.c | 4 ++-- - fs/proc/base.c | 2 +- - fs/proc/proc_sysctl.c | 2 +- - include/linux/dcache.h | 4 ++-- - include/linux/nfs_xdr.h | 2 +- - kernel/sched/swait.c | 1 + + fs/cifs/readdir.c | 2 +- + fs/dcache.c | 27 +++++++++++++++------------ + fs/fuse/dir.c | 2 +- + fs/namei.c | 4 ++-- + fs/nfs/dir.c | 4 ++-- + fs/nfs/unlink.c | 4 ++-- + fs/proc/base.c | 2 +- + fs/proc/proc_sysctl.c | 2 +- + include/linux/dcache.h | 4 ++-- + include/linux/nfs_xdr.h | 2 +- + kernel/sched/swait.c | 1 + 11 files changed, 29 insertions(+), 25 deletions(-) -diff --git a/fs/cifs/readdir.c b/fs/cifs/readdir.c -index ef24b4527459..3ce6331a1101 100644 --- a/fs/cifs/readdir.c +++ b/fs/cifs/readdir.c -@@ -80,7 +80,7 @@ cifs_prime_dcache(struct dentry *parent, struct qstr *name, +@@ -80,7 +80,7 @@ cifs_prime_dcache(struct dentry *parent, struct inode *inode; struct super_block *sb = parent->d_sb; struct cifs_sb_info *cifs_sb = CIFS_SB(sb); @@ -34,11 +31,9 @@ index ef24b4527459..3ce6331a1101 100644 cifs_dbg(FYI, "%s: for %s\n", __func__, name->name); -diff --git a/fs/dcache.c b/fs/dcache.c -index c00380d37a3a..b08506ef464a 100644 --- a/fs/dcache.c +++ b/fs/dcache.c -@@ -2488,21 +2488,24 @@ static inline void end_dir_add(struct inode *dir, unsigned n) +@@ -2417,21 +2417,24 @@ static inline void end_dir_add(struct in static void d_wait_lookup(struct dentry *dentry) { @@ -59,7 +54,7 @@ index c00380d37a3a..b08506ef464a 100644 + + INIT_LIST_HEAD(&__wait.task_list); + do { -+ prepare_to_swait(dentry->d_wait, &__wait, TASK_UNINTERRUPTIBLE); ++ prepare_to_swait_exclusive(dentry->d_wait, &__wait, TASK_UNINTERRUPTIBLE); + spin_unlock(&dentry->d_lock); + schedule(); + spin_lock(&dentry->d_lock); @@ -74,7 +69,7 @@ index c00380d37a3a..b08506ef464a 100644 { unsigned int hash = name->hash; struct hlist_bl_head *b = in_lookup_hash(parent, hash); -@@ -2617,7 +2620,7 @@ void __d_lookup_done(struct dentry *dentry) +@@ -2546,7 +2549,7 @@ void __d_lookup_done(struct dentry *dent hlist_bl_lock(b); dentry->d_flags &= ~DCACHE_PAR_LOOKUP; __hlist_bl_del(&dentry->d_u.d_in_lookup_hash); @@ -83,11 +78,9 @@ index c00380d37a3a..b08506ef464a 100644 dentry->d_wait = NULL; hlist_bl_unlock(b); INIT_HLIST_NODE(&dentry->d_u.d_alias); -diff --git a/fs/fuse/dir.c b/fs/fuse/dir.c -index 29868c35c19a..76d354eee035 100644 --- a/fs/fuse/dir.c +++ b/fs/fuse/dir.c -@@ -1188,7 +1188,7 @@ static int fuse_direntplus_link(struct file *file, +@@ -1203,7 +1203,7 @@ static int fuse_direntplus_link(struct f struct inode *dir = d_inode(parent); struct fuse_conn *fc; struct inode *inode; @@ -96,20 +89,18 @@ index 29868c35c19a..76d354eee035 100644 if (!o->nodeid) { /* -diff --git a/fs/namei.c b/fs/namei.c -index d1e467b7b9de..895363adbd32 100644 --- a/fs/namei.c +++ b/fs/namei.c -@@ -1668,7 +1668,7 @@ static struct dentry *lookup_slow(const struct qstr *name, +@@ -1645,7 +1645,7 @@ static struct dentry *__lookup_slow(cons { - struct dentry *dentry = ERR_PTR(-ENOENT), *old; + struct dentry *dentry, *old; struct inode *inode = dir->d_inode; - DECLARE_WAIT_QUEUE_HEAD_ONSTACK(wq); + DECLARE_SWAIT_QUEUE_HEAD_ONSTACK(wq); - inode_lock_shared(inode); /* Don't go there if it's already dead */ -@@ -3141,7 +3141,7 @@ static int lookup_open(struct nameidata *nd, struct path *path, + if (unlikely(IS_DEADDIR(inode))) +@@ -3135,7 +3135,7 @@ static int lookup_open(struct nameidata struct dentry *dentry; int error, create_error = 0; umode_t mode = op->mode; @@ -118,11 +109,9 @@ index d1e467b7b9de..895363adbd32 100644 if (unlikely(IS_DEADDIR(dir_inode))) return -ENOENT; -diff --git a/fs/nfs/dir.c b/fs/nfs/dir.c -index 1f3818580413..f43f5da4a8c3 100644 --- a/fs/nfs/dir.c +++ b/fs/nfs/dir.c -@@ -452,7 +452,7 @@ static +@@ -445,7 +445,7 @@ static void nfs_prime_dcache(struct dentry *parent, struct nfs_entry *entry) { struct qstr filename = QSTR_INIT(entry->name, entry->len); @@ -131,17 +120,15 @@ index 1f3818580413..f43f5da4a8c3 100644 struct dentry *dentry; struct dentry *alias; struct inode *dir = d_inode(parent); -@@ -1443,7 +1443,7 @@ int nfs_atomic_open(struct inode *dir, struct dentry *dentry, +@@ -1459,7 +1459,7 @@ int nfs_atomic_open(struct inode *dir, s struct file *file, unsigned open_flags, - umode_t mode, int *opened) + umode_t mode) { - DECLARE_WAIT_QUEUE_HEAD_ONSTACK(wq); + DECLARE_SWAIT_QUEUE_HEAD_ONSTACK(wq); struct nfs_open_context *ctx; struct dentry *res; struct iattr attr = { .ia_valid = ATTR_OPEN }; -diff --git a/fs/nfs/unlink.c b/fs/nfs/unlink.c -index 2e78bc25bcea..0dc1d3e6a62f 100644 --- a/fs/nfs/unlink.c +++ b/fs/nfs/unlink.c @@ -13,7 +13,7 @@ @@ -153,7 +140,7 @@ index 2e78bc25bcea..0dc1d3e6a62f 100644 #include #include -@@ -206,7 +206,7 @@ nfs_async_unlink(struct dentry *dentry, const struct qstr *name) +@@ -206,7 +206,7 @@ nfs_async_unlink(struct dentry *dentry, goto out_free_name; } data->res.dir_attr = &data->dir_attr; @@ -162,11 +149,9 @@ index 2e78bc25bcea..0dc1d3e6a62f 100644 status = -EBUSY; spin_lock(&dentry->d_lock); -diff --git a/fs/proc/base.c b/fs/proc/base.c -index 9063738ff1f0..4085e56e261c 100644 --- a/fs/proc/base.c +++ b/fs/proc/base.c -@@ -1900,7 +1900,7 @@ bool proc_fill_cache(struct file *file, struct dir_context *ctx, +@@ -1876,7 +1876,7 @@ bool proc_fill_cache(struct file *file, child = d_hash_and_lookup(dir, &qname); if (!child) { @@ -175,11 +160,9 @@ index 9063738ff1f0..4085e56e261c 100644 child = d_alloc_parallel(dir, &qname, &wq); if (IS_ERR(child)) goto end_instantiate; -diff --git a/fs/proc/proc_sysctl.c b/fs/proc/proc_sysctl.c -index 82ac5f682b73..c35714621a38 100644 --- a/fs/proc/proc_sysctl.c +++ b/fs/proc/proc_sysctl.c -@@ -679,7 +679,7 @@ static bool proc_sys_fill_cache(struct file *file, +@@ -677,7 +677,7 @@ static bool proc_sys_fill_cache(struct f child = d_lookup(dir, &qname); if (!child) { @@ -188,11 +171,9 @@ index 82ac5f682b73..c35714621a38 100644 child = d_alloc_parallel(dir, &qname, &wq); if (IS_ERR(child)) return false; -diff --git a/include/linux/dcache.h b/include/linux/dcache.h -index 006f4ccda5f5..d413993f7f17 100644 --- a/include/linux/dcache.h +++ b/include/linux/dcache.h -@@ -107,7 +107,7 @@ struct dentry { +@@ -105,7 +105,7 @@ struct dentry { union { struct list_head d_lru; /* LRU list */ @@ -201,8 +182,8 @@ index 006f4ccda5f5..d413993f7f17 100644 }; struct list_head d_child; /* child of parent list */ struct list_head d_subdirs; /* our children */ -@@ -238,7 +238,7 @@ extern void d_set_d_op(struct dentry *dentry, const struct dentry_operations *op - extern struct dentry * d_alloc(struct dentry *, const struct qstr *); +@@ -236,7 +236,7 @@ extern struct dentry * d_alloc(struct de + extern struct dentry * d_alloc_anon(struct super_block *); extern struct dentry * d_alloc_pseudo(struct super_block *, const struct qstr *); extern struct dentry * d_alloc_parallel(struct dentry *, const struct qstr *, - wait_queue_head_t *); @@ -210,11 +191,9 @@ index 006f4ccda5f5..d413993f7f17 100644 extern struct dentry * d_splice_alias(struct inode *, struct dentry *); extern struct dentry * d_add_ci(struct dentry *, struct inode *, struct qstr *); extern struct dentry * d_exact_alias(struct dentry *, struct inode *); -diff --git a/include/linux/nfs_xdr.h b/include/linux/nfs_xdr.h -index 6959968dc36a..802e849b57ac 100644 --- a/include/linux/nfs_xdr.h +++ b/include/linux/nfs_xdr.h -@@ -1530,7 +1530,7 @@ struct nfs_unlinkdata { +@@ -1549,7 +1549,7 @@ struct nfs_unlinkdata { struct nfs_removeargs args; struct nfs_removeres res; struct dentry *dentry; @@ -223,11 +202,9 @@ index 6959968dc36a..802e849b57ac 100644 struct rpc_cred *cred; struct nfs_fattr dir_attr; long timeout; -diff --git a/kernel/sched/swait.c b/kernel/sched/swait.c -index 7006375949c2..b14638a05ec9 100644 --- a/kernel/sched/swait.c +++ b/kernel/sched/swait.c -@@ -69,6 +69,7 @@ void swake_up_all(struct swait_queue_head *q) +@@ -70,6 +70,7 @@ void swake_up_all(struct swait_queue_hea struct swait_queue *curr; LIST_HEAD(tmp); @@ -235,6 +212,3 @@ index 7006375949c2..b14638a05ec9 100644 raw_spin_lock_irq(&q->lock); list_splice_init(&q->task_list, &tmp); while (!list_empty(&tmp)) { --- -2.19.2 - diff --git a/kernel/patches-4.14.x-rt/0306-workqueue-Use-normal-rcu.patch b/kernel/patches-4.19.x-rt/0193-workqueue-use-rcu.patch similarity index 79% rename from kernel/patches-4.14.x-rt/0306-workqueue-Use-normal-rcu.patch rename to kernel/patches-4.19.x-rt/0193-workqueue-use-rcu.patch index d3603d10c..bfd7d95a8 100644 --- a/kernel/patches-4.14.x-rt/0306-workqueue-Use-normal-rcu.patch +++ b/kernel/patches-4.19.x-rt/0193-workqueue-use-rcu.patch @@ -1,7 +1,6 @@ -From a2a559cbb22d6441d6ae9667b0a96aae156634a1 Mon Sep 17 00:00:00 2001 +Subject: workqueue: Use normal rcu From: Thomas Gleixner Date: Wed, 24 Jul 2013 15:26:54 +0200 -Subject: [PATCH 306/450] workqueue: Use normal rcu There is no need for sched_rcu. The undocumented reason why sched_rcu is used is to avoid a few explicit rcu_read_lock()/unlock() pairs by @@ -10,11 +9,9 @@ protected by preempt or irq disabled regions. Signed-off-by: Thomas Gleixner --- - kernel/workqueue.c | 95 +++++++++++++++++++++++++--------------------- + kernel/workqueue.c | 95 +++++++++++++++++++++++++++++------------------------ 1 file changed, 52 insertions(+), 43 deletions(-) -diff --git a/kernel/workqueue.c b/kernel/workqueue.c -index 08bc551976b2..7ed3b49267a8 100644 --- a/kernel/workqueue.c +++ b/kernel/workqueue.c @@ -127,7 +127,7 @@ enum { @@ -35,7 +32,7 @@ index 08bc551976b2..7ed3b49267a8 100644 * * MD: wq_mayday_lock protected. */ -@@ -186,7 +186,7 @@ struct worker_pool { +@@ -183,7 +183,7 @@ struct worker_pool { atomic_t nr_running ____cacheline_aligned_in_smp; /* @@ -44,7 +41,7 @@ index 08bc551976b2..7ed3b49267a8 100644 * from get_work_pool(). */ struct rcu_head rcu; -@@ -215,7 +215,7 @@ struct pool_workqueue { +@@ -212,7 +212,7 @@ struct pool_workqueue { /* * Release of unbound pwq is punted to system_wq. See put_pwq() * and pwq_unbound_release_workfn() for details. pool_workqueue @@ -53,7 +50,7 @@ index 08bc551976b2..7ed3b49267a8 100644 * determined without grabbing wq->mutex. */ struct work_struct unbound_release_work; -@@ -359,20 +359,20 @@ static void workqueue_sysfs_unregister(struct workqueue_struct *wq); +@@ -357,20 +357,20 @@ static void workqueue_sysfs_unregister(s #include #define assert_rcu_or_pool_mutex() \ @@ -80,7 +77,7 @@ index 08bc551976b2..7ed3b49267a8 100644 #define for_each_cpu_worker_pool(pool, cpu) \ for ((pool) = &per_cpu(cpu_worker_pools, cpu)[0]; \ -@@ -384,7 +384,7 @@ static void workqueue_sysfs_unregister(struct workqueue_struct *wq); +@@ -382,7 +382,7 @@ static void workqueue_sysfs_unregister(s * @pool: iteration cursor * @pi: integer used for iteration * @@ -89,7 +86,7 @@ index 08bc551976b2..7ed3b49267a8 100644 * locked. If the pool needs to be used beyond the locking in effect, the * caller is responsible for guaranteeing that the pool stays online. * -@@ -416,7 +416,7 @@ static void workqueue_sysfs_unregister(struct workqueue_struct *wq); +@@ -414,7 +414,7 @@ static void workqueue_sysfs_unregister(s * @pwq: iteration cursor * @wq: the target workqueue * @@ -98,7 +95,7 @@ index 08bc551976b2..7ed3b49267a8 100644 * If the pwq needs to be used beyond the locking in effect, the caller is * responsible for guaranteeing that the pwq stays online. * -@@ -552,7 +552,7 @@ static int worker_pool_assign_id(struct worker_pool *pool) +@@ -550,7 +550,7 @@ static int worker_pool_assign_id(struct * @wq: the target workqueue * @node: the node ID * @@ -107,7 +104,7 @@ index 08bc551976b2..7ed3b49267a8 100644 * read locked. * If the pwq needs to be used beyond the locking in effect, the caller is * responsible for guaranteeing that the pwq stays online. -@@ -696,8 +696,8 @@ static struct pool_workqueue *get_work_pwq(struct work_struct *work) +@@ -694,8 +694,8 @@ static struct pool_workqueue *get_work_p * @work: the work item of interest * * Pools are created and destroyed under wq_pool_mutex, and allows read @@ -118,7 +115,7 @@ index 08bc551976b2..7ed3b49267a8 100644 * * All fields of the returned pool are accessible as long as the above * mentioned locking is in effect. If the returned pool needs to be used -@@ -1102,7 +1102,7 @@ static void put_pwq_unlocked(struct pool_workqueue *pwq) +@@ -1100,7 +1100,7 @@ static void put_pwq_unlocked(struct pool { if (pwq) { /* @@ -127,7 +124,7 @@ index 08bc551976b2..7ed3b49267a8 100644 * following lock operations are safe. */ spin_lock_irq(&pwq->pool->lock); -@@ -1230,6 +1230,7 @@ static int try_to_grab_pending(struct work_struct *work, bool is_dwork, +@@ -1228,6 +1228,7 @@ static int try_to_grab_pending(struct wo if (!test_and_set_bit(WORK_STRUCT_PENDING_BIT, work_data_bits(work))) return 0; @@ -135,7 +132,7 @@ index 08bc551976b2..7ed3b49267a8 100644 /* * The queueing is in progress, or it is already queued. Try to * steal it from ->worklist without clearing WORK_STRUCT_PENDING. -@@ -1268,10 +1269,12 @@ static int try_to_grab_pending(struct work_struct *work, bool is_dwork, +@@ -1266,10 +1267,12 @@ static int try_to_grab_pending(struct wo set_work_pool_and_keep_pending(work, pool->id); spin_unlock(&pool->lock); @@ -148,7 +145,7 @@ index 08bc551976b2..7ed3b49267a8 100644 local_irq_restore(*flags); if (work_is_canceling(work)) return -ENOENT; -@@ -1385,6 +1388,7 @@ static void __queue_work(int cpu, struct workqueue_struct *wq, +@@ -1383,6 +1386,7 @@ static void __queue_work(int cpu, struct if (unlikely(wq->flags & __WQ_DRAINING) && WARN_ON_ONCE(!is_chained_work(wq))) return; @@ -156,7 +153,7 @@ index 08bc551976b2..7ed3b49267a8 100644 retry: if (req_cpu == WORK_CPU_UNBOUND) cpu = wq_select_unbound_cpu(raw_smp_processor_id()); -@@ -1441,10 +1445,8 @@ static void __queue_work(int cpu, struct workqueue_struct *wq, +@@ -1439,10 +1443,8 @@ static void __queue_work(int cpu, struct /* pwq determined, queue */ trace_workqueue_queue_work(req_cpu, pwq, work); @@ -169,7 +166,7 @@ index 08bc551976b2..7ed3b49267a8 100644 pwq->nr_in_flight[pwq->work_color]++; work_flags = work_color_to_flags(pwq->work_color); -@@ -1462,7 +1464,9 @@ static void __queue_work(int cpu, struct workqueue_struct *wq, +@@ -1460,7 +1462,9 @@ static void __queue_work(int cpu, struct insert_work(pwq, work, worklist, work_flags); @@ -179,7 +176,7 @@ index 08bc551976b2..7ed3b49267a8 100644 } /** -@@ -2815,14 +2819,14 @@ static bool start_flush_work(struct work_struct *work, struct wq_barrier *barr) +@@ -2855,14 +2859,14 @@ static bool start_flush_work(struct work might_sleep(); @@ -197,7 +194,7 @@ index 08bc551976b2..7ed3b49267a8 100644 /* see the comment in try_to_grab_pending() with the same code */ pwq = get_work_pwq(work); if (pwq) { -@@ -2853,10 +2857,11 @@ static bool start_flush_work(struct work_struct *work, struct wq_barrier *barr) +@@ -2894,10 +2898,11 @@ static bool start_flush_work(struct work lock_map_acquire(&pwq->wq->lockdep_map); lock_map_release(&pwq->wq->lockdep_map); } @@ -210,7 +207,7 @@ index 08bc551976b2..7ed3b49267a8 100644 return false; } -@@ -3284,7 +3289,7 @@ static void rcu_free_pool(struct rcu_head *rcu) +@@ -3341,7 +3346,7 @@ static void rcu_free_pool(struct rcu_hea * put_unbound_pool - put a worker_pool * @pool: worker_pool to put * @@ -219,7 +216,7 @@ index 08bc551976b2..7ed3b49267a8 100644 * safe manner. get_unbound_pool() calls this function on its failure path * and this function should be able to release pools which went through, * successfully or not, init_worker_pool(). -@@ -3338,8 +3343,8 @@ static void put_unbound_pool(struct worker_pool *pool) +@@ -3395,8 +3400,8 @@ static void put_unbound_pool(struct work del_timer_sync(&pool->idle_timer); del_timer_sync(&pool->mayday_timer); @@ -230,7 +227,7 @@ index 08bc551976b2..7ed3b49267a8 100644 } /** -@@ -3446,14 +3451,14 @@ static void pwq_unbound_release_workfn(struct work_struct *work) +@@ -3503,14 +3508,14 @@ static void pwq_unbound_release_workfn(s put_unbound_pool(pool); mutex_unlock(&wq_pool_mutex); @@ -247,7 +244,7 @@ index 08bc551976b2..7ed3b49267a8 100644 } /** -@@ -4128,7 +4133,7 @@ void destroy_workqueue(struct workqueue_struct *wq) +@@ -4195,7 +4200,7 @@ void destroy_workqueue(struct workqueue_ * The base ref is never dropped on per-cpu pwqs. Directly * schedule RCU free. */ @@ -256,7 +253,7 @@ index 08bc551976b2..7ed3b49267a8 100644 } else { /* * We're the sole accessor of @wq at this point. Directly -@@ -4238,7 +4243,8 @@ bool workqueue_congested(int cpu, struct workqueue_struct *wq) +@@ -4305,7 +4310,8 @@ bool workqueue_congested(int cpu, struct struct pool_workqueue *pwq; bool ret; @@ -266,7 +263,7 @@ index 08bc551976b2..7ed3b49267a8 100644 if (cpu == WORK_CPU_UNBOUND) cpu = smp_processor_id(); -@@ -4249,7 +4255,8 @@ bool workqueue_congested(int cpu, struct workqueue_struct *wq) +@@ -4316,7 +4322,8 @@ bool workqueue_congested(int cpu, struct pwq = unbound_pwq_by_node(wq, cpu_to_node(cpu)); ret = !list_empty(&pwq->delayed_works); @@ -276,7 +273,7 @@ index 08bc551976b2..7ed3b49267a8 100644 return ret; } -@@ -4275,15 +4282,15 @@ unsigned int work_busy(struct work_struct *work) +@@ -4342,15 +4349,15 @@ unsigned int work_busy(struct work_struc if (work_pending(work)) ret |= WORK_BUSY_PENDING; @@ -296,7 +293,7 @@ index 08bc551976b2..7ed3b49267a8 100644 return ret; } -@@ -4472,7 +4479,7 @@ void show_workqueue_state(void) +@@ -4534,7 +4541,7 @@ void show_workqueue_state(void) unsigned long flags; int pi; @@ -305,7 +302,7 @@ index 08bc551976b2..7ed3b49267a8 100644 pr_info("Showing busy workqueues and worker pools:\n"); -@@ -4537,7 +4544,7 @@ void show_workqueue_state(void) +@@ -4599,7 +4606,7 @@ void show_workqueue_state(void) touch_nmi_watchdog(); } @@ -313,8 +310,8 @@ index 08bc551976b2..7ed3b49267a8 100644 + rcu_read_unlock(); } - /* -@@ -4898,16 +4905,16 @@ bool freeze_workqueues_busy(void) + /* used to show worker information through /proc/PID/{comm,stat,status} */ +@@ -4986,16 +4993,16 @@ bool freeze_workqueues_busy(void) * nr_active is monotonically decreasing. It's safe * to peek without lock. */ @@ -334,7 +331,7 @@ index 08bc551976b2..7ed3b49267a8 100644 } out_unlock: mutex_unlock(&wq_pool_mutex); -@@ -5097,7 +5104,8 @@ static ssize_t wq_pool_ids_show(struct device *dev, +@@ -5190,7 +5197,8 @@ static ssize_t wq_pool_ids_show(struct d const char *delim = ""; int node, written = 0; @@ -344,7 +341,7 @@ index 08bc551976b2..7ed3b49267a8 100644 for_each_node(node) { written += scnprintf(buf + written, PAGE_SIZE - written, "%s%d:%d", delim, node, -@@ -5105,7 +5113,8 @@ static ssize_t wq_pool_ids_show(struct device *dev, +@@ -5198,7 +5206,8 @@ static ssize_t wq_pool_ids_show(struct d delim = " "; } written += scnprintf(buf + written, PAGE_SIZE - written, "\n"); @@ -354,6 +351,3 @@ index 08bc551976b2..7ed3b49267a8 100644 return written; } --- -2.19.2 - diff --git a/kernel/patches-4.14.x-rt/0307-workqueue-Use-local-irq-lock-instead-of-irq-disable-.patch b/kernel/patches-4.19.x-rt/0194-workqueue-use-locallock.patch similarity index 68% rename from kernel/patches-4.14.x-rt/0307-workqueue-Use-local-irq-lock-instead-of-irq-disable-.patch rename to kernel/patches-4.19.x-rt/0194-workqueue-use-locallock.patch index cabc3d169..9b21c6d4c 100644 --- a/kernel/patches-4.14.x-rt/0307-workqueue-Use-local-irq-lock-instead-of-irq-disable-.patch +++ b/kernel/patches-4.19.x-rt/0194-workqueue-use-locallock.patch @@ -1,30 +1,26 @@ -From 2077501f424bee3e44c9796c85083ba395b2f85f Mon Sep 17 00:00:00 2001 +Subject: workqueue: Use local irq lock instead of irq disable regions From: Thomas Gleixner Date: Sun, 17 Jul 2011 21:42:26 +0200 -Subject: [PATCH 307/450] workqueue: Use local irq lock instead of irq disable - regions Use a local_irq_lock as a replacement for irq off regions. We keep the semantic of irq-off in regard to the pool->lock and remain preemptible. Signed-off-by: Thomas Gleixner --- - kernel/workqueue.c | 36 ++++++++++++++++++++++-------------- - 1 file changed, 22 insertions(+), 14 deletions(-) + kernel/workqueue.c | 45 ++++++++++++++++++++++++++++++--------------- + 1 file changed, 30 insertions(+), 15 deletions(-) -diff --git a/kernel/workqueue.c b/kernel/workqueue.c -index 7ed3b49267a8..b798d32af3fd 100644 --- a/kernel/workqueue.c +++ b/kernel/workqueue.c @@ -49,6 +49,7 @@ - #include #include + #include #include +#include #include "workqueue_internal.h" -@@ -352,6 +353,8 @@ EXPORT_SYMBOL_GPL(system_power_efficient_wq); +@@ -350,6 +351,8 @@ EXPORT_SYMBOL_GPL(system_power_efficient struct workqueue_struct *system_freezable_power_efficient_wq __read_mostly; EXPORT_SYMBOL_GPL(system_freezable_power_efficient_wq); @@ -33,7 +29,7 @@ index 7ed3b49267a8..b798d32af3fd 100644 static int worker_thread(void *__worker); static void workqueue_sysfs_unregister(struct workqueue_struct *wq); -@@ -1105,9 +1108,11 @@ static void put_pwq_unlocked(struct pool_workqueue *pwq) +@@ -1103,9 +1106,11 @@ static void put_pwq_unlocked(struct pool * As both pwqs and pools are RCU protected, the * following lock operations are safe. */ @@ -47,7 +43,7 @@ index 7ed3b49267a8..b798d32af3fd 100644 } } -@@ -1211,7 +1216,7 @@ static int try_to_grab_pending(struct work_struct *work, bool is_dwork, +@@ -1209,7 +1214,7 @@ static int try_to_grab_pending(struct wo struct worker_pool *pool; struct pool_workqueue *pwq; @@ -56,7 +52,7 @@ index 7ed3b49267a8..b798d32af3fd 100644 /* try to steal the timer if it exists */ if (is_dwork) { -@@ -1275,7 +1280,7 @@ static int try_to_grab_pending(struct work_struct *work, bool is_dwork, +@@ -1273,7 +1278,7 @@ static int try_to_grab_pending(struct wo spin_unlock(&pool->lock); fail: rcu_read_unlock(); @@ -65,16 +61,21 @@ index 7ed3b49267a8..b798d32af3fd 100644 if (work_is_canceling(work)) return -ENOENT; cpu_relax(); -@@ -1380,7 +1385,7 @@ static void __queue_work(int cpu, struct workqueue_struct *wq, +@@ -1378,7 +1383,13 @@ static void __queue_work(int cpu, struct * queued or lose PENDING. Grabbing PENDING and queueing should * happen with IRQ disabled. */ -- WARN_ON_ONCE(!irqs_disabled()); -+ WARN_ON_ONCE_NONRT(!irqs_disabled()); ++#ifndef CONFIG_PREEMPT_RT_FULL ++ /* ++ * nort: On RT the "interrupts-disabled" rule has been replaced with ++ * pendingb_lock. ++ */ + lockdep_assert_irqs_disabled(); ++#endif debug_work_activate(work); -@@ -1486,14 +1491,14 @@ bool queue_work_on(int cpu, struct workqueue_struct *wq, +@@ -1484,14 +1495,14 @@ bool queue_work_on(int cpu, struct workq bool ret = false; unsigned long flags; @@ -91,9 +92,9 @@ index 7ed3b49267a8..b798d32af3fd 100644 return ret; } EXPORT_SYMBOL(queue_work_on); -@@ -1502,8 +1507,11 @@ void delayed_work_timer_fn(unsigned long __data) +@@ -1500,8 +1511,11 @@ void delayed_work_timer_fn(struct timer_ { - struct delayed_work *dwork = (struct delayed_work *)__data; + struct delayed_work *dwork = from_timer(dwork, t, timer); + /* XXX */ + /* local_lock(pendingb_lock); */ @@ -103,7 +104,7 @@ index 7ed3b49267a8..b798d32af3fd 100644 } EXPORT_SYMBOL(delayed_work_timer_fn); -@@ -1559,14 +1567,14 @@ bool queue_delayed_work_on(int cpu, struct workqueue_struct *wq, +@@ -1556,14 +1570,14 @@ bool queue_delayed_work_on(int cpu, stru unsigned long flags; /* read the comment in __queue_work() */ @@ -120,7 +121,7 @@ index 7ed3b49267a8..b798d32af3fd 100644 return ret; } EXPORT_SYMBOL(queue_delayed_work_on); -@@ -1601,7 +1609,7 @@ bool mod_delayed_work_on(int cpu, struct workqueue_struct *wq, +@@ -1598,7 +1612,7 @@ bool mod_delayed_work_on(int cpu, struct if (likely(ret >= 0)) { __queue_delayed_work(cpu, wq, dwork, delay); @@ -129,7 +130,22 @@ index 7ed3b49267a8..b798d32af3fd 100644 } /* -ENOENT from try_to_grab_pending() becomes %true */ -@@ -2951,7 +2959,7 @@ static bool __cancel_work_timer(struct work_struct *work, bool is_dwork) +@@ -1609,11 +1623,12 @@ EXPORT_SYMBOL_GPL(mod_delayed_work_on); + static void rcu_work_rcufn(struct rcu_head *rcu) + { + struct rcu_work *rwork = container_of(rcu, struct rcu_work, rcu); ++ unsigned long flags; + + /* read the comment in __queue_work() */ +- local_irq_disable(); ++ local_lock_irqsave(pendingb_lock, flags); + __queue_work(WORK_CPU_UNBOUND, rwork->wq, &rwork->work); +- local_irq_enable(); ++ local_unlock_irqrestore(pendingb_lock, flags); + } + + /** +@@ -2999,7 +3014,7 @@ static bool __cancel_work_timer(struct w /* tell other tasks trying to grab @work to back off */ mark_work_canceling(work); @@ -138,7 +154,7 @@ index 7ed3b49267a8..b798d32af3fd 100644 /* * This allows canceling during early boot. We know that @work -@@ -3012,10 +3020,10 @@ EXPORT_SYMBOL_GPL(cancel_work_sync); +@@ -3060,10 +3075,10 @@ EXPORT_SYMBOL_GPL(cancel_work_sync); */ bool flush_delayed_work(struct delayed_work *dwork) { @@ -151,7 +167,7 @@ index 7ed3b49267a8..b798d32af3fd 100644 return flush_work(&dwork->work); } EXPORT_SYMBOL(flush_delayed_work); -@@ -3033,7 +3041,7 @@ static bool __cancel_work(struct work_struct *work, bool is_dwork) +@@ -3101,7 +3116,7 @@ static bool __cancel_work(struct work_st return false; set_work_pool_and_clear_pending(work, get_work_pool_id(work)); @@ -160,6 +176,3 @@ index 7ed3b49267a8..b798d32af3fd 100644 return ret; } --- -2.19.2 - diff --git a/kernel/patches-4.14.x-rt/0308-workqueue-Prevent-workqueue-versus-ata-piix-livelock.patch b/kernel/patches-4.19.x-rt/0195-work-queue-work-around-irqsafe-timer-optimization.patch similarity index 92% rename from kernel/patches-4.14.x-rt/0308-workqueue-Prevent-workqueue-versus-ata-piix-livelock.patch rename to kernel/patches-4.19.x-rt/0195-work-queue-work-around-irqsafe-timer-optimization.patch index a027ce37d..42a5e3745 100644 --- a/kernel/patches-4.14.x-rt/0308-workqueue-Prevent-workqueue-versus-ata-piix-livelock.patch +++ b/kernel/patches-4.19.x-rt/0195-work-queue-work-around-irqsafe-timer-optimization.patch @@ -1,7 +1,6 @@ -From f01d9be16d6f9f10226fdfe059747e3234a58827 Mon Sep 17 00:00:00 2001 From: Thomas Gleixner -Date: Mon, 1 Jul 2013 11:02:42 +0200 -Subject: [PATCH 308/450] workqueue: Prevent workqueue versus ata-piix livelock +Date: Mon, 01 Jul 2013 11:02:42 +0200 +Subject: workqueue: Prevent workqueue versus ata-piix livelock An Intel i7 system regularly detected rcu_preempt stalls after the kernel was upgraded from 3.6-rt to 3.8-rt. When the stall happened, disk I/O was no @@ -109,22 +108,20 @@ Signed-off-by: Carsten Emde Signed-off-by: Thomas Gleixner Signed-off-by: Sebastian Andrzej Siewior --- - kernel/workqueue.c | 3 ++- + kernel/workqueue.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) -diff --git a/kernel/workqueue.c b/kernel/workqueue.c -index b798d32af3fd..a222bed39623 100644 --- a/kernel/workqueue.c +++ b/kernel/workqueue.c @@ -50,6 +50,7 @@ - #include + #include #include #include +#include #include "workqueue_internal.h" -@@ -1283,7 +1284,7 @@ static int try_to_grab_pending(struct work_struct *work, bool is_dwork, +@@ -1281,7 +1282,7 @@ static int try_to_grab_pending(struct wo local_unlock_irqrestore(pendingb_lock, *flags); if (work_is_canceling(work)) return -ENOENT; @@ -133,6 +130,3 @@ index b798d32af3fd..a222bed39623 100644 return -EAGAIN; } --- -2.19.2 - diff --git a/kernel/patches-4.14.x-rt/0309-sched-Distangle-worker-accounting-from-rqlock.patch b/kernel/patches-4.19.x-rt/0196-workqueue-distangle-from-rq-lock.patch similarity index 81% rename from kernel/patches-4.14.x-rt/0309-sched-Distangle-worker-accounting-from-rqlock.patch rename to kernel/patches-4.19.x-rt/0196-workqueue-distangle-from-rq-lock.patch index 29d78ab58..1d916c0b9 100644 --- a/kernel/patches-4.14.x-rt/0309-sched-Distangle-worker-accounting-from-rqlock.patch +++ b/kernel/patches-4.19.x-rt/0196-workqueue-distangle-from-rq-lock.patch @@ -1,13 +1,12 @@ -From 658a6d6a81af4d03fff5e502932460e169becf3f Mon Sep 17 00:00:00 2001 From: Thomas Gleixner -Date: Wed, 22 Jun 2011 19:47:03 +0200 -Subject: [PATCH 309/450] sched: Distangle worker accounting from rqlock - +Date: Wed Jun 22 19:47:03 2011 +0200 +Subject: sched: Distangle worker accounting from rqlock + The worker accounting for cpu bound workers is plugged into the core scheduler code and the wakeup code. This is not a hard requirement and can be avoided by keeping track of the state in the workqueue code itself. - + Keep track of the sleeping state in the worker itself and call the notifier before entering the core scheduler. There might be false positives when the task is woken between that call and actually @@ -15,7 +14,7 @@ scheduling, but that's not really different from scheduling and being woken immediately after switching away. There is also no harm from updating nr_running when the task returns from scheduling instead of accounting it in the wakeup code. - + Signed-off-by: Thomas Gleixner Cc: Peter Zijlstra Cc: Tejun Heo @@ -23,17 +22,18 @@ Cc: Jens Axboe Cc: Linus Torvalds Link: http://lkml.kernel.org/r/20110622174919.135236139@linutronix.de Signed-off-by: Thomas Gleixner +[bigeasy: preempt_disable() around wq_worker_sleeping() by Daniel Bristot de + Oliveira] +Signed-off-by: Sebastian Andrzej Siewior --- - kernel/sched/core.c | 84 +++++++------------------------------ - kernel/workqueue.c | 52 ++++++++++------------- - kernel/workqueue_internal.h | 5 ++- - 3 files changed, 41 insertions(+), 100 deletions(-) + kernel/sched/core.c | 90 ++++++++++---------------------------------- + kernel/workqueue.c | 52 +++++++++++-------------- + kernel/workqueue_internal.h | 5 +- + 3 files changed, 47 insertions(+), 100 deletions(-) -diff --git a/kernel/sched/core.c b/kernel/sched/core.c -index 44c22ff3e6fe..c304127bee78 100644 --- a/kernel/sched/core.c +++ b/kernel/sched/core.c -@@ -1733,10 +1733,6 @@ static inline void ttwu_activate(struct rq *rq, struct task_struct *p, int en_fl +@@ -1702,10 +1702,6 @@ static inline void ttwu_activate(struct { activate_task(rq, p, en_flags); p->on_rq = TASK_ON_RQ_QUEUED; @@ -44,11 +44,10 @@ index 44c22ff3e6fe..c304127bee78 100644 } /* -@@ -2176,56 +2172,6 @@ try_to_wake_up(struct task_struct *p, unsigned int state, int wake_flags) - return success; +@@ -2142,56 +2138,6 @@ try_to_wake_up(struct task_struct *p, un } --/** + /** - * try_to_wake_up_local - try to wake up a local task with rq lock held - * @p: the thread to be awakened - * @rf: request-queue flags for pinning @@ -98,10 +97,11 @@ index 44c22ff3e6fe..c304127bee78 100644 - raw_spin_unlock(&p->pi_lock); -} - - /** +-/** * wake_up_process - Wake up a specific process * @p: The process to be woken up. -@@ -3427,21 +3373,6 @@ static void __sched notrace __schedule(bool preempt) + * +@@ -3518,21 +3464,6 @@ static void __sched notrace __schedule(b atomic_inc(&rq->nr_iowait); delayacct_blkio_start(); } @@ -123,7 +123,7 @@ index 44c22ff3e6fe..c304127bee78 100644 } switch_count = &prev->nvcsw; } -@@ -3502,6 +3433,14 @@ static inline void sched_submit_work(struct task_struct *tsk) +@@ -3592,6 +3523,20 @@ static inline void sched_submit_work(str { if (!tsk->state || tsk_is_pi_blocked(tsk)) return; @@ -131,14 +131,20 @@ index 44c22ff3e6fe..c304127bee78 100644 + /* + * If a worker went to sleep, notify and ask workqueue whether + * it wants to wake up a task to maintain concurrency. ++ * As this function is called inside the schedule() context, ++ * we disable preemption to avoid it calling schedule() again ++ * in the possible wakeup of a kworker. + */ -+ if (tsk->flags & PF_WQ_WORKER) ++ if (tsk->flags & PF_WQ_WORKER) { ++ preempt_disable(); + wq_worker_sleeping(tsk); ++ preempt_enable_no_resched(); ++ } + /* * If we are going to sleep and we have plugged IO queued, * make sure to submit it to avoid deadlocks. -@@ -3510,6 +3449,12 @@ static inline void sched_submit_work(struct task_struct *tsk) +@@ -3600,6 +3545,12 @@ static inline void sched_submit_work(str blk_schedule_flush_plug(tsk); } @@ -151,7 +157,7 @@ index 44c22ff3e6fe..c304127bee78 100644 asmlinkage __visible void __sched schedule(void) { struct task_struct *tsk = current; -@@ -3520,6 +3465,7 @@ asmlinkage __visible void __sched schedule(void) +@@ -3610,6 +3561,7 @@ asmlinkage __visible void __sched schedu __schedule(false); sched_preempt_enable_no_resched(); } while (need_resched()); @@ -159,11 +165,9 @@ index 44c22ff3e6fe..c304127bee78 100644 } EXPORT_SYMBOL(schedule); -diff --git a/kernel/workqueue.c b/kernel/workqueue.c -index a222bed39623..c0b2a2e65d75 100644 --- a/kernel/workqueue.c +++ b/kernel/workqueue.c -@@ -845,43 +845,32 @@ static void wake_up_worker(struct worker_pool *pool) +@@ -843,43 +843,32 @@ static void wake_up_worker(struct worker } /** @@ -218,7 +222,7 @@ index a222bed39623..c0b2a2e65d75 100644 struct worker_pool *pool; /* -@@ -890,13 +879,15 @@ struct task_struct *wq_worker_sleeping(struct task_struct *task) +@@ -888,13 +877,15 @@ struct task_struct *wq_worker_sleeping(s * checking NOT_RUNNING. */ if (worker->flags & WORKER_NOT_RUNNING) @@ -238,7 +242,7 @@ index a222bed39623..c0b2a2e65d75 100644 /* * The counterpart of the following dec_and_test, implied mb, -@@ -910,9 +901,12 @@ struct task_struct *wq_worker_sleeping(struct task_struct *task) +@@ -908,9 +899,12 @@ struct task_struct *wq_worker_sleeping(s * lock is safe. */ if (atomic_dec_and_test(&pool->nr_running) && @@ -254,11 +258,9 @@ index a222bed39623..c0b2a2e65d75 100644 } /** -diff --git a/kernel/workqueue_internal.h b/kernel/workqueue_internal.h -index d390d1be3748..2dbcfe9bc364 100644 --- a/kernel/workqueue_internal.h +++ b/kernel/workqueue_internal.h -@@ -45,6 +45,7 @@ struct worker { +@@ -44,6 +44,7 @@ struct worker { unsigned long last_active; /* L: last active timestamp */ unsigned int flags; /* X: flags */ int id; /* I: worker id */ @@ -266,7 +268,7 @@ index d390d1be3748..2dbcfe9bc364 100644 /* * Opaque string set with work_set_desc(). Printed out with task -@@ -70,7 +71,7 @@ static inline struct worker *current_wq_worker(void) +@@ -69,7 +70,7 @@ static inline struct worker *current_wq_ * Scheduler hooks for concurrency managed workqueue. Only to be used from * sched/core.c and workqueue.c. */ @@ -276,6 +278,3 @@ index d390d1be3748..2dbcfe9bc364 100644 +void wq_worker_sleeping(struct task_struct *task); #endif /* _KERNEL_WORKQUEUE_INTERNAL_H */ --- -2.19.2 - diff --git a/kernel/patches-4.14.x-rt/0311-debugobjects-Make-RT-aware.patch b/kernel/patches-4.19.x-rt/0197-debugobjects-rt.patch similarity index 58% rename from kernel/patches-4.14.x-rt/0311-debugobjects-Make-RT-aware.patch rename to kernel/patches-4.19.x-rt/0197-debugobjects-rt.patch index 0e24ed928..767759b82 100644 --- a/kernel/patches-4.14.x-rt/0311-debugobjects-Make-RT-aware.patch +++ b/kernel/patches-4.19.x-rt/0197-debugobjects-rt.patch @@ -1,20 +1,17 @@ -From ff1fd4c04ee29a12cf2ef8a3395461f27c6f63fe Mon Sep 17 00:00:00 2001 +Subject: debugobjects: Make RT aware From: Thomas Gleixner Date: Sun, 17 Jul 2011 21:41:35 +0200 -Subject: [PATCH 311/450] debugobjects: Make RT aware Avoid filling the pool / allocating memory with irqs off(). Signed-off-by: Thomas Gleixner --- - lib/debugobjects.c | 5 ++++- + lib/debugobjects.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) -diff --git a/lib/debugobjects.c b/lib/debugobjects.c -index 99308479b1c8..161da6c6e173 100644 --- a/lib/debugobjects.c +++ b/lib/debugobjects.c -@@ -339,7 +339,10 @@ __debug_object_init(void *addr, struct debug_obj_descr *descr, int onstack) +@@ -376,7 +376,10 @@ static void struct debug_obj *obj; unsigned long flags; @@ -26,6 +23,3 @@ index 99308479b1c8..161da6c6e173 100644 db = get_bucket((unsigned long) addr); --- -2.19.2 - diff --git a/kernel/patches-4.14.x-rt/0313-seqlock-Prevent-rt-starvation.patch b/kernel/patches-4.19.x-rt/0198-seqlock-prevent-rt-starvation.patch similarity index 77% rename from kernel/patches-4.14.x-rt/0313-seqlock-Prevent-rt-starvation.patch rename to kernel/patches-4.19.x-rt/0198-seqlock-prevent-rt-starvation.patch index 1d56a4748..31779c079 100644 --- a/kernel/patches-4.14.x-rt/0313-seqlock-Prevent-rt-starvation.patch +++ b/kernel/patches-4.19.x-rt/0198-seqlock-prevent-rt-starvation.patch @@ -1,7 +1,6 @@ -From 031a7a902e23165e75d54bd19d84fd30d969624c Mon Sep 17 00:00:00 2001 +Subject: seqlock: Prevent rt starvation From: Thomas Gleixner Date: Wed, 22 Feb 2012 12:03:30 +0100 -Subject: [PATCH 313/450] seqlock: Prevent rt starvation If a low prio writer gets preempted while holding the seqlock write locked, a high prio reader spins forever on RT. @@ -19,16 +18,16 @@ Nicholas Mc Guire: - __write_seqcount_begin => __raw_write_seqcount_begin Signed-off-by: Thomas Gleixner ---- - include/linux/seqlock.h | 56 ++++++++++++++++++++++++++++++++--------- - include/net/neighbour.h | 6 ++--- - 2 files changed, 47 insertions(+), 15 deletions(-) -diff --git a/include/linux/seqlock.h b/include/linux/seqlock.h -index f189a8a3bbb8..e99de03f09ef 100644 + +--- + include/linux/seqlock.h | 57 +++++++++++++++++++++++++++++++++++++----------- + include/net/neighbour.h | 6 ++--- + 2 files changed, 48 insertions(+), 15 deletions(-) + --- a/include/linux/seqlock.h +++ b/include/linux/seqlock.h -@@ -221,20 +221,30 @@ static inline int read_seqcount_retry(const seqcount_t *s, unsigned start) +@@ -221,20 +221,30 @@ static inline int read_seqcount_retry(co return __read_seqcount_retry(s, start); } @@ -63,7 +62,7 @@ index f189a8a3bbb8..e99de03f09ef 100644 /** * raw_write_seqcount_barrier - do a seq write barrier * @s: pointer to seqcount_t -@@ -429,10 +439,32 @@ typedef struct { +@@ -428,10 +438,33 @@ typedef struct { /* * Read side functions for starting and finalizing a read side section. */ @@ -81,7 +80,7 @@ index f189a8a3bbb8..e99de03f09ef 100644 + unsigned ret; + +repeat: -+ ret = ACCESS_ONCE(sl->seqcount.sequence); ++ ret = READ_ONCE(sl->seqcount.sequence); + if (unlikely(ret & 1)) { + /* + * Take the lock and let the writer proceed (i.e. evtl @@ -90,13 +89,14 @@ index f189a8a3bbb8..e99de03f09ef 100644 + spin_unlock_wait(&sl->lock); + goto repeat; + } ++ smp_rmb(); + return ret; +} +#endif static inline unsigned read_seqretry(const seqlock_t *sl, unsigned start) { -@@ -447,36 +479,36 @@ static inline unsigned read_seqretry(const seqlock_t *sl, unsigned start) +@@ -446,36 +479,36 @@ static inline unsigned read_seqretry(con static inline void write_seqlock(seqlock_t *sl) { spin_lock(&sl->lock); @@ -139,7 +139,7 @@ index f189a8a3bbb8..e99de03f09ef 100644 spin_unlock_irq(&sl->lock); } -@@ -485,7 +517,7 @@ static inline unsigned long __write_seqlock_irqsave(seqlock_t *sl) +@@ -484,7 +517,7 @@ static inline unsigned long __write_seql unsigned long flags; spin_lock_irqsave(&sl->lock, flags); @@ -148,7 +148,7 @@ index f189a8a3bbb8..e99de03f09ef 100644 return flags; } -@@ -495,7 +527,7 @@ static inline unsigned long __write_seqlock_irqsave(seqlock_t *sl) +@@ -494,7 +527,7 @@ static inline unsigned long __write_seql static inline void write_sequnlock_irqrestore(seqlock_t *sl, unsigned long flags) { @@ -157,20 +157,18 @@ index f189a8a3bbb8..e99de03f09ef 100644 spin_unlock_irqrestore(&sl->lock, flags); } -diff --git a/include/net/neighbour.h b/include/net/neighbour.h -index a964366a7ef5..51c854583987 100644 --- a/include/net/neighbour.h +++ b/include/net/neighbour.h -@@ -450,7 +450,7 @@ static inline int neigh_hh_bridge(struct hh_cache *hh, struct sk_buff *skb) +@@ -451,7 +451,7 @@ static inline int neigh_hh_bridge(struct } #endif -static inline int neigh_hh_output(const struct hh_cache *hh, struct sk_buff *skb) +static inline int neigh_hh_output(struct hh_cache *hh, struct sk_buff *skb) { + unsigned int hh_alen = 0; unsigned int seq; - unsigned int hh_len; -@@ -474,7 +474,7 @@ static inline int neigh_hh_output(const struct hh_cache *hh, struct sk_buff *skb +@@ -493,7 +493,7 @@ static inline int neigh_hh_output(const static inline int neigh_output(struct neighbour *n, struct sk_buff *skb) { @@ -179,7 +177,7 @@ index a964366a7ef5..51c854583987 100644 if ((n->nud_state & NUD_CONNECTED) && hh->hh_len) return neigh_hh_output(hh, skb); -@@ -515,7 +515,7 @@ struct neighbour_cb { +@@ -534,7 +534,7 @@ struct neighbour_cb { #define NEIGH_CB(skb) ((struct neighbour_cb *)(skb)->cb) @@ -188,6 +186,3 @@ index a964366a7ef5..51c854583987 100644 const struct net_device *dev) { unsigned int seq; --- -2.19.2 - diff --git a/kernel/patches-4.14.x-rt/0314-sunrpc-Make-svc_xprt_do_enqueue-use-get_cpu_light.patch b/kernel/patches-4.19.x-rt/0199-sunrpc-make-svc_xprt_do_enqueue-use-get_cpu_light.patch similarity index 70% rename from kernel/patches-4.14.x-rt/0314-sunrpc-Make-svc_xprt_do_enqueue-use-get_cpu_light.patch rename to kernel/patches-4.19.x-rt/0199-sunrpc-make-svc_xprt_do_enqueue-use-get_cpu_light.patch index 8d10adc7e..d6980dc43 100644 --- a/kernel/patches-4.14.x-rt/0314-sunrpc-Make-svc_xprt_do_enqueue-use-get_cpu_light.patch +++ b/kernel/patches-4.19.x-rt/0199-sunrpc-make-svc_xprt_do_enqueue-use-get_cpu_light.patch @@ -1,8 +1,6 @@ -From f234a2ed83e2717ba6f33d8c22ba5f9172f47ddf Mon Sep 17 00:00:00 2001 From: Mike Galbraith Date: Wed, 18 Feb 2015 16:05:28 +0100 -Subject: [PATCH 314/450] sunrpc: Make svc_xprt_do_enqueue() use - get_cpu_light() +Subject: sunrpc: Make svc_xprt_do_enqueue() use get_cpu_light() |BUG: sleeping function called from invalid context at kernel/locking/rtmutex.c:915 |in_atomic(): 1, irqs_disabled(): 0, pid: 3194, name: rpc.nfsd @@ -30,40 +28,26 @@ Subject: [PATCH 314/450] sunrpc: Make svc_xprt_do_enqueue() use Signed-off-by: Mike Galbraith Signed-off-by: Sebastian Andrzej Siewior --- - net/sunrpc/svc_xprt.c | 6 +++--- - 1 file changed, 3 insertions(+), 3 deletions(-) + net/sunrpc/svc_xprt.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) -diff --git a/net/sunrpc/svc_xprt.c b/net/sunrpc/svc_xprt.c -index ea7b5a3a53f0..7d24cb5ea450 100644 --- a/net/sunrpc/svc_xprt.c +++ b/net/sunrpc/svc_xprt.c -@@ -396,7 +396,7 @@ void svc_xprt_do_enqueue(struct svc_xprt *xprt) - goto out; - } +@@ -393,7 +393,7 @@ void svc_xprt_do_enqueue(struct svc_xprt + if (test_and_set_bit(XPT_BUSY, &xprt->xpt_flags)) + return; - cpu = get_cpu(); + cpu = get_cpu_light(); pool = svc_pool_for_cpu(xprt->xpt_server, cpu); atomic_long_inc(&pool->sp_stats.packets); -@@ -432,7 +432,7 @@ void svc_xprt_do_enqueue(struct svc_xprt *xprt) - - atomic_long_inc(&pool->sp_stats.threads_woken); - wake_up_process(rqstp->rq_task); -- put_cpu(); -+ put_cpu_light(); - goto out; - } - rcu_read_unlock(); -@@ -453,7 +453,7 @@ void svc_xprt_do_enqueue(struct svc_xprt *xprt) - goto redo_search; - } +@@ -417,7 +417,7 @@ void svc_xprt_do_enqueue(struct svc_xprt rqstp = NULL; + out_unlock: + rcu_read_unlock(); - put_cpu(); + put_cpu_light(); - out: trace_svc_xprt_do_enqueue(xprt, rqstp); } --- -2.19.2 - + EXPORT_SYMBOL_GPL(svc_xprt_do_enqueue); diff --git a/kernel/patches-4.14.x-rt/0315-net-Use-skbufhead-with-raw-lock.patch b/kernel/patches-4.19.x-rt/0200-skbufhead-raw-lock.patch similarity index 69% rename from kernel/patches-4.14.x-rt/0315-net-Use-skbufhead-with-raw-lock.patch rename to kernel/patches-4.19.x-rt/0200-skbufhead-raw-lock.patch index b24cccfdb..6b4332cc2 100644 --- a/kernel/patches-4.14.x-rt/0315-net-Use-skbufhead-with-raw-lock.patch +++ b/kernel/patches-4.19.x-rt/0200-skbufhead-raw-lock.patch @@ -1,7 +1,6 @@ -From eb7077b932491031b0470d697306c842b256a424 Mon Sep 17 00:00:00 2001 From: Thomas Gleixner Date: Tue, 12 Jul 2011 15:38:34 +0200 -Subject: [PATCH 315/450] net: Use skbufhead with raw lock +Subject: net: Use skbufhead with raw lock Use the rps lock as rawlock so we can keep irq-off regions. It looks low latency. However we can't kfree() from this context therefore we defer this @@ -9,16 +8,14 @@ to the softirq and use the tofree_queue list for it (similar to process_queue). Signed-off-by: Thomas Gleixner --- - include/linux/netdevice.h | 1 + - include/linux/skbuff.h | 7 +++++++ - net/core/dev.c | 31 ++++++++++++++++++++++++------- - 3 files changed, 32 insertions(+), 7 deletions(-) + include/linux/netdevice.h | 1 + + include/linux/skbuff.h | 7 +++++++ + net/core/dev.c | 33 +++++++++++++++++++++++++-------- + 3 files changed, 33 insertions(+), 8 deletions(-) -diff --git a/include/linux/netdevice.h b/include/linux/netdevice.h -index a516dbe5869f..fd318a3b4fc1 100644 --- a/include/linux/netdevice.h +++ b/include/linux/netdevice.h -@@ -2799,6 +2799,7 @@ struct softnet_data { +@@ -2970,6 +2970,7 @@ struct softnet_data { unsigned int dropped; struct sk_buff_head input_pkt_queue; struct napi_struct backlog; @@ -26,8 +23,6 @@ index a516dbe5869f..fd318a3b4fc1 100644 }; -diff --git a/include/linux/skbuff.h b/include/linux/skbuff.h -index f6250555ce7d..e3d27db9d4ae 100644 --- a/include/linux/skbuff.h +++ b/include/linux/skbuff.h @@ -287,6 +287,7 @@ struct sk_buff_head { @@ -38,7 +33,7 @@ index f6250555ce7d..e3d27db9d4ae 100644 }; struct sk_buff; -@@ -1688,6 +1689,12 @@ static inline void skb_queue_head_init(struct sk_buff_head *list) +@@ -1702,6 +1703,12 @@ static inline void skb_queue_head_init(s __skb_queue_head_init(list); } @@ -51,11 +46,9 @@ index f6250555ce7d..e3d27db9d4ae 100644 static inline void skb_queue_head_init_class(struct sk_buff_head *list, struct lock_class_key *class) { -diff --git a/net/core/dev.c b/net/core/dev.c -index 8972786d17de..b26b1b82f680 100644 --- a/net/core/dev.c +++ b/net/core/dev.c -@@ -217,14 +217,14 @@ static inline struct hlist_head *dev_index_hash(struct net *net, int ifindex) +@@ -217,14 +217,14 @@ static inline struct hlist_head *dev_ind static inline void rps_lock(struct softnet_data *sd) { #ifdef CONFIG_RPS @@ -72,7 +65,7 @@ index 8972786d17de..b26b1b82f680 100644 #endif } -@@ -4630,7 +4630,7 @@ static void flush_backlog(struct work_struct *work) +@@ -5244,7 +5244,7 @@ static void flush_backlog(struct work_st skb_queue_walk_safe(&sd->input_pkt_queue, skb, tmp) { if (skb->dev->reg_state == NETREG_UNREGISTERING) { __skb_unlink(skb, &sd->input_pkt_queue); @@ -81,7 +74,7 @@ index 8972786d17de..b26b1b82f680 100644 input_queue_head_incr(sd); } } -@@ -4640,11 +4640,14 @@ static void flush_backlog(struct work_struct *work) +@@ -5254,11 +5254,14 @@ static void flush_backlog(struct work_st skb_queue_walk_safe(&sd->process_queue, skb, tmp) { if (skb->dev->reg_state == NETREG_UNREGISTERING) { __skb_unlink(skb, &sd->process_queue); @@ -97,7 +90,7 @@ index 8972786d17de..b26b1b82f680 100644 } static void flush_all_backlogs(void) -@@ -5195,7 +5198,9 @@ static int process_backlog(struct napi_struct *napi, int quota) +@@ -5837,7 +5840,9 @@ static int process_backlog(struct napi_s while (again) { struct sk_buff *skb; @@ -107,7 +100,7 @@ index 8972786d17de..b26b1b82f680 100644 rcu_read_lock(); __netif_receive_skb(skb); rcu_read_unlock(); -@@ -5203,9 +5208,9 @@ static int process_backlog(struct napi_struct *napi, int quota) +@@ -5845,9 +5850,9 @@ static int process_backlog(struct napi_s if (++work >= quota) return work; @@ -118,7 +111,7 @@ index 8972786d17de..b26b1b82f680 100644 rps_lock(sd); if (skb_queue_empty(&sd->input_pkt_queue)) { /* -@@ -5645,13 +5650,21 @@ static __latent_entropy void net_rx_action(struct softirq_action *h) +@@ -6312,13 +6317,21 @@ static __latent_entropy void net_rx_acti unsigned long time_limit = jiffies + usecs_to_jiffies(netdev_budget_usecs); int budget = netdev_budget; @@ -140,7 +133,12 @@ index 8972786d17de..b26b1b82f680 100644 for (;;) { struct napi_struct *n; -@@ -8468,6 +8481,9 @@ static int dev_cpu_dead(unsigned int oldcpu) +@@ -9307,10 +9320,13 @@ static int dev_cpu_dead(unsigned int old + netif_rx_ni(skb); + input_queue_head_incr(oldsd); + } +- while ((skb = skb_dequeue(&oldsd->input_pkt_queue))) { ++ while ((skb = __skb_dequeue(&oldsd->input_pkt_queue))) { netif_rx_ni(skb); input_queue_head_incr(oldsd); } @@ -150,7 +148,7 @@ index 8972786d17de..b26b1b82f680 100644 return 0; } -@@ -8771,8 +8787,9 @@ static int __init net_dev_init(void) +@@ -9619,8 +9635,9 @@ static int __init net_dev_init(void) INIT_WORK(flush, flush_backlog); @@ -159,9 +157,6 @@ index 8972786d17de..b26b1b82f680 100644 + skb_queue_head_init_raw(&sd->input_pkt_queue); + skb_queue_head_init_raw(&sd->process_queue); + skb_queue_head_init_raw(&sd->tofree_queue); - INIT_LIST_HEAD(&sd->poll_list); - sd->output_queue_tailp = &sd->output_queue; - #ifdef CONFIG_RPS --- -2.19.2 - + #ifdef CONFIG_XFRM_OFFLOAD + skb_queue_head_init(&sd->xfrm_backlog); + #endif diff --git a/kernel/patches-4.19.x-rt/0201-net-move-xmit_recursion-to-per-task-variable-on-RT.patch b/kernel/patches-4.19.x-rt/0201-net-move-xmit_recursion-to-per-task-variable-on-RT.patch new file mode 100644 index 000000000..4198f8399 --- /dev/null +++ b/kernel/patches-4.19.x-rt/0201-net-move-xmit_recursion-to-per-task-variable-on-RT.patch @@ -0,0 +1,265 @@ +From: Sebastian Andrzej Siewior +Date: Wed, 13 Jan 2016 15:55:02 +0100 +Subject: net: move xmit_recursion to per-task variable on -RT + +A softirq on -RT can be preempted. That means one task is in +__dev_queue_xmit(), gets preempted and another task may enter +__dev_queue_xmit() aw well. netperf together with a bridge device +will then trigger the `recursion alert` because each task increments +the xmit_recursion variable which is per-CPU. +A virtual device like br0 is required to trigger this warning. + +This patch moves the lock owner and counter to be per task instead per-CPU so +it counts the recursion properly on -RT. The owner is also a task now and not a +CPU number. + +Cc: stable-rt@vger.kernel.org +Signed-off-by: Sebastian Andrzej Siewior +--- + include/linux/netdevice.h | 95 ++++++++++++++++++++++++++++++++++++++++++---- + include/linux/sched.h | 3 + + net/core/dev.c | 15 ++++--- + net/core/filter.c | 6 +- + 4 files changed, 104 insertions(+), 15 deletions(-) + +--- a/include/linux/netdevice.h ++++ b/include/linux/netdevice.h +@@ -587,7 +587,11 @@ struct netdev_queue { + * write-mostly part + */ + spinlock_t _xmit_lock ____cacheline_aligned_in_smp; ++#ifdef CONFIG_PREEMPT_RT_FULL ++ struct task_struct *xmit_lock_owner; ++#else + int xmit_lock_owner; ++#endif + /* + * Time (in jiffies) of last Tx + */ +@@ -2608,14 +2612,53 @@ void netdev_freemem(struct net_device *d + void synchronize_net(void); + int init_dummy_netdev(struct net_device *dev); + +-DECLARE_PER_CPU(int, xmit_recursion); + #define XMIT_RECURSION_LIMIT 10 ++#ifdef CONFIG_PREEMPT_RT_FULL ++static inline int dev_recursion_level(void) ++{ ++ return current->xmit_recursion; ++} ++ ++static inline int xmit_rec_read(void) ++{ ++ return current->xmit_recursion; ++} ++ ++static inline void xmit_rec_inc(void) ++{ ++ current->xmit_recursion++; ++} ++ ++static inline void xmit_rec_dec(void) ++{ ++ current->xmit_recursion--; ++} ++ ++#else ++ ++DECLARE_PER_CPU(int, xmit_recursion); + + static inline int dev_recursion_level(void) + { + return this_cpu_read(xmit_recursion); + } + ++static inline int xmit_rec_read(void) ++{ ++ return __this_cpu_read(xmit_recursion); ++} ++ ++static inline void xmit_rec_inc(void) ++{ ++ __this_cpu_inc(xmit_recursion); ++} ++ ++static inline void xmit_rec_dec(void) ++{ ++ __this_cpu_dec(xmit_recursion); ++} ++#endif ++ + struct net_device *dev_get_by_index(struct net *net, int ifindex); + struct net_device *__dev_get_by_index(struct net *net, int ifindex); + struct net_device *dev_get_by_index_rcu(struct net *net, int ifindex); +@@ -3791,10 +3834,48 @@ static inline u32 netif_msg_init(int deb + return (1 << debug_value) - 1; + } + ++#ifdef CONFIG_PREEMPT_RT_FULL ++static inline void netdev_queue_set_owner(struct netdev_queue *txq, int cpu) ++{ ++ txq->xmit_lock_owner = current; ++} ++ ++static inline void netdev_queue_clear_owner(struct netdev_queue *txq) ++{ ++ txq->xmit_lock_owner = NULL; ++} ++ ++static inline bool netdev_queue_has_owner(struct netdev_queue *txq) ++{ ++ if (txq->xmit_lock_owner != NULL) ++ return true; ++ return false; ++} ++ ++#else ++ ++static inline void netdev_queue_set_owner(struct netdev_queue *txq, int cpu) ++{ ++ txq->xmit_lock_owner = cpu; ++} ++ ++static inline void netdev_queue_clear_owner(struct netdev_queue *txq) ++{ ++ txq->xmit_lock_owner = -1; ++} ++ ++static inline bool netdev_queue_has_owner(struct netdev_queue *txq) ++{ ++ if (txq->xmit_lock_owner != -1) ++ return true; ++ return false; ++} ++#endif ++ + static inline void __netif_tx_lock(struct netdev_queue *txq, int cpu) + { + spin_lock(&txq->_xmit_lock); +- txq->xmit_lock_owner = cpu; ++ netdev_queue_set_owner(txq, cpu); + } + + static inline bool __netif_tx_acquire(struct netdev_queue *txq) +@@ -3811,32 +3892,32 @@ static inline void __netif_tx_release(st + static inline void __netif_tx_lock_bh(struct netdev_queue *txq) + { + spin_lock_bh(&txq->_xmit_lock); +- txq->xmit_lock_owner = smp_processor_id(); ++ netdev_queue_set_owner(txq, smp_processor_id()); + } + + static inline bool __netif_tx_trylock(struct netdev_queue *txq) + { + bool ok = spin_trylock(&txq->_xmit_lock); + if (likely(ok)) +- txq->xmit_lock_owner = smp_processor_id(); ++ netdev_queue_set_owner(txq, smp_processor_id()); + return ok; + } + + static inline void __netif_tx_unlock(struct netdev_queue *txq) + { +- txq->xmit_lock_owner = -1; ++ netdev_queue_clear_owner(txq); + spin_unlock(&txq->_xmit_lock); + } + + static inline void __netif_tx_unlock_bh(struct netdev_queue *txq) + { +- txq->xmit_lock_owner = -1; ++ netdev_queue_clear_owner(txq); + spin_unlock_bh(&txq->_xmit_lock); + } + + static inline void txq_trans_update(struct netdev_queue *txq) + { +- if (txq->xmit_lock_owner != -1) ++ if (netdev_queue_has_owner(txq)) + txq->trans_start = jiffies; + } + +--- a/include/linux/sched.h ++++ b/include/linux/sched.h +@@ -1209,6 +1209,9 @@ struct task_struct { + #ifdef CONFIG_DEBUG_ATOMIC_SLEEP + unsigned long task_state_change; + #endif ++#ifdef CONFIG_PREEMPT_RT_FULL ++ int xmit_recursion; ++#endif + int pagefault_disabled; + #ifdef CONFIG_MMU + struct task_struct *oom_reaper_list; +--- a/net/core/dev.c ++++ b/net/core/dev.c +@@ -3523,8 +3523,10 @@ static void skb_update_prio(struct sk_bu + #define skb_update_prio(skb) + #endif + ++#ifndef CONFIG_PREEMPT_RT_FULL + DEFINE_PER_CPU(int, xmit_recursion); + EXPORT_SYMBOL(xmit_recursion); ++#endif + + /** + * dev_loopback_xmit - loop back @skb +@@ -3815,9 +3817,12 @@ static int __dev_queue_xmit(struct sk_bu + if (dev->flags & IFF_UP) { + int cpu = smp_processor_id(); /* ok because BHs are off */ + ++#ifdef CONFIG_PREEMPT_RT_FULL ++ if (txq->xmit_lock_owner != current) { ++#else + if (txq->xmit_lock_owner != cpu) { +- if (unlikely(__this_cpu_read(xmit_recursion) > +- XMIT_RECURSION_LIMIT)) ++#endif ++ if (unlikely(xmit_rec_read() > XMIT_RECURSION_LIMIT)) + goto recursion_alert; + + skb = validate_xmit_skb(skb, dev, &again); +@@ -3827,9 +3832,9 @@ static int __dev_queue_xmit(struct sk_bu + HARD_TX_LOCK(dev, txq, cpu); + + if (!netif_xmit_stopped(txq)) { +- __this_cpu_inc(xmit_recursion); ++ xmit_rec_inc(); + skb = dev_hard_start_xmit(skb, dev, txq, &rc); +- __this_cpu_dec(xmit_recursion); ++ xmit_rec_dec(); + if (dev_xmit_complete(rc)) { + HARD_TX_UNLOCK(dev, txq); + goto out; +@@ -8372,7 +8377,7 @@ static void netdev_init_one_queue(struct + /* Initialize queue lock */ + spin_lock_init(&queue->_xmit_lock); + netdev_set_xmit_lockdep_class(&queue->_xmit_lock, dev->type); +- queue->xmit_lock_owner = -1; ++ netdev_queue_clear_owner(queue); + netdev_queue_numa_node_write(queue, NUMA_NO_NODE); + queue->dev = dev; + #ifdef CONFIG_BQL +--- a/net/core/filter.c ++++ b/net/core/filter.c +@@ -2000,7 +2000,7 @@ static inline int __bpf_tx_skb(struct ne + { + int ret; + +- if (unlikely(__this_cpu_read(xmit_recursion) > XMIT_RECURSION_LIMIT)) { ++ if (unlikely(xmit_rec_read() > XMIT_RECURSION_LIMIT)) { + net_crit_ratelimited("bpf: recursion limit reached on datapath, buggy bpf program?\n"); + kfree_skb(skb); + return -ENETDOWN; +@@ -2008,9 +2008,9 @@ static inline int __bpf_tx_skb(struct ne + + skb->dev = dev; + +- __this_cpu_inc(xmit_recursion); ++ xmit_rec_inc(); + ret = dev_queue_xmit(skb); +- __this_cpu_dec(xmit_recursion); ++ xmit_rec_dec(); + + return ret; + } diff --git a/kernel/patches-4.14.x-rt/0319-net-provide-a-way-to-delegate-processing-a-softirq-t.patch b/kernel/patches-4.19.x-rt/0202-net-provide-a-way-to-delegate-processing-a-softirq-t.patch similarity index 71% rename from kernel/patches-4.14.x-rt/0319-net-provide-a-way-to-delegate-processing-a-softirq-t.patch rename to kernel/patches-4.19.x-rt/0202-net-provide-a-way-to-delegate-processing-a-softirq-t.patch index 9cca6e838..2a3057c42 100644 --- a/kernel/patches-4.14.x-rt/0319-net-provide-a-way-to-delegate-processing-a-softirq-t.patch +++ b/kernel/patches-4.19.x-rt/0202-net-provide-a-way-to-delegate-processing-a-softirq-t.patch @@ -1,8 +1,7 @@ -From b6f4517055f64f0afefa8fd3c16340334709b6eb Mon Sep 17 00:00:00 2001 From: Sebastian Andrzej Siewior Date: Wed, 20 Jan 2016 15:39:05 +0100 -Subject: [PATCH 319/450] net: provide a way to delegate processing a softirq - to ksoftirqd +Subject: net: provide a way to delegate processing a softirq to + ksoftirqd If the NET_RX uses up all of his budget it moves the following NAPI invocations into the `ksoftirqd`. On -RT it does not do so. Instead it @@ -14,16 +13,14 @@ __raise_softirq_irqoff_ksoft() which raises the softirq in the ksoftird. Cc: stable-rt@vger.kernel.org Signed-off-by: Sebastian Andrzej Siewior --- - include/linux/interrupt.h | 8 ++++++++ - kernel/softirq.c | 21 +++++++++++++++++++++ - net/core/dev.c | 2 +- + include/linux/interrupt.h | 8 ++++++++ + kernel/softirq.c | 21 +++++++++++++++++++++ + net/core/dev.c | 2 +- 3 files changed, 30 insertions(+), 1 deletion(-) -diff --git a/include/linux/interrupt.h b/include/linux/interrupt.h -index 326af722c5ee..0f25fa19b2d8 100644 --- a/include/linux/interrupt.h +++ b/include/linux/interrupt.h -@@ -519,6 +519,14 @@ extern void thread_do_softirq(void); +@@ -524,6 +524,14 @@ extern void thread_do_softirq(void); extern void open_softirq(int nr, void (*action)(struct softirq_action *)); extern void softirq_init(void); extern void __raise_softirq_irqoff(unsigned int nr); @@ -38,15 +35,12 @@ index 326af722c5ee..0f25fa19b2d8 100644 extern void raise_softirq_irqoff(unsigned int nr); extern void raise_softirq(unsigned int nr); -diff --git a/kernel/softirq.c b/kernel/softirq.c -index da87715b10be..e3f89bcef432 100644 --- a/kernel/softirq.c +++ b/kernel/softirq.c -@@ -689,6 +689,27 @@ void __raise_softirq_irqoff(unsigned int nr) - wakeup_proper_softirq(nr); +@@ -722,6 +722,27 @@ void __raise_softirq_irqoff(unsigned int } -+/* + /* + * Same as __raise_softirq_irqoff() but will process them in ksoftirqd + */ +void __raise_softirq_irqoff_ksoft(unsigned int nr) @@ -67,14 +61,13 @@ index da87715b10be..e3f89bcef432 100644 + wakeup_proper_softirq(nr); +} + - /* ++/* * This function must run with irqs disabled! */ -diff --git a/net/core/dev.c b/net/core/dev.c -index 8d35a35d99a0..b5f1f2c51297 100644 + void raise_softirq_irqoff(unsigned int nr) --- a/net/core/dev.c +++ b/net/core/dev.c -@@ -5699,7 +5699,7 @@ static __latent_entropy void net_rx_action(struct softirq_action *h) +@@ -6366,7 +6366,7 @@ static __latent_entropy void net_rx_acti list_splice_tail(&repoll, &list); list_splice(&list, &sd->poll_list); if (!list_empty(&sd->poll_list)) @@ -83,6 +76,3 @@ index 8d35a35d99a0..b5f1f2c51297 100644 net_rps_action_and_irq_enable(sd); out: --- -2.19.2 - diff --git a/kernel/patches-4.14.x-rt/0320-net-dev-always-take-qdisc-s-busylock-in-__dev_xmit_s.patch b/kernel/patches-4.19.x-rt/0203-net-dev-always-take-qdisc-s-busylock-in-__dev_xmit_s.patch similarity index 74% rename from kernel/patches-4.14.x-rt/0320-net-dev-always-take-qdisc-s-busylock-in-__dev_xmit_s.patch rename to kernel/patches-4.19.x-rt/0203-net-dev-always-take-qdisc-s-busylock-in-__dev_xmit_s.patch index 9a4005cdc..954ae4287 100644 --- a/kernel/patches-4.14.x-rt/0320-net-dev-always-take-qdisc-s-busylock-in-__dev_xmit_s.patch +++ b/kernel/patches-4.19.x-rt/0203-net-dev-always-take-qdisc-s-busylock-in-__dev_xmit_s.patch @@ -1,8 +1,6 @@ -From 955191c007edaf54336e0134d4f19f96ece44d8a Mon Sep 17 00:00:00 2001 From: Sebastian Andrzej Siewior Date: Wed, 30 Mar 2016 13:36:29 +0200 -Subject: [PATCH 320/450] net: dev: always take qdisc's busylock in - __dev_xmit_skb() +Subject: [PATCH] net: dev: always take qdisc's busylock in __dev_xmit_skb() The root-lock is dropped before dev_hard_start_xmit() is invoked and after setting the __QDISC___STATE_RUNNING bit. If this task is now pushed away @@ -17,14 +15,12 @@ low-prio task and submit the packet. Signed-off-by: Sebastian Andrzej Siewior --- - net/core/dev.c | 4 ++++ + net/core/dev.c | 4 ++++ 1 file changed, 4 insertions(+) -diff --git a/net/core/dev.c b/net/core/dev.c -index b5f1f2c51297..0b2abcfce03a 100644 --- a/net/core/dev.c +++ b/net/core/dev.c -@@ -3199,7 +3199,11 @@ static inline int __dev_xmit_skb(struct sk_buff *skb, struct Qdisc *q, +@@ -3451,7 +3451,11 @@ static inline int __dev_xmit_skb(struct * This permits qdisc->running owner to get the lock more * often and dequeue packets faster. */ @@ -36,6 +32,3 @@ index b5f1f2c51297..0b2abcfce03a 100644 if (unlikely(contended)) spin_lock(&q->busylock); --- -2.19.2 - diff --git a/kernel/patches-4.14.x-rt/0321-net-Qdisc-use-a-seqlock-instead-seqcount.patch b/kernel/patches-4.19.x-rt/0204-net-Qdisc-use-a-seqlock-instead-seqcount.patch similarity index 69% rename from kernel/patches-4.14.x-rt/0321-net-Qdisc-use-a-seqlock-instead-seqcount.patch rename to kernel/patches-4.19.x-rt/0204-net-Qdisc-use-a-seqlock-instead-seqcount.patch index e570c22a2..4922bfa18 100644 --- a/kernel/patches-4.14.x-rt/0321-net-Qdisc-use-a-seqlock-instead-seqcount.patch +++ b/kernel/patches-4.19.x-rt/0204-net-Qdisc-use-a-seqlock-instead-seqcount.patch @@ -1,7 +1,6 @@ -From ffd70bea069b587528d5136ff594181e0ba1f75f Mon Sep 17 00:00:00 2001 From: Sebastian Andrzej Siewior Date: Wed, 14 Sep 2016 17:36:35 +0200 -Subject: [PATCH 321/450] net/Qdisc: use a seqlock instead seqcount +Subject: [PATCH] net/Qdisc: use a seqlock instead seqcount The seqcount disables preemption on -RT while it is held which can't remove. Also we don't want the reader to spin for ages if the writer is @@ -10,22 +9,20 @@ the lock while writer is active. Signed-off-by: Sebastian Andrzej Siewior --- - include/linux/seqlock.h | 9 +++++++++ - include/net/gen_stats.h | 9 +++++---- - include/net/net_seq_lock.h | 15 +++++++++++++++ - include/net/sch_generic.h | 21 ++++++++++++++++++--- - net/core/gen_estimator.c | 6 +++--- - net/core/gen_stats.c | 8 ++++---- - net/sched/sch_api.c | 2 +- - net/sched/sch_generic.c | 12 ++++++++++++ - 8 files changed, 67 insertions(+), 15 deletions(-) + include/linux/seqlock.h | 9 +++++++++ + include/net/gen_stats.h | 9 +++++---- + include/net/net_seq_lock.h | 15 +++++++++++++++ + include/net/sch_generic.h | 19 +++++++++++++++++-- + net/core/gen_estimator.c | 6 +++--- + net/core/gen_stats.c | 8 ++++---- + net/sched/sch_api.c | 2 +- + net/sched/sch_generic.c | 12 ++++++++++++ + 8 files changed, 66 insertions(+), 14 deletions(-) create mode 100644 include/net/net_seq_lock.h -diff --git a/include/linux/seqlock.h b/include/linux/seqlock.h -index e99de03f09ef..a59751276b94 100644 --- a/include/linux/seqlock.h +++ b/include/linux/seqlock.h -@@ -482,6 +482,15 @@ static inline void write_seqlock(seqlock_t *sl) +@@ -482,6 +482,15 @@ static inline void write_seqlock(seqlock __raw_write_seqcount_begin(&sl->seqcount); } @@ -41,8 +38,6 @@ index e99de03f09ef..a59751276b94 100644 static inline void write_sequnlock(seqlock_t *sl) { __raw_write_seqcount_end(&sl->seqcount); -diff --git a/include/net/gen_stats.h b/include/net/gen_stats.h -index 304f7aa9cc01..00d3813cef26 100644 --- a/include/net/gen_stats.h +++ b/include/net/gen_stats.h @@ -6,6 +6,7 @@ @@ -53,7 +48,7 @@ index 304f7aa9cc01..00d3813cef26 100644 struct gnet_stats_basic_cpu { struct gnet_stats_basic_packed bstats; -@@ -36,11 +37,11 @@ int gnet_stats_start_copy_compat(struct sk_buff *skb, int type, +@@ -36,11 +37,11 @@ int gnet_stats_start_copy_compat(struct spinlock_t *lock, struct gnet_dump *d, int padattr); @@ -67,25 +62,22 @@ index 304f7aa9cc01..00d3813cef26 100644 struct gnet_stats_basic_packed *bstats, struct gnet_stats_basic_cpu __percpu *cpu, struct gnet_stats_basic_packed *b); -@@ -57,13 +58,13 @@ int gen_new_estimator(struct gnet_stats_basic_packed *bstats, +@@ -60,13 +61,13 @@ int gen_new_estimator(struct gnet_stats_ struct gnet_stats_basic_cpu __percpu *cpu_bstats, struct net_rate_estimator __rcu **rate_est, - spinlock_t *stats_lock, + spinlock_t *lock, - seqcount_t *running, struct nlattr *opt); + net_seqlock_t *running, struct nlattr *opt); void gen_kill_estimator(struct net_rate_estimator __rcu **ptr); int gen_replace_estimator(struct gnet_stats_basic_packed *bstats, struct gnet_stats_basic_cpu __percpu *cpu_bstats, struct net_rate_estimator __rcu **ptr, - spinlock_t *stats_lock, + spinlock_t *lock, - seqcount_t *running, struct nlattr *opt); + net_seqlock_t *running, struct nlattr *opt); bool gen_estimator_active(struct net_rate_estimator __rcu **ptr); bool gen_estimator_read(struct net_rate_estimator __rcu **ptr, struct gnet_stats_rate_est64 *sample); -diff --git a/include/net/net_seq_lock.h b/include/net/net_seq_lock.h -new file mode 100644 -index 000000000000..a7034298a82a --- /dev/null +++ b/include/net/net_seq_lock.h @@ -0,0 +1,15 @@ @@ -104,8 +96,6 @@ index 000000000000..a7034298a82a +#endif + +#endif -diff --git a/include/net/sch_generic.h b/include/net/sch_generic.h -index f59acacaa265..6ac7c3659973 100644 --- a/include/net/sch_generic.h +++ b/include/net/sch_generic.h @@ -10,6 +10,7 @@ @@ -116,8 +106,8 @@ index f59acacaa265..6ac7c3659973 100644 #include #include #include -@@ -90,7 +91,7 @@ struct Qdisc { - struct sk_buff *gso_skb ____cacheline_aligned_in_smp; +@@ -97,7 +98,7 @@ struct Qdisc { + struct sk_buff_head gso_skb ____cacheline_aligned_in_smp; struct qdisc_skb_head q; struct gnet_stats_basic_packed bstats; - seqcount_t running; @@ -125,13 +115,10 @@ index f59acacaa265..6ac7c3659973 100644 struct gnet_stats_queue qstats; unsigned long state; struct Qdisc *next_sched; -@@ -109,13 +110,22 @@ static inline void qdisc_refcount_inc(struct Qdisc *qdisc) - refcount_inc(&qdisc->refcnt); - } - --static inline bool qdisc_is_running(const struct Qdisc *qdisc) -+static inline bool qdisc_is_running(struct Qdisc *qdisc) +@@ -118,7 +119,11 @@ static inline bool qdisc_is_running(stru { + if (qdisc->flags & TCQ_F_NOLOCK) + return spin_is_locked(&qdisc->seqlock); +#ifdef CONFIG_PREEMPT_RT_BASE + return spin_is_locked(&qdisc->running.lock) ? true : false; +#else @@ -140,16 +127,18 @@ index f59acacaa265..6ac7c3659973 100644 } static inline bool qdisc_run_begin(struct Qdisc *qdisc) - { +@@ -129,17 +134,27 @@ static inline bool qdisc_run_begin(struc + } else if (qdisc_is_running(qdisc)) { + return false; + } +#ifdef CONFIG_PREEMPT_RT_BASE + if (try_write_seqlock(&qdisc->running)) + return true; + return false; +#else - if (qdisc_is_running(qdisc)) - return false; /* Variant of write_seqcount_begin() telling lockdep a trylock -@@ -124,11 +134,16 @@ static inline bool qdisc_run_begin(struct Qdisc *qdisc) + * was attempted. + */ raw_write_seqcount_begin(&qdisc->running); seqcount_acquire(&qdisc->running.dep_map, 0, 1, _RET_IP_); return true; @@ -163,10 +152,10 @@ index f59acacaa265..6ac7c3659973 100644 +#else write_seqcount_end(&qdisc->running); +#endif + if (qdisc->flags & TCQ_F_NOLOCK) + spin_unlock(&qdisc->seqlock); } - - static inline bool qdisc_may_bulk(const struct Qdisc *qdisc) -@@ -337,7 +352,7 @@ static inline spinlock_t *qdisc_root_sleeping_lock(const struct Qdisc *qdisc) +@@ -458,7 +473,7 @@ static inline spinlock_t *qdisc_root_sle return qdisc_lock(root); } @@ -175,8 +164,6 @@ index f59acacaa265..6ac7c3659973 100644 { struct Qdisc *root = qdisc_root_sleeping(qdisc); -diff --git a/net/core/gen_estimator.c b/net/core/gen_estimator.c -index 7f980bd7426e..7250106015ef 100644 --- a/net/core/gen_estimator.c +++ b/net/core/gen_estimator.c @@ -46,7 +46,7 @@ @@ -188,29 +175,27 @@ index 7f980bd7426e..7250106015ef 100644 struct gnet_stats_basic_cpu __percpu *cpu_bstats; u8 ewma_log; u8 intvl_log; /* period : (250ms << intvl_log) */ -@@ -129,7 +129,7 @@ int gen_new_estimator(struct gnet_stats_basic_packed *bstats, +@@ -129,7 +129,7 @@ int gen_new_estimator(struct gnet_stats_ struct gnet_stats_basic_cpu __percpu *cpu_bstats, struct net_rate_estimator __rcu **rate_est, - spinlock_t *stats_lock, + spinlock_t *lock, - seqcount_t *running, + net_seqlock_t *running, struct nlattr *opt) { struct gnet_estimator *parm = nla_data(opt); -@@ -222,7 +222,7 @@ int gen_replace_estimator(struct gnet_stats_basic_packed *bstats, +@@ -227,7 +227,7 @@ int gen_replace_estimator(struct gnet_st struct gnet_stats_basic_cpu __percpu *cpu_bstats, struct net_rate_estimator __rcu **rate_est, - spinlock_t *stats_lock, + spinlock_t *lock, - seqcount_t *running, struct nlattr *opt) + net_seqlock_t *running, struct nlattr *opt) { return gen_new_estimator(bstats, cpu_bstats, rate_est, - stats_lock, running, opt); -diff --git a/net/core/gen_stats.c b/net/core/gen_stats.c -index 441c04adedba..07f9a6a1f8e4 100644 + lock, running, opt); --- a/net/core/gen_stats.c +++ b/net/core/gen_stats.c -@@ -142,7 +142,7 @@ __gnet_stats_copy_basic_cpu(struct gnet_stats_basic_packed *bstats, +@@ -142,7 +142,7 @@ static void } void @@ -219,7 +204,7 @@ index 441c04adedba..07f9a6a1f8e4 100644 struct gnet_stats_basic_packed *bstats, struct gnet_stats_basic_cpu __percpu *cpu, struct gnet_stats_basic_packed *b) -@@ -155,10 +155,10 @@ __gnet_stats_copy_basic(const seqcount_t *running, +@@ -155,10 +155,10 @@ void } do { if (running) @@ -241,24 +226,20 @@ index 441c04adedba..07f9a6a1f8e4 100644 struct gnet_dump *d, struct gnet_stats_basic_cpu __percpu *cpu, struct gnet_stats_basic_packed *b) -diff --git a/net/sched/sch_api.c b/net/sched/sch_api.c -index 7b4270987ac1..4a2f63501c02 100644 --- a/net/sched/sch_api.c +++ b/net/sched/sch_api.c -@@ -1081,7 +1081,7 @@ static struct Qdisc *qdisc_create(struct net_device *dev, - rcu_assign_pointer(sch->stab, stab); - } - if (tca[TCA_RATE]) { -- seqcount_t *running; -+ net_seqlock_t *running; +@@ -1166,7 +1166,7 @@ static struct Qdisc *qdisc_create(struct + rcu_assign_pointer(sch->stab, stab); + } + if (tca[TCA_RATE]) { +- seqcount_t *running; ++ net_seqlock_t *running; - err = -EOPNOTSUPP; - if (sch->flags & TCQ_F_MQROOT) -diff --git a/net/sched/sch_generic.c b/net/sched/sch_generic.c -index de0839491dd8..341f7895659c 100644 + err = -EOPNOTSUPP; + if (sch->flags & TCQ_F_MQROOT) { --- a/net/sched/sch_generic.c +++ b/net/sched/sch_generic.c -@@ -429,7 +429,11 @@ struct Qdisc noop_qdisc = { +@@ -570,7 +570,11 @@ struct Qdisc noop_qdisc = { .ops = &noop_qdisc_ops, .q.lock = __SPIN_LOCK_UNLOCKED(noop_qdisc.q.lock), .dev_queue = &noop_netdev_queue, @@ -270,7 +251,7 @@ index de0839491dd8..341f7895659c 100644 .busylock = __SPIN_LOCK_UNLOCKED(noop_qdisc.busylock), }; EXPORT_SYMBOL(noop_qdisc); -@@ -628,9 +632,17 @@ struct Qdisc *qdisc_alloc(struct netdev_queue *dev_queue, +@@ -860,9 +864,17 @@ struct Qdisc *qdisc_alloc(struct netdev_ lockdep_set_class(&sch->busylock, dev->qdisc_tx_busylock ?: &qdisc_tx_busylock); @@ -287,7 +268,4 @@ index de0839491dd8..341f7895659c 100644 +#endif sch->ops = ops; - sch->enqueue = ops->enqueue; --- -2.19.2 - + sch->flags = ops->static_flags; diff --git a/kernel/patches-4.14.x-rt/0322-net-add-back-the-missing-serialization-in-ip_send_un.patch b/kernel/patches-4.19.x-rt/0205-net-add-back-the-missing-serialization-in-ip_send_un.patch similarity index 74% rename from kernel/patches-4.14.x-rt/0322-net-add-back-the-missing-serialization-in-ip_send_un.patch rename to kernel/patches-4.19.x-rt/0205-net-add-back-the-missing-serialization-in-ip_send_un.patch index 8d618b9f7..1946d6dd8 100644 --- a/kernel/patches-4.14.x-rt/0322-net-add-back-the-missing-serialization-in-ip_send_un.patch +++ b/kernel/patches-4.19.x-rt/0205-net-add-back-the-missing-serialization-in-ip_send_un.patch @@ -1,7 +1,6 @@ -From 8b60687c87f5161e598d231c4e9c28a467a8e567 Mon Sep 17 00:00:00 2001 From: Sebastian Andrzej Siewior Date: Wed, 31 Aug 2016 17:21:56 +0200 -Subject: [PATCH 322/450] net: add back the missing serialization in +Subject: [PATCH] net: add back the missing serialization in ip_send_unicast_reply() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 @@ -38,11 +37,9 @@ This is brings back the old locks. Cc: stable-rt@vger.kernel.org Signed-off-by: Sebastian Andrzej Siewior --- - net/ipv4/tcp_ipv4.c | 6 ++++++ + net/ipv4/tcp_ipv4.c | 6 ++++++ 1 file changed, 6 insertions(+) -diff --git a/net/ipv4/tcp_ipv4.c b/net/ipv4/tcp_ipv4.c -index 31b34c0c2d5f..a08d68e97bdb 100644 --- a/net/ipv4/tcp_ipv4.c +++ b/net/ipv4/tcp_ipv4.c @@ -62,6 +62,7 @@ @@ -53,7 +50,7 @@ index 31b34c0c2d5f..a08d68e97bdb 100644 #include #include -@@ -580,6 +581,7 @@ void tcp_v4_send_check(struct sock *sk, struct sk_buff *skb) +@@ -634,6 +635,7 @@ void tcp_v4_send_check(struct sock *sk, } EXPORT_SYMBOL(tcp_v4_send_check); @@ -61,38 +58,35 @@ index 31b34c0c2d5f..a08d68e97bdb 100644 /* * This routine will send an RST to the other tcp. * -@@ -709,6 +711,7 @@ static void tcp_v4_send_reset(const struct sock *sk, struct sk_buff *skb) - +@@ -768,6 +770,7 @@ static void tcp_v4_send_reset(const stru arg.tos = ip_hdr(skb)->tos; arg.uid = sock_net_uid(net, sk && sk_fullsock(sk) ? sk : NULL); -+ local_lock(tcp_sk_lock); local_bh_disable(); - ip_send_unicast_reply(*this_cpu_ptr(net->ipv4.tcp_sk), - skb, &TCP_SKB_CB(skb)->header.h4.opt, -@@ -718,6 +721,7 @@ static void tcp_v4_send_reset(const struct sock *sk, struct sk_buff *skb) ++ local_lock(tcp_sk_lock); + ctl_sk = *this_cpu_ptr(net->ipv4.tcp_sk); + if (sk) + ctl_sk->sk_mark = (sk->sk_state == TCP_TIME_WAIT) ? +@@ -780,6 +783,7 @@ static void tcp_v4_send_reset(const stru + ctl_sk->sk_mark = 0; __TCP_INC_STATS(net, TCP_MIB_OUTSEGS); __TCP_INC_STATS(net, TCP_MIB_OUTRSTS); - local_bh_enable(); + local_unlock(tcp_sk_lock); + local_bh_enable(); #ifdef CONFIG_TCP_MD5SIG - out: -@@ -795,6 +799,7 @@ static void tcp_v4_send_ack(const struct sock *sk, - arg.bound_dev_if = oif; +@@ -860,6 +864,7 @@ static void tcp_v4_send_ack(const struct arg.tos = tos; arg.uid = sock_net_uid(net, sk_fullsock(sk) ? sk : NULL); -+ local_lock(tcp_sk_lock); local_bh_disable(); - ip_send_unicast_reply(*this_cpu_ptr(net->ipv4.tcp_sk), - skb, &TCP_SKB_CB(skb)->header.h4.opt, -@@ -803,6 +808,7 @@ static void tcp_v4_send_ack(const struct sock *sk, ++ local_lock(tcp_sk_lock); + ctl_sk = *this_cpu_ptr(net->ipv4.tcp_sk); + if (sk) + ctl_sk->sk_mark = (sk->sk_state == TCP_TIME_WAIT) ? +@@ -871,6 +876,7 @@ static void tcp_v4_send_ack(const struct + ctl_sk->sk_mark = 0; __TCP_INC_STATS(net, TCP_MIB_OUTSEGS); - local_bh_enable(); + local_unlock(tcp_sk_lock); + local_bh_enable(); } - static void tcp_v4_timewait_ack(struct sock *sk, struct sk_buff *skb) --- -2.19.2 - diff --git a/kernel/patches-4.19.x-rt/0206-net-add-a-lock-around-icmp_sk.patch b/kernel/patches-4.19.x-rt/0206-net-add-a-lock-around-icmp_sk.patch new file mode 100644 index 000000000..a0774be74 --- /dev/null +++ b/kernel/patches-4.19.x-rt/0206-net-add-a-lock-around-icmp_sk.patch @@ -0,0 +1,58 @@ +From: Sebastian Andrzej Siewior +Date: Wed, 31 Aug 2016 17:54:09 +0200 +Subject: [PATCH] net: add a lock around icmp_sk() + +It looks like the this_cpu_ptr() access in icmp_sk() is protected with +local_bh_disable(). To avoid missing serialization in -RT I am adding +here a local lock. No crash has been observed, this is just precaution. + +Cc: stable-rt@vger.kernel.org +Signed-off-by: Sebastian Andrzej Siewior +--- + net/ipv4/icmp.c | 8 ++++++++ + 1 file changed, 8 insertions(+) + +--- a/net/ipv4/icmp.c ++++ b/net/ipv4/icmp.c +@@ -77,6 +77,7 @@ + #include + #include + #include ++#include + #include + #include + #include +@@ -204,6 +205,8 @@ static const struct icmp_control icmp_po + * + * On SMP we have one ICMP socket per-cpu. + */ ++static DEFINE_LOCAL_IRQ_LOCK(icmp_sk_lock); ++ + static struct sock *icmp_sk(struct net *net) + { + return *this_cpu_ptr(net->ipv4.icmp_sk); +@@ -214,12 +217,16 @@ static inline struct sock *icmp_xmit_loc + { + struct sock *sk; + ++ if (!local_trylock(icmp_sk_lock)) ++ return NULL; ++ + sk = icmp_sk(net); + + if (unlikely(!spin_trylock(&sk->sk_lock.slock))) { + /* This can happen if the output path signals a + * dst_link_failure() for an outgoing ICMP packet. + */ ++ local_unlock(icmp_sk_lock); + return NULL; + } + return sk; +@@ -228,6 +235,7 @@ static inline struct sock *icmp_xmit_loc + static inline void icmp_xmit_unlock(struct sock *sk) + { + spin_unlock(&sk->sk_lock.slock); ++ local_unlock(icmp_sk_lock); + } + + int sysctl_icmp_msgs_per_sec __read_mostly = 1000; diff --git a/kernel/patches-4.14.x-rt/0326-net-Have-__napi_schedule_irqoff-disable-interrupts-o.patch b/kernel/patches-4.19.x-rt/0207-net-Have-__napi_schedule_irqoff-disable-interrupts-o.patch similarity index 76% rename from kernel/patches-4.14.x-rt/0326-net-Have-__napi_schedule_irqoff-disable-interrupts-o.patch rename to kernel/patches-4.19.x-rt/0207-net-Have-__napi_schedule_irqoff-disable-interrupts-o.patch index 937420a08..0888d7d97 100644 --- a/kernel/patches-4.14.x-rt/0326-net-Have-__napi_schedule_irqoff-disable-interrupts-o.patch +++ b/kernel/patches-4.19.x-rt/0207-net-Have-__napi_schedule_irqoff-disable-interrupts-o.patch @@ -1,8 +1,7 @@ -From b15c950527882f5fb205a4aaabf11a32fcde90de Mon Sep 17 00:00:00 2001 From: Steven Rostedt Date: Tue, 6 Dec 2016 17:50:30 -0500 -Subject: [PATCH 326/450] net: Have __napi_schedule_irqoff() disable interrupts - on RT +Subject: [PATCH] net: Have __napi_schedule_irqoff() disable interrupts on + RT A customer hit a crash where the napi sd->poll_list became corrupted. The customer had the bnx2x driver, which does a @@ -23,15 +22,13 @@ Cc: stable-rt@vger.kernel.org Signed-off-by: Steven Rostedt (Red Hat) Signed-off-by: Sebastian Andrzej Siewior --- - include/linux/netdevice.h | 12 ++++++++++++ - net/core/dev.c | 2 ++ + include/linux/netdevice.h | 12 ++++++++++++ + net/core/dev.c | 2 ++ 2 files changed, 14 insertions(+) -diff --git a/include/linux/netdevice.h b/include/linux/netdevice.h -index 6b891e37d8e3..3ceccf72757e 100644 --- a/include/linux/netdevice.h +++ b/include/linux/netdevice.h -@@ -409,7 +409,19 @@ typedef enum rx_handler_result rx_handler_result_t; +@@ -422,7 +422,19 @@ typedef enum rx_handler_result rx_handle typedef rx_handler_result_t rx_handler_func_t(struct sk_buff **pskb); void __napi_schedule(struct napi_struct *n); @@ -51,11 +48,9 @@ index 6b891e37d8e3..3ceccf72757e 100644 static inline bool napi_disable_pending(struct napi_struct *n) { -diff --git a/net/core/dev.c b/net/core/dev.c -index 0b2abcfce03a..8f40b36c2ec3 100644 --- a/net/core/dev.c +++ b/net/core/dev.c -@@ -5294,6 +5294,7 @@ bool napi_schedule_prep(struct napi_struct *n) +@@ -5936,6 +5936,7 @@ bool napi_schedule_prep(struct napi_stru } EXPORT_SYMBOL(napi_schedule_prep); @@ -63,7 +58,7 @@ index 0b2abcfce03a..8f40b36c2ec3 100644 /** * __napi_schedule_irqoff - schedule for receive * @n: entry to schedule -@@ -5305,6 +5306,7 @@ void __napi_schedule_irqoff(struct napi_struct *n) +@@ -5947,6 +5948,7 @@ void __napi_schedule_irqoff(struct napi_ ____napi_schedule(this_cpu_ptr(&softnet_data), n); } EXPORT_SYMBOL(__napi_schedule_irqoff); @@ -71,6 +66,3 @@ index 0b2abcfce03a..8f40b36c2ec3 100644 bool napi_complete_done(struct napi_struct *n, int work_done) { --- -2.19.2 - diff --git a/kernel/patches-4.14.x-rt/0327-irqwork-push-most-work-into-softirq-context.patch b/kernel/patches-4.19.x-rt/0208-irqwork-push_most_work_into_softirq_context.patch similarity index 62% rename from kernel/patches-4.14.x-rt/0327-irqwork-push-most-work-into-softirq-context.patch rename to kernel/patches-4.19.x-rt/0208-irqwork-push_most_work_into_softirq_context.patch index f2c21fc5f..52c36c6d1 100644 --- a/kernel/patches-4.14.x-rt/0327-irqwork-push-most-work-into-softirq-context.patch +++ b/kernel/patches-4.19.x-rt/0208-irqwork-push_most_work_into_softirq_context.patch @@ -1,7 +1,6 @@ -From 38e63f2f170b11dc5d7d899f6f47987c9780d06c Mon Sep 17 00:00:00 2001 +Subject: irqwork: push most work into softirq context From: Sebastian Andrzej Siewior Date: Tue, 23 Jun 2015 15:32:51 +0200 -Subject: [PATCH 327/450] irqwork: push most work into softirq context Initially we defered all irqwork into softirq because we didn't want the latency spikes if perf or another user was busy and delayed the RT task. @@ -18,29 +17,40 @@ This patch incorporates tglx orignal work which revoked a little bringing back the arch_irq_work_raise() if possible and a few fixes from Steven Rostedt and Mike Galbraith, +[bigeasy: melt tglx's irq_work_tick_soft() which splits irq_work_tick() into a + hard and soft variant] Signed-off-by: Sebastian Andrzej Siewior --- - include/linux/irq_work.h | 1 + - kernel/irq_work.c | 47 +++++++++++++++++++++++++++++----------- - kernel/sched/topology.c | 1 + - kernel/time/tick-sched.c | 1 + - kernel/time/timer.c | 5 ++++- - 5 files changed, 41 insertions(+), 14 deletions(-) + include/linux/irq_work.h | 8 ++++++ + kernel/irq_work.c | 60 ++++++++++++++++++++++++++++++++++++----------- + kernel/rcu/tree.c | 1 + kernel/sched/topology.c | 1 + kernel/time/tick-sched.c | 1 + kernel/time/timer.c | 2 + + 6 files changed, 60 insertions(+), 13 deletions(-) -diff --git a/include/linux/irq_work.h b/include/linux/irq_work.h -index 9270d73ea682..929fb9091d16 100644 --- a/include/linux/irq_work.h +++ b/include/linux/irq_work.h -@@ -17,6 +17,7 @@ - #define IRQ_WORK_BUSY 2UL - #define IRQ_WORK_FLAGS 3UL - #define IRQ_WORK_LAZY 4UL /* Doesn't want IPI, wait for tick */ -+#define IRQ_WORK_HARD_IRQ 8UL /* Run hard IRQ context, even on RT */ +@@ -18,6 +18,8 @@ - struct irq_work { - unsigned long flags; -diff --git a/kernel/irq_work.c b/kernel/irq_work.c -index bcf107ce0854..0ddaf1e66d8c 100644 + /* Doesn't want IPI, wait for tick: */ + #define IRQ_WORK_LAZY BIT(2) ++/* Run hard IRQ context, even on RT */ ++#define IRQ_WORK_HARD_IRQ BIT(3) + + #define IRQ_WORK_CLAIMED (IRQ_WORK_PENDING | IRQ_WORK_BUSY) + +@@ -52,4 +54,10 @@ static inline bool irq_work_needs_cpu(vo + static inline void irq_work_run(void) { } + #endif + ++#if defined(CONFIG_IRQ_WORK) && defined(CONFIG_PREEMPT_RT_FULL) ++void irq_work_tick_soft(void); ++#else ++static inline void irq_work_tick_soft(void) { } ++#endif ++ + #endif /* _LINUX_IRQ_WORK_H */ --- a/kernel/irq_work.c +++ b/kernel/irq_work.c @@ -17,6 +17,7 @@ @@ -51,7 +61,7 @@ index bcf107ce0854..0ddaf1e66d8c 100644 #include -@@ -65,6 +66,8 @@ void __weak arch_irq_work_raise(void) +@@ -64,6 +65,8 @@ void __weak arch_irq_work_raise(void) */ bool irq_work_queue_on(struct irq_work *work, int cpu) { @@ -60,7 +70,7 @@ index bcf107ce0854..0ddaf1e66d8c 100644 /* All work should have been flushed before going offline */ WARN_ON_ONCE(cpu_is_offline(cpu)); -@@ -75,7 +78,12 @@ bool irq_work_queue_on(struct irq_work *work, int cpu) +@@ -76,7 +79,12 @@ bool irq_work_queue_on(struct irq_work * if (!irq_work_claim(work)) return false; @@ -73,8 +83,8 @@ index bcf107ce0854..0ddaf1e66d8c 100644 + if (llist_add(&work->llnode, list)) arch_send_call_function_single_ipi(cpu); - return true; -@@ -86,6 +94,9 @@ EXPORT_SYMBOL_GPL(irq_work_queue_on); + #else /* #ifdef CONFIG_SMP */ +@@ -89,6 +97,9 @@ bool irq_work_queue_on(struct irq_work * /* Enqueue the irq work @work on the current CPU */ bool irq_work_queue(struct irq_work *work) { @@ -84,7 +94,7 @@ index bcf107ce0854..0ddaf1e66d8c 100644 /* Only queue if not already pending */ if (!irq_work_claim(work)) return false; -@@ -93,13 +104,15 @@ bool irq_work_queue(struct irq_work *work) +@@ -96,13 +107,15 @@ bool irq_work_queue(struct irq_work *wor /* Queue the entry and raise the IPI if needed. */ preempt_disable(); @@ -107,7 +117,7 @@ index bcf107ce0854..0ddaf1e66d8c 100644 arch_irq_work_raise(); } -@@ -116,9 +129,8 @@ bool irq_work_needs_cpu(void) +@@ -119,9 +132,8 @@ bool irq_work_needs_cpu(void) raised = this_cpu_ptr(&raised_list); lazy = this_cpu_ptr(&lazy_list); @@ -119,16 +129,21 @@ index bcf107ce0854..0ddaf1e66d8c 100644 /* All work should have been flushed before going offline */ WARN_ON_ONCE(cpu_is_offline(smp_processor_id())); -@@ -132,7 +144,7 @@ static void irq_work_run_list(struct llist_head *list) - struct irq_work *work; +@@ -135,8 +147,12 @@ static void irq_work_run_list(struct lli struct llist_node *llnode; + unsigned long flags; -- BUG_ON(!irqs_disabled()); -+ BUG_ON_NONRT(!irqs_disabled()); - ++#ifndef CONFIG_PREEMPT_RT_FULL ++ /* ++ * nort: On RT IRQ-work may run in SOFTIRQ context. ++ */ + BUG_ON(!irqs_disabled()); +- ++#endif if (llist_empty(list)) return; -@@ -169,7 +181,16 @@ static void irq_work_run_list(struct llist_head *list) + +@@ -168,7 +184,16 @@ static void irq_work_run_list(struct lli void irq_work_run(void) { irq_work_run_list(this_cpu_ptr(&raised_list)); @@ -146,11 +161,37 @@ index bcf107ce0854..0ddaf1e66d8c 100644 } EXPORT_SYMBOL_GPL(irq_work_run); -diff --git a/kernel/sched/topology.c b/kernel/sched/topology.c -index 659e075ef70b..bb22e3620a90 100644 +@@ -178,8 +203,17 @@ void irq_work_tick(void) + + if (!llist_empty(raised) && !arch_irq_work_has_interrupt()) + irq_work_run_list(raised); ++ ++ if (!IS_ENABLED(CONFIG_PREEMPT_RT_FULL)) ++ irq_work_run_list(this_cpu_ptr(&lazy_list)); ++} ++ ++#if defined(CONFIG_IRQ_WORK) && defined(CONFIG_PREEMPT_RT_FULL) ++void irq_work_tick_soft(void) ++{ + irq_work_run_list(this_cpu_ptr(&lazy_list)); + } ++#endif + + /* + * Synchronize against the irq_work @entry, ensures the entry is not +--- a/kernel/rcu/tree.c ++++ b/kernel/rcu/tree.c +@@ -1296,6 +1296,7 @@ static int rcu_implicit_dynticks_qs(stru + !rdp->rcu_iw_pending && rdp->rcu_iw_gp_seq != rnp->gp_seq && + (rnp->ffmask & rdp->grpmask)) { + init_irq_work(&rdp->rcu_iw, rcu_iw_handler); ++ rdp->rcu_iw.flags = IRQ_WORK_HARD_IRQ; + rdp->rcu_iw_pending = true; + rdp->rcu_iw_gp_seq = rnp->gp_seq; + irq_work_queue_on(&rdp->rcu_iw, rdp->cpu); --- a/kernel/sched/topology.c +++ b/kernel/sched/topology.c -@@ -286,6 +286,7 @@ static int init_rootdomain(struct root_domain *rd) +@@ -279,6 +279,7 @@ static int init_rootdomain(struct root_d rd->rto_cpu = -1; raw_spin_lock_init(&rd->rto_lock); init_irq_work(&rd->rto_push_work, rto_push_irq_work_func); @@ -158,11 +199,9 @@ index 659e075ef70b..bb22e3620a90 100644 #endif init_dl_bw(&rd->dl_bw); -diff --git a/kernel/time/tick-sched.c b/kernel/time/tick-sched.c -index 92222682dfce..643b36a0b8e1 100644 --- a/kernel/time/tick-sched.c +++ b/kernel/time/tick-sched.c -@@ -230,6 +230,7 @@ static void nohz_full_kick_func(struct irq_work *work) +@@ -232,6 +232,7 @@ static void nohz_full_kick_func(struct i static DEFINE_PER_CPU(struct irq_work, nohz_full_kick_work) = { .func = nohz_full_kick_func, @@ -170,29 +209,14 @@ index 92222682dfce..643b36a0b8e1 100644 }; /* -diff --git a/kernel/time/timer.c b/kernel/time/timer.c -index 9b08190ff65a..2362b03051aa 100644 --- a/kernel/time/timer.c +++ b/kernel/time/timer.c -@@ -1638,7 +1638,7 @@ void update_process_times(int user_tick) - scheduler_tick(); - run_local_timers(); - rcu_check_callbacks(user_tick); --#ifdef CONFIG_IRQ_WORK -+#if defined(CONFIG_IRQ_WORK) && !defined(CONFIG_PREEMPT_RT_FULL) - if (in_irq()) - irq_work_tick(); - #endif -@@ -1695,6 +1695,9 @@ static __latent_entropy void run_timer_softirq(struct softirq_action *h) +@@ -1733,6 +1733,8 @@ static __latent_entropy void run_timer_s { struct timer_base *base = this_cpu_ptr(&timer_bases[BASE_STD]); -+#if defined(CONFIG_IRQ_WORK) && defined(CONFIG_PREEMPT_RT_FULL) -+ irq_work_tick(); -+#endif ++ irq_work_tick_soft(); ++ __run_timers(base); if (IS_ENABLED(CONFIG_NO_HZ_COMMON)) __run_timers(this_cpu_ptr(&timer_bases[BASE_DEF])); --- -2.19.2 - diff --git a/kernel/patches-4.14.x-rt/0330-printk-Make-rt-aware.patch b/kernel/patches-4.19.x-rt/0209-printk-rt-aware.patch similarity index 50% rename from kernel/patches-4.14.x-rt/0330-printk-Make-rt-aware.patch rename to kernel/patches-4.19.x-rt/0209-printk-rt-aware.patch index a2f568d26..7293dcf1a 100644 --- a/kernel/patches-4.14.x-rt/0330-printk-Make-rt-aware.patch +++ b/kernel/patches-4.19.x-rt/0209-printk-rt-aware.patch @@ -1,21 +1,42 @@ -From 39baf9e4fb2678d4d977ab5c833063a28814935d Mon Sep 17 00:00:00 2001 +Subject: printk: Make rt aware From: Thomas Gleixner Date: Wed, 19 Sep 2012 14:50:37 +0200 -Subject: [PATCH 330/450] printk: Make rt aware Drop the lock before calling the console driver and do not disable interrupts while printing to a serial console. Signed-off-by: Thomas Gleixner --- - kernel/printk/printk.c | 19 ++++++++++++++++++- - 1 file changed, 18 insertions(+), 1 deletion(-) + kernel/printk/printk.c | 33 ++++++++++++++++++++++++++++++--- + 1 file changed, 30 insertions(+), 3 deletions(-) -diff --git a/kernel/printk/printk.c b/kernel/printk/printk.c -index 9c946617baae..febac6df82d2 100644 --- a/kernel/printk/printk.c +++ b/kernel/printk/printk.c -@@ -1563,6 +1563,7 @@ static void call_console_drivers(const char *ext_text, size_t ext_len, +@@ -1617,6 +1617,7 @@ SYSCALL_DEFINE3(syslog, int, type, char + return do_syslog(type, buf, len, SYSLOG_FROM_READER); + } + ++#ifndef CONFIG_PREEMPT_RT_FULL + /* + * Special console_lock variants that help to reduce the risk of soft-lockups. + * They allow to pass console_lock to another printk() call using a busy wait. +@@ -1757,6 +1758,15 @@ static int console_trylock_spinning(void + return 1; + } + ++#else ++ ++static int console_trylock_spinning(void) ++{ ++ return console_trylock(); ++} ++ ++#endif ++ + /* + * Call the console drivers, asking them to write out + * log_buf[start] to log_buf[end - 1]. +@@ -1772,6 +1782,7 @@ static void call_console_drivers(const c if (!console_drivers) return; @@ -23,7 +44,7 @@ index 9c946617baae..febac6df82d2 100644 for_each_console(con) { if (exclusive_console && con != exclusive_console) continue; -@@ -1578,6 +1579,7 @@ static void call_console_drivers(const char *ext_text, size_t ext_len, +@@ -1787,6 +1798,7 @@ static void call_console_drivers(const c else con->write(con, text, len); } @@ -31,7 +52,7 @@ index 9c946617baae..febac6df82d2 100644 } int printk_delay_msec __read_mostly; -@@ -1762,6 +1764,16 @@ asmlinkage int vprintk_emit(int facility, int level, +@@ -1978,20 +1990,30 @@ asmlinkage int vprintk_emit(int facility /* If called from the scheduler, we can not call up(). */ if (!in_sched) { @@ -48,16 +69,24 @@ index 9c946617baae..febac6df82d2 100644 /* * Disable preemption to avoid being preempted while holding * console_sem which would prevent anyone from printing to -@@ -1773,7 +1785,7 @@ asmlinkage int vprintk_emit(int facility, int level, + * console + */ +- preempt_disable(); ++ migrate_disable(); + /* + * Try to acquire and then immediately release the console * semaphore. The release will print out buffers and wake up * /dev/kmsg and syslog() users. */ -- if (console_trylock()) -+ if (may_trylock && console_trylock()) +- if (console_trylock_spinning()) ++ if (may_trylock && console_trylock_spinning()) console_unlock(); - preempt_enable(); +- preempt_enable(); ++ migrate_enable(); } -@@ -2217,10 +2229,15 @@ void console_unlock(void) + + wake_up_klogd(); +@@ -2444,6 +2466,10 @@ void console_unlock(void) console_seq++; raw_spin_unlock(&logbuf_lock); @@ -65,14 +94,14 @@ index 9c946617baae..febac6df82d2 100644 + printk_safe_exit_irqrestore(flags); + call_console_drivers(ext_text, ext_len, text, len); +#else - stop_critical_timings(); /* don't trace print latency */ - call_console_drivers(ext_text, ext_len, text, len); - start_critical_timings(); + /* + * While actively printing out messages, if another printk() + * were to occur on another CPU, it may wait for this one to +@@ -2462,6 +2488,7 @@ void console_unlock(void) + } + printk_safe_exit_irqrestore(flags); +#endif if (do_cond_resched) cond_resched(); --- -2.19.2 - diff --git a/kernel/patches-4.14.x-rt/0331-kernel-printk-Don-t-try-to-print-from-IRQ-NMI-region.patch b/kernel/patches-4.19.x-rt/0210-kernel-printk-Don-t-try-to-print-from-IRQ-NMI-region.patch similarity index 68% rename from kernel/patches-4.14.x-rt/0331-kernel-printk-Don-t-try-to-print-from-IRQ-NMI-region.patch rename to kernel/patches-4.19.x-rt/0210-kernel-printk-Don-t-try-to-print-from-IRQ-NMI-region.patch index cdb5ae5bd..8b917b609 100644 --- a/kernel/patches-4.14.x-rt/0331-kernel-printk-Don-t-try-to-print-from-IRQ-NMI-region.patch +++ b/kernel/patches-4.19.x-rt/0210-kernel-printk-Don-t-try-to-print-from-IRQ-NMI-region.patch @@ -1,7 +1,6 @@ -From eb5db28c8bde4025a99c5ae984a59e27bee2c978 Mon Sep 17 00:00:00 2001 From: Sebastian Andrzej Siewior Date: Thu, 19 May 2016 17:45:27 +0200 -Subject: [PATCH 331/450] kernel/printk: Don't try to print from IRQ/NMI region +Subject: [PATCH] kernel/printk: Don't try to print from IRQ/NMI region On -RT we try to acquire sleeping locks which might lead to warnings from lockdep or a warn_on() from spin_try_lock() (which is a rtmutex on @@ -11,14 +10,12 @@ this via console_unblank() / bust_spinlocks() as well. Signed-off-by: Sebastian Andrzej Siewior --- - kernel/printk/printk.c | 10 ++++++++++ + kernel/printk/printk.c | 10 ++++++++++ 1 file changed, 10 insertions(+) -diff --git a/kernel/printk/printk.c b/kernel/printk/printk.c -index febac6df82d2..9b0deab74376 100644 --- a/kernel/printk/printk.c +++ b/kernel/printk/printk.c -@@ -1563,6 +1563,11 @@ static void call_console_drivers(const char *ext_text, size_t ext_len, +@@ -1782,6 +1782,11 @@ static void call_console_drivers(const c if (!console_drivers) return; @@ -30,7 +27,7 @@ index febac6df82d2..9b0deab74376 100644 migrate_disable(); for_each_console(con) { if (exclusive_console && con != exclusive_console) -@@ -2291,6 +2296,11 @@ void console_unblank(void) +@@ -2540,6 +2545,11 @@ void console_unblank(void) { struct console *c; @@ -42,6 +39,3 @@ index febac6df82d2..9b0deab74376 100644 /* * console_unblank can no longer be called in interrupt context unless * oops_in_progress is set to 1.. --- -2.19.2 - diff --git a/kernel/patches-4.19.x-rt/0211-HACK-printk-drop-the-logbuf_lock-more-often.patch b/kernel/patches-4.19.x-rt/0211-HACK-printk-drop-the-logbuf_lock-more-often.patch new file mode 100644 index 000000000..0e0148abb --- /dev/null +++ b/kernel/patches-4.19.x-rt/0211-HACK-printk-drop-the-logbuf_lock-more-often.patch @@ -0,0 +1,76 @@ +From: Sebastian Andrzej Siewior +Date: Thu, 21 Mar 2013 19:01:05 +0100 +Subject: printk: Drop the logbuf_lock more often + +The lock is hold with irgs off. The latency drops 500us+ on my arm bugs +with a "full" buffer after executing "dmesg" on the shell. + +Signed-off-by: Sebastian Andrzej Siewior +--- + kernel/printk/printk.c | 28 ++++++++++++++++++++++++++++ + 1 file changed, 28 insertions(+) + +--- a/kernel/printk/printk.c ++++ b/kernel/printk/printk.c +@@ -1420,12 +1420,23 @@ static int syslog_print_all(char __user + u64 next_seq; + u64 seq; + u32 idx; ++ int attempts = 0; ++ int num_msg; + + text = kmalloc(LOG_LINE_MAX + PREFIX_MAX, GFP_KERNEL); + if (!text) + return -ENOMEM; + + logbuf_lock_irq(); ++ ++try_again: ++ attempts++; ++ if (attempts > 10) { ++ len = -EBUSY; ++ goto out; ++ } ++ num_msg = 0; ++ + /* + * Find first record that fits, including all following records, + * into the user-provided buffer for this dump. +@@ -1438,6 +1449,14 @@ static int syslog_print_all(char __user + len += msg_print_text(msg, true, NULL, 0); + idx = log_next(idx); + seq++; ++ num_msg++; ++ if (num_msg > 5) { ++ num_msg = 0; ++ logbuf_unlock_irq(); ++ logbuf_lock_irq(); ++ if (clear_seq < log_first_seq) ++ goto try_again; ++ } + } + + /* move first record forward until length fits into the buffer */ +@@ -1449,6 +1468,14 @@ static int syslog_print_all(char __user + len -= msg_print_text(msg, true, NULL, 0); + idx = log_next(idx); + seq++; ++ num_msg++; ++ if (num_msg > 5) { ++ num_msg = 0; ++ logbuf_unlock_irq(); ++ logbuf_lock_irq(); ++ if (clear_seq < log_first_seq) ++ goto try_again; ++ } + } + + /* last message fitting into this dump */ +@@ -1486,6 +1513,7 @@ static int syslog_print_all(char __user + clear_seq = log_next_seq; + clear_idx = log_next_idx; + } ++out: + logbuf_unlock_irq(); + + kfree(text); diff --git a/kernel/patches-4.14.x-rt/0338-ARM-enable-irq-in-translation-section-permission-fau.patch b/kernel/patches-4.19.x-rt/0212-ARM-enable-irq-in-translation-section-permission-fau.patch similarity index 84% rename from kernel/patches-4.14.x-rt/0338-ARM-enable-irq-in-translation-section-permission-fau.patch rename to kernel/patches-4.19.x-rt/0212-ARM-enable-irq-in-translation-section-permission-fau.patch index 022ea66a7..e41d4889a 100644 --- a/kernel/patches-4.14.x-rt/0338-ARM-enable-irq-in-translation-section-permission-fau.patch +++ b/kernel/patches-4.19.x-rt/0212-ARM-enable-irq-in-translation-section-permission-fau.patch @@ -1,11 +1,6 @@ -From e595f5980764a8964b43d1b292a3b978bbf0d774 Mon Sep 17 00:00:00 2001 From: "Yadi.hu" Date: Wed, 10 Dec 2014 10:32:09 +0800 -Subject: [PATCH 338/450] ARM: enable irq in translation/section permission - fault handlers -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit +Subject: ARM: enable irq in translation/section permission fault handlers Probably happens on all ARM, with CONFIG_PREEMPT_RT_FULL @@ -63,14 +58,12 @@ permission exception. Signed-off-by: Yadi.hu Signed-off-by: Sebastian Andrzej Siewior --- - arch/arm/mm/fault.c | 6 ++++++ + arch/arm/mm/fault.c | 6 ++++++ 1 file changed, 6 insertions(+) -diff --git a/arch/arm/mm/fault.c b/arch/arm/mm/fault.c -index 49b1b8048635..b261967ea028 100644 --- a/arch/arm/mm/fault.c +++ b/arch/arm/mm/fault.c -@@ -437,6 +437,9 @@ do_translation_fault(unsigned long addr, unsigned int fsr, +@@ -439,6 +439,9 @@ do_translation_fault(unsigned long addr, if (addr < TASK_SIZE) return do_page_fault(addr, fsr, regs); @@ -80,7 +73,7 @@ index 49b1b8048635..b261967ea028 100644 if (user_mode(regs)) goto bad_area; -@@ -504,6 +507,9 @@ do_translation_fault(unsigned long addr, unsigned int fsr, +@@ -506,6 +509,9 @@ do_translation_fault(unsigned long addr, static int do_sect_fault(unsigned long addr, unsigned int fsr, struct pt_regs *regs) { @@ -90,6 +83,3 @@ index 49b1b8048635..b261967ea028 100644 do_bad_area(addr, fsr, regs); return 0; } --- -2.19.2 - diff --git a/kernel/patches-4.14.x-rt/0339-genirq-update-irq_set_irqchip_state-documentation.patch b/kernel/patches-4.19.x-rt/0213-genirq-update-irq_set_irqchip_state-documentation.patch similarity index 71% rename from kernel/patches-4.14.x-rt/0339-genirq-update-irq_set_irqchip_state-documentation.patch rename to kernel/patches-4.19.x-rt/0213-genirq-update-irq_set_irqchip_state-documentation.patch index 84413d1a6..a2f12d933 100644 --- a/kernel/patches-4.14.x-rt/0339-genirq-update-irq_set_irqchip_state-documentation.patch +++ b/kernel/patches-4.19.x-rt/0213-genirq-update-irq_set_irqchip_state-documentation.patch @@ -1,7 +1,6 @@ -From 10496b07541c3e46e56e399f85ff66022b78b153 Mon Sep 17 00:00:00 2001 From: Josh Cartwright Date: Thu, 11 Feb 2016 11:54:00 -0600 -Subject: [PATCH 339/450] genirq: update irq_set_irqchip_state documentation +Subject: genirq: update irq_set_irqchip_state documentation On -rt kernels, the use of migrate_disable()/migrate_enable() is sufficient to guarantee a task isn't moved to another CPU. Update the @@ -10,14 +9,12 @@ irq_set_irqchip_state() documentation to reflect this. Signed-off-by: Josh Cartwright Signed-off-by: Sebastian Andrzej Siewior --- - kernel/irq/manage.c | 2 +- + kernel/irq/manage.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) -diff --git a/kernel/irq/manage.c b/kernel/irq/manage.c -index d4d993c27ac0..400eca839bcc 100644 --- a/kernel/irq/manage.c +++ b/kernel/irq/manage.c -@@ -2213,7 +2213,7 @@ EXPORT_SYMBOL_GPL(irq_get_irqchip_state); +@@ -2274,7 +2274,7 @@ EXPORT_SYMBOL_GPL(irq_get_irqchip_state) * This call sets the internal irqchip state of an interrupt, * depending on the value of @which. * @@ -26,6 +23,3 @@ index d4d993c27ac0..400eca839bcc 100644 * interrupt controller has per-cpu registers. */ int irq_set_irqchip_state(unsigned int irq, enum irqchip_irq_state which, --- -2.19.2 - diff --git a/kernel/patches-4.14.x-rt/0340-KVM-arm-arm64-downgrade-preempt_disable-d-region-to-.patch b/kernel/patches-4.19.x-rt/0214-KVM-arm-arm64-downgrade-preempt_disable-d-region-to-.patch similarity index 64% rename from kernel/patches-4.14.x-rt/0340-KVM-arm-arm64-downgrade-preempt_disable-d-region-to-.patch rename to kernel/patches-4.19.x-rt/0214-KVM-arm-arm64-downgrade-preempt_disable-d-region-to-.patch index 800700a67..5a7896a1f 100644 --- a/kernel/patches-4.14.x-rt/0340-KVM-arm-arm64-downgrade-preempt_disable-d-region-to-.patch +++ b/kernel/patches-4.19.x-rt/0214-KVM-arm-arm64-downgrade-preempt_disable-d-region-to-.patch @@ -1,8 +1,6 @@ -From 1e13ef754a632ffc5908b83d70b67325ab4edee8 Mon Sep 17 00:00:00 2001 From: Josh Cartwright Date: Thu, 11 Feb 2016 11:54:01 -0600 -Subject: [PATCH 340/450] KVM: arm/arm64: downgrade preempt_disable()d region - to migrate_disable() +Subject: KVM: arm/arm64: downgrade preempt_disable()d region to migrate_disable() kvm_arch_vcpu_ioctl_run() disables the use of preemption when updating the vgic and timer states to prevent the calling task from migrating to @@ -19,14 +17,12 @@ Reported-by: Manish Jaggi Signed-off-by: Josh Cartwright Signed-off-by: Sebastian Andrzej Siewior --- - virt/kvm/arm/arm.c | 6 +++--- + virt/kvm/arm/arm.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) -diff --git a/virt/kvm/arm/arm.c b/virt/kvm/arm/arm.c -index 045aa39b14c1..bdf11f40ce34 100644 --- a/virt/kvm/arm/arm.c +++ b/virt/kvm/arm/arm.c -@@ -651,7 +651,7 @@ int kvm_arch_vcpu_ioctl_run(struct kvm_vcpu *vcpu, struct kvm_run *run) +@@ -699,7 +699,7 @@ int kvm_arch_vcpu_ioctl_run(struct kvm_v * involves poking the GIC, which must be done in a * non-preemptible context. */ @@ -35,24 +31,21 @@ index 045aa39b14c1..bdf11f40ce34 100644 kvm_pmu_flush_hwstate(vcpu); -@@ -688,7 +688,7 @@ int kvm_arch_vcpu_ioctl_run(struct kvm_vcpu *vcpu, struct kvm_run *run) - kvm_pmu_sync_hwstate(vcpu); - kvm_timer_sync_hwstate(vcpu); +@@ -748,7 +748,7 @@ int kvm_arch_vcpu_ioctl_run(struct kvm_v + kvm_timer_sync_hwstate(vcpu); kvm_vgic_sync_hwstate(vcpu); + local_irq_enable(); - preempt_enable(); + migrate_enable(); continue; } -@@ -743,7 +743,7 @@ int kvm_arch_vcpu_ioctl_run(struct kvm_vcpu *vcpu, struct kvm_run *run) - - kvm_vgic_sync_hwstate(vcpu); +@@ -826,7 +826,7 @@ int kvm_arch_vcpu_ioctl_run(struct kvm_v + /* Exit types that need handling before we can be preempted */ + handle_exit_early(vcpu, run, ret); - preempt_enable(); + migrate_enable(); ret = handle_exit(vcpu, run, ret); } --- -2.19.2 - diff --git a/kernel/patches-4.19.x-rt/0215-arm64-fpsimd-use-preemp_disable-in-addition-to-local.patch b/kernel/patches-4.19.x-rt/0215-arm64-fpsimd-use-preemp_disable-in-addition-to-local.patch new file mode 100644 index 000000000..9a6063b8e --- /dev/null +++ b/kernel/patches-4.19.x-rt/0215-arm64-fpsimd-use-preemp_disable-in-addition-to-local.patch @@ -0,0 +1,164 @@ +From: Sebastian Andrzej Siewior +Date: Wed, 25 Jul 2018 14:02:38 +0200 +Subject: [PATCH] arm64: fpsimd: use preemp_disable in addition to + local_bh_disable() + +In v4.16-RT I noticed a number of warnings from task_fpsimd_load(). The +code disables BH and expects that it is not preemptible. On -RT the +task remains preemptible but remains the same CPU. This may corrupt the +content of the SIMD registers if the task is preempted during +saving/restoring those registers. + +Add preempt_disable()/enable() to enfore the required semantic on -RT. + +Signed-off-by: Sebastian Andrzej Siewior +--- + arch/arm64/kernel/fpsimd.c | 31 +++++++++++++++++++++++++++++-- + 1 file changed, 29 insertions(+), 2 deletions(-) + +--- a/arch/arm64/kernel/fpsimd.c ++++ b/arch/arm64/kernel/fpsimd.c +@@ -159,6 +159,16 @@ static void sve_free(struct task_struct + __sve_free(task); + } + ++static void *sve_free_atomic(struct task_struct *task) ++{ ++ void *sve_state = task->thread.sve_state; ++ ++ WARN_ON(test_tsk_thread_flag(task, TIF_SVE)); ++ ++ task->thread.sve_state = NULL; ++ return sve_state; ++} ++ + /* + * TIF_SVE controls whether a task can use SVE without trapping while + * in userspace, and also the way a task's FPSIMD/SVE state is stored +@@ -547,6 +557,7 @@ int sve_set_vector_length(struct task_st + * non-SVE thread. + */ + if (task == current) { ++ preempt_disable(); + local_bh_disable(); + + fpsimd_save(); +@@ -557,8 +568,10 @@ int sve_set_vector_length(struct task_st + if (test_and_clear_tsk_thread_flag(task, TIF_SVE)) + sve_to_fpsimd(task); + +- if (task == current) ++ if (task == current) { + local_bh_enable(); ++ preempt_enable(); ++ } + + /* + * Force reallocation of task SVE state to the correct size +@@ -813,6 +826,7 @@ asmlinkage void do_sve_acc(unsigned int + + sve_alloc(current); + ++ preempt_disable(); + local_bh_disable(); + + fpsimd_save(); +@@ -826,6 +840,7 @@ asmlinkage void do_sve_acc(unsigned int + WARN_ON(1); /* SVE access shouldn't have trapped */ + + local_bh_enable(); ++ preempt_enable(); + } + + /* +@@ -892,10 +907,12 @@ void fpsimd_thread_switch(struct task_st + void fpsimd_flush_thread(void) + { + int vl, supported_vl; ++ void *mem = NULL; + + if (!system_supports_fpsimd()) + return; + ++ preempt_disable(); + local_bh_disable(); + + memset(¤t->thread.uw.fpsimd_state, 0, +@@ -904,7 +921,7 @@ void fpsimd_flush_thread(void) + + if (system_supports_sve()) { + clear_thread_flag(TIF_SVE); +- sve_free(current); ++ mem = sve_free_atomic(current); + + /* + * Reset the task vector length as required. +@@ -940,6 +957,8 @@ void fpsimd_flush_thread(void) + set_thread_flag(TIF_FOREIGN_FPSTATE); + + local_bh_enable(); ++ preempt_enable(); ++ kfree(mem); + } + + /* +@@ -951,9 +970,11 @@ void fpsimd_preserve_current_state(void) + if (!system_supports_fpsimd()) + return; + ++ preempt_disable(); + local_bh_disable(); + fpsimd_save(); + local_bh_enable(); ++ preempt_enable(); + } + + /* +@@ -1011,6 +1032,7 @@ void fpsimd_restore_current_state(void) + if (!system_supports_fpsimd()) + return; + ++ preempt_disable(); + local_bh_disable(); + + if (test_and_clear_thread_flag(TIF_FOREIGN_FPSTATE)) { +@@ -1019,6 +1041,7 @@ void fpsimd_restore_current_state(void) + } + + local_bh_enable(); ++ preempt_enable(); + } + + /* +@@ -1031,6 +1054,7 @@ void fpsimd_update_current_state(struct + if (!system_supports_fpsimd()) + return; + ++ preempt_disable(); + local_bh_disable(); + + current->thread.uw.fpsimd_state = *state; +@@ -1043,6 +1067,7 @@ void fpsimd_update_current_state(struct + clear_thread_flag(TIF_FOREIGN_FPSTATE); + + local_bh_enable(); ++ preempt_enable(); + } + + /* +@@ -1088,6 +1113,7 @@ void kernel_neon_begin(void) + + BUG_ON(!may_use_simd()); + ++ preempt_disable(); + local_bh_disable(); + + __this_cpu_write(kernel_neon_busy, true); +@@ -1101,6 +1127,7 @@ void kernel_neon_begin(void) + preempt_disable(); + + local_bh_enable(); ++ preempt_enable(); + } + EXPORT_SYMBOL(kernel_neon_begin); + diff --git a/kernel/patches-4.14.x-rt/0342-kgdb-serial-Short-term-workaround.patch b/kernel/patches-4.19.x-rt/0216-kgb-serial-hackaround.patch similarity index 69% rename from kernel/patches-4.14.x-rt/0342-kgdb-serial-Short-term-workaround.patch rename to kernel/patches-4.19.x-rt/0216-kgb-serial-hackaround.patch index 01fd9ac60..6794740ea 100644 --- a/kernel/patches-4.14.x-rt/0342-kgdb-serial-Short-term-workaround.patch +++ b/kernel/patches-4.19.x-rt/0216-kgb-serial-hackaround.patch @@ -1,7 +1,6 @@ -From 72ac596912e69a9196b10e55a7893aa790795328 Mon Sep 17 00:00:00 2001 From: Jason Wessel Date: Thu, 28 Jul 2011 12:42:23 -0500 -Subject: [PATCH 342/450] kgdb/serial: Short term workaround +Subject: kgdb/serial: Short term workaround On 07/27/2011 04:37 PM, Thomas Gleixner wrote: > - KGDB (not yet disabled) is reportedly unusable on -rt right now due @@ -17,17 +16,16 @@ change separation between the console and the HW to have a polled mode Thanks, Jason. + --- - drivers/tty/serial/8250/8250_port.c | 3 +++ - include/linux/kdb.h | 2 ++ - kernel/debug/kdb/kdb_io.c | 2 ++ + drivers/tty/serial/8250/8250_port.c | 3 +++ + include/linux/kdb.h | 2 ++ + kernel/debug/kdb/kdb_io.c | 2 ++ 3 files changed, 7 insertions(+) -diff --git a/drivers/tty/serial/8250/8250_port.c b/drivers/tty/serial/8250/8250_port.c -index c331434ce443..6e029f34f37f 100644 --- a/drivers/tty/serial/8250/8250_port.c +++ b/drivers/tty/serial/8250/8250_port.c -@@ -35,6 +35,7 @@ +@@ -31,6 +31,7 @@ #include #include #include @@ -35,7 +33,7 @@ index c331434ce443..6e029f34f37f 100644 #include #include #include -@@ -3226,6 +3227,8 @@ void serial8250_console_write(struct uart_8250_port *up, const char *s, +@@ -3241,6 +3242,8 @@ void serial8250_console_write(struct uar if (port->sysrq || oops_in_progress) locked = 0; @@ -44,11 +42,9 @@ index c331434ce443..6e029f34f37f 100644 else spin_lock_irqsave(&port->lock, flags); -diff --git a/include/linux/kdb.h b/include/linux/kdb.h -index 68bd88223417..e033b25b0b72 100644 --- a/include/linux/kdb.h +++ b/include/linux/kdb.h -@@ -167,6 +167,7 @@ extern __printf(2, 0) int vkdb_printf(enum kdb_msgsrc src, const char *fmt, +@@ -167,6 +167,7 @@ extern __printf(2, 0) int vkdb_printf(en extern __printf(1, 2) int kdb_printf(const char *, ...); typedef __printf(1, 2) int (*kdb_printf_t)(const char *, ...); @@ -56,7 +52,7 @@ index 68bd88223417..e033b25b0b72 100644 extern void kdb_init(int level); /* Access to kdb specific polling devices */ -@@ -201,6 +202,7 @@ extern int kdb_register_flags(char *, kdb_func_t, char *, char *, +@@ -201,6 +202,7 @@ extern int kdb_register_flags(char *, kd extern int kdb_unregister(char *); #else /* ! CONFIG_KGDB_KDB */ static inline __printf(1, 2) int kdb_printf(const char *fmt, ...) { return 0; } @@ -64,8 +60,6 @@ index 68bd88223417..e033b25b0b72 100644 static inline void kdb_init(int level) {} static inline int kdb_register(char *cmd, kdb_func_t func, char *usage, char *help, short minlen) { return 0; } -diff --git a/kernel/debug/kdb/kdb_io.c b/kernel/debug/kdb/kdb_io.c -index 6a4b41484afe..197cb422f6e1 100644 --- a/kernel/debug/kdb/kdb_io.c +++ b/kernel/debug/kdb/kdb_io.c @@ -857,9 +857,11 @@ int kdb_printf(const char *fmt, ...) @@ -80,6 +74,3 @@ index 6a4b41484afe..197cb422f6e1 100644 return r; } --- -2.19.2 - diff --git a/kernel/patches-4.14.x-rt/0343-sysfs-Add-sys-kernel-realtime-entry.patch b/kernel/patches-4.19.x-rt/0217-sysfs-realtime-entry.patch similarity index 73% rename from kernel/patches-4.14.x-rt/0343-sysfs-Add-sys-kernel-realtime-entry.patch rename to kernel/patches-4.19.x-rt/0217-sysfs-realtime-entry.patch index 3c7e14d03..85c90149d 100644 --- a/kernel/patches-4.14.x-rt/0343-sysfs-Add-sys-kernel-realtime-entry.patch +++ b/kernel/patches-4.19.x-rt/0217-sysfs-realtime-entry.patch @@ -1,7 +1,6 @@ -From 4b9a22a36e9791e67a615fe2e3ea774b42cf22ce Mon Sep 17 00:00:00 2001 +Subject: sysfs: Add /sys/kernel/realtime entry From: Clark Williams -Date: Sat, 30 Jul 2011 21:55:53 -0500 -Subject: [PATCH 343/450] sysfs: Add /sys/kernel/realtime entry +Date: Sat Jul 30 21:55:53 2011 -0500 Add a /sys/kernel entry to indicate that the kernel is a realtime kernel. @@ -15,11 +14,9 @@ Are there better solutions? Should it exist and return 0 on !-rt? Signed-off-by: Clark Williams Signed-off-by: Peter Zijlstra --- - kernel/ksysfs.c | 12 ++++++++++++ + kernel/ksysfs.c | 12 ++++++++++++ 1 file changed, 12 insertions(+) -diff --git a/kernel/ksysfs.c b/kernel/ksysfs.c -index 46ba853656f6..9a23632b6294 100644 --- a/kernel/ksysfs.c +++ b/kernel/ksysfs.c @@ -140,6 +140,15 @@ KERNEL_ATTR_RO(vmcoreinfo); @@ -38,16 +35,13 @@ index 46ba853656f6..9a23632b6294 100644 /* whether file capabilities are enabled */ static ssize_t fscaps_show(struct kobject *kobj, struct kobj_attribute *attr, char *buf) -@@ -230,6 +239,9 @@ static struct attribute * kernel_attrs[] = { - #ifndef CONFIG_TINY_RCU +@@ -231,6 +240,9 @@ static struct attribute * kernel_attrs[] &rcu_expedited_attr.attr, &rcu_normal_attr.attr, -+#endif + #endif +#ifdef CONFIG_PREEMPT_RT_FULL + &realtime_attr.attr, - #endif ++#endif NULL }; --- -2.19.2 - + diff --git a/kernel/patches-4.14.x-rt/0346-mm-rt-kmap_atomic-scheduling.patch b/kernel/patches-4.19.x-rt/0218-mm-rt-kmap-atomic-scheduling.patch similarity index 76% rename from kernel/patches-4.14.x-rt/0346-mm-rt-kmap_atomic-scheduling.patch rename to kernel/patches-4.19.x-rt/0218-mm-rt-kmap-atomic-scheduling.patch index f88e44397..0e5d34b6d 100644 --- a/kernel/patches-4.14.x-rt/0346-mm-rt-kmap_atomic-scheduling.patch +++ b/kernel/patches-4.19.x-rt/0218-mm-rt-kmap-atomic-scheduling.patch @@ -1,7 +1,6 @@ -From c86332002f578e056c2d18c61cd4c288e1108f93 Mon Sep 17 00:00:00 2001 +Subject: mm, rt: kmap_atomic scheduling From: Peter Zijlstra Date: Thu, 28 Jul 2011 10:43:51 +0200 -Subject: [PATCH 346/450] mm, rt: kmap_atomic scheduling In fact, with migrate_disable() existing one could play games with kmap_atomic. You could save/restore the kmap_atomic slots on context @@ -20,17 +19,15 @@ Link: http://lkml.kernel.org/r/1311842631.5890.208.camel@twins and the pte content right away in the task struct. Shortens the context switch code. ] --- - arch/x86/kernel/process_32.c | 32 ++++++++++++++++++++++++++++++++ - arch/x86/mm/highmem_32.c | 13 ++++++++++--- - arch/x86/mm/iomap_32.c | 9 ++++++++- - include/linux/highmem.h | 27 +++++++++++++++++++++++---- - include/linux/sched.h | 7 +++++++ - include/linux/uaccess.h | 2 ++ - mm/highmem.c | 6 ++++-- - 7 files changed, 86 insertions(+), 10 deletions(-) + arch/x86/kernel/process_32.c | 32 ++++++++++++++++++++++++++++++++ + arch/x86/mm/highmem_32.c | 13 ++++++++++--- + arch/x86/mm/iomap_32.c | 9 ++++++++- + include/linux/highmem.h | 31 +++++++++++++++++++++++++------ + include/linux/sched.h | 7 +++++++ + include/linux/uaccess.h | 2 ++ + mm/highmem.c | 6 ++++-- + 7 files changed, 88 insertions(+), 12 deletions(-) -diff --git a/arch/x86/kernel/process_32.c b/arch/x86/kernel/process_32.c -index c2df91eab573..f6f189399d94 100644 --- a/arch/x86/kernel/process_32.c +++ b/arch/x86/kernel/process_32.c @@ -38,6 +38,7 @@ @@ -41,7 +38,7 @@ index c2df91eab573..f6f189399d94 100644 #include #include -@@ -200,6 +201,35 @@ start_thread(struct pt_regs *regs, unsigned long new_ip, unsigned long new_sp) +@@ -198,6 +199,35 @@ start_thread(struct pt_regs *regs, unsig } EXPORT_SYMBOL_GPL(start_thread); @@ -77,7 +74,7 @@ index c2df91eab573..f6f189399d94 100644 /* * switch_to(x,y) should switch tasks from x to y. -@@ -269,6 +299,8 @@ __switch_to(struct task_struct *prev_p, struct task_struct *next_p) +@@ -267,6 +297,8 @@ EXPORT_SYMBOL_GPL(start_thread); switch_to_extra(prev_p, next_p); @@ -86,8 +83,6 @@ index c2df91eab573..f6f189399d94 100644 /* * Leave lazy mode, flushing any hypercalls made here. * This must be done before restoring TLS segments so -diff --git a/arch/x86/mm/highmem_32.c b/arch/x86/mm/highmem_32.c -index 6d18b70ed5a9..f752724c22e8 100644 --- a/arch/x86/mm/highmem_32.c +++ b/arch/x86/mm/highmem_32.c @@ -32,10 +32,11 @@ EXPORT_SYMBOL(kunmap); @@ -103,7 +98,7 @@ index 6d18b70ed5a9..f752724c22e8 100644 pagefault_disable(); if (!PageHighMem(page)) -@@ -45,7 +46,10 @@ void *kmap_atomic_prot(struct page *page, pgprot_t prot) +@@ -45,7 +46,10 @@ void *kmap_atomic_prot(struct page *page idx = type + KM_TYPE_NR*smp_processor_id(); vaddr = __fix_to_virt(FIX_KMAP_BEGIN + idx); BUG_ON(!pte_none(*(kmap_pte-idx))); @@ -134,11 +129,9 @@ index 6d18b70ed5a9..f752724c22e8 100644 } EXPORT_SYMBOL(__kunmap_atomic); -diff --git a/arch/x86/mm/iomap_32.c b/arch/x86/mm/iomap_32.c -index ada98b39b8ad..2620fb55ece1 100644 --- a/arch/x86/mm/iomap_32.c +++ b/arch/x86/mm/iomap_32.c -@@ -56,6 +56,7 @@ EXPORT_SYMBOL_GPL(iomap_free); +@@ -59,6 +59,7 @@ EXPORT_SYMBOL_GPL(iomap_free); void *kmap_atomic_prot_pfn(unsigned long pfn, pgprot_t prot) { @@ -146,7 +139,7 @@ index ada98b39b8ad..2620fb55ece1 100644 unsigned long vaddr; int idx, type; -@@ -65,7 +66,10 @@ void *kmap_atomic_prot_pfn(unsigned long pfn, pgprot_t prot) +@@ -68,7 +69,10 @@ void *kmap_atomic_prot_pfn(unsigned long type = kmap_atomic_idx_push(); idx = type + KM_TYPE_NR * smp_processor_id(); vaddr = __fix_to_virt(FIX_KMAP_BEGIN + idx); @@ -158,7 +151,7 @@ index ada98b39b8ad..2620fb55ece1 100644 arch_flush_lazy_mmu_mode(); return (void *)vaddr; -@@ -113,6 +117,9 @@ iounmap_atomic(void __iomem *kvaddr) +@@ -119,6 +123,9 @@ iounmap_atomic(void __iomem *kvaddr) * is a bad idea also, in case the page changes cacheability * attributes or becomes a protected page in a hypervisor. */ @@ -168,11 +161,27 @@ index ada98b39b8ad..2620fb55ece1 100644 kpte_clear_flush(kmap_pte-idx, vaddr); kmap_atomic_idx_pop(); } -diff --git a/include/linux/highmem.h b/include/linux/highmem.h -index 776f90f3a1cd..cfcd7b7ab205 100644 --- a/include/linux/highmem.h +++ b/include/linux/highmem.h -@@ -87,32 +87,51 @@ static inline void __kunmap_atomic(void *addr) +@@ -66,7 +66,7 @@ static inline void kunmap(struct page *p + + static inline void *kmap_atomic(struct page *page) + { +- preempt_disable(); ++ preempt_disable_nort(); + pagefault_disable(); + return page_address(page); + } +@@ -75,7 +75,7 @@ static inline void *kmap_atomic(struct p + static inline void __kunmap_atomic(void *addr) + { + pagefault_enable(); +- preempt_enable(); ++ preempt_enable_nort(); + } + + #define kmap_atomic_pfn(pfn) kmap_atomic(pfn_to_page(pfn)) +@@ -87,32 +87,51 @@ static inline void __kunmap_atomic(void #if defined(CONFIG_HIGHMEM) || defined(CONFIG_X86_32) @@ -228,19 +237,17 @@ index 776f90f3a1cd..cfcd7b7ab205 100644 #endif } -diff --git a/include/linux/sched.h b/include/linux/sched.h -index ff13666bc6dd..678b52680df3 100644 --- a/include/linux/sched.h +++ b/include/linux/sched.h -@@ -27,6 +27,7 @@ - #include +@@ -28,6 +28,7 @@ #include #include + #include +#include /* task_struct member predeclarations (sorted alphabetically): */ struct audit_context; -@@ -1153,6 +1154,12 @@ struct task_struct { +@@ -1206,6 +1207,12 @@ struct task_struct { int softirq_nestcnt; unsigned int softirqs_raised; #endif @@ -253,11 +260,9 @@ index ff13666bc6dd..678b52680df3 100644 #ifdef CONFIG_DEBUG_ATOMIC_SLEEP unsigned long task_state_change; #endif -diff --git a/include/linux/uaccess.h b/include/linux/uaccess.h -index 251e655d407f..57e8e32ef2b0 100644 --- a/include/linux/uaccess.h +++ b/include/linux/uaccess.h -@@ -185,6 +185,7 @@ static __always_inline void pagefault_disabled_dec(void) +@@ -185,6 +185,7 @@ static __always_inline void pagefault_di */ static inline void pagefault_disable(void) { @@ -265,7 +270,7 @@ index 251e655d407f..57e8e32ef2b0 100644 pagefault_disabled_inc(); /* * make sure to have issued the store before a pagefault -@@ -201,6 +202,7 @@ static inline void pagefault_enable(void) +@@ -201,6 +202,7 @@ static inline void pagefault_enable(void */ barrier(); pagefault_disabled_dec(); @@ -273,8 +278,6 @@ index 251e655d407f..57e8e32ef2b0 100644 } /* -diff --git a/mm/highmem.c b/mm/highmem.c -index 59db3223a5d6..22aa3ddbd87b 100644 --- a/mm/highmem.c +++ b/mm/highmem.c @@ -30,10 +30,11 @@ @@ -290,7 +293,7 @@ index 59db3223a5d6..22aa3ddbd87b 100644 /* * Virtual_count is not a pure "count". -@@ -108,8 +109,9 @@ static inline wait_queue_head_t *get_pkmap_wait_queue_head(unsigned int color) +@@ -108,8 +109,9 @@ static inline wait_queue_head_t *get_pkm unsigned long totalhigh_pages __read_mostly; EXPORT_SYMBOL(totalhigh_pages); @@ -301,6 +304,3 @@ index 59db3223a5d6..22aa3ddbd87b 100644 unsigned int nr_free_highpages (void) { --- -2.19.2 - diff --git a/kernel/patches-4.14.x-rt/0348-x86-highmem-Add-a-already-used-pte-check.patch b/kernel/patches-4.19.x-rt/0219-x86-highmem-add-a-already-used-pte-check.patch similarity index 59% rename from kernel/patches-4.14.x-rt/0348-x86-highmem-Add-a-already-used-pte-check.patch rename to kernel/patches-4.19.x-rt/0219-x86-highmem-add-a-already-used-pte-check.patch index bacf64474..47860fc3a 100644 --- a/kernel/patches-4.14.x-rt/0348-x86-highmem-Add-a-already-used-pte-check.patch +++ b/kernel/patches-4.19.x-rt/0219-x86-highmem-add-a-already-used-pte-check.patch @@ -1,20 +1,17 @@ -From 22b6bd239d4879b0df770a89cab7ee952b9c4526 Mon Sep 17 00:00:00 2001 From: Sebastian Andrzej Siewior Date: Mon, 11 Mar 2013 17:09:55 +0100 -Subject: [PATCH 348/450] x86/highmem: Add a "already used pte" check +Subject: x86/highmem: Add a "already used pte" check This is a copy from kmap_atomic_prot(). Signed-off-by: Sebastian Andrzej Siewior --- - arch/x86/mm/iomap_32.c | 2 ++ + arch/x86/mm/iomap_32.c | 2 ++ 1 file changed, 2 insertions(+) -diff --git a/arch/x86/mm/iomap_32.c b/arch/x86/mm/iomap_32.c -index 2620fb55ece1..585f6829653b 100644 --- a/arch/x86/mm/iomap_32.c +++ b/arch/x86/mm/iomap_32.c -@@ -66,6 +66,8 @@ void *kmap_atomic_prot_pfn(unsigned long pfn, pgprot_t prot) +@@ -69,6 +69,8 @@ void *kmap_atomic_prot_pfn(unsigned long type = kmap_atomic_idx_push(); idx = type + KM_TYPE_NR * smp_processor_id(); vaddr = __fix_to_virt(FIX_KMAP_BEGIN + idx); @@ -23,6 +20,3 @@ index 2620fb55ece1..585f6829653b 100644 #ifdef CONFIG_PREEMPT_RT_FULL current->kmap_pte[type] = pte; #endif --- -2.19.2 - diff --git a/kernel/patches-4.14.x-rt/0349-arm-highmem-Flush-tlb-on-unmap.patch b/kernel/patches-4.19.x-rt/0220-arm-highmem-flush-tlb-on-unmap.patch similarity index 76% rename from kernel/patches-4.14.x-rt/0349-arm-highmem-Flush-tlb-on-unmap.patch rename to kernel/patches-4.19.x-rt/0220-arm-highmem-flush-tlb-on-unmap.patch index bacf5126a..08e17cab7 100644 --- a/kernel/patches-4.14.x-rt/0349-arm-highmem-Flush-tlb-on-unmap.patch +++ b/kernel/patches-4.19.x-rt/0220-arm-highmem-flush-tlb-on-unmap.patch @@ -1,7 +1,6 @@ -From 9ea265c764addc8bd1864075d10a19de2a54f470 Mon Sep 17 00:00:00 2001 From: Sebastian Andrzej Siewior Date: Mon, 11 Mar 2013 21:37:27 +0100 -Subject: [PATCH 349/450] arm/highmem: Flush tlb on unmap +Subject: arm/highmem: Flush tlb on unmap The tlb should be flushed on unmap and thus make the mapping entry invalid. This is only done in the non-debug case which does not look @@ -9,11 +8,9 @@ right. Signed-off-by: Sebastian Andrzej Siewior --- - arch/arm/mm/highmem.c | 2 +- + arch/arm/mm/highmem.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) -diff --git a/arch/arm/mm/highmem.c b/arch/arm/mm/highmem.c -index d02f8187b1cc..eb4b225d28c9 100644 --- a/arch/arm/mm/highmem.c +++ b/arch/arm/mm/highmem.c @@ -112,10 +112,10 @@ void __kunmap_atomic(void *kvaddr) @@ -28,6 +25,3 @@ index d02f8187b1cc..eb4b225d28c9 100644 kmap_atomic_idx_pop(); } else if (vaddr >= PKMAP_ADDR(0) && vaddr < PKMAP_ADDR(LAST_PKMAP)) { /* this address was obtained through kmap_high_get() */ --- -2.19.2 - diff --git a/kernel/patches-4.14.x-rt/0350-arm-Enable-highmem-for-rt.patch b/kernel/patches-4.19.x-rt/0221-arm-enable-highmem-for-rt.patch similarity index 84% rename from kernel/patches-4.14.x-rt/0350-arm-Enable-highmem-for-rt.patch rename to kernel/patches-4.19.x-rt/0221-arm-enable-highmem-for-rt.patch index 72b70c097..3891177cb 100644 --- a/kernel/patches-4.14.x-rt/0350-arm-Enable-highmem-for-rt.patch +++ b/kernel/patches-4.19.x-rt/0221-arm-enable-highmem-for-rt.patch @@ -1,19 +1,16 @@ -From 959854b30385fb9a7899f30bc3bb84e46ce4ce5c Mon Sep 17 00:00:00 2001 +Subject: arm: Enable highmem for rt From: Thomas Gleixner Date: Wed, 13 Feb 2013 11:03:11 +0100 -Subject: [PATCH 350/450] arm: Enable highmem for rt fixup highmem for ARM. Signed-off-by: Thomas Gleixner --- - arch/arm/include/asm/switch_to.h | 8 +++++ - arch/arm/mm/highmem.c | 56 +++++++++++++++++++++++++++----- - include/linux/highmem.h | 1 + + arch/arm/include/asm/switch_to.h | 8 +++++ + arch/arm/mm/highmem.c | 56 +++++++++++++++++++++++++++++++++------ + include/linux/highmem.h | 1 3 files changed, 57 insertions(+), 8 deletions(-) -diff --git a/arch/arm/include/asm/switch_to.h b/arch/arm/include/asm/switch_to.h -index d3e937dcee4d..6ab96a2ce1f8 100644 --- a/arch/arm/include/asm/switch_to.h +++ b/arch/arm/include/asm/switch_to.h @@ -4,6 +4,13 @@ @@ -30,7 +27,7 @@ index d3e937dcee4d..6ab96a2ce1f8 100644 /* * For v7 SMP cores running a preemptible kernel we may be pre-empted * during a TLB maintenance operation, so execute an inner-shareable dsb -@@ -26,6 +33,7 @@ extern struct task_struct *__switch_to(struct task_struct *, struct thread_info +@@ -26,6 +33,7 @@ extern struct task_struct *__switch_to(s #define switch_to(prev,next,last) \ do { \ __complete_pending_tlbi(); \ @@ -38,11 +35,9 @@ index d3e937dcee4d..6ab96a2ce1f8 100644 last = __switch_to(prev,task_thread_info(prev), task_thread_info(next)); \ } while (0) -diff --git a/arch/arm/mm/highmem.c b/arch/arm/mm/highmem.c -index eb4b225d28c9..542692dbd40a 100644 --- a/arch/arm/mm/highmem.c +++ b/arch/arm/mm/highmem.c -@@ -34,6 +34,11 @@ static inline pte_t get_fixmap_pte(unsigned long vaddr) +@@ -34,6 +34,11 @@ static inline pte_t get_fixmap_pte(unsig return *ptep; } @@ -166,8 +161,6 @@ index eb4b225d28c9..542692dbd40a 100644 + } +} +#endif -diff --git a/include/linux/highmem.h b/include/linux/highmem.h -index 8f248e2137eb..5f0bd7a3e6a7 100644 --- a/include/linux/highmem.h +++ b/include/linux/highmem.h @@ -8,6 +8,7 @@ @@ -178,6 +171,3 @@ index 8f248e2137eb..5f0bd7a3e6a7 100644 #include --- -2.19.2 - diff --git a/kernel/patches-4.14.x-rt/0351-scsi-fcoe-Make-RT-aware.patch b/kernel/patches-4.19.x-rt/0222-scsi-fcoe-rt-aware.patch similarity index 66% rename from kernel/patches-4.14.x-rt/0351-scsi-fcoe-Make-RT-aware.patch rename to kernel/patches-4.19.x-rt/0222-scsi-fcoe-rt-aware.patch index 8b360948f..6b3ca2c3b 100644 --- a/kernel/patches-4.14.x-rt/0351-scsi-fcoe-Make-RT-aware.patch +++ b/kernel/patches-4.19.x-rt/0222-scsi-fcoe-rt-aware.patch @@ -1,23 +1,20 @@ -From aaa790579b2116b6fce8e79d3be5a14c898109d1 Mon Sep 17 00:00:00 2001 +Subject: scsi/fcoe: Make RT aware. From: Thomas Gleixner Date: Sat, 12 Nov 2011 14:00:48 +0100 -Subject: [PATCH 351/450] scsi/fcoe: Make RT aware. Do not disable preemption while taking sleeping locks. All user look safe for migrate_diable() only. Signed-off-by: Thomas Gleixner --- - drivers/scsi/fcoe/fcoe.c | 16 ++++++++-------- - drivers/scsi/fcoe/fcoe_ctlr.c | 4 ++-- - drivers/scsi/libfc/fc_exch.c | 4 ++-- + drivers/scsi/fcoe/fcoe.c | 16 ++++++++-------- + drivers/scsi/fcoe/fcoe_ctlr.c | 4 ++-- + drivers/scsi/libfc/fc_exch.c | 4 ++-- 3 files changed, 12 insertions(+), 12 deletions(-) -diff --git a/drivers/scsi/fcoe/fcoe.c b/drivers/scsi/fcoe/fcoe.c -index 85f9a3eba387..08ea05ddcd82 100644 --- a/drivers/scsi/fcoe/fcoe.c +++ b/drivers/scsi/fcoe/fcoe.c -@@ -1464,11 +1464,11 @@ static int fcoe_rcv(struct sk_buff *skb, struct net_device *netdev, +@@ -1459,11 +1459,11 @@ static int fcoe_rcv(struct sk_buff *skb, static int fcoe_alloc_paged_crc_eof(struct sk_buff *skb, int tlen) { struct fcoe_percpu_s *fps; @@ -32,7 +29,7 @@ index 85f9a3eba387..08ea05ddcd82 100644 return rc; } -@@ -1655,11 +1655,11 @@ static inline int fcoe_filter_frames(struct fc_lport *lport, +@@ -1650,11 +1650,11 @@ static inline int fcoe_filter_frames(str return 0; } @@ -46,7 +43,7 @@ index 85f9a3eba387..08ea05ddcd82 100644 return -EINVAL; } -@@ -1702,7 +1702,7 @@ static void fcoe_recv_frame(struct sk_buff *skb) +@@ -1697,7 +1697,7 @@ static void fcoe_recv_frame(struct sk_bu */ hp = (struct fcoe_hdr *) skb_network_header(skb); @@ -55,7 +52,7 @@ index 85f9a3eba387..08ea05ddcd82 100644 if (unlikely(FC_FCOE_DECAPS_VER(hp) != FC_FCOE_VER)) { if (stats->ErrorFrames < 5) printk(KERN_WARNING "fcoe: FCoE version " -@@ -1734,13 +1734,13 @@ static void fcoe_recv_frame(struct sk_buff *skb) +@@ -1729,13 +1729,13 @@ static void fcoe_recv_frame(struct sk_bu goto drop; if (!fcoe_filter_frames(lport, fp)) { @@ -71,11 +68,9 @@ index 85f9a3eba387..08ea05ddcd82 100644 kfree_skb(skb); } -diff --git a/drivers/scsi/fcoe/fcoe_ctlr.c b/drivers/scsi/fcoe/fcoe_ctlr.c -index 03019e07abb9..9ec11316bfe6 100644 --- a/drivers/scsi/fcoe/fcoe_ctlr.c +++ b/drivers/scsi/fcoe/fcoe_ctlr.c -@@ -835,7 +835,7 @@ static unsigned long fcoe_ctlr_age_fcfs(struct fcoe_ctlr *fip) +@@ -835,7 +835,7 @@ static unsigned long fcoe_ctlr_age_fcfs( INIT_LIST_HEAD(&del_list); @@ -84,7 +79,7 @@ index 03019e07abb9..9ec11316bfe6 100644 list_for_each_entry_safe(fcf, next, &fip->fcfs, list) { deadline = fcf->time + fcf->fka_period + fcf->fka_period / 2; -@@ -871,7 +871,7 @@ static unsigned long fcoe_ctlr_age_fcfs(struct fcoe_ctlr *fip) +@@ -871,7 +871,7 @@ static unsigned long fcoe_ctlr_age_fcfs( sel_time = fcf->time; } } @@ -93,11 +88,9 @@ index 03019e07abb9..9ec11316bfe6 100644 list_for_each_entry_safe(fcf, next, &del_list, list) { /* Removes fcf from current list */ -diff --git a/drivers/scsi/libfc/fc_exch.c b/drivers/scsi/libfc/fc_exch.c -index 42bcf7f3a0f9..2ce045d6860c 100644 --- a/drivers/scsi/libfc/fc_exch.c +++ b/drivers/scsi/libfc/fc_exch.c -@@ -833,10 +833,10 @@ static struct fc_exch *fc_exch_em_alloc(struct fc_lport *lport, +@@ -833,10 +833,10 @@ static struct fc_exch *fc_exch_em_alloc( } memset(ep, 0, sizeof(*ep)); @@ -110,6 +103,3 @@ index 42bcf7f3a0f9..2ce045d6860c 100644 /* peek cache of free slot */ if (pool->left != FC_XID_UNKNOWN) { --- -2.19.2 - diff --git a/kernel/patches-4.14.x-rt/0353-x86-crypto-Reduce-preempt-disabled-regions.patch b/kernel/patches-4.19.x-rt/0223-x86-crypto-reduce-preempt-disabled-regions.patch similarity index 78% rename from kernel/patches-4.14.x-rt/0353-x86-crypto-Reduce-preempt-disabled-regions.patch rename to kernel/patches-4.19.x-rt/0223-x86-crypto-reduce-preempt-disabled-regions.patch index 691999d49..5b2f529ee 100644 --- a/kernel/patches-4.14.x-rt/0353-x86-crypto-Reduce-preempt-disabled-regions.patch +++ b/kernel/patches-4.19.x-rt/0223-x86-crypto-reduce-preempt-disabled-regions.patch @@ -1,7 +1,6 @@ -From 24f3c348c0fa264d8b9a6b9a6ad2907f8dbbd3f5 Mon Sep 17 00:00:00 2001 +Subject: x86: crypto: Reduce preempt disabled regions From: Peter Zijlstra Date: Mon, 14 Nov 2011 18:19:27 +0100 -Subject: [PATCH 353/450] x86: crypto: Reduce preempt disabled regions Restrict the preempt disabled regions to the actual floating point operations and enable preemption for the administrative actions. @@ -14,14 +13,12 @@ Signed-off-by: Peter Zijlstra Signed-off-by: Thomas Gleixner --- - arch/x86/crypto/aesni-intel_glue.c | 22 ++++++++++++---------- + arch/x86/crypto/aesni-intel_glue.c | 22 ++++++++++++---------- 1 file changed, 12 insertions(+), 10 deletions(-) -diff --git a/arch/x86/crypto/aesni-intel_glue.c b/arch/x86/crypto/aesni-intel_glue.c -index c690ddc78c03..7a3138d33e33 100644 --- a/arch/x86/crypto/aesni-intel_glue.c +++ b/arch/x86/crypto/aesni-intel_glue.c -@@ -387,14 +387,14 @@ static int ecb_encrypt(struct skcipher_request *req) +@@ -434,14 +434,14 @@ static int ecb_encrypt(struct skcipher_r err = skcipher_walk_virt(&walk, req, true); @@ -38,7 +35,7 @@ index c690ddc78c03..7a3138d33e33 100644 return err; } -@@ -409,14 +409,14 @@ static int ecb_decrypt(struct skcipher_request *req) +@@ -456,14 +456,14 @@ static int ecb_decrypt(struct skcipher_r err = skcipher_walk_virt(&walk, req, true); @@ -55,7 +52,7 @@ index c690ddc78c03..7a3138d33e33 100644 return err; } -@@ -431,14 +431,14 @@ static int cbc_encrypt(struct skcipher_request *req) +@@ -478,14 +478,14 @@ static int cbc_encrypt(struct skcipher_r err = skcipher_walk_virt(&walk, req, true); @@ -72,7 +69,7 @@ index c690ddc78c03..7a3138d33e33 100644 return err; } -@@ -453,14 +453,14 @@ static int cbc_decrypt(struct skcipher_request *req) +@@ -500,14 +500,14 @@ static int cbc_decrypt(struct skcipher_r err = skcipher_walk_virt(&walk, req, true); @@ -89,7 +86,7 @@ index c690ddc78c03..7a3138d33e33 100644 return err; } -@@ -510,18 +510,20 @@ static int ctr_crypt(struct skcipher_request *req) +@@ -557,18 +557,20 @@ static int ctr_crypt(struct skcipher_req err = skcipher_walk_virt(&walk, req, true); @@ -112,6 +109,3 @@ index c690ddc78c03..7a3138d33e33 100644 return err; } --- -2.19.2 - diff --git a/kernel/patches-4.19.x-rt/0224-crypto-Reduce-preempt-disabled-regions-more-algos.patch b/kernel/patches-4.19.x-rt/0224-crypto-Reduce-preempt-disabled-regions-more-algos.patch new file mode 100644 index 000000000..c9f0040d9 --- /dev/null +++ b/kernel/patches-4.19.x-rt/0224-crypto-Reduce-preempt-disabled-regions-more-algos.patch @@ -0,0 +1,254 @@ +From: Sebastian Andrzej Siewior +Date: Fri, 21 Feb 2014 17:24:04 +0100 +Subject: crypto: Reduce preempt disabled regions, more algos + +Don Estabrook reported +| kernel: WARNING: CPU: 2 PID: 858 at kernel/sched/core.c:2428 migrate_disable+0xed/0x100() +| kernel: WARNING: CPU: 2 PID: 858 at kernel/sched/core.c:2462 migrate_enable+0x17b/0x200() +| kernel: WARNING: CPU: 3 PID: 865 at kernel/sched/core.c:2428 migrate_disable+0xed/0x100() + +and his backtrace showed some crypto functions which looked fine. + +The problem is the following sequence: + +glue_xts_crypt_128bit() +{ + blkcipher_walk_virt(); /* normal migrate_disable() */ + + glue_fpu_begin(); /* get atomic */ + + while (nbytes) { + __glue_xts_crypt_128bit(); + blkcipher_walk_done(); /* with nbytes = 0, migrate_enable() + * while we are atomic */ + }; + glue_fpu_end() /* no longer atomic */ +} + +and this is why the counter get out of sync and the warning is printed. +The other problem is that we are non-preemptible between +glue_fpu_begin() and glue_fpu_end() and the latency grows. To fix this, +I shorten the FPU off region and ensure blkcipher_walk_done() is called +with preemption enabled. This might hurt the performance because we now +enable/disable the FPU state more often but we gain lower latency and +the bug is gone. + + +Reported-by: Don Estabrook +Signed-off-by: Sebastian Andrzej Siewior +--- + arch/x86/crypto/cast5_avx_glue.c | 21 +++++++++------------ + arch/x86/crypto/glue_helper.c | 31 ++++++++++++++++--------------- + 2 files changed, 25 insertions(+), 27 deletions(-) + +--- a/arch/x86/crypto/cast5_avx_glue.c ++++ b/arch/x86/crypto/cast5_avx_glue.c +@@ -61,7 +61,7 @@ static inline void cast5_fpu_end(bool fp + + static int ecb_crypt(struct skcipher_request *req, bool enc) + { +- bool fpu_enabled = false; ++ bool fpu_enabled; + struct crypto_skcipher *tfm = crypto_skcipher_reqtfm(req); + struct cast5_ctx *ctx = crypto_skcipher_ctx(tfm); + struct skcipher_walk walk; +@@ -76,7 +76,7 @@ static int ecb_crypt(struct skcipher_req + u8 *wsrc = walk.src.virt.addr; + u8 *wdst = walk.dst.virt.addr; + +- fpu_enabled = cast5_fpu_begin(fpu_enabled, &walk, nbytes); ++ fpu_enabled = cast5_fpu_begin(false, &walk, nbytes); + + /* Process multi-block batch */ + if (nbytes >= bsize * CAST5_PARALLEL_BLOCKS) { +@@ -105,10 +105,9 @@ static int ecb_crypt(struct skcipher_req + } while (nbytes >= bsize); + + done: ++ cast5_fpu_end(fpu_enabled); + err = skcipher_walk_done(&walk, nbytes); + } +- +- cast5_fpu_end(fpu_enabled); + return err; + } + +@@ -212,7 +211,7 @@ static int cbc_decrypt(struct skcipher_r + { + struct crypto_skcipher *tfm = crypto_skcipher_reqtfm(req); + struct cast5_ctx *ctx = crypto_skcipher_ctx(tfm); +- bool fpu_enabled = false; ++ bool fpu_enabled; + struct skcipher_walk walk; + unsigned int nbytes; + int err; +@@ -220,12 +219,11 @@ static int cbc_decrypt(struct skcipher_r + err = skcipher_walk_virt(&walk, req, false); + + while ((nbytes = walk.nbytes)) { +- fpu_enabled = cast5_fpu_begin(fpu_enabled, &walk, nbytes); ++ fpu_enabled = cast5_fpu_begin(false, &walk, nbytes); + nbytes = __cbc_decrypt(ctx, &walk); ++ cast5_fpu_end(fpu_enabled); + err = skcipher_walk_done(&walk, nbytes); + } +- +- cast5_fpu_end(fpu_enabled); + return err; + } + +@@ -292,7 +290,7 @@ static int ctr_crypt(struct skcipher_req + { + struct crypto_skcipher *tfm = crypto_skcipher_reqtfm(req); + struct cast5_ctx *ctx = crypto_skcipher_ctx(tfm); +- bool fpu_enabled = false; ++ bool fpu_enabled; + struct skcipher_walk walk; + unsigned int nbytes; + int err; +@@ -300,13 +298,12 @@ static int ctr_crypt(struct skcipher_req + err = skcipher_walk_virt(&walk, req, false); + + while ((nbytes = walk.nbytes) >= CAST5_BLOCK_SIZE) { +- fpu_enabled = cast5_fpu_begin(fpu_enabled, &walk, nbytes); ++ fpu_enabled = cast5_fpu_begin(false, &walk, nbytes); + nbytes = __ctr_crypt(&walk, ctx); ++ cast5_fpu_end(fpu_enabled); + err = skcipher_walk_done(&walk, nbytes); + } + +- cast5_fpu_end(fpu_enabled); +- + if (walk.nbytes) { + ctr_crypt_final(&walk, ctx); + err = skcipher_walk_done(&walk, 0); +--- a/arch/x86/crypto/glue_helper.c ++++ b/arch/x86/crypto/glue_helper.c +@@ -38,7 +38,7 @@ int glue_ecb_req_128bit(const struct com + void *ctx = crypto_skcipher_ctx(crypto_skcipher_reqtfm(req)); + const unsigned int bsize = 128 / 8; + struct skcipher_walk walk; +- bool fpu_enabled = false; ++ bool fpu_enabled; + unsigned int nbytes; + int err; + +@@ -51,7 +51,7 @@ int glue_ecb_req_128bit(const struct com + unsigned int i; + + fpu_enabled = glue_fpu_begin(bsize, gctx->fpu_blocks_limit, +- &walk, fpu_enabled, nbytes); ++ &walk, false, nbytes); + for (i = 0; i < gctx->num_funcs; i++) { + func_bytes = bsize * gctx->funcs[i].num_blocks; + +@@ -69,10 +69,9 @@ int glue_ecb_req_128bit(const struct com + if (nbytes < bsize) + break; + } ++ glue_fpu_end(fpu_enabled); + err = skcipher_walk_done(&walk, nbytes); + } +- +- glue_fpu_end(fpu_enabled); + return err; + } + EXPORT_SYMBOL_GPL(glue_ecb_req_128bit); +@@ -115,7 +114,7 @@ int glue_cbc_decrypt_req_128bit(const st + void *ctx = crypto_skcipher_ctx(crypto_skcipher_reqtfm(req)); + const unsigned int bsize = 128 / 8; + struct skcipher_walk walk; +- bool fpu_enabled = false; ++ bool fpu_enabled; + unsigned int nbytes; + int err; + +@@ -129,7 +128,7 @@ int glue_cbc_decrypt_req_128bit(const st + u128 last_iv; + + fpu_enabled = glue_fpu_begin(bsize, gctx->fpu_blocks_limit, +- &walk, fpu_enabled, nbytes); ++ &walk, false, nbytes); + /* Start of the last block. */ + src += nbytes / bsize - 1; + dst += nbytes / bsize - 1; +@@ -161,10 +160,10 @@ int glue_cbc_decrypt_req_128bit(const st + done: + u128_xor(dst, dst, (u128 *)walk.iv); + *(u128 *)walk.iv = last_iv; ++ glue_fpu_end(fpu_enabled); + err = skcipher_walk_done(&walk, nbytes); + } + +- glue_fpu_end(fpu_enabled); + return err; + } + EXPORT_SYMBOL_GPL(glue_cbc_decrypt_req_128bit); +@@ -175,7 +174,7 @@ int glue_ctr_req_128bit(const struct com + void *ctx = crypto_skcipher_ctx(crypto_skcipher_reqtfm(req)); + const unsigned int bsize = 128 / 8; + struct skcipher_walk walk; +- bool fpu_enabled = false; ++ bool fpu_enabled; + unsigned int nbytes; + int err; + +@@ -189,7 +188,7 @@ int glue_ctr_req_128bit(const struct com + le128 ctrblk; + + fpu_enabled = glue_fpu_begin(bsize, gctx->fpu_blocks_limit, +- &walk, fpu_enabled, nbytes); ++ &walk, false, nbytes); + + be128_to_le128(&ctrblk, (be128 *)walk.iv); + +@@ -213,11 +212,10 @@ int glue_ctr_req_128bit(const struct com + } + + le128_to_be128((be128 *)walk.iv, &ctrblk); ++ glue_fpu_end(fpu_enabled); + err = skcipher_walk_done(&walk, nbytes); + } + +- glue_fpu_end(fpu_enabled); +- + if (nbytes) { + le128 ctrblk; + u128 tmp; +@@ -278,7 +276,7 @@ int glue_xts_req_128bit(const struct com + { + const unsigned int bsize = 128 / 8; + struct skcipher_walk walk; +- bool fpu_enabled = false; ++ bool fpu_enabled; + unsigned int nbytes; + int err; + +@@ -289,21 +287,24 @@ int glue_xts_req_128bit(const struct com + + /* set minimum length to bsize, for tweak_fn */ + fpu_enabled = glue_fpu_begin(bsize, gctx->fpu_blocks_limit, +- &walk, fpu_enabled, ++ &walk, false, + nbytes < bsize ? bsize : nbytes); + + /* calculate first value of T */ + tweak_fn(tweak_ctx, walk.iv, walk.iv); + + while (nbytes) { ++ fpu_enabled = glue_fpu_begin(bsize, gctx->fpu_blocks_limit, ++ &walk, fpu_enabled, ++ nbytes < bsize ? bsize : nbytes); + nbytes = __glue_xts_req_128bit(gctx, crypt_ctx, &walk); + ++ glue_fpu_end(fpu_enabled); ++ fpu_enabled = false; + err = skcipher_walk_done(&walk, nbytes); + nbytes = walk.nbytes; + } + +- glue_fpu_end(fpu_enabled); +- + return err; + } + EXPORT_SYMBOL_GPL(glue_xts_req_128bit); diff --git a/kernel/patches-4.19.x-rt/0225-crypto-limit-more-FPU-enabled-sections.patch b/kernel/patches-4.19.x-rt/0225-crypto-limit-more-FPU-enabled-sections.patch new file mode 100644 index 000000000..927731e85 --- /dev/null +++ b/kernel/patches-4.19.x-rt/0225-crypto-limit-more-FPU-enabled-sections.patch @@ -0,0 +1,97 @@ +From: Sebastian Andrzej Siewior +Date: Thu, 30 Nov 2017 13:40:10 +0100 +Subject: [PATCH] crypto: limit more FPU-enabled sections +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Those crypto drivers use SSE/AVX/… for their crypto work and in order to +do so in kernel they need to enable the "FPU" in kernel mode which +disables preemption. +There are two problems with the way they are used: +- the while loop which processes X bytes may create latency spikes and + should be avoided or limited. +- the cipher-walk-next part may allocate/free memory and may use + kmap_atomic(). + +The whole kernel_fpu_begin()/end() processing isn't probably that cheap. +It most likely makes sense to process as much of those as possible in one +go. The new *_fpu_sched_rt() schedules only if a RT task is pending. + +Probably we should measure the performance those ciphers in pure SW +mode and with this optimisations to see if it makes sense to keep them +for RT. + +This kernel_fpu_resched() makes the code more preemptible which might hurt +performance. + +Cc: stable-rt@vger.kernel.org +Signed-off-by: Sebastian Andrzej Siewior +--- + arch/x86/crypto/chacha20_glue.c | 9 +++++---- + arch/x86/include/asm/fpu/api.h | 1 + + arch/x86/kernel/fpu/core.c | 12 ++++++++++++ + 3 files changed, 18 insertions(+), 4 deletions(-) + +--- a/arch/x86/crypto/chacha20_glue.c ++++ b/arch/x86/crypto/chacha20_glue.c +@@ -81,23 +81,24 @@ static int chacha20_simd(struct skcipher + + crypto_chacha20_init(state, ctx, walk.iv); + +- kernel_fpu_begin(); +- + while (walk.nbytes >= CHACHA20_BLOCK_SIZE) { ++ kernel_fpu_begin(); ++ + chacha20_dosimd(state, walk.dst.virt.addr, walk.src.virt.addr, + rounddown(walk.nbytes, CHACHA20_BLOCK_SIZE)); ++ kernel_fpu_end(); + err = skcipher_walk_done(&walk, + walk.nbytes % CHACHA20_BLOCK_SIZE); + } + + if (walk.nbytes) { ++ kernel_fpu_begin(); + chacha20_dosimd(state, walk.dst.virt.addr, walk.src.virt.addr, + walk.nbytes); ++ kernel_fpu_end(); + err = skcipher_walk_done(&walk, 0); + } + +- kernel_fpu_end(); +- + return err; + } + +--- a/arch/x86/include/asm/fpu/api.h ++++ b/arch/x86/include/asm/fpu/api.h +@@ -25,6 +25,7 @@ extern void __kernel_fpu_begin(void); + extern void __kernel_fpu_end(void); + extern void kernel_fpu_begin(void); + extern void kernel_fpu_end(void); ++extern void kernel_fpu_resched(void); + extern bool irq_fpu_usable(void); + + /* +--- a/arch/x86/kernel/fpu/core.c ++++ b/arch/x86/kernel/fpu/core.c +@@ -138,6 +138,18 @@ void kernel_fpu_end(void) + } + EXPORT_SYMBOL_GPL(kernel_fpu_end); + ++void kernel_fpu_resched(void) ++{ ++ WARN_ON_FPU(!this_cpu_read(in_kernel_fpu)); ++ ++ if (should_resched(PREEMPT_OFFSET)) { ++ kernel_fpu_end(); ++ cond_resched(); ++ kernel_fpu_begin(); ++ } ++} ++EXPORT_SYMBOL_GPL(kernel_fpu_resched); ++ + /* + * Save the FPU state (mark it for reload if necessary): + * diff --git a/kernel/patches-4.14.x-rt/0430-crypto-scompress-serialize-RT-percpu-scratch-buffer-.patch b/kernel/patches-4.19.x-rt/0226-crypto-scompress-serialize-RT-percpu-scratch-buffer-.patch similarity index 77% rename from kernel/patches-4.14.x-rt/0430-crypto-scompress-serialize-RT-percpu-scratch-buffer-.patch rename to kernel/patches-4.19.x-rt/0226-crypto-scompress-serialize-RT-percpu-scratch-buffer-.patch index 667d00f33..29fc6e938 100644 --- a/kernel/patches-4.14.x-rt/0430-crypto-scompress-serialize-RT-percpu-scratch-buffer-.patch +++ b/kernel/patches-4.19.x-rt/0226-crypto-scompress-serialize-RT-percpu-scratch-buffer-.patch @@ -1,10 +1,7 @@ -From 33b672b6b513a144f0ccb471e007a9a7e7544af0 Mon Sep 17 00:00:00 2001 From: Mike Galbraith Date: Wed, 11 Jul 2018 17:14:47 +0200 -Subject: [PATCH 430/450] crypto: scompress - serialize RT percpu scratch - buffer access with a local lock - -[ Upstream commit 1a4eff3f8e743d149be26a414822710aef07fe14 ] +Subject: [PATCH] crypto: scompress - serialize RT percpu scratch buffer + access with a local lock | BUG: sleeping function called from invalid context at kernel/locking/rtmutex.c:974 | in_atomic(): 1, irqs_disabled(): 0, pid: 1401, name: cryptomgr_test @@ -37,13 +34,10 @@ causing the splat above. Serialize with a local lock for RT instead. Signed-off-by: Mike Galbraith Signed-off-by: Sebastian Andrzej Siewior -Signed-off-by: Steven Rostedt (VMware) --- - crypto/scompress.c | 6 ++++-- + crypto/scompress.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) -diff --git a/crypto/scompress.c b/crypto/scompress.c -index 2075e2c4e7df..c6b4e265c6bf 100644 --- a/crypto/scompress.c +++ b/crypto/scompress.c @@ -24,6 +24,7 @@ @@ -54,7 +48,7 @@ index 2075e2c4e7df..c6b4e265c6bf 100644 #include #include #include -@@ -34,6 +35,7 @@ static void * __percpu *scomp_src_scratches; +@@ -34,6 +35,7 @@ static void * __percpu *scomp_src_scratc static void * __percpu *scomp_dst_scratches; static int scomp_scratch_users; static DEFINE_MUTEX(scomp_lock); @@ -62,7 +56,7 @@ index 2075e2c4e7df..c6b4e265c6bf 100644 #ifdef CONFIG_NET static int crypto_scomp_report(struct sk_buff *skb, struct crypto_alg *alg) -@@ -193,7 +195,7 @@ static int scomp_acomp_comp_decomp(struct acomp_req *req, int dir) +@@ -146,7 +148,7 @@ static int scomp_acomp_comp_decomp(struc void **tfm_ctx = acomp_tfm_ctx(tfm); struct crypto_scomp *scomp = *tfm_ctx; void **ctx = acomp_request_ctx(req); @@ -71,7 +65,7 @@ index 2075e2c4e7df..c6b4e265c6bf 100644 u8 *scratch_src = *per_cpu_ptr(scomp_src_scratches, cpu); u8 *scratch_dst = *per_cpu_ptr(scomp_dst_scratches, cpu); int ret; -@@ -228,7 +230,7 @@ static int scomp_acomp_comp_decomp(struct acomp_req *req, int dir) +@@ -181,7 +183,7 @@ static int scomp_acomp_comp_decomp(struc 1); } out: @@ -80,6 +74,3 @@ index 2075e2c4e7df..c6b4e265c6bf 100644 return ret; } --- -2.19.2 - diff --git a/kernel/patches-4.14.x-rt/0429-crypto-cryptd-add-a-lock-instead-preempt_disable-loc.patch b/kernel/patches-4.19.x-rt/0227-crypto-cryptd-add-a-lock-instead-preempt_disable-loc.patch similarity index 73% rename from kernel/patches-4.14.x-rt/0429-crypto-cryptd-add-a-lock-instead-preempt_disable-loc.patch rename to kernel/patches-4.19.x-rt/0227-crypto-cryptd-add-a-lock-instead-preempt_disable-loc.patch index 9917f78dd..eee9ac835 100644 --- a/kernel/patches-4.14.x-rt/0429-crypto-cryptd-add-a-lock-instead-preempt_disable-loc.patch +++ b/kernel/patches-4.19.x-rt/0227-crypto-cryptd-add-a-lock-instead-preempt_disable-loc.patch @@ -1,11 +1,8 @@ -From 17d691e76e9bf821fa0f10311b91b42bb1b3857a Mon Sep 17 00:00:00 2001 From: Sebastian Andrzej Siewior Date: Thu, 26 Jul 2018 18:52:00 +0200 -Subject: [PATCH 429/450] crypto: cryptd - add a lock instead +Subject: [PATCH] crypto: cryptd - add a lock instead preempt_disable/local_bh_disable -[ Upstream commit 21aedb30d85979697f79a72a084e5d781e323663 ] - cryptd has a per-CPU lock which protected with local_bh_disable() and preempt_disable(). Add an explicit spin_lock to make the locking context more obvious and @@ -16,16 +13,13 @@ after the cpu_queue has been obtain. This is not a problem because the actual ressource is protected by the spinlock. Signed-off-by: Sebastian Andrzej Siewior -Signed-off-by: Steven Rostedt (VMware) --- - crypto/cryptd.c | 19 +++++++++---------- + crypto/cryptd.c | 19 +++++++++---------- 1 file changed, 9 insertions(+), 10 deletions(-) -diff --git a/crypto/cryptd.c b/crypto/cryptd.c -index 248f6ba41688..54b7985c8caa 100644 --- a/crypto/cryptd.c +++ b/crypto/cryptd.c -@@ -37,6 +37,7 @@ +@@ -39,6 +39,7 @@ MODULE_PARM_DESC(cryptd_max_cpu_qlen, "S struct cryptd_cpu_queue { struct crypto_queue queue; struct work_struct work; @@ -33,17 +27,17 @@ index 248f6ba41688..54b7985c8caa 100644 }; struct cryptd_queue { -@@ -115,6 +116,7 @@ static int cryptd_init_queue(struct cryptd_queue *queue, +@@ -117,6 +118,7 @@ static int cryptd_init_queue(struct cryp cpu_queue = per_cpu_ptr(queue->cpu_queue, cpu); crypto_init_queue(&cpu_queue->queue, max_cpu_qlen); INIT_WORK(&cpu_queue->work, cryptd_queue_worker); + spin_lock_init(&cpu_queue->qlock); } + pr_info("cryptd: max_cpu_qlen set to %d\n", max_cpu_qlen); return 0; - } -@@ -139,8 +141,10 @@ static int cryptd_enqueue_request(struct cryptd_queue *queue, +@@ -141,8 +143,10 @@ static int cryptd_enqueue_request(struct + struct cryptd_cpu_queue *cpu_queue; atomic_t *refcnt; - bool may_backlog; - cpu = get_cpu(); - cpu_queue = this_cpu_ptr(queue->cpu_queue); @@ -54,7 +48,7 @@ index 248f6ba41688..54b7985c8caa 100644 err = crypto_enqueue_request(&cpu_queue->queue, request); refcnt = crypto_tfm_ctx(request->tfm); -@@ -157,7 +161,7 @@ static int cryptd_enqueue_request(struct cryptd_queue *queue, +@@ -158,7 +162,7 @@ static int cryptd_enqueue_request(struct atomic_inc(refcnt); out_put_cpu: @@ -63,7 +57,7 @@ index 248f6ba41688..54b7985c8caa 100644 return err; } -@@ -173,16 +177,11 @@ static void cryptd_queue_worker(struct work_struct *work) +@@ -174,16 +178,11 @@ static void cryptd_queue_worker(struct w cpu_queue = container_of(work, struct cryptd_cpu_queue, work); /* * Only handle one request at a time to avoid hogging crypto workqueue. @@ -82,6 +76,3 @@ index 248f6ba41688..54b7985c8caa 100644 if (!req) return; --- -2.19.2 - diff --git a/kernel/patches-4.14.x-rt/0188-panic-skip-get_random_bytes-for-RT_FULL-in-init_oops.patch b/kernel/patches-4.19.x-rt/0228-panic-disable-random-on-rt.patch similarity index 61% rename from kernel/patches-4.14.x-rt/0188-panic-skip-get_random_bytes-for-RT_FULL-in-init_oops.patch rename to kernel/patches-4.19.x-rt/0228-panic-disable-random-on-rt.patch index e91cd2a77..51aa8c6c3 100644 --- a/kernel/patches-4.14.x-rt/0188-panic-skip-get_random_bytes-for-RT_FULL-in-init_oops.patch +++ b/kernel/patches-4.19.x-rt/0228-panic-disable-random-on-rt.patch @@ -1,22 +1,18 @@ -From 7fee3caa1bdf406d3ebe5fc1328f6645c8b2422e Mon Sep 17 00:00:00 2001 From: Thomas Gleixner Date: Tue, 14 Jul 2015 14:26:34 +0200 -Subject: [PATCH 188/450] panic: skip get_random_bytes for RT_FULL in - init_oops_id +Subject: panic: skip get_random_bytes for RT_FULL in init_oops_id Disable on -RT. If this is invoked from irq-context we will have problems to acquire the sleeping lock. Signed-off-by: Thomas Gleixner --- - kernel/panic.c | 2 ++ + kernel/panic.c | 2 ++ 1 file changed, 2 insertions(+) -diff --git a/kernel/panic.c b/kernel/panic.c -index bdd18afa19a4..5da649633795 100644 --- a/kernel/panic.c +++ b/kernel/panic.c -@@ -482,9 +482,11 @@ static u64 oops_id; +@@ -479,9 +479,11 @@ static u64 oops_id; static int init_oops_id(void) { @@ -28,6 +24,3 @@ index bdd18afa19a4..5da649633795 100644 oops_id++; return 0; --- -2.19.2 - diff --git a/kernel/patches-4.14.x-rt/0285-x86-stackprotector-Avoid-random-pool-on-rt.patch b/kernel/patches-4.19.x-rt/0229-x86-stackprot-no-random-on-rt.patch similarity index 78% rename from kernel/patches-4.14.x-rt/0285-x86-stackprotector-Avoid-random-pool-on-rt.patch rename to kernel/patches-4.19.x-rt/0229-x86-stackprot-no-random-on-rt.patch index 67c05f27b..66c2ecf59 100644 --- a/kernel/patches-4.14.x-rt/0285-x86-stackprotector-Avoid-random-pool-on-rt.patch +++ b/kernel/patches-4.19.x-rt/0229-x86-stackprot-no-random-on-rt.patch @@ -1,7 +1,6 @@ -From c3edfff3893fb9ea36c0b9199adcee709c07b57d Mon Sep 17 00:00:00 2001 From: Thomas Gleixner Date: Thu, 16 Dec 2010 14:25:18 +0100 -Subject: [PATCH 285/450] x86: stackprotector: Avoid random pool on rt +Subject: x86: stackprotector: Avoid random pool on rt CPU bringup calls into the random pool to initialize the stack canary. During boot that works nicely even on RT as the might sleep @@ -13,12 +12,11 @@ entropy and we rely on the TSC randomnness. Reported-by: Carsten Emde Signed-off-by: Thomas Gleixner + --- - arch/x86/include/asm/stackprotector.h | 8 +++++++- + arch/x86/include/asm/stackprotector.h | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) -diff --git a/arch/x86/include/asm/stackprotector.h b/arch/x86/include/asm/stackprotector.h -index 371b3a4af000..06613a805b25 100644 --- a/arch/x86/include/asm/stackprotector.h +++ b/arch/x86/include/asm/stackprotector.h @@ -60,7 +60,7 @@ @@ -30,7 +28,7 @@ index 371b3a4af000..06613a805b25 100644 u64 tsc; #ifdef CONFIG_X86_64 -@@ -71,8 +71,14 @@ static __always_inline void boot_init_stack_canary(void) +@@ -71,8 +71,14 @@ static __always_inline void boot_init_st * of randomness. The TSC only matters for very early init, * there it already has some randomness on most systems. Later * on during the bootup the random pool has true entropy too. @@ -45,6 +43,3 @@ index 371b3a4af000..06613a805b25 100644 tsc = rdtsc(); canary += tsc + (tsc << 32UL); canary &= CANARY_MASK; --- -2.19.2 - diff --git a/kernel/patches-4.14.x-rt/0360-random-Make-it-work-on-rt.patch b/kernel/patches-4.19.x-rt/0230-random-make-it-work-on-rt.patch similarity index 71% rename from kernel/patches-4.14.x-rt/0360-random-Make-it-work-on-rt.patch rename to kernel/patches-4.19.x-rt/0230-random-make-it-work-on-rt.patch index 4d55851e3..5ccf43fdd 100644 --- a/kernel/patches-4.14.x-rt/0360-random-Make-it-work-on-rt.patch +++ b/kernel/patches-4.19.x-rt/0230-random-make-it-work-on-rt.patch @@ -1,7 +1,6 @@ -From 846a0171bb7bedde591b065bf8bf3482c071801e Mon Sep 17 00:00:00 2001 +Subject: random: Make it work on rt From: Thomas Gleixner Date: Tue, 21 Aug 2012 20:38:50 +0200 -Subject: [PATCH 360/450] random: Make it work on rt Delegate the random insertion to the forced threaded interrupt handler. Store the return IP of the hard interrupt handler in the irq @@ -9,20 +8,20 @@ descriptor and feed it into the random generator as a source of entropy. Signed-off-by: Thomas Gleixner ---- - drivers/char/random.c | 11 +++++------ - drivers/hv/vmbus_drv.c | 4 +++- - include/linux/irqdesc.h | 1 + - include/linux/random.h | 2 +- - kernel/irq/handle.c | 8 +++++++- - kernel/irq/manage.c | 6 ++++++ - 6 files changed, 23 insertions(+), 9 deletions(-) -diff --git a/drivers/char/random.c b/drivers/char/random.c -index 8a6228ab983c..29a46c372df3 100644 +--- + drivers/char/random.c | 11 +++++------ + drivers/hv/hv.c | 4 +++- + drivers/hv/vmbus_drv.c | 4 +++- + include/linux/irqdesc.h | 1 + + include/linux/random.h | 2 +- + kernel/irq/handle.c | 8 +++++++- + kernel/irq/manage.c | 6 ++++++ + 7 files changed, 26 insertions(+), 10 deletions(-) + --- a/drivers/char/random.c +++ b/drivers/char/random.c -@@ -1218,28 +1218,27 @@ static __u32 get_reg(struct fast_pool *f, struct pt_regs *regs) +@@ -1229,28 +1229,27 @@ static __u32 get_reg(struct fast_pool *f return *ptr; } @@ -56,11 +55,25 @@ index 8a6228ab983c..29a46c372df3 100644 fast_mix(fast_pool); add_interrupt_bench(cycles); -diff --git a/drivers/hv/vmbus_drv.c b/drivers/hv/vmbus_drv.c -index 2cd134dd94d2..cedf225d4182 100644 +--- a/drivers/hv/hv.c ++++ b/drivers/hv/hv.c +@@ -112,10 +112,12 @@ int hv_post_message(union hv_connection_ + static void hv_stimer0_isr(void) + { + struct hv_per_cpu_context *hv_cpu; ++ struct pt_regs *regs = get_irq_regs(); ++ u64 ip = regs ? instruction_pointer(regs) : 0; + + hv_cpu = this_cpu_ptr(hv_context.cpu_context); + hv_cpu->clk_evt->event_handler(hv_cpu->clk_evt); +- add_interrupt_randomness(stimer0_vector, 0); ++ add_interrupt_randomness(stimer0_vector, 0, ip); + } + + static int hv_ce_set_next_event(unsigned long delta, --- a/drivers/hv/vmbus_drv.c +++ b/drivers/hv/vmbus_drv.c -@@ -966,6 +966,8 @@ static void vmbus_isr(void) +@@ -1042,6 +1042,8 @@ static void vmbus_isr(void) void *page_addr = hv_cpu->synic_event_page; struct hv_message *msg; union hv_synic_event_flags *event; @@ -69,7 +82,7 @@ index 2cd134dd94d2..cedf225d4182 100644 bool handled = false; if (unlikely(page_addr == NULL)) -@@ -1009,7 +1011,7 @@ static void vmbus_isr(void) +@@ -1085,7 +1087,7 @@ static void vmbus_isr(void) tasklet_schedule(&hv_cpu->msg_dpc); } @@ -77,9 +90,7 @@ index 2cd134dd94d2..cedf225d4182 100644 + add_interrupt_randomness(HYPERVISOR_CALLBACK_VECTOR, 0, ip); } - -diff --git a/include/linux/irqdesc.h b/include/linux/irqdesc.h -index b6084898d330..d334476cdca6 100644 + /* --- a/include/linux/irqdesc.h +++ b/include/linux/irqdesc.h @@ -70,6 +70,7 @@ struct irq_desc { @@ -90,11 +101,9 @@ index b6084898d330..d334476cdca6 100644 raw_spinlock_t lock; struct cpumask *percpu_enabled; const struct cpumask *percpu_affinity; -diff --git a/include/linux/random.h b/include/linux/random.h -index 4024f7d9c77d..462d752a739b 100644 --- a/include/linux/random.h +++ b/include/linux/random.h -@@ -32,7 +32,7 @@ static inline void add_latent_entropy(void) {} +@@ -32,7 +32,7 @@ static inline void add_latent_entropy(vo extern void add_input_randomness(unsigned int type, unsigned int code, unsigned int value) __latent_entropy; @@ -103,11 +112,9 @@ index 4024f7d9c77d..462d752a739b 100644 extern void get_random_bytes(void *buf, int nbytes); extern int wait_for_random_bytes(void); -diff --git a/kernel/irq/handle.c b/kernel/irq/handle.c -index 79f987b942b8..d1dbacc29941 100644 --- a/kernel/irq/handle.c +++ b/kernel/irq/handle.c -@@ -183,10 +183,16 @@ irqreturn_t handle_irq_event_percpu(struct irq_desc *desc) +@@ -185,10 +185,16 @@ irqreturn_t handle_irq_event_percpu(stru { irqreturn_t retval; unsigned int flags = 0; @@ -125,11 +132,9 @@ index 79f987b942b8..d1dbacc29941 100644 if (!noirqdebug) note_interrupt(desc, retval); -diff --git a/kernel/irq/manage.c b/kernel/irq/manage.c -index 400eca839bcc..01b282ddb83b 100644 --- a/kernel/irq/manage.c +++ b/kernel/irq/manage.c -@@ -1031,6 +1031,12 @@ static int irq_thread(void *data) +@@ -1076,6 +1076,12 @@ static int irq_thread(void *data) if (action_ret == IRQ_WAKE_THREAD) irq_wake_secondary(desc, action); @@ -142,6 +147,3 @@ index 400eca839bcc..01b282ddb83b 100644 wake_threads_waitq(desc); } --- -2.19.2 - diff --git a/kernel/patches-4.14.x-rt/0361-random-avoid-preempt_disable-ed-section.patch b/kernel/patches-4.19.x-rt/0231-random-avoid-preempt_disable-ed-section.patch similarity index 79% rename from kernel/patches-4.14.x-rt/0361-random-avoid-preempt_disable-ed-section.patch rename to kernel/patches-4.19.x-rt/0231-random-avoid-preempt_disable-ed-section.patch index b3ded2d40..846d4616f 100644 --- a/kernel/patches-4.14.x-rt/0361-random-avoid-preempt_disable-ed-section.patch +++ b/kernel/patches-4.19.x-rt/0231-random-avoid-preempt_disable-ed-section.patch @@ -1,7 +1,6 @@ -From 9926c096cded9f549edd991ee41f3f2d26c71691 Mon Sep 17 00:00:00 2001 From: Sebastian Andrzej Siewior Date: Fri, 12 May 2017 15:46:17 +0200 -Subject: [PATCH 361/450] random: avoid preempt_disable()ed section +Subject: [PATCH] random: avoid preempt_disable()ed section extract_crng() will use sleeping locks while in a preempt_disable() section due to get_cpu_var(). @@ -10,11 +9,9 @@ Work around it with local_locks. Cc: stable-rt@vger.kernel.org # where it applies to Signed-off-by: Sebastian Andrzej Siewior --- - drivers/char/random.c | 11 +++++++---- + drivers/char/random.c | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) -diff --git a/drivers/char/random.c b/drivers/char/random.c -index 29a46c372df3..9fb3c929765c 100644 --- a/drivers/char/random.c +++ b/drivers/char/random.c @@ -265,6 +265,7 @@ @@ -25,7 +22,7 @@ index 29a46c372df3..9fb3c929765c 100644 #include #include -@@ -2196,6 +2197,7 @@ static rwlock_t batched_entropy_reset_lock = __RW_LOCK_UNLOCKED(batched_entropy_ +@@ -2223,6 +2224,7 @@ static rwlock_t batched_entropy_reset_lo * at any point prior. */ static DEFINE_PER_CPU(struct batched_entropy, batched_entropy_u64); @@ -33,7 +30,7 @@ index 29a46c372df3..9fb3c929765c 100644 u64 get_random_u64(void) { u64 ret; -@@ -2216,7 +2218,7 @@ u64 get_random_u64(void) +@@ -2243,7 +2245,7 @@ u64 get_random_u64(void) warn_unseeded_randomness(&previous); use_lock = READ_ONCE(crng_init) < 2; @@ -42,7 +39,7 @@ index 29a46c372df3..9fb3c929765c 100644 if (use_lock) read_lock_irqsave(&batched_entropy_reset_lock, flags); if (batch->position % ARRAY_SIZE(batch->entropy_u64) == 0) { -@@ -2226,12 +2228,13 @@ u64 get_random_u64(void) +@@ -2253,12 +2255,13 @@ u64 get_random_u64(void) ret = batch->entropy_u64[batch->position++]; if (use_lock) read_unlock_irqrestore(&batched_entropy_reset_lock, flags); @@ -57,7 +54,7 @@ index 29a46c372df3..9fb3c929765c 100644 u32 get_random_u32(void) { u32 ret; -@@ -2246,7 +2249,7 @@ u32 get_random_u32(void) +@@ -2273,7 +2276,7 @@ u32 get_random_u32(void) warn_unseeded_randomness(&previous); use_lock = READ_ONCE(crng_init) < 2; @@ -66,7 +63,7 @@ index 29a46c372df3..9fb3c929765c 100644 if (use_lock) read_lock_irqsave(&batched_entropy_reset_lock, flags); if (batch->position % ARRAY_SIZE(batch->entropy_u32) == 0) { -@@ -2256,7 +2259,7 @@ u32 get_random_u32(void) +@@ -2283,7 +2286,7 @@ u32 get_random_u32(void) ret = batch->entropy_u32[batch->position++]; if (use_lock) read_unlock_irqrestore(&batched_entropy_reset_lock, flags); @@ -75,6 +72,3 @@ index 29a46c372df3..9fb3c929765c 100644 return ret; } EXPORT_SYMBOL(get_random_u32); --- -2.19.2 - diff --git a/kernel/patches-4.14.x-rt/0363-cpu-hotplug-Implement-CPU-pinning.patch b/kernel/patches-4.19.x-rt/0232-cpu-hotplug--Implement-CPU-pinning.patch similarity index 70% rename from kernel/patches-4.14.x-rt/0363-cpu-hotplug-Implement-CPU-pinning.patch rename to kernel/patches-4.19.x-rt/0232-cpu-hotplug--Implement-CPU-pinning.patch index 1feb155f3..2841608b7 100644 --- a/kernel/patches-4.14.x-rt/0363-cpu-hotplug-Implement-CPU-pinning.patch +++ b/kernel/patches-4.19.x-rt/0232-cpu-hotplug--Implement-CPU-pinning.patch @@ -1,31 +1,26 @@ -From 1e90ab9e5476d88116ff2b47999ca5437cdd5f24 Mon Sep 17 00:00:00 2001 +Subject: cpu/hotplug: Implement CPU pinning From: Thomas Gleixner Date: Wed, 19 Jul 2017 17:31:20 +0200 -Subject: [PATCH 363/450] cpu/hotplug: Implement CPU pinning Signed-off-by: Thomas Gleixner --- - include/linux/sched.h | 1 + - kernel/cpu.c | 40 ++++++++++++++++++++++++++++++++++++++++ - 2 files changed, 41 insertions(+) + include/linux/sched.h | 1 + + kernel/cpu.c | 38 ++++++++++++++++++++++++++++++++++++++ + 2 files changed, 39 insertions(+) -diff --git a/include/linux/sched.h b/include/linux/sched.h -index 678b52680df3..ac1e8dd32a6f 100644 --- a/include/linux/sched.h +++ b/include/linux/sched.h -@@ -629,6 +629,7 @@ struct task_struct { - #if defined(CONFIG_PREEMPT_COUNT) && defined(CONFIG_SMP) +@@ -671,6 +671,7 @@ struct task_struct { + #if defined(CONFIG_SMP) && defined(CONFIG_PREEMPT_RT_BASE) int migrate_disable; int migrate_disable_update; + int pinned_on_cpu; # ifdef CONFIG_SCHED_DEBUG int migrate_disable_atomic; # endif -diff --git a/kernel/cpu.c b/kernel/cpu.c -index 92a1e437e777..bc97ca16de81 100644 --- a/kernel/cpu.c +++ b/kernel/cpu.c -@@ -75,6 +75,11 @@ static DEFINE_PER_CPU(struct cpuhp_cpu_state, cpuhp_state) = { +@@ -75,6 +75,11 @@ static DEFINE_PER_CPU(struct cpuhp_cpu_s .fail = CPUHP_INVALID, }; @@ -37,7 +32,7 @@ index 92a1e437e777..bc97ca16de81 100644 #if defined(CONFIG_LOCKDEP) && defined(CONFIG_SMP) static struct lockdep_map cpuhp_state_up_map = STATIC_LOCKDEP_MAP_INIT("cpuhp_state-up", &cpuhp_state_up_map); -@@ -293,7 +298,30 @@ static int cpu_hotplug_disabled; +@@ -286,7 +291,28 @@ static int cpu_hotplug_disabled; */ void pin_current_cpu(void) { @@ -53,13 +48,11 @@ index 92a1e437e777..bc97ca16de81 100644 + return; + } + cpu = smp_processor_id(); -+ preempt_lazy_enable(); + preempt_enable(); + + __read_rt_lock(cpuhp_pin); + preempt_disable(); -+ preempt_lazy_disable(); + if (cpu != smp_processor_id()) { + __read_rt_unlock(cpuhp_pin); + goto again; @@ -68,7 +61,7 @@ index 92a1e437e777..bc97ca16de81 100644 } /** -@@ -301,6 +329,13 @@ void pin_current_cpu(void) +@@ -294,6 +320,13 @@ void pin_current_cpu(void) */ void unpin_current_cpu(void) { @@ -82,7 +75,7 @@ index 92a1e437e777..bc97ca16de81 100644 } DEFINE_STATIC_PERCPU_RWSEM(cpu_hotplug_lock); -@@ -865,6 +900,7 @@ static int take_cpu_down(void *_param) +@@ -828,6 +861,7 @@ static int take_cpu_down(void *_param) static int takedown_cpu(unsigned int cpu) { @@ -90,7 +83,7 @@ index 92a1e437e777..bc97ca16de81 100644 struct cpuhp_cpu_state *st = per_cpu_ptr(&cpuhp_state, cpu); int err; -@@ -877,11 +913,14 @@ static int takedown_cpu(unsigned int cpu) +@@ -840,11 +874,14 @@ static int takedown_cpu(unsigned int cpu */ irq_lock_sparse(); @@ -105,7 +98,7 @@ index 92a1e437e777..bc97ca16de81 100644 /* CPU refused to die */ irq_unlock_sparse(); /* Unpark the hotplug thread so we can rollback there */ -@@ -900,6 +939,7 @@ static int takedown_cpu(unsigned int cpu) +@@ -863,6 +900,7 @@ static int takedown_cpu(unsigned int cpu wait_for_ap_thread(st, false); BUG_ON(st->state != CPUHP_AP_IDLE_DEAD); @@ -113,6 +106,3 @@ index 92a1e437e777..bc97ca16de81 100644 /* Interrupts are moved away from the dying cpu, reenable alloc/free */ irq_unlock_sparse(); --- -2.19.2 - diff --git a/kernel/patches-4.14.x-rt/0433-sched-Allow-pinned-user-tasks-to-be-awakened-to-the-.patch b/kernel/patches-4.19.x-rt/0233-sched-Allow-pinned-user-tasks-to-be-awakened-to-the-.patch similarity index 68% rename from kernel/patches-4.14.x-rt/0433-sched-Allow-pinned-user-tasks-to-be-awakened-to-the-.patch rename to kernel/patches-4.19.x-rt/0233-sched-Allow-pinned-user-tasks-to-be-awakened-to-the-.patch index 1722c22a7..4d22d7372 100644 --- a/kernel/patches-4.14.x-rt/0433-sched-Allow-pinned-user-tasks-to-be-awakened-to-the-.patch +++ b/kernel/patches-4.19.x-rt/0233-sched-Allow-pinned-user-tasks-to-be-awakened-to-the-.patch @@ -1,10 +1,7 @@ -From 4326f7d62d7ab0d3e95e49e9fc806866aba01d26 Mon Sep 17 00:00:00 2001 From: Mike Galbraith Date: Sun, 19 Aug 2018 08:28:35 +0200 -Subject: [PATCH 433/450] sched: Allow pinned user tasks to be awakened to the - CPU they pinned - -[ Upstream commit cd4d35ef89948221f7cd1751cee453943967364c ] +Subject: [PATCH] sched: Allow pinned user tasks to be awakened to the CPU they + pinned Since commit 7af443ee16976 ("sched/core: Require cpu_active() in select_task_rq(), for user tasks") select_fallback_rq() will BUG() if @@ -19,14 +16,12 @@ Cc: stable-rt@vger.kernel.org Signed-off-by: Mike Galbraith Signed-off-by: Sebastian Andrzej Siewior --- - kernel/sched/core.c | 2 +- + kernel/sched/core.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) -diff --git a/kernel/sched/core.c b/kernel/sched/core.c -index e1fc94836fe0..6ce950f24a7f 100644 --- a/kernel/sched/core.c +++ b/kernel/sched/core.c -@@ -980,7 +980,7 @@ static inline bool is_cpu_allowed(struct task_struct *p, int cpu) +@@ -902,7 +902,7 @@ static inline bool is_cpu_allowed(struct if (!cpumask_test_cpu(cpu, p->cpus_ptr)) return false; @@ -35,6 +30,3 @@ index e1fc94836fe0..6ce950f24a7f 100644 return cpu_online(cpu); return cpu_active(cpu); --- -2.19.2 - diff --git a/kernel/patches-4.14.x-rt/0364-hotplug-duct-tape-RT-rwlock-usage-for-non-RT.patch b/kernel/patches-4.19.x-rt/0234-hotplug-duct-tape-RT-rwlock-usage-for-non-RT.patch similarity index 73% rename from kernel/patches-4.14.x-rt/0364-hotplug-duct-tape-RT-rwlock-usage-for-non-RT.patch rename to kernel/patches-4.19.x-rt/0234-hotplug-duct-tape-RT-rwlock-usage-for-non-RT.patch index 4aafd93fe..fa9c3485b 100644 --- a/kernel/patches-4.14.x-rt/0364-hotplug-duct-tape-RT-rwlock-usage-for-non-RT.patch +++ b/kernel/patches-4.19.x-rt/0234-hotplug-duct-tape-RT-rwlock-usage-for-non-RT.patch @@ -1,7 +1,6 @@ -From f94abf1239c11e181f09b117bc25e76247778145 Mon Sep 17 00:00:00 2001 From: Sebastian Andrzej Siewior Date: Fri, 4 Aug 2017 18:31:00 +0200 -Subject: [PATCH 364/450] hotplug: duct-tape RT-rwlock usage for non-RT +Subject: [PATCH] hotplug: duct-tape RT-rwlock usage for non-RT This type is only available on -RT. We need to craft something for non-RT. Since the only migrate_disable() user is -RT only, there is no @@ -9,14 +8,12 @@ damage. Signed-off-by: Sebastian Andrzej Siewior --- - kernel/cpu.c | 14 +++++++++++++- + kernel/cpu.c | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) -diff --git a/kernel/cpu.c b/kernel/cpu.c -index bc97ca16de81..7f73ec1d95e6 100644 --- a/kernel/cpu.c +++ b/kernel/cpu.c -@@ -75,7 +75,7 @@ static DEFINE_PER_CPU(struct cpuhp_cpu_state, cpuhp_state) = { +@@ -75,7 +75,7 @@ static DEFINE_PER_CPU(struct cpuhp_cpu_s .fail = CPUHP_INVALID, }; @@ -25,7 +22,7 @@ index bc97ca16de81..7f73ec1d95e6 100644 static DEFINE_PER_CPU(struct rt_rw_lock, cpuhp_pin_lock) = \ __RWLOCK_RT_INITIALIZER(cpuhp_pin_lock); #endif -@@ -298,6 +298,7 @@ static int cpu_hotplug_disabled; +@@ -291,6 +291,7 @@ static int cpu_hotplug_disabled; */ void pin_current_cpu(void) { @@ -33,7 +30,7 @@ index bc97ca16de81..7f73ec1d95e6 100644 struct rt_rw_lock *cpuhp_pin; unsigned int cpu; int ret; -@@ -322,6 +323,7 @@ void pin_current_cpu(void) +@@ -313,6 +314,7 @@ void pin_current_cpu(void) goto again; } current->pinned_on_cpu = cpu; @@ -41,7 +38,7 @@ index bc97ca16de81..7f73ec1d95e6 100644 } /** -@@ -329,6 +331,7 @@ void pin_current_cpu(void) +@@ -320,6 +322,7 @@ void pin_current_cpu(void) */ void unpin_current_cpu(void) { @@ -49,7 +46,7 @@ index bc97ca16de81..7f73ec1d95e6 100644 struct rt_rw_lock *cpuhp_pin = this_cpu_ptr(&cpuhp_pin_lock); if (WARN_ON(current->pinned_on_cpu != smp_processor_id())) -@@ -336,6 +339,7 @@ void unpin_current_cpu(void) +@@ -327,6 +330,7 @@ void unpin_current_cpu(void) current->pinned_on_cpu = -1; __read_rt_unlock(cpuhp_pin); @@ -57,7 +54,7 @@ index bc97ca16de81..7f73ec1d95e6 100644 } DEFINE_STATIC_PERCPU_RWSEM(cpu_hotplug_lock); -@@ -900,7 +904,9 @@ static int take_cpu_down(void *_param) +@@ -861,7 +865,9 @@ static int take_cpu_down(void *_param) static int takedown_cpu(unsigned int cpu) { @@ -67,7 +64,7 @@ index bc97ca16de81..7f73ec1d95e6 100644 struct cpuhp_cpu_state *st = per_cpu_ptr(&cpuhp_state, cpu); int err; -@@ -913,14 +919,18 @@ static int takedown_cpu(unsigned int cpu) +@@ -874,14 +880,18 @@ static int takedown_cpu(unsigned int cpu */ irq_lock_sparse(); @@ -86,7 +83,7 @@ index bc97ca16de81..7f73ec1d95e6 100644 /* CPU refused to die */ irq_unlock_sparse(); /* Unpark the hotplug thread so we can rollback there */ -@@ -939,7 +949,9 @@ static int takedown_cpu(unsigned int cpu) +@@ -900,7 +910,9 @@ static int takedown_cpu(unsigned int cpu wait_for_ap_thread(st, false); BUG_ON(st->state != CPUHP_AP_IDLE_DEAD); @@ -96,6 +93,3 @@ index bc97ca16de81..7f73ec1d95e6 100644 /* Interrupts are moved away from the dying cpu, reenable alloc/free */ irq_unlock_sparse(); --- -2.19.2 - diff --git a/kernel/patches-4.14.x-rt/0366-net-Remove-preemption-disabling-in-netif_rx.patch b/kernel/patches-4.19.x-rt/0235-upstream-net-rt-remove-preemption-disabling-in-netif_rx.patch similarity index 81% rename from kernel/patches-4.14.x-rt/0366-net-Remove-preemption-disabling-in-netif_rx.patch rename to kernel/patches-4.19.x-rt/0235-upstream-net-rt-remove-preemption-disabling-in-netif_rx.patch index 6ba607e01..8a74934c0 100644 --- a/kernel/patches-4.14.x-rt/0366-net-Remove-preemption-disabling-in-netif_rx.patch +++ b/kernel/patches-4.19.x-rt/0235-upstream-net-rt-remove-preemption-disabling-in-netif_rx.patch @@ -1,7 +1,6 @@ -From cb63600a11ea7567c15f2143452d9cffe42b1b3a Mon Sep 17 00:00:00 2001 +Subject: net: Remove preemption disabling in netif_rx() From: Priyanka Jain Date: Thu, 17 May 2012 09:35:11 +0530 -Subject: [PATCH 366/450] net: Remove preemption disabling in netif_rx() 1)enqueue_to_backlog() (called from netif_rx) should be bind to a particluar CPU. This can be achieved by @@ -31,14 +30,14 @@ Link: http://lkml.kernel.org/r/1337227511-2271-1-git-send-email-Priyanka.Jain@fr Signed-off-by: Thomas Gleixner --- - net/core/dev.c | 8 ++++---- + Testing: Tested successfully on p4080ds(8-core SMP system) + + net/core/dev.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) -diff --git a/net/core/dev.c b/net/core/dev.c -index 8f40b36c2ec3..3aa9256869b2 100644 --- a/net/core/dev.c +++ b/net/core/dev.c -@@ -4068,7 +4068,7 @@ static int netif_rx_internal(struct sk_buff *skb) +@@ -4470,7 +4470,7 @@ static int netif_rx_internal(struct sk_b struct rps_dev_flow voidflow, *rflow = &voidflow; int cpu; @@ -47,7 +46,7 @@ index 8f40b36c2ec3..3aa9256869b2 100644 rcu_read_lock(); cpu = get_rps_cpu(skb->dev, skb, &rflow); -@@ -4078,14 +4078,14 @@ static int netif_rx_internal(struct sk_buff *skb) +@@ -4480,14 +4480,14 @@ static int netif_rx_internal(struct sk_b ret = enqueue_to_backlog(skb, cpu, &rflow->last_qtail); rcu_read_unlock(); @@ -65,6 +64,3 @@ index 8f40b36c2ec3..3aa9256869b2 100644 } return ret; } --- -2.19.2 - diff --git a/kernel/patches-4.14.x-rt/0367-net-Another-local_irq_disable-kmalloc-headache.patch b/kernel/patches-4.19.x-rt/0236-net-another-local-irq-disable-alloc-atomic-headache.patch similarity index 75% rename from kernel/patches-4.14.x-rt/0367-net-Another-local_irq_disable-kmalloc-headache.patch rename to kernel/patches-4.19.x-rt/0236-net-another-local-irq-disable-alloc-atomic-headache.patch index 487de0396..6bb46fc3f 100644 --- a/kernel/patches-4.14.x-rt/0367-net-Another-local_irq_disable-kmalloc-headache.patch +++ b/kernel/patches-4.19.x-rt/0236-net-another-local-irq-disable-alloc-atomic-headache.patch @@ -1,17 +1,14 @@ -From 1582331d109290155c4ee90d393240f9f604de9a Mon Sep 17 00:00:00 2001 From: Thomas Gleixner Date: Wed, 26 Sep 2012 16:21:08 +0200 -Subject: [PATCH 367/450] net: Another local_irq_disable/kmalloc headache +Subject: net: Another local_irq_disable/kmalloc headache Replace it by a local lock. Though that's pretty inefficient :( Signed-off-by: Thomas Gleixner --- - net/core/skbuff.c | 10 ++++++---- + net/core/skbuff.c | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) -diff --git a/net/core/skbuff.c b/net/core/skbuff.c -index 4067fa3fcbb2..1bb67588ca5a 100644 --- a/net/core/skbuff.c +++ b/net/core/skbuff.c @@ -63,6 +63,7 @@ @@ -30,7 +27,7 @@ index 4067fa3fcbb2..1bb67588ca5a 100644 static void *__netdev_alloc_frag(unsigned int fragsz, gfp_t gfp_mask) { -@@ -337,10 +339,10 @@ static void *__netdev_alloc_frag(unsigned int fragsz, gfp_t gfp_mask) +@@ -337,10 +339,10 @@ static void *__netdev_alloc_frag(unsigne unsigned long flags; void *data; @@ -43,7 +40,7 @@ index 4067fa3fcbb2..1bb67588ca5a 100644 return data; } -@@ -408,13 +410,13 @@ struct sk_buff *__netdev_alloc_skb(struct net_device *dev, unsigned int len, +@@ -412,13 +414,13 @@ struct sk_buff *__netdev_alloc_skb(struc if (sk_memalloc_socks()) gfp_mask |= __GFP_MEMALLOC; @@ -59,6 +56,3 @@ index 4067fa3fcbb2..1bb67588ca5a 100644 if (unlikely(!data)) return NULL; --- -2.19.2 - diff --git a/kernel/patches-4.14.x-rt/0368-net-core-protect-users-of-napi_alloc_cache-against-r.patch b/kernel/patches-4.19.x-rt/0237-net-core-protect-users-of-napi_alloc_cache-against-r.patch similarity index 80% rename from kernel/patches-4.14.x-rt/0368-net-core-protect-users-of-napi_alloc_cache-against-r.patch rename to kernel/patches-4.19.x-rt/0237-net-core-protect-users-of-napi_alloc_cache-against-r.patch index 3bb4d3fd1..64cbb8557 100644 --- a/kernel/patches-4.14.x-rt/0368-net-core-protect-users-of-napi_alloc_cache-against-r.patch +++ b/kernel/patches-4.19.x-rt/0237-net-core-protect-users-of-napi_alloc_cache-against-r.patch @@ -1,7 +1,6 @@ -From 6cf8f87baddba1e9fc5d04d1ada5e2c89550e03a Mon Sep 17 00:00:00 2001 From: Sebastian Andrzej Siewior Date: Fri, 15 Jan 2016 16:33:34 +0100 -Subject: [PATCH 368/450] net/core: protect users of napi_alloc_cache against +Subject: net/core: protect users of napi_alloc_cache against reentrance On -RT the code running in BH can not be moved to another CPU so CPU @@ -13,11 +12,9 @@ This patch ensures that each user of napi_alloc_cache uses a local lock. Cc: stable-rt@vger.kernel.org Signed-off-by: Sebastian Andrzej Siewior --- - net/core/skbuff.c | 25 +++++++++++++++++++------ + net/core/skbuff.c | 25 +++++++++++++++++++------ 1 file changed, 19 insertions(+), 6 deletions(-) -diff --git a/net/core/skbuff.c b/net/core/skbuff.c -index 1bb67588ca5a..8ec36697002b 100644 --- a/net/core/skbuff.c +++ b/net/core/skbuff.c @@ -332,6 +332,7 @@ struct napi_alloc_cache { @@ -28,7 +25,7 @@ index 1bb67588ca5a..8ec36697002b 100644 static void *__netdev_alloc_frag(unsigned int fragsz, gfp_t gfp_mask) { -@@ -361,9 +362,13 @@ EXPORT_SYMBOL(netdev_alloc_frag); +@@ -363,9 +364,13 @@ EXPORT_SYMBOL(netdev_alloc_frag); static void *__napi_alloc_frag(unsigned int fragsz, gfp_t gfp_mask) { @@ -44,7 +41,7 @@ index 1bb67588ca5a..8ec36697002b 100644 } void *napi_alloc_frag(unsigned int fragsz) -@@ -457,9 +462,10 @@ EXPORT_SYMBOL(__netdev_alloc_skb); +@@ -461,9 +466,10 @@ EXPORT_SYMBOL(__netdev_alloc_skb); struct sk_buff *__napi_alloc_skb(struct napi_struct *napi, unsigned int len, gfp_t gfp_mask) { @@ -56,7 +53,7 @@ index 1bb67588ca5a..8ec36697002b 100644 len += NET_SKB_PAD + NET_IP_ALIGN; -@@ -477,7 +483,10 @@ struct sk_buff *__napi_alloc_skb(struct napi_struct *napi, unsigned int len, +@@ -481,7 +487,10 @@ struct sk_buff *__napi_alloc_skb(struct if (sk_memalloc_socks()) gfp_mask |= __GFP_MEMALLOC; @@ -67,7 +64,7 @@ index 1bb67588ca5a..8ec36697002b 100644 if (unlikely(!data)) return NULL; -@@ -488,7 +497,7 @@ struct sk_buff *__napi_alloc_skb(struct napi_struct *napi, unsigned int len, +@@ -492,7 +501,7 @@ struct sk_buff *__napi_alloc_skb(struct } /* use OR instead of assignment to avoid clearing of bits in mask */ @@ -76,7 +73,7 @@ index 1bb67588ca5a..8ec36697002b 100644 skb->pfmemalloc = 1; skb->head_frag = 1; -@@ -720,23 +729,26 @@ void __consume_stateless_skb(struct sk_buff *skb) +@@ -724,23 +733,26 @@ void __consume_stateless_skb(struct sk_b void __kfree_skb_flush(void) { @@ -105,7 +102,7 @@ index 1bb67588ca5a..8ec36697002b 100644 /* record skb to CPU local list */ nc->skb_cache[nc->skb_count++] = skb; -@@ -751,6 +763,7 @@ static inline void _kfree_skb_defer(struct sk_buff *skb) +@@ -755,6 +767,7 @@ static inline void _kfree_skb_defer(stru nc->skb_cache); nc->skb_count = 0; } @@ -113,6 +110,3 @@ index 1bb67588ca5a..8ec36697002b 100644 } void __kfree_skb_defer(struct sk_buff *skb) { --- -2.19.2 - diff --git a/kernel/patches-4.14.x-rt/0369-net-netfilter-Serialize-xt_write_recseq-sections-on-.patch b/kernel/patches-4.19.x-rt/0238-net-fix-iptable-xt-write-recseq-begin-rt-fallout.patch similarity index 66% rename from kernel/patches-4.14.x-rt/0369-net-netfilter-Serialize-xt_write_recseq-sections-on-.patch rename to kernel/patches-4.19.x-rt/0238-net-fix-iptable-xt-write-recseq-begin-rt-fallout.patch index 85e7b08d8..c8ac66972 100644 --- a/kernel/patches-4.14.x-rt/0369-net-netfilter-Serialize-xt_write_recseq-sections-on-.patch +++ b/kernel/patches-4.19.x-rt/0238-net-fix-iptable-xt-write-recseq-begin-rt-fallout.patch @@ -1,8 +1,6 @@ -From f1bade1c769369bc88fd39199fac306dbe7ce9af Mon Sep 17 00:00:00 2001 +Subject: net: netfilter: Serialize xt_write_recseq sections on RT From: Thomas Gleixner Date: Sun, 28 Oct 2012 11:18:08 +0100 -Subject: [PATCH 369/450] net: netfilter: Serialize xt_write_recseq sections on - RT The netfilter code relies only on the implicit semantics of local_bh_disable() for serializing wt_write_recseq sections. RT breaks @@ -10,13 +8,12 @@ that and needs explicit serialization here. Reported-by: Peter LaDow Signed-off-by: Thomas Gleixner + --- - include/linux/netfilter/x_tables.h | 7 +++++++ - net/netfilter/core.c | 6 ++++++ + include/linux/netfilter/x_tables.h | 7 +++++++ + net/netfilter/core.c | 6 ++++++ 2 files changed, 13 insertions(+) -diff --git a/include/linux/netfilter/x_tables.h b/include/linux/netfilter/x_tables.h -index 54f346a45cd0..79723e76af66 100644 --- a/include/linux/netfilter/x_tables.h +++ b/include/linux/netfilter/x_tables.h @@ -6,6 +6,7 @@ @@ -27,7 +24,7 @@ index 54f346a45cd0..79723e76af66 100644 #include /* Test a struct->invflags and a boolean for inequality */ -@@ -341,6 +342,8 @@ void xt_free_table_info(struct xt_table_info *info); +@@ -345,6 +346,8 @@ void xt_free_table_info(struct xt_table_ */ DECLARE_PER_CPU(seqcount_t, xt_recseq); @@ -36,7 +33,7 @@ index 54f346a45cd0..79723e76af66 100644 /* xt_tee_enabled - true if x_tables needs to handle reentrancy * * Enabled if current ip(6)tables ruleset has at least one -j TEE rule. -@@ -361,6 +364,9 @@ static inline unsigned int xt_write_recseq_begin(void) +@@ -365,6 +368,9 @@ static inline unsigned int xt_write_recs { unsigned int addend; @@ -46,7 +43,7 @@ index 54f346a45cd0..79723e76af66 100644 /* * Low order bit of sequence is set if we already * called xt_write_recseq_begin(). -@@ -391,6 +397,7 @@ static inline void xt_write_recseq_end(unsigned int addend) +@@ -395,6 +401,7 @@ static inline void xt_write_recseq_end(u /* this is kind of a write_seqcount_end(), but addend is 0 or 1 */ smp_wmb(); __this_cpu_add(xt_recseq.sequence, addend); @@ -54,11 +51,9 @@ index 54f346a45cd0..79723e76af66 100644 } /* -diff --git a/net/netfilter/core.c b/net/netfilter/core.c -index 52cd2901a097..c63e937b6676 100644 --- a/net/netfilter/core.c +++ b/net/netfilter/core.c -@@ -21,6 +21,7 @@ +@@ -20,6 +20,7 @@ #include #include #include @@ -66,7 +61,7 @@ index 52cd2901a097..c63e937b6676 100644 #include #include #include -@@ -28,6 +29,11 @@ +@@ -27,6 +28,11 @@ #include "nf_internals.h" @@ -75,9 +70,6 @@ index 52cd2901a097..c63e937b6676 100644 +EXPORT_PER_CPU_SYMBOL(xt_write_lock); +#endif + - static DEFINE_MUTEX(afinfo_mutex); + const struct nf_ipv6_ops __rcu *nf_ipv6_ops __read_mostly; + EXPORT_SYMBOL_GPL(nf_ipv6_ops); - const struct nf_afinfo __rcu *nf_afinfo[NFPROTO_NUMPROTO] __read_mostly; --- -2.19.2 - diff --git a/kernel/patches-4.14.x-rt/0370-net-Add-a-mutex-around-devnet_rename_seq.patch b/kernel/patches-4.19.x-rt/0239-net-make-devnet_rename_seq-a-mutex.patch similarity index 77% rename from kernel/patches-4.14.x-rt/0370-net-Add-a-mutex-around-devnet_rename_seq.patch rename to kernel/patches-4.19.x-rt/0239-net-make-devnet_rename_seq-a-mutex.patch index a6b8f3231..d237db4d0 100644 --- a/kernel/patches-4.14.x-rt/0370-net-Add-a-mutex-around-devnet_rename_seq.patch +++ b/kernel/patches-4.19.x-rt/0239-net-make-devnet_rename_seq-a-mutex.patch @@ -1,7 +1,6 @@ -From f503f56d286c9e53fe956dbe3430b09967dc5970 Mon Sep 17 00:00:00 2001 From: Sebastian Andrzej Siewior Date: Wed, 20 Mar 2013 18:06:20 +0100 -Subject: [PATCH 370/450] net: Add a mutex around devnet_rename_seq +Subject: net: Add a mutex around devnet_rename_seq On RT write_seqcount_begin() disables preemption and device_rename() allocates memory with GFP_KERNEL and grabs later the sysfs_mutex @@ -17,14 +16,12 @@ it when it detects a writer in progress. This keeps the normal case Signed-off-by: Sebastian Andrzej Siewior Signed-off-by: Thomas Gleixner --- - net/core/dev.c | 34 ++++++++++++++++++++-------------- + net/core/dev.c | 34 ++++++++++++++++++++-------------- 1 file changed, 20 insertions(+), 14 deletions(-) -diff --git a/net/core/dev.c b/net/core/dev.c -index 3aa9256869b2..d1309f51d066 100644 --- a/net/core/dev.c +++ b/net/core/dev.c -@@ -195,6 +195,7 @@ static unsigned int napi_gen_id = NR_CPUS; +@@ -195,6 +195,7 @@ static unsigned int napi_gen_id = NR_CPU static DEFINE_READ_MOSTLY_HASHTABLE(napi_hash, 8); static seqcount_t devnet_rename_seq; @@ -32,7 +29,7 @@ index 3aa9256869b2..d1309f51d066 100644 static inline void dev_base_seq_inc(struct net *net) { -@@ -920,7 +921,8 @@ int netdev_get_name(struct net *net, char *name, int ifindex) +@@ -920,7 +921,8 @@ int netdev_get_name(struct net *net, cha strcpy(name, dev->name); rcu_read_unlock(); if (read_seqcount_retry(&devnet_rename_seq, seq)) { @@ -42,7 +39,7 @@ index 3aa9256869b2..d1309f51d066 100644 goto retry; } -@@ -1189,20 +1191,17 @@ int dev_change_name(struct net_device *dev, const char *newname) +@@ -1183,20 +1185,17 @@ int dev_change_name(struct net_device *d if (dev->flags & IFF_UP) return -EBUSY; @@ -69,7 +66,7 @@ index 3aa9256869b2..d1309f51d066 100644 if (oldname[0] && !strchr(oldname, '%')) netdev_info(dev, "renamed from %s\n", oldname); -@@ -1215,11 +1214,12 @@ int dev_change_name(struct net_device *dev, const char *newname) +@@ -1209,11 +1208,12 @@ int dev_change_name(struct net_device *d if (ret) { memcpy(dev->name, oldname, IFNAMSIZ); dev->name_assign_type = old_assign_type; @@ -85,7 +82,7 @@ index 3aa9256869b2..d1309f51d066 100644 netdev_adjacent_rename_links(dev, oldname); -@@ -1240,7 +1240,8 @@ int dev_change_name(struct net_device *dev, const char *newname) +@@ -1234,7 +1234,8 @@ int dev_change_name(struct net_device *d /* err >= 0 after dev_alloc_name() or stores the first errno */ if (err >= 0) { err = ret; @@ -95,7 +92,7 @@ index 3aa9256869b2..d1309f51d066 100644 memcpy(dev->name, oldname, IFNAMSIZ); memcpy(oldname, newname, IFNAMSIZ); dev->name_assign_type = old_assign_type; -@@ -1253,6 +1254,11 @@ int dev_change_name(struct net_device *dev, const char *newname) +@@ -1247,6 +1248,11 @@ int dev_change_name(struct net_device *d } return err; @@ -107,6 +104,3 @@ index 3aa9256869b2..d1309f51d066 100644 } /** --- -2.19.2 - diff --git a/kernel/patches-4.14.x-rt/0372-lockdep-selftest-Only-do-hardirq-context-test-for-ra.patch b/kernel/patches-4.19.x-rt/0240-lockdep-selftest-only-do-hardirq-context-test-for-raw-spinlock.patch similarity index 86% rename from kernel/patches-4.14.x-rt/0372-lockdep-selftest-Only-do-hardirq-context-test-for-ra.patch rename to kernel/patches-4.19.x-rt/0240-lockdep-selftest-only-do-hardirq-context-test-for-raw-spinlock.patch index c470dd3b7..6162cd2da 100644 --- a/kernel/patches-4.14.x-rt/0372-lockdep-selftest-Only-do-hardirq-context-test-for-ra.patch +++ b/kernel/patches-4.19.x-rt/0240-lockdep-selftest-only-do-hardirq-context-test-for-raw-spinlock.patch @@ -1,8 +1,8 @@ -From f3e9a706ad5104e136748227b3957ecdb5a1fe95 Mon Sep 17 00:00:00 2001 -From: Yong Zhang +Subject: lockdep: selftest: Only do hardirq context test for raw spinlock +From: Yong Zhang Date: Mon, 16 Apr 2012 15:01:56 +0800 -Subject: [PATCH 372/450] lockdep: selftest: Only do hardirq context test for - raw spinlock + +From: Yong Zhang On -rt there is no softirq context any more and rwlock is sleepable, disable softirq context test and rwlock+irq test. @@ -12,11 +12,9 @@ Cc: Yong Zhang Link: http://lkml.kernel.org/r/1334559716-18447-3-git-send-email-yong.zhang0@gmail.com Signed-off-by: Thomas Gleixner --- - lib/locking-selftest.c | 23 +++++++++++++++++++++++ + lib/locking-selftest.c | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) -diff --git a/lib/locking-selftest.c b/lib/locking-selftest.c -index b5c1293ce147..7a452887c9c3 100644 --- a/lib/locking-selftest.c +++ b/lib/locking-selftest.c @@ -2057,6 +2057,7 @@ void locking_selftest(void) @@ -56,6 +54,3 @@ index b5c1293ce147..7a452887c9c3 100644 ww_tests(); --- -2.19.2 - diff --git a/kernel/patches-4.14.x-rt/0373-lockdep-selftest-fix-warnings-due-to-missing-PREEMPT.patch b/kernel/patches-4.19.x-rt/0241-lockdep-selftest-fix-warnings-due-to-missing-PREEMPT.patch similarity index 75% rename from kernel/patches-4.14.x-rt/0373-lockdep-selftest-fix-warnings-due-to-missing-PREEMPT.patch rename to kernel/patches-4.19.x-rt/0241-lockdep-selftest-fix-warnings-due-to-missing-PREEMPT.patch index bab26647c..01cc757dd 100644 --- a/kernel/patches-4.14.x-rt/0373-lockdep-selftest-fix-warnings-due-to-missing-PREEMPT.patch +++ b/kernel/patches-4.19.x-rt/0241-lockdep-selftest-fix-warnings-due-to-missing-PREEMPT.patch @@ -1,8 +1,6 @@ -From ccbca38a3469e06ecbd3bda0725b2228afc68ab6 Mon Sep 17 00:00:00 2001 From: Josh Cartwright Date: Wed, 28 Jan 2015 13:08:45 -0600 -Subject: [PATCH 373/450] lockdep: selftest: fix warnings due to missing - PREEMPT_RT conditionals +Subject: lockdep: selftest: fix warnings due to missing PREEMPT_RT conditionals "lockdep: Selftest: Only do hardirq context test for raw spinlock" disabled the execution of certain tests with PREEMPT_RT_FULL, but did @@ -25,11 +23,9 @@ Signed-off-by: Xander Huff Acked-by: Gratian Crisan Signed-off-by: Sebastian Andrzej Siewior --- - lib/locking-selftest.c | 27 +++++++++++++++++++++++++++ + lib/locking-selftest.c | 27 +++++++++++++++++++++++++++ 1 file changed, 27 insertions(+) -diff --git a/lib/locking-selftest.c b/lib/locking-selftest.c -index 7a452887c9c3..075e225f4111 100644 --- a/lib/locking-selftest.c +++ b/lib/locking-selftest.c @@ -742,6 +742,8 @@ GENERATE_TESTCASE(init_held_rtmutex); @@ -41,7 +37,7 @@ index 7a452887c9c3..075e225f4111 100644 #include "locking-selftest-rlock-hardirq.h" GENERATE_PERMUTATIONS_2_EVENTS(irqsafe1_hard_rlock) -@@ -757,9 +759,12 @@ GENERATE_PERMUTATIONS_2_EVENTS(irqsafe1_soft_rlock) +@@ -757,9 +759,12 @@ GENERATE_PERMUTATIONS_2_EVENTS(irqsafe1_ #include "locking-selftest-wlock-softirq.h" GENERATE_PERMUTATIONS_2_EVENTS(irqsafe1_soft_wlock) @@ -54,7 +50,7 @@ index 7a452887c9c3..075e225f4111 100644 /* * Enabling hardirqs with a softirq-safe lock held: */ -@@ -792,6 +797,8 @@ GENERATE_PERMUTATIONS_2_EVENTS(irqsafe2A_rlock) +@@ -792,6 +797,8 @@ GENERATE_PERMUTATIONS_2_EVENTS(irqsafe2A #undef E1 #undef E2 @@ -63,7 +59,7 @@ index 7a452887c9c3..075e225f4111 100644 /* * Enabling irqs with an irq-safe lock held: */ -@@ -815,6 +822,8 @@ GENERATE_PERMUTATIONS_2_EVENTS(irqsafe2A_rlock) +@@ -815,6 +822,8 @@ GENERATE_PERMUTATIONS_2_EVENTS(irqsafe2A #include "locking-selftest-spin-hardirq.h" GENERATE_PERMUTATIONS_2_EVENTS(irqsafe2B_hard_spin) @@ -72,7 +68,7 @@ index 7a452887c9c3..075e225f4111 100644 #include "locking-selftest-rlock-hardirq.h" GENERATE_PERMUTATIONS_2_EVENTS(irqsafe2B_hard_rlock) -@@ -830,6 +839,8 @@ GENERATE_PERMUTATIONS_2_EVENTS(irqsafe2B_soft_rlock) +@@ -830,6 +839,8 @@ GENERATE_PERMUTATIONS_2_EVENTS(irqsafe2B #include "locking-selftest-wlock-softirq.h" GENERATE_PERMUTATIONS_2_EVENTS(irqsafe2B_soft_wlock) @@ -81,7 +77,7 @@ index 7a452887c9c3..075e225f4111 100644 #undef E1 #undef E2 -@@ -861,6 +872,8 @@ GENERATE_PERMUTATIONS_2_EVENTS(irqsafe2B_soft_wlock) +@@ -861,6 +872,8 @@ GENERATE_PERMUTATIONS_2_EVENTS(irqsafe2B #include "locking-selftest-spin-hardirq.h" GENERATE_PERMUTATIONS_3_EVENTS(irqsafe3_hard_spin) @@ -90,7 +86,7 @@ index 7a452887c9c3..075e225f4111 100644 #include "locking-selftest-rlock-hardirq.h" GENERATE_PERMUTATIONS_3_EVENTS(irqsafe3_hard_rlock) -@@ -876,6 +889,8 @@ GENERATE_PERMUTATIONS_3_EVENTS(irqsafe3_soft_rlock) +@@ -876,6 +889,8 @@ GENERATE_PERMUTATIONS_3_EVENTS(irqsafe3_ #include "locking-selftest-wlock-softirq.h" GENERATE_PERMUTATIONS_3_EVENTS(irqsafe3_soft_wlock) @@ -99,7 +95,7 @@ index 7a452887c9c3..075e225f4111 100644 #undef E1 #undef E2 #undef E3 -@@ -909,6 +924,8 @@ GENERATE_PERMUTATIONS_3_EVENTS(irqsafe3_soft_wlock) +@@ -909,6 +924,8 @@ GENERATE_PERMUTATIONS_3_EVENTS(irqsafe3_ #include "locking-selftest-spin-hardirq.h" GENERATE_PERMUTATIONS_3_EVENTS(irqsafe4_hard_spin) @@ -108,7 +104,7 @@ index 7a452887c9c3..075e225f4111 100644 #include "locking-selftest-rlock-hardirq.h" GENERATE_PERMUTATIONS_3_EVENTS(irqsafe4_hard_rlock) -@@ -924,10 +941,14 @@ GENERATE_PERMUTATIONS_3_EVENTS(irqsafe4_soft_rlock) +@@ -924,10 +941,14 @@ GENERATE_PERMUTATIONS_3_EVENTS(irqsafe4_ #include "locking-selftest-wlock-softirq.h" GENERATE_PERMUTATIONS_3_EVENTS(irqsafe4_soft_wlock) @@ -123,7 +119,7 @@ index 7a452887c9c3..075e225f4111 100644 /* * read-lock / write-lock irq inversion. * -@@ -990,6 +1011,10 @@ GENERATE_PERMUTATIONS_3_EVENTS(irq_inversion_soft_wlock) +@@ -990,6 +1011,10 @@ GENERATE_PERMUTATIONS_3_EVENTS(irq_inver #undef E2 #undef E3 @@ -134,7 +130,7 @@ index 7a452887c9c3..075e225f4111 100644 /* * read-lock / write-lock recursion that is actually safe. */ -@@ -1028,6 +1053,8 @@ GENERATE_PERMUTATIONS_3_EVENTS(irq_read_recursion_soft) +@@ -1028,6 +1053,8 @@ GENERATE_PERMUTATIONS_3_EVENTS(irq_read_ #undef E2 #undef E3 @@ -143,6 +139,3 @@ index 7a452887c9c3..075e225f4111 100644 /* * read-lock / write-lock recursion that is unsafe. */ --- -2.19.2 - diff --git a/kernel/patches-4.14.x-rt/0381-sched-Add-support-for-lazy-preemption.patch b/kernel/patches-4.19.x-rt/0242-preempt-lazy-support.patch similarity index 77% rename from kernel/patches-4.14.x-rt/0381-sched-Add-support-for-lazy-preemption.patch rename to kernel/patches-4.19.x-rt/0242-preempt-lazy-support.patch index 5c1f3b658..a8353ec2f 100644 --- a/kernel/patches-4.14.x-rt/0381-sched-Add-support-for-lazy-preemption.patch +++ b/kernel/patches-4.19.x-rt/0242-preempt-lazy-support.patch @@ -1,7 +1,6 @@ -From e12239c4111671341a3541f2d5bf0c11ab461a95 Mon Sep 17 00:00:00 2001 +Subject: sched: Add support for lazy preemption From: Thomas Gleixner Date: Fri, 26 Oct 2012 18:50:54 +0100 -Subject: [PATCH 381/450] sched: Add support for lazy preemption It has become an obsession to mitigate the determinism vs. throughput loss of RT. Looking at the mainline semantics of preemption points @@ -53,22 +52,21 @@ performance. Signed-off-by: Thomas Gleixner --- - include/linux/preempt.h | 35 ++++++++++++++- - include/linux/sched.h | 38 +++++++++++++++++ - include/linux/thread_info.h | 12 +++++- - include/linux/trace_events.h | 1 + - kernel/Kconfig.preempt | 6 +++ - kernel/sched/core.c | 83 +++++++++++++++++++++++++++++++++++- - kernel/sched/fair.c | 16 +++---- - kernel/sched/features.h | 3 ++ - kernel/sched/sched.h | 9 ++++ - kernel/trace/trace.c | 36 +++++++++------- - kernel/trace/trace.h | 2 + - kernel/trace/trace_output.c | 14 +++++- - 12 files changed, 226 insertions(+), 29 deletions(-) + include/linux/preempt.h | 35 +++++++++++++++++- + include/linux/sched.h | 38 +++++++++++++++++++ + include/linux/thread_info.h | 12 +++++- + include/linux/trace_events.h | 1 + kernel/Kconfig.preempt | 6 +++ + kernel/cpu.c | 2 + + kernel/sched/core.c | 83 +++++++++++++++++++++++++++++++++++++++++-- + kernel/sched/fair.c | 16 ++++---- + kernel/sched/features.h | 3 + + kernel/sched/sched.h | 9 ++++ + kernel/trace/trace.c | 36 ++++++++++-------- + kernel/trace/trace.h | 2 + + kernel/trace/trace_output.c | 14 ++++++- + 13 files changed, 228 insertions(+), 29 deletions(-) -diff --git a/include/linux/preempt.h b/include/linux/preempt.h -index fd2efc6ffc3f..0591df500e9d 100644 --- a/include/linux/preempt.h +++ b/include/linux/preempt.h @@ -180,6 +180,20 @@ extern void preempt_count_sub(int val); @@ -141,11 +139,9 @@ index fd2efc6ffc3f..0591df500e9d 100644 set_preempt_need_resched(); \ } while (0) -diff --git a/include/linux/sched.h b/include/linux/sched.h -index ac1e8dd32a6f..462baf19cf41 100644 --- a/include/linux/sched.h +++ b/include/linux/sched.h -@@ -1670,6 +1670,44 @@ static inline int test_tsk_need_resched(struct task_struct *tsk) +@@ -1725,6 +1725,44 @@ static inline int test_tsk_need_resched( return unlikely(test_tsk_thread_flag(tsk,TIF_NEED_RESCHED)); } @@ -190,11 +186,9 @@ index ac1e8dd32a6f..462baf19cf41 100644 static inline bool __task_is_stopped_or_traced(struct task_struct *task) { if (task->state & (__TASK_STOPPED | __TASK_TRACED)) -diff --git a/include/linux/thread_info.h b/include/linux/thread_info.h -index cf2862bd134a..fd05d83740df 100644 --- a/include/linux/thread_info.h +++ b/include/linux/thread_info.h -@@ -86,7 +86,17 @@ static inline int test_ti_thread_flag(struct thread_info *ti, int flag) +@@ -97,7 +97,17 @@ static inline int test_ti_thread_flag(st #define test_thread_flag(flag) \ test_ti_thread_flag(current_thread_info(), flag) @@ -213,8 +207,6 @@ index cf2862bd134a..fd05d83740df 100644 #ifndef CONFIG_HAVE_ARCH_WITHIN_STACK_FRAMES static inline int arch_within_stack_frames(const void * const stack, -diff --git a/include/linux/trace_events.h b/include/linux/trace_events.h -index ffd595ab5008..edd1e42e8a2f 100644 --- a/include/linux/trace_events.h +++ b/include/linux/trace_events.h @@ -64,6 +64,7 @@ struct trace_entry { @@ -225,8 +217,6 @@ index ffd595ab5008..edd1e42e8a2f 100644 }; #define TRACE_EVENT_TYPE_MAX \ -diff --git a/kernel/Kconfig.preempt b/kernel/Kconfig.preempt -index f8a2982bdbde..11dbe26a8279 100644 --- a/kernel/Kconfig.preempt +++ b/kernel/Kconfig.preempt @@ -6,6 +6,12 @@ config PREEMPT_RT_BASE @@ -242,11 +232,25 @@ index f8a2982bdbde..11dbe26a8279 100644 choice prompt "Preemption Model" default PREEMPT_NONE -diff --git a/kernel/sched/core.c b/kernel/sched/core.c -index c304127bee78..64f3c372776b 100644 +--- a/kernel/cpu.c ++++ b/kernel/cpu.c +@@ -304,11 +304,13 @@ void pin_current_cpu(void) + return; + } + cpu = smp_processor_id(); ++ preempt_lazy_enable(); + preempt_enable(); + + __read_rt_lock(cpuhp_pin); + + preempt_disable(); ++ preempt_lazy_disable(); + if (cpu != smp_processor_id()) { + __read_rt_unlock(cpuhp_pin); + goto again; --- a/kernel/sched/core.c +++ b/kernel/sched/core.c -@@ -518,6 +518,48 @@ void resched_curr(struct rq *rq) +@@ -491,6 +491,48 @@ void resched_curr(struct rq *rq) trace_sched_wake_idle_without_ipi(cpu); } @@ -295,7 +299,7 @@ index c304127bee78..64f3c372776b 100644 void resched_cpu(int cpu) { struct rq *rq = cpu_rq(cpu); -@@ -2462,6 +2504,9 @@ int sched_fork(unsigned long clone_flags, struct task_struct *p) +@@ -2403,6 +2445,9 @@ int sched_fork(unsigned long clone_flags p->on_cpu = 0; #endif init_task_preempt_count(p); @@ -305,7 +309,7 @@ index c304127bee78..64f3c372776b 100644 #ifdef CONFIG_SMP plist_node_init(&p->pushable_tasks, MAX_PRIO); RB_CLEAR_NODE(&p->pushable_dl_tasks); -@@ -3379,6 +3424,7 @@ static void __sched notrace __schedule(bool preempt) +@@ -3470,6 +3515,7 @@ static void __sched notrace __schedule(b next = pick_next_task(rq, prev, &rf); clear_tsk_need_resched(prev); @@ -313,7 +317,7 @@ index c304127bee78..64f3c372776b 100644 clear_preempt_need_resched(); if (likely(prev != next)) { -@@ -3554,6 +3600,30 @@ static void __sched notrace preempt_schedule_common(void) +@@ -3650,6 +3696,30 @@ static void __sched notrace preempt_sche } while (need_resched()); } @@ -344,7 +348,7 @@ index c304127bee78..64f3c372776b 100644 #ifdef CONFIG_PREEMPT /* * this is the entry point to schedule() from in-kernel preemption -@@ -3568,7 +3638,8 @@ asmlinkage __visible void __sched notrace preempt_schedule(void) +@@ -3664,7 +3734,8 @@ asmlinkage __visible void __sched notrac */ if (likely(!preemptible())) return; @@ -354,7 +358,7 @@ index c304127bee78..64f3c372776b 100644 preempt_schedule_common(); } NOKPROBE_SYMBOL(preempt_schedule); -@@ -3595,6 +3666,9 @@ asmlinkage __visible void __sched notrace preempt_schedule_notrace(void) +@@ -3691,6 +3762,9 @@ asmlinkage __visible void __sched notrac if (likely(!preemptible())) return; @@ -364,7 +368,7 @@ index c304127bee78..64f3c372776b 100644 do { /* * Because the function tracer can trace preempt_count_sub() -@@ -5334,7 +5408,9 @@ void init_idle(struct task_struct *idle, int cpu) +@@ -5459,7 +5533,9 @@ void init_idle(struct task_struct *idle, /* Set the preempt count _outside_ the spinlocks! */ init_idle_preempt_count(idle, cpu); @@ -375,7 +379,7 @@ index c304127bee78..64f3c372776b 100644 /* * The idle tasks have their own, simple scheduling class: */ -@@ -6890,6 +6966,7 @@ void migrate_disable(void) +@@ -7181,6 +7257,7 @@ void migrate_disable(void) } preempt_disable(); @@ -383,7 +387,7 @@ index c304127bee78..64f3c372776b 100644 pin_current_cpu(); migrate_disable_update_cpus_allowed(p); -@@ -6957,6 +7034,7 @@ void migrate_enable(void) +@@ -7248,6 +7325,7 @@ void migrate_enable(void) arg.dest_cpu = dest_cpu; unpin_current_cpu(); @@ -391,7 +395,7 @@ index c304127bee78..64f3c372776b 100644 preempt_enable(); stop_one_cpu(task_cpu(p), migration_cpu_stop, &arg); tlb_migrate_finish(p->mm); -@@ -6965,6 +7043,7 @@ void migrate_enable(void) +@@ -7256,6 +7334,7 @@ void migrate_enable(void) } } unpin_current_cpu(); @@ -399,11 +403,9 @@ index c304127bee78..64f3c372776b 100644 preempt_enable(); } EXPORT_SYMBOL(migrate_enable); -diff --git a/kernel/sched/fair.c b/kernel/sched/fair.c -index 304a7ebc7657..9cae149e78b6 100644 --- a/kernel/sched/fair.c +++ b/kernel/sched/fair.c -@@ -3842,7 +3842,7 @@ check_preempt_tick(struct cfs_rq *cfs_rq, struct sched_entity *curr) +@@ -4017,7 +4017,7 @@ check_preempt_tick(struct cfs_rq *cfs_rq ideal_runtime = sched_slice(cfs_rq, curr); delta_exec = curr->sum_exec_runtime - curr->prev_sum_exec_runtime; if (delta_exec > ideal_runtime) { @@ -412,7 +414,7 @@ index 304a7ebc7657..9cae149e78b6 100644 /* * The current task ran long enough, ensure it doesn't get * re-elected due to buddy favours. -@@ -3866,7 +3866,7 @@ check_preempt_tick(struct cfs_rq *cfs_rq, struct sched_entity *curr) +@@ -4041,7 +4041,7 @@ check_preempt_tick(struct cfs_rq *cfs_rq return; if (delta > ideal_runtime) @@ -421,7 +423,7 @@ index 304a7ebc7657..9cae149e78b6 100644 } static void -@@ -4008,7 +4008,7 @@ entity_tick(struct cfs_rq *cfs_rq, struct sched_entity *curr, int queued) +@@ -4183,7 +4183,7 @@ entity_tick(struct cfs_rq *cfs_rq, struc * validating it and just reschedule. */ if (queued) { @@ -430,7 +432,7 @@ index 304a7ebc7657..9cae149e78b6 100644 return; } /* -@@ -4190,7 +4190,7 @@ static void __account_cfs_rq_runtime(struct cfs_rq *cfs_rq, u64 delta_exec) +@@ -4367,7 +4367,7 @@ static void __account_cfs_rq_runtime(str * hierarchy can be throttled */ if (!assign_cfs_rq_runtime(cfs_rq) && likely(cfs_rq->curr)) @@ -439,7 +441,7 @@ index 304a7ebc7657..9cae149e78b6 100644 } static __always_inline -@@ -4855,7 +4855,7 @@ static void hrtick_start_fair(struct rq *rq, struct task_struct *p) +@@ -5038,7 +5038,7 @@ static void hrtick_start_fair(struct rq if (delta < 0) { if (rq->curr == p) @@ -448,7 +450,7 @@ index 304a7ebc7657..9cae149e78b6 100644 return; } hrtick_start(rq, delta); -@@ -6249,7 +6249,7 @@ static void check_preempt_wakeup(struct rq *rq, struct task_struct *p, int wake_ +@@ -6614,7 +6614,7 @@ static void check_preempt_wakeup(struct return; preempt: @@ -457,7 +459,7 @@ index 304a7ebc7657..9cae149e78b6 100644 /* * Only set the backward buddy when the current task is still * on the rq. This can happen when a wakeup gets interleaved -@@ -9103,7 +9103,7 @@ static void task_fork_fair(struct task_struct *p) +@@ -9701,7 +9701,7 @@ static void task_fork_fair(struct task_s * 'current' within the tree based on its new key value. */ swap(curr->vruntime, se->vruntime); @@ -466,7 +468,7 @@ index 304a7ebc7657..9cae149e78b6 100644 } se->vruntime -= cfs_rq->min_vruntime; -@@ -9127,7 +9127,7 @@ prio_changed_fair(struct rq *rq, struct task_struct *p, int oldprio) +@@ -9725,7 +9725,7 @@ prio_changed_fair(struct rq *rq, struct */ if (rq->curr == p) { if (p->prio > oldprio) @@ -475,8 +477,6 @@ index 304a7ebc7657..9cae149e78b6 100644 } else check_preempt_curr(rq, p, 0); } -diff --git a/kernel/sched/features.h b/kernel/sched/features.h -index c675ee1694f5..fb069998b518 100644 --- a/kernel/sched/features.h +++ b/kernel/sched/features.h @@ -48,6 +48,9 @@ SCHED_FEAT(NONTASK_CAPACITY, true) @@ -489,11 +489,9 @@ index c675ee1694f5..fb069998b518 100644 #else /* -diff --git a/kernel/sched/sched.h b/kernel/sched/sched.h -index bd6363799cf6..4862a596717c 100644 --- a/kernel/sched/sched.h +++ b/kernel/sched/sched.h -@@ -1546,6 +1546,15 @@ extern void init_sched_fair_class(void); +@@ -1638,6 +1638,15 @@ extern void reweight_task(struct task_st extern void resched_curr(struct rq *rq); extern void resched_cpu(int cpu); @@ -509,11 +507,9 @@ index bd6363799cf6..4862a596717c 100644 extern struct rt_bandwidth def_rt_bandwidth; extern void init_rt_bandwidth(struct rt_bandwidth *rt_b, u64 period, u64 runtime); -diff --git a/kernel/trace/trace.c b/kernel/trace/trace.c -index e6c7395840b4..18c88eb19b5e 100644 --- a/kernel/trace/trace.c +++ b/kernel/trace/trace.c -@@ -2135,6 +2135,7 @@ tracing_generic_entry_update(struct trace_entry *entry, unsigned long flags, +@@ -2134,6 +2134,7 @@ tracing_generic_entry_update(struct trac struct task_struct *tsk = current; entry->preempt_count = pc & 0xff; @@ -521,7 +517,7 @@ index e6c7395840b4..18c88eb19b5e 100644 entry->pid = (tsk) ? tsk->pid : 0; entry->flags = #ifdef CONFIG_TRACE_IRQFLAGS_SUPPORT -@@ -2145,7 +2146,8 @@ tracing_generic_entry_update(struct trace_entry *entry, unsigned long flags, +@@ -2144,7 +2145,8 @@ tracing_generic_entry_update(struct trac ((pc & NMI_MASK ) ? TRACE_FLAG_NMI : 0) | ((pc & HARDIRQ_MASK) ? TRACE_FLAG_HARDIRQ : 0) | ((pc & SOFTIRQ_OFFSET) ? TRACE_FLAG_SOFTIRQ : 0) | @@ -531,7 +527,7 @@ index e6c7395840b4..18c88eb19b5e 100644 (test_preempt_need_resched() ? TRACE_FLAG_PREEMPT_RESCHED : 0); entry->migrate_disable = (tsk) ? __migrate_disabled(tsk) & 0xFF : 0; -@@ -3352,15 +3354,17 @@ get_total_entries(struct trace_buffer *buf, +@@ -3346,15 +3348,17 @@ get_total_entries(struct trace_buffer *b static void print_lat_help_header(struct seq_file *m) { @@ -558,31 +554,29 @@ index e6c7395840b4..18c88eb19b5e 100644 } static void print_event_info(struct trace_buffer *buf, struct seq_file *m) -@@ -3396,15 +3400,17 @@ static void print_func_help_header_irq(struct trace_buffer *buf, struct seq_file +@@ -3390,15 +3394,17 @@ static void print_func_help_header_irq(s tgid ? tgid_space : space); seq_printf(m, "# %s / _----=> need-resched\n", tgid ? tgid_space : space); - seq_printf(m, "# %s| / _---=> hardirq/softirq\n", -+ seq_printf(m, "# %s| / _----=> need-resched_lazy\n", ++ seq_printf(m, "# %s| / _---=> need-resched_lazy\n", tgid ? tgid_space : space); - seq_printf(m, "# %s|| / _--=> preempt-depth\n", -+ seq_printf(m, "# %s|| / _---=> hardirq/softirq\n", ++ seq_printf(m, "# %s|| / _--=> hardirq/softirq\n", tgid ? tgid_space : space); - seq_printf(m, "# %s||| / delay\n", -+ seq_printf(m, "# %s||| / _--=> preempt-depth\n", ++ seq_printf(m, "# %s||| / preempt-depth\n", tgid ? tgid_space : space); - seq_printf(m, "# TASK-PID %sCPU# |||| TIMESTAMP FUNCTION\n", -+ seq_printf(m, "# %s|||| / delay\n", ++ seq_printf(m, "# %s|||| / delay\n", + tgid ? tgid_space : space); -+ seq_printf(m, "# TASK-PID %sCPU# ||||| TIMESTAMP FUNCTION\n", ++ seq_printf(m, "# TASK-PID %sCPU# ||||| TIMESTAMP FUNCTION\n", tgid ? " TGID " : space); - seq_printf(m, "# | | %s | |||| | |\n", -+ seq_printf(m, "# | | %s | ||||| | |\n", ++ seq_printf(m, "# | | %s | ||||| | |\n", tgid ? " | " : space); } -diff --git a/kernel/trace/trace.h b/kernel/trace/trace.h -index 0b8af849dc75..18bf383f46e8 100644 --- a/kernel/trace/trace.h +++ b/kernel/trace/trace.h @@ -127,6 +127,7 @@ struct kretprobe_trace_entry_head { @@ -601,11 +595,9 @@ index 0b8af849dc75..18bf383f46e8 100644 }; #define TRACE_BUF_SIZE 1024 -diff --git a/kernel/trace/trace_output.c b/kernel/trace/trace_output.c -index dfbe55f3e6ac..74a4bfc2c6b7 100644 --- a/kernel/trace/trace_output.c +++ b/kernel/trace/trace_output.c -@@ -447,6 +447,7 @@ int trace_print_lat_fmt(struct trace_seq *s, struct trace_entry *entry) +@@ -448,6 +448,7 @@ int trace_print_lat_fmt(struct trace_seq { char hardsoft_irq; char need_resched; @@ -613,7 +605,7 @@ index dfbe55f3e6ac..74a4bfc2c6b7 100644 char irqs_off; int hardirq; int softirq; -@@ -477,6 +478,9 @@ int trace_print_lat_fmt(struct trace_seq *s, struct trace_entry *entry) +@@ -478,6 +479,9 @@ int trace_print_lat_fmt(struct trace_seq break; } @@ -623,7 +615,7 @@ index dfbe55f3e6ac..74a4bfc2c6b7 100644 hardsoft_irq = (nmi && hardirq) ? 'Z' : nmi ? 'z' : -@@ -485,14 +489,20 @@ int trace_print_lat_fmt(struct trace_seq *s, struct trace_entry *entry) +@@ -486,14 +490,20 @@ int trace_print_lat_fmt(struct trace_seq softirq ? 's' : '.' ; @@ -646,6 +638,3 @@ index dfbe55f3e6ac..74a4bfc2c6b7 100644 if (entry->migrate_disable) trace_seq_printf(s, "%x", entry->migrate_disable); else --- -2.19.2 - diff --git a/kernel/patches-4.14.x-rt/0382-ftrace-Fix-trace-header-alignment.patch b/kernel/patches-4.19.x-rt/0243-ftrace-Fix-trace-header-alignment.patch similarity index 84% rename from kernel/patches-4.14.x-rt/0382-ftrace-Fix-trace-header-alignment.patch rename to kernel/patches-4.19.x-rt/0243-ftrace-Fix-trace-header-alignment.patch index 5db071e99..2baa6c6ad 100644 --- a/kernel/patches-4.14.x-rt/0382-ftrace-Fix-trace-header-alignment.patch +++ b/kernel/patches-4.19.x-rt/0243-ftrace-Fix-trace-header-alignment.patch @@ -1,7 +1,6 @@ -From 390a5ced0ef719df2a79efefb432898a454b628f Mon Sep 17 00:00:00 2001 From: Mike Galbraith Date: Sun, 16 Oct 2016 05:08:30 +0200 -Subject: [PATCH 382/450] ftrace: Fix trace header alignment +Subject: [PATCH] ftrace: Fix trace header alignment Line up helper arrows to the right column. @@ -10,14 +9,12 @@ Signed-off-by: Mike Galbraith [bigeasy: fixup function tracer header] Signed-off-by: Sebastian Andrzej Siewior --- - kernel/trace/trace.c | 22 +++++++++++----------- + kernel/trace/trace.c | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) -diff --git a/kernel/trace/trace.c b/kernel/trace/trace.c -index 18c88eb19b5e..4fc60e5ec4b9 100644 --- a/kernel/trace/trace.c +++ b/kernel/trace/trace.c -@@ -3354,17 +3354,17 @@ get_total_entries(struct trace_buffer *buf, +@@ -3348,17 +3348,17 @@ get_total_entries(struct trace_buffer *b static void print_lat_help_header(struct seq_file *m) { @@ -46,6 +43,3 @@ index 18c88eb19b5e..4fc60e5ec4b9 100644 } static void print_event_info(struct trace_buffer *buf, struct seq_file *m) --- -2.19.2 - diff --git a/kernel/patches-4.14.x-rt/0383-x86-Support-for-lazy-preemption.patch b/kernel/patches-4.19.x-rt/0244-x86-preempt-lazy.patch similarity index 73% rename from kernel/patches-4.14.x-rt/0383-x86-Support-for-lazy-preemption.patch rename to kernel/patches-4.19.x-rt/0244-x86-preempt-lazy.patch index b116c0074..ffb6e9af5 100644 --- a/kernel/patches-4.14.x-rt/0383-x86-Support-for-lazy-preemption.patch +++ b/kernel/patches-4.19.x-rt/0244-x86-preempt-lazy.patch @@ -1,38 +1,33 @@ -From fd1e22d07c1cfd9b044d2651d635faeea31409ee Mon Sep 17 00:00:00 2001 +Subject: x86: Support for lazy preemption From: Thomas Gleixner -Date: Thu, 1 Nov 2012 11:03:47 +0100 -Subject: [PATCH 383/450] x86: Support for lazy preemption +Date: Thu, 01 Nov 2012 11:03:47 +0100 Implement the x86 pieces for lazy preempt. Signed-off-by: Thomas Gleixner --- - arch/x86/Kconfig | 1 + - arch/x86/entry/common.c | 4 ++-- - arch/x86/entry/entry_32.S | 17 ++++++++++++++++ - arch/x86/entry/entry_64.S | 16 +++++++++++++++ - arch/x86/include/asm/preempt.h | 31 +++++++++++++++++++++++++++++- - arch/x86/include/asm/thread_info.h | 11 +++++++++++ - arch/x86/kernel/asm-offsets.c | 2 ++ + arch/x86/Kconfig | 1 + + arch/x86/entry/common.c | 4 ++-- + arch/x86/entry/entry_32.S | 17 +++++++++++++++++ + arch/x86/entry/entry_64.S | 16 ++++++++++++++++ + arch/x86/include/asm/preempt.h | 31 ++++++++++++++++++++++++++++++- + arch/x86/include/asm/thread_info.h | 11 +++++++++++ + arch/x86/kernel/asm-offsets.c | 2 ++ 7 files changed, 79 insertions(+), 3 deletions(-) -diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig -index 0520b7003c43..d34820fddc8f 100644 --- a/arch/x86/Kconfig +++ b/arch/x86/Kconfig -@@ -169,6 +169,7 @@ config X86 +@@ -180,6 +180,7 @@ config X86 select HAVE_HARDLOCKUP_DETECTOR_PERF if PERF_EVENTS && HAVE_PERF_EVENTS_NMI select HAVE_PERF_REGS select HAVE_PERF_USER_STACK_DUMP + select HAVE_PREEMPT_LAZY - select HAVE_RCU_TABLE_FREE + select HAVE_RCU_TABLE_FREE if PARAVIRT select HAVE_RCU_TABLE_INVALIDATE if HAVE_RCU_TABLE_FREE select HAVE_REGS_AND_STACK_ACCESS_API -diff --git a/arch/x86/entry/common.c b/arch/x86/entry/common.c -index 121f804a9dcb..0e27f35febe7 100644 --- a/arch/x86/entry/common.c +++ b/arch/x86/entry/common.c -@@ -133,7 +133,7 @@ static long syscall_trace_enter(struct pt_regs *regs) +@@ -133,7 +133,7 @@ static long syscall_trace_enter(struct p #define EXIT_TO_USERMODE_LOOP_FLAGS \ (_TIF_SIGPENDING | _TIF_NOTIFY_RESUME | _TIF_UPROBE | \ @@ -41,7 +36,7 @@ index 121f804a9dcb..0e27f35febe7 100644 static void exit_to_usermode_loop(struct pt_regs *regs, u32 cached_flags) { -@@ -148,7 +148,7 @@ static void exit_to_usermode_loop(struct pt_regs *regs, u32 cached_flags) +@@ -148,7 +148,7 @@ static void exit_to_usermode_loop(struct /* We have work to do. */ local_irq_enable(); @@ -50,20 +45,18 @@ index 121f804a9dcb..0e27f35febe7 100644 schedule(); #ifdef ARCH_RT_DELAYS_SIGNAL_SEND -diff --git a/arch/x86/entry/entry_32.S b/arch/x86/entry/entry_32.S -index 60c4c342316c..cd0c7c56e2dd 100644 --- a/arch/x86/entry/entry_32.S +++ b/arch/x86/entry/entry_32.S -@@ -350,8 +350,25 @@ END(ret_from_exception) +@@ -764,8 +764,25 @@ END(ret_from_exception) ENTRY(resume_kernel) DISABLE_INTERRUPTS(CLBR_ANY) .Lneed_resched: + # preempt count == 0 + NEED_RS set? cmpl $0, PER_CPU_VAR(__preempt_count) +#ifndef CONFIG_PREEMPT_LAZY - jnz restore_all + jnz restore_all_kernel +#else -+ jz test_int_off ++ jz test_int_off + + # atleast preempt count == 0 ? + cmpl $_PREEMPT_ENABLED,PER_CPU_VAR(__preempt_count) @@ -75,16 +68,14 @@ index 60c4c342316c..cd0c7c56e2dd 100644 + + testl $_TIF_NEED_RESCHED_LAZY, TASK_TI_flags(%ebp) + jz restore_all -+test_int_off: ++ test_int_off: +#endif testl $X86_EFLAGS_IF, PT_EFLAGS(%esp) # interrupts off (exception path) ? - jz restore_all + jz restore_all_kernel call preempt_schedule_irq -diff --git a/arch/x86/entry/entry_64.S b/arch/x86/entry/entry_64.S -index 8192e87963b5..75d42cb8a7c9 100644 --- a/arch/x86/entry/entry_64.S +++ b/arch/x86/entry/entry_64.S -@@ -633,7 +633,23 @@ retint_kernel: +@@ -705,7 +705,23 @@ GLOBAL(swapgs_restore_regs_and_return_to btl $9, EFLAGS(%rsp) /* were interrupts off? */ jnc 1f 0: cmpl $0, PER_CPU_VAR(__preempt_count) @@ -101,18 +92,16 @@ index 8192e87963b5..75d42cb8a7c9 100644 + cmpl $0, TASK_TI_preempt_lazy_count(%rcx) + jnz 1f + -+ bt $TIF_NEED_RESCHED_LAZY,TASK_TI_flags(%rcx) ++ btl $TIF_NEED_RESCHED_LAZY,TASK_TI_flags(%rcx) + jnc 1f +do_preempt_schedule_irq: +#endif call preempt_schedule_irq jmp 0b 1: -diff --git a/arch/x86/include/asm/preempt.h b/arch/x86/include/asm/preempt.h -index 7f2dbd91fc74..22992c837795 100644 --- a/arch/x86/include/asm/preempt.h +++ b/arch/x86/include/asm/preempt.h -@@ -86,17 +86,46 @@ static __always_inline void __preempt_count_sub(int val) +@@ -86,17 +86,46 @@ static __always_inline void __preempt_co * a decrement which hits zero means we have no preempt_count and should * reschedule. */ @@ -160,11 +149,9 @@ index 7f2dbd91fc74..22992c837795 100644 } #ifdef CONFIG_PREEMPT -diff --git a/arch/x86/include/asm/thread_info.h b/arch/x86/include/asm/thread_info.h -index bf9175d87844..151ddafc6374 100644 --- a/arch/x86/include/asm/thread_info.h +++ b/arch/x86/include/asm/thread_info.h -@@ -56,11 +56,14 @@ struct task_struct; +@@ -56,17 +56,24 @@ struct task_struct; struct thread_info { unsigned long flags; /* low level flags */ u32 status; /* thread synchronous flags */ @@ -178,8 +165,7 @@ index bf9175d87844..151ddafc6374 100644 + .preempt_lazy_count = 0, \ } - #define init_stack (init_thread_union.stack) -@@ -69,6 +72,10 @@ struct thread_info { + #else /* !__ASSEMBLY__ */ #include @@ -190,7 +176,7 @@ index bf9175d87844..151ddafc6374 100644 #endif /* -@@ -93,6 +100,7 @@ struct thread_info { +@@ -91,6 +98,7 @@ struct thread_info { #define TIF_NOCPUID 15 /* CPUID is not accessible in userland */ #define TIF_NOTSC 16 /* TSC is not accessible in userland */ #define TIF_IA32 17 /* IA32 compatibility process */ @@ -198,7 +184,7 @@ index bf9175d87844..151ddafc6374 100644 #define TIF_NOHZ 19 /* in adaptive nohz mode */ #define TIF_MEMDIE 20 /* is terminating due to OOM killer */ #define TIF_POLLING_NRFLAG 21 /* idle is polling for TIF_NEED_RESCHED */ -@@ -122,6 +130,7 @@ struct thread_info { +@@ -120,6 +128,7 @@ struct thread_info { #define _TIF_NOCPUID (1 << TIF_NOCPUID) #define _TIF_NOTSC (1 << TIF_NOTSC) #define _TIF_IA32 (1 << TIF_IA32) @@ -206,7 +192,7 @@ index bf9175d87844..151ddafc6374 100644 #define _TIF_NOHZ (1 << TIF_NOHZ) #define _TIF_POLLING_NRFLAG (1 << TIF_POLLING_NRFLAG) #define _TIF_IO_BITMAP (1 << TIF_IO_BITMAP) -@@ -167,6 +176,8 @@ struct thread_info { +@@ -165,6 +174,8 @@ struct thread_info { #define _TIF_WORK_CTXSW_PREV (_TIF_WORK_CTXSW|_TIF_USER_RETURN_NOTIFY) #define _TIF_WORK_CTXSW_NEXT (_TIF_WORK_CTXSW) @@ -215,8 +201,6 @@ index bf9175d87844..151ddafc6374 100644 #define STACK_WARN (THREAD_SIZE/8) /* -diff --git a/arch/x86/kernel/asm-offsets.c b/arch/x86/kernel/asm-offsets.c -index 76417a9aab73..62c3e27c8e1c 100644 --- a/arch/x86/kernel/asm-offsets.c +++ b/arch/x86/kernel/asm-offsets.c @@ -38,6 +38,7 @@ void common(void) { @@ -235,6 +219,3 @@ index 76417a9aab73..62c3e27c8e1c 100644 /* TLB state for the entry code */ OFFSET(TLB_STATE_user_pcid_flush_mask, tlb_state, user_pcid_flush_mask); --- -2.19.2 - diff --git a/kernel/patches-4.19.x-rt/0245-x86-lazy-preempt-properly-check-against-preempt-mask.patch b/kernel/patches-4.19.x-rt/0245-x86-lazy-preempt-properly-check-against-preempt-mask.patch new file mode 100644 index 000000000..0151e3943 --- /dev/null +++ b/kernel/patches-4.19.x-rt/0245-x86-lazy-preempt-properly-check-against-preempt-mask.patch @@ -0,0 +1,25 @@ +From: Sebastian Andrzej Siewior +Date: Mon, 18 Feb 2019 16:57:09 +0100 +Subject: [PATCH] x86: lazy-preempt: properly check against preempt-mask + +should_resched() should check against preempt_offset after unmasking the +need-resched-bit. Otherwise should_resched() won't work for +preempt_offset != 0 and lazy-preempt set. + +Cc: stable-rt@vger.kernel.org +Signed-off-by: Sebastian Andrzej Siewior +--- + arch/x86/include/asm/preempt.h | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/arch/x86/include/asm/preempt.h ++++ b/arch/x86/include/asm/preempt.h +@@ -118,7 +118,7 @@ static __always_inline bool should_resch + + /* preempt count == 0 ? */ + tmp &= ~PREEMPT_NEED_RESCHED; +- if (tmp) ++ if (tmp != preempt_offset) + return false; + if (current_thread_info()->preempt_lazy_count) + return false; diff --git a/kernel/patches-4.19.x-rt/0246-x86-lazy-preempt-use-proper-return-label-on-32bit-x8.patch b/kernel/patches-4.19.x-rt/0246-x86-lazy-preempt-use-proper-return-label-on-32bit-x8.patch new file mode 100644 index 000000000..98b1ce39b --- /dev/null +++ b/kernel/patches-4.19.x-rt/0246-x86-lazy-preempt-use-proper-return-label-on-32bit-x8.patch @@ -0,0 +1,37 @@ +From: Sebastian Andrzej Siewior +Date: Tue, 26 Feb 2019 14:53:49 +0100 +Subject: [PATCH] x86: lazy-preempt: use proper return label on 32bit-x86 + +The lazy-preempt uses the wrong return label in case preemption isn't +possible. This results crash while returning to the kernel. + +Use the correct return label if preemption isn' possible. + +Reported-by: Andri Yngvason +Signed-off-by: Sebastian Andrzej Siewior +--- + arch/x86/entry/entry_32.S | 8 ++++---- + 1 file changed, 4 insertions(+), 4 deletions(-) + +--- a/arch/x86/entry/entry_32.S ++++ b/arch/x86/entry/entry_32.S +@@ -773,15 +773,15 @@ ENTRY(resume_kernel) + + # atleast preempt count == 0 ? + cmpl $_PREEMPT_ENABLED,PER_CPU_VAR(__preempt_count) +- jne restore_all ++ jne restore_all_kernel + + movl PER_CPU_VAR(current_task), %ebp + cmpl $0,TASK_TI_preempt_lazy_count(%ebp) # non-zero preempt_lazy_count ? +- jnz restore_all ++ jnz restore_all_kernel + + testl $_TIF_NEED_RESCHED_LAZY, TASK_TI_flags(%ebp) +- jz restore_all +- test_int_off: ++ jz restore_all_kernel ++test_int_off: + #endif + testl $X86_EFLAGS_IF, PT_EFLAGS(%esp) # interrupts off (exception path) ? + jz restore_all_kernel diff --git a/kernel/patches-4.14.x-rt/0384-arm-Add-support-for-lazy-preemption.patch b/kernel/patches-4.19.x-rt/0247-arm-preempt-lazy-support.patch similarity index 73% rename from kernel/patches-4.14.x-rt/0384-arm-Add-support-for-lazy-preemption.patch rename to kernel/patches-4.19.x-rt/0247-arm-preempt-lazy-support.patch index cda9f594f..99a7df7d9 100644 --- a/kernel/patches-4.14.x-rt/0384-arm-Add-support-for-lazy-preemption.patch +++ b/kernel/patches-4.19.x-rt/0247-arm-preempt-lazy-support.patch @@ -1,34 +1,29 @@ -From d43c1351f9ca08417f637274c72a3026ca6c8485 Mon Sep 17 00:00:00 2001 +Subject: arm: Add support for lazy preemption From: Thomas Gleixner Date: Wed, 31 Oct 2012 12:04:11 +0100 -Subject: [PATCH 384/450] arm: Add support for lazy preemption Implement the arm pieces for lazy preempt. Signed-off-by: Thomas Gleixner --- - arch/arm/Kconfig | 1 + - arch/arm/include/asm/thread_info.h | 8 ++++++-- - arch/arm/kernel/asm-offsets.c | 1 + - arch/arm/kernel/entry-armv.S | 19 ++++++++++++++++--- - arch/arm/kernel/entry-common.S | 9 +++++++-- - arch/arm/kernel/signal.c | 3 ++- + arch/arm/Kconfig | 1 + + arch/arm/include/asm/thread_info.h | 8 ++++++-- + arch/arm/kernel/asm-offsets.c | 1 + + arch/arm/kernel/entry-armv.S | 19 ++++++++++++++++--- + arch/arm/kernel/entry-common.S | 9 +++++++-- + arch/arm/kernel/signal.c | 3 ++- 6 files changed, 33 insertions(+), 8 deletions(-) -diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig -index ac05a027539a..558b0995e94a 100644 --- a/arch/arm/Kconfig +++ b/arch/arm/Kconfig -@@ -85,6 +85,7 @@ config ARM +@@ -90,6 +90,7 @@ config ARM select HAVE_PERF_EVENTS select HAVE_PERF_REGS select HAVE_PERF_USER_STACK_DUMP + select HAVE_PREEMPT_LAZY select HAVE_RCU_TABLE_FREE if (SMP && ARM_LPAE) select HAVE_REGS_AND_STACK_ACCESS_API - select HAVE_SYSCALL_TRACEPOINTS -diff --git a/arch/arm/include/asm/thread_info.h b/arch/arm/include/asm/thread_info.h -index 57d2ad9c75ca..cdfb6855943b 100644 + select HAVE_RSEQ --- a/arch/arm/include/asm/thread_info.h +++ b/arch/arm/include/asm/thread_info.h @@ -49,6 +49,7 @@ struct cpu_context_save { @@ -39,7 +34,7 @@ index 57d2ad9c75ca..cdfb6855943b 100644 mm_segment_t addr_limit; /* address limit */ struct task_struct *task; /* main task structure */ __u32 cpu; /* cpu */ -@@ -142,7 +143,8 @@ extern int vfp_restore_user_hwstate(struct user_vfp *, +@@ -139,7 +140,8 @@ extern int vfp_restore_user_hwstate(stru #define TIF_SYSCALL_TRACE 4 /* syscall trace active */ #define TIF_SYSCALL_AUDIT 5 /* syscall auditing active */ #define TIF_SYSCALL_TRACEPOINT 6 /* syscall tracepoint instrumentation */ @@ -49,7 +44,7 @@ index 57d2ad9c75ca..cdfb6855943b 100644 #define TIF_NOHZ 12 /* in adaptive nohz mode */ #define TIF_USING_IWMMXT 17 -@@ -152,6 +154,7 @@ extern int vfp_restore_user_hwstate(struct user_vfp *, +@@ -149,6 +151,7 @@ extern int vfp_restore_user_hwstate(stru #define _TIF_SIGPENDING (1 << TIF_SIGPENDING) #define _TIF_NEED_RESCHED (1 << TIF_NEED_RESCHED) #define _TIF_NOTIFY_RESUME (1 << TIF_NOTIFY_RESUME) @@ -57,7 +52,7 @@ index 57d2ad9c75ca..cdfb6855943b 100644 #define _TIF_UPROBE (1 << TIF_UPROBE) #define _TIF_SYSCALL_TRACE (1 << TIF_SYSCALL_TRACE) #define _TIF_SYSCALL_AUDIT (1 << TIF_SYSCALL_AUDIT) -@@ -167,7 +170,8 @@ extern int vfp_restore_user_hwstate(struct user_vfp *, +@@ -164,7 +167,8 @@ extern int vfp_restore_user_hwstate(stru * Change these and you break ASM code in entry-common.S */ #define _TIF_WORK_MASK (_TIF_NEED_RESCHED | _TIF_SIGPENDING | \ @@ -67,11 +62,9 @@ index 57d2ad9c75ca..cdfb6855943b 100644 #endif /* __KERNEL__ */ #endif /* __ASM_ARM_THREAD_INFO_H */ -diff --git a/arch/arm/kernel/asm-offsets.c b/arch/arm/kernel/asm-offsets.c -index 608008229c7d..3866da3f7bb7 100644 --- a/arch/arm/kernel/asm-offsets.c +++ b/arch/arm/kernel/asm-offsets.c -@@ -65,6 +65,7 @@ int main(void) +@@ -56,6 +56,7 @@ int main(void) BLANK(); DEFINE(TI_FLAGS, offsetof(struct thread_info, flags)); DEFINE(TI_PREEMPT, offsetof(struct thread_info, preempt_count)); @@ -79,11 +72,9 @@ index 608008229c7d..3866da3f7bb7 100644 DEFINE(TI_ADDR_LIMIT, offsetof(struct thread_info, addr_limit)); DEFINE(TI_TASK, offsetof(struct thread_info, task)); DEFINE(TI_CPU, offsetof(struct thread_info, cpu)); -diff --git a/arch/arm/kernel/entry-armv.S b/arch/arm/kernel/entry-armv.S -index fbc707626b3e..b434c59d2b64 100644 --- a/arch/arm/kernel/entry-armv.S +++ b/arch/arm/kernel/entry-armv.S -@@ -220,11 +220,18 @@ __irq_svc: +@@ -216,11 +216,18 @@ ENDPROC(__dabt_svc) #ifdef CONFIG_PREEMPT ldr r8, [tsk, #TI_PREEMPT] @ get preempt count @@ -104,7 +95,7 @@ index fbc707626b3e..b434c59d2b64 100644 #endif svc_exit r5, irq = 1 @ return from exception -@@ -239,8 +246,14 @@ svc_preempt: +@@ -235,8 +242,14 @@ ENDPROC(__irq_svc) 1: bl preempt_schedule_irq @ irq en/disable is done inside ldr r0, [tsk, #TI_FLAGS] @ get new tasks TI_FLAGS tst r0, #_TIF_NEED_RESCHED @@ -120,11 +111,9 @@ index fbc707626b3e..b434c59d2b64 100644 #endif __und_fault: -diff --git a/arch/arm/kernel/entry-common.S b/arch/arm/kernel/entry-common.S -index 54c10503d71f..3fdeade24e3f 100644 --- a/arch/arm/kernel/entry-common.S +++ b/arch/arm/kernel/entry-common.S -@@ -53,7 +53,9 @@ ret_fast_syscall: +@@ -56,7 +56,9 @@ saved_pc .req lr cmp r2, #TASK_SIZE blne addr_limit_check_failed ldr r1, [tsk, #TI_FLAGS] @ re-check for syscall tracing @@ -135,7 +124,7 @@ index 54c10503d71f..3fdeade24e3f 100644 bne fast_work_pending -@@ -83,8 +85,11 @@ ret_fast_syscall: +@@ -93,8 +95,11 @@ ENDPROC(ret_fast_syscall) cmp r2, #TASK_SIZE blne addr_limit_check_failed ldr r1, [tsk, #TI_FLAGS] @ re-check for syscall tracing @@ -148,11 +137,9 @@ index 54c10503d71f..3fdeade24e3f 100644 UNWIND(.fnend ) ENDPROC(ret_fast_syscall) -diff --git a/arch/arm/kernel/signal.c b/arch/arm/kernel/signal.c -index cdfe52b15a0a..198cf8bf0b37 100644 --- a/arch/arm/kernel/signal.c +++ b/arch/arm/kernel/signal.c -@@ -615,7 +615,8 @@ do_work_pending(struct pt_regs *regs, unsigned int thread_flags, int syscall) +@@ -652,7 +652,8 @@ do_work_pending(struct pt_regs *regs, un */ trace_hardirqs_off(); do { @@ -162,6 +149,3 @@ index cdfe52b15a0a..198cf8bf0b37 100644 schedule(); } else { if (unlikely(!user_mode(regs))) --- -2.19.2 - diff --git a/kernel/patches-4.14.x-rt/0385-powerpc-Add-support-for-lazy-preemption.patch b/kernel/patches-4.19.x-rt/0248-powerpc-preempt-lazy-support.patch similarity index 68% rename from kernel/patches-4.14.x-rt/0385-powerpc-Add-support-for-lazy-preemption.patch rename to kernel/patches-4.19.x-rt/0248-powerpc-preempt-lazy-support.patch index 69c6dd640..2e9979c76 100644 --- a/kernel/patches-4.14.x-rt/0385-powerpc-Add-support-for-lazy-preemption.patch +++ b/kernel/patches-4.19.x-rt/0248-powerpc-preempt-lazy-support.patch @@ -1,21 +1,18 @@ -From 70711d06940fcca6da7a80610b8c039da2c37d52 Mon Sep 17 00:00:00 2001 From: Thomas Gleixner Date: Thu, 1 Nov 2012 10:14:11 +0100 -Subject: [PATCH 385/450] powerpc: Add support for lazy preemption +Subject: powerpc: Add support for lazy preemption Implement the powerpc pieces for lazy preempt. Signed-off-by: Thomas Gleixner --- - arch/powerpc/Kconfig | 1 + - arch/powerpc/include/asm/thread_info.h | 11 ++++++++--- - arch/powerpc/kernel/asm-offsets.c | 1 + - arch/powerpc/kernel/entry_32.S | 17 ++++++++++++----- - arch/powerpc/kernel/entry_64.S | 14 +++++++++++--- + arch/powerpc/Kconfig | 1 + + arch/powerpc/include/asm/thread_info.h | 9 +++++++-- + arch/powerpc/kernel/asm-offsets.c | 1 + + arch/powerpc/kernel/entry_32.S | 17 ++++++++++++----- + arch/powerpc/kernel/entry_64.S | 16 ++++++++++++---- 5 files changed, 33 insertions(+), 11 deletions(-) -diff --git a/arch/powerpc/Kconfig b/arch/powerpc/Kconfig -index f3201bf888ad..b5658e925465 100644 --- a/arch/powerpc/Kconfig +++ b/arch/powerpc/Kconfig @@ -216,6 +216,7 @@ config PPC @@ -25,12 +22,10 @@ index f3201bf888ad..b5658e925465 100644 + select HAVE_PREEMPT_LAZY select HAVE_RCU_TABLE_FREE if SMP select HAVE_REGS_AND_STACK_ACCESS_API - select HAVE_SYSCALL_TRACEPOINTS -diff --git a/arch/powerpc/include/asm/thread_info.h b/arch/powerpc/include/asm/thread_info.h -index a264c3ad366b..020afb8329a1 100644 + select HAVE_RELIABLE_STACKTRACE if PPC64 && CPU_LITTLE_ENDIAN --- a/arch/powerpc/include/asm/thread_info.h +++ b/arch/powerpc/include/asm/thread_info.h -@@ -36,6 +36,8 @@ struct thread_info { +@@ -37,6 +37,8 @@ struct thread_info { int cpu; /* cpu we're on */ int preempt_count; /* 0 => preemptable, <0 => BUG */ @@ -39,45 +34,42 @@ index a264c3ad366b..020afb8329a1 100644 unsigned long local_flags; /* private flags for thread */ #ifdef CONFIG_LIVEPATCH unsigned long *livepatch_sp; -@@ -81,8 +83,7 @@ static inline struct thread_info *current_thread_info(void) - #define TIF_SYSCALL_TRACE 0 /* syscall trace active */ +@@ -81,7 +83,7 @@ extern int arch_dup_task_struct(struct t #define TIF_SIGPENDING 1 /* signal pending */ #define TIF_NEED_RESCHED 2 /* rescheduling necessary */ --#define TIF_POLLING_NRFLAG 3 /* true if poll_idle() is polling -- TIF_NEED_RESCHED */ -+#define TIF_NEED_RESCHED_LAZY 3 /* lazy rescheduling necessary */ - #define TIF_32BIT 4 /* 32 bit binary */ + #define TIF_FSCHECK 3 /* Check FS is USER_DS on return */ +-#define TIF_32BIT 4 /* 32 bit binary */ ++#define TIF_NEED_RESCHED_LAZY 4 /* lazy rescheduling necessary */ #define TIF_RESTORE_TM 5 /* need to restore TM FP/VEC/VSX */ #define TIF_PATCH_PENDING 6 /* pending live patching update */ -@@ -101,6 +102,8 @@ static inline struct thread_info *current_thread_info(void) - #if defined(CONFIG_PPC64) + #define TIF_SYSCALL_AUDIT 7 /* syscall auditing active */ +@@ -100,6 +102,7 @@ extern int arch_dup_task_struct(struct t #define TIF_ELF2ABI 18 /* function descriptors must die! */ #endif -+#define TIF_POLLING_NRFLAG 19 /* true if poll_idle() is polling -+ TIF_NEED_RESCHED */ + #define TIF_POLLING_NRFLAG 19 /* true if poll_idle() is polling TIF_NEED_RESCHED */ ++#define TIF_32BIT 20 /* 32 bit binary */ /* as above, but as bit values */ #define _TIF_SYSCALL_TRACE (1< Date: Thu, 14 May 2015 17:52:17 +0200 -Subject: [PATCH 386/450] arch/arm64: Add lazy preempt support +Subject: arch/arm64: Add lazy preempt support arm64 is missing support for PREEMPT_RT. The main feature which is lacking is support for lazy preemption. The arch-specific entry code, @@ -12,27 +11,23 @@ indicate that support for full RT preemption is now available. Signed-off-by: Anders Roxell --- - arch/arm64/Kconfig | 1 + - arch/arm64/include/asm/thread_info.h | 6 +++++- - arch/arm64/kernel/asm-offsets.c | 1 + - arch/arm64/kernel/entry.S | 12 +++++++++--- - arch/arm64/kernel/signal.c | 2 +- + arch/arm64/Kconfig | 1 + + arch/arm64/include/asm/thread_info.h | 6 +++++- + arch/arm64/kernel/asm-offsets.c | 1 + + arch/arm64/kernel/entry.S | 12 +++++++++--- + arch/arm64/kernel/signal.c | 2 +- 5 files changed, 17 insertions(+), 5 deletions(-) -diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig -index 724afce517fd..f3c5213ea0ec 100644 --- a/arch/arm64/Kconfig +++ b/arch/arm64/Kconfig -@@ -103,6 +103,7 @@ config ARM64 +@@ -140,6 +140,7 @@ config ARM64 select HAVE_PERF_EVENTS select HAVE_PERF_REGS select HAVE_PERF_USER_STACK_DUMP + select HAVE_PREEMPT_LAZY select HAVE_REGS_AND_STACK_ACCESS_API select HAVE_RCU_TABLE_FREE - select HAVE_SYSCALL_TRACEPOINTS -diff --git a/arch/arm64/include/asm/thread_info.h b/arch/arm64/include/asm/thread_info.h -index fc786d344e46..b833258b7594 100644 + select HAVE_RSEQ --- a/arch/arm64/include/asm/thread_info.h +++ b/arch/arm64/include/asm/thread_info.h @@ -43,6 +43,7 @@ struct thread_info { @@ -42,8 +37,8 @@ index fc786d344e46..b833258b7594 100644 + int preempt_lazy_count; /* 0 => preemptable, <0 => bug */ }; - #define INIT_THREAD_INFO(tsk) \ -@@ -82,6 +83,7 @@ void arch_setup_new_exec(void); + #define thread_saved_pc(tsk) \ +@@ -76,6 +77,7 @@ void arch_release_task_struct(struct tas #define TIF_FOREIGN_FPSTATE 3 /* CPU's FP state is not current's */ #define TIF_UPROBE 4 /* uprobe breakpoint or singlestep */ #define TIF_FSCHECK 5 /* Check FS is USER_DS on return */ @@ -51,7 +46,7 @@ index fc786d344e46..b833258b7594 100644 #define TIF_NOHZ 7 #define TIF_SYSCALL_TRACE 8 #define TIF_SYSCALL_AUDIT 9 -@@ -98,6 +100,7 @@ void arch_setup_new_exec(void); +@@ -94,6 +96,7 @@ void arch_release_task_struct(struct tas #define _TIF_NEED_RESCHED (1 << TIF_NEED_RESCHED) #define _TIF_NOTIFY_RESUME (1 << TIF_NOTIFY_RESUME) #define _TIF_FOREIGN_FPSTATE (1 << TIF_FOREIGN_FPSTATE) @@ -59,7 +54,7 @@ index fc786d344e46..b833258b7594 100644 #define _TIF_NOHZ (1 << TIF_NOHZ) #define _TIF_SYSCALL_TRACE (1 << TIF_SYSCALL_TRACE) #define _TIF_SYSCALL_AUDIT (1 << TIF_SYSCALL_AUDIT) -@@ -109,8 +112,9 @@ void arch_setup_new_exec(void); +@@ -106,8 +109,9 @@ void arch_release_task_struct(struct tas #define _TIF_WORK_MASK (_TIF_NEED_RESCHED | _TIF_SIGPENDING | \ _TIF_NOTIFY_RESUME | _TIF_FOREIGN_FPSTATE | \ @@ -70,11 +65,9 @@ index fc786d344e46..b833258b7594 100644 #define _TIF_SYSCALL_WORK (_TIF_SYSCALL_TRACE | _TIF_SYSCALL_AUDIT | \ _TIF_SYSCALL_TRACEPOINT | _TIF_SECCOMP | \ _TIF_NOHZ) -diff --git a/arch/arm64/kernel/asm-offsets.c b/arch/arm64/kernel/asm-offsets.c -index b5e43b01b396..ae26a1664436 100644 --- a/arch/arm64/kernel/asm-offsets.c +++ b/arch/arm64/kernel/asm-offsets.c -@@ -39,6 +39,7 @@ int main(void) +@@ -41,6 +41,7 @@ int main(void) BLANK(); DEFINE(TSK_TI_FLAGS, offsetof(struct task_struct, thread_info.flags)); DEFINE(TSK_TI_PREEMPT, offsetof(struct task_struct, thread_info.preempt_count)); @@ -82,11 +75,9 @@ index b5e43b01b396..ae26a1664436 100644 DEFINE(TSK_TI_ADDR_LIMIT, offsetof(struct task_struct, thread_info.addr_limit)); #ifdef CONFIG_ARM64_SW_TTBR0_PAN DEFINE(TSK_TI_TTBR0, offsetof(struct task_struct, thread_info.ttbr0)); -diff --git a/arch/arm64/kernel/entry.S b/arch/arm64/kernel/entry.S -index c1ffa95c0ad2..c60ecb5a3916 100644 --- a/arch/arm64/kernel/entry.S +++ b/arch/arm64/kernel/entry.S -@@ -637,11 +637,16 @@ el1_irq: +@@ -623,11 +623,16 @@ ENDPROC(el1_sync) #ifdef CONFIG_PREEMPT ldr w24, [tsk, #TSK_TI_PREEMPT] // get preempt count @@ -106,7 +97,7 @@ index c1ffa95c0ad2..c60ecb5a3916 100644 #endif #ifdef CONFIG_TRACE_IRQFLAGS bl trace_hardirqs_on -@@ -655,6 +660,7 @@ el1_preempt: +@@ -641,6 +646,7 @@ ENDPROC(el1_irq) 1: bl preempt_schedule_irq // irq en/disable is done inside ldr x0, [tsk, #TSK_TI_FLAGS] // get new tasks TI_FLAGS tbnz x0, #TIF_NEED_RESCHED, 1b // needs rescheduling? @@ -114,19 +105,14 @@ index c1ffa95c0ad2..c60ecb5a3916 100644 ret x24 #endif -diff --git a/arch/arm64/kernel/signal.c b/arch/arm64/kernel/signal.c -index 43442b3a463f..81bf9545a589 100644 --- a/arch/arm64/kernel/signal.c +++ b/arch/arm64/kernel/signal.c -@@ -756,7 +756,7 @@ asmlinkage void do_notify_resume(struct pt_regs *regs, +@@ -926,7 +926,7 @@ asmlinkage void do_notify_resume(struct /* Check valid user FS if needed */ addr_limit_user_check(); - if (thread_flags & _TIF_NEED_RESCHED) { + if (thread_flags & _TIF_NEED_RESCHED_MASK) { - schedule(); - } else { - local_irq_enable(); --- -2.19.2 - + /* Unmask Debug and SError for the next task */ + local_daif_restore(DAIF_PROCCTX_NOIRQ); + diff --git a/kernel/patches-4.14.x-rt/0390-connector-cn_proc-Protect-send_msg-with-a-local-lock.patch b/kernel/patches-4.19.x-rt/0250-connector-cn_proc-Protect-send_msg-with-a-local-lock.patch similarity index 82% rename from kernel/patches-4.14.x-rt/0390-connector-cn_proc-Protect-send_msg-with-a-local-lock.patch rename to kernel/patches-4.19.x-rt/0250-connector-cn_proc-Protect-send_msg-with-a-local-lock.patch index e85e7112c..f91af26e9 100644 --- a/kernel/patches-4.14.x-rt/0390-connector-cn_proc-Protect-send_msg-with-a-local-lock.patch +++ b/kernel/patches-4.19.x-rt/0250-connector-cn_proc-Protect-send_msg-with-a-local-lock.patch @@ -1,8 +1,7 @@ -From 7b81b256010ffb7952153f83a93a0f65ff7d187c Mon Sep 17 00:00:00 2001 From: Mike Galbraith Date: Sun, 16 Oct 2016 05:11:54 +0200 -Subject: [PATCH 390/450] connector/cn_proc: Protect send_msg() with a local - lock on RT +Subject: [PATCH] connector/cn_proc: Protect send_msg() with a local lock + on RT |BUG: sleeping function called from invalid context at kernel/locking/rtmutex.c:931 |in_atomic(): 1, irqs_disabled(): 0, pid: 31807, name: sleep @@ -31,11 +30,9 @@ delivery") which is v4.7-rc6. Signed-off-by: Mike Galbraith Signed-off-by: Sebastian Andrzej Siewior --- - drivers/connector/cn_proc.c | 6 ++++-- + drivers/connector/cn_proc.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) -diff --git a/drivers/connector/cn_proc.c b/drivers/connector/cn_proc.c -index a782ce87715c..19d265948526 100644 --- a/drivers/connector/cn_proc.c +++ b/drivers/connector/cn_proc.c @@ -32,6 +32,7 @@ @@ -46,7 +43,7 @@ index a782ce87715c..19d265948526 100644 /* * Size of a cn_msg followed by a proc_event structure. Since the -@@ -54,10 +55,11 @@ static struct cb_id cn_proc_event_id = { CN_IDX_PROC, CN_VAL_PROC }; +@@ -54,10 +55,11 @@ static struct cb_id cn_proc_event_id = { /* proc_event_counts is used as the sequence number of the netlink message */ static DEFINE_PER_CPU(__u32, proc_event_counts) = { 0 }; @@ -59,7 +56,7 @@ index a782ce87715c..19d265948526 100644 msg->seq = __this_cpu_inc_return(proc_event_counts) - 1; ((struct proc_event *)msg->data)->cpu = smp_processor_id(); -@@ -70,7 +72,7 @@ static inline void send_msg(struct cn_msg *msg) +@@ -70,7 +72,7 @@ static inline void send_msg(struct cn_ms */ cn_netlink_send(msg, 0, CN_IDX_PROC, GFP_NOWAIT); @@ -68,6 +65,3 @@ index a782ce87715c..19d265948526 100644 } void proc_fork_connector(struct task_struct *task) --- -2.19.2 - diff --git a/kernel/patches-4.14.x-rt/0391-drivers-block-zram-Replace-bit-spinlocks-with-rtmute.patch b/kernel/patches-4.19.x-rt/0251-drivers-block-zram-Replace-bit-spinlocks-with-rtmute.patch similarity index 51% rename from kernel/patches-4.14.x-rt/0391-drivers-block-zram-Replace-bit-spinlocks-with-rtmute.patch rename to kernel/patches-4.19.x-rt/0251-drivers-block-zram-Replace-bit-spinlocks-with-rtmute.patch index 90c450253..11ae91954 100644 --- a/kernel/patches-4.14.x-rt/0391-drivers-block-zram-Replace-bit-spinlocks-with-rtmute.patch +++ b/kernel/patches-4.19.x-rt/0251-drivers-block-zram-Replace-bit-spinlocks-with-rtmute.patch @@ -1,8 +1,7 @@ -From 16ccbac971b79234c20b2a26399bc971088d0b69 Mon Sep 17 00:00:00 2001 From: Mike Galbraith Date: Thu, 31 Mar 2016 04:08:28 +0200 -Subject: [PATCH 391/450] drivers/block/zram: Replace bit spinlocks with - rtmutex for -rt +Subject: [PATCH] drivers/block/zram: Replace bit spinlocks with rtmutex + for -rt They're nondeterministic, and lead to ___might_sleep() splats in -rt. OTOH, they're a lot less wasteful than an rtmutex per page. @@ -10,17 +9,15 @@ OTOH, they're a lot less wasteful than an rtmutex per page. Signed-off-by: Mike Galbraith Signed-off-by: Sebastian Andrzej Siewior --- - drivers/block/zram/zram_drv.c | 26 ++++++++++++++++++++++++++ - drivers/block/zram/zram_drv.h | 3 +++ - 2 files changed, 29 insertions(+) + drivers/block/zram/zram_drv.c | 38 ++++++++++++++++++++++++++++++++++++++ + drivers/block/zram/zram_drv.h | 3 +++ + 2 files changed, 41 insertions(+) -diff --git a/drivers/block/zram/zram_drv.c b/drivers/block/zram/zram_drv.c -index 27b202c64c84..bde8871f41ed 100644 --- a/drivers/block/zram/zram_drv.c +++ b/drivers/block/zram/zram_drv.c -@@ -761,6 +761,30 @@ static DEVICE_ATTR_RO(io_stat); - static DEVICE_ATTR_RO(mm_stat); - static DEVICE_ATTR_RO(debug_stat); +@@ -53,6 +53,40 @@ static size_t huge_class_size; + + static void zram_free_page(struct zram *zram, size_t index); +#ifdef CONFIG_PREEMPT_RT_BASE +static void zram_meta_init_table_locks(struct zram *zram, size_t num_pages) @@ -31,54 +28,68 @@ index 27b202c64c84..bde8871f41ed 100644 + spin_lock_init(&zram->table[index].lock); +} + ++static int zram_slot_trylock(struct zram *zram, u32 index) ++{ ++ int ret; ++ ++ ret = spin_trylock(&zram->table[index].lock); ++ if (ret) ++ __set_bit(ZRAM_LOCK, &zram->table[index].value); ++ return ret; ++} ++ +static void zram_slot_lock(struct zram *zram, u32 index) +{ + spin_lock(&zram->table[index].lock); -+ __set_bit(ZRAM_ACCESS, &zram->table[index].value); ++ __set_bit(ZRAM_LOCK, &zram->table[index].value); +} + +static void zram_slot_unlock(struct zram *zram, u32 index) +{ -+ __clear_bit(ZRAM_ACCESS, &zram->table[index].value); ++ __clear_bit(ZRAM_LOCK, &zram->table[index].value); + spin_unlock(&zram->table[index].lock); +} + +#else +static void zram_meta_init_table_locks(struct zram *zram, size_t num_pages) { } + - static void zram_slot_lock(struct zram *zram, u32 index) + static int zram_slot_trylock(struct zram *zram, u32 index) { - bit_spin_lock(ZRAM_ACCESS, &zram->table[index].value); -@@ -770,6 +794,7 @@ static void zram_slot_unlock(struct zram *zram, u32 index) + return bit_spin_trylock(ZRAM_LOCK, &zram->table[index].value); +@@ -67,6 +101,7 @@ static void zram_slot_unlock(struct zram { - bit_spin_unlock(ZRAM_ACCESS, &zram->table[index].value); + bit_spin_unlock(ZRAM_LOCK, &zram->table[index].value); } +#endif + static inline bool init_done(struct zram *zram) + { +@@ -900,6 +935,8 @@ static DEVICE_ATTR_RO(io_stat); + static DEVICE_ATTR_RO(mm_stat); + static DEVICE_ATTR_RO(debug_stat); + ++ ++ static void zram_meta_free(struct zram *zram, u64 disksize) { -@@ -799,6 +824,7 @@ static bool zram_meta_alloc(struct zram *zram, u64 disksize) - return false; - } + size_t num_pages = disksize >> PAGE_SHIFT; +@@ -930,6 +967,7 @@ static bool zram_meta_alloc(struct zram + if (!huge_class_size) + huge_class_size = zs_huge_class_size(zram->mem_pool); + zram_meta_init_table_locks(zram, num_pages); return true; } -diff --git a/drivers/block/zram/zram_drv.h b/drivers/block/zram/zram_drv.h -index 31762db861e3..a417c96b8f3f 100644 --- a/drivers/block/zram/zram_drv.h +++ b/drivers/block/zram/zram_drv.h -@@ -77,6 +77,9 @@ struct zram_table_entry { +@@ -61,6 +61,9 @@ struct zram_table_entry { unsigned long element; }; unsigned long value; +#ifdef CONFIG_PREEMPT_RT_BASE + spinlock_t lock; +#endif - }; - - struct zram_stats { --- -2.19.2 - + #ifdef CONFIG_ZRAM_MEMORY_TRACKING + ktime_t ac_time; + #endif diff --git a/kernel/patches-4.14.x-rt/0392-drivers-zram-Don-t-disable-preemption-in-zcomp_strea.patch b/kernel/patches-4.19.x-rt/0252-drivers-zram-Don-t-disable-preemption-in-zcomp_strea.patch similarity index 69% rename from kernel/patches-4.14.x-rt/0392-drivers-zram-Don-t-disable-preemption-in-zcomp_strea.patch rename to kernel/patches-4.19.x-rt/0252-drivers-zram-Don-t-disable-preemption-in-zcomp_strea.patch index 711fce209..e6ea828d3 100644 --- a/kernel/patches-4.14.x-rt/0392-drivers-zram-Don-t-disable-preemption-in-zcomp_strea.patch +++ b/kernel/patches-4.19.x-rt/0252-drivers-zram-Don-t-disable-preemption-in-zcomp_strea.patch @@ -1,7 +1,6 @@ -From 912de8033e7d10dcf3340bd41af5db636c239e72 Mon Sep 17 00:00:00 2001 From: Mike Galbraith Date: Thu, 20 Oct 2016 11:15:22 +0200 -Subject: [PATCH 392/450] drivers/zram: Don't disable preemption in +Subject: [PATCH] drivers/zram: Don't disable preemption in zcomp_stream_get/put() In v4.7, the driver switched to percpu compression streams, disabling @@ -14,16 +13,14 @@ Signed-off-by: Mike Galbraith [bigeasy: get_locked_var() -> per zcomp_strm lock] Signed-off-by: Sebastian Andrzej Siewior --- - drivers/block/zram/zcomp.c | 12 ++++++++++-- - drivers/block/zram/zcomp.h | 1 + - drivers/block/zram/zram_drv.c | 5 +++-- + drivers/block/zram/zcomp.c | 12 ++++++++++-- + drivers/block/zram/zcomp.h | 1 + + drivers/block/zram/zram_drv.c | 5 +++-- 3 files changed, 14 insertions(+), 4 deletions(-) -diff --git a/drivers/block/zram/zcomp.c b/drivers/block/zram/zcomp.c -index 5b8992beffec..374931245128 100644 --- a/drivers/block/zram/zcomp.c +++ b/drivers/block/zram/zcomp.c -@@ -116,12 +116,19 @@ ssize_t zcomp_available_show(const char *comp, char *buf) +@@ -116,12 +116,19 @@ ssize_t zcomp_available_show(const char struct zcomp_strm *zcomp_stream_get(struct zcomp *comp) { @@ -45,7 +42,7 @@ index 5b8992beffec..374931245128 100644 } int zcomp_compress(struct zcomp_strm *zstrm, -@@ -171,6 +178,7 @@ int zcomp_cpu_up_prepare(unsigned int cpu, struct hlist_node *node) +@@ -171,6 +178,7 @@ int zcomp_cpu_up_prepare(unsigned int cp pr_err("Can't allocate a compression stream\n"); return -ENOMEM; } @@ -53,8 +50,6 @@ index 5b8992beffec..374931245128 100644 *per_cpu_ptr(comp->stream, cpu) = zstrm; return 0; } -diff --git a/drivers/block/zram/zcomp.h b/drivers/block/zram/zcomp.h -index 41c1002a7d7d..d424eafcbf8e 100644 --- a/drivers/block/zram/zcomp.h +++ b/drivers/block/zram/zcomp.h @@ -14,6 +14,7 @@ struct zcomp_strm { @@ -65,11 +60,9 @@ index 41c1002a7d7d..d424eafcbf8e 100644 }; /* dynamic per-device compression frontend */ -diff --git a/drivers/block/zram/zram_drv.c b/drivers/block/zram/zram_drv.c -index bde8871f41ed..269a16e312f7 100644 --- a/drivers/block/zram/zram_drv.c +++ b/drivers/block/zram/zram_drv.c -@@ -876,6 +876,7 @@ static int __zram_bvec_read(struct zram *zram, struct page *page, u32 index, +@@ -1026,6 +1026,7 @@ static int __zram_bvec_read(struct zram unsigned long handle; unsigned int size; void *src, *dst; @@ -77,7 +70,7 @@ index bde8871f41ed..269a16e312f7 100644 if (zram_wb_enabled(zram)) { zram_slot_lock(zram, index); -@@ -910,6 +911,7 @@ static int __zram_bvec_read(struct zram *zram, struct page *page, u32 index, +@@ -1060,6 +1061,7 @@ static int __zram_bvec_read(struct zram size = zram_get_obj_size(zram, index); @@ -85,7 +78,7 @@ index bde8871f41ed..269a16e312f7 100644 src = zs_map_object(zram->mem_pool, handle, ZS_MM_RO); if (size == PAGE_SIZE) { dst = kmap_atomic(page); -@@ -917,14 +919,13 @@ static int __zram_bvec_read(struct zram *zram, struct page *page, u32 index, +@@ -1067,14 +1069,13 @@ static int __zram_bvec_read(struct zram kunmap_atomic(dst); ret = 0; } else { @@ -101,6 +94,3 @@ index bde8871f41ed..269a16e312f7 100644 zram_slot_unlock(zram, index); /* Should NEVER happen. Return bio error if it does. */ --- -2.19.2 - diff --git a/kernel/patches-4.14.x-rt/0393-drivers-zram-fix-zcomp_stream_get-smp_processor_id-u.patch b/kernel/patches-4.19.x-rt/0253-drivers-zram-fix-zcomp_stream_get-smp_processor_id-u.patch similarity index 65% rename from kernel/patches-4.14.x-rt/0393-drivers-zram-fix-zcomp_stream_get-smp_processor_id-u.patch rename to kernel/patches-4.19.x-rt/0253-drivers-zram-fix-zcomp_stream_get-smp_processor_id-u.patch index f4db705e7..fde000b05 100644 --- a/kernel/patches-4.14.x-rt/0393-drivers-zram-fix-zcomp_stream_get-smp_processor_id-u.patch +++ b/kernel/patches-4.19.x-rt/0253-drivers-zram-fix-zcomp_stream_get-smp_processor_id-u.patch @@ -1,8 +1,7 @@ -From 72be58e6adba4825bfad0c9604eed85fcd8030ca Mon Sep 17 00:00:00 2001 From: Mike Galbraith Date: Wed, 23 Aug 2017 11:57:29 +0200 -Subject: [PATCH 393/450] drivers/zram: fix zcomp_stream_get() - smp_processor_id() use in preemptible code +Subject: [PATCH] drivers/zram: fix zcomp_stream_get() smp_processor_id() use + in preemptible code Use get_local_ptr() instead this_cpu_ptr() to avoid a warning regarding smp_processor_id() in preemptible code. @@ -14,14 +13,12 @@ Cc: stable-rt@vger.kernel.org Signed-off-by: Mike Galbraith Signed-off-by: Sebastian Andrzej Siewior --- - drivers/block/zram/zcomp.c | 3 ++- + drivers/block/zram/zcomp.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) -diff --git a/drivers/block/zram/zcomp.c b/drivers/block/zram/zcomp.c -index 374931245128..40345483a022 100644 --- a/drivers/block/zram/zcomp.c +++ b/drivers/block/zram/zcomp.c -@@ -118,7 +118,7 @@ struct zcomp_strm *zcomp_stream_get(struct zcomp *comp) +@@ -118,7 +118,7 @@ struct zcomp_strm *zcomp_stream_get(stru { struct zcomp_strm *zstrm; @@ -30,7 +27,7 @@ index 374931245128..40345483a022 100644 spin_lock(&zstrm->zcomp_lock); return zstrm; } -@@ -129,6 +129,7 @@ void zcomp_stream_put(struct zcomp *comp) +@@ -129,6 +129,7 @@ void zcomp_stream_put(struct zcomp *comp zstrm = *this_cpu_ptr(comp->stream); spin_unlock(&zstrm->zcomp_lock); @@ -38,6 +35,3 @@ index 374931245128..40345483a022 100644 } int zcomp_compress(struct zcomp_strm *zstrm, --- -2.19.2 - diff --git a/kernel/patches-4.14.x-rt/0394-tpm_tis-fix-stall-after-iowrite-s.patch b/kernel/patches-4.19.x-rt/0254-tpm_tis-fix-stall-after-iowrite-s.patch similarity index 78% rename from kernel/patches-4.14.x-rt/0394-tpm_tis-fix-stall-after-iowrite-s.patch rename to kernel/patches-4.19.x-rt/0254-tpm_tis-fix-stall-after-iowrite-s.patch index 6d6afe66e..012162724 100644 --- a/kernel/patches-4.14.x-rt/0394-tpm_tis-fix-stall-after-iowrite-s.patch +++ b/kernel/patches-4.19.x-rt/0254-tpm_tis-fix-stall-after-iowrite-s.patch @@ -1,7 +1,6 @@ -From 89f1902ff3e45ed84f483356f9c28ae5afa78d0c Mon Sep 17 00:00:00 2001 From: Haris Okanovic Date: Tue, 15 Aug 2017 15:13:08 -0500 -Subject: [PATCH 394/450] tpm_tis: fix stall after iowrite*()s +Subject: [PATCH] tpm_tis: fix stall after iowrite*()s ioread8() operations to TPM MMIO addresses can stall the cpu when immediately following a sequence of iowrite*()'s to the same region. @@ -21,14 +20,12 @@ amortize the cost of flushing data to chip across multiple instructions. Signed-off-by: Haris Okanovic Signed-off-by: Sebastian Andrzej Siewior --- - drivers/char/tpm/tpm_tis.c | 29 +++++++++++++++++++++++++++-- + drivers/char/tpm/tpm_tis.c | 29 +++++++++++++++++++++++++++-- 1 file changed, 27 insertions(+), 2 deletions(-) -diff --git a/drivers/char/tpm/tpm_tis.c b/drivers/char/tpm/tpm_tis.c -index 50b59a69dc33..cbdb0a6c5337 100644 --- a/drivers/char/tpm/tpm_tis.c +++ b/drivers/char/tpm/tpm_tis.c -@@ -52,6 +52,31 @@ static inline struct tpm_tis_tcg_phy *to_tpm_tis_tcg_phy(struct tpm_tis_data *da +@@ -53,6 +53,31 @@ static inline struct tpm_tis_tcg_phy *to return container_of(data, struct tpm_tis_tcg_phy, priv); } @@ -60,7 +57,7 @@ index 50b59a69dc33..cbdb0a6c5337 100644 static bool interrupts = true; module_param(interrupts, bool, 0444); MODULE_PARM_DESC(interrupts, "Enable interrupts"); -@@ -149,7 +174,7 @@ static int tpm_tcg_write_bytes(struct tpm_tis_data *data, u32 addr, u16 len, +@@ -150,7 +175,7 @@ static int tpm_tcg_write_bytes(struct tp struct tpm_tis_tcg_phy *phy = to_tpm_tis_tcg_phy(data); while (len--) @@ -69,7 +66,7 @@ index 50b59a69dc33..cbdb0a6c5337 100644 return 0; } -@@ -176,7 +201,7 @@ static int tpm_tcg_write32(struct tpm_tis_data *data, u32 addr, u32 value) +@@ -177,7 +202,7 @@ static int tpm_tcg_write32(struct tpm_ti { struct tpm_tis_tcg_phy *phy = to_tpm_tis_tcg_phy(data); @@ -78,6 +75,3 @@ index 50b59a69dc33..cbdb0a6c5337 100644 return 0; } --- -2.19.2 - diff --git a/kernel/patches-4.19.x-rt/0255-watchdog-prevent-deferral-of-watchdogd-wakeup-on-RT.patch b/kernel/patches-4.19.x-rt/0255-watchdog-prevent-deferral-of-watchdogd-wakeup-on-RT.patch new file mode 100644 index 000000000..2e954cf7d --- /dev/null +++ b/kernel/patches-4.19.x-rt/0255-watchdog-prevent-deferral-of-watchdogd-wakeup-on-RT.patch @@ -0,0 +1,74 @@ +From: Julia Cartwright +Date: Fri, 28 Sep 2018 21:03:51 +0000 +Subject: [PATCH] watchdog: prevent deferral of watchdogd wakeup on RT + +When PREEMPT_RT_FULL is enabled, all hrtimer expiry functions are +deferred for execution into the context of ktimersoftd unless otherwise +annotated. + +Deferring the expiry of the hrtimer used by the watchdog core, however, +is a waste, as the callback does nothing but queue a kthread work item +and wakeup watchdogd. + +It's worst then that, too: the deferral through ktimersoftd also means +that for correct behavior a user must adjust the scheduling parameters +of both watchdogd _and_ ktimersoftd, which is unnecessary and has other +side effects (like causing unrelated expiry functions to execute at +potentially elevated priority). + +Instead, mark the hrtimer used by the watchdog core as being _HARD to +allow it's execution directly from hardirq context. The work done in +this expiry function is well-bounded and minimal. + +A user still must adjust the scheduling parameters of the watchdogd +to be correct w.r.t. their application needs. + +Cc: Guenter Roeck +Reported-and-tested-by: Steffen Trumtrar +Reported-by: Tim Sander +Signed-off-by: Julia Cartwright +Acked-by: Guenter Roeck +[bigeasy: use only HRTIMER_MODE_REL_HARD] +Signed-off-by: Sebastian Andrzej Siewior +--- + drivers/watchdog/watchdog_dev.c | 8 ++++---- + 1 file changed, 4 insertions(+), 4 deletions(-) + +--- a/drivers/watchdog/watchdog_dev.c ++++ b/drivers/watchdog/watchdog_dev.c +@@ -147,7 +147,7 @@ static inline void watchdog_update_worke + ktime_t t = watchdog_next_keepalive(wdd); + + if (t > 0) +- hrtimer_start(&wd_data->timer, t, HRTIMER_MODE_REL); ++ hrtimer_start(&wd_data->timer, t, HRTIMER_MODE_REL_HARD); + } else { + hrtimer_cancel(&wd_data->timer); + } +@@ -166,7 +166,7 @@ static int __watchdog_ping(struct watchd + if (ktime_after(earliest_keepalive, now)) { + hrtimer_start(&wd_data->timer, + ktime_sub(earliest_keepalive, now), +- HRTIMER_MODE_REL); ++ HRTIMER_MODE_REL_HARD); + return 0; + } + +@@ -945,7 +945,7 @@ static int watchdog_cdev_register(struct + return -ENODEV; + + kthread_init_work(&wd_data->work, watchdog_ping_work); +- hrtimer_init(&wd_data->timer, CLOCK_MONOTONIC, HRTIMER_MODE_REL); ++ hrtimer_init(&wd_data->timer, CLOCK_MONOTONIC, HRTIMER_MODE_REL_HARD); + wd_data->timer.function = watchdog_timer_expired; + + if (wdd->id == 0) { +@@ -992,7 +992,7 @@ static int watchdog_cdev_register(struct + __module_get(wdd->ops->owner); + kref_get(&wd_data->kref); + if (handle_boot_enabled) +- hrtimer_start(&wd_data->timer, 0, HRTIMER_MODE_REL); ++ hrtimer_start(&wd_data->timer, 0, HRTIMER_MODE_REL_HARD); + else + pr_info("watchdog%d running and kernel based pre-userspace handler disabled\n", + wdd->id); diff --git a/kernel/patches-4.14.x-rt/0396-drm-radeon-i915-Use-preempt_disable-enable_rt-where-.patch b/kernel/patches-4.19.x-rt/0256-drmradeoni915_Use_preempt_disableenable_rt()_where_recommended.patch similarity index 60% rename from kernel/patches-4.14.x-rt/0396-drm-radeon-i915-Use-preempt_disable-enable_rt-where-.patch rename to kernel/patches-4.19.x-rt/0256-drmradeoni915_Use_preempt_disableenable_rt()_where_recommended.patch index 84b6ce11a..208b03f55 100644 --- a/kernel/patches-4.14.x-rt/0396-drm-radeon-i915-Use-preempt_disable-enable_rt-where-.patch +++ b/kernel/patches-4.19.x-rt/0256-drmradeoni915_Use_preempt_disableenable_rt()_where_recommended.patch @@ -1,8 +1,6 @@ -From 70536d56ecd5eb835f376d928cf1c650c3b7c224 Mon Sep 17 00:00:00 2001 +Subject: drm,radeon,i915: Use preempt_disable/enable_rt() where recommended From: Mike Galbraith Date: Sat, 27 Feb 2016 08:09:11 +0100 -Subject: [PATCH 396/450] drm,radeon,i915: Use preempt_disable/enable_rt() - where recommended DRM folks identified the spots, so use them. @@ -11,15 +9,13 @@ Cc: Sebastian Andrzej Siewior Cc: linux-rt-users Signed-off-by: Thomas Gleixner --- - drivers/gpu/drm/i915/i915_irq.c | 2 ++ - drivers/gpu/drm/radeon/radeon_display.c | 2 ++ + drivers/gpu/drm/i915/i915_irq.c | 2 ++ + drivers/gpu/drm/radeon/radeon_display.c | 2 ++ 2 files changed, 4 insertions(+) -diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c -index 20a471ad0ad2..5d34d48a8b7b 100644 --- a/drivers/gpu/drm/i915/i915_irq.c +++ b/drivers/gpu/drm/i915/i915_irq.c -@@ -867,6 +867,7 @@ static bool i915_get_crtc_scanoutpos(struct drm_device *dev, unsigned int pipe, +@@ -1025,6 +1025,7 @@ static bool i915_get_crtc_scanoutpos(str spin_lock_irqsave(&dev_priv->uncore.lock, irqflags); /* preempt_disable_rt() should go right here in PREEMPT_RT patchset. */ @@ -27,7 +23,7 @@ index 20a471ad0ad2..5d34d48a8b7b 100644 /* Get optional system timestamp before query. */ if (stime) -@@ -918,6 +919,7 @@ static bool i915_get_crtc_scanoutpos(struct drm_device *dev, unsigned int pipe, +@@ -1076,6 +1077,7 @@ static bool i915_get_crtc_scanoutpos(str *etime = ktime_get(); /* preempt_enable_rt() should go right here in PREEMPT_RT patchset. */ @@ -35,11 +31,9 @@ index 20a471ad0ad2..5d34d48a8b7b 100644 spin_unlock_irqrestore(&dev_priv->uncore.lock, irqflags); -diff --git a/drivers/gpu/drm/radeon/radeon_display.c b/drivers/gpu/drm/radeon/radeon_display.c -index ddfe91efa61e..3157bcf6428f 100644 --- a/drivers/gpu/drm/radeon/radeon_display.c +++ b/drivers/gpu/drm/radeon/radeon_display.c -@@ -1839,6 +1839,7 @@ int radeon_get_crtc_scanoutpos(struct drm_device *dev, unsigned int pipe, +@@ -1813,6 +1813,7 @@ int radeon_get_crtc_scanoutpos(struct dr struct radeon_device *rdev = dev->dev_private; /* preempt_disable_rt() should go right here in PREEMPT_RT patchset. */ @@ -47,7 +41,7 @@ index ddfe91efa61e..3157bcf6428f 100644 /* Get optional system timestamp before query. */ if (stime) -@@ -1931,6 +1932,7 @@ int radeon_get_crtc_scanoutpos(struct drm_device *dev, unsigned int pipe, +@@ -1905,6 +1906,7 @@ int radeon_get_crtc_scanoutpos(struct dr *etime = ktime_get(); /* preempt_enable_rt() should go right here in PREEMPT_RT patchset. */ @@ -55,6 +49,3 @@ index ddfe91efa61e..3157bcf6428f 100644 /* Decode into vertical and horizontal scanout position. */ *vpos = position & 0x1fff; --- -2.19.2 - diff --git a/kernel/patches-4.14.x-rt/0397-drm-i915-Use-local_lock-unlock_irq-in-intel_pipe_upd.patch b/kernel/patches-4.19.x-rt/0257-drmi915_Use_local_lockunlock_irq()_in_intel_pipe_update_startend().patch similarity index 83% rename from kernel/patches-4.14.x-rt/0397-drm-i915-Use-local_lock-unlock_irq-in-intel_pipe_upd.patch rename to kernel/patches-4.19.x-rt/0257-drmi915_Use_local_lockunlock_irq()_in_intel_pipe_update_startend().patch index fc1b092d6..21ac78071 100644 --- a/kernel/patches-4.14.x-rt/0397-drm-i915-Use-local_lock-unlock_irq-in-intel_pipe_upd.patch +++ b/kernel/patches-4.19.x-rt/0257-drmi915_Use_local_lockunlock_irq()_in_intel_pipe_update_startend().patch @@ -1,8 +1,7 @@ -From 64527d1b545fbf0b43017ec72478da9183dda8f9 Mon Sep 17 00:00:00 2001 +Subject: drm,i915: Use local_lock/unlock_irq() in intel_pipe_update_start/end() From: Mike Galbraith Date: Sat, 27 Feb 2016 09:01:42 +0100 -Subject: [PATCH 397/450] drm,i915: Use local_lock/unlock_irq() in - intel_pipe_update_start/end() + [ 8.014039] BUG: sleeping function called from invalid context at kernel/locking/rtmutex.c:918 [ 8.014041] in_atomic(): 0, irqs_disabled(): 1, pid: 78, name: kworker/u4:4 @@ -57,11 +56,9 @@ Cc: Sebastian Andrzej Siewior Cc: linux-rt-users Signed-off-by: Thomas Gleixner --- - drivers/gpu/drm/i915/intel_sprite.c | 11 ++++++----- - 1 file changed, 6 insertions(+), 5 deletions(-) + drivers/gpu/drm/i915/intel_sprite.c | 13 ++++++++----- + 1 file changed, 8 insertions(+), 5 deletions(-) -diff --git a/drivers/gpu/drm/i915/intel_sprite.c b/drivers/gpu/drm/i915/intel_sprite.c -index 41e31a454604..7e0cadf51b31 100644 --- a/drivers/gpu/drm/i915/intel_sprite.c +++ b/drivers/gpu/drm/i915/intel_sprite.c @@ -36,6 +36,7 @@ @@ -72,25 +69,25 @@ index 41e31a454604..7e0cadf51b31 100644 #include "intel_drv.h" #include "intel_frontbuffer.h" #include -@@ -67,7 +68,7 @@ int intel_usecs_to_scanlines(const struct drm_display_mode *adjusted_mode, - } - +@@ -60,6 +61,8 @@ int intel_usecs_to_scanlines(const struc #define VBLANK_EVASION_TIME_US 100 -- + #endif + +static DEFINE_LOCAL_IRQ_LOCK(pipe_update_lock); ++ /** * intel_pipe_update_start() - start update of a set of display registers - * @crtc: the crtc of which the registers are going to be updated -@@ -102,7 +103,7 @@ void intel_pipe_update_start(struct intel_crtc *crtc) - VBLANK_EVASION_TIME_US); - max = vblank_start - 1; + * @new_crtc_state: the new crtc state +@@ -107,7 +110,7 @@ void intel_pipe_update_start(const struc + if (intel_psr_wait_for_idle(new_crtc_state)) + DRM_ERROR("PSR idle timed out, atomic update may fail\n"); - local_irq_disable(); + local_lock_irq(pipe_update_lock); - if (min <= 0 || max <= 0) - return; -@@ -132,11 +133,11 @@ void intel_pipe_update_start(struct intel_crtc *crtc) + crtc->debug.min_vbl = min; + crtc->debug.max_vbl = max; +@@ -131,11 +134,11 @@ void intel_pipe_update_start(const struc break; } @@ -104,8 +101,17 @@ index 41e31a454604..7e0cadf51b31 100644 } finish_wait(wq, &wait); -@@ -201,7 +202,7 @@ void intel_pipe_update_end(struct intel_crtc *crtc) - crtc->base.state->event = NULL; +@@ -168,7 +171,7 @@ void intel_pipe_update_start(const struc + return; + + irq_disable: +- local_irq_disable(); ++ local_lock_irq(pipe_update_lock); + } + + /** +@@ -204,7 +207,7 @@ void intel_pipe_update_end(struct intel_ + new_crtc_state->base.event = NULL; } - local_irq_enable(); @@ -113,6 +119,3 @@ index 41e31a454604..7e0cadf51b31 100644 if (intel_vgpu_active(dev_priv)) return; --- -2.19.2 - diff --git a/kernel/patches-4.14.x-rt/0446-drm-i915-disable-tracing-on-RT.patch b/kernel/patches-4.19.x-rt/0258-drm-i915-disable-tracing-on-RT.patch similarity index 74% rename from kernel/patches-4.14.x-rt/0446-drm-i915-disable-tracing-on-RT.patch rename to kernel/patches-4.19.x-rt/0258-drm-i915-disable-tracing-on-RT.patch index 6c86b7a0c..634ce8c06 100644 --- a/kernel/patches-4.14.x-rt/0446-drm-i915-disable-tracing-on-RT.patch +++ b/kernel/patches-4.19.x-rt/0258-drm-i915-disable-tracing-on-RT.patch @@ -1,9 +1,6 @@ -From 78503b8e92ec3b0c27a46fc5834e39e3cdf415b6 Mon Sep 17 00:00:00 2001 From: Sebastian Andrzej Siewior Date: Thu, 6 Dec 2018 09:52:20 +0100 -Subject: [PATCH 446/450] drm/i915: disable tracing on -RT - -[ Upstream commit 05cebb309b156646e61b898e92acc8e46c47ba75 ] +Subject: [PATCH] drm/i915: disable tracing on -RT Luca Abeni reported this: | BUG: scheduling while atomic: kworker/u8:2/15203/0x00000003 @@ -24,13 +21,10 @@ Based on this I don't see any other way than disable trace points on RT. Cc: stable-rt@vger.kernel.org Reported-by: Luca Abeni Signed-off-by: Sebastian Andrzej Siewior -Signed-off-by: Steven Rostedt (VMware) --- - drivers/gpu/drm/i915/i915_trace.h | 4 ++++ + drivers/gpu/drm/i915/i915_trace.h | 4 ++++ 1 file changed, 4 insertions(+) -diff --git a/drivers/gpu/drm/i915/i915_trace.h b/drivers/gpu/drm/i915/i915_trace.h -index ef72da74b87f..adf0974415bc 100644 --- a/drivers/gpu/drm/i915/i915_trace.h +++ b/drivers/gpu/drm/i915/i915_trace.h @@ -2,6 +2,10 @@ @@ -44,6 +38,3 @@ index ef72da74b87f..adf0974415bc 100644 #include #include #include --- -2.19.2 - diff --git a/kernel/patches-4.19.x-rt/0259-drm-i915-skip-DRM_I915_LOW_LEVEL_TRACEPOINTS-with-NO.patch b/kernel/patches-4.19.x-rt/0259-drm-i915-skip-DRM_I915_LOW_LEVEL_TRACEPOINTS-with-NO.patch new file mode 100644 index 000000000..c660aeb73 --- /dev/null +++ b/kernel/patches-4.19.x-rt/0259-drm-i915-skip-DRM_I915_LOW_LEVEL_TRACEPOINTS-with-NO.patch @@ -0,0 +1,25 @@ +From: Sebastian Andrzej Siewior +Date: Wed, 19 Dec 2018 10:47:02 +0100 +Subject: [PATCH] drm/i915: skip DRM_I915_LOW_LEVEL_TRACEPOINTS with NOTRACE + +The order of the header files is important. If this header file is +included after tracepoint.h was included then the NOTRACE here becomes a +nop. Currently this happens for two .c files which use the tracepoitns +behind DRM_I915_LOW_LEVEL_TRACEPOINTS. + +Signed-off-by: Sebastian Andrzej Siewior +--- + drivers/gpu/drm/i915/i915_trace.h | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/drivers/gpu/drm/i915/i915_trace.h ++++ b/drivers/gpu/drm/i915/i915_trace.h +@@ -683,7 +683,7 @@ DEFINE_EVENT(i915_request, i915_request_ + TP_ARGS(rq) + ); + +-#if defined(CONFIG_DRM_I915_LOW_LEVEL_TRACEPOINTS) ++#if defined(CONFIG_DRM_I915_LOW_LEVEL_TRACEPOINTS) && !defined(NOTRACE) + DEFINE_EVENT(i915_request, i915_request_submit, + TP_PROTO(struct i915_request *rq), + TP_ARGS(rq) diff --git a/kernel/patches-4.14.x-rt/0398-cgroups-use-simple-wait-in-css_release.patch b/kernel/patches-4.19.x-rt/0260-cgroups-use-simple-wait-in-css_release.patch similarity index 75% rename from kernel/patches-4.14.x-rt/0398-cgroups-use-simple-wait-in-css_release.patch rename to kernel/patches-4.19.x-rt/0260-cgroups-use-simple-wait-in-css_release.patch index 172516c5a..8963a3e86 100644 --- a/kernel/patches-4.14.x-rt/0398-cgroups-use-simple-wait-in-css_release.patch +++ b/kernel/patches-4.19.x-rt/0260-cgroups-use-simple-wait-in-css_release.patch @@ -1,7 +1,6 @@ -From d7802ae19e6c72f9ac79e4f520aafd24bb103d57 Mon Sep 17 00:00:00 2001 From: Sebastian Andrzej Siewior Date: Fri, 13 Feb 2015 15:52:24 +0100 -Subject: [PATCH 398/450] cgroups: use simple wait in css_release() +Subject: cgroups: use simple wait in css_release() To avoid: |BUG: sleeping function called from invalid context at kernel/locking/rtmutex.c:914 @@ -29,36 +28,32 @@ To avoid: Signed-off-by: Sebastian Andrzej Siewior --- - include/linux/cgroup-defs.h | 2 ++ - kernel/cgroup/cgroup.c | 9 +++++---- + include/linux/cgroup-defs.h | 2 ++ + kernel/cgroup/cgroup.c | 9 +++++---- 2 files changed, 7 insertions(+), 4 deletions(-) -diff --git a/include/linux/cgroup-defs.h b/include/linux/cgroup-defs.h -index e7905d9353e8..4ecf7875e04f 100644 --- a/include/linux/cgroup-defs.h +++ b/include/linux/cgroup-defs.h -@@ -19,6 +19,7 @@ - #include +@@ -20,6 +20,7 @@ + #include #include #include +#include #ifdef CONFIG_CGROUPS -@@ -152,6 +153,7 @@ struct cgroup_subsys_state { +@@ -157,6 +158,7 @@ struct cgroup_subsys_state { + /* percpu_ref killing and RCU release */ - struct rcu_head rcu_head; struct work_struct destroy_work; + struct swork_event destroy_swork; + struct rcu_work destroy_rwork; /* - * PI: the parent css. Placed here for cache proximity to following -diff --git a/kernel/cgroup/cgroup.c b/kernel/cgroup/cgroup.c -index 3fc11b8851ac..a04c3aded76b 100644 --- a/kernel/cgroup/cgroup.c +++ b/kernel/cgroup/cgroup.c -@@ -4515,10 +4515,10 @@ static void css_free_rcu_fn(struct rcu_head *rcu_head) - queue_work(cgroup_destroy_wq, &css->destroy_work); +@@ -4625,10 +4625,10 @@ static void css_free_rwork_fn(struct wor + } } -static void css_release_work_fn(struct work_struct *work) @@ -70,7 +65,7 @@ index 3fc11b8851ac..a04c3aded76b 100644 struct cgroup_subsys *ss = css->ss; struct cgroup *cgrp = css->cgroup; -@@ -4569,8 +4569,8 @@ static void css_release(struct percpu_ref *ref) +@@ -4688,8 +4688,8 @@ static void css_release(struct percpu_re struct cgroup_subsys_state *css = container_of(ref, struct cgroup_subsys_state, refcnt); @@ -81,7 +76,7 @@ index 3fc11b8851ac..a04c3aded76b 100644 } static void init_and_link_css(struct cgroup_subsys_state *css, -@@ -5276,6 +5276,7 @@ static int __init cgroup_wq_init(void) +@@ -5411,6 +5411,7 @@ static int __init cgroup_wq_init(void) */ cgroup_destroy_wq = alloc_workqueue("cgroup_destroy", 0, 1); BUG_ON(!cgroup_destroy_wq); @@ -89,6 +84,3 @@ index 3fc11b8851ac..a04c3aded76b 100644 return 0; } core_initcall(cgroup_wq_init); --- -2.19.2 - diff --git a/kernel/patches-4.14.x-rt/0401-cpuset-Convert-callback_lock-to-raw_spinlock_t.patch b/kernel/patches-4.19.x-rt/0261-cpuset-Convert-callback_lock-to-raw_spinlock_t.patch similarity index 81% rename from kernel/patches-4.14.x-rt/0401-cpuset-Convert-callback_lock-to-raw_spinlock_t.patch rename to kernel/patches-4.19.x-rt/0261-cpuset-Convert-callback_lock-to-raw_spinlock_t.patch index c850db396..db1c0e36e 100644 --- a/kernel/patches-4.14.x-rt/0401-cpuset-Convert-callback_lock-to-raw_spinlock_t.patch +++ b/kernel/patches-4.19.x-rt/0261-cpuset-Convert-callback_lock-to-raw_spinlock_t.patch @@ -1,7 +1,6 @@ -From c57cd4291d8026ef3c55b26b80471f4a62dd1742 Mon Sep 17 00:00:00 2001 From: Mike Galbraith Date: Sun, 8 Jan 2017 09:32:25 +0100 -Subject: [PATCH 401/450] cpuset: Convert callback_lock to raw_spinlock_t +Subject: [PATCH] cpuset: Convert callback_lock to raw_spinlock_t The two commits below add up to a cpuset might_sleep() splat for RT: @@ -46,11 +45,9 @@ Cc: stable-rt@vger.kernel.org Signed-off-by: Mike Galbraith Signed-off-by: Sebastian Andrzej Siewior --- - kernel/cgroup/cpuset.c | 66 +++++++++++++++++++++--------------------- + kernel/cgroup/cpuset.c | 66 ++++++++++++++++++++++++------------------------- 1 file changed, 33 insertions(+), 33 deletions(-) -diff --git a/kernel/cgroup/cpuset.c b/kernel/cgroup/cpuset.c -index 7bb7384b543a..bda2af78277a 100644 --- a/kernel/cgroup/cpuset.c +++ b/kernel/cgroup/cpuset.c @@ -288,7 +288,7 @@ static struct cpuset top_cpuset = { @@ -62,7 +59,7 @@ index 7bb7384b543a..bda2af78277a 100644 static struct workqueue_struct *cpuset_migrate_mm_wq; -@@ -926,9 +926,9 @@ static void update_cpumasks_hier(struct cpuset *cs, struct cpumask *new_cpus) +@@ -922,9 +922,9 @@ static void update_cpumasks_hier(struct continue; rcu_read_unlock(); @@ -74,7 +71,7 @@ index 7bb7384b543a..bda2af78277a 100644 WARN_ON(!is_in_v2_mode() && !cpumask_equal(cp->cpus_allowed, cp->effective_cpus)); -@@ -993,9 +993,9 @@ static int update_cpumask(struct cpuset *cs, struct cpuset *trialcs, +@@ -989,9 +989,9 @@ static int update_cpumask(struct cpuset if (retval < 0) return retval; @@ -86,7 +83,7 @@ index 7bb7384b543a..bda2af78277a 100644 /* use trialcs->cpus_allowed as a temp variable */ update_cpumasks_hier(cs, trialcs->cpus_allowed); -@@ -1179,9 +1179,9 @@ static void update_nodemasks_hier(struct cpuset *cs, nodemask_t *new_mems) +@@ -1175,9 +1175,9 @@ static void update_nodemasks_hier(struct continue; rcu_read_unlock(); @@ -98,7 +95,7 @@ index 7bb7384b543a..bda2af78277a 100644 WARN_ON(!is_in_v2_mode() && !nodes_equal(cp->mems_allowed, cp->effective_mems)); -@@ -1249,9 +1249,9 @@ static int update_nodemask(struct cpuset *cs, struct cpuset *trialcs, +@@ -1245,9 +1245,9 @@ static int update_nodemask(struct cpuset if (retval < 0) goto done; @@ -110,7 +107,7 @@ index 7bb7384b543a..bda2af78277a 100644 /* use trialcs->mems_allowed as a temp variable */ update_nodemasks_hier(cs, &trialcs->mems_allowed); -@@ -1342,9 +1342,9 @@ static int update_flag(cpuset_flagbits_t bit, struct cpuset *cs, +@@ -1338,9 +1338,9 @@ static int update_flag(cpuset_flagbits_t spread_flag_changed = ((is_spread_slab(cs) != is_spread_slab(trialcs)) || (is_spread_page(cs) != is_spread_page(trialcs))); @@ -122,7 +119,7 @@ index 7bb7384b543a..bda2af78277a 100644 if (!cpumask_empty(trialcs->cpus_allowed) && balance_flag_changed) rebuild_sched_domains_locked(); -@@ -1759,7 +1759,7 @@ static int cpuset_common_seq_show(struct seq_file *sf, void *v) +@@ -1755,7 +1755,7 @@ static int cpuset_common_seq_show(struct cpuset_filetype_t type = seq_cft(sf)->private; int ret = 0; @@ -131,7 +128,7 @@ index 7bb7384b543a..bda2af78277a 100644 switch (type) { case FILE_CPULIST: -@@ -1778,7 +1778,7 @@ static int cpuset_common_seq_show(struct seq_file *sf, void *v) +@@ -1774,7 +1774,7 @@ static int cpuset_common_seq_show(struct ret = -EINVAL; } @@ -140,7 +137,7 @@ index 7bb7384b543a..bda2af78277a 100644 return ret; } -@@ -1993,12 +1993,12 @@ static int cpuset_css_online(struct cgroup_subsys_state *css) +@@ -1989,12 +1989,12 @@ static int cpuset_css_online(struct cgro cpuset_inc(); @@ -155,7 +152,7 @@ index 7bb7384b543a..bda2af78277a 100644 if (!test_bit(CGRP_CPUSET_CLONE_CHILDREN, &css->cgroup->flags)) goto out_unlock; -@@ -2025,12 +2025,12 @@ static int cpuset_css_online(struct cgroup_subsys_state *css) +@@ -2021,12 +2021,12 @@ static int cpuset_css_online(struct cgro } rcu_read_unlock(); @@ -170,7 +167,7 @@ index 7bb7384b543a..bda2af78277a 100644 out_unlock: mutex_unlock(&cpuset_mutex); return 0; -@@ -2069,7 +2069,7 @@ static void cpuset_css_free(struct cgroup_subsys_state *css) +@@ -2065,7 +2065,7 @@ static void cpuset_css_free(struct cgrou static void cpuset_bind(struct cgroup_subsys_state *root_css) { mutex_lock(&cpuset_mutex); @@ -179,7 +176,7 @@ index 7bb7384b543a..bda2af78277a 100644 if (is_in_v2_mode()) { cpumask_copy(top_cpuset.cpus_allowed, cpu_possible_mask); -@@ -2080,7 +2080,7 @@ static void cpuset_bind(struct cgroup_subsys_state *root_css) +@@ -2076,7 +2076,7 @@ static void cpuset_bind(struct cgroup_su top_cpuset.mems_allowed = top_cpuset.effective_mems; } @@ -188,7 +185,7 @@ index 7bb7384b543a..bda2af78277a 100644 mutex_unlock(&cpuset_mutex); } -@@ -2178,12 +2178,12 @@ hotplug_update_tasks_legacy(struct cpuset *cs, +@@ -2174,12 +2174,12 @@ hotplug_update_tasks_legacy(struct cpuse { bool is_empty; @@ -203,7 +200,7 @@ index 7bb7384b543a..bda2af78277a 100644 /* * Don't call update_tasks_cpumask() if the cpuset becomes empty, -@@ -2220,10 +2220,10 @@ hotplug_update_tasks(struct cpuset *cs, +@@ -2216,10 +2216,10 @@ hotplug_update_tasks(struct cpuset *cs, if (nodes_empty(*new_mems)) *new_mems = parent_cs(cs)->effective_mems; @@ -216,7 +213,7 @@ index 7bb7384b543a..bda2af78277a 100644 if (cpus_updated) update_tasks_cpumask(cs); -@@ -2316,21 +2316,21 @@ static void cpuset_hotplug_workfn(struct work_struct *work) +@@ -2312,21 +2312,21 @@ static void cpuset_hotplug_workfn(struct /* synchronize cpus_allowed to cpu_active_mask */ if (cpus_updated) { @@ -242,7 +239,7 @@ index 7bb7384b543a..bda2af78277a 100644 update_tasks_nodemask(&top_cpuset); } -@@ -2429,11 +2429,11 @@ void cpuset_cpus_allowed(struct task_struct *tsk, struct cpumask *pmask) +@@ -2425,11 +2425,11 @@ void cpuset_cpus_allowed(struct task_str { unsigned long flags; @@ -256,7 +253,7 @@ index 7bb7384b543a..bda2af78277a 100644 } void cpuset_cpus_allowed_fallback(struct task_struct *tsk) -@@ -2481,11 +2481,11 @@ nodemask_t cpuset_mems_allowed(struct task_struct *tsk) +@@ -2477,11 +2477,11 @@ nodemask_t cpuset_mems_allowed(struct ta nodemask_t mask; unsigned long flags; @@ -270,7 +267,7 @@ index 7bb7384b543a..bda2af78277a 100644 return mask; } -@@ -2577,14 +2577,14 @@ bool __cpuset_node_allowed(int node, gfp_t gfp_mask) +@@ -2573,14 +2573,14 @@ bool __cpuset_node_allowed(int node, gfp return true; /* Not hardwall and node outside mems_allowed: scan up cpusets */ @@ -287,6 +284,3 @@ index 7bb7384b543a..bda2af78277a 100644 return allowed; } --- -2.19.2 - diff --git a/kernel/patches-4.14.x-rt/0405-apparmor-use-a-locallock-instead-preempt_disable.patch b/kernel/patches-4.19.x-rt/0262-apparmor-use-a-locallock-instead-preempt_disable.patch similarity index 52% rename from kernel/patches-4.14.x-rt/0405-apparmor-use-a-locallock-instead-preempt_disable.patch rename to kernel/patches-4.19.x-rt/0262-apparmor-use-a-locallock-instead-preempt_disable.patch index 4121d4812..5a6742fd8 100644 --- a/kernel/patches-4.14.x-rt/0405-apparmor-use-a-locallock-instead-preempt_disable.patch +++ b/kernel/patches-4.19.x-rt/0262-apparmor-use-a-locallock-instead-preempt_disable.patch @@ -1,7 +1,6 @@ -From 820c946179cf515de1701e6a5493f452b45fbede Mon Sep 17 00:00:00 2001 From: Sebastian Andrzej Siewior Date: Wed, 11 Oct 2017 17:43:49 +0200 -Subject: [PATCH 405/450] apparmor: use a locallock instead preempt_disable() +Subject: apparmor: use a locallock instead preempt_disable() get_buffers() disables preemption which acts as a lock for the per-CPU variable. Since we can't disable preemption here on RT, a local_lock is @@ -10,33 +9,29 @@ than one user within the critical section. Signed-off-by: Sebastian Andrzej Siewior --- - security/apparmor/include/path.h | 21 +++++++++++++++++---- - security/apparmor/lsm.c | 2 +- - 2 files changed, 18 insertions(+), 5 deletions(-) + security/apparmor/include/path.h | 19 ++++++++++++++++--- + security/apparmor/lsm.c | 2 +- + 2 files changed, 17 insertions(+), 4 deletions(-) -diff --git a/security/apparmor/include/path.h b/security/apparmor/include/path.h -index 05fb3305671e..b26c16b02662 100644 --- a/security/apparmor/include/path.h +++ b/security/apparmor/include/path.h -@@ -39,9 +39,10 @@ struct aa_buffers { - }; +@@ -40,8 +40,10 @@ struct aa_buffers { #include --#include + #include +#include DECLARE_PER_CPU(struct aa_buffers, aa_buffers); +DECLARE_LOCAL_IRQ_LOCK(aa_buffers_lock); - #define COUNT_ARGS(X...) COUNT_ARGS_HELPER(, ##X, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0) - #define COUNT_ARGS_HELPER(_0, _1, _2, _3, _4, _5, _6, _7, _8, _9, n, X...) n -@@ -55,12 +56,24 @@ DECLARE_PER_CPU(struct aa_buffers, aa_buffers); + #define ASSIGN(FN, A, X, N) ((X) = FN(A, N)) + #define EVAL1(FN, A, X) ASSIGN(FN, A, X, 0) /*X = FN(0)*/ +@@ -51,7 +53,17 @@ DECLARE_PER_CPU(struct aa_buffers, aa_bu #define for_each_cpu_buffer(I) for ((I) = 0; (I) < MAX_PATH_BUFFERS; (I)++) -#ifdef CONFIG_DEBUG_PREEMPT +#ifdef CONFIG_PREEMPT_RT_BASE -+ +static inline void AA_BUG_PREEMPT_ENABLED(const char *s) +{ + struct local_irq_lock *lv; @@ -50,34 +45,27 @@ index 05fb3305671e..b26c16b02662 100644 #define AA_BUG_PREEMPT_ENABLED(X) AA_BUG(preempt_count() <= 0, X) #else #define AA_BUG_PREEMPT_ENABLED(X) /* nop */ - #endif +@@ -67,14 +79,15 @@ DECLARE_PER_CPU(struct aa_buffers, aa_bu -+ - #define __get_buffer(N) ({ \ - struct aa_buffers *__cpu_var; \ - AA_BUG_PREEMPT_ENABLED("__get_buffer without preempt disabled"); \ -@@ -73,14 +86,14 @@ DECLARE_PER_CPU(struct aa_buffers, aa_buffers); - - #define get_buffers(X...) \ - do { \ -- preempt_disable(); \ -+ local_lock(aa_buffers_lock); \ - __get_buffers(X); \ + #define get_buffers(X...) \ + do { \ +- struct aa_buffers *__cpu_var = get_cpu_ptr(&aa_buffers); \ ++ struct aa_buffers *__cpu_var; \ ++ __cpu_var = get_locked_ptr(aa_buffers_lock, &aa_buffers); \ + __get_buffers(__cpu_var, X); \ } while (0) - #define put_buffers(X, Y...) \ - do { \ - __put_buffers(X, Y); \ -- preempt_enable(); \ -+ local_unlock(aa_buffers_lock); \ + #define put_buffers(X, Y...) \ + do { \ + __put_buffers(X, Y); \ +- put_cpu_ptr(&aa_buffers); \ ++ put_locked_ptr(aa_buffers_lock, &aa_buffers); \ } while (0) #endif /* __AA_PATH_H */ -diff --git a/security/apparmor/lsm.c b/security/apparmor/lsm.c -index 1346ee5be04f..aa7e4dee107b 100644 --- a/security/apparmor/lsm.c +++ b/security/apparmor/lsm.c -@@ -44,7 +44,7 @@ +@@ -45,7 +45,7 @@ int apparmor_initialized; DEFINE_PER_CPU(struct aa_buffers, aa_buffers); @@ -86,6 +74,3 @@ index 1346ee5be04f..aa7e4dee107b 100644 /* * LSM hook functions --- -2.19.2 - diff --git a/kernel/patches-4.14.x-rt/0406-workqueue-Prevent-deadlock-stall-on-RT.patch b/kernel/patches-4.19.x-rt/0263-workqueue-prevent-deadlock-stall.patch similarity index 81% rename from kernel/patches-4.14.x-rt/0406-workqueue-Prevent-deadlock-stall-on-RT.patch rename to kernel/patches-4.19.x-rt/0263-workqueue-prevent-deadlock-stall.patch index cb3cc1dc9..478256a09 100644 --- a/kernel/patches-4.14.x-rt/0406-workqueue-Prevent-deadlock-stall-on-RT.patch +++ b/kernel/patches-4.19.x-rt/0263-workqueue-prevent-deadlock-stall.patch @@ -1,7 +1,6 @@ -From fab8d1ee5c6af549a87a97f4b19d714a10db0426 Mon Sep 17 00:00:00 2001 +Subject: workqueue: Prevent deadlock/stall on RT From: Thomas Gleixner -Date: Fri, 27 Jun 2014 16:24:52 +0200 -Subject: [PATCH 406/450] workqueue: Prevent deadlock/stall on RT +Date: Fri, 27 Jun 2014 16:24:52 +0200 (CEST) Austin reported a XFS deadlock/stall on RT where scheduled work gets never exececuted and tasks are waiting for each other for ever. @@ -36,16 +35,15 @@ Signed-off-by: Thomas Gleixner Link: http://vger.kernel.org/r/alpine.DEB.2.10.1406271249510.5170@nanos Cc: Richard Weinberger Cc: Steven Rostedt ---- - kernel/sched/core.c | 7 ++++-- - kernel/workqueue.c | 60 +++++++++++++++++++++++++++++++++++---------- - 2 files changed, 52 insertions(+), 15 deletions(-) -diff --git a/kernel/sched/core.c b/kernel/sched/core.c -index 64f3c372776b..d7bfa2dd53e4 100644 +--- + kernel/sched/core.c | 6 +++-- + kernel/workqueue.c | 60 ++++++++++++++++++++++++++++++++++++++++------------ + 2 files changed, 51 insertions(+), 15 deletions(-) + --- a/kernel/sched/core.c +++ b/kernel/sched/core.c -@@ -3477,9 +3477,8 @@ void __noreturn do_task_dead(void) +@@ -3567,9 +3567,8 @@ void __noreturn do_task_dead(void) static inline void sched_submit_work(struct task_struct *tsk) { @@ -56,19 +54,16 @@ index 64f3c372776b..d7bfa2dd53e4 100644 /* * If a worker went to sleep, notify and ask workqueue whether * it wants to wake up a task to maintain concurrency. -@@ -3487,6 +3486,10 @@ static inline void sched_submit_work(struct task_struct *tsk) - if (tsk->flags & PF_WQ_WORKER) - wq_worker_sleeping(tsk); +@@ -3583,6 +3582,9 @@ static inline void sched_submit_work(str + preempt_enable_no_resched(); + } -+ + if (tsk_is_pi_blocked(tsk)) + return; + /* * If we are going to sleep and we have plugged IO queued, * make sure to submit it to avoid deadlocks. -diff --git a/kernel/workqueue.c b/kernel/workqueue.c -index c0b2a2e65d75..76297cce5602 100644 --- a/kernel/workqueue.c +++ b/kernel/workqueue.c @@ -125,6 +125,11 @@ enum { @@ -80,10 +75,10 @@ index c0b2a2e65d75..76297cce5602 100644 + * wq_worker_sleeping(). All other places are nicely serialized via + * pool->lock. + * - * A: pool->attach_mutex protected. + * A: wq_pool_attach_mutex protected. * * PL: wq_pool_mutex protected. -@@ -432,6 +437,31 @@ static void workqueue_sysfs_unregister(struct workqueue_struct *wq); +@@ -430,6 +435,31 @@ static void workqueue_sysfs_unregister(s if (({ assert_rcu_or_wq_mutex(wq); false; })) { } \ else @@ -115,7 +110,7 @@ index c0b2a2e65d75..76297cce5602 100644 #ifdef CONFIG_DEBUG_OBJECTS_WORK static struct debug_obj_descr work_debug_descr; -@@ -838,10 +868,16 @@ static struct worker *first_idle_worker(struct worker_pool *pool) +@@ -836,10 +866,16 @@ static struct worker *first_idle_worker( */ static void wake_up_worker(struct worker_pool *pool) { @@ -133,7 +128,7 @@ index c0b2a2e65d75..76297cce5602 100644 } /** -@@ -870,7 +906,7 @@ void wq_worker_running(struct task_struct *task) +@@ -868,7 +904,7 @@ void wq_worker_running(struct task_struc */ void wq_worker_sleeping(struct task_struct *task) { @@ -142,7 +137,7 @@ index c0b2a2e65d75..76297cce5602 100644 struct worker_pool *pool; /* -@@ -887,26 +923,18 @@ void wq_worker_sleeping(struct task_struct *task) +@@ -885,26 +921,18 @@ void wq_worker_sleeping(struct task_stru return; worker->sleeping = 1; @@ -172,7 +167,7 @@ index c0b2a2e65d75..76297cce5602 100644 } /** -@@ -1637,7 +1665,9 @@ static void worker_enter_idle(struct worker *worker) +@@ -1675,7 +1703,9 @@ static void worker_enter_idle(struct wor worker->last_active = jiffies; /* idle_list is LIFO */ @@ -182,7 +177,7 @@ index c0b2a2e65d75..76297cce5602 100644 if (too_many_workers(pool) && !timer_pending(&pool->idle_timer)) mod_timer(&pool->idle_timer, jiffies + IDLE_WORKER_TIMEOUT); -@@ -1670,7 +1700,9 @@ static void worker_leave_idle(struct worker *worker) +@@ -1708,7 +1738,9 @@ static void worker_leave_idle(struct wor return; worker_clr_flags(worker, WORKER_IDLE); pool->nr_idle--; @@ -192,7 +187,7 @@ index c0b2a2e65d75..76297cce5602 100644 } static struct worker *alloc_worker(int node) -@@ -1836,7 +1868,9 @@ static void destroy_worker(struct worker *worker) +@@ -1876,7 +1908,9 @@ static void destroy_worker(struct worker pool->nr_workers--; pool->nr_idle--; @@ -202,6 +197,3 @@ index c0b2a2e65d75..76297cce5602 100644 worker->flags |= WORKER_DIE; wake_up_process(worker->task); } --- -2.19.2 - diff --git a/kernel/patches-4.14.x-rt/0129-signals-Allow-rt-tasks-to-cache-one-sigqueue-struct.patch b/kernel/patches-4.19.x-rt/0264-signals-allow-rt-tasks-to-cache-one-sigqueue-struct.patch similarity index 71% rename from kernel/patches-4.14.x-rt/0129-signals-Allow-rt-tasks-to-cache-one-sigqueue-struct.patch rename to kernel/patches-4.19.x-rt/0264-signals-allow-rt-tasks-to-cache-one-sigqueue-struct.patch index 17fe86a5a..dd828e3c6 100644 --- a/kernel/patches-4.14.x-rt/0129-signals-Allow-rt-tasks-to-cache-one-sigqueue-struct.patch +++ b/kernel/patches-4.19.x-rt/0264-signals-allow-rt-tasks-to-cache-one-sigqueue-struct.patch @@ -1,25 +1,23 @@ -From 818da71ff388a006767feb2a8332b9fc3f80766e Mon Sep 17 00:00:00 2001 From: Thomas Gleixner Date: Fri, 3 Jul 2009 08:44:56 -0500 -Subject: [PATCH 129/450] signals: Allow rt tasks to cache one sigqueue struct +Subject: signals: Allow rt tasks to cache one sigqueue struct To avoid allocation allow rt tasks to cache one sigqueue struct in task struct. Signed-off-by: Thomas Gleixner + --- - include/linux/sched.h | 2 ++ - include/linux/signal.h | 1 + - kernel/exit.c | 2 +- - kernel/fork.c | 1 + - kernel/signal.c | 69 +++++++++++++++++++++++++++++++++++++++--- + include/linux/sched.h | 2 + + include/linux/signal.h | 1 + kernel/exit.c | 2 - + kernel/fork.c | 1 + kernel/signal.c | 69 ++++++++++++++++++++++++++++++++++++++++++++++--- 5 files changed, 70 insertions(+), 5 deletions(-) -diff --git a/include/linux/sched.h b/include/linux/sched.h -index b0390902a36f..92f7f58d44f6 100644 --- a/include/linux/sched.h +++ b/include/linux/sched.h -@@ -828,6 +828,8 @@ struct task_struct { +@@ -895,6 +895,8 @@ struct task_struct { /* Signal handlers: */ struct signal_struct *signal; struct sighand_struct *sighand; @@ -28,11 +26,9 @@ index b0390902a36f..92f7f58d44f6 100644 sigset_t blocked; sigset_t real_blocked; /* Restored if set_restore_sigmask() was used: */ -diff --git a/include/linux/signal.h b/include/linux/signal.h -index 843bd62b1ead..5d6a2206157a 100644 --- a/include/linux/signal.h +++ b/include/linux/signal.h -@@ -243,6 +243,7 @@ static inline void init_sigpending(struct sigpending *sig) +@@ -245,6 +245,7 @@ static inline void init_sigpending(struc } extern void flush_sigqueue(struct sigpending *queue); @@ -40,11 +36,9 @@ index 843bd62b1ead..5d6a2206157a 100644 /* Test if 'sig' is valid signal. Use this instead of testing _NSIG directly */ static inline int valid_signal(unsigned long sig) -diff --git a/kernel/exit.c b/kernel/exit.c -index e3a08761eb40..26f3b352b37a 100644 --- a/kernel/exit.c +++ b/kernel/exit.c -@@ -159,7 +159,7 @@ static void __exit_signal(struct task_struct *tsk) +@@ -160,7 +160,7 @@ static void __exit_signal(struct task_st * Do this under ->siglock, we can race with another thread * doing sigqueue_free() if we have SIGQUEUE_PREALLOC signals. */ @@ -53,11 +47,9 @@ index e3a08761eb40..26f3b352b37a 100644 tsk->sighand = NULL; spin_unlock(&sighand->siglock); -diff --git a/kernel/fork.c b/kernel/fork.c -index d45043432b17..c66167f0bba6 100644 --- a/kernel/fork.c +++ b/kernel/fork.c -@@ -1649,6 +1649,7 @@ static __latent_entropy struct task_struct *copy_process( +@@ -1802,6 +1802,7 @@ static __latent_entropy struct task_stru spin_lock_init(&p->alloc_lock); init_sigpending(&p->pending); @@ -65,8 +57,6 @@ index d45043432b17..c66167f0bba6 100644 p->utime = p->stime = p->gtime = 0; #ifdef CONFIG_ARCH_HAS_SCALED_CPUTIME -diff --git a/kernel/signal.c b/kernel/signal.c -index 8ffd4fb0a0f2..ca7de0d8a4bd 100644 --- a/kernel/signal.c +++ b/kernel/signal.c @@ -19,6 +19,7 @@ @@ -77,8 +67,8 @@ index 8ffd4fb0a0f2..ca7de0d8a4bd 100644 #include #include #include -@@ -360,13 +361,30 @@ static bool task_participate_group_stop(struct task_struct *task) - return false; +@@ -388,13 +389,30 @@ void task_join_group_stop(struct task_st + } } +static inline struct sigqueue *get_task_cache(struct task_struct *t) @@ -109,7 +99,7 @@ index 8ffd4fb0a0f2..ca7de0d8a4bd 100644 { struct sigqueue *q = NULL; struct user_struct *user; -@@ -383,7 +401,10 @@ __sigqueue_alloc(int sig, struct task_struct *t, gfp_t flags, int override_rlimi +@@ -411,7 +429,10 @@ static struct sigqueue * if (override_rlimit || atomic_read(&user->sigpending) <= task_rlimit(t, RLIMIT_SIGPENDING)) { @@ -121,7 +111,7 @@ index 8ffd4fb0a0f2..ca7de0d8a4bd 100644 } else { print_dropped_signal(sig); } -@@ -400,6 +421,13 @@ __sigqueue_alloc(int sig, struct task_struct *t, gfp_t flags, int override_rlimi +@@ -428,6 +449,13 @@ static struct sigqueue * return q; } @@ -135,7 +125,7 @@ index 8ffd4fb0a0f2..ca7de0d8a4bd 100644 static void __sigqueue_free(struct sigqueue *q) { if (q->flags & SIGQUEUE_PREALLOC) -@@ -409,6 +437,21 @@ static void __sigqueue_free(struct sigqueue *q) +@@ -437,6 +465,21 @@ static void __sigqueue_free(struct sigqu kmem_cache_free(sigqueue_cachep, q); } @@ -157,11 +147,10 @@ index 8ffd4fb0a0f2..ca7de0d8a4bd 100644 void flush_sigqueue(struct sigpending *queue) { struct sigqueue *q; -@@ -421,6 +464,21 @@ void flush_sigqueue(struct sigpending *queue) - } +@@ -450,6 +493,21 @@ void flush_sigqueue(struct sigpending *q } -+/* + /* + * Called from __exit_signal. Flush tsk->pending and + * tsk->sigqueue_cache + */ @@ -176,10 +165,11 @@ index 8ffd4fb0a0f2..ca7de0d8a4bd 100644 + kmem_cache_free(sigqueue_cachep, q); +} + - /* ++/* * Flush all pending signals for this kthread. */ -@@ -542,7 +600,7 @@ static void collect_signal(int sig, struct sigpending *list, siginfo_t *info, + void flush_signals(struct task_struct *t) +@@ -572,7 +630,7 @@ static void collect_signal(int sig, stru (info->si_code == SI_TIMER) && (info->si_sys_private); @@ -188,7 +178,7 @@ index 8ffd4fb0a0f2..ca7de0d8a4bd 100644 } else { /* * Ok, it wasn't in the queue. This must be -@@ -578,6 +636,8 @@ int dequeue_signal(struct task_struct *tsk, sigset_t *mask, siginfo_t *info) +@@ -609,6 +667,8 @@ int dequeue_signal(struct task_struct *t bool resched_timer = false; int signr; @@ -197,7 +187,7 @@ index 8ffd4fb0a0f2..ca7de0d8a4bd 100644 /* We only dequeue private signals from ourselves, we don't let * signalfd steal them */ -@@ -1514,7 +1574,8 @@ EXPORT_SYMBOL(kill_pid); +@@ -1747,7 +1807,8 @@ EXPORT_SYMBOL(kill_pid); */ struct sigqueue *sigqueue_alloc(void) { @@ -207,6 +197,3 @@ index 8ffd4fb0a0f2..ca7de0d8a4bd 100644 if (q) q->flags |= SIGQUEUE_PREALLOC; --- -2.19.2 - diff --git a/kernel/patches-4.19.x-rt/0265-localversion.patch b/kernel/patches-4.19.x-rt/0265-localversion.patch new file mode 100644 index 000000000..0cccc7790 --- /dev/null +++ b/kernel/patches-4.19.x-rt/0265-localversion.patch @@ -0,0 +1,13 @@ +Subject: Add localversion for -RT release +From: Thomas Gleixner +Date: Fri, 08 Jul 2011 20:25:16 +0200 + +Signed-off-by: Thomas Gleixner +--- + localversion-rt | 1 + + 1 file changed, 1 insertion(+) + +--- /dev/null ++++ b/localversion-rt +@@ -0,0 +1 @@ ++-rt16