lkml.org 
[lkml]   [2016]   [Oct]   [20]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
Patch in this message
/
From
Subject[PATCH v2 2/7] pstore: locking: dont lock unless caller asks to
Date
In preparation of not locking at all for certain buffers depending on if
there's contention, make locking optional depending if caller requested it.

Signed-off-by: Joel Fernandes <joelaf@google.com>
---
fs/pstore/ram.c | 10 +++++-----
fs/pstore/ram_core.c | 27 ++++++++++++++++-----------
include/linux/pstore_ram.h | 10 +++++++++-
3 files changed, 30 insertions(+), 17 deletions(-)

diff --git a/fs/pstore/ram.c b/fs/pstore/ram.c
index f1219af..cb07ef6 100644
--- a/fs/pstore/ram.c
+++ b/fs/pstore/ram.c
@@ -260,7 +260,7 @@ static size_t ramoops_write_kmsg_hdr(struct persistent_ram_zone *prz,
compressed ? 'C' : 'D');
WARN_ON_ONCE(!hdr);
len = hdr ? strlen(hdr) : 0;
- persistent_ram_write(prz, hdr, len);
+ persistent_ram_write(prz, hdr, len, PSTORE_RAM_LOCK);
kfree(hdr);

return len;
@@ -280,17 +280,17 @@ static int notrace ramoops_pstore_write_buf(enum pstore_type_id type,
if (type == PSTORE_TYPE_CONSOLE) {
if (!cxt->cprz)
return -ENOMEM;
- persistent_ram_write(cxt->cprz, buf, size);
+ persistent_ram_write(cxt->cprz, buf, size, PSTORE_RAM_LOCK);
return 0;
} else if (type == PSTORE_TYPE_FTRACE) {
if (!cxt->fprz)
return -ENOMEM;
- persistent_ram_write(cxt->fprz, buf, size);
+ persistent_ram_write(cxt->fprz, buf, size, PSTORE_RAM_LOCK);
return 0;
} else if (type == PSTORE_TYPE_PMSG) {
if (!cxt->mprz)
return -ENOMEM;
- persistent_ram_write(cxt->mprz, buf, size);
+ persistent_ram_write(cxt->mprz, buf, size, PSTORE_RAM_LOCK);
return 0;
}

@@ -324,7 +324,7 @@ static int notrace ramoops_pstore_write_buf(enum pstore_type_id type,
hlen = ramoops_write_kmsg_hdr(prz, compressed);
if (size + hlen > prz->buffer_size)
size = prz->buffer_size - hlen;
- persistent_ram_write(prz, buf, size);
+ persistent_ram_write(prz, buf, size, PSTORE_RAM_LOCK);

cxt->dump_write_cnt = (cxt->dump_write_cnt + 1) % cxt->max_dump_cnt;

diff --git a/fs/pstore/ram_core.c b/fs/pstore/ram_core.c
index cb92055..69c7b96 100644
--- a/fs/pstore/ram_core.c
+++ b/fs/pstore/ram_core.c
@@ -49,13 +49,15 @@ static inline size_t buffer_start(struct persistent_ram_zone *prz)
}

/* increase and wrap the start pointer, returning the old value */
-static size_t buffer_start_add(struct persistent_ram_zone *prz, size_t a)
+static size_t buffer_start_add(struct persistent_ram_zone *prz, size_t a,
+ int lock)
{
int old;
int new;
unsigned long flags;

- raw_spin_lock_irqsave(&prz->buffer_lock, flags);
+ if (lock == PSTORE_RAM_LOCK)
+ raw_spin_lock_irqsave(&prz->buffer_lock, flags);

old = atomic_read(&prz->buffer->start);
new = old + a;
@@ -63,19 +65,21 @@ static size_t buffer_start_add(struct persistent_ram_zone *prz, size_t a)
new -= prz->buffer_size;
atomic_set(&prz->buffer->start, new);

- raw_spin_unlock_irqrestore(&prz->buffer_lock, flags);
+ if (lock == PSTORE_RAM_LOCK)
+ raw_spin_unlock_irqrestore(&prz->buffer_lock, flags);

return old;
}

/* increase the size counter until it hits the max size */
-static void buffer_size_add(struct persistent_ram_zone *prz, size_t a)
+static void buffer_size_add(struct persistent_ram_zone *prz, size_t a, int lock)
{
size_t old;
size_t new;
unsigned long flags;

- raw_spin_lock_irqsave(&prz->buffer_lock, flags);
+ if (lock == PSTORE_RAM_LOCK)
+ raw_spin_lock_irqsave(&prz->buffer_lock, flags);

old = atomic_read(&prz->buffer->size);
if (old == prz->buffer_size)
@@ -87,7 +91,8 @@ static void buffer_size_add(struct persistent_ram_zone *prz, size_t a)
atomic_set(&prz->buffer->size, new);

exit:
- raw_spin_unlock_irqrestore(&prz->buffer_lock, flags);
+ if (lock == PSTORE_RAM_LOCK)
+ raw_spin_unlock_irqrestore(&prz->buffer_lock, flags);
}

static void notrace persistent_ram_encode_rs8(struct persistent_ram_zone *prz,
@@ -300,7 +305,7 @@ void persistent_ram_save_old(struct persistent_ram_zone *prz)
}

int notrace persistent_ram_write(struct persistent_ram_zone *prz,
- const void *s, unsigned int count)
+ const void *s, unsigned int count, int lock)
{
int rem;
int c = count;
@@ -311,9 +316,9 @@ int notrace persistent_ram_write(struct persistent_ram_zone *prz,
c = prz->buffer_size;
}

- buffer_size_add(prz, c);
+ buffer_size_add(prz, c, lock);

- start = buffer_start_add(prz, c);
+ start = buffer_start_add(prz, c, lock);

rem = prz->buffer_size - start;
if (unlikely(rem < c)) {
@@ -342,9 +347,9 @@ int notrace persistent_ram_write_user(struct persistent_ram_zone *prz,
c = prz->buffer_size;
}

- buffer_size_add(prz, c);
+ buffer_size_add(prz, c, PSTORE_RAM_LOCK);

- start = buffer_start_add(prz, c);
+ start = buffer_start_add(prz, c, PSTORE_RAM_LOCK);

rem = prz->buffer_size - start;
if (unlikely(rem < c)) {
diff --git a/include/linux/pstore_ram.h b/include/linux/pstore_ram.h
index 244d242..69f3487 100644
--- a/include/linux/pstore_ram.h
+++ b/include/linux/pstore_ram.h
@@ -24,6 +24,14 @@
#include <linux/list.h>
#include <linux/types.h>

+/*
+ * Choose whether access to the RAM zone requires locking or not. If a zone
+ * can be written to from different CPUs like with ftrace for example, then
+ * PSTORE_RAM_LOCK is used. For all other cases, PSTORE_RAM_NOLOCK should be used.
+ */
+#define PSTORE_RAM_NOLOCK 0
+#define PSTORE_RAM_LOCK 1
+
struct persistent_ram_buffer;
struct rs_control;

@@ -61,7 +69,7 @@ void persistent_ram_free(struct persistent_ram_zone *prz);
void persistent_ram_zap(struct persistent_ram_zone *prz);

int persistent_ram_write(struct persistent_ram_zone *prz, const void *s,
- unsigned int count);
+ unsigned int count, int lock);
int persistent_ram_write_user(struct persistent_ram_zone *prz,
const void __user *s, unsigned int count);

--
2.7.4
\
 
 \ /
  Last update: 2016-10-20 09:35    [W:0.104 / U:6.308 seconds]
©2003-2018 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site