Skip to content

Commit 51a8588

Browse files
MerlijnWajermartinkpetersen
authored andcommitted
scsi: sr: get rid of sr global mutex
When replacing the Big Kernel Lock in commit 2a48fc0 ("block: autoconvert trivial BKL users to private mutex"), the lock was replaced with a sr-wide lock. This causes very poor performance when using multiple sr devices, as the sr driver was not able to execute more than one command to one drive at any given time, even when there were many CD drives available. Replace the global mutex with per-sr-device mutex. Someone tried this patch at the time, but it never made it upstream, due to possible concerns with race conditions, but it's not clear the patch actually caused those: https://www.spinics.net/lists/linux-scsi/msg63706.html https://www.spinics.net/lists/linux-scsi/msg63750.html Also see http://lists.xiph.org/pipermail/paranoia/2019-December/001647.html Link: https://lore.kernel.org/r/20200218143918.30267-1-merlijn@archive.org Acked-by: Arnd Bergmann <arnd@arndb.de> Signed-off-by: Merlijn Wajer <merlijn@archive.org> Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
1 parent 679b2ec commit 51a8588

File tree

2 files changed

+13
-9
lines changed

2 files changed

+13
-9
lines changed

drivers/scsi/sr.c

Lines changed: 11 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -79,7 +79,6 @@ MODULE_ALIAS_SCSI_DEVICE(TYPE_WORM);
7979
CDC_CD_R|CDC_CD_RW|CDC_DVD|CDC_DVD_R|CDC_DVD_RAM|CDC_GENERIC_PACKET| \
8080
CDC_MRW|CDC_MRW_W|CDC_RAM)
8181

82-
static DEFINE_MUTEX(sr_mutex);
8382
static int sr_probe(struct device *);
8483
static int sr_remove(struct device *);
8584
static blk_status_t sr_init_command(struct scsi_cmnd *SCpnt);
@@ -536,9 +535,9 @@ static int sr_block_open(struct block_device *bdev, fmode_t mode)
536535
scsi_autopm_get_device(sdev);
537536
check_disk_change(bdev);
538537

539-
mutex_lock(&sr_mutex);
538+
mutex_lock(&cd->lock);
540539
ret = cdrom_open(&cd->cdi, bdev, mode);
541-
mutex_unlock(&sr_mutex);
540+
mutex_unlock(&cd->lock);
542541

543542
scsi_autopm_put_device(sdev);
544543
if (ret)
@@ -551,10 +550,10 @@ static int sr_block_open(struct block_device *bdev, fmode_t mode)
551550
static void sr_block_release(struct gendisk *disk, fmode_t mode)
552551
{
553552
struct scsi_cd *cd = scsi_cd(disk);
554-
mutex_lock(&sr_mutex);
553+
mutex_lock(&cd->lock);
555554
cdrom_release(&cd->cdi, mode);
556555
scsi_cd_put(cd);
557-
mutex_unlock(&sr_mutex);
556+
mutex_unlock(&cd->lock);
558557
}
559558

560559
static int sr_block_ioctl(struct block_device *bdev, fmode_t mode, unsigned cmd,
@@ -565,7 +564,7 @@ static int sr_block_ioctl(struct block_device *bdev, fmode_t mode, unsigned cmd,
565564
void __user *argp = (void __user *)arg;
566565
int ret;
567566

568-
mutex_lock(&sr_mutex);
567+
mutex_lock(&cd->lock);
569568

570569
ret = scsi_ioctl_block_when_processing_errors(sdev, cmd,
571570
(mode & FMODE_NDELAY) != 0);
@@ -595,7 +594,7 @@ static int sr_block_ioctl(struct block_device *bdev, fmode_t mode, unsigned cmd,
595594
scsi_autopm_put_device(sdev);
596595

597596
out:
598-
mutex_unlock(&sr_mutex);
597+
mutex_unlock(&cd->lock);
599598
return ret;
600599
}
601600

@@ -608,7 +607,7 @@ static int sr_block_compat_ioctl(struct block_device *bdev, fmode_t mode, unsign
608607
void __user *argp = compat_ptr(arg);
609608
int ret;
610609

611-
mutex_lock(&sr_mutex);
610+
mutex_lock(&cd->lock);
612611

613612
ret = scsi_ioctl_block_when_processing_errors(sdev, cmd,
614613
(mode & FMODE_NDELAY) != 0);
@@ -638,7 +637,7 @@ static int sr_block_compat_ioctl(struct block_device *bdev, fmode_t mode, unsign
638637
scsi_autopm_put_device(sdev);
639638

640639
out:
641-
mutex_unlock(&sr_mutex);
640+
mutex_unlock(&cd->lock);
642641
return ret;
643642

644643
}
@@ -745,6 +744,7 @@ static int sr_probe(struct device *dev)
745744
disk = alloc_disk(1);
746745
if (!disk)
747746
goto fail_free;
747+
mutex_init(&cd->lock);
748748

749749
spin_lock(&sr_index_lock);
750750
minor = find_first_zero_bit(sr_index_bits, SR_DISKS);
@@ -1055,6 +1055,8 @@ static void sr_kref_release(struct kref *kref)
10551055

10561056
put_disk(disk);
10571057

1058+
mutex_destroy(&cd->lock);
1059+
10581060
kfree(cd);
10591061
}
10601062

drivers/scsi/sr.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020

2121
#include <linux/genhd.h>
2222
#include <linux/kref.h>
23+
#include <linux/mutex.h>
2324

2425
#define MAX_RETRIES 3
2526
#define SR_TIMEOUT (30 * HZ)
@@ -51,6 +52,7 @@ typedef struct scsi_cd {
5152
bool ignore_get_event:1; /* GET_EVENT is unreliable, use TUR */
5253

5354
struct cdrom_device_info cdi;
55+
struct mutex lock;
5456
/* We hold gendisk and scsi_device references on probe and use
5557
* the refs on this kref to decide when to release them */
5658
struct kref kref;

0 commit comments

Comments
 (0)