Skip to content

Commit aca5b1e

Browse files
Joel Fernandesgregkh
authored andcommitted
pstore: Allow prz to control need for locking
commit 663deb47880f2283809669563c5a52ac7c6aef1a upstream. In preparation of not locking at all for certain buffers depending on if there's contention, make locking optional depending on the initialization of the prz. Signed-off-by: Joel Fernandes <joelaf@google.com> [kees: moved locking flag into prz instead of via caller arguments] Signed-off-by: Kees Cook <keescook@chromium.org> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
1 parent ff013a6 commit aca5b1e

3 files changed

Lines changed: 27 additions & 12 deletions

File tree

fs/pstore/ram.c

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -413,7 +413,7 @@ static int ramoops_init_przs(struct device *dev, struct ramoops_context *cxt,
413413
for (i = 0; i < cxt->max_dump_cnt; i++) {
414414
cxt->przs[i] = persistent_ram_new(*paddr, cxt->record_size, 0,
415415
&cxt->ecc_info,
416-
cxt->memtype);
416+
cxt->memtype, 0);
417417
if (IS_ERR(cxt->przs[i])) {
418418
err = PTR_ERR(cxt->przs[i]);
419419
dev_err(dev, "failed to request mem region (0x%zx@0x%llx): %d\n",
@@ -450,7 +450,8 @@ static int ramoops_init_prz(struct device *dev, struct ramoops_context *cxt,
450450
return -ENOMEM;
451451
}
452452

453-
*prz = persistent_ram_new(*paddr, sz, sig, &cxt->ecc_info, cxt->memtype);
453+
*prz = persistent_ram_new(*paddr, sz, sig, &cxt->ecc_info,
454+
cxt->memtype, 0);
454455
if (IS_ERR(*prz)) {
455456
int err = PTR_ERR(*prz);
456457

fs/pstore/ram_core.c

Lines changed: 15 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -52,17 +52,19 @@ static size_t buffer_start_add(struct persistent_ram_zone *prz, size_t a)
5252
{
5353
int old;
5454
int new;
55-
unsigned long flags;
55+
unsigned long flags = 0;
5656

57-
raw_spin_lock_irqsave(&prz->buffer_lock, flags);
57+
if (!(prz->flags & PRZ_FLAG_NO_LOCK))
58+
raw_spin_lock_irqsave(&prz->buffer_lock, flags);
5859

5960
old = atomic_read(&prz->buffer->start);
6061
new = old + a;
6162
while (unlikely(new >= prz->buffer_size))
6263
new -= prz->buffer_size;
6364
atomic_set(&prz->buffer->start, new);
6465

65-
raw_spin_unlock_irqrestore(&prz->buffer_lock, flags);
66+
if (!(prz->flags & PRZ_FLAG_NO_LOCK))
67+
raw_spin_unlock_irqrestore(&prz->buffer_lock, flags);
6668

6769
return old;
6870
}
@@ -72,9 +74,10 @@ static void buffer_size_add(struct persistent_ram_zone *prz, size_t a)
7274
{
7375
size_t old;
7476
size_t new;
75-
unsigned long flags;
77+
unsigned long flags = 0;
7678

77-
raw_spin_lock_irqsave(&prz->buffer_lock, flags);
79+
if (!(prz->flags & PRZ_FLAG_NO_LOCK))
80+
raw_spin_lock_irqsave(&prz->buffer_lock, flags);
7881

7982
old = atomic_read(&prz->buffer->size);
8083
if (old == prz->buffer_size)
@@ -86,7 +89,8 @@ static void buffer_size_add(struct persistent_ram_zone *prz, size_t a)
8689
atomic_set(&prz->buffer->size, new);
8790

8891
exit:
89-
raw_spin_unlock_irqrestore(&prz->buffer_lock, flags);
92+
if (!(prz->flags & PRZ_FLAG_NO_LOCK))
93+
raw_spin_unlock_irqrestore(&prz->buffer_lock, flags);
9094
}
9195

9296
static void notrace persistent_ram_encode_rs8(struct persistent_ram_zone *prz,
@@ -420,7 +424,8 @@ static int persistent_ram_buffer_map(phys_addr_t start, phys_addr_t size,
420424
}
421425

422426
static int persistent_ram_post_init(struct persistent_ram_zone *prz, u32 sig,
423-
struct persistent_ram_ecc_info *ecc_info)
427+
struct persistent_ram_ecc_info *ecc_info,
428+
unsigned long flags)
424429
{
425430
int ret;
426431

@@ -449,6 +454,7 @@ static int persistent_ram_post_init(struct persistent_ram_zone *prz, u32 sig,
449454
prz->buffer->sig = sig;
450455
persistent_ram_zap(prz);
451456
prz->buffer_lock = __RAW_SPIN_LOCK_UNLOCKED(buffer_lock);
457+
prz->flags = flags;
452458

453459
return 0;
454460
}
@@ -473,7 +479,7 @@ void persistent_ram_free(struct persistent_ram_zone *prz)
473479

474480
struct persistent_ram_zone *persistent_ram_new(phys_addr_t start, size_t size,
475481
u32 sig, struct persistent_ram_ecc_info *ecc_info,
476-
unsigned int memtype)
482+
unsigned int memtype, u32 flags)
477483
{
478484
struct persistent_ram_zone *prz;
479485
int ret = -ENOMEM;
@@ -488,7 +494,7 @@ struct persistent_ram_zone *persistent_ram_new(phys_addr_t start, size_t size,
488494
if (ret)
489495
goto err;
490496

491-
ret = persistent_ram_post_init(prz, sig, ecc_info);
497+
ret = persistent_ram_post_init(prz, sig, ecc_info, flags);
492498
if (ret)
493499
goto err;
494500

include/linux/pstore_ram.h

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,13 @@
2323
#include <linux/types.h>
2424
#include <linux/init.h>
2525

26+
/*
27+
* Choose whether access to the RAM zone requires locking or not. If a zone
28+
* can be written to from different CPUs like with ftrace for example, then
29+
* PRZ_FLAG_NO_LOCK is used. For all other cases, locking is required.
30+
*/
31+
#define PRZ_FLAG_NO_LOCK BIT(0)
32+
2633
struct persistent_ram_buffer;
2734
struct rs_control;
2835

@@ -39,6 +46,7 @@ struct persistent_ram_zone {
3946
void *vaddr;
4047
struct persistent_ram_buffer *buffer;
4148
size_t buffer_size;
49+
u32 flags;
4250
raw_spinlock_t buffer_lock;
4351

4452
/* ECC correction */
@@ -55,7 +63,7 @@ struct persistent_ram_zone {
5563

5664
struct persistent_ram_zone *persistent_ram_new(phys_addr_t start, size_t size,
5765
u32 sig, struct persistent_ram_ecc_info *ecc_info,
58-
unsigned int memtype);
66+
unsigned int memtype, u32 flags);
5967
void persistent_ram_free(struct persistent_ram_zone *prz);
6068
void persistent_ram_zap(struct persistent_ram_zone *prz);
6169

0 commit comments

Comments
 (0)