* [PATCH v4 2nd 0/4] pstore: ramoops: support multiple pmsg instances
@ 2017-01-31 1:58 Nobuhiro Iwamatsu
2017-01-31 1:58 ` [PATCH v4 2nd 1/4] ramoops: Add __ramoops_init_prz() as generic function Nobuhiro Iwamatsu
` (3 more replies)
0 siblings, 4 replies; 12+ messages in thread
From: Nobuhiro Iwamatsu @ 2017-01-31 1:58 UTC (permalink / raw)
To: Anton Vorontsov, Colin Cross, Kees Cook, Tony Luck
Cc: linux-kernel, Nobuhiro Iwamatsu
The following series implements multiple pmsg. This feature allows userspace
program to control individual content aging or priority.
If a pstore backend module(e.g. ramoops) requires the multiple pmsg instances
when registering itself to pstore, multiple /dev/pmsg[ID] are created. Writes
to each /dev/pmsg[ID] are isolated each other. After reboot, the contents are
available in /sys/fs/pstore/pmsg-[backend]-[ID].
In addition, we add multiple pmsg support for ramoops. We can specify multiple
pmsg area size by its module parameter as follows.
pmsg_size=0x1000,0x2000,...
I did check the operation of this feature on CycloneV (socfpga) Helio board.
v4:
Rebase to 4.10-rc5
The following patches have been removed from this series as similar functions
were modified by other commit.
- pstore: Replace four kzalloc() calls by kcalloc() in ramoops_init_przs()
- pstore: Change parameter of ramoops_free_przs()
- pstore: Rename 'przs' to 'dprzs' in struct ramoops_context
- ramoops: Rename ramoops_init_prz() to ramoops_init_dprzs()
v3:
Rebase to v4.8.
Split patch.
merged device_create().
Remove Blank lines.
Update documentiation of DT binding.
Update parsing function of ramoops_pmsg_size, add NULL termination.
Update module parameters for pmsg_size list.
Hiraku Toyooka (2):
pstore: support multiple pmsg instances
selftests/pstore: add testcases for multiple pmsg instances
Nobuhiro Iwamatsu (2):
ramoops: Add __ramoops_init_prz() as generic function
ramoops: support multiple pmsg instances
Documentation/admin-guide/ramoops.rst | 22 ++
.../bindings/reserved-memory/ramoops.txt | 6 +-
fs/pstore/pmsg.c | 23 +-
fs/pstore/ram.c | 286 +++++++++++++++++----
include/linux/pstore.h | 1 +
include/linux/pstore_ram.h | 8 +-
tools/testing/selftests/pstore/common_tests | 21 +-
.../selftests/pstore/pstore_post_reboot_tests | 27 +-
tools/testing/selftests/pstore/pstore_tests | 14 +-
9 files changed, 326 insertions(+), 82 deletions(-)
--
2.11.0
^ permalink raw reply [flat|nested] 12+ messages in thread
* [PATCH v4 2nd 1/4] ramoops: Add __ramoops_init_prz() as generic function
2017-01-31 1:58 [PATCH v4 2nd 0/4] pstore: ramoops: support multiple pmsg instances Nobuhiro Iwamatsu
@ 2017-01-31 1:58 ` Nobuhiro Iwamatsu
2017-02-02 22:13 ` Mark Salyzyn
2017-01-31 1:58 ` [PATCH v4 2nd 2/4] pstore: support multiple pmsg instances Nobuhiro Iwamatsu
` (2 subsequent siblings)
3 siblings, 1 reply; 12+ messages in thread
From: Nobuhiro Iwamatsu @ 2017-01-31 1:58 UTC (permalink / raw)
To: Anton Vorontsov, Colin Cross, Kees Cook, Tony Luck
Cc: linux-kernel, Nobuhiro Iwamatsu, Hiraku Toyooka, Mark Salyzyn,
Seiji Aguchi, Shuah Khan
This commit adds generic function __ramoops_init_prz() to reduce redundancy
between ramoops_init_prz() and ramoops_init_przs().
Signed-off-by: Nobuhiro Iwamatsu <nobuhiro.iwamatsu.kw@hitachi.com>
Signed-off-by: Hiraku Toyooka <hiraku.toyooka.gu@hitachi.com>
Cc: Anton Vorontsov <anton@enomsg.org>
Cc: Colin Cross <ccross@android.com>
Cc: Kees Cook <keescook@chromium.org>
Cc: Mark Salyzyn <salyzyn@android.com>
Cc: Seiji Aguchi <seiji.aguchi.tr@hitachi.com>
Cc: Shuah Khan <shuahkh@osg.samsung.com>
Cc: Tony Luck <tony.luck@intel.com>
V4:
Rebase.
V3:
Rebase.
Split patch.
---
fs/pstore/ram.c | 73 ++++++++++++++++++++++++++++++---------------------------
1 file changed, 38 insertions(+), 35 deletions(-)
diff --git a/fs/pstore/ram.c b/fs/pstore/ram.c
index a412aec848ce..72072e8123e3 100644
--- a/fs/pstore/ram.c
+++ b/fs/pstore/ram.c
@@ -520,6 +520,40 @@ static void ramoops_free_przs(struct persistent_ram_zone **przs)
kfree(przs);
}
+static int __ramoops_init_prz(const char *name,
+ struct device *dev, struct ramoops_context *cxt,
+ struct persistent_ram_zone **prz,
+ phys_addr_t *paddr, size_t sz, u32 sig,
+ u32 flags, bool zap)
+{
+ if (!sz)
+ return 0;
+
+ if (zap && *paddr + sz - cxt->phys_addr > cxt->size) {
+ dev_err(dev, "no room for %s mem region (0x%zx@0x%llx) in (0x%lx@0x%llx)\n",
+ name, sz, (unsigned long long)*paddr,
+ cxt->size, (unsigned long long)cxt->phys_addr);
+ return -ENOMEM;
+ }
+
+ *prz = persistent_ram_new(*paddr, sz, sig, &cxt->ecc_info,
+ cxt->memtype, flags);
+ if (IS_ERR(*prz)) {
+ int err = PTR_ERR(*prz);
+
+ dev_err(dev, "failed to request %s mem region (0x%zx@0x%llx): %d\n",
+ name, sz, (unsigned long long)*paddr, err);
+ return err;
+ }
+
+ if (zap)
+ persistent_ram_zap(*prz);
+
+ *paddr += sz;
+
+ return 0;
+}
+
static int ramoops_init_przs(const char *name,
struct device *dev, struct ramoops_context *cxt,
struct persistent_ram_zone ***przs,
@@ -580,15 +614,9 @@ static int ramoops_init_przs(const char *name,
goto fail;
for (i = 0; i < *cnt; i++) {
- prz_ar[i] = persistent_ram_new(*paddr, zone_sz, sig,
- &cxt->ecc_info,
- cxt->memtype, flags);
- if (IS_ERR(prz_ar[i])) {
- err = PTR_ERR(prz_ar[i]);
- dev_err(dev, "failed to request %s mem region (0x%zx@0x%llx): %d\n",
- name, record_size,
- (unsigned long long)*paddr, err);
-
+ err = __ramoops_init_prz(name, dev, cxt, &prz_ar[i], paddr,
+ zone_sz, sig, flags, false);
+ if (err) {
while (i > 0) {
i--;
persistent_ram_free(prz_ar[i]);
@@ -596,7 +624,6 @@ static int ramoops_init_przs(const char *name,
kfree(prz_ar);
goto fail;
}
- *paddr += zone_sz;
}
*przs = prz_ar;
@@ -612,31 +639,7 @@ static int ramoops_init_prz(const char *name,
struct persistent_ram_zone **prz,
phys_addr_t *paddr, size_t sz, u32 sig)
{
- if (!sz)
- return 0;
-
- if (*paddr + sz - cxt->phys_addr > cxt->size) {
- dev_err(dev, "no room for %s mem region (0x%zx@0x%llx) in (0x%lx@0x%llx)\n",
- name, sz, (unsigned long long)*paddr,
- cxt->size, (unsigned long long)cxt->phys_addr);
- return -ENOMEM;
- }
-
- *prz = persistent_ram_new(*paddr, sz, sig, &cxt->ecc_info,
- cxt->memtype, 0);
- if (IS_ERR(*prz)) {
- int err = PTR_ERR(*prz);
-
- dev_err(dev, "failed to request %s mem region (0x%zx@0x%llx): %d\n",
- name, sz, (unsigned long long)*paddr, err);
- return err;
- }
-
- persistent_ram_zap(*prz);
-
- *paddr += sz;
-
- return 0;
+ return __ramoops_init_prz(name, dev, cxt, prz, paddr, sz, sig, 0, true);
}
static int ramoops_parse_dt_size(struct platform_device *pdev,
--
2.11.0
^ permalink raw reply related [flat|nested] 12+ messages in thread
* [PATCH v4 2nd 2/4] pstore: support multiple pmsg instances
2017-01-31 1:58 [PATCH v4 2nd 0/4] pstore: ramoops: support multiple pmsg instances Nobuhiro Iwamatsu
2017-01-31 1:58 ` [PATCH v4 2nd 1/4] ramoops: Add __ramoops_init_prz() as generic function Nobuhiro Iwamatsu
@ 2017-01-31 1:58 ` Nobuhiro Iwamatsu
2017-02-01 20:28 ` Kees Cook
2017-02-02 22:17 ` Mark Salyzyn
2017-01-31 1:58 ` [PATCH v4 2nd 3/4] ramoops: " Nobuhiro Iwamatsu
2017-01-31 1:58 ` [PATCH v4 2nd 4/4] selftests/pstore: add testcases for " Nobuhiro Iwamatsu
3 siblings, 2 replies; 12+ messages in thread
From: Nobuhiro Iwamatsu @ 2017-01-31 1:58 UTC (permalink / raw)
To: Anton Vorontsov, Colin Cross, Kees Cook, Tony Luck
Cc: linux-kernel, Hiraku Toyooka, Nobuhiro Iwamatsu, Mark Salyzyn,
Seiji Aguchi
From: Hiraku Toyooka <hiraku.toyooka.gu@hitachi.com>
This enables pmsg to deal with multiple instances. One possible
use is content priority control on limited persistent store space. By
using different buffers, we can prevent important messages from being
overwritten by less important messages.
When pstore backend module specifies the number of instances (num_pmsg)
in pstore_info, multiple /dev/pmsg[ID] appear. (ID is an integer
starting at 0. It corresponds to minor number of the each char device.)
Writes to each /dev/pmsg[ID] are isolated each other. After reboot, the
contents are available in /sys/fs/pstore/pmsg-[backend]-[ID].
Signed-off-by: Hiraku Toyooka <hiraku.toyooka.gu@hitachi.com>
Signed-off-by: Nobuhiro Iwamatsu <nobuhiro.iwamatsu.kw@hitachi.com>
Cc: Anton Vorontsov <anton@enomsg.org>
Cc: Colin Cross <ccross@android.com>
Cc: Kees Cook <keescook@chromium.org>
Cc: Mark Salyzyn <salyzyn@android.com>
Cc: Seiji Aguchi <seiji.aguchi.tr@hitachi.com>
Cc: Tony Luck <tony.luck@intel.com>
V4:
Rebase.
V3:
rebase.
merged device_create().
---
fs/pstore/pmsg.c | 23 ++++++++++++++++-------
include/linux/pstore.h | 1 +
2 files changed, 17 insertions(+), 7 deletions(-)
diff --git a/fs/pstore/pmsg.c b/fs/pstore/pmsg.c
index 78f6176c020f..5da5cba4b387 100644
--- a/fs/pstore/pmsg.c
+++ b/fs/pstore/pmsg.c
@@ -34,7 +34,8 @@ static ssize_t write_pmsg(struct file *file, const char __user *buf,
return -EFAULT;
mutex_lock(&pmsg_lock);
- ret = psinfo->write_buf_user(PSTORE_TYPE_PMSG, 0, &id, 0, buf, 0, count,
+ ret = psinfo->write_buf_user(PSTORE_TYPE_PMSG, 0, &id,
+ iminor(file->f_inode), buf, 0, count,
psinfo);
mutex_unlock(&pmsg_lock);
return ret ? ret : count;
@@ -61,7 +62,7 @@ static char *pmsg_devnode(struct device *dev, umode_t *mode)
void pstore_register_pmsg(void)
{
- struct device *pmsg_device;
+ int i;
pmsg_major = register_chrdev(0, PMSG_NAME, &pmsg_fops);
if (pmsg_major < 0) {
@@ -76,15 +77,23 @@ void pstore_register_pmsg(void)
}
pmsg_class->devnode = pmsg_devnode;
- pmsg_device = device_create(pmsg_class, NULL, MKDEV(pmsg_major, 0),
- NULL, "%s%d", PMSG_NAME, 0);
- if (IS_ERR(pmsg_device)) {
- pr_err("failed to create device\n");
- goto err_device;
+ /* allocate additional /dev/pmsg[ID] */
+ for (i = 0; i < psinfo->num_pmsg; i++) {
+ struct device *pmsg_device;
+
+ pmsg_device = device_create(pmsg_class, NULL,
+ MKDEV(pmsg_major, i), NULL, "%s%d",
+ PMSG_NAME, i);
+ if (IS_ERR(pmsg_device)) {
+ pr_err("failed to create device\n");
+ goto err_device;
+ }
}
return;
err_device:
+ for (i--; i >= 0; i--)
+ device_destroy(pmsg_class, MKDEV(pmsg_major, i));
class_destroy(pmsg_class);
err_class:
unregister_chrdev(pmsg_major, PMSG_NAME);
diff --git a/include/linux/pstore.h b/include/linux/pstore.h
index 0da29cae009b..7a5db4833b8a 100644
--- a/include/linux/pstore.h
+++ b/include/linux/pstore.h
@@ -55,6 +55,7 @@ struct pstore_info {
size_t bufsize;
struct mutex read_mutex; /* serialize open/read/close */
int flags;
+ unsigned int num_pmsg;
int (*open)(struct pstore_info *psi);
int (*close)(struct pstore_info *psi);
ssize_t (*read)(u64 *id, enum pstore_type_id *type,
--
2.11.0
^ permalink raw reply related [flat|nested] 12+ messages in thread
* [PATCH v4 2nd 3/4] ramoops: support multiple pmsg instances
2017-01-31 1:58 [PATCH v4 2nd 0/4] pstore: ramoops: support multiple pmsg instances Nobuhiro Iwamatsu
2017-01-31 1:58 ` [PATCH v4 2nd 1/4] ramoops: Add __ramoops_init_prz() as generic function Nobuhiro Iwamatsu
2017-01-31 1:58 ` [PATCH v4 2nd 2/4] pstore: support multiple pmsg instances Nobuhiro Iwamatsu
@ 2017-01-31 1:58 ` Nobuhiro Iwamatsu
2017-01-31 1:58 ` [PATCH v4 2nd 4/4] selftests/pstore: add testcases for " Nobuhiro Iwamatsu
3 siblings, 0 replies; 12+ messages in thread
From: Nobuhiro Iwamatsu @ 2017-01-31 1:58 UTC (permalink / raw)
To: Anton Vorontsov, Colin Cross, Kees Cook, Tony Luck
Cc: linux-kernel, Nobuhiro Iwamatsu, Hiraku Toyooka, Jonathan Corbet,
Mark Salyzyn, Seiji Aguchi
This enables ramoops to deal with multiple pmsg instances.
A User can configure the size of each buffers by its module parameter
as follows.
pmsg_size=0x1000,0x2000,...
Then, the ramoops allocates multiple buffers and tells the number
of buffers to pstore to create multiple /dev/pmsg[ID].
Signed-off-by: Hiraku Toyooka <hiraku.toyooka.gu@hitachi.com>
Signed-off-by: Nobuhiro Iwamatsu <nobuhiro.iwamatsu.kw@hitachi.com>
Cc: Jonathan Corbet <corbet@lwn.net>
Cc: Anton Vorontsov <anton@enomsg.org>
Cc: Colin Cross <ccross@android.com>
Cc: Kees Cook <keescook@chromium.org>
Cc: Mark Salyzyn <salyzyn@android.com>
Cc: Seiji Aguchi <seiji.aguchi.tr@hitachi.com>
Cc: Tony Luck <tony.luck@intel.com>
V4:
- Rebase.
V3:
- Rebase.
- Update documentiation of DT binding.
- Update parsing function of ramoops_pmsg_size, add NULL-terminated.
- Update module parameters for pmsg_size list.
---
Documentation/admin-guide/ramoops.rst | 22 ++
.../bindings/reserved-memory/ramoops.txt | 6 +-
fs/pstore/ram.c | 223 ++++++++++++++++++---
include/linux/pstore_ram.h | 8 +-
4 files changed, 231 insertions(+), 28 deletions(-)
diff --git a/Documentation/admin-guide/ramoops.rst b/Documentation/admin-guide/ramoops.rst
index 4efd7ce77565..611ee1d7d9ba 100644
--- a/Documentation/admin-guide/ramoops.rst
+++ b/Documentation/admin-guide/ramoops.rst
@@ -154,3 +154,25 @@ file. Here is an example of usage::
0 ffffffff811d9c54 ffffffff8101a7a0 __const_udelay <- native_machine_emergency_restart+0x110/0x1e0
0 ffffffff811d9c34 ffffffff811d9c80 __delay <- __const_udelay+0x30/0x40
0 ffffffff811d9d14 ffffffff811d9c3f delay_tsc <- __delay+0xf/0x20
+
+6. Pmsg support
+
+Ramoops supports pmsg - logging userspace mesages in persistent store. By
+default, one pmsg area becomes available in ramoops. You can write data into
+/dev/pmsg0, e.g.:
+
+ # echo foo > /dev/pmsg0
+
+After reboot, the stored data can be read from pmsg-ramoops-0 on the pstore
+filesystem.
+
+You can specify size of the pmsg area by additional kernel command line, e.g.:
+
+ "ramoops.pmsg_size=0x1000"
+
+You can also use multiple pmsg areas, e.g.:
+
+ "ramoops.pmsg_size=0x1000,0x2000,..."
+
+Then, pmsg0, pmsg1, ... will appear on /dev. This is useful to control
+individual content aging or priority.
diff --git a/Documentation/devicetree/bindings/reserved-memory/ramoops.txt b/Documentation/devicetree/bindings/reserved-memory/ramoops.txt
index 0eba562fe5c6..e270221b98df 100644
--- a/Documentation/devicetree/bindings/reserved-memory/ramoops.txt
+++ b/Documentation/devicetree/bindings/reserved-memory/ramoops.txt
@@ -39,7 +39,11 @@ Optional properties:
- ftrace-size: size in bytes of log buffer reserved for function tracing and
profiling (defaults to 0: disabled)
-- pmsg-size: size in bytes of log buffer reserved for userspace messages
+- pmsg-size: array of value that are used to size in bytes of log buffer
+ reserved for userspace messages.
+
+ pmsg-size = <0x10000 0x10000>;
+
(defaults to 0: disabled)
- unbuffered: if present, use unbuffered mappings to map the reserved region
diff --git a/fs/pstore/ram.c b/fs/pstore/ram.c
index 72072e8123e3..50bc78aff6b8 100644
--- a/fs/pstore/ram.c
+++ b/fs/pstore/ram.c
@@ -53,8 +53,8 @@ static ulong ramoops_ftrace_size = MIN_MEM_SIZE;
module_param_named(ftrace_size, ramoops_ftrace_size, ulong, 0400);
MODULE_PARM_DESC(ftrace_size, "size of ftrace log");
-static ulong ramoops_pmsg_size = MIN_MEM_SIZE;
-module_param_named(pmsg_size, ramoops_pmsg_size, ulong, 0400);
+static char *ramoops_pmsg_size_str;
+module_param_named(pmsg_size, ramoops_pmsg_size_str, charp, 0400);
MODULE_PARM_DESC(pmsg_size, "size of user space message log");
static unsigned long long mem_address;
@@ -88,14 +88,14 @@ struct ramoops_context {
struct persistent_ram_zone **dprzs; /* Oops dump zones */
struct persistent_ram_zone *cprz; /* Console zone */
struct persistent_ram_zone **fprzs; /* Ftrace zones */
- struct persistent_ram_zone *mprz; /* PMSG zone */
+ struct persistent_ram_zone **mprzs; /* PMSG zone */
phys_addr_t phys_addr;
unsigned long size;
unsigned int memtype;
size_t record_size;
size_t console_size;
size_t ftrace_size;
- size_t pmsg_size;
+ size_t *pmsg_size;
int dump_oops;
u32 flags;
struct persistent_ram_ecc_info ecc_info;
@@ -275,9 +275,11 @@ static ssize_t ramoops_pstore_read(u64 *id, enum pstore_type_id *type,
prz = ramoops_get_next_prz(&cxt->cprz, &cxt->console_read_cnt,
1, id, type, PSTORE_TYPE_CONSOLE, 0);
- if (!prz_ok(prz))
- prz = ramoops_get_next_prz(&cxt->mprz, &cxt->pmsg_read_cnt,
- 1, id, type, PSTORE_TYPE_PMSG, 0);
+ while (cxt->pmsg_read_cnt < cxt->pstore.num_pmsg && !prz_ok(prz))
+ /* get pmsg prz */
+ prz = ramoops_get_next_prz(cxt->mprzs, &cxt->pmsg_read_cnt,
+ cxt->pstore.num_pmsg, id, type,
+ PSTORE_TYPE_PMSG, 0);
/* ftrace is last since it may want to dynamically allocate memory. */
if (!prz_ok(prz)) {
@@ -455,9 +457,9 @@ static int notrace ramoops_pstore_write_buf_user(enum pstore_type_id type,
if (type == PSTORE_TYPE_PMSG) {
struct ramoops_context *cxt = psi->data;
- if (!cxt->mprz)
+ if (!cxt->mprzs)
return -ENOMEM;
- return persistent_ram_write_user(cxt->mprz, buf, size);
+ return persistent_ram_write_user(cxt->mprzs[part], buf, size);
}
return -EINVAL;
@@ -484,7 +486,9 @@ static int ramoops_pstore_erase(enum pstore_type_id type, u64 id, int count,
prz = cxt->fprzs[id];
break;
case PSTORE_TYPE_PMSG:
- prz = cxt->mprz;
+ if (id >= cxt->pstore.num_pmsg)
+ return -EINVAL;
+ prz = cxt->mprzs[id];
break;
default:
return -EINVAL;
@@ -634,6 +638,40 @@ static int ramoops_init_przs(const char *name,
return err;
}
+/* int function for pmsg przs */
+static int ramoops_init_mprzs(const char *name,
+ struct device *dev, struct ramoops_context *cxt,
+ phys_addr_t *paddr, unsigned long total)
+{
+ int err = -ENOMEM;
+ int i;
+
+ if (!total)
+ return 0;
+
+ if (*paddr + total - cxt->phys_addr > cxt->size) {
+ dev_err(dev, "no room for pmsg\n");
+ return -ENOMEM;
+ }
+
+ cxt->mprzs = kcalloc(cxt->pstore.num_pmsg, sizeof(*cxt->mprzs),
+ GFP_KERNEL);
+ if (!cxt->mprzs)
+ return -ENOMEM;
+
+ for (i = 0; i < cxt->pstore.num_pmsg; i++) {
+ err = __ramoops_init_prz(name, dev, cxt, &cxt->mprzs[i], paddr,
+ cxt->pmsg_size[i], 0, 0, true);
+ if (err)
+ goto fail_mprz;
+ }
+
+ return 0;
+fail_mprz:
+ ramoops_free_przs(cxt->mprzs);
+ return err;
+}
+
static int ramoops_init_prz(const char *name,
struct device *dev, struct ramoops_context *cxt,
struct persistent_ram_zone **prz,
@@ -670,7 +708,8 @@ static int ramoops_parse_dt(struct platform_device *pdev,
struct device_node *of_node = pdev->dev.of_node;
struct resource *res;
u32 value;
- int ret;
+ int ret, i;
+ unsigned int num_pmsg;
dev_dbg(&pdev->dev, "using Device Tree\n");
@@ -696,12 +735,71 @@ static int ramoops_parse_dt(struct platform_device *pdev,
parse_size("record-size", pdata->record_size);
parse_size("console-size", pdata->console_size);
parse_size("ftrace-size", pdata->ftrace_size);
- parse_size("pmsg-size", pdata->pmsg_size);
parse_size("ecc-size", pdata->ecc_info.ecc_size);
parse_size("flags", pdata->flags);
#undef parse_size
+ /* Parse pmesg size */
+ if (!of_find_property(of_node, "pmsg-size", &num_pmsg))
+ return 0; /* no data */
+
+ num_pmsg = num_pmsg / sizeof(u32);
+
+ pdata->pmsg_size =
+ devm_kzalloc(&pdev->dev, sizeof(size_t) * (num_pmsg + 1),
+ GFP_KERNEL);
+ if (!pdata->pmsg_size)
+ return -ENOMEM;
+
+ for (i = 0; i < num_pmsg; i++) {
+ ret = of_property_read_u32_index(of_node, "pmsg-size",
+ i, &value);
+ if (ret) {
+ dev_warn(&pdev->dev,
+ "%s: failed to read pmsg-size[%d]: %d\n",
+ __func__, i, ret);
+ return -EINVAL;
+ }
+
+ /* CHECK INT_MAX */
+ if (value > INT_MAX) {
+ dev_err(&pdev->dev, "value %x > INT_MAX\n", value);
+ return -EOVERFLOW;
+ }
+ pdata->pmsg_size[i] = value;
+ }
+
+ return 0;
+}
+
+#define ADDR_STRING_SIZE 10 /* "0x00000000" */
+static int update_pmsg_size_mod_param(size_t *pmsg_size, int num)
+{
+ int i, len;
+
+ /* string size + commas count + NULL-terminated */
+ len = ADDR_STRING_SIZE * num + (num - 1) + 1;
+
+ /* using commandline or already allocation buffer.*/
+ if (ramoops_pmsg_size_str)
+ goto out;
+
+ ramoops_pmsg_size_str = kzalloc(len, GFP_KERNEL);
+ if (!ramoops_pmsg_size_str)
+ return -ENOMEM;
+
+ for (i = 0 ; i < num; i++) {
+ char str[ADDR_STRING_SIZE + 1];
+
+ memset(str, 0, sizeof(str));
+ if (i == num - 1)
+ snprintf(str, sizeof(str), "0x%x", pmsg_size[i]);
+ else
+ snprintf(str, sizeof(str), "0x%x,", pmsg_size[i]);
+ strcat(ramoops_pmsg_size_str, str);
+ }
+out:
return 0;
}
@@ -713,6 +811,8 @@ static int ramoops_probe(struct platform_device *pdev)
size_t dump_mem_sz;
phys_addr_t paddr;
int err = -EINVAL;
+ unsigned long pmsg_size_total = 0;
+ unsigned int num_pmsg = 0;
if (dev_of_node(dev) && !pdata) {
pdata = devm_kzalloc(&pdev->dev, sizeof(*pdata), GFP_KERNEL);
@@ -755,8 +855,20 @@ static int ramoops_probe(struct platform_device *pdev)
pdata->console_size = rounddown_pow_of_two(pdata->console_size);
if (pdata->ftrace_size && !is_power_of_2(pdata->ftrace_size))
pdata->ftrace_size = rounddown_pow_of_two(pdata->ftrace_size);
- if (pdata->pmsg_size && !is_power_of_2(pdata->pmsg_size))
- pdata->pmsg_size = rounddown_pow_of_two(pdata->pmsg_size);
+
+ if (pdata->pmsg_size) {
+ for (;; num_pmsg++) {
+ unsigned long size = pdata->pmsg_size[num_pmsg];
+
+ if (!size)
+ break;
+
+ if (!is_power_of_2(size))
+ pdata->pmsg_size[num_pmsg]
+ = rounddown_pow_of_two(size);
+ pmsg_size_total += size;
+ }
+ }
cxt->size = pdata->mem_size;
cxt->phys_addr = pdata->mem_address;
@@ -764,20 +876,29 @@ static int ramoops_probe(struct platform_device *pdev)
cxt->record_size = pdata->record_size;
cxt->console_size = pdata->console_size;
cxt->ftrace_size = pdata->ftrace_size;
- cxt->pmsg_size = pdata->pmsg_size;
cxt->dump_oops = pdata->dump_oops;
cxt->flags = pdata->flags;
cxt->ecc_info = pdata->ecc_info;
+ cxt->pstore.num_pmsg = num_pmsg;
- paddr = cxt->phys_addr;
+ if (num_pmsg) {
+ cxt->pmsg_size = kcalloc(num_pmsg, sizeof(size_t), GFP_KERNEL);
+ if (!cxt->pmsg_size) {
+ err = -ENOMEM;
+ goto fail_out;
+ }
+ memcpy(cxt->pmsg_size, pdata->pmsg_size,
+ sizeof(size_t) * num_pmsg);
+ }
+ paddr = cxt->phys_addr;
dump_mem_sz = cxt->size - cxt->console_size - cxt->ftrace_size
- - cxt->pmsg_size;
+ - pmsg_size_total;
err = ramoops_init_przs("dump", dev, cxt, &cxt->dprzs, &paddr,
dump_mem_sz, cxt->record_size,
&cxt->max_dump_cnt, 0, 0);
if (err)
- goto fail_out;
+ goto fail_init_dprzs;
err = ramoops_init_prz("console", dev, cxt, &cxt->cprz, &paddr,
cxt->console_size, 0);
@@ -795,10 +916,9 @@ static int ramoops_probe(struct platform_device *pdev)
if (err)
goto fail_init_fprz;
- err = ramoops_init_prz("pmsg", dev, cxt, &cxt->mprz, &paddr,
- cxt->pmsg_size, 0);
+ err = ramoops_init_mprzs("pmsg", dev, cxt, &paddr, pmsg_size_total);
if (err)
- goto fail_init_mprz;
+ goto fail_init_mprzs;
cxt->pstore.data = cxt;
/*
@@ -841,8 +961,8 @@ static int ramoops_probe(struct platform_device *pdev)
record_size = pdata->record_size;
dump_oops = pdata->dump_oops;
ramoops_console_size = pdata->console_size;
- ramoops_pmsg_size = pdata->pmsg_size;
ramoops_ftrace_size = pdata->ftrace_size;
+ update_pmsg_size_mod_param(cxt->pmsg_size, cxt->pstore.num_pmsg);
pr_info("attached 0x%lx@0x%llx, ecc: %d/%d\n",
cxt->size, (unsigned long long)cxt->phys_addr,
@@ -854,8 +974,8 @@ static int ramoops_probe(struct platform_device *pdev)
kfree(cxt->pstore.buf);
fail_clear:
cxt->pstore.bufsize = 0;
- persistent_ram_free(cxt->mprz);
-fail_init_mprz:
+ ramoops_free_przs(cxt->mprzs);
+fail_init_mprzs:
cxt->max_ftrace_cnt = 0;
ramoops_free_przs(cxt->fprzs);
fail_init_fprz:
@@ -863,6 +983,8 @@ static int ramoops_probe(struct platform_device *pdev)
fail_init_cprz:
cxt->max_dump_cnt = 0;
ramoops_free_przs(cxt->dprzs);
+fail_init_dprzs:
+ kfree(cxt->pmsg_size);
fail_out:
return err;
}
@@ -875,8 +997,10 @@ static int ramoops_remove(struct platform_device *pdev)
kfree(cxt->pstore.buf);
cxt->pstore.bufsize = 0;
+ kfree(cxt->pmsg_size);
- persistent_ram_free(cxt->mprz);
+ ramoops_free_przs(cxt->mprzs);
+ cxt->pstore.num_pmsg = 0;
persistent_ram_free(cxt->cprz);
/* Free ftrace PRZs */
@@ -903,6 +1027,43 @@ static struct platform_driver ramoops_driver = {
},
};
+static unsigned long *parse_size_str(char *size_str)
+{
+ int i, ret;
+ unsigned long *size_array, count = 1;
+
+ if (size_str) {
+ char *s = size_str;
+
+ /* Necessary array size is the number of commas + 1 */
+ for (; (s = strchr(s, ',')); s++)
+ count++;
+ }
+
+ /* Add NULL-terminated */
+ count++;
+
+ size_array = kcalloc(count, sizeof(unsigned long), GFP_KERNEL);
+ if (!size_array)
+ goto out;
+
+ if (size_str) {
+ for (i = 0; i < count; i++) {
+ ret = get_option(&size_str, (int *)&size_array[i]);
+ if (ret == 1)
+ break;
+ else if (ret != 2) {
+ size_array[i] = 0;
+ break;
+ }
+ }
+ } else
+ size_array[0] = MIN_MEM_SIZE;
+
+out:
+ return size_array;
+}
+
static void ramoops_register_dummy(void)
{
if (!mem_size)
@@ -922,7 +1083,10 @@ static void ramoops_register_dummy(void)
dummy_data->record_size = record_size;
dummy_data->console_size = ramoops_console_size;
dummy_data->ftrace_size = ramoops_ftrace_size;
- dummy_data->pmsg_size = ramoops_pmsg_size;
+ dummy_data->pmsg_size = parse_size_str(ramoops_pmsg_size_str);
+
+ if (!dummy_data->pmsg_size)
+ goto fail_pmsg_size;
dummy_data->dump_oops = dump_oops;
dummy_data->flags = RAMOOPS_FLAG_FTRACE_PER_CPU;
@@ -937,7 +1101,13 @@ static void ramoops_register_dummy(void)
if (IS_ERR(dummy)) {
pr_info("could not create platform device: %ld\n",
PTR_ERR(dummy));
+ goto fail_pdev;
}
+ return;
+fail_pdev:
+ kfree(dummy_data->pmsg_size);
+fail_pmsg_size:
+ kfree(dummy_data);
}
static int __init ramoops_init(void)
@@ -951,6 +1121,7 @@ static void __exit ramoops_exit(void)
{
platform_driver_unregister(&ramoops_driver);
platform_device_unregister(dummy);
+ kfree(dummy_data->pmsg_size);
kfree(dummy_data);
}
module_exit(ramoops_exit);
diff --git a/include/linux/pstore_ram.h b/include/linux/pstore_ram.h
index 9395f06e8372..030fa45af2bf 100644
--- a/include/linux/pstore_ram.h
+++ b/include/linux/pstore_ram.h
@@ -84,6 +84,12 @@ ssize_t persistent_ram_ecc_string(struct persistent_ram_zone *prz,
* Ramoops platform data
* @mem_size memory size for ramoops
* @mem_address physical memory address to contain ramoops
+ * @pmsg_size array containing size of each pmsg area. 0 value in the array
+ * indicates the end of the content. For example, if the following
+ * array is given,
+ * .pmsg_size = { 0x1000, 0x2000, 0x0, 0x3000, };
+ * then, pmsg areas are allocated for the first two size values
+ * and '0x3000' is just ignored.
*/
#define RAMOOPS_FLAG_FTRACE_PER_CPU BIT(0)
@@ -95,7 +101,7 @@ struct ramoops_platform_data {
unsigned long record_size;
unsigned long console_size;
unsigned long ftrace_size;
- unsigned long pmsg_size;
+ unsigned long *pmsg_size;
int dump_oops;
u32 flags;
struct persistent_ram_ecc_info ecc_info;
--
2.11.0
^ permalink raw reply related [flat|nested] 12+ messages in thread
* [PATCH v4 2nd 4/4] selftests/pstore: add testcases for multiple pmsg instances
2017-01-31 1:58 [PATCH v4 2nd 0/4] pstore: ramoops: support multiple pmsg instances Nobuhiro Iwamatsu
` (2 preceding siblings ...)
2017-01-31 1:58 ` [PATCH v4 2nd 3/4] ramoops: " Nobuhiro Iwamatsu
@ 2017-01-31 1:58 ` Nobuhiro Iwamatsu
3 siblings, 0 replies; 12+ messages in thread
From: Nobuhiro Iwamatsu @ 2017-01-31 1:58 UTC (permalink / raw)
To: Anton Vorontsov, Colin Cross, Kees Cook, Tony Luck
Cc: linux-kernel, Hiraku Toyooka, Nobuhiro Iwamatsu, Mark Salyzyn,
Seiji Aguchi, Shuah Khan
From: Hiraku Toyooka <hiraku.toyooka.gu@hitachi.com>
To test multiple pmsg, we should check that /dev/pmsg[N] (N > 0) is
available. After reboot, we should check that pmsg-[backend]-[N] which
keeps content is detected even if pmsg-[backend]-[N-M] (0 < M <= N)
doesn't exist due to lack of contents.
So this adds the following testcases.
- pstore_tests
- Write unique string to the last /dev/pmsgN
- pstore_post_reboot_tests
- Check the last pmsg area is detected
Signed-off-by: Hiraku Toyooka <hiraku.toyooka.gu@hitachi.com>
Signed-off-by: Nobuhiro Iwamatsu <nobuhiro.iwamatsu.kw@hitachi.com>
Cc: Anton Vorontsov <anton@enomsg.org>
Cc: Colin Cross <ccross@android.com>
Cc: Kees Cook <keescook@chromium.org>
Cc: Mark Salyzyn <salyzyn@android.com>
Cc: Seiji Aguchi <seiji.aguchi.tr@hitachi.com>
Cc: Shuah Khan <shuahkh@osg.samsung.com>
Cc: Tony Luck <tony.luck@intel.com>
V4:
Rebase.
V3:
Rebase.
V2:
Remove Blank lines.
---
tools/testing/selftests/pstore/common_tests | 21 +++++++++++++++--
.../selftests/pstore/pstore_post_reboot_tests | 27 ++++++++++++----------
tools/testing/selftests/pstore/pstore_tests | 14 ++++++++---
3 files changed, 45 insertions(+), 17 deletions(-)
diff --git a/tools/testing/selftests/pstore/common_tests b/tools/testing/selftests/pstore/common_tests
index 3ea64d7cf1cd..566a25d10350 100755
--- a/tools/testing/selftests/pstore/common_tests
+++ b/tools/testing/selftests/pstore/common_tests
@@ -27,9 +27,9 @@ show_result() { # result_value
}
check_files_exist() { # type of pstorefs file
- if [ -e ${1}-${backend}-0 ]; then
+ if [ -e ${1}0 ]; then
prlog "ok"
- for f in `ls ${1}-${backend}-*`; do
+ for f in `ls ${1}*`; do
prlog -e "\t${f}"
done
else
@@ -53,6 +53,23 @@ operate_files() { # tested value, files, operation
fi
}
+check_pmsg_content() { # pmsg filename
+ prev_uuid=`cat $TOP_DIR/prev_uuid`
+ if [ $? -eq 0 ]; then
+ nr_matched=`grep -c "$TEST_STRING_PATTERN" $1`
+ if [ "$nr_matched" = "1" ]; then
+ grep -q "$TEST_STRING_PATTERN"$prev_uuid $1
+ show_result $?
+ else
+ prlog "FAIL"
+ rc=1
+ fi
+ else
+ prlog "FAIL"
+ rc=1
+ fi
+}
+
# Parameters
TEST_STRING_PATTERN="Testing pstore: uuid="
UUID=`cat /proc/sys/kernel/random/uuid`
diff --git a/tools/testing/selftests/pstore/pstore_post_reboot_tests b/tools/testing/selftests/pstore/pstore_post_reboot_tests
index 6ccb154cb4aa..272498fa9281 100755
--- a/tools/testing/selftests/pstore/pstore_post_reboot_tests
+++ b/tools/testing/selftests/pstore/pstore_post_reboot_tests
@@ -35,13 +35,13 @@ fi
cd ${mount_point}
prlog -n "Checking dmesg files exist in pstore filesystem ... "
-check_files_exist dmesg
+check_files_exist dmesg-${backend}-
prlog -n "Checking console files exist in pstore filesystem ... "
-check_files_exist console
+check_files_exist console-${backend}-
prlog -n "Checking pmsg files exist in pstore filesystem ... "
-check_files_exist pmsg
+check_files_exist pmsg-${backend}-
prlog -n "Checking dmesg files contain oops end marker"
grep_end_trace() {
@@ -54,16 +54,19 @@ prlog -n "Checking console file contains oops end marker ... "
grep -q "\---\[ end trace" console-${backend}-0
show_result $?
-prlog -n "Checking pmsg file properly keeps the content written before crash ... "
-prev_uuid=`cat $TOP_DIR/prev_uuid`
-if [ $? -eq 0 ]; then
- nr_matched=`grep -c "$TEST_STRING_PATTERN" pmsg-${backend}-0`
- if [ $nr_matched -eq 1 ]; then
- grep -q "$TEST_STRING_PATTERN"$prev_uuid pmsg-${backend}-0
- show_result $?
+prlog -n "Checking pmsg-"${backend}"-0 properly keeps the content written before crash ... "
+check_pmsg_content pmsg-${backend}-0
+
+prlog -n "Checking the last pmsg area is detected "
+last_num_pmsg=`ls -v pmsg-* | tail -n1 | sed -e "s/^pmsg-${backend}-\([0-9]*\).*$/\1/"`
+last_num_devpmsg=`ls -v /dev/pmsg* | tail -n1 | sed -e "s/^\/dev\/pmsg\([0-9]*\).*$/\1/"`
+#checks the last number of pmsg-*-* and /dev/pmsg* correspond.
+if [ "$last_num_pmsg" -eq "$last_num_devpmsg" ]; then
+ if [ "$last_num_pmsg" = "0" ]; then
+ prlog "... No multiple pmsg-*-* exists. We skip this testcase."
else
- prlog "FAIL"
- rc=1
+ prlog -n "(pmsg-${backend}-${last_num_pmsg}) ... "
+ check_pmsg_content pmsg-${backend}-${last_num_pmsg}
fi
else
prlog "FAIL"
diff --git a/tools/testing/selftests/pstore/pstore_tests b/tools/testing/selftests/pstore/pstore_tests
index f25d2a349a60..b74b3afb9722 100755
--- a/tools/testing/selftests/pstore/pstore_tests
+++ b/tools/testing/selftests/pstore/pstore_tests
@@ -13,9 +13,8 @@ prlog -n "Checking pstore console is registered ... "
dmesg | grep -q "console \[pstore"
show_result $?
-prlog -n "Checking /dev/pmsg0 exists ... "
-test -e /dev/pmsg0
-show_result $?
+prlog -n "Checking /dev/pmsg files exist ... "
+check_files_exist /dev/pmsg
prlog -n "Writing unique string to /dev/pmsg0 ... "
if [ -e "/dev/pmsg0" ]; then
@@ -27,4 +26,13 @@ else
rc=1
fi
+last_devpmsg=`ls -v /dev/pmsg* | tail -n1`
+prlog -n "Writing unique string to the last /dev/pmsgN "
+if [ "$last_devpmsg" = "/dev/pmsg0" ]; then
+ prlog "... No multiple /dev/pmsg* exists. We skip this testcase."
+else
+ prlog -n "(${last_devpmsg}) ... "
+ echo "${TEST_STRING_PATTERN}""$UUID" > ${last_devpmsg}
+ show_result $?
+fi
exit $rc
--
2.11.0
^ permalink raw reply related [flat|nested] 12+ messages in thread
* Re: [PATCH v4 2nd 2/4] pstore: support multiple pmsg instances
2017-01-31 1:58 ` [PATCH v4 2nd 2/4] pstore: support multiple pmsg instances Nobuhiro Iwamatsu
@ 2017-02-01 20:28 ` Kees Cook
2017-02-07 8:44 ` 岩松信洋 / IWAMATSU,NOBUHIRO
2017-02-02 22:17 ` Mark Salyzyn
1 sibling, 1 reply; 12+ messages in thread
From: Kees Cook @ 2017-02-01 20:28 UTC (permalink / raw)
To: Nobuhiro Iwamatsu
Cc: Anton Vorontsov, Colin Cross, Tony Luck, LKML, Hiraku Toyooka,
Mark Salyzyn, Seiji Aguchi
On Mon, Jan 30, 2017 at 5:58 PM, Nobuhiro Iwamatsu
<nobuhiro.iwamatsu.kw@hitachi.com> wrote:
> From: Hiraku Toyooka <hiraku.toyooka.gu@hitachi.com>
>
> This enables pmsg to deal with multiple instances. One possible
> use is content priority control on limited persistent store space. By
> using different buffers, we can prevent important messages from being
> overwritten by less important messages.
>
> When pstore backend module specifies the number of instances (num_pmsg)
> in pstore_info, multiple /dev/pmsg[ID] appear. (ID is an integer
> starting at 0. It corresponds to minor number of the each char device.)
> Writes to each /dev/pmsg[ID] are isolated each other. After reboot, the
> contents are available in /sys/fs/pstore/pmsg-[backend]-[ID].
>
> Signed-off-by: Hiraku Toyooka <hiraku.toyooka.gu@hitachi.com>
> Signed-off-by: Nobuhiro Iwamatsu <nobuhiro.iwamatsu.kw@hitachi.com>
> Cc: Anton Vorontsov <anton@enomsg.org>
> Cc: Colin Cross <ccross@android.com>
> Cc: Kees Cook <keescook@chromium.org>
> Cc: Mark Salyzyn <salyzyn@android.com>
> Cc: Seiji Aguchi <seiji.aguchi.tr@hitachi.com>
> Cc: Tony Luck <tony.luck@intel.com>
>
> V4:
> Rebase.
> V3:
> rebase.
> merged device_create().
> ---
> fs/pstore/pmsg.c | 23 ++++++++++++++++-------
> include/linux/pstore.h | 1 +
> 2 files changed, 17 insertions(+), 7 deletions(-)
>
> diff --git a/fs/pstore/pmsg.c b/fs/pstore/pmsg.c
> index 78f6176c020f..5da5cba4b387 100644
> --- a/fs/pstore/pmsg.c
> +++ b/fs/pstore/pmsg.c
> @@ -34,7 +34,8 @@ static ssize_t write_pmsg(struct file *file, const char __user *buf,
> return -EFAULT;
>
> mutex_lock(&pmsg_lock);
> - ret = psinfo->write_buf_user(PSTORE_TYPE_PMSG, 0, &id, 0, buf, 0, count,
> + ret = psinfo->write_buf_user(PSTORE_TYPE_PMSG, 0, &id,
> + iminor(file->f_inode), buf, 0, count,
> psinfo);
> mutex_unlock(&pmsg_lock);
> return ret ? ret : count;
> @@ -61,7 +62,7 @@ static char *pmsg_devnode(struct device *dev, umode_t *mode)
>
> void pstore_register_pmsg(void)
> {
> - struct device *pmsg_device;
> + int i;
>
> pmsg_major = register_chrdev(0, PMSG_NAME, &pmsg_fops);
> if (pmsg_major < 0) {
> @@ -76,15 +77,23 @@ void pstore_register_pmsg(void)
> }
> pmsg_class->devnode = pmsg_devnode;
>
> - pmsg_device = device_create(pmsg_class, NULL, MKDEV(pmsg_major, 0),
> - NULL, "%s%d", PMSG_NAME, 0);
> - if (IS_ERR(pmsg_device)) {
> - pr_err("failed to create device\n");
> - goto err_device;
> + /* allocate additional /dev/pmsg[ID] */
This isn't "additional" any more, but rather "Allocate each pmsg
device" or something.
> + for (i = 0; i < psinfo->num_pmsg; i++) {
> + struct device *pmsg_device;
> +
> + pmsg_device = device_create(pmsg_class, NULL,
> + MKDEV(pmsg_major, i), NULL, "%s%d",
> + PMSG_NAME, i);
> + if (IS_ERR(pmsg_device)) {
> + pr_err("failed to create device\n");
> + goto err_device;
> + }
> }
> return;
>
> err_device:
> + for (i--; i >= 0; i--)
> + device_destroy(pmsg_class, MKDEV(pmsg_major, i));
> class_destroy(pmsg_class);
> err_class:
> unregister_chrdev(pmsg_major, PMSG_NAME);
> diff --git a/include/linux/pstore.h b/include/linux/pstore.h
> index 0da29cae009b..7a5db4833b8a 100644
> --- a/include/linux/pstore.h
> +++ b/include/linux/pstore.h
> @@ -55,6 +55,7 @@ struct pstore_info {
> size_t bufsize;
> struct mutex read_mutex; /* serialize open/read/close */
> int flags;
> + unsigned int num_pmsg;
Something in this patch needs to set num_pmsg to 1 unconditionally, so
that bisectability is retained. I.e. after this patch, I should still
get a /dev/pmsg0 device. Right now, it will be skipped since num_pmsg
will always == 0.
> int (*open)(struct pstore_info *psi);
> int (*close)(struct pstore_info *psi);
> ssize_t (*read)(u64 *id, enum pstore_type_id *type,
> --
> 2.11.0
>
Thanks for the rebasing!
-Kees
--
Kees Cook
Pixel Security
^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: [PATCH v4 2nd 1/4] ramoops: Add __ramoops_init_prz() as generic function
2017-01-31 1:58 ` [PATCH v4 2nd 1/4] ramoops: Add __ramoops_init_prz() as generic function Nobuhiro Iwamatsu
@ 2017-02-02 22:13 ` Mark Salyzyn
2017-02-07 8:51 ` 岩松信洋 / IWAMATSU,NOBUHIRO
0 siblings, 1 reply; 12+ messages in thread
From: Mark Salyzyn @ 2017-02-02 22:13 UTC (permalink / raw)
To: Nobuhiro Iwamatsu, Anton Vorontsov, Colin Cross, Kees Cook, Tony Luck
Cc: linux-kernel, Hiraku Toyooka, Seiji Aguchi, Shuah Khan
On 01/30/2017 05:58 PM, Nobuhiro Iwamatsu wrote:
> +
> + if (zap && *paddr + sz - cxt->phys_addr > cxt->size) {
> + dev_err(dev, "no room for %s mem region (0x%zx@0x%llx) in (0x%lx@0x%llx)\n",
> + name, sz, (unsigned long long)*paddr,
> + cxt->size, (unsigned long long)cxt->phys_addr);
> + return -ENOMEM;
> + }
> +
Why not allow this limit check for ramoops_init_prsz call?
-- Mark
^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: [PATCH v4 2nd 2/4] pstore: support multiple pmsg instances
2017-01-31 1:58 ` [PATCH v4 2nd 2/4] pstore: support multiple pmsg instances Nobuhiro Iwamatsu
2017-02-01 20:28 ` Kees Cook
@ 2017-02-02 22:17 ` Mark Salyzyn
2017-02-07 8:47 ` 岩松信洋 / IWAMATSU,NOBUHIRO
1 sibling, 1 reply; 12+ messages in thread
From: Mark Salyzyn @ 2017-02-02 22:17 UTC (permalink / raw)
To: Nobuhiro Iwamatsu, Anton Vorontsov, Colin Cross, Kees Cook, Tony Luck
Cc: linux-kernel, Hiraku Toyooka, Seiji Aguchi
On 01/30/2017 05:58 PM, Nobuhiro Iwamatsu wrote:
> diff --git a/include/linux/pstore.h b/include/linux/pstore.h
> index 0da29cae009b..7a5db4833b8a 100644
> --- a/include/linux/pstore.h
> +++ b/include/linux/pstore.h
> @@ -55,6 +55,7 @@ struct pstore_info {
> size_t bufsize;
> struct mutex read_mutex; /* serialize open/read/close */
> int flags;
> + unsigned int num_pmsg;
> int (*open)(struct pstore_info *psi);
> int (*close)(struct pstore_info *psi);
> ssize_t (*read)(u64 *id, enum pstore_type_id *type,
Before patch there was an implication that num_pmsg was 1, after patch
calloc leaves this at a value of 0. Please reconcile the functional
difference that this causes.
-- Mark
^ permalink raw reply [flat|nested] 12+ messages in thread
* RE: [PATCH v4 2nd 2/4] pstore: support multiple pmsg instances
2017-02-01 20:28 ` Kees Cook
@ 2017-02-07 8:44 ` 岩松信洋 / IWAMATSU,NOBUHIRO
0 siblings, 0 replies; 12+ messages in thread
From: 岩松信洋 / IWAMATSU,NOBUHIRO @ 2017-02-07 8:44 UTC (permalink / raw)
To: Kees Cook
Cc: Anton Vorontsov, Colin Cross, Tony Luck, LKML, Mark Salyzyn,
阿口誠司 / AGUCHI,SEIJI
Hi,
Thanks for your review.
> -----Original Message-----
> From: keescook@google.com [mailto:keescook@google.com] On Behalf Of Kees
> Cook
> Sent: Thursday, February 02, 2017 5:29 AM
> To: 岩松信洋 / IWAMATSU,NOBUHIRO
> Cc: Anton Vorontsov; Colin Cross; Tony Luck; LKML; Hiraku Toyooka; Mark
> Salyzyn; 阿口誠司 / AGUCHI,SEIJI
> Subject: Re: [PATCH v4 2nd 2/4] pstore: support multiple pmsg instances
>
> On Mon, Jan 30, 2017 at 5:58 PM, Nobuhiro Iwamatsu
> <nobuhiro.iwamatsu.kw@hitachi.com> wrote:
> > From: Hiraku Toyooka <hiraku.toyooka.gu@hitachi.com>
> >
> > This enables pmsg to deal with multiple instances. One possible use is
> > content priority control on limited persistent store space. By using
> > different buffers, we can prevent important messages from being
> > overwritten by less important messages.
> >
> > When pstore backend module specifies the number of instances
> > (num_pmsg) in pstore_info, multiple /dev/pmsg[ID] appear. (ID is an
> > integer starting at 0. It corresponds to minor number of the each char
> > device.) Writes to each /dev/pmsg[ID] are isolated each other. After
> > reboot, the contents are available in
> /sys/fs/pstore/pmsg-[backend]-[ID].
> >
> > Signed-off-by: Hiraku Toyooka <hiraku.toyooka.gu@hitachi.com>
> > Signed-off-by: Nobuhiro Iwamatsu <nobuhiro.iwamatsu.kw@hitachi.com>
> > Cc: Anton Vorontsov <anton@enomsg.org>
> > Cc: Colin Cross <ccross@android.com>
> > Cc: Kees Cook <keescook@chromium.org>
> > Cc: Mark Salyzyn <salyzyn@android.com>
> > Cc: Seiji Aguchi <seiji.aguchi.tr@hitachi.com>
> > Cc: Tony Luck <tony.luck@intel.com>
> >
> > V4:
> > Rebase.
> > V3:
> > rebase.
> > merged device_create().
> > ---
> > fs/pstore/pmsg.c | 23 ++++++++++++++++-------
> > include/linux/pstore.h | 1 +
> > 2 files changed, 17 insertions(+), 7 deletions(-)
> >
> > diff --git a/fs/pstore/pmsg.c b/fs/pstore/pmsg.c index
> > 78f6176c020f..5da5cba4b387 100644
> > --- a/fs/pstore/pmsg.c
> > +++ b/fs/pstore/pmsg.c
> > @@ -34,7 +34,8 @@ static ssize_t write_pmsg(struct file *file, const char
> __user *buf,
> > return -EFAULT;
> >
> > mutex_lock(&pmsg_lock);
> > - ret = psinfo->write_buf_user(PSTORE_TYPE_PMSG, 0, &id, 0, buf,
> 0, count,
> > + ret = psinfo->write_buf_user(PSTORE_TYPE_PMSG, 0, &id,
> > + iminor(file->f_inode), buf, 0,
> > + count,
> > psinfo);
> > mutex_unlock(&pmsg_lock);
> > return ret ? ret : count;
> > @@ -61,7 +62,7 @@ static char *pmsg_devnode(struct device *dev,
> > umode_t *mode)
> >
> > void pstore_register_pmsg(void)
> > {
> > - struct device *pmsg_device;
> > + int i;
> >
> > pmsg_major = register_chrdev(0, PMSG_NAME, &pmsg_fops);
> > if (pmsg_major < 0) {
> > @@ -76,15 +77,23 @@ void pstore_register_pmsg(void)
> > }
> > pmsg_class->devnode = pmsg_devnode;
> >
> > - pmsg_device = device_create(pmsg_class, NULL, MKDEV(pmsg_major,
> 0),
> > - NULL, "%s%d", PMSG_NAME, 0);
> > - if (IS_ERR(pmsg_device)) {
> > - pr_err("failed to create device\n");
> > - goto err_device;
> > + /* allocate additional /dev/pmsg[ID] */
>
> This isn't "additional" any more, but rather "Allocate each pmsg device"
> or something.
OK, I will fix.
>
> > + for (i = 0; i < psinfo->num_pmsg; i++) {
> > + struct device *pmsg_device;
> > +
> > + pmsg_device = device_create(pmsg_class, NULL,
> > + MKDEV(pmsg_major, i), NULL,
> "%s%d",
> > + PMSG_NAME, i);
> > + if (IS_ERR(pmsg_device)) {
> > + pr_err("failed to create device\n");
> > + goto err_device;
> > + }
> > }
> > return;
> >
> > err_device:
> > + for (i--; i >= 0; i--)
> > + device_destroy(pmsg_class, MKDEV(pmsg_major, i));
> > class_destroy(pmsg_class);
> > err_class:
> > unregister_chrdev(pmsg_major, PMSG_NAME); diff --git
> > a/include/linux/pstore.h b/include/linux/pstore.h index
> > 0da29cae009b..7a5db4833b8a 100644
> > --- a/include/linux/pstore.h
> > +++ b/include/linux/pstore.h
> > @@ -55,6 +55,7 @@ struct pstore_info {
> > size_t bufsize;
> > struct mutex read_mutex; /* serialize open/read/close
> */
> > int flags;
> > + unsigned int num_pmsg;
>
> Something in this patch needs to set num_pmsg to 1 unconditionally, so that
> bisectability is retained. I.e. after this patch, I should still get a
> /dev/pmsg0 device. Right now, it will be skipped since num_pmsg will always
> == 0.
Indeed, I will fix too.
Best regards,
Nobuhiro
^ permalink raw reply [flat|nested] 12+ messages in thread
* RE: [PATCH v4 2nd 2/4] pstore: support multiple pmsg instances
2017-02-02 22:17 ` Mark Salyzyn
@ 2017-02-07 8:47 ` 岩松信洋 / IWAMATSU,NOBUHIRO
0 siblings, 0 replies; 12+ messages in thread
From: 岩松信洋 / IWAMATSU,NOBUHIRO @ 2017-02-07 8:47 UTC (permalink / raw)
To: Mark Salyzyn, Anton Vorontsov, Colin Cross, Kees Cook, Tony Luck
Cc: linux-kernel, 阿口誠司 / AGUCHI,SEIJI
Hi,
Thanks for your review.
> -----Original Message-----
> From: Mark Salyzyn [mailto:salyzyn@android.com]
> Sent: Friday, February 03, 2017 7:18 AM
> To: 岩松信洋 / IWAMATSU,NOBUHIRO; Anton Vorontsov; Colin Cross; Kees Cook;
> Tony Luck
> Cc: linux-kernel@vger.kernel.org; Hiraku Toyooka; 阿口誠司 / AGUCHI,
> SEIJI
> Subject: Re: [PATCH v4 2nd 2/4] pstore: support multiple pmsg instances
>
> On 01/30/2017 05:58 PM, Nobuhiro Iwamatsu wrote:
> > diff --git a/include/linux/pstore.h b/include/linux/pstore.h index
> > 0da29cae009b..7a5db4833b8a 100644
> > --- a/include/linux/pstore.h
> > +++ b/include/linux/pstore.h
> > @@ -55,6 +55,7 @@ struct pstore_info {
> > size_t bufsize;
> > struct mutex read_mutex; /* serialize open/read/close */
> > int flags;
> > + unsigned int num_pmsg;
> > int (*open)(struct pstore_info *psi);
> > int (*close)(struct pstore_info *psi);
> > ssize_t (*read)(u64 *id, enum pstore_type_id *type,
>
> Before patch there was an implication that num_pmsg was 1, after patch calloc
> leaves this at a value of 0. Please reconcile the functional difference
> that this causes.
Yes, I was pointed out here also by Kees.
I will fix this.
Best regards,
Nobuhiro
^ permalink raw reply [flat|nested] 12+ messages in thread
* RE: [PATCH v4 2nd 1/4] ramoops: Add __ramoops_init_prz() as generic function
2017-02-02 22:13 ` Mark Salyzyn
@ 2017-02-07 8:51 ` 岩松信洋 / IWAMATSU,NOBUHIRO
2017-02-07 16:05 ` Mark Salyzyn
0 siblings, 1 reply; 12+ messages in thread
From: 岩松信洋 / IWAMATSU,NOBUHIRO @ 2017-02-07 8:51 UTC (permalink / raw)
To: Mark Salyzyn, Anton Vorontsov, Colin Cross, Kees Cook, Tony Luck
Cc: linux-kernel,
阿口誠司 / AGUCHI,SEIJI,
Shuah Khan
Hi,
Thanks for your review.
> -----Original Message-----
> From: Mark Salyzyn [mailto:salyzyn@android.com]
> Sent: Friday, February 03, 2017 7:13 AM
> To: 岩松信洋 / IWAMATSU,NOBUHIRO; Anton Vorontsov; Colin Cross; Kees Cook;
> Tony Luck
> Cc: linux-kernel@vger.kernel.org; Hiraku Toyooka; 阿口誠司 / AGUCHI,
> SEIJI; Shuah Khan
> Subject: Re: [PATCH v4 2nd 1/4] ramoops: Add __ramoops_init_prz() as generic
> function
>
> On 01/30/2017 05:58 PM, Nobuhiro Iwamatsu wrote:
> > +
> > + if (zap && *paddr + sz - cxt->phys_addr > cxt->size) {
> > + dev_err(dev, "no room for %s mem region (0x%zx@0x%llx) in
> (0x%lx@0x%llx)\n",
> > + name, sz, (unsigned long long)*paddr,
> > + cxt->size, (unsigned long long)cxt->phys_addr);
> > + return -ENOMEM;
> > + }
> > +
> Why not allow this limit check for ramoops_init_prsz call?
>
This code is controlled by flag of zap.
If zap is false, __ramoops_init_prz() is worked same as original ramoops_init_przs().
Best regards,
Nobuhiro
^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: [PATCH v4 2nd 1/4] ramoops: Add __ramoops_init_prz() as generic function
2017-02-07 8:51 ` 岩松信洋 / IWAMATSU,NOBUHIRO
@ 2017-02-07 16:05 ` Mark Salyzyn
0 siblings, 0 replies; 12+ messages in thread
From: Mark Salyzyn @ 2017-02-07 16:05 UTC (permalink / raw)
To: 岩松信洋 / IWAMATSU,NOBUHIRO,
Anton Vorontsov, Colin Cross, Kees Cook, Tony Luck
Cc: linux-kernel,
阿口誠司 / AGUCHI,SEIJI,
Shuah Khan
On 02/07/2017 12:51 AM, 岩松信洋 / IWAMATSU,NOBUHIRO wrote:
> Hi,
>
> Thanks for your review.
>
>> -----Original Message-----
>> From: Mark Salyzyn [mailto:salyzyn@android.com]
>> Sent: Friday, February 03, 2017 7:13 AM
>> To: 岩松信洋 / IWAMATSU,NOBUHIRO; Anton Vorontsov; Colin Cross; Kees Cook;
>> Tony Luck
>> Cc: linux-kernel@vger.kernel.org; Hiraku Toyooka; 阿口誠司 / AGUCHI,
>> SEIJI; Shuah Khan
>> Subject: Re: [PATCH v4 2nd 1/4] ramoops: Add __ramoops_init_prz() as generic
>> function
>>
>> On 01/30/2017 05:58 PM, Nobuhiro Iwamatsu wrote:
>>> +
>>> + if (zap && *paddr + sz - cxt->phys_addr > cxt->size) {
>>> + dev_err(dev, "no room for %s mem region (0x%zx@0x%llx) in
>> (0x%lx@0x%llx)\n",
>>> + name, sz, (unsigned long long)*paddr,
>>> + cxt->size, (unsigned long long)cxt->phys_addr);
>>> + return -ENOMEM;
>>> + }
>>> +
>> Why not allow this limit check for ramoops_init_prsz call?
>>
> This code is controlled by flag of zap.
> If zap is false, __ramoops_init_prz() is worked same as original ramoops_init_przs().
>
> Best regards,
> Nobuhiro
I agree, preserve functionality as is. Please consider removing the need
for zap && in a future patch, as I _believe_ (untested, and no deep
dive) that the limit check is relevant for the zap is false path as well
and may have been an oversight.
-- Mark
^ permalink raw reply [flat|nested] 12+ messages in thread
end of thread, other threads:[~2017-02-07 16:07 UTC | newest]
Thread overview: 12+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2017-01-31 1:58 [PATCH v4 2nd 0/4] pstore: ramoops: support multiple pmsg instances Nobuhiro Iwamatsu
2017-01-31 1:58 ` [PATCH v4 2nd 1/4] ramoops: Add __ramoops_init_prz() as generic function Nobuhiro Iwamatsu
2017-02-02 22:13 ` Mark Salyzyn
2017-02-07 8:51 ` 岩松信洋 / IWAMATSU,NOBUHIRO
2017-02-07 16:05 ` Mark Salyzyn
2017-01-31 1:58 ` [PATCH v4 2nd 2/4] pstore: support multiple pmsg instances Nobuhiro Iwamatsu
2017-02-01 20:28 ` Kees Cook
2017-02-07 8:44 ` 岩松信洋 / IWAMATSU,NOBUHIRO
2017-02-02 22:17 ` Mark Salyzyn
2017-02-07 8:47 ` 岩松信洋 / IWAMATSU,NOBUHIRO
2017-01-31 1:58 ` [PATCH v4 2nd 3/4] ramoops: " Nobuhiro Iwamatsu
2017-01-31 1:58 ` [PATCH v4 2nd 4/4] selftests/pstore: add testcases for " Nobuhiro Iwamatsu
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.