Messages in this thread Patch in this message | | | From | Geliang Tang <> | Subject | [PATCH 3/3] pstore: add 'rmmod ramoops' support | Date | Fri, 16 Oct 2015 23:25:55 +0800 |
| |
ramoops doesn't support unregistering yet, it was marked as TODO. This patch adds some code to fix it: 1) Add functions to unregister kmsg/console/ftrace/pmsg. 2) Add a function to free compression buffer. 3) Remove try_module_get() to allow this module can be unloaded. 4) Unmap the memory and free it. 5) Set console flags, make sure it can be registered again after be unregistered.
Signed-off-by: Geliang Tang <geliangtang@163.com> --- fs/pstore/ftrace.c | 15 ++++++++++++++- fs/pstore/internal.h | 4 ++++ fs/pstore/platform.c | 40 ++++++++++++++++++++++++++++++++-------- fs/pstore/pmsg.c | 7 +++++++ fs/pstore/ram.c | 19 ++++++++----------- include/linux/pstore.h | 5 +++++ 6 files changed, 70 insertions(+), 20 deletions(-)
diff --git a/fs/pstore/ftrace.c b/fs/pstore/ftrace.c index 76a4eeb..554c1ce 100644 --- a/fs/pstore/ftrace.c +++ b/fs/pstore/ftrace.c @@ -104,9 +104,10 @@ static const struct file_operations pstore_knob_fops = { .write = pstore_ftrace_knob_write, }; +static struct dentry *dir; + void pstore_register_ftrace(void) { - struct dentry *dir; struct dentry *file; if (!psinfo->write_buf) @@ -129,3 +130,15 @@ void pstore_register_ftrace(void) err_file: debugfs_remove(dir); } + +void pstore_unregister_ftrace(void) +{ + mutex_lock(&pstore_ftrace_lock); + if (pstore_ftrace_enabled) { + unregister_ftrace_function(&pstore_ftrace_ops); + pstore_ftrace_enabled = 0; + } + mutex_unlock(&pstore_ftrace_lock); + + debugfs_remove_recursive(dir); +} diff --git a/fs/pstore/internal.h b/fs/pstore/internal.h index c36ba2c..96253c4 100644 --- a/fs/pstore/internal.h +++ b/fs/pstore/internal.h @@ -41,14 +41,18 @@ pstore_ftrace_decode_cpu(struct pstore_ftrace_record *rec) #ifdef CONFIG_PSTORE_FTRACE extern void pstore_register_ftrace(void); +extern void pstore_unregister_ftrace(void); #else static inline void pstore_register_ftrace(void) {} +static inline void pstore_unregister_ftrace(void) {} #endif #ifdef CONFIG_PSTORE_PMSG extern void pstore_register_pmsg(void); +extern void pstore_unregister_pmsg(void); #else static inline void pstore_register_pmsg(void) {} +static inline void pstore_unregister_pmsg(void) {} #endif extern struct pstore_info *psinfo; diff --git a/fs/pstore/platform.c b/fs/pstore/platform.c index 1b11249..c474dc2 100644 --- a/fs/pstore/platform.c +++ b/fs/pstore/platform.c @@ -237,6 +237,12 @@ static void allocate_buf_for_compression(void) } +static void free_buf_for_compression(void) +{ + kfree(stream.workspace); + kfree(big_oops_buf); +} + /* * Called when compression fails, since the printk buffer * would be fetched for compression calling it again when @@ -358,6 +364,11 @@ static void pstore_register_kmsg(void) kmsg_dump_register(&pstore_dumper); } +static void pstore_unregister_kmsg(void) +{ + kmsg_dump_unregister(&pstore_dumper); +} + #ifdef CONFIG_PSTORE_CONSOLE static void pstore_console_write(struct console *con, const char *s, unsigned c) { @@ -387,16 +398,22 @@ static void pstore_console_write(struct console *con, const char *s, unsigned c) static struct console pstore_console = { .name = "pstore", .write = pstore_console_write, - .flags = CON_PRINTBUFFER | CON_ENABLED | CON_ANYTIME, .index = -1, }; static void pstore_register_console(void) { + pstore_console.flags = CON_PRINTBUFFER | CON_ENABLED | CON_ANYTIME; register_console(&pstore_console); } + +static void pstore_unregister_console(void) +{ + unregister_console(&pstore_console); +} #else static void pstore_register_console(void) {} +static void pstore_unregister_console(void) {} #endif static int pstore_write_compat(enum pstore_type_id type, @@ -420,8 +437,6 @@ static int pstore_write_compat(enum pstore_type_id type, */ int pstore_register(struct pstore_info *psi) { - struct module *owner = psi->owner; - if (backend && strcmp(backend, psi->name)) return -EPERM; @@ -437,11 +452,6 @@ int pstore_register(struct pstore_info *psi) mutex_init(&psinfo->read_mutex); spin_unlock(&pstore_lock); - if (owner && !try_module_get(owner)) { - psinfo = NULL; - return -EINVAL; - } - allocate_buf_for_compression(); if (pstore_is_mounted()) @@ -473,6 +483,20 @@ int pstore_register(struct pstore_info *psi) } EXPORT_SYMBOL_GPL(pstore_register); +void pstore_unregister(void) +{ + pstore_unregister_pmsg(); + pstore_unregister_ftrace(); + pstore_unregister_console(); + pstore_unregister_kmsg(); + + free_buf_for_compression(); + + psinfo = NULL; + backend = NULL; +} +EXPORT_SYMBOL_GPL(pstore_unregister); + /* * Read all the records from the persistent store. Create * files in our filesystem. Don't warn about -EEXIST errors diff --git a/fs/pstore/pmsg.c b/fs/pstore/pmsg.c index 5a2f05a..7de20cd 100644 --- a/fs/pstore/pmsg.c +++ b/fs/pstore/pmsg.c @@ -114,3 +114,10 @@ err_class: err: return; } + +void pstore_unregister_pmsg(void) +{ + device_destroy(pmsg_class, MKDEV(pmsg_major, 0)); + class_destroy(pmsg_class); + unregister_chrdev(pmsg_major, PMSG_NAME); +} diff --git a/fs/pstore/ram.c b/fs/pstore/ram.c index 6c26c4d..d938bc1 100644 --- a/fs/pstore/ram.c +++ b/fs/pstore/ram.c @@ -580,28 +580,25 @@ fail_out: static int __exit ramoops_remove(struct platform_device *pdev) { -#if 0 - /* TODO(kees): We cannot unload ramoops since pstore doesn't support - * unregistering yet. - */ struct ramoops_context *cxt = &oops_cxt; - iounmap(cxt->virt_addr); - release_mem_region(cxt->phys_addr, cxt->size); - cxt->max_dump_cnt = 0; + pstore_unregister(); - /* TODO(kees): When pstore supports unregistering, call it here. */ + cxt->max_dump_cnt = 0; kfree(cxt->pstore.buf); cxt->pstore.bufsize = 0; + persistent_ram_free(cxt->mprz); + persistent_ram_free(cxt->fprz); + persistent_ram_free(cxt->cprz); + ramoops_free_przs(cxt); + return 0; -#endif - return -EBUSY; } static struct platform_driver ramoops_driver = { .probe = ramoops_probe, - .remove = __exit_p(ramoops_remove), + .remove = ramoops_remove, .driver = { .name = "ramoops", }, diff --git a/include/linux/pstore.h b/include/linux/pstore.h index 8e7a25b..34e4a6d 100644 --- a/include/linux/pstore.h +++ b/include/linux/pstore.h @@ -77,6 +77,7 @@ struct pstore_info { #ifdef CONFIG_PSTORE extern int pstore_register(struct pstore_info *); +extern void pstore_unregister(void); extern bool pstore_cannot_block_path(enum kmsg_dump_reason reason); #else static inline int @@ -84,6 +85,10 @@ pstore_register(struct pstore_info *psi) { return -ENODEV; } +static inline void +pstore_unregister(void) +{ +} static inline bool pstore_cannot_block_path(enum kmsg_dump_reason reason) { -- 2.5.0
| |