2023-02-03 11:35:02

by Victor Hassan

[permalink] [raw]
Subject: [PATCH] pstore/blk: Export a method to implemente panic_write()

The panic_write() is necessary to write the pstore frontend message
to blk devices when panic. Here is a way to register panic_write when
we use "best_effort" way to register the pstore blk-backend.

Usage:

xx_register_pstore_panic_write(pstore_blk_notifier_type type,
struct pstore_device_info *pdi)
{
switch (type) {
case PSTORE_BLK_BACKEND_REGISTER:
case PSTORE_BLK_BACKEND_PANIC_DRV_REGISTER:
...

pid->zone.panic_write = xxx;

...
break;
case PSTORE_BLK_BACKEND_UNREGISTER:
case PSTORE_BLK_BACKEND_PANIC_DRV_UNREGISTER:
...

pdi->zone.panic_write = NULL;

...
break;
default:
break;
}

}

static struct pstore_blk_notifier pbn = {
.notitifer_call = xx_register_pstore_panic_write;
}

use {un,}register_pstore_blk_panic_notifier() to register/unregister
pstore_blk_notifier

Signed-off-by: Victor Hassan <[email protected]>
---
fs/pstore/blk.c | 101 +++++++++++++++++++++++++++++++++++--
include/linux/pstore_blk.h | 19 +++++++
2 files changed, 116 insertions(+), 4 deletions(-)

diff --git a/fs/pstore/blk.c b/fs/pstore/blk.c
index 4ae0cfcd15f2..2c70a3bff1ae 100644
--- a/fs/pstore/blk.c
+++ b/fs/pstore/blk.c
@@ -18,6 +18,7 @@
#include <linux/file.h>
#include <linux/init_syscalls.h>
#include <linux/mount.h>
+#include <linux/notifier.h>

static long kmsg_size = CONFIG_PSTORE_BLK_KMSG_SIZE;
module_param(kmsg_size, long, 0400);
@@ -72,6 +73,14 @@ static DEFINE_MUTEX(pstore_blk_lock);
static struct file *psblk_file;
static struct pstore_device_info *pstore_device_info;

+static struct {
+ struct raw_notifier_head chain;
+ struct pstore_blk_notifier *pbn;
+ bool notifier;
+} pstore_blk_panic_notifier = {
+ .chain = RAW_NOTIFIER_INIT(pstore_blk_panic_notifier.chain),
+};
+
#define check_size(name, alignsize) ({ \
long _##name_ = (name); \
_##name_ = _##name_ <= 0 ? 0 : (_##name_ * 1024); \
@@ -94,6 +103,82 @@ static struct pstore_device_info *pstore_device_info;
dev->zone.name = _##name_; \
}

+static int pstore_blk_panic_notifier_call(struct notifier_block *nb,
+ unsigned long action, void *data)
+{
+ int ret = 0;
+ struct pstore_blk_notifier *pbn =
+ container_of(nb, struct pstore_blk_notifier, nb);
+
+ if (pbn)
+ ret = pbn->notifier_call(action, data);
+
+ return ret;
+}
+
+int register_pstore_blk_panic_notifier(struct pstore_blk_notifier *pbn)
+{
+ int err = 0;
+ struct notifier_block *nb;
+
+ mutex_lock(&pstore_blk_lock);
+
+ if (pstore_blk_panic_notifier.notifier) {
+ pr_info("had register panic\n");
+ goto unlock;
+ }
+
+ nb = &pbn->nb;
+ nb->notifier_call = pstore_blk_panic_notifier_call;
+
+ err = raw_notifier_chain_register(&pstore_blk_panic_notifier.chain, nb);
+ if (err)
+ goto unlock;
+
+ if (pstore_device_info)
+ err = nb->notifier_call(nb, PSTORE_BLK_BACKEND_PANIC_DRV_REGISTER,
+ pstore_device_info);
+
+ if (!err)
+ pstore_blk_panic_notifier.notifier = true;
+
+unlock:
+ mutex_unlock(&pstore_blk_lock);
+
+ return err;
+}
+EXPORT_SYMBOL_GPL(register_pstore_blk_panic_notifier);
+
+void unregister_pstore_blk_panic_notifier(struct pstore_blk_notifier *pbn)
+{
+ struct notifier_block *nb = &pbn->nb;
+
+ mutex_lock(&pstore_blk_lock);
+
+ raw_notifier_chain_unregister(&pstore_blk_panic_notifier.chain, nb);
+
+ if (pstore_device_info)
+ nb->notifier_call(nb, PSTORE_BLK_BACKEND_PANIC_DRV_UNREGISTER,
+ pstore_device_info);
+
+ pstore_blk_panic_notifier.notifier = false;
+
+ mutex_unlock(&pstore_blk_lock);
+}
+EXPORT_SYMBOL_GPL(unregister_pstore_blk_panic_notifier);
+
+static int pstore_blk_panic_notifier_init_call(struct pstore_device_info *pdi)
+{
+ return raw_notifier_call_chain(&pstore_blk_panic_notifier.chain,
+ PSTORE_BLK_BACKEND_REGISTER, pdi);
+}
+
+static int pstore_blk_panic_notifier_exit_call(struct pstore_device_info *pdi)
+{
+ return raw_notifier_call_chain(&pstore_blk_panic_notifier.chain,
+ PSTORE_BLK_BACKEND_UNREGISTER, pdi);
+}
+
static int __register_pstore_device(struct pstore_device_info *dev)
{
int ret;
@@ -301,16 +386,22 @@ static int __init __best_effort_init(void)
if (!best_effort_dev)
return -ENOMEM;

+ strcpy(best_effort_dev->path, blkdev);
best_effort_dev->zone.read = psblk_generic_blk_read;
best_effort_dev->zone.write = psblk_generic_blk_write;

ret = __register_pstore_blk(best_effort_dev,
early_boot_devpath(blkdev));
- if (ret)
+ if (ret) {
kfree(best_effort_dev);
- else
- pr_info("attached %s (%lu) (no dedicated panic_write!)\n",
- blkdev, best_effort_dev->zone.total_size);
+ } else {
+ if (pstore_blk_panic_notifier_init_call(best_effort_dev) == NOTIFY_OK)
+ pr_info("attached %s (%lu) (dedicated panic_write!)\n",
+ blkdev, best_effort_dev->zone.total_size);
+ else
+ pr_info("attached %s (%lu) (no dedicated panic_write!)\n",
+ blkdev, best_effort_dev->zone.total_size);
+ }

return ret;
}
@@ -326,6 +417,8 @@ static void __exit __best_effort_exit(void)
if (psblk_file) {
struct pstore_device_info *dev = pstore_device_info;

+ pstore_blk_panic_notifier_exit_call(dev);
+
__unregister_pstore_device(dev);
kfree(dev);
fput(psblk_file);
diff --git a/include/linux/pstore_blk.h b/include/linux/pstore_blk.h
index 924ca07aafbd..4c1fc8debdc7 100644
--- a/include/linux/pstore_blk.h
+++ b/include/linux/pstore_blk.h
@@ -17,13 +17,32 @@
*
*/
struct pstore_device_info {
+ char path[80];
unsigned int flags;
struct pstore_zone_info zone;
};

+enum pstore_blk_notifier_type {
+ PSTORE_BLK_BACKEND_REGISTER = 1,
+ PSTORE_BLK_BACKEND_PANIC_DRV_REGISTER,
+ PSTORE_BLK_BACKEND_UNREGISTER,
+ PSTORE_BLK_BACKEND_PANIC_DRV_UNREGISTER,
+};
+
+typedef int (*pstore_blk_notifier_fn_t)(pstore_blk_notifier_type type,
+ struct pstore_device_info *dev);
+
+struct pstore_blk_notifier {
+ struct notifier_block nb;
+ pstore_blk_notifier_fn_t notifier_call;
+};
+
int register_pstore_device(struct pstore_device_info *dev);
void unregister_pstore_device(struct pstore_device_info *dev);

+int register_pstore_blk_panic_notifier(struct pstore_blk_notifier *pbn);
+void unregister_pstore_blk_panic_notifier(struct pstore_blk_notifier *nb);
+
/**
* struct pstore_blk_config - the pstore_blk backend configuration
*
--
2.29.0



2023-02-03 19:58:50

by kernel test robot

[permalink] [raw]
Subject: Re: [PATCH] pstore/blk: Export a method to implemente panic_write()

Hi Victor,

Thank you for the patch! Yet something to improve:

[auto build test ERROR on kees/for-next/pstore]
[also build test ERROR on kees/for-next/kspp linus/master v6.2-rc6 next-20230203]
[If your patch is applied to the wrong git tree, kindly drop us a note.
And when submitting patch, we suggest to use '--base' as documented in
https://git-scm.com/docs/git-format-patch#_base_tree_information]

url: https://github.com/intel-lab-lkp/linux/commits/Victor-Hassan/pstore-blk-Export-a-method-to-implemente-panic_write/20230203-193548
base: https://git.kernel.org/pub/scm/linux/kernel/git/kees/linux.git for-next/pstore
patch link: https://lore.kernel.org/r/20230203113515.93540-1-victor%40allwinnertech.com
patch subject: [PATCH] pstore/blk: Export a method to implemente panic_write()
config: x86_64-randconfig-a012 (https://download.01.org/0day-ci/archive/20230204/[email protected]/config)
compiler: clang version 14.0.6 (https://github.com/llvm/llvm-project f28c006a5895fc0e329fe15fead81e37457cb1d1)
reproduce (this is a W=1 build):
wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross
chmod +x ~/bin/make.cross
# https://github.com/intel-lab-lkp/linux/commit/368e42ba015da6c7bdd201b8fdb669e936307cbb
git remote add linux-review https://github.com/intel-lab-lkp/linux
git fetch --no-tags linux-review Victor-Hassan/pstore-blk-Export-a-method-to-implemente-panic_write/20230203-193548
git checkout 368e42ba015da6c7bdd201b8fdb669e936307cbb
# save the config file
mkdir build_dir && cp config build_dir/.config
COMPILER_INSTALL_PATH=$HOME/0day COMPILER=clang make.cross W=1 O=build_dir ARCH=x86_64 olddefconfig
COMPILER_INSTALL_PATH=$HOME/0day COMPILER=clang make.cross W=1 O=build_dir ARCH=x86_64 SHELL=/bin/bash fs/pstore/

If you fix the issue, kindly add following tag where applicable
| Reported-by: kernel test robot <[email protected]>

All errors (new ones prefixed by >>):

In file included from fs/pstore/blk.c:16:
>> include/linux/pstore_blk.h:32:41: error: must use 'enum' tag to refer to type 'pstore_blk_notifier_type'
typedef int (*pstore_blk_notifier_fn_t)(pstore_blk_notifier_type type,
^
enum
1 error generated.


vim +32 include/linux/pstore_blk.h

31
> 32 typedef int (*pstore_blk_notifier_fn_t)(pstore_blk_notifier_type type,
33 struct pstore_device_info *dev);
34

--
0-DAY CI Kernel Test Service
https://github.com/intel/lkp-tests

2023-02-03 21:19:24

by kernel test robot

[permalink] [raw]
Subject: Re: [PATCH] pstore/blk: Export a method to implemente panic_write()

Hi Victor,

Thank you for the patch! Yet something to improve:

[auto build test ERROR on kees/for-next/pstore]
[also build test ERROR on kees/for-next/kspp linus/master v6.2-rc6 next-20230203]
[If your patch is applied to the wrong git tree, kindly drop us a note.
And when submitting patch, we suggest to use '--base' as documented in
https://git-scm.com/docs/git-format-patch#_base_tree_information]

url: https://github.com/intel-lab-lkp/linux/commits/Victor-Hassan/pstore-blk-Export-a-method-to-implemente-panic_write/20230203-193548
base: https://git.kernel.org/pub/scm/linux/kernel/git/kees/linux.git for-next/pstore
patch link: https://lore.kernel.org/r/20230203113515.93540-1-victor%40allwinnertech.com
patch subject: [PATCH] pstore/blk: Export a method to implemente panic_write()
config: x86_64-randconfig-a011 (https://download.01.org/0day-ci/archive/20230204/[email protected]/config)
compiler: gcc-11 (Debian 11.3.0-8) 11.3.0
reproduce (this is a W=1 build):
# https://github.com/intel-lab-lkp/linux/commit/368e42ba015da6c7bdd201b8fdb669e936307cbb
git remote add linux-review https://github.com/intel-lab-lkp/linux
git fetch --no-tags linux-review Victor-Hassan/pstore-blk-Export-a-method-to-implemente-panic_write/20230203-193548
git checkout 368e42ba015da6c7bdd201b8fdb669e936307cbb
# save the config file
mkdir build_dir && cp config build_dir/.config
make W=1 O=build_dir ARCH=x86_64 olddefconfig
make W=1 O=build_dir ARCH=x86_64 SHELL=/bin/bash drivers/ fs/

If you fix the issue, kindly add following tag where applicable
| Reported-by: kernel test robot <[email protected]>

All errors (new ones prefixed by >>):

In file included from drivers/mtd/mtdpstore.c:7:
>> include/linux/pstore_blk.h:32:41: error: unknown type name 'pstore_blk_notifier_type'
32 | typedef int (*pstore_blk_notifier_fn_t)(pstore_blk_notifier_type type,
| ^~~~~~~~~~~~~~~~~~~~~~~~
>> include/linux/pstore_blk.h:37:9: error: unknown type name 'pstore_blk_notifier_fn_t'
37 | pstore_blk_notifier_fn_t notifier_call;
| ^~~~~~~~~~~~~~~~~~~~~~~~
--
In file included from fs/pstore/blk.c:16:
>> include/linux/pstore_blk.h:32:41: error: unknown type name 'pstore_blk_notifier_type'
32 | typedef int (*pstore_blk_notifier_fn_t)(pstore_blk_notifier_type type,
| ^~~~~~~~~~~~~~~~~~~~~~~~
>> include/linux/pstore_blk.h:37:9: error: unknown type name 'pstore_blk_notifier_fn_t'
37 | pstore_blk_notifier_fn_t notifier_call;
| ^~~~~~~~~~~~~~~~~~~~~~~~
fs/pstore/blk.c: In function 'pstore_blk_panic_notifier_call':
>> fs/pstore/blk.c:114:23: error: called object is not a function or function pointer
114 | ret = pbn->notifier_call(action, data);
| ^~~


vim +/pstore_blk_notifier_type +32 include/linux/pstore_blk.h

31
> 32 typedef int (*pstore_blk_notifier_fn_t)(pstore_blk_notifier_type type,
33 struct pstore_device_info *dev);
34
35 struct pstore_blk_notifier {
36 struct notifier_block nb;
> 37 pstore_blk_notifier_fn_t notifier_call;
38 };
39

--
0-DAY CI Kernel Test Service
https://github.com/intel/lkp-tests