Skip to content

Commit fd56200

Browse files
Julia CartwrightIngo Molnar
authored andcommitted
squashfs: Make use of local lock in multi_cpu decompressor
The squashfs multi CPU decompressor makes use of get_cpu_ptr() to acquire a pointer to per-CPU data. get_cpu_ptr() implicitly disables preemption which serializes the access to the per-CPU data. But decompression can take quite some time depending on the size. The observed preempt disabled times in real world scenarios went up to 8ms, causing massive wakeup latencies. This happens on all CPUs as the decompression is fully parallelized. Replace the implicit preemption control with an explicit local lock. This allows RT kernels to substitute it with a real per CPU lock, which serializes the access but keeps the code section preemptible. On non RT kernels this maps to preempt_disable() as before, i.e. no functional change. [ bigeasy: Use local_lock(), patch description] Reported-by: Alexander Stein <[email protected]> Signed-off-by: Julia Cartwright <[email protected]> Signed-off-by: Sebastian Andrzej Siewior <[email protected]> Signed-off-by: Ingo Molnar <[email protected]> Tested-by: Alexander Stein <[email protected]> Acked-by: Peter Zijlstra <[email protected]> Link: https://lore.kernel.org/r/[email protected]
1 parent b01b214 commit fd56200

File tree

1 file changed

+14
-7
lines changed

1 file changed

+14
-7
lines changed

fs/squashfs/decompressor_multi_percpu.c

Lines changed: 14 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
#include <linux/slab.h>
99
#include <linux/percpu.h>
1010
#include <linux/buffer_head.h>
11+
#include <linux/local_lock.h>
1112

1213
#include "squashfs_fs.h"
1314
#include "squashfs_fs_sb.h"
@@ -20,7 +21,8 @@
2021
*/
2122

2223
struct squashfs_stream {
23-
void *stream;
24+
void *stream;
25+
local_lock_t lock;
2426
};
2527

2628
void *squashfs_decompressor_create(struct squashfs_sb_info *msblk,
@@ -41,6 +43,7 @@ void *squashfs_decompressor_create(struct squashfs_sb_info *msblk,
4143
err = PTR_ERR(stream->stream);
4244
goto out;
4345
}
46+
local_lock_init(&stream->lock);
4447
}
4548

4649
kfree(comp_opts);
@@ -75,12 +78,16 @@ void squashfs_decompressor_destroy(struct squashfs_sb_info *msblk)
7578
int squashfs_decompress(struct squashfs_sb_info *msblk, struct buffer_head **bh,
7679
int b, int offset, int length, struct squashfs_page_actor *output)
7780
{
78-
struct squashfs_stream __percpu *percpu =
79-
(struct squashfs_stream __percpu *) msblk->stream;
80-
struct squashfs_stream *stream = get_cpu_ptr(percpu);
81-
int res = msblk->decompressor->decompress(msblk, stream->stream, bh, b,
82-
offset, length, output);
83-
put_cpu_ptr(stream);
81+
struct squashfs_stream *stream;
82+
int res;
83+
84+
local_lock(&msblk->stream->lock);
85+
stream = this_cpu_ptr(msblk->stream);
86+
87+
res = msblk->decompressor->decompress(msblk, stream->stream, bh, b,
88+
offset, length, output);
89+
90+
local_unlock(&msblk->stream->lock);
8491

8592
if (res < 0)
8693
ERROR("%s decompression failed, data probably corrupt\n",

0 commit comments

Comments
 (0)