The patch titled Subject: proc/kcore: replace kclist_lock rwlock with rwsem has been added to the -mm tree. Its filename is proc-kcore-replace-kclist_lock-rwlock-with-rwsem.patch This patch should soon appear at http://ozlabs.org/~akpm/mmots/broken-out/proc-kcore-replace-kclist_lock-rwlock-with-rwsem.patch and later at http://ozlabs.org/~akpm/mmotm/broken-out/proc-kcore-replace-kclist_lock-rwlock-with-rwsem.patch Before you just go and hit "reply", please: a) Consider who else should be cc'ed b) Prefer to cc a suitable mailing list as well c) Ideally: find the original patch on the mailing list and do a reply-to-all to that, adding suitable additional cc's *** Remember to use Documentation/process/submit-checklist.rst when testing your code *** The -mm tree is included into linux-next and is updated there every 3-4 working days ------------------------------------------------------ From: Omar Sandoval <osandov@xxxxxx> Subject: proc/kcore: replace kclist_lock rwlock with rwsem Now we only need kclist_lock from user context and at fs init time, and the following changes need to sleep while holding the kclist_lock. Link: http://lkml.kernel.org/r/783ba3becc424db45e5d5c93559fc40ef6173f01.1531440458.git.osandov@xxxxxx Signed-off-by: Omar Sandoval <osandov@xxxxxx> Reviewed-by: Andrew Morton <akpm@xxxxxxxxxxxxxxxxxxxx> Cc: Alexey Dobriyan <adobriyan@xxxxxxxxx> Cc: Bhupesh Sharma <bhsharma@xxxxxxxxxx> Cc: Eric Biederman <ebiederm@xxxxxxxxxxxx> Cc: James Morse <james.morse@xxxxxxx> Signed-off-by: Andrew Morton <akpm@xxxxxxxxxxxxxxxxxxxx> --- diff -puN fs/proc/kcore.c~proc-kcore-replace-kclist_lock-rwlock-with-rwsem fs/proc/kcore.c --- a/fs/proc/kcore.c~proc-kcore-replace-kclist_lock-rwlock-with-rwsem +++ a/fs/proc/kcore.c @@ -59,8 +59,8 @@ struct memelfnote }; static LIST_HEAD(kclist_head); -static DEFINE_RWLOCK(kclist_lock); -static int kcore_need_update = 1; +static DECLARE_RWSEM(kclist_lock); +static atomic_t kcore_need_update = ATOMIC_INIT(1); /* This doesn't grab kclist_lock, so it should only be used at init time. */ void __init @@ -117,8 +117,8 @@ static void __kcore_update_ram(struct li struct kcore_list *tmp, *pos; LIST_HEAD(garbage); - write_lock(&kclist_lock); - if (kcore_need_update) { + down_write(&kclist_lock); + if (atomic_cmpxchg(&kcore_need_update, 1, 0)) { list_for_each_entry_safe(pos, tmp, &kclist_head, list) { if (pos->type == KCORE_RAM || pos->type == KCORE_VMEMMAP) @@ -127,9 +127,8 @@ static void __kcore_update_ram(struct li list_splice_tail(list, &kclist_head); } else list_splice(list, &garbage); - kcore_need_update = 0; proc_root_kcore->size = get_kcore_size(&nphdr, &size); - write_unlock(&kclist_lock); + up_write(&kclist_lock); free_kclist_ents(&garbage); } @@ -452,11 +451,11 @@ read_kcore(struct file *file, char __use int nphdr; unsigned long start; - read_lock(&kclist_lock); + down_read(&kclist_lock); size = get_kcore_size(&nphdr, &elf_buflen); if (buflen == 0 || *fpos >= size) { - read_unlock(&kclist_lock); + up_read(&kclist_lock); return 0; } @@ -473,11 +472,11 @@ read_kcore(struct file *file, char __use tsz = buflen; elf_buf = kzalloc(elf_buflen, GFP_ATOMIC); if (!elf_buf) { - read_unlock(&kclist_lock); + up_read(&kclist_lock); return -ENOMEM; } elf_kcore_store_hdr(elf_buf, nphdr, elf_buflen); - read_unlock(&kclist_lock); + up_read(&kclist_lock); if (copy_to_user(buffer, elf_buf + *fpos, tsz)) { kfree(elf_buf); return -EFAULT; @@ -492,7 +491,7 @@ read_kcore(struct file *file, char __use if (buflen == 0) return acc; } else - read_unlock(&kclist_lock); + up_read(&kclist_lock); /* * Check to see if our file offset matches with any of @@ -505,12 +504,12 @@ read_kcore(struct file *file, char __use while (buflen) { struct kcore_list *m; - read_lock(&kclist_lock); + down_read(&kclist_lock); list_for_each_entry(m, &kclist_head, list) { if (start >= m->addr && start < (m->addr+m->size)) break; } - read_unlock(&kclist_lock); + up_read(&kclist_lock); if (&m->list == &kclist_head) { if (clear_user(buffer, tsz)) @@ -563,7 +562,7 @@ static int open_kcore(struct inode *inod if (!filp->private_data) return -ENOMEM; - if (kcore_need_update) + if (atomic_read(&kcore_need_update)) kcore_update_ram(); if (i_size_read(inode) != proc_root_kcore->size) { inode_lock(inode); @@ -593,9 +592,8 @@ static int __meminit kcore_callback(stru switch (action) { case MEM_ONLINE: case MEM_OFFLINE: - write_lock(&kclist_lock); - kcore_need_update = 1; - write_unlock(&kclist_lock); + atomic_set(&kcore_need_update, 1); + break; } return NOTIFY_OK; } _ Patches currently in -mm which might be from osandov@xxxxxx are proc-kcore-dont-grab-lock-for-kclist_add.patch proc-kcore-replace-kclist_lock-rwlock-with-rwsem.patch proc-kcore-fix-memory-hotplug-vs-multiple-opens-race.patch proc-kcore-hold-lock-during-read.patch proc-kcore-clean-up-elf-header-generation.patch proc-kcore-optimize-multiple-page-reads.patch proc-kcore-add-vmcoreinfo-note-to-proc-kcore.patch -- To unsubscribe from this list: send the line "unsubscribe mm-commits" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html