From: Joe Perches <joe@perches.com>
To: Andrew Morton <akpm@linux-foundation.org>
Cc: LKML <linux-kernel@vger.kernel.org>
Subject: [RFC patch] vsprintf: Add %pav extension for print_vma_addr
Date: Tue, 26 May 2015 16:05:04 -0700 [thread overview]
Message-ID: <1432681504.2846.116.camel@perches.com> (raw)
print_vma_addr is another function to emit useful
data similar to print_symbol. The print_symbol
functionality has been added via %p[fFsS] vsprintf
extensions.
Perhaps it's appropriate to add vma_addr address
decoding to vsprintf too.
This would allow code conversions where the very
unlikely interleaving of messages from multiple
threads might occur.
like arch/x86/kernel/traps.c:
from:
if (show_unhandled_signals && unhandled_signal(tsk, signr) &&
printk_ratelimit()) {
pr_info("%s[%d] trap %s ip:%lx sp:%lx error:%lx",
tsk->comm, tsk->pid, str,
regs->ip, regs->sp, error_code);
print_vma_addr(" in ", regs->ip);
pr_cont("\n");
to:
pr_info("%s[%d] trap %s ip:%lx sp:%lx error:%lx in %pav\n",
regs->ip, regs->sp, error_code, ®s->ip);
}
Something like:
---
Documentation/printk-formats.txt | 5 ++++
lib/vsprintf.c | 62 ++++++++++++++++++++++++++++++++++++----
2 files changed, 61 insertions(+), 6 deletions(-)
diff --git a/Documentation/printk-formats.txt b/Documentation/printk-formats.txt
index 2ec6d84..962f82c 100644
--- a/Documentation/printk-formats.txt
+++ b/Documentation/printk-formats.txt
@@ -86,6 +86,11 @@ DMA addresses types dma_addr_t:
For printing a dma_addr_t type which can vary based on build options,
regardless of the width of the CPU data path. Passed by reference.
+VMA addresses: where the content of an unsigned long * is used in find_vma()
+ %pav "%s[%lx+%lx]",
+ kbasename(d_path(vma->vm_file)),
+ vma->vm_start, vma->vm_end - vma->vm_start)
+
Raw buffer as an escaped string:
%*pE[achnops]
diff --git a/lib/vsprintf.c b/lib/vsprintf.c
index 8243e2f..f4956c1 100644
--- a/lib/vsprintf.c
+++ b/lib/vsprintf.c
@@ -1313,23 +1313,70 @@ char *netdev_feature_string(char *buf, char *end, const u8 *addr,
}
static noinline_for_stack
+char *vma_addr(char *buf, char *end, const void *addr,
+ struct printf_spec spec, const char *fmt)
+{
+ struct mm_struct *mm = current->mm;
+ struct vm_area_struct *vma;
+ unsigned long ip = *(unsigned long *)addr;
+ char *rtn;
+
+ /* if we are in atomic contexts (in exception stacks, etc.) */
+ if (preempt_count())
+ return string(buf, end, "(atomic context)", spec);
+
+ down_read(&mm->mmap_sem);
+ vma = find_vma(mm, ip);
+ if (vma && vma->vm_file) {
+ struct file *f = vma->vm_file;
+ char *gfp_buf = (char *)__get_free_page(GFP_KERNEL);
+
+ if (gfp_buf) {
+ char *p = d_path(&f->f_path, gfp_buf, PAGE_SIZE);
+
+ if (IS_ERR(p))
+ p = "?";
+
+ rtn = buf + snprintf(buf, end > buf ? end - buf : 0,
+ "%s[%lx+%lx]",
+ kbasename(p),
+ vma->vm_start,
+ vma->vm_end - vma->vm_start);
+
+ free_page((unsigned long)gfp_buf);
+ } else {
+ rtn = string(buf, end, "(__get_free_page failed)", spec);
+ }
+ } else {
+ rtn = string(buf, end, "(find_vma failed)", spec);
+ }
+
+ up_read(&mm->mmap_sem);
+
+ return rtn;
+}
+
+static noinline_for_stack
char *address_val(char *buf, char *end, const void *addr,
struct printf_spec spec, const char *fmt)
{
unsigned long long num;
- spec.flags |= SPECIAL | SMALL | ZEROPAD;
- spec.base = 16;
-
switch (fmt[1]) {
+ case 'v':
+ return vma_addr(buf, end, addr, spec, fmt);
case 'd':
- num = *(const dma_addr_t *)addr;
+ spec.flags |= SPECIAL | SMALL | ZEROPAD;
+ spec.base = 16;
spec.field_width = sizeof(dma_addr_t) * 2 + 2;
+ num = *(const dma_addr_t *)addr;
break;
case 'p':
default:
- num = *(const phys_addr_t *)addr;
+ spec.flags |= SPECIAL | SMALL | ZEROPAD;
+ spec.base = 16;
spec.field_width = sizeof(phys_addr_t) * 2 + 2;
+ num = *(const phys_addr_t *)addr;
break;
}
@@ -1453,7 +1500,10 @@ int kptr_restrict __read_mostly;
* N no separator
* The maximum supported length is 64 bytes of the input. Consider
* to use print_hex_dump() for the larger input.
- * - 'a[pd]' For address types [p] phys_addr_t, [d] dma_addr_t and derivatives
+ * - 'a[pdv]' For address types:
+ * [p] phys_addr_t and derivatives (resource_size_t)
+ * [d] dma_addr_t
+ * [v] vma_addr
* (default assumed to be phys_addr_t, passed by reference)
* - 'd[234]' For a dentry name (optionally 2-4 last components)
* - 'D[234]' Same as 'd' but for a struct file
next reply other threads:[~2015-05-26 23:05 UTC|newest]
Thread overview: 6+ messages / expand[flat|nested] mbox.gz Atom feed top
2015-05-26 23:05 Joe Perches [this message]
2015-05-27 21:04 ` [RFC patch] vsprintf: Add %pav extension for print_vma_addr Andrew Morton
2015-05-27 21:09 ` Joe Perches
2015-05-27 21:19 ` Andrew Morton
2015-05-31 17:51 ` Joe Perches
2015-06-01 23:36 ` Andrew Morton
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=1432681504.2846.116.camel@perches.com \
--to=joe@perches.com \
--cc=akpm@linux-foundation.org \
--cc=linux-kernel@vger.kernel.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.