History

Merge tag 'slab-for-6.0-rc4' of git://git.kernel.org/pub/scm/linux/kernel/git/vbabka/slab

Pull slab fix from Vlastimil Babka: - A fix from Waiman Long to avoid a theoretical deadlock reported by lockdep. * tag 'slab-for-6.0-rc4' of git://git.kernel.org/pub/scm/linux/kernel/git/vbabka/slab: mm/slab_common: Deleting kobject in kmem_cache_destroy() without holding slab_mutex/cpu_hotplug_lock

Linus Torvalds committed 4 years ago

Commit d3300762 parents 2880e1a 0495e331 file · +29 −16Browse files

Unified · Split

mm/slab_common.c+29−16
@@ -392,6 +392,28 @@ kmem_cache_create(const char *name, unsigned int size, unsigned int align, · 391 unmodified lines
392}392}
393EXPORT_SYMBOL(kmem_cache_create);393EXPORT_SYMBOL(kmem_cache_create);
394 394
395#ifdef SLAB_SUPPORTS_SYSFS
396/*
397 * For a given kmem_cache, kmem_cache_destroy() should only be called
398 * once or there will be a use-after-free problem. The actual deletion
399 * and release of the kobject does not need slab_mutex or cpu_hotplug_lock
400 * protection. So they are now done without holding those locks.
401 *
402 * Note that there will be a slight delay in the deletion of sysfs files
403 * if kmem_cache_release() is called indrectly from a work function.
404 */
405static void kmem_cache_release(struct kmem_cache *s)
406{
407 sysfs_slab_unlink(s);
408 sysfs_slab_release(s);
409}
410#else
411static void kmem_cache_release(struct kmem_cache *s)
412{
413 slab_kmem_cache_release(s);
414}
415#endif
416
395static void slab_caches_to_rcu_destroy_workfn(struct work_struct *work)417static void slab_caches_to_rcu_destroy_workfn(struct work_struct *work)
396{418{
397 LIST_HEAD(to_destroy);419 LIST_HEAD(to_destroy);
@@ -418,11 +440,7 @@ static void slab_caches_to_rcu_destroy_workfn(struct work_struct *work) · 20 unmodified lines
418 list_for_each_entry_safe(s, s2, &to_destroy, list) {440 list_for_each_entry_safe(s, s2, &to_destroy, list) {
419 debugfs_slab_release(s);441 debugfs_slab_release(s);
420 kfence_shutdown_cache(s);442 kfence_shutdown_cache(s);
421#ifdef SLAB_SUPPORTS_SYSFS443 kmem_cache_release(s);
422 sysfs_slab_release(s);
423#else
424 slab_kmem_cache_release(s);
425#endif
426 }444 }
427}445}
428 446
@@ -437,20 +455,11 @@ static int shutdown_cache(struct kmem_cache *s) · 8 unmodified lines
437 list_del(&s->list);455 list_del(&s->list);
438 456
439 if (s->flags & SLAB_TYPESAFE_BY_RCU) {457 if (s->flags & SLAB_TYPESAFE_BY_RCU) {
440#ifdef SLAB_SUPPORTS_SYSFS
441 sysfs_slab_unlink(s);
442#endif
443 list_add_tail(&s->list, &slab_caches_to_rcu_destroy);458 list_add_tail(&s->list, &slab_caches_to_rcu_destroy);
444 schedule_work(&slab_caches_to_rcu_destroy_work);459 schedule_work(&slab_caches_to_rcu_destroy_work);
445 } else {460 } else {
446 kfence_shutdown_cache(s);461 kfence_shutdown_cache(s);
447 debugfs_slab_release(s);462 debugfs_slab_release(s);
448#ifdef SLAB_SUPPORTS_SYSFS
449 sysfs_slab_unlink(s);
450 sysfs_slab_release(s);
451#else
452 slab_kmem_cache_release(s);
453#endif
454 }463 }
455 464
456 return 0;465 return 0;
@@ -465,14 +474,16 @@ void slab_kmem_cache_release(struct kmem_cache *s) · 8 unmodified lines
465 474
466void kmem_cache_destroy(struct kmem_cache *s)475void kmem_cache_destroy(struct kmem_cache *s)
467{476{
477 int refcnt;
478
468 if (unlikely(!s) || !kasan_check_byte(s))479 if (unlikely(!s) || !kasan_check_byte(s))
469 return;480 return;
470 481
471 cpus_read_lock();482 cpus_read_lock();
472 mutex_lock(&slab_mutex);483 mutex_lock(&slab_mutex);
473 484
474 s->refcount--;485 refcnt = --s->refcount;
475 if (s->refcount)486 if (refcnt)
476 goto out_unlock;487 goto out_unlock;
477 488
478 WARN(shutdown_cache(s),489 WARN(shutdown_cache(s),
@@ -481,6 +492,8 @@ void kmem_cache_destroy(struct kmem_cache *s) · 2 unmodified lines
481out_unlock:492out_unlock:
482 mutex_unlock(&slab_mutex);493 mutex_unlock(&slab_mutex);
483 cpus_read_unlock();494 cpus_read_unlock();
495 if (!refcnt && !(s->flags & SLAB_TYPESAFE_BY_RCU))
496 kmem_cache_release(s);
484}497}
485EXPORT_SYMBOL(kmem_cache_destroy);498EXPORT_SYMBOL(kmem_cache_destroy);
486 499

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