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

Configure Feed

Select the types of activity you want to include in your feed.

fs/proc/vmcore: convert vmcore_cb_lock into vmcore_mutex

We want to protect vmcore modifications from concurrent opening of
the vmcore, and also serialize vmcore modification.

(a) We can currently modify the vmcore after it was opened. This can happen
if a vmcoredd is added after the vmcore module was initialized and
already opened by user space. We want to fix that and prepare for
new code wanting to serialize against concurrent opening.

(b) To handle it cleanly we need to protect the modifications against
concurrent opening. As the modifications end up allocating memory and
can sleep, we cannot rely on the spinlock.

Let's convert the spinlock into a mutex to prepare for further changes.

Signed-off-by: David Hildenbrand <david@redhat.com>
Message-Id: <20241204125444.1734652-2-david@redhat.com>
Acked-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>

authored by

David Hildenbrand and committed by
Michael S. Tsirkin
cdbc6971 33bb2d16

+8 -7
+8 -7
fs/proc/vmcore.c
··· 62 62 /* Device Dump Size */ 63 63 static size_t vmcoredd_orig_sz; 64 64 65 - static DEFINE_SPINLOCK(vmcore_cb_lock); 65 + static DEFINE_MUTEX(vmcore_mutex); 66 + 66 67 DEFINE_STATIC_SRCU(vmcore_cb_srcu); 67 68 /* List of registered vmcore callbacks. */ 68 69 static LIST_HEAD(vmcore_cb_list); ··· 73 72 void register_vmcore_cb(struct vmcore_cb *cb) 74 73 { 75 74 INIT_LIST_HEAD(&cb->next); 76 - spin_lock(&vmcore_cb_lock); 75 + mutex_lock(&vmcore_mutex); 77 76 list_add_tail(&cb->next, &vmcore_cb_list); 78 77 /* 79 78 * Registering a vmcore callback after the vmcore was opened is ··· 81 80 */ 82 81 if (vmcore_opened) 83 82 pr_warn_once("Unexpected vmcore callback registration\n"); 84 - spin_unlock(&vmcore_cb_lock); 83 + mutex_unlock(&vmcore_mutex); 85 84 } 86 85 EXPORT_SYMBOL_GPL(register_vmcore_cb); 87 86 88 87 void unregister_vmcore_cb(struct vmcore_cb *cb) 89 88 { 90 - spin_lock(&vmcore_cb_lock); 89 + mutex_lock(&vmcore_mutex); 91 90 list_del_rcu(&cb->next); 92 91 /* 93 92 * Unregistering a vmcore callback after the vmcore was opened is ··· 96 95 */ 97 96 if (vmcore_opened) 98 97 pr_warn_once("Unexpected vmcore callback unregistration\n"); 99 - spin_unlock(&vmcore_cb_lock); 98 + mutex_unlock(&vmcore_mutex); 100 99 101 100 synchronize_srcu(&vmcore_cb_srcu); 102 101 } ··· 121 120 122 121 static int open_vmcore(struct inode *inode, struct file *file) 123 122 { 124 - spin_lock(&vmcore_cb_lock); 123 + mutex_lock(&vmcore_mutex); 125 124 vmcore_opened = true; 126 - spin_unlock(&vmcore_cb_lock); 125 + mutex_unlock(&vmcore_mutex); 127 126 128 127 return 0; 129 128 }