4.4.126-rt141-rc1
Subsystems (10)
cover 4.4.126-rt141-rc1
Dear RT Folks,
This is the RT stable review cycle of patch 4.4.126-rt141-rc1.
The series contains a few patches which never made it to the v4.4-rt tree. I identified the patches using Steven's workflow. Next thing I try to do is to use Julia's script to idendtify missing patches. In theory nothing should be.
Please scream at me if I messed something up. Please test the patches too.
The pre-releases will not be pushed to the git repository, only the final release is.
If all goes well, this patch will be converted to the next main release on 16.04.2017.
Enjoy,
-- Daniel
ps: Bare with me, I didn't have time to get all the magic tooling working for releasing a -rc series as Steven has done in the past. That's why this mail looks slightly different then what you are used.
Changes from 4.4.126-rt141:
Daniel Wagner (1):
Linux 4.4.126-rt141-rc1
Sebastian Andrzej Siewior (4):
locking: add types.h
mm/slub: close possible memory-leak in kmem_cache_alloc_bulk() arm*: disable NEON in kernel mode
crypto: limit more FPU-enabled sections
Steven Rostedt (VMware) (1):
Revert "memcontrol: Prevent scheduling while atomic in cgroup code"
Thomas Gleixner (1):
timer: Invoke timer_start_debug() where it makes sense
arch/arm/Kconfig | 2 +- arch/arm64/crypto/Kconfig | 14 +++++++------- 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 | 8 +++++--- 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 ++++++++++++ include/linux/spinlock_types_raw.h | 2 ++ kernel/time/timer.c | 4 ++-- localversion-rt | 2 +- mm/memcontrol.c | 7 ++----- mm/slub.c | 1 + 17 files changed, 174 insertions(+), 34 deletions(-)
Signature · 1 line
2.14.3
PATCH 1/7 locking: add types.h
From: Sebastian Andrzej Siewior <[email protected]>
During the stable update the arm architecture did not compile anymore due to missing definition of u16/32.
--- include/linux/spinlock_types_raw.h | 2 ++ 1 file changed, 2 insertions(+)
include/linux/spinlock_types_raw.h +2 -0
@@ -1,6 +1,8 @@#ifndef __LINUX_SPINLOCK_TYPES_RAW_H#define __LINUX_SPINLOCK_TYPES_RAW_H +#include <linux/types.h> +#if defined(CONFIG_SMP )# include <asm/spinlock_types.h> #else
Signature · 1 line
2.14.3
PATCH 2/7 timer: Invoke timer_start_debug() where it makes sense
In reply to Daniel WagnerFrom: Thomas Gleixner <[email protected]>
The timer start debug function is called before the proper timer base is set. As a consequence the trace data contains the stale CPU and flags values.
Call the debug function after setting the new base and flags.
--- kernel/time/timer.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
kernel/time/timer.c +2 -2
@@ -838,8 +838,6 @@ __mod_timer(struct timer_list *timer, unsigned long expires,if (!ret && pending_only) goto out_unlock; -debug_activate (timer, expires); - new_base =get_target_base (base, pinned);if (base != new_base) {
@@ -854,6 +852,8 @@ __mod_timer(struct timer_list *timer, unsigned long expires, base =switch_timer_base (timer, base, new_base); } +debug_activate (timer, expires); + timer->expires = expires;internal_add_timer (base, timer);
Signature · 1 line
2.14.3
PATCH 3/7 mm/slub: close possible memory-leak in kmem_cache_alloc_bulk()
In reply to Daniel WagnerFrom: Sebastian Andrzej Siewior <[email protected]>
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.
--- mm/slub.c | 1 + 1 file changed, 1 insertion(+)
mm/slub.c +1 -0
@@ -3026,6 +3026,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 ;
Signature · 1 line
2.14.3
PATCH 4/7 arm*: disable NEON in kernel mode
In reply to Daniel WagnerFrom: Sebastian Andrzej Siewior <[email protected]>
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 is enabled on first invocation and may allocate/free/map memory before the NEON mode is disabled again.
This needs to be changed until it can be enabled.
On ARM NEON in kernel mode can be simply disabled. on ARM64 it needs to stay on due to possible EFI callbacks so here I disable each algorithm.
--- arch/arm/Kconfig | 2 +- arch/arm64/crypto/Kconfig | 14 +++++++------- 2 files changed, 8 insertions(+), 8 deletions(-)
arch/arm/Kconfig +1 -1
@@ -2119,7 +2119,7 @@ config NEON config KERNEL_MODE_NEON bool "Support for NEON in kernel mode" - depends on NEON && AEABI + depends on NEON && AEABI && !PREEMPT_RT_BASE help Say Y to include support for NEON in kernel mode.
arch/arm64/crypto/Kconfig +7 -7
@@ -10,41 +10,41 @@ if ARM64_CRYPTO config CRYPTO_SHA1_ARM64_CE tristate "SHA-1 digest algorithm (ARMv8 Crypto Extensions)" - depends on ARM64 && KERNEL_MODE_NEON + depends on ARM64 && KERNEL_MODE_NEON && !PREEMPT_RT_BASE select CRYPTO_HASH config CRYPTO_SHA2_ARM64_CE tristate "SHA-224/SHA-256 digest algorithm (ARMv8 Crypto Extensions)" - depends on ARM64 && KERNEL_MODE_NEON + depends on ARM64 && KERNEL_MODE_NEON && !PREEMPT_RT_BASE select CRYPTO_HASH config CRYPTO_GHASH_ARM64_CE tristate "GHASH (for GCM chaining mode) using ARMv8 Crypto Extensions" - depends on ARM64 && KERNEL_MODE_NEON + depends on ARM64 && KERNEL_MODE_NEON && !PREEMPT_RT_BASE select CRYPTO_HASH config CRYPTO_AES_ARM64_CE tristate "AES core cipher using ARMv8 Crypto Extensions" - depends on ARM64 && KERNEL_MODE_NEON + depends on ARM64 && KERNEL_MODE_NEON && !PREEMPT_RT_BASE select CRYPTO_ALGAPI config CRYPTO_AES_ARM64_CE_CCM tristate "AES in CCM mode using ARMv8 Crypto Extensions" - depends on ARM64 && KERNEL_MODE_NEON + depends on ARM64 && KERNEL_MODE_NEON && !PREEMPT_RT_BASE select CRYPTO_ALGAPI select CRYPTO_AES_ARM64_CE select CRYPTO_AEAD config CRYPTO_AES_ARM64_CE_BLK tristate "AES in ECB/CBC/CTR/XTS modes using ARMv8 Crypto Extensions" - depends on ARM64 && KERNEL_MODE_NEON + depends on ARM64 && KERNEL_MODE_NEON && !PREEMPT_RT_BASE select CRYPTO_BLKCIPHER select CRYPTO_AES_ARM64_CE select CRYPTO_ABLK_HELPER config CRYPTO_AES_ARM64_NEON_BLK tristate "AES in ECB/CBC/CTR/XTS modes using NEON instructions" - depends on ARM64 && KERNEL_MODE_NEON + depends on ARM64 && KERNEL_MODE_NEON && !PREEMPT_RT_BASE select CRYPTO_BLKCIPHER select CRYPTO_AES select CRYPTO_ABLK_HELPER
Signature · 1 line
2.14.3
PATCH 5/7 crypto: limit more FPU-enabled sections
In reply to Daniel WagnerFrom: Sebastian Andrzej Siewior <[email protected]>
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.
--- 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 | 8 +++++--- 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(+), 18 deletions(-)
arch/x86/crypto/camellia_aesni_avx2_glue.c +20 -0
@@ -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);
arch/x86/crypto/camellia_aesni_avx_glue.c +19 -0
@@ -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);
arch/x86/crypto/cast6_avx_glue.c +19 -5
@@ -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 ; }
arch/x86/crypto/chacha20_glue.c +5 -3
@@ -80,22 +80,24 @@ static int chacha20_simd(struct blkcipher_desc *desc, struct scatterlist *dst,crypto_chacha20_init (state,crypto_blkcipher_ctx (desc->tfm), 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 =blkcipher_walk_done (desc, &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 =blkcipher_walk_done (desc, &walk,0 ); } -kernel_fpu_end ();return err; }
arch/x86/crypto/serpent_avx2_glue.c +19 -0
@@ -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);
arch/x86/crypto/serpent_avx_glue.c +19 -4
@@ -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 ; }
arch/x86/crypto/serpent_sse2_glue.c +19 -4
@@ -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 ; }
arch/x86/crypto/twofish_avx_glue.c +25 -2
@@ -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 ;
arch/x86/include/asm/fpu/api.h +1 -0
@@ -24,6 +24,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 );/*
arch/x86/kernel/fpu/core.c +12 -0
@@ -149,6 +149,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); +/* * CR0::TS save/restore functions: */
Signature · 1 line
2.14.3
PATCH 6/7 Revert "memcontrol: Prevent scheduling while atomic in cgroup code"
In reply to Daniel WagnerFrom: "Steven Rostedt (VMware)" <[email protected]>
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() <== boomBut 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.
[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/[email protected]
]
--- mm/memcontrol.c | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-)
mm/memcontrol.c +2 -5
@@ -1925,17 +1925,14 @@ static void drain_local_stock(struct work_struct *dummy)*/ static void refill_stock (struct mem_cgroup *memcg,unsigned int nr_pages) { -struct memcg_stock_pcp *stock; -int cpu =get_cpu_light (); - - stock = &per_cpu (memcg_stock, cpu); +struct memcg_stock_pcp *stock = &get_cpu_var (memcg_stock);if (stock->cached != memcg) {/* reset if necessary */ drain_stock (stock); stock->cached = memcg; } stock->nr_pages += nr_pages; -put_cpu_light (); +put_cpu_var (memcg_stock); }/*
Signature · 1 line
2.14.3
PATCH 7/7 Linux 4.4.126-rt141-rc1
In reply to Daniel Wagner--- localversion-rt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
localversion-rt +1 -1
@@ -1 +1 @@ --rt141 +-rt141-rc1
Signature · 1 line
2.14.3