Sign Up
Log In
Log In
or
Sign Up
Places
All Projects
Status Monitor
Collapse sidebar
SUSE:SLE-15-SP5:GA
drbd.24681
drbd-Fix-locking-for-the-drbd_devices-idr.patch
Overview
Repositories
Revisions
Requests
Users
Attributes
Meta
File drbd-Fix-locking-for-the-drbd_devices-idr.patch of Package drbd.24681
From f7e77b8e3222dbc62973eb1c7bb9230668877543 Mon Sep 17 00:00:00 2001 From: Philipp Reisner <philipp.reisner@linbit.com> Date: Wed, 26 May 2021 10:39:46 +0200 Subject: [PATCH] drbd: Fix locking for the drbd_devices idr The call graphs that modify the drbd_devices idr are: drbd_adm_new_minor() drbd_create_device() idr_alloc(&drbd_devices, ) adm_del_minor() drbd_unregister_device() idr_remove(&drbd_devices, ) Since enabling the use of using parallel_ops (August 2016, commit ccb4c56c) there was no locking that protected idr_alloc() and idr_remove() running in paralle on multiple CPUs. --- drbd/drbd_int.h | 2 +- drbd/drbd_main.c | 7 +++++++ 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/drbd/drbd_int.h b/drbd/drbd_int.h index a4f4ce80..0f7c3b0c 100644 --- a/drbd/drbd_int.h +++ b/drbd/drbd_int.h @@ -138,7 +138,7 @@ drbd_insert_fault(struct drbd_device *device, unsigned int type) { (typecheck(struct drbd_device*, x) && \ ((x) ? (((x)->magic ^ DRBD_MAGIC) == (long)(x)) : 0)) -extern struct idr drbd_devices; /* RCU, updates: genl_lock() */ +extern struct idr drbd_devices; /* RCU, updates: drbd_devices_lock */ extern struct list_head drbd_resources; /* RCU, updates: resources_mutex */ extern struct mutex resources_mutex; diff --git a/drbd/drbd_main.c b/drbd/drbd_main.c index 0636adf0..1e325aed 100644 --- a/drbd/drbd_main.c +++ b/drbd/drbd_main.c @@ -134,6 +134,7 @@ module_param_named(protocol_version_min, drbd_protocol_version_min, drbd_protoco */ struct idr drbd_devices; struct list_head drbd_resources; +DEFINE_SPINLOCK(drbd_devices_lock); DEFINE_MUTEX(resources_mutex); struct kmem_cache *drbd_request_cache; @@ -3767,7 +3768,9 @@ enum drbd_ret_code drbd_create_device(struct drbd_config_context *adm_ctx, unsig locked = true; spin_lock_irq(&resource->req_lock); + spin_lock(&drbd_devices_lock); id = idr_alloc(&drbd_devices, device, minor, minor + 1, GFP_NOWAIT); + spin_unlock(&drbd_devices_lock); if (id < 0) { if (id == -ENOSPC) err = ERR_MINOR_OR_VOLUME_EXISTS; @@ -3841,7 +3844,9 @@ out_remove_peer_device: kref_debug_put(&device->kref_debug, 1); out_idr_remove_minor: + spin_lock(&drbd_devices_lock); idr_remove(&drbd_devices, minor); + spin_unlock(&drbd_devices_lock); kref_debug_put(&device->kref_debug, 1); out_no_minor_idr: if (locked) @@ -3889,7 +3894,9 @@ void drbd_unregister_device(struct drbd_device *device) idr_remove(&connection->peer_devices, device->vnr); } idr_remove(&resource->devices, device->vnr); + spin_lock(&drbd_devices_lock); idr_remove(&drbd_devices, device->minor); + spin_unlock(&drbd_devices_lock); spin_unlock_irq(&resource->req_lock); for_each_peer_device(peer_device, device) -- 2.16.4
Locations
Projects
Search
Status Monitor
Help
OpenBuildService.org
Documentation
API Documentation
Code of Conduct
Contact
Support
@OBShq
Terms
openSUSE Build Service is sponsored by
The Open Build Service is an
openSUSE project
.
Sign Up
Log In
Places
Places
All Projects
Status Monitor