From: Douglas Gilbert <dgilbert@interlog.com>
To: Hannes Reinecke <hare@suse.de>,
"Martin K. Petersen" <martin.petersen@oracle.com>
Cc: Christoph Hellwig <hch@lst.de>,
Daniel Wagner <daniel.wagner@suse.com>,
Johannes Thumshirn <johannes.thumshirn@wdc.com>,
James Bottomley <james.bottomley@hansenpartnership.com>,
linux-scsi@vger.kernel.org
Subject: Re: [PATCHv3 0/4] scsi: use xarray ... scsi_alloc_target()
Date: Fri, 29 May 2020 00:21:34 -0400 [thread overview]
Message-ID: <966f816a-d66e-e58f-d764-aeacf5026adf@interlog.com> (raw)
In-Reply-To: <20200528163625.110184-1-hare@suse.de>
[-- Attachment #1: Type: text/plain, Size: 1202 bytes --]
Hannes,
I believe scsi_alloc_target() is broken in the found_target case.
For starters starget is created, built and _not_ put in the xarray,
hence it is leaked? Seems to me that the code shouldn't go
as far as it does before it detects the found_target case.
What I'm seeing in testing (script attached) after applying my
patches outlined in earlier posts (second attachment) is that
LUN 0 is missing on all targets within a host apart from
target_id==0 . For example:
# modprobe scsi_debug ptype=0x9 no_uld=1 max_luns=2 num_tgts=2
# lsscsi -gs
[0:0:0:0] comms Linux scsi_debug 0189 - /dev/sg0 -
[0:0:0:1] comms Linux scsi_debug 0189 - /dev/sg1 -
[0:0:1:1] comms Linux scsi_debug 0189 - /dev/sg2 -
[N:0:1:1] disk INTEL SSDPEKKF256G7L__1 /dev/nvme0n1 - 256GB
# sg_luns /dev/sg2
Lun list length = 16 which imples 2 lun entries
Report luns [select_report=0x0]:
0000000000000000
0001000000000000
So where did [0:0:1:0] go? The response to REPORT LUNS says it should
be there.
I thought about jumping into scsi_alloc_target() but it is horribly
complicated, so I'll let you deal with it :-)
Doug Gilbert
[-- Attachment #2: tst_sdebug_modpr_rmmod.sh --]
[-- Type: application/x-shellscript, Size: 808 bytes --]
[-- Attachment #3: hr2_fixes.patch --]
[-- Type: text/x-patch, Size: 4382 bytes --]
diff --git a/drivers/scsi/hosts.c b/drivers/scsi/hosts.c
index 004a50a95560..7dff8ac850ab 100644
--- a/drivers/scsi/hosts.c
+++ b/drivers/scsi/hosts.c
@@ -345,6 +345,7 @@ static void scsi_host_dev_release(struct device *dev)
if (parent)
put_device(parent);
+ xa_destroy(&shost->__targets);
kfree(shost);
}
@@ -382,7 +383,7 @@ struct Scsi_Host *scsi_host_alloc(struct scsi_host_template *sht, int privsize)
shost->host_lock = &shost->default_lock;
spin_lock_init(shost->host_lock);
shost->shost_state = SHOST_CREATED;
- xa_init(&shost->__targets);
+ xa_init_flags(&shost->__targets, XA_FLAGS_LOCK_IRQ);
INIT_LIST_HEAD(&shost->eh_cmd_q);
INIT_LIST_HEAD(&shost->starved_list);
init_waitqueue_head(&shost->host_wait);
@@ -501,6 +502,7 @@ struct Scsi_Host *scsi_host_alloc(struct scsi_host_template *sht, int privsize)
fail_index_remove:
ida_simple_remove(&host_index_ida, shost->host_no);
fail_kfree:
+ xa_destroy(&shost->__targets);
kfree(shost);
return NULL;
}
diff --git a/drivers/scsi/scsi_scan.c b/drivers/scsi/scsi_scan.c
index e75e7f93f8f6..e146c36adcf3 100644
--- a/drivers/scsi/scsi_scan.c
+++ b/drivers/scsi/scsi_scan.c
@@ -309,6 +309,7 @@ static void scsi_target_destroy(struct scsi_target *starget)
{
struct device *dev = &starget->dev;
struct Scsi_Host *shost = dev_to_shost(dev->parent);
+ struct scsi_target *e_starg;
unsigned long flags;
unsigned long tid = scsi_target_index(starget);
@@ -318,8 +319,10 @@ static void scsi_target_destroy(struct scsi_target *starget)
spin_lock_irqsave(shost->host_lock, flags);
if (shost->hostt->target_destroy)
shost->hostt->target_destroy(starget);
- xa_erase(&shost->__targets, tid);
+ e_starg = xa_erase(&shost->__targets, tid);
spin_unlock_irqrestore(shost->host_lock, flags);
+ if (e_starg != starget)
+ pr_err("%s: bad xa_erase()\n", __func__);
put_device(dev);
}
@@ -328,6 +331,7 @@ static void scsi_target_dev_release(struct device *dev)
struct device *parent = dev->parent;
struct scsi_target *starget = to_scsi_target(dev);
+ xa_destroy(&starget->devices);
kfree(starget);
put_device(parent);
}
@@ -415,7 +419,7 @@ static struct scsi_target *scsi_alloc_target(struct device *parent,
starget->id = id;
starget->channel = channel;
starget->can_queue = 0;
- xa_init(&starget->devices);
+ xa_init_flags(&starget->devices, XA_FLAGS_LOCK_IRQ);
starget->state = STARGET_CREATED;
starget->scsi_level = SCSI_2;
starget->max_target_blocked = SCSI_DEFAULT_TARGET_BLOCKED;
@@ -428,7 +432,7 @@ static struct scsi_target *scsi_alloc_target(struct device *parent,
get_device(&found_target->dev);
goto found;
}
- if (xa_insert(&shost->__targets, tid, starget, GFP_KERNEL)) {
+ if (xa_insert(&shost->__targets, tid, starget, GFP_ATOMIC)) {
dev_printk(KERN_ERR, dev, "target index busy\n");
kfree(starget);
return NULL;
diff --git a/drivers/scsi/scsi_sysfs.c b/drivers/scsi/scsi_sysfs.c
index 63fa57684782..8a5e6c0a4bed 100644
--- a/drivers/scsi/scsi_sysfs.c
+++ b/drivers/scsi/scsi_sysfs.c
@@ -434,6 +434,7 @@ static void scsi_device_cls_release(struct device *class_dev)
static void scsi_device_dev_release_usercontext(struct work_struct *work)
{
struct scsi_device *sdev;
+ struct scsi_device *e_sdev;
struct scsi_target *starget;
struct device *parent;
struct list_head *this, *tmp;
@@ -449,9 +450,11 @@ static void scsi_device_dev_release_usercontext(struct work_struct *work)
parent = sdev->sdev_gendev.parent;
spin_lock_irqsave(sdev->host->host_lock, flags);
- xa_erase(&starget->devices, sdev->lun_idx);
+ e_sdev = xa_erase(&starget->devices, sdev->lun_idx);
list_del(&sdev->starved_entry);
spin_unlock_irqrestore(sdev->host->host_lock, flags);
+ if (e_sdev != sdev)
+ pr_err("%s: bad sdev erase\n", __func__);
cancel_work_sync(&sdev->event_work);
@@ -1621,14 +1624,14 @@ void scsi_sysfs_device_initialize(struct scsi_device *sdev)
if (sdev->lun < 256) {
sdev->lun_idx = sdev->lun;
WARN_ON(xa_insert(&starget->devices, sdev->lun_idx,
- sdev, GFP_KERNEL) < 0);
+ sdev, GFP_ATOMIC) < 0);
} else {
struct xa_limit scsi_lun_limit = {
.min = 256,
.max = UINT_MAX,
};
WARN_ON(xa_alloc(&starget->devices, &sdev->lun_idx,
- sdev, scsi_lun_limit, GFP_KERNEL) < 0);
+ sdev, scsi_lun_limit, GFP_ATOMIC) < 0);
}
spin_unlock_irqrestore(shost->host_lock, flags);
/*
prev parent reply other threads:[~2020-05-29 4:21 UTC|newest]
Thread overview: 25+ messages / expand[flat|nested] mbox.gz Atom feed top
2020-05-28 16:36 [PATCHv3 0/4] scsi: use xarray for devices and targets Hannes Reinecke
2020-05-28 16:36 ` [PATCH 1/4] scsi: convert target lookup to xarray Hannes Reinecke
2020-05-28 17:18 ` Douglas Gilbert
2020-05-28 19:08 ` Douglas Gilbert
2020-05-28 17:48 ` Bart Van Assche
2020-05-29 6:24 ` Hannes Reinecke
2020-05-28 16:36 ` [PATCH 2/4] target_core_pscsi: use __scsi_device_lookup() Hannes Reinecke
2020-05-28 17:55 ` Bart Van Assche
2020-05-29 7:02 ` Daniel Wagner
2020-05-28 16:36 ` [PATCH 3/4] scsi: move target device list to xarray Hannes Reinecke
2020-05-28 17:50 ` Douglas Gilbert
2020-05-28 18:54 ` Matthew Wilcox
2020-05-28 19:44 ` Douglas Gilbert
2020-05-28 19:53 ` Matthew Wilcox
2020-05-29 6:45 ` Hannes Reinecke
2020-05-28 20:58 ` Hannes Reinecke
2020-05-29 0:20 ` Matthew Wilcox
2020-05-29 6:50 ` Hannes Reinecke
2020-05-29 11:21 ` Matthew Wilcox
2020-05-29 12:46 ` Hannes Reinecke
2020-05-29 12:50 ` Matthew Wilcox
2020-05-29 13:17 ` Hannes Reinecke
2020-05-29 16:24 ` Douglas Gilbert
2020-05-28 16:36 ` [PATCH 4/4] scsi: remove direct device lookup per host Hannes Reinecke
2020-05-29 4:21 ` Douglas Gilbert [this message]
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=966f816a-d66e-e58f-d764-aeacf5026adf@interlog.com \
--to=dgilbert@interlog.com \
--cc=daniel.wagner@suse.com \
--cc=hare@suse.de \
--cc=hch@lst.de \
--cc=james.bottomley@hansenpartnership.com \
--cc=johannes.thumshirn@wdc.com \
--cc=linux-scsi@vger.kernel.org \
--cc=martin.petersen@oracle.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox