2022-08-15 17:44:24

by Kent Overstreet

[permalink] [raw]
Subject: Printbufs v6

Hey Andrew - here's the rest of the patch series. My brand new email account was
suspended halfway through because it thought I was sending spam... subtle
commentary on the contents, perhaps?

Cheers



2022-08-15 17:45:32

by Kent Overstreet

[permalink] [raw]
Subject: [PATCH 05/11] x86/resctrl: Convert to printbuf

From: Kent Overstreet <[email protected]>

This converts from seq_buf to printbuf. We're using printbuf in external
buffer mode so it's a trivial direct conversion.

Signed-off-by: Kent Overstreet <[email protected]>
Cc: [email protected]
---
arch/x86/kernel/cpu/resctrl/rdtgroup.c | 16 ++++++++--------
1 file changed, 8 insertions(+), 8 deletions(-)

diff --git a/arch/x86/kernel/cpu/resctrl/rdtgroup.c b/arch/x86/kernel/cpu/resctrl/rdtgroup.c
index f276aff521..50c12711a2 100644
--- a/arch/x86/kernel/cpu/resctrl/rdtgroup.c
+++ b/arch/x86/kernel/cpu/resctrl/rdtgroup.c
@@ -19,7 +19,7 @@
#include <linux/fs_parser.h>
#include <linux/sysfs.h>
#include <linux/kernfs.h>
-#include <linux/seq_buf.h>
+#include <linux/printbuf.h>
#include <linux/seq_file.h>
#include <linux/sched/signal.h>
#include <linux/sched/task.h>
@@ -51,7 +51,7 @@ static struct kernfs_node *kn_mongrp;
/* Kernel fs node for "mon_data" directory under root */
static struct kernfs_node *kn_mondata;

-static struct seq_buf last_cmd_status;
+static struct printbuf last_cmd_status;
static char last_cmd_status_buf[512];

struct dentry *debugfs_resctrl;
@@ -59,13 +59,13 @@ struct dentry *debugfs_resctrl;
void rdt_last_cmd_clear(void)
{
lockdep_assert_held(&rdtgroup_mutex);
- seq_buf_clear(&last_cmd_status);
+ printbuf_reset(&last_cmd_status);
}

void rdt_last_cmd_puts(const char *s)
{
lockdep_assert_held(&rdtgroup_mutex);
- seq_buf_puts(&last_cmd_status, s);
+ prt_str(&last_cmd_status, s);
}

void rdt_last_cmd_printf(const char *fmt, ...)
@@ -74,7 +74,7 @@ void rdt_last_cmd_printf(const char *fmt, ...)

va_start(ap, fmt);
lockdep_assert_held(&rdtgroup_mutex);
- seq_buf_vprintf(&last_cmd_status, fmt, ap);
+ prt_vprintf(&last_cmd_status, fmt, ap);
va_end(ap);
}

@@ -833,7 +833,7 @@ static int rdt_last_cmd_status_show(struct kernfs_open_file *of,
int len;

mutex_lock(&rdtgroup_mutex);
- len = seq_buf_used(&last_cmd_status);
+ len = printbuf_written(&last_cmd_status);
if (len)
seq_printf(seq, "%.*s", len, last_cmd_status_buf);
else
@@ -3248,8 +3248,8 @@ int __init rdtgroup_init(void)
{
int ret = 0;

- seq_buf_init(&last_cmd_status, last_cmd_status_buf,
- sizeof(last_cmd_status_buf));
+ last_cmd_status = PRINTBUF_EXTERN(last_cmd_status_buf,
+ sizeof(last_cmd_status_buf));

ret = rdtgroup_setup_root();
if (ret)
--
2.36.1

2022-08-15 17:45:47

by Kent Overstreet

[permalink] [raw]
Subject: [PATCH 06/11] PCI/P2PDMA: Convert to printbuf

From: Kent Overstreet <[email protected]>

This converts from seq_buf to printbuf. We're using printbuf in external
buffer mode so this is a direct conversion.

Signed-off-by: Kent Overstreet <[email protected]>
Cc: [email protected]
---
drivers/pci/p2pdma.c | 21 ++++++++-------------
1 file changed, 8 insertions(+), 13 deletions(-)

diff --git a/drivers/pci/p2pdma.c b/drivers/pci/p2pdma.c
index 4496a7c5c4..8e29e7caba 100644
--- a/drivers/pci/p2pdma.c
+++ b/drivers/pci/p2pdma.c
@@ -18,7 +18,7 @@
#include <linux/memremap.h>
#include <linux/percpu-refcount.h>
#include <linux/random.h>
-#include <linux/seq_buf.h>
+#include <linux/printbuf.h>
#include <linux/xarray.h>

struct pci_p2pdma {
@@ -275,12 +275,9 @@ static int pci_bridge_has_acs_redir(struct pci_dev *pdev)
return 0;
}

-static void seq_buf_print_bus_devfn(struct seq_buf *buf, struct pci_dev *pdev)
+static void prt_bus_devfn(struct printbuf *buf, struct pci_dev *pdev)
{
- if (!buf)
- return;
-
- seq_buf_printf(buf, "%s;", pci_name(pdev));
+ prt_printf(buf, "%s;", pci_name(pdev));
}

static bool cpu_supports_p2pdma(void)
@@ -454,13 +451,11 @@ calc_map_type_and_dist(struct pci_dev *provider, struct pci_dev *client,
struct pci_dev *a = provider, *b = client, *bb;
bool acs_redirects = false;
struct pci_p2pdma *p2pdma;
- struct seq_buf acs_list;
int acs_cnt = 0;
int dist_a = 0;
int dist_b = 0;
char buf[128];
-
- seq_buf_init(&acs_list, buf, sizeof(buf));
+ struct printbuf acs_list = PRINTBUF_EXTERN(buf, sizeof(buf));

/*
* Note, we don't need to take references to devices returned by
@@ -471,7 +466,7 @@ calc_map_type_and_dist(struct pci_dev *provider, struct pci_dev *client,
dist_b = 0;

if (pci_bridge_has_acs_redir(a)) {
- seq_buf_print_bus_devfn(&acs_list, a);
+ prt_bus_devfn(&acs_list, a);
acs_cnt++;
}

@@ -500,7 +495,7 @@ calc_map_type_and_dist(struct pci_dev *provider, struct pci_dev *client,
break;

if (pci_bridge_has_acs_redir(bb)) {
- seq_buf_print_bus_devfn(&acs_list, bb);
+ prt_bus_devfn(&acs_list, bb);
acs_cnt++;
}

@@ -515,11 +510,11 @@ calc_map_type_and_dist(struct pci_dev *provider, struct pci_dev *client,
}

if (verbose) {
- acs_list.buffer[acs_list.len-1] = 0; /* drop final semicolon */
+ acs_list.buf[acs_list.pos-1] = 0; /* drop final semicolon */
pci_warn(client, "ACS redirect is set between the client and provider (%s)\n",
pci_name(provider));
pci_warn(client, "to disable ACS redirect for this path, add the kernel parameter: pci=disable_acs_redir=%s\n",
- acs_list.buffer);
+ acs_list.buf);
}
acs_redirects = true;

--
2.36.1

2022-08-15 17:50:31

by Kent Overstreet

[permalink] [raw]
Subject: [PATCH 07/11] tracing: trace_events_synth: Convert to printbuf

From: Kent Overstreet <[email protected]>

This converts from seq_buf to printbuf.

This code was using seq_buf for building up dynamically allocated
strings; the conversion uses printbuf's heap allocation functionality to
simplify things (no longer need to calculate size of the output string).

Also, alphabetize the #includes.

Signed-off-by: Kent Overstreet <[email protected]>
Cc: Steven Rostedt <[email protected]>
Cc: Ingo Molnar <[email protected]>
---
kernel/trace/trace_events_synth.c | 51 ++++++++++---------------------
1 file changed, 16 insertions(+), 35 deletions(-)

diff --git a/kernel/trace/trace_events_synth.c b/kernel/trace/trace_events_synth.c
index 5e8c07aef0..720c75429c 100644
--- a/kernel/trace/trace_events_synth.c
+++ b/kernel/trace/trace_events_synth.c
@@ -5,13 +5,14 @@
* Copyright (C) 2015, 2020 Tom Zanussi <[email protected]>
*/

-#include <linux/module.h>
#include <linux/kallsyms.h>
-#include <linux/security.h>
+#include <linux/module.h>
#include <linux/mutex.h>
+#include <linux/printbuf.h>
+#include <linux/rculist.h>
+#include <linux/security.h>
#include <linux/slab.h>
#include <linux/stacktrace.h>
-#include <linux/rculist.h>
#include <linux/tracefs.h>

/* for gfp flag names */
@@ -611,7 +612,7 @@ static struct synth_field *parse_synth_field(int argc, char **argv,
const char *prefix = NULL, *field_type = argv[0], *field_name, *array;
struct synth_field *field;
int len, ret = -ENOMEM;
- struct seq_buf s;
+ struct printbuf buf;
ssize_t size;

if (!strcmp(field_type, "unsigned")) {
@@ -654,28 +655,16 @@ static struct synth_field *parse_synth_field(int argc, char **argv,
goto free;
}

- len = strlen(field_type) + 1;
-
- if (array)
- len += strlen(array);
-
- if (prefix)
- len += strlen(prefix);
-
- field->type = kzalloc(len, GFP_KERNEL);
- if (!field->type)
- goto free;
-
- seq_buf_init(&s, field->type, len);
+ buf = PRINTBUF;
if (prefix)
- seq_buf_puts(&s, prefix);
- seq_buf_puts(&s, field_type);
+ prt_str(&buf, prefix);
+ prt_str(&buf, field_type);
if (array)
- seq_buf_puts(&s, array);
- if (WARN_ON_ONCE(!seq_buf_buffer_left(&s)))
+ prt_str(&buf, array);
+ if (buf.allocation_failure)
goto free;

- s.buffer[s.len] = '\0';
+ field->type = buf.buf;

size = synth_field_size(field->type);
if (size < 0) {
@@ -687,23 +676,15 @@ static struct synth_field *parse_synth_field(int argc, char **argv,
goto free;
} else if (size == 0) {
if (synth_field_is_string(field->type)) {
- char *type;
-
- len = sizeof("__data_loc ") + strlen(field->type) + 1;
- type = kzalloc(len, GFP_KERNEL);
- if (!type)
- goto free;
-
- seq_buf_init(&s, type, len);
- seq_buf_puts(&s, "__data_loc ");
- seq_buf_puts(&s, field->type);
+ buf = PRINTBUF;
+ prt_str(&buf, "__data_loc ");
+ prt_str(&buf, field->type);

- if (WARN_ON_ONCE(!seq_buf_buffer_left(&s)))
+ if (buf.allocation_failure)
goto free;
- s.buffer[s.len] = '\0';

kfree(field->type);
- field->type = type;
+ field->type = buf.buf;

field->is_dynamic = true;
size = sizeof(u64);
--
2.36.1

2022-08-15 17:50:42

by Kent Overstreet

[permalink] [raw]
Subject: [PATCH 04/11] powerpc: Convert to printbuf

From: Kent Overstreet <[email protected]>

This converts from seq_buf to printbuf. We're using printbuf in external
buffer mode, so it's a direct conversion, aside from some trivial
refactoring in cpu_show_meltdown() to make the code more consistent.

Signed-off-by: Kent Overstreet <[email protected]>
Cc: [email protected]
---
arch/powerpc/kernel/process.c | 16 +++--
arch/powerpc/kernel/security.c | 75 ++++++++++-------------
arch/powerpc/platforms/pseries/papr_scm.c | 34 +++++-----
3 files changed, 57 insertions(+), 68 deletions(-)

diff --git a/arch/powerpc/kernel/process.c b/arch/powerpc/kernel/process.c
index 0fbda89cd1..05654dbeb2 100644
--- a/arch/powerpc/kernel/process.c
+++ b/arch/powerpc/kernel/process.c
@@ -37,7 +37,7 @@
#include <linux/hw_breakpoint.h>
#include <linux/uaccess.h>
#include <linux/pkeys.h>
-#include <linux/seq_buf.h>
+#include <linux/printbuf.h>

#include <asm/interrupt.h>
#include <asm/io.h>
@@ -1396,32 +1396,30 @@ void show_user_instructions(struct pt_regs *regs)
{
unsigned long pc;
int n = NR_INSN_TO_PRINT;
- struct seq_buf s;
char buf[96]; /* enough for 8 times 9 + 2 chars */
+ struct printbuf s = PRINTBUF_EXTERN(buf, sizeof(buf));

pc = regs->nip - (NR_INSN_TO_PRINT * 3 / 4 * sizeof(int));

- seq_buf_init(&s, buf, sizeof(buf));
-
while (n) {
int i;

- seq_buf_clear(&s);
+ printbuf_reset(&s);

for (i = 0; i < 8 && n; i++, n--, pc += sizeof(int)) {
int instr;

if (copy_from_user_nofault(&instr, (void __user *)pc,
sizeof(instr))) {
- seq_buf_printf(&s, "XXXXXXXX ");
+ prt_printf(&s, "XXXXXXXX ");
continue;
}
- seq_buf_printf(&s, regs->nip == pc ? "<%08x> " : "%08x ", instr);
+ prt_printf(&s, regs->nip == pc ? "<%08x> " : "%08x ", instr);
}

- if (!seq_buf_has_overflowed(&s))
+ if (printbuf_remaining(&s))
pr_info("%s[%d]: code: %s\n", current->comm,
- current->pid, s.buffer);
+ current->pid, s.buf);
}
}

diff --git a/arch/powerpc/kernel/security.c b/arch/powerpc/kernel/security.c
index d96fd14bd7..b34de62e65 100644
--- a/arch/powerpc/kernel/security.c
+++ b/arch/powerpc/kernel/security.c
@@ -10,7 +10,7 @@
#include <linux/memblock.h>
#include <linux/nospec.h>
#include <linux/prctl.h>
-#include <linux/seq_buf.h>
+#include <linux/printbuf.h>
#include <linux/debugfs.h>

#include <asm/asm-prototypes.h>
@@ -144,31 +144,28 @@ void __init setup_spectre_v2(void)
#ifdef CONFIG_PPC_BOOK3S_64
ssize_t cpu_show_meltdown(struct device *dev, struct device_attribute *attr, char *buf)
{
+ struct printbuf s = PRINTBUF_EXTERN(buf, PAGE_SIZE);
bool thread_priv;

thread_priv = security_ftr_enabled(SEC_FTR_L1D_THREAD_PRIV);

if (rfi_flush) {
- struct seq_buf s;
- seq_buf_init(&s, buf, PAGE_SIZE - 1);

- seq_buf_printf(&s, "Mitigation: RFI Flush");
+ prt_printf(&s, "Mitigation: RFI Flush");
if (thread_priv)
- seq_buf_printf(&s, ", L1D private per thread");
-
- seq_buf_printf(&s, "\n");
-
- return s.len;
+ prt_printf(&s, ", L1D private per thread");
+
+ prt_printf(&s, "\n");
+ } else if (thread_priv) {
+ prt_printf(&s, "Vulnerable: L1D private per thread\n");
+ } else if (!security_ftr_enabled(SEC_FTR_L1D_FLUSH_HV) &&
+ !security_ftr_enabled(SEC_FTR_L1D_FLUSH_PR)) {
+ prt_printf(&s, "Not affected\n");
+ } else {
+ prt_printf(&s, "Vulnerable\n");
}

- if (thread_priv)
- return sprintf(buf, "Vulnerable: L1D private per thread\n");
-
- if (!security_ftr_enabled(SEC_FTR_L1D_FLUSH_HV) &&
- !security_ftr_enabled(SEC_FTR_L1D_FLUSH_PR))
- return sprintf(buf, "Not affected\n");
-
- return sprintf(buf, "Vulnerable\n");
+ return printbuf_written(&s);
}

ssize_t cpu_show_l1tf(struct device *dev, struct device_attribute *attr, char *buf)
@@ -179,70 +176,66 @@ ssize_t cpu_show_l1tf(struct device *dev, struct device_attribute *attr, char *b

ssize_t cpu_show_spectre_v1(struct device *dev, struct device_attribute *attr, char *buf)
{
- struct seq_buf s;
-
- seq_buf_init(&s, buf, PAGE_SIZE - 1);
+ struct printbuf s = PRINTBUF_EXTERN(buf, PAGE_SIZE);

if (security_ftr_enabled(SEC_FTR_BNDS_CHK_SPEC_BAR)) {
if (barrier_nospec_enabled)
- seq_buf_printf(&s, "Mitigation: __user pointer sanitization");
+ prt_printf(&s, "Mitigation: __user pointer sanitization");
else
- seq_buf_printf(&s, "Vulnerable");
+ prt_printf(&s, "Vulnerable");

if (security_ftr_enabled(SEC_FTR_SPEC_BAR_ORI31))
- seq_buf_printf(&s, ", ori31 speculation barrier enabled");
+ prt_printf(&s, ", ori31 speculation barrier enabled");

- seq_buf_printf(&s, "\n");
+ prt_printf(&s, "\n");
} else
- seq_buf_printf(&s, "Not affected\n");
+ prt_printf(&s, "Not affected\n");

- return s.len;
+ return printbuf_written(&s);
}

ssize_t cpu_show_spectre_v2(struct device *dev, struct device_attribute *attr, char *buf)
{
- struct seq_buf s;
+ struct printbuf s = PRINTBUF_EXTERN(buf, PAGE_SIZE);
bool bcs, ccd;

- seq_buf_init(&s, buf, PAGE_SIZE - 1);
-
bcs = security_ftr_enabled(SEC_FTR_BCCTRL_SERIALISED);
ccd = security_ftr_enabled(SEC_FTR_COUNT_CACHE_DISABLED);

if (bcs || ccd) {
- seq_buf_printf(&s, "Mitigation: ");
+ prt_printf(&s, "Mitigation: ");

if (bcs)
- seq_buf_printf(&s, "Indirect branch serialisation (kernel only)");
+ prt_printf(&s, "Indirect branch serialisation (kernel only)");

if (bcs && ccd)
- seq_buf_printf(&s, ", ");
+ prt_printf(&s, ", ");

if (ccd)
- seq_buf_printf(&s, "Indirect branch cache disabled");
+ prt_printf(&s, "Indirect branch cache disabled");

} else if (count_cache_flush_type != BRANCH_CACHE_FLUSH_NONE) {
- seq_buf_printf(&s, "Mitigation: Software count cache flush");
+ prt_printf(&s, "Mitigation: Software count cache flush");

if (count_cache_flush_type == BRANCH_CACHE_FLUSH_HW)
- seq_buf_printf(&s, " (hardware accelerated)");
+ prt_printf(&s, " (hardware accelerated)");

} else if (btb_flush_enabled) {
- seq_buf_printf(&s, "Mitigation: Branch predictor state flush");
+ prt_printf(&s, "Mitigation: Branch predictor state flush");
} else {
- seq_buf_printf(&s, "Vulnerable");
+ prt_printf(&s, "Vulnerable");
}

if (bcs || ccd || count_cache_flush_type != BRANCH_CACHE_FLUSH_NONE) {
if (link_stack_flush_type != BRANCH_CACHE_FLUSH_NONE)
- seq_buf_printf(&s, ", Software link stack flush");
+ prt_printf(&s, ", Software link stack flush");
if (link_stack_flush_type == BRANCH_CACHE_FLUSH_HW)
- seq_buf_printf(&s, " (hardware accelerated)");
+ prt_printf(&s, " (hardware accelerated)");
}

- seq_buf_printf(&s, "\n");
+ prt_printf(&s, "\n");

- return s.len;
+ return printbuf_written(&s);
}

#ifdef CONFIG_PPC_BOOK3S_64
diff --git a/arch/powerpc/platforms/pseries/papr_scm.c b/arch/powerpc/platforms/pseries/papr_scm.c
index 20f6ed813b..a1fd25243c 100644
--- a/arch/powerpc/platforms/pseries/papr_scm.c
+++ b/arch/powerpc/platforms/pseries/papr_scm.c
@@ -12,7 +12,7 @@
#include <linux/libnvdimm.h>
#include <linux/platform_device.h>
#include <linux/delay.h>
-#include <linux/seq_buf.h>
+#include <linux/printbuf.h>
#include <linux/nd.h>

#include <asm/plpar_wrappers.h>
@@ -1142,7 +1142,7 @@ static ssize_t perf_stats_show(struct device *dev,
{
int index;
ssize_t rc;
- struct seq_buf s;
+ struct printbuf s = PRINTBUF_EXTERN(buf, PAGE_SIZE);
struct papr_scm_perf_stat *stat;
struct papr_scm_perf_stats *stats;
struct nvdimm *dimm = to_nvdimm(dev);
@@ -1165,18 +1165,17 @@ static ssize_t perf_stats_show(struct device *dev,
* values. Since stat_id is essentially a char string of
* 8 bytes, simply use the string format specifier to print it.
*/
- seq_buf_init(&s, buf, PAGE_SIZE);
for (index = 0, stat = stats->scm_statistic;
index < be32_to_cpu(stats->num_statistics);
++index, ++stat) {
- seq_buf_printf(&s, "%.8s = 0x%016llX\n",
- stat->stat_id,
- be64_to_cpu(stat->stat_val));
+ prt_printf(&s, "%.8s = 0x%016llX\n",
+ stat->stat_id,
+ be64_to_cpu(stat->stat_val));
}

free_stats:
kfree(stats);
- return rc ? rc : (ssize_t)seq_buf_used(&s);
+ return rc ?: printbuf_written(&s);
}
static DEVICE_ATTR_ADMIN_RO(perf_stats);

@@ -1185,7 +1184,7 @@ static ssize_t flags_show(struct device *dev,
{
struct nvdimm *dimm = to_nvdimm(dev);
struct papr_scm_priv *p = nvdimm_provider_data(dimm);
- struct seq_buf s;
+ struct printbuf s = PRINTBUF_EXTERN(buf, PAGE_SIZE);
u64 health;
int rc;

@@ -1196,29 +1195,28 @@ static ssize_t flags_show(struct device *dev,
/* Copy health_bitmap locally, check masks & update out buffer */
health = READ_ONCE(p->health_bitmap);

- seq_buf_init(&s, buf, PAGE_SIZE);
if (health & PAPR_PMEM_UNARMED_MASK)
- seq_buf_printf(&s, "not_armed ");
+ prt_printf(&s, "not_armed ");

if (health & PAPR_PMEM_BAD_SHUTDOWN_MASK)
- seq_buf_printf(&s, "flush_fail ");
+ prt_printf(&s, "flush_fail ");

if (health & PAPR_PMEM_BAD_RESTORE_MASK)
- seq_buf_printf(&s, "restore_fail ");
+ prt_printf(&s, "restore_fail ");

if (health & PAPR_PMEM_ENCRYPTED)
- seq_buf_printf(&s, "encrypted ");
+ prt_printf(&s, "encrypted ");

if (health & PAPR_PMEM_SMART_EVENT_MASK)
- seq_buf_printf(&s, "smart_notify ");
+ prt_printf(&s, "smart_notify ");

if (health & PAPR_PMEM_SCRUBBED_AND_LOCKED)
- seq_buf_printf(&s, "scrubbed locked ");
+ prt_printf(&s, "scrubbed locked ");

- if (seq_buf_used(&s))
- seq_buf_printf(&s, "\n");
+ if (printbuf_written(&s))
+ prt_printf(&s, "\n");

- return seq_buf_used(&s);
+ return printbuf_written(&s);
}
DEVICE_ATTR_RO(flags);

--
2.36.1

2022-08-15 17:51:11

by Kent Overstreet

[permalink] [raw]
Subject: [PATCH 03/11] tools/testing/nvdimm: Convert to printbuf

From: Kent Overstreet <[email protected]>

This converts from seq_buf to printbuf. Here we're using printbuf with
an external buffer, meaning it's a direct conversion.

Signed-off-by: Kent Overstreet <[email protected]>
Cc: Dan Williams <[email protected]>
Cc: Dave Hansen <[email protected]>
Cc: [email protected]
Acked-by: Dan Williams <[email protected]>
Tested-By: Shivaprasad G Bhat <[email protected]>
---
tools/testing/nvdimm/test/ndtest.c | 22 ++++++++++------------
1 file changed, 10 insertions(+), 12 deletions(-)

diff --git a/tools/testing/nvdimm/test/ndtest.c b/tools/testing/nvdimm/test/ndtest.c
index 4d1a947367..a2097955da 100644
--- a/tools/testing/nvdimm/test/ndtest.c
+++ b/tools/testing/nvdimm/test/ndtest.c
@@ -12,7 +12,7 @@
#include <linux/ndctl.h>
#include <nd-core.h>
#include <linux/printk.h>
-#include <linux/seq_buf.h>
+#include <linux/printbuf.h>

#include "../watermark.h"
#include "nfit_test.h"
@@ -740,32 +740,30 @@ static ssize_t flags_show(struct device *dev,
{
struct nvdimm *nvdimm = to_nvdimm(dev);
struct ndtest_dimm *dimm = nvdimm_provider_data(nvdimm);
- struct seq_buf s;
+ struct printbuf s = PRINTBUF_EXTERN(buf, PAGE_SIZE);
u64 flags;

flags = dimm->flags;

- seq_buf_init(&s, buf, PAGE_SIZE);
if (flags & PAPR_PMEM_UNARMED_MASK)
- seq_buf_printf(&s, "not_armed ");
+ prt_printf(&s, "not_armed ");

if (flags & PAPR_PMEM_BAD_SHUTDOWN_MASK)
- seq_buf_printf(&s, "flush_fail ");
+ prt_printf(&s, "flush_fail ");

if (flags & PAPR_PMEM_BAD_RESTORE_MASK)
- seq_buf_printf(&s, "restore_fail ");
+ prt_printf(&s, "restore_fail ");

if (flags & PAPR_PMEM_SAVE_MASK)
- seq_buf_printf(&s, "save_fail ");
+ prt_printf(&s, "save_fail ");

if (flags & PAPR_PMEM_SMART_EVENT_MASK)
- seq_buf_printf(&s, "smart_notify ");
+ prt_printf(&s, "smart_notify ");

+ if (printbuf_written(&s))
+ prt_printf(&s, "\n");

- if (seq_buf_used(&s))
- seq_buf_printf(&s, "\n");
-
- return seq_buf_used(&s);
+ return printbuf_written(&s);
}
static DEVICE_ATTR_RO(flags);

--
2.36.1

2022-08-15 17:51:38

by Steven Rostedt

[permalink] [raw]
Subject: Re: [PATCH 07/11] tracing: trace_events_synth: Convert to printbuf

On Mon, 15 Aug 2022 13:26:09 -0400
Kent Overstreet <[email protected]> wrote:

> From: Kent Overstreet <[email protected]>
>
> This converts from seq_buf to printbuf.
>
> This code was using seq_buf for building up dynamically allocated
> strings; the conversion uses printbuf's heap allocation functionality to
> simplify things (no longer need to calculate size of the output string).

As I stated before. I'll look into converting the seq_bufs to printbuf for
tracing at a later date. That includes this file.

Please remove this patch from the series.

>
> Also, alphabetize the #includes.
>

And although the #includes are not in the order the tracing directory
prefers, that order is upside-down x-mas tree, not alphabetical.

Thanks,

-- Steve


> Signed-off-by: Kent Overstreet <[email protected]>
> Cc: Steven Rostedt <[email protected]>
> Cc: Ingo Molnar <[email protected]>
> ---
> kernel/trace/trace_events_synth.c | 51 ++++++++++---------------------
> 1 file changed, 16 insertions(+), 35 deletions(-)
>
> diff --git a/kernel/trace/trace_events_synth.c b/kernel/trace/trace_events_synth.c
> index 5e8c07aef0..720c75429c 100644
> --- a/kernel/trace/trace_events_synth.c
> +++ b/kernel/trace/trace_events_synth.c
> @@ -5,13 +5,14 @@
> * Copyright (C) 2015, 2020 Tom Zanussi <[email protected]>
> */
>
> -#include <linux/module.h>
> #include <linux/kallsyms.h>
> -#include <linux/security.h>
> +#include <linux/module.h>
> #include <linux/mutex.h>
> +#include <linux/printbuf.h>
> +#include <linux/rculist.h>
> +#include <linux/security.h>
> #include <linux/slab.h>
> #include <linux/stacktrace.h>
> -#include <linux/rculist.h>
> #include <linux/tracefs.h>
>
> /* for gfp flag names */
> @@ -611,7 +612,7 @@ static struct synth_field *parse_synth_field(int argc, char **argv,
> const char *prefix = NULL, *field_type = argv[0], *field_name, *array;
> struct synth_field *field;
> int len, ret = -ENOMEM;
> - struct seq_buf s;
> + struct printbuf buf;
> ssize_t size;
>
> if (!strcmp(field_type, "unsigned")) {
> @@ -654,28 +655,16 @@ static struct synth_field *parse_synth_field(int argc, char **argv,
> goto free;
> }
>
> - len = strlen(field_type) + 1;
> -
> - if (array)
> - len += strlen(array);
> -
> - if (prefix)
> - len += strlen(prefix);
> -
> - field->type = kzalloc(len, GFP_KERNEL);
> - if (!field->type)
> - goto free;
> -
> - seq_buf_init(&s, field->type, len);
> + buf = PRINTBUF;
> if (prefix)
> - seq_buf_puts(&s, prefix);
> - seq_buf_puts(&s, field_type);
> + prt_str(&buf, prefix);
> + prt_str(&buf, field_type);
> if (array)
> - seq_buf_puts(&s, array);
> - if (WARN_ON_ONCE(!seq_buf_buffer_left(&s)))
> + prt_str(&buf, array);
> + if (buf.allocation_failure)
> goto free;
>
> - s.buffer[s.len] = '\0';
> + field->type = buf.buf;
>
> size = synth_field_size(field->type);
> if (size < 0) {
> @@ -687,23 +676,15 @@ static struct synth_field *parse_synth_field(int argc, char **argv,
> goto free;
> } else if (size == 0) {
> if (synth_field_is_string(field->type)) {
> - char *type;
> -
> - len = sizeof("__data_loc ") + strlen(field->type) + 1;
> - type = kzalloc(len, GFP_KERNEL);
> - if (!type)
> - goto free;
> -
> - seq_buf_init(&s, type, len);
> - seq_buf_puts(&s, "__data_loc ");
> - seq_buf_puts(&s, field->type);
> + buf = PRINTBUF;
> + prt_str(&buf, "__data_loc ");
> + prt_str(&buf, field->type);
>
> - if (WARN_ON_ONCE(!seq_buf_buffer_left(&s)))
> + if (buf.allocation_failure)
> goto free;
> - s.buffer[s.len] = '\0';
>
> kfree(field->type);
> - field->type = type;
> + field->type = buf.buf;
>
> field->is_dynamic = true;
> size = sizeof(u64);

2022-08-15 18:00:06

by Kent Overstreet

[permalink] [raw]
Subject: [PATCH 08/11] d_path: prt_path()

From: Kent Overstreet <[email protected]>

This implements a new printbuf version of d_path()/mangle_path(), which
will replace the seq_buf version.

Signed-off-by: Kent Overstreet <[email protected]>
Cc: Alexander Viro <[email protected]>
---
fs/d_path.c | 35 +++++++++++++++++++++++++++++++++++
include/linux/dcache.h | 1 +
2 files changed, 36 insertions(+)

diff --git a/fs/d_path.c b/fs/d_path.c
index e4e0ebad1f..1bd9e85f2f 100644
--- a/fs/d_path.c
+++ b/fs/d_path.c
@@ -5,6 +5,7 @@
#include <linux/fs_struct.h>
#include <linux/fs.h>
#include <linux/slab.h>
+#include <linux/printbuf.h>
#include <linux/prefetch.h>
#include "mount.h"

@@ -294,6 +295,40 @@ char *d_path(const struct path *path, char *buf, int buflen)
}
EXPORT_SYMBOL(d_path);

+/**
+ * prt_path - format a path for output
+ * @out: printbuf to output to
+ * @path: path to write into the sequence buffer.
+ * @esc: set of characters to escape in the output
+ *
+ * Write a path name into the sequence buffer.
+ *
+ * Returns 0 on success, or error code from d_path
+ */
+int prt_path(struct printbuf *out, const struct path *path, const char *esc)
+{
+ char *p, *buf;
+ size_t size;
+again:
+ buf = out->buf + out->pos;
+ size = printbuf_remaining_size(out);
+
+ p = d_path(path, buf, size);
+ if (IS_ERR(p)) {
+ printbuf_make_room(out, max_t(size_t, 64, size * 2));
+ if (printbuf_remaining_size(out) > size)
+ goto again;
+
+ return PTR_ERR(p);
+ }
+
+ p = mangle_path(buf, p, esc);
+ if (p)
+ out->pos += p - buf;
+ return 0;
+}
+EXPORT_SYMBOL(prt_path);
+
/*
* Helper function for dentry_operations.d_dname() members
*/
diff --git a/include/linux/dcache.h b/include/linux/dcache.h
index c73e5e327e..bdd5940aa7 100644
--- a/include/linux/dcache.h
+++ b/include/linux/dcache.h
@@ -293,6 +293,7 @@ extern char *d_absolute_path(const struct path *, char *, int);
extern char *d_path(const struct path *, char *, int);
extern char *dentry_path_raw(const struct dentry *, char *, int);
extern char *dentry_path(const struct dentry *, char *, int);
+extern int prt_path(struct printbuf *, const struct path *, const char *);

/* Allocation counts.. */

--
2.36.1

2022-08-15 18:07:55

by Kent Overstreet

[permalink] [raw]
Subject: Re: [PATCH 07/11] tracing: trace_events_synth: Convert to printbuf

On Mon, Aug 15, 2022 at 01:43:14PM -0400, Steven Rostedt wrote:
> On Mon, 15 Aug 2022 13:26:09 -0400
> Kent Overstreet <[email protected]> wrote:
>
> > From: Kent Overstreet <[email protected]>
> >
> > This converts from seq_buf to printbuf.
> >
> > This code was using seq_buf for building up dynamically allocated
> > strings; the conversion uses printbuf's heap allocation functionality to
> > simplify things (no longer need to calculate size of the output string).
>
> As I stated before. I'll look into converting the seq_bufs to printbuf for
> tracing at a later date. That includes this file.

You specified the other tracing patch, you did not specify this one.

Andrew, I just reran the tracing tests with this patch dropped - you can just
drop it, no other fixups are required.

2022-08-15 18:55:33

by Steven Rostedt

[permalink] [raw]
Subject: Re: [PATCH 07/11] tracing: trace_events_synth: Convert to printbuf

On Mon, 15 Aug 2022 13:58:30 -0400
Kent Overstreet <[email protected]> wrote:

> You specified the other tracing patch, you did not specify this one.

I said: "As I said. Feel free to move seq_buf.c back into the tracing directory (but
still need to keep seq_buf.h in include/linux), and feel free to convert
all the other users besides tracing, to printbuf."

This is one of the tracing patches.

>
> Andrew, I just reran the tracing tests with this patch dropped - you can just
> drop it, no other fixups are required.

Thanks,

-- Steve