[RHEL7,COMMIT] scsi: don't allocate memory under spinlock in scsi_register_device_handler()

Submitted by Konstantin Khorenko on Aug. 20, 2018, 7:49 a.m.

Details

Message ID 201808200749.w7K7nB11002040@finist_ce7.work
State New
Series "scsi: don't allocate memory under spinlock in scsi_register_device_handler()"
Headers show

Commit Message

Konstantin Khorenko Aug. 20, 2018, 7:49 a.m.
The commit is pushed to "branch-rh7-3.10.0-862.11.6.vz7.64.x-ovz" and will appear at https://src.openvz.org/scm/ovz/vzkernel.git
after rh7-3.10.0-862.11.6.vz7.64.4
------>
commit cc2e7a1d6e016832af7847cce30faf66890d7d99
Author: Konstantin Khorenko <khorenko@virtuozzo.com>
Date:   Mon Aug 20 10:41:50 2018 +0300

    scsi: don't allocate memory under spinlock in scsi_register_device_handler()
    
    scsi_register_device_handler
     spin_lock(&list_lock)
     kzalloc
      kmalloc
       kmem_cache_alloc_trace
        slab_alloc
         cache_alloc_debugcheck_before
          might_sleep_if
           might_sleep
            might_resched
             _cond_resched
    
    This is a pure RedHat code, mainstream does not have it.
    Moveover if kzalloc() fails, we return with list_lock not released.
    
    Fix it by allocating memory outside of spinlock.
    
    https://jira.sw.ru/browse/PSBM-87859
    
    Signed-off-by: Konstantin Khorenko <khorenko@virtuozzo.com>
---
 drivers/scsi/device_handler/scsi_dh.c | 6 ++++--
 1 file changed, 4 insertions(+), 2 deletions(-)

Patch hide | download patch | download mbox

diff --git a/drivers/scsi/device_handler/scsi_dh.c b/drivers/scsi/device_handler/scsi_dh.c
index 147827832aad..dc1cdf3f3090 100644
--- a/drivers/scsi/device_handler/scsi_dh.c
+++ b/drivers/scsi/device_handler/scsi_dh.c
@@ -365,7 +365,6 @@  int scsi_register_device_handler(struct scsi_device_handler *scsi_dh,
 	if (!scsi_dh->attach || !scsi_dh->detach)
 		return -EINVAL;
 
-	spin_lock(&list_lock);
 	if (scsi_dh_aux_src) {
 		scsi_dh_aux = kzalloc(sizeof(struct scsi_device_handler_aux), GFP_KERNEL);
 		if (!scsi_dh_aux)
@@ -373,8 +372,11 @@  int scsi_register_device_handler(struct scsi_device_handler *scsi_dh,
 
 		memcpy(scsi_dh_aux, scsi_dh_aux_src, scsi_dh_aux_src_size);
 		scsi_dh_aux->scsi_dh = scsi_dh;
-		list_add(&scsi_dh_aux->list, &scsi_dh_aux_list);
 	}
+
+	spin_lock(&list_lock);
+	if (scsi_dh_aux_src)
+		list_add(&scsi_dh_aux->list, &scsi_dh_aux_list);
 	list_add(&scsi_dh->list, &scsi_dh_list);
 	spin_unlock(&list_lock);