Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

efi: pstore: move workqueue handling out of efivars

The worker thread that gets kicked off to sync the state of the
EFI variable list is only used by the EFI pstore implementation,
and is defined in its source file. So let's move its scheduling
there as well. Since our efivar_init() scan will bail on duplicate
entries, there is no need to disable the workqueue like we did
before, so we can run it unconditionally.

Signed-off-by: Ard Biesheuvel <ardb@kernel.org>

+5 -26
+5 -2
drivers/firmware/efi/efi-pstore.c
··· 21 21 EFI_VARIABLE_RUNTIME_ACCESS) 22 22 23 23 static LIST_HEAD(efi_pstore_list); 24 + static DECLARE_WORK(efivar_work, NULL); 24 25 25 26 static int efi_pstore_open(struct pstore_info *psi) 26 27 { ··· 268 267 ret = efivar_entry_set_safe(efi_name, vendor, PSTORE_EFI_ATTRIBUTES, 269 268 preemptible(), record->size, record->psi->buf); 270 269 271 - if (record->reason == KMSG_DUMP_OOPS) 272 - efivar_run_worker(); 270 + if (record->reason == KMSG_DUMP_OOPS && try_module_get(THIS_MODULE)) 271 + if (!schedule_work(&efivar_work)) 272 + module_put(THIS_MODULE); 273 273 274 274 return ret; 275 275 }; ··· 414 412 } 415 413 416 414 kfree(entry); 415 + module_put(THIS_MODULE); 417 416 } 418 417 419 418 static __init int efivars_pstore_init(void)
-21
drivers/firmware/efi/vars.c
··· 32 32 */ 33 33 static DEFINE_SEMAPHORE(efivars_lock); 34 34 35 - static bool efivar_wq_enabled = true; 36 - DECLARE_WORK(efivar_work, NULL); 37 - EXPORT_SYMBOL_GPL(efivar_work); 38 - 39 35 static bool 40 36 validate_device_path(efi_char16_t *var_name, int match, u8 *buffer, 41 37 unsigned long len) ··· 386 390 { 387 391 size_t i, len8 = len16 / sizeof(efi_char16_t); 388 392 char *str8; 389 - 390 - /* 391 - * Disable the workqueue since the algorithm it uses for 392 - * detecting new variables won't work with this buggy 393 - * implementation of GetNextVariableName(). 394 - */ 395 - efivar_wq_enabled = false; 396 393 397 394 str8 = kzalloc(len8, GFP_KERNEL); 398 395 if (!str8) ··· 1145 1156 return __efivars->kobject; 1146 1157 } 1147 1158 EXPORT_SYMBOL_GPL(efivars_kobject); 1148 - 1149 - /** 1150 - * efivar_run_worker - schedule the efivar worker thread 1151 - */ 1152 - void efivar_run_worker(void) 1153 - { 1154 - if (efivar_wq_enabled) 1155 - schedule_work(&efivar_work); 1156 - } 1157 - EXPORT_SYMBOL_GPL(efivar_run_worker); 1158 1159 1159 1160 /** 1160 1161 * efivars_register - register an efivars
-3
include/linux/efi.h
··· 1037 1037 bool efivar_variable_is_removable(efi_guid_t vendor, const char *name, 1038 1038 size_t len); 1039 1039 1040 - extern struct work_struct efivar_work; 1041 - void efivar_run_worker(void); 1042 - 1043 1040 #if defined(CONFIG_EFI_VARS) || defined(CONFIG_EFI_VARS_MODULE) 1044 1041 int efivars_sysfs_init(void); 1045 1042