From 2646f347455c030fc04874bc69652c0a08f34e14 Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Thu, 13 Oct 2022 18:28:11 +0200 Subject: [PATCH] 6.0-stable patches added patches: random-avoid-reading-two-cache-lines-on-irq-randomness.patch random-use-expired-timer-rather-than-wq-for-mixing-fast-pool.patch --- ...ng-two-cache-lines-on-irq-randomness.patch | 38 +++++ ...-rather-than-wq-for-mixing-fast-pool.patch | 130 ++++++++++++++++++ queue-6.0/series | 2 + 3 files changed, 170 insertions(+) create mode 100644 queue-6.0/random-avoid-reading-two-cache-lines-on-irq-randomness.patch create mode 100644 queue-6.0/random-use-expired-timer-rather-than-wq-for-mixing-fast-pool.patch diff --git a/queue-6.0/random-avoid-reading-two-cache-lines-on-irq-randomness.patch b/queue-6.0/random-avoid-reading-two-cache-lines-on-irq-randomness.patch new file mode 100644 index 00000000000..203a00d550c --- /dev/null +++ b/queue-6.0/random-avoid-reading-two-cache-lines-on-irq-randomness.patch @@ -0,0 +1,38 @@ +From 9ee0507e896b45af6d65408c77815800bce30008 Mon Sep 17 00:00:00 2001 +From: "Jason A. Donenfeld" +Date: Thu, 22 Sep 2022 18:46:04 +0200 +Subject: random: avoid reading two cache lines on irq randomness + +From: Jason A. Donenfeld + +commit 9ee0507e896b45af6d65408c77815800bce30008 upstream. + +In order to avoid reading and dirtying two cache lines on every IRQ, +move the work_struct to the bottom of the fast_pool struct. add_ +interrupt_randomness() always touches .pool and .count, which are +currently split, because .mix pushes everything down. Instead, move .mix +to the bottom, so that .pool and .count are always in the first cache +line, since .mix is only accessed when the pool is full. + +Fixes: 58340f8e952b ("random: defer fast pool mixing to worker") +Reviewed-by: Sebastian Andrzej Siewior +Signed-off-by: Jason A. Donenfeld +Signed-off-by: Greg Kroah-Hartman +--- + drivers/char/random.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/drivers/char/random.c ++++ b/drivers/char/random.c +@@ -920,10 +920,10 @@ EXPORT_SYMBOL_GPL(unregister_random_vmfo + #endif + + struct fast_pool { +- struct work_struct mix; + unsigned long pool[4]; + unsigned long last; + unsigned int count; ++ struct work_struct mix; + }; + + static DEFINE_PER_CPU(struct fast_pool, irq_randomness) = { diff --git a/queue-6.0/random-use-expired-timer-rather-than-wq-for-mixing-fast-pool.patch b/queue-6.0/random-use-expired-timer-rather-than-wq-for-mixing-fast-pool.patch new file mode 100644 index 00000000000..1dbcf358622 --- /dev/null +++ b/queue-6.0/random-use-expired-timer-rather-than-wq-for-mixing-fast-pool.patch @@ -0,0 +1,130 @@ +From 748bc4dd9e663f23448d8ad7e58c011a67ea1eca Mon Sep 17 00:00:00 2001 +From: "Jason A. Donenfeld" +Date: Thu, 22 Sep 2022 18:46:04 +0200 +Subject: random: use expired timer rather than wq for mixing fast pool +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Jason A. Donenfeld + +commit 748bc4dd9e663f23448d8ad7e58c011a67ea1eca upstream. + +Previously, the fast pool was dumped into the main pool periodically in +the fast pool's hard IRQ handler. This worked fine and there weren't +problems with it, until RT came around. Since RT converts spinlocks into +sleeping locks, problems cropped up. Rather than switching to raw +spinlocks, the RT developers preferred we make the transformation from +originally doing: + + do_some_stuff() + spin_lock() + do_some_other_stuff() + spin_unlock() + +to doing: + + do_some_stuff() + queue_work_on(some_other_stuff_worker) + +This is an ordinary pattern done all over the kernel. However, Sherry +noticed a 10% performance regression in qperf TCP over a 40gbps +InfiniBand card. Quoting her message: + +> MT27500 Family [ConnectX-3] cards: +> Infiniband device 'mlx4_0' port 1 status: +> default gid: fe80:0000:0000:0000:0010:e000:0178:9eb1 +> base lid: 0x6 +> sm lid: 0x1 +> state: 4: ACTIVE +> phys state: 5: LinkUp +> rate: 40 Gb/sec (4X QDR) +> link_layer: InfiniBand +> +> Cards are configured with IP addresses on private subnet for IPoIB +> performance testing. +> Regression identified in this bug is in TCP latency in this stack as reported +> by qperf tcp_lat metric: +> +> We have one system listen as a qperf server: +> [root@yourQperfServer ~]# qperf +> +> Have the other system connect to qperf server as a client (in this +> case, it’s X7 server with Mellanox card): +> [root@yourQperfClient ~]# numactl -m0 -N0 qperf 20.20.20.101 -v -uu -ub --time 60 --wait_server 20 -oo msg_size:4K:1024K:*2 tcp_lat + +Rather than incur the scheduling latency from queue_work_on, we can +instead switch to running on the next timer tick, on the same core. This +also batches things a bit more -- once per jiffy -- which is okay now +that mix_interrupt_randomness() can credit multiple bits at once. + +Reported-by: Sherry Yang +Tested-by: Paul Webb +Cc: Sherry Yang +Cc: Phillip Goerl +Cc: Jack Vogel +Cc: Nicky Veitch +Cc: Colm Harrington +Cc: Ramanan Govindarajan +Cc: Sebastian Andrzej Siewior +Cc: Dominik Brodowski +Cc: Tejun Heo +Cc: Sultan Alsawaf +Cc: stable@vger.kernel.org +Fixes: 58340f8e952b ("random: defer fast pool mixing to worker") +Signed-off-by: Jason A. Donenfeld +Signed-off-by: Greg Kroah-Hartman +--- + drivers/char/random.c | 18 +++++++++++------- + 1 file changed, 11 insertions(+), 7 deletions(-) + +--- a/drivers/char/random.c ++++ b/drivers/char/random.c +@@ -923,17 +923,20 @@ struct fast_pool { + unsigned long pool[4]; + unsigned long last; + unsigned int count; +- struct work_struct mix; ++ struct timer_list mix; + }; + ++static void mix_interrupt_randomness(struct timer_list *work); ++ + static DEFINE_PER_CPU(struct fast_pool, irq_randomness) = { + #ifdef CONFIG_64BIT + #define FASTMIX_PERM SIPHASH_PERMUTATION +- .pool = { SIPHASH_CONST_0, SIPHASH_CONST_1, SIPHASH_CONST_2, SIPHASH_CONST_3 } ++ .pool = { SIPHASH_CONST_0, SIPHASH_CONST_1, SIPHASH_CONST_2, SIPHASH_CONST_3 }, + #else + #define FASTMIX_PERM HSIPHASH_PERMUTATION +- .pool = { HSIPHASH_CONST_0, HSIPHASH_CONST_1, HSIPHASH_CONST_2, HSIPHASH_CONST_3 } ++ .pool = { HSIPHASH_CONST_0, HSIPHASH_CONST_1, HSIPHASH_CONST_2, HSIPHASH_CONST_3 }, + #endif ++ .mix = __TIMER_INITIALIZER(mix_interrupt_randomness, 0) + }; + + /* +@@ -975,7 +978,7 @@ int __cold random_online_cpu(unsigned in + } + #endif + +-static void mix_interrupt_randomness(struct work_struct *work) ++static void mix_interrupt_randomness(struct timer_list *work) + { + struct fast_pool *fast_pool = container_of(work, struct fast_pool, mix); + /* +@@ -1029,10 +1032,11 @@ void add_interrupt_randomness(int irq) + if (new_count < 1024 && !time_is_before_jiffies(fast_pool->last + HZ)) + return; + +- if (unlikely(!fast_pool->mix.func)) +- INIT_WORK(&fast_pool->mix, mix_interrupt_randomness); + fast_pool->count |= MIX_INFLIGHT; +- queue_work_on(raw_smp_processor_id(), system_highpri_wq, &fast_pool->mix); ++ if (!timer_pending(&fast_pool->mix)) { ++ fast_pool->mix.expires = jiffies; ++ add_timer_on(&fast_pool->mix, raw_smp_processor_id()); ++ } + } + EXPORT_SYMBOL_GPL(add_interrupt_randomness); + diff --git a/queue-6.0/series b/queue-6.0/series index da9275614c9..e9bba63d2f3 100644 --- a/queue-6.0/series +++ b/queue-6.0/series @@ -16,3 +16,5 @@ revert-usb-fixup-for-merge-issue-with-usb-dwc3-don-t-switch-otg-peripheral-if-ex revert-usb-dwc3-don-t-switch-otg-peripheral-if-extcon-is-present.patch revert-powerpc-rtas-implement-reentrant-rtas-call.patch revert-crypto-qat-reduce-size-of-mapped-region.patch +random-avoid-reading-two-cache-lines-on-irq-randomness.patch +random-use-expired-timer-rather-than-wq-for-mixing-fast-pool.patch -- 2.47.3