Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S932826AbcJTHeW (ORCPT ); Thu, 20 Oct 2016 03:34:22 -0400 Received: from mail-pf0-f170.google.com ([209.85.192.170]:34026 "EHLO mail-pf0-f170.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1756866AbcJTHeU (ORCPT ); Thu, 20 Oct 2016 03:34:20 -0400 From: Joel Fernandes To: linux-kernel@vger.kernel.org Cc: Kees Cook , Joel Fernandes , Anton Vorontsov , Colin Cross , Tony Luck Subject: [PATCH v2 2/7] pstore: locking: dont lock unless caller asks to Date: Thu, 20 Oct 2016 00:34:01 -0700 Message-Id: <1476948846-15006-3-git-send-email-joelaf@google.com> X-Mailer: git-send-email 2.7.4 In-Reply-To: <1476948846-15006-1-git-send-email-joelaf@google.com> References: <1476948846-15006-1-git-send-email-joelaf@google.com> Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Length: 5741 Lines: 173 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 --- 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 #include +/* + * 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