]> git.proxmox.com Git - mirror_ubuntu-bionic-kernel.git/blobdiff - fs/pstore/ram.c
pstore/ram: Correctly calculate usable PRZ bytes
[mirror_ubuntu-bionic-kernel.git] / fs / pstore / ram.c
index 7125b398d312e71714d96d4ed51baeff2e149601..9c5f8d8c051c35e92a70ca01ebac938ef6947c8f 100644 (file)
@@ -804,17 +804,14 @@ static int ramoops_probe(struct platform_device *pdev)
 
        cxt->pstore.data = cxt;
        /*
-        * Console can handle any buffer size, so prefer LOG_LINE_MAX. If we
-        * have to handle dumps, we must have at least record_size buffer. And
-        * for ftrace, bufsize is irrelevant (if bufsize is 0, buf will be
-        * ZERO_SIZE_PTR).
+        * Since bufsize is only used for dmesg crash dumps, it
+        * must match the size of the dprz record (after PRZ header
+        * and ECC bytes have been accounted for).
         */
-       if (cxt->console_size)
-               cxt->pstore.bufsize = 1024; /* LOG_LINE_MAX */
-       cxt->pstore.bufsize = max(cxt->record_size, cxt->pstore.bufsize);
-       cxt->pstore.buf = kmalloc(cxt->pstore.bufsize, GFP_KERNEL);
+       cxt->pstore.bufsize = cxt->dprzs[0]->buffer_size;
+       cxt->pstore.buf = kzalloc(cxt->pstore.bufsize, GFP_KERNEL);
        if (!cxt->pstore.buf) {
-               pr_err("cannot allocate pstore buffer\n");
+               pr_err("cannot allocate pstore crash dump buffer\n");
                err = -ENOMEM;
                goto fail_clear;
        }
@@ -896,8 +893,22 @@ static struct platform_driver ramoops_driver = {
        },
 };
 
-static void ramoops_register_dummy(void)
+static inline void ramoops_unregister_dummy(void)
+{
+       platform_device_unregister(dummy);
+       dummy = NULL;
+
+       kfree(dummy_data);
+       dummy_data = NULL;
+}
+
+static void __init ramoops_register_dummy(void)
 {
+       /*
+        * Prepare a dummy platform data structure to carry the module
+        * parameters. If mem_size isn't set, then there are no module
+        * parameters, and we can skip this.
+        */
        if (!mem_size)
                return;
 
@@ -930,21 +941,28 @@ static void ramoops_register_dummy(void)
        if (IS_ERR(dummy)) {
                pr_info("could not create platform device: %ld\n",
                        PTR_ERR(dummy));
+               dummy = NULL;
+               ramoops_unregister_dummy();
        }
 }
 
 static int __init ramoops_init(void)
 {
+       int ret;
+
        ramoops_register_dummy();
-       return platform_driver_register(&ramoops_driver);
+       ret = platform_driver_register(&ramoops_driver);
+       if (ret != 0)
+               ramoops_unregister_dummy();
+
+       return ret;
 }
 postcore_initcall(ramoops_init);
 
 static void __exit ramoops_exit(void)
 {
        platform_driver_unregister(&ramoops_driver);
-       platform_device_unregister(dummy);
-       kfree(dummy_data);
+       ramoops_unregister_dummy();
 }
 module_exit(ramoops_exit);