Commit 4693080316e671580459875723795fdb805a6cf4

Authored by Joel Fernandes
Committed by Greg Kroah-Hartman
1 parent 5463a3dccf

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>

Showing 3 changed files with 27 additions and 12 deletions Side-by-side Diff

... ... @@ -434,7 +434,7 @@
434 434 for (i = 0; i < cxt->max_dump_cnt; i++) {
435 435 cxt->przs[i] = persistent_ram_new(*paddr, cxt->record_size, 0,
436 436 &cxt->ecc_info,
437   - cxt->memtype);
  437 + cxt->memtype, 0);
438 438 if (IS_ERR(cxt->przs[i])) {
439 439 err = PTR_ERR(cxt->przs[i]);
440 440 dev_err(dev, "failed to request mem region (0x%zx@0x%llx): %d\n",
... ... @@ -471,7 +471,8 @@
471 471 return -ENOMEM;
472 472 }
473 473  
474   - *prz = persistent_ram_new(*paddr, sz, sig, &cxt->ecc_info, cxt->memtype);
  474 + *prz = persistent_ram_new(*paddr, sz, sig, &cxt->ecc_info,
  475 + cxt->memtype, 0);
475 476 if (IS_ERR(*prz)) {
476 477 int err = PTR_ERR(*prz);
477 478  
fs/pstore/ram_core.c
... ... @@ -53,9 +53,10 @@
53 53 {
54 54 int old;
55 55 int new;
56   - unsigned long flags;
  56 + unsigned long flags = 0;
57 57  
58   - raw_spin_lock_irqsave(&prz->buffer_lock, flags);
  58 + if (!(prz->flags & PRZ_FLAG_NO_LOCK))
  59 + raw_spin_lock_irqsave(&prz->buffer_lock, flags);
59 60  
60 61 old = atomic_read(&prz->buffer->start);
61 62 new = old + a;
... ... @@ -63,7 +64,8 @@
63 64 new -= prz->buffer_size;
64 65 atomic_set(&prz->buffer->start, new);
65 66  
66   - raw_spin_unlock_irqrestore(&prz->buffer_lock, flags);
  67 + if (!(prz->flags & PRZ_FLAG_NO_LOCK))
  68 + raw_spin_unlock_irqrestore(&prz->buffer_lock, flags);
67 69  
68 70 return old;
69 71 }
70 72  
... ... @@ -73,9 +75,10 @@
73 75 {
74 76 size_t old;
75 77 size_t new;
76   - unsigned long flags;
  78 + unsigned long flags = 0;
77 79  
78   - raw_spin_lock_irqsave(&prz->buffer_lock, flags);
  80 + if (!(prz->flags & PRZ_FLAG_NO_LOCK))
  81 + raw_spin_lock_irqsave(&prz->buffer_lock, flags);
79 82  
80 83 old = atomic_read(&prz->buffer->size);
81 84 if (old == prz->buffer_size)
... ... @@ -87,7 +90,8 @@
87 90 atomic_set(&prz->buffer->size, new);
88 91  
89 92 exit:
90   - raw_spin_unlock_irqrestore(&prz->buffer_lock, flags);
  93 + if (!(prz->flags & PRZ_FLAG_NO_LOCK))
  94 + raw_spin_unlock_irqrestore(&prz->buffer_lock, flags);
91 95 }
92 96  
93 97 static void notrace persistent_ram_encode_rs8(struct persistent_ram_zone *prz,
... ... @@ -463,7 +467,8 @@
463 467 }
464 468  
465 469 static int persistent_ram_post_init(struct persistent_ram_zone *prz, u32 sig,
466   - struct persistent_ram_ecc_info *ecc_info)
  470 + struct persistent_ram_ecc_info *ecc_info,
  471 + unsigned long flags)
467 472 {
468 473 int ret;
469 474  
... ... @@ -492,6 +497,7 @@
492 497 prz->buffer->sig = sig;
493 498 persistent_ram_zap(prz);
494 499 prz->buffer_lock = __RAW_SPIN_LOCK_UNLOCKED(buffer_lock);
  500 + prz->flags = flags;
495 501  
496 502 return 0;
497 503 }
... ... @@ -516,7 +522,7 @@
516 522  
517 523 struct persistent_ram_zone *persistent_ram_new(phys_addr_t start, size_t size,
518 524 u32 sig, struct persistent_ram_ecc_info *ecc_info,
519   - unsigned int memtype)
  525 + unsigned int memtype, u32 flags)
520 526 {
521 527 struct persistent_ram_zone *prz;
522 528 int ret = -ENOMEM;
... ... @@ -531,7 +537,7 @@
531 537 if (ret)
532 538 goto err;
533 539  
534   - ret = persistent_ram_post_init(prz, sig, ecc_info);
  540 + ret = persistent_ram_post_init(prz, sig, ecc_info, flags);
535 541 if (ret)
536 542 goto err;
537 543  
include/linux/pstore_ram.h
... ... @@ -24,6 +24,13 @@
24 24 #include <linux/list.h>
25 25 #include <linux/types.h>
26 26  
  27 +/*
  28 + * Choose whether access to the RAM zone requires locking or not. If a zone
  29 + * can be written to from different CPUs like with ftrace for example, then
  30 + * PRZ_FLAG_NO_LOCK is used. For all other cases, locking is required.
  31 + */
  32 +#define PRZ_FLAG_NO_LOCK BIT(0)
  33 +
27 34 struct persistent_ram_buffer;
28 35 struct rs_control;
29 36  
... ... @@ -40,6 +47,7 @@
40 47 void *vaddr;
41 48 struct persistent_ram_buffer *buffer;
42 49 size_t buffer_size;
  50 + u32 flags;
43 51 raw_spinlock_t buffer_lock;
44 52  
45 53 /* ECC correction */
... ... @@ -56,7 +64,7 @@
56 64  
57 65 struct persistent_ram_zone *persistent_ram_new(phys_addr_t start, size_t size,
58 66 u32 sig, struct persistent_ram_ecc_info *ecc_info,
59   - unsigned int memtype);
  67 + unsigned int memtype, u32 flags);
60 68 void persistent_ram_free(struct persistent_ram_zone *prz);
61 69 void persistent_ram_zap(struct persistent_ram_zone *prz);
62 70