History

Crash: add lock to serialize crash hotplug handling

Eric reported that handling corresponding crash hotplug event can be failed easily when many memory hotplug event are notified in a short period. They failed because failing to take __kexec_lock. ======= [ 78.714569] Fallback order for Node 0: 0 [ 78.714575] Built 1 zonelists, mobility grouping on. Total pages: 1817886 [ 78.717133] Policy zone: Normal [ 78.724423] crash hp: kexec_trylock() failed, elfcorehdr may be inaccurate [ 78.727207] crash hp: kexec_trylock() failed, elfcorehdr may be inaccurate [ 80.056643] PEFILE: Unsigned PE binary ======= The memory hotplug events are notified very quickly and very many, while the handling of crash hotplug is much slower relatively. So the atomic variable __kexec_lock and kexec_trylock() can't guarantee the serialization of crash hotplug handling. Here, add a new mutex lock __crash_hotplug_lock to serialize crash hotplug handling specifically. This doesn't impact the usage of __kexec_lock.

Baoquan He committed 3 years ago

Commit e2a8f201 parent bbe246f1 file · +17 −0Browse files

Unified · Split

kernel/crash_core.c+17−0
@@ -739,6 +739,17 @@ subsys_initcall(crash_notes_memory_init); · 738 unmodified lines
739#undef pr_fmt739#undef pr_fmt
740#define pr_fmt(fmt) "crash hp: " fmt740#define pr_fmt(fmt) "crash hp: " fmt
741 741
742/*
743 * Different than kexec/kdump loading/unloading/jumping/shrinking which
744 * usually rarely happen, there will be many crash hotplug events notified
745 * during one short period, e.g one memory board is hot added and memory
746 * regions are online. So mutex lock __crash_hotplug_lock is used to
747 * serialize the crash hotplug handling specifically.
748 */
749DEFINE_MUTEX(__crash_hotplug_lock);
750#define crash_hotplug_lock() mutex_lock(&__crash_hotplug_lock)
751#define crash_hotplug_unlock() mutex_unlock(&__crash_hotplug_lock)
752
742/*753/*
743 * This routine utilized when the crash_hotplug sysfs node is read.754 * This routine utilized when the crash_hotplug sysfs node is read.
744 * It reflects the kernel's ability/permission to update the crash755 * It reflects the kernel's ability/permission to update the crash
@@ -748,9 +759,11 @@ int crash_check_update_elfcorehdr(void) · 3 unmodified lines
748{759{
749 int rc = 0;760 int rc = 0;
750 761
762 crash_hotplug_lock();
751 /* Obtain lock while reading crash information */763 /* Obtain lock while reading crash information */
752 if (!kexec_trylock()) {764 if (!kexec_trylock()) {
753 pr_info("kexec_trylock() failed, elfcorehdr may be inaccurate\n");765 pr_info("kexec_trylock() failed, elfcorehdr may be inaccurate\n");
766 crash_hotplug_unlock();
754 return 0;767 return 0;
755 }768 }
756 if (kexec_crash_image) {769 if (kexec_crash_image) {
@@ -761,6 +774,7 @@ int crash_check_update_elfcorehdr(void) · 4 unmodified lines
761 }774 }
762 /* Release lock now that update complete */775 /* Release lock now that update complete */
763 kexec_unlock();776 kexec_unlock();
777 crash_hotplug_unlock();
764 778
765 return rc;779 return rc;
766}780}
@@ -783,9 +797,11 @@ static void crash_handle_hotplug_event(unsigned int hp_action, unsigned int cpu) · 16 unmodified lines
783{797{
784 struct kimage *image;798 struct kimage *image;
785 799
800 crash_hotplug_lock();
786 /* Obtain lock while changing crash information */801 /* Obtain lock while changing crash information */
787 if (!kexec_trylock()) {802 if (!kexec_trylock()) {
788 pr_info("kexec_trylock() failed, elfcorehdr may be inaccurate\n");803 pr_info("kexec_trylock() failed, elfcorehdr may be inaccurate\n");
804 crash_hotplug_unlock();
789 return;805 return;
790 }806 }
791 807
@@ -852,6 +868,7 @@ static void crash_handle_hotplug_event(unsigned int hp_action, unsigned int cpu) · 60 unmodified lines
852out:868out:
853 /* Release lock now that update complete */869 /* Release lock now that update complete */
854 kexec_unlock();870 kexec_unlock();
871 crash_hotplug_unlock();
855}872}
856 873
857static int crash_memhp_notifier(struct notifier_block *nb, unsigned long val, void *v)874static int crash_memhp_notifier(struct notifier_block *nb, unsigned long val, void *v)

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t