efi: Avoid sysfs spew on reboot and panic
Subsystems (3)
PATCH 1/1 efi: Avoid sysfs spew on reboot and panic
Right now all pstore accesses to efivars will delete or create new sysfs nodes. This is less than ideal if we've paniced or are rebooting, since we're in entirely the wrong context to do this kind of thing. Add the reason to the pstore callback and make sure we only manipulate the files if we're still going to be alive afterwards.
--- drivers/acpi/apei/erst.c | 6 ++++-- drivers/firmware/efivars.c | 17 +++++++++++++---- fs/pstore/platform.c | 7 ++++--- include/linux/kmsg_dump.h | 1 + include/linux/pstore.h | 5 ++++- 5 files changed, 26 insertions(+), 10 deletions(-)
drivers/acpi/apei/erst.c +4 -2
@@ -934,7 +934,8 @@ static int erst_close_pstore(struct pstore_info *psi);static ssize_t erst_reader (u64 *id,enum pstore_type_id *type,struct timespec *time,struct pstore_info *psi);static u64 erst_writer (enum pstore_type_id type,unsigned int part, -size_t size,struct pstore_info *psi); +enum kmsg_dump_reason reason,size_t size, +struct pstore_info *psi);static int erst_clearer (enum pstore_type_id type,u64 id,struct pstore_info *psi);
@@ -1041,7 +1042,8 @@ out: }static u64 erst_writer (enum pstore_type_id type,unsigned int part, -size_t size,struct pstore_info *psi) +enum kmsg_dump_reason reason,size_t size, +struct pstore_info *psi) {struct cper_pstore_record *rcd = (struct cper_pstore_record *) (erst_info.buf -sizeof (*rcd));
drivers/firmware/efivars.c +13 -4
@@ -491,7 +491,8 @@ static ssize_t efi_pstore_read(u64 *id, enum pstore_type_id *type, }static u64 efi_pstore_write (enum pstore_type_id type,unsigned int part, -size_t size,struct pstore_info *psi) +enum kmsg_dump_reason reason,size_t size, +struct pstore_info *psi) {char name[DUMP_NAME_LEN ];char stub_name[DUMP_NAME_LEN ];
@@ -544,6 +545,14 @@ static u64 efi_pstore_write(enum pstore_type_id type, unsigned int part,spin_unlock (&efivars->lock); +/* +* If it's more severe than KMSG_DUMP_OOPS then we're already dead. +* Don't bother playing with sysfs. +*/ + +if (reason >KMSG_DUMP_OOPS ) +return part; +if (found)efivar_unregister (found);
@@ -552,14 +561,13 @@ static u64 efi_pstore_write(enum pstore_type_id type, unsigned int part,utf16_strsize (efi_name,DUMP_NAME_LEN *2 ), efi_name, &vendor); -return part; };static int efi_pstore_erase (enum pstore_type_id type,u64 id,struct pstore_info *psi) { -efi_pstore_write (type, id,0 , psi); +efi_pstore_write (type, id,KMSG_DUMP_UNKNOWN ,0 , psi);return 0 ; }
@@ -581,7 +589,8 @@ static ssize_t efi_pstore_read(u64 *id, enum pstore_type_id *type, }static u64 efi_pstore_write (enum pstore_type_id type,unsigned int part, -size_t size,struct pstore_info *psi) +enum kmsg_dump_reason reason,size_t size, +struct pstore_info *psi) {return 0 ; }
fs/pstore/platform.c +4 -3
@@ -51,7 +51,8 @@ void pstore_set_kmsg_bytes(int bytes)static int oopscount;static char *reason_str[] = { -"Oops" ,"Panic" ,"Kexec" ,"Restart" ,"Halt" ,"Poweroff" ,"Emergency" +"Unknown" ,"Oops" ,"Panic" ,"Kexec" ,"Restart" ,"Halt" ,"Poweroff" , +"Emergency" };/*
@@ -97,7 +98,7 @@ static void pstore_dump(struct kmsg_dumper *dumper,memcpy (dst, s1 + s1_start, l1_cpy);memcpy (dst + l1_cpy, s2 + s2_start, l2_cpy); - id = psinfo->write (PSTORE_TYPE_DMESG , part, + id = psinfo->write (PSTORE_TYPE_DMESG , part, reason, hsize + l1_cpy + l2_cpy, psinfo);if (reason ==KMSG_DUMP_OOPS &&pstore_is_mounted ()) pstore_mkfile(PSTORE_TYPE_DMESG, psinfo->name, id,
@@ -207,7 +208,7 @@ int pstore_write(enum pstore_type_id type, char *buf, size_t size)mutex_lock (&psinfo->buf_mutex);memcpy (psinfo->buf, buf, size); - id = psinfo->write (type,0 , size, psinfo); + id = psinfo->write (type,0 ,KMSG_DUMP_UNKNOWN , size, psinfo);if (pstore_is_mounted ())pstore_mkfile (PSTORE_TYPE_DMESG , psinfo->name, id, psinfo->buf, size,CURRENT_TIME , psinfo);
include/linux/kmsg_dump.h +1 -0
@@ -16,6 +16,7 @@#include <linux/list.h> enum kmsg_dump_reason { +KMSG_DUMP_UNKNOWN ,KMSG_DUMP_OOPS ,KMSG_DUMP_PANIC ,KMSG_DUMP_KEXEC ,
include/linux/pstore.h +4 -1
@@ -22,6 +22,8 @@#ifndef _LINUX_PSTORE_H#define _LINUX_PSTORE_H +#include <linux/kmsg_dump.h> +/* types */ enum pstore_type_id { PSTORE_TYPE_DMESG = 0,
@@ -40,7 +42,8 @@ struct pstore_info {ssize_t (*read)(u64 *id,enum pstore_type_id *type,struct timespec *time,struct pstore_info *psi);u64 (*write)(enum pstore_type_id type,unsigned int part, -size_t size,struct pstore_info *psi); +enum kmsg_dump_reason reason,size_t size, +struct pstore_info *psi);int (*erase)(enum pstore_type_id type,u64 id,struct pstore_info *psi);void *data;
Signature · 1 line
1.7.6.2
Quoted 119 lines · Matthew Garrett
Right now all pstore accesses to efivars will delete or create new sysfs nodes. This is less than ideal if we've paniced or are rebooting, since we're in entirely the wrong context to do this kind of thing. Add the reason to the pstore callback and make sure we only manipulate the files if we're still going to be alive afterwards.
Signed-off-by Matthew Garrett<[email protected]>Reported-by Seiji Aguchi<[email protected]>--- drivers/acpi/apei/erst.c | 6 ++++-- drivers/firmware/efivars.c | 17 +++++++++++++---- fs/pstore/platform.c | 7 ++++--- include/linux/kmsg_dump.h | 1 + include/linux/pstore.h | 5 ++++- 5 files changed, 26 insertions(+), 10 deletions(-)drivers/acpi/apei/erst.c +4
-2@@ -934,7 +934,8 @@ static int erst_close_pstore(struct pstore_info *psi);static ssize_t erst_reader (u64 *id,enum pstore_type_id *type,struct timespec *time,struct pstore_info *psi);static u64 erst_writer (enum pstore_type_id type,unsigned int part, -size_t size,struct pstore_info *psi); +enum kmsg_dump_reason reason,size_t size, +struct pstore_info *psi);static int erst_clearer (enum pstore_type_id type,u64 id,struct pstore_info *psi);@@ -1041,7 +1042,8 @@ out: }static u64 erst_writer (enum pstore_type_id type,unsigned int part, -size_t size,struct pstore_info *psi) +enum kmsg_dump_reason reason,size_t size, +struct pstore_info *psi) {struct cper_pstore_record *rcd = (struct cper_pstore_record *) (erst_info.buf -sizeof (*rcd));drivers/firmware/efivars.c +13
-4@@ -491,7 +491,8 @@ static ssize_t efi_pstore_read(u64 *id, enum pstore_type_id *type, }static u64 efi_pstore_write (enum pstore_type_id type,unsigned int part, -size_t size,struct pstore_info *psi) +enum kmsg_dump_reason reason,size_t size, +struct pstore_info *psi) {char name[DUMP_NAME_LEN ];char stub_name[DUMP_NAME_LEN ];@@ -544,6 +545,14 @@ static u64 efi_pstore_write(enum pstore_type_id type, unsigned int part,spin_unlock (&efivars->lock); +/* +* If it's more severe than KMSG_DUMP_OOPS then we're already dead. +* Don't bother playing with sysfs. +*/ + +if (reason>KMSG_DUMP_OOPS ) +return part; +if (found)efivar_unregister (found);@@ -552,14 +561,13 @@ static u64 efi_pstore_write(enum pstore_type_id type, unsigned int part,utf16_strsize (efi_name,DUMP_NAME_LEN *2 ), efi_name,&vendor); -return part; };static int efi_pstore_erase (enum pstore_type_id type,u64 id,struct pstore_info *psi) { -efi_pstore_write (type, id,0 , psi); +efi_pstore_write (type, id,KMSG_DUMP_UNKNOWN ,0 , psi);return 0 ; }@@ -581,7 +589,8 @@ static ssize_t efi_pstore_read(u64 *id, enum pstore_type_id *type, }static u64 efi_pstore_write (enum pstore_type_id type,unsigned int part, -size_t size,struct pstore_info *psi) +enum kmsg_dump_reason reason,size_t size, +struct pstore_info *psi) {return 0 ; }fs/pstore/platform.c +3
-2@@ -51,7 +51,8 @@ void pstore_set_kmsg_bytes(int bytes)static int oopscount;static char *reason_str[] = { -"Oops" ,"Panic" ,"Kexec" ,"Restart" ,"Halt" ,"Poweroff" ,"Emergency" +"Unknown" ,"Oops" ,"Panic" ,"Kexec" ,"Restart" ,"Halt" ,"Poweroff" , +"Emergency" };/* @@ -97,7 +98,7 @@ static void pstore_dump(struct kmsg_dumper *dumper,memcpy (dst, s1 + s1_start, l1_cpy);memcpy (dst + l1_cpy, s2 + s2_start, l2_cpy); - id = psinfo->write (PSTORE_TYPE_DMESG , part, + id = psinfo->write (PSTORE_TYPE_DMESG , part, reason, hsize + l1_cpy + l2_cpy, psinfo);if (reason ==KMSG_DUMP_OOPS &&pstore_is_mounted ()) pstore_mkfile(PSTORE_TYPE_DMESG, psinfo->name, id,
fs/pstore/platform.c int pstore_write(enum pstore_type_id type, char *buf, size_t size) · line 211
Quoted 5 lines
fs/pstore/platform.c +1
-1@@ -207,7 +208,7 @@ int pstore_write(enum pstore_type_id type, char *buf, size_t size)mutex_lock (&psinfo->buf_mutex);memcpy (psinfo->buf, buf, size); - id = psinfo->write (type,0 , size, psinfo); + id = psinfo->write (type,0 ,KMSG_DUMP_UNKNOWN , size, psinfo);
I can't say it is wrong because no real caller for this function, but I can't say it is right, yet. KMSG_DUMP_UNKNOWN here looks too arbirary. Do you have any reason to use this type here ?
Quoted 38 lines
fs/pstore/platform.c +0
-0if (pstore_is_mounted ())pstore_mkfile (PSTORE_TYPE_DMESG , psinfo->name, id, psinfo->buf, size,CURRENT_TIME , psinfo);include/linux/kmsg_dump.h +1
-0@@ -16,6 +16,7 @@#include <linux/list.h> enum kmsg_dump_reason { +KMSG_DUMP_UNKNOWN ,KMSG_DUMP_OOPS ,KMSG_DUMP_PANIC ,KMSG_DUMP_KEXEC ,include/linux/pstore.h +4
-1@@ -22,6 +22,8 @@#ifndef _LINUX_PSTORE_H#define _LINUX_PSTORE_H +#include <linux/kmsg_dump.h> +/* types */ enum pstore_type_id { PSTORE_TYPE_DMESG = 0,@@ -40,7 +42,8 @@ struct pstore_info {ssize_t (*read)(u64 *id,enum pstore_type_id *type,struct timespec *time,struct pstore_info *psi);u64 (*write)(enum pstore_type_id type,unsigned int part, -size_t size,struct pstore_info *psi); +enum kmsg_dump_reason reason,size_t size, +struct pstore_info *psi);int (*erase)(enum pstore_type_id type,u64 id,struct pstore_info *psi);void *data;
Quoted 8 lines · Chen Gong
fs/pstore/platform.c int pstore_write(enum pstore_type_id type, char *buf, size_t size) · line 211
Quoted 4 lines
fs/pstore/platform.c +1
-1mutex_lock (&psinfo->buf_mutex);memcpy (psinfo->buf, buf, size); - id = psinfo->write (type,0 , size, psinfo); + id = psinfo->write (type,0 ,KMSG_DUMP_UNKNOWN , size, psinfo);I can't say it is wrong because no real caller for this function, but I can't say it is right, yet.
KMSG_DUMP_UNKNOWNhere looks too arbirary. Do you have any reason to use this type here ?
If a function calls pstore_write() directly then we have no type to associate with it. It seems worth making this explicit.
Signature · 1 line
Matthew Garrett | [email protected]
Quoted 10 lines · Matthew Garrett
Quoted 8 lines · Chen Gong
fs/pstore/platform.c int pstore_write(enum pstore_type_id type, char *buf, size_t size) · line 211
Quoted 4 lines
mutex_lock(&psinfo->buf_mutex); memcpy(psinfo->buf, buf, size);fs/pstore/platform.c +1
-1- id = psinfo->write (type,0 , size, psinfo); + id = psinfo->write (type,0 ,KMSG_DUMP_UNKNOWN , size, psinfo);I can't say it is wrong because no real caller for this function, but I can't say it is right, yet.
KMSG_DUMP_UNKNOWNhere looks too arbirary. Do you have any reason to use this type here ?
Quoted 3 lines
If a function calls
pstore_write()directly then we have no type to associate with it. It seems worth making this explicit.
Yep, that's the point. We hope to get a more reasonable method to do it, not any assumption.
Quoted 11 lines · Chen Gong
Quoted 10 lines · Matthew Garrett
Quoted 8 lines · Chen Gong
fs/pstore/platform.c int pstore_write(enum pstore_type_id type, char *buf, size_t size) · line 211
Quoted 4 lines
fs/pstore/platform.c +1
-1mutex_lock (&psinfo->buf_mutex);memcpy (psinfo->buf, buf, size); - id = psinfo->write (type,0 , size, psinfo); + id = psinfo->write (type,0 ,KMSG_DUMP_UNKNOWN , size, psinfo);I can't say it is wrong because no real caller for this function, but I can't say it is right, yet.
KMSG_DUMP_UNKNOWNhere looks too arbirary. Do you have any reason to use this type here ?
Quoted 5 lines
Quoted 2 lines
If a function calls
pstore_write()directly then we have no type to associate with it. It seems worth making this explicit.Yep, that's the point. We hope to get a more reasonable method to do it, not any assumption.
I'm afraid I don't understand. Could you give an example of how you think this should look?
Signature · 1 line
Matthew Garrett | [email protected]
Quoted 12 lines · Matthew Garrett
Quoted 11 lines · Chen Gong
Quoted 10 lines · Matthew Garrett
Quoted 8 lines · Chen Gong
fs/pstore/platform.c int pstore_write(enum pstore_type_id type, char *buf, size_t size) · line 211
Quoted 4 lines
mutex_lock(&psinfo->buf_mutex); memcpy(psinfo->buf, buf, size);fs/pstore/platform.c +1
-1- id = psinfo->write (type,0 , size, psinfo); + id = psinfo->write (type,0 ,KMSG_DUMP_UNKNOWN , size, psinfo);I can't say it is wrong because no real caller for this function, but I can't say it is right, yet.
KMSG_DUMP_UNKNOWNhere looks too arbirary. Do you have any reason to use this type here ?
Quoted 9 lines
Quoted 5 lines
Quoted 2 lines
If a function calls
pstore_write()directly then we have no type to associate with it. It seems worth making this explicit.Yep, that's the point. We hope to get a more reasonable method to do it, not any assumption.
I'm afraid I don't understand. Could you give an example of how you think this should look?
If you insist on your design, I prefer deleting the function pstore_write before applying your patch. We all know no real users to call this function, every backend will register Its own callback, so this function is useless at all.
Luck, Tony
reviewerQuoted 3 lines
If you insist on your design, I prefer deleting the function
pstore_writebefore applying your patch. We all know no real users to call this function, every backend will register Its own callback, so this function is useless at all.
We could do that. I threw in pstore_write without any particular use case in mind. Since there hasn't been a rush of people adding calls to it (and since it seems that pstore back ends have very limited amounts of space at their disposal, any use of pstore_write would probably cause problems for the dmesg dump model) removing it sounds like a good idea.
If someone does want to use it - they will have to figure out how to solve priority issues.
-Tony ���{.n�+�������+%�����ݶ��w��{.n�+����{��G�����{ay�ʇڙ�,j��f���h��������z_�(�階�ݢj"���m������G������?����&���~��iO��z��v�^�m����������?�I�
Quoted 16 lines
Quoted 16 lines
Quoted 15 lines
Quoted 10 lines
Quoted 9 lines
fs/pstore/platform.c int pstore_write(enum pstore_type_id type, char *buf, size_t size) · line 211
Quoted 5 lines
mutex_lock(&psinfo->buf_mutex); memcpy(psinfo->buf, buf, size);fs/pstore/platform.c +1
-1- id = psinfo->write (type,0 , size, psinfo); + id = psinfo->write (type,0 ,KMSG_DUMP_UNKNOWN , size, psinfo);I can't say it is wrong because no real caller for this function, but I can't say it is right, yet.
KMSG_DUMP_UNKNOWNhere looks too arbirary. Do you have any reason to use this type here ?Quoted 2 lines
If a function calls
pstore_write()directly then we have no type to associate with it. It seems worth making this explicit.Yep, that's the point. We hope to get a more reasonable method to do it, not any assumption.
Quoted 6 lines
Quoted 3 lines
I'm afraid I don't understand. Could you give an example of how you think this should look?
If you insist on your design, I prefer deleting the function
pstore_writebefore applying your patch. We all know no real users to call this function, every backend will register Its own callback, so this function is useless at all.
Matthew,
Do you plan to resend this patch?
Your patch will be accepted if you resend it,
because pstore_write() has been deleted by Kees.
Seiji ���{.n�+�������+%�����ݶ��w��{.n�+����{��G�����{ay�ʇڙ�,j��f���h��������z_�(�階�ݢj"���m������G������?����&���~��iO��z��v�^�m����������?�I�
Matthew
Quoted 1 line
Reported-by Seiji Aguchi <[email protected]>
Could you please change it to [email protected]?
Seiji
________________________________________
Right now all pstore accesses to efivars will delete or create new sysfs nodes. This is less than ideal if we've paniced or are rebooting, since we're in entirely the wrong context to do this kind of thing. Add the reason to the pstore callback and make sure we only manipulate the files if we're still going to be alive afterwards.
--- drivers/acpi/apei/erst.c | 6 ++++-- drivers/firmware/efivars.c | 17 +++++++++++++---- fs/pstore/platform.c | 7 ++++--- include/linux/kmsg_dump.h | 1 + include/linux/pstore.h | 5 ++++- 5 files changed, 26 insertions(+), 10 deletions(-)
drivers/acpi/apei/erst.c +4 -2
@@ -934,7 +934,8 @@ static int erst_close_pstore(struct pstore_info *psi);static ssize_t erst_reader (u64 *id,enum pstore_type_id *type,struct timespec *time,struct pstore_info *psi);static u64 erst_writer (enum pstore_type_id type,unsigned int part, -size_t size,struct pstore_info *psi); +enum kmsg_dump_reason reason,size_t size, +struct pstore_info *psi);static int erst_clearer (enum pstore_type_id type,u64 id,struct pstore_info *psi);
@@ -1041,7 +1042,8 @@ out: }static u64 erst_writer (enum pstore_type_id type,unsigned int part, -size_t size,struct pstore_info *psi) +enum kmsg_dump_reason reason,size_t size, +struct pstore_info *psi) {struct cper_pstore_record *rcd = (struct cper_pstore_record *) (erst_info.buf -sizeof (*rcd));
drivers/firmware/efivars.c +13 -4
@@ -491,7 +491,8 @@ static ssize_t efi_pstore_read(u64 *id, enum pstore_type_id *type, }static u64 efi_pstore_write (enum pstore_type_id type,unsigned int part, -size_t size,struct pstore_info *psi) +enum kmsg_dump_reason reason,size_t size, +struct pstore_info *psi) {char name[DUMP_NAME_LEN ];char stub_name[DUMP_NAME_LEN ];
@@ -544,6 +545,14 @@ static u64 efi_pstore_write(enum pstore_type_id type, unsigned int part,spin_unlock (&efivars->lock); +/* +* If it's more severe than KMSG_DUMP_OOPS then we're already dead. +* Don't bother playing with sysfs. +*/ + +if (reason >KMSG_DUMP_OOPS ) +return part; +if (found)efivar_unregister (found);
@@ -552,14 +561,13 @@ static u64 efi_pstore_write(enum pstore_type_id type, unsigned int part,utf16_strsize (efi_name,DUMP_NAME_LEN *2 ), efi_name, &vendor); -return part; };static int efi_pstore_erase (enum pstore_type_id type,u64 id,struct pstore_info *psi) { -efi_pstore_write (type, id,0 , psi); +efi_pstore_write (type, id,KMSG_DUMP_UNKNOWN ,0 , psi);return 0 ; }
@@ -581,7 +589,8 @@ static ssize_t efi_pstore_read(u64 *id, enum pstore_type_id *type, }static u64 efi_pstore_write (enum pstore_type_id type,unsigned int part, -size_t size,struct pstore_info *psi) +enum kmsg_dump_reason reason,size_t size, +struct pstore_info *psi) {return 0 ; }
fs/pstore/platform.c +4 -3
@@ -51,7 +51,8 @@ void pstore_set_kmsg_bytes(int bytes)static int oopscount;static char *reason_str[] = { -"Oops" ,"Panic" ,"Kexec" ,"Restart" ,"Halt" ,"Poweroff" ,"Emergency" +"Unknown" ,"Oops" ,"Panic" ,"Kexec" ,"Restart" ,"Halt" ,"Poweroff" , +"Emergency" };/*
@@ -97,7 +98,7 @@ static void pstore_dump(struct kmsg_dumper *dumper,memcpy (dst, s1 + s1_start, l1_cpy);memcpy (dst + l1_cpy, s2 + s2_start, l2_cpy); - id = psinfo->write (PSTORE_TYPE_DMESG , part, + id = psinfo->write (PSTORE_TYPE_DMESG , part, reason, hsize + l1_cpy + l2_cpy, psinfo);if (reason ==KMSG_DUMP_OOPS &&pstore_is_mounted ()) pstore_mkfile(PSTORE_TYPE_DMESG, psinfo->name, id,
@@ -207,7 +208,7 @@ int pstore_write(enum pstore_type_id type, char *buf, size_t size)mutex_lock (&psinfo->buf_mutex);memcpy (psinfo->buf, buf, size); - id = psinfo->write (type,0 , size, psinfo); + id = psinfo->write (type,0 ,KMSG_DUMP_UNKNOWN , size, psinfo);if (pstore_is_mounted ())pstore_mkfile (PSTORE_TYPE_DMESG , psinfo->name, id, psinfo->buf, size,CURRENT_TIME , psinfo);
include/linux/kmsg_dump.h +1 -0
@@ -16,6 +16,7 @@#include <linux/list.h> enum kmsg_dump_reason { +KMSG_DUMP_UNKNOWN ,KMSG_DUMP_OOPS ,KMSG_DUMP_PANIC ,KMSG_DUMP_KEXEC ,
include/linux/pstore.h +4 -1
@@ -22,6 +22,8 @@#ifndef _LINUX_PSTORE_H#define _LINUX_PSTORE_H +#include <linux/kmsg_dump.h> +/* types */ enum pstore_type_id { PSTORE_TYPE_DMESG = 0,
@@ -40,7 +42,8 @@ struct pstore_info {ssize_t (*read)(u64 *id,enum pstore_type_id *type,struct timespec *time,struct pstore_info *psi);u64 (*write)(enum pstore_type_id type,unsigned int part, -size_t size,struct pstore_info *psi); +enum kmsg_dump_reason reason,size_t size, +struct pstore_info *psi);int (*erase)(enum pstore_type_id type,u64 id,struct pstore_info *psi);void *data;
--
1.7.6.2
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to [email protected]
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/