Re: [PATCH RFC 1/9] [SCSI] Detect overflow of sense data buffer

2013-01-23 Thread Hannes Reinecke

On 01/22/2013 04:08 PM, Ewan Milne wrote:

On Fri, 2013-01-18 at 16:46 +, James Bottomley wrote:

On Fri, 2013-01-18 at 11:27 -0500, Ewan D. Milne wrote:

--- a/drivers/scsi/scsi_error.c
+++ b/drivers/scsi/scsi_error.c
@@ -241,6 +241,9 @@ static int scsi_check_sense(struct scsi_cmnd *scmd)
if (! scsi_command_normalize_sense(scmd, sshdr))
return FAILED;  /* no valid sense data */

+   if (sshdr.overflow)
+   scmd_printk(KERN_WARNING, scmd, Sense data overflow);
+
if (scsi_sense_is_deferred(sshdr))
return NEEDS_RETRY;

@@ -2059,14 +2062,18 @@ int scsi_normalize_sense(const u8 *sense_buffer, int 
sb_len,
sshdr-asc = sense_buffer[2];
if (sb_len  3)
sshdr-ascq = sense_buffer[3];
+   if (sb_len  4)
+   sshdr-overflow = ((sense_buffer[4]  0x80) != 0);
if (sb_len  7)
sshdr-additional_length = sense_buffer[7];
} else {
/*
 * fixed format
 */
-   if (sb_len  2)
+   if (sb_len  2) {
+   sshdr-overflow = ((sense_buffer[2]  0x10) != 0);
sshdr-sense_key = (sense_buffer[2]  0xf);
+   }
if (sb_len  7) {
sb_len = (sb_len  (sense_buffer[7] + 8)) ?
 sb_len : (sense_buffer[7] + 8);


This isn't the right way to do it:  The overflow bit is a recent
introduction in SPC-4.  The correct way to tell if we have an overflow
or not is to look at the additional sense length and compare it to the
allocation length; this will work for everything.


Unfortunately, I am not sure that the allocation length that was sent
to the device is always available.  I will look into this more closely
but it appeared to me that e.g. FC drivers like qla2xxx get the sense
data automatically from the HBA firmware.  In the case of that driver
the host sense buffer size looks like it is hard-coded to 32 bytes,
for all I know the firmware might only asking for 18 bytes.


Hmm.

Maybe we should be adding a 'max_sense_len' field to the SCSI host;
that way we could check against this.
Nevertheless, that information would be lost to us in either case.

I wonder how these vendors propose to handle long sense code data;
silently ignoring it doesn't seem to be the correct way.


Of course, for a normal REQUEST SENSE command where the allocation
length is in the CDB, it would indeed be easy to add a check against
the additional sense length.



I'm not even convinced that overflow is important: for a lot of the
sense probes, we deliberately induce overflows by giving the request
sense command a short buffer.  Printing a warning in scsi_check_sense
will get very noisy very fast.


That would indeed be a problem.  I didn't see this behavior when testing
the changes but I'll need to investigate this further.

The purpose of detecting the sense data overflow was to provide some
visibility that a device is returning a large amount of sense data that
is currently being silently ignored.  In the case of descriptor format
sense data, it is possible that a descriptor we want to examine is
located after one or more other descriptors, and we might not get it
at all if the buffer isn't large enough.

Agreed. but the newest standard won't be adopted to existing 
devices, so we should figure out a way of dealing with those, too.


Cheers,

Hannes
--
Dr. Hannes Reinecke   zSeries  Storage
h...@suse.de  +49 911 74053 688
SUSE LINUX Products GmbH, Maxfeldstr. 5, 90409 Nürnberg
GF: J. Hawn, J. Guild, F. Imendörffer, HRB 16746 (AG Nürnberg)
--
To unsubscribe from this list: send the line unsubscribe linux-scsi in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH RFC 1/9] [SCSI] Detect overflow of sense data buffer

2013-01-23 Thread James Bottomley
On Tue, 2013-01-22 at 10:08 -0500, Ewan Milne wrote:
 On Fri, 2013-01-18 at 16:46 +, James Bottomley wrote:
  On Fri, 2013-01-18 at 11:27 -0500, Ewan D. Milne wrote:
   --- a/drivers/scsi/scsi_error.c
   +++ b/drivers/scsi/scsi_error.c
   @@ -241,6 +241,9 @@ static int scsi_check_sense(struct scsi_cmnd *scmd)
 if (! scsi_command_normalize_sense(scmd, sshdr))
 return FAILED;  /* no valid sense data */

   + if (sshdr.overflow)
   + scmd_printk(KERN_WARNING, scmd, Sense data overflow);
   +
 if (scsi_sense_is_deferred(sshdr))
 return NEEDS_RETRY;

   @@ -2059,14 +2062,18 @@ int scsi_normalize_sense(const u8 *sense_buffer, 
   int sb_len,
 sshdr-asc = sense_buffer[2];
 if (sb_len  3)
 sshdr-ascq = sense_buffer[3];
   + if (sb_len  4)
   + sshdr-overflow = ((sense_buffer[4]  0x80) != 0);
 if (sb_len  7)
 sshdr-additional_length = sense_buffer[7];
 } else {
 /*
  * fixed format
  */
   - if (sb_len  2)
   + if (sb_len  2) {
   + sshdr-overflow = ((sense_buffer[2]  0x10) != 0);
 sshdr-sense_key = (sense_buffer[2]  0xf);
   + }
 if (sb_len  7) {
 sb_len = (sb_len  (sense_buffer[7] + 8)) ?
  sb_len : (sense_buffer[7] + 8);
  
  This isn't the right way to do it:  The overflow bit is a recent
  introduction in SPC-4.  The correct way to tell if we have an overflow
  or not is to look at the additional sense length and compare it to the
  allocation length; this will work for everything.
 
 Unfortunately, I am not sure that the allocation length that was sent
 to the device is always available.

Well, yes it is, we just don't store it.  scsi_normalize_sense() takes
as input the length of the sense buffer we gave it.  If we want an
overflow indication, we can certainly compare that against the
additional length (assuming we have enough bytes to get the additional
length).

   I will look into this more closely
 but it appeared to me that e.g. FC drivers like qla2xxx get the sense
 data automatically from the HBA firmware.  In the case of that driver
 the host sense buffer size looks like it is hard-coded to 32 bytes,
 for all I know the firmware might only asking for 18 bytes.

You mean for their ACA emulation in the transport?  They have to be
picking up at least the standard minimum in order not to be in
violation, surely?

 Of course, for a normal REQUEST SENSE command where the allocation
 length is in the CDB, it would indeed be easy to add a check against
 the additional sense length.
 
  
  I'm not even convinced that overflow is important: for a lot of the
  sense probes, we deliberately induce overflows by giving the request
  sense command a short buffer.  Printing a warning in scsi_check_sense
  will get very noisy very fast.
 
 That would indeed be a problem.  I didn't see this behavior when testing
 the changes but I'll need to investigate this further.
 
 The purpose of detecting the sense data overflow was to provide some
 visibility that a device is returning a large amount of sense data that
 is currently being silently ignored.  In the case of descriptor format
 sense data, it is possible that a descriptor we want to examine is
 located after one or more other descriptors, and we might not get it
 at all if the buffer isn't large enough.

But why should we care?  A lot of the time it will be spewing
descriptors with irrelevant FRU information.  I really think printing
there's been an overflow isn't a good idea.  I'm not sure there's much
use in the sshdr indicating there's been one.  It *may* be useful to
indicate how big the allocation length should have been, but I'm not
even convinced of that, since the data is now lost.

James


--
To unsubscribe from this list: send the line unsubscribe linux-scsi in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


linux-3.7.4: BUG: unable to handle kernel NULL pointer dereference at target_fabric_port_link

2013-01-23 Thread Kouichi ONO
Hi,
after upgrade from 3.7.3 to 3.7.4, I got NULL pointer dereference at
target_fabric_port_link().

Jan 22 23:58:52  kernel: [   89.333115] BUG: unable to handle kernel NULL 
pointer dereference at   (null)
Jan 22 23:58:52  kernel: [   89.333251] IP: [a049d988] 
target_fabric_port_link+0x18/0x100 [target_core_mod]
Jan 22 23:58:52  kernel: [   89.82] PGD 40b94c067 PUD 40b8de067 PMD 0
Jan 22 23:58:52  kernel: [   89.333564] Oops:  [#1] PREEMPT SMP
Jan 22 23:58:52  kernel: [   89.333756] Modules linked in: iscsi_target_mod 
target_core_pscsi target_core_file target_core_iblock binfmt_misc target
_core_mod iscsi_tcp libiscsi_tcp libiscsi scsi_transport_iscsi twofish_generic 
twofish_avx_x86_64 twofish_x86_64_3way twofish_x86_64 twofish_common camellia
_generic camellia_x86_64 serpent_avx_x86_64 serpent_sse2_x86_64 serpent_generic 
glue_helper blowfish_generic blowfish_x86_64 blowfish_common dlm cast5_avx_x
86_64 cast5_generic sctp sha512_generic sha256_generic crypto_null bridge stp 
llc nf_conntrack_ipv6 nf_defrag_ipv6 xt_LOG nf_conntrack_ipv4 nf_defrag_ipv4 k
vm_intel kvm crc32c_intel aesni_intel ablk_helper cryptd xts lrw gf128mul 
iTCO_wdt snd_hda_codec_hdmi microcode psmouse serio_raw pcspkr 
snd_hda_codec_realt
ek lpc_ich mfd_core snd_ice1724 snd_ak4113 snd_hda_intel snd_pt2258 
snd_hda_codec snd_i2c snd_ak4114 snd_hwdep snd_ice17xx_ak4xxx snd_ak4xxx_adda 
snd_pcm_os
s snd_mixer_oss snd_ac97_codec ac97_bus snd_pcm snd_seq_dummy snd_page_alloc 
snd_seq_oss snd_
Jan 22 23:58:52  kernel: seq_midi snd_rawmidi snd_seq_midi_event snd_seq 
rtc_cmos snd_seq_device snd_timer snd mei soundcore button vhost_net tun w8
3627ehf hwmon_vid coretemp hwmon acpi_cpufreq mperf processor firewire_sbp2 
firewire_core crc_itu_t evdev fuse ocfs2_dlmfs ocfs2_stack_o2cb ocfs2_dlm ocfs2_
nodemanager ocfs2_stackglue configfs autofs4 usb_storage sg ata_generic 
pata_acpi sr_mod cdrom pata_marvell xhci_hcd e1000e ehci_hcd
Jan 22 23:58:52  kernel: [   89.339089] CPU 7
Jan 22 23:58:52  kernel: [   89.339132] Pid: 4050, comm: ln Tainted: GW 
   3.7.4-dirty #1  /DP67BG
Jan 22 23:58:52  kernel: [   89.339277] RIP: 0010:[a049d988]  
[a049d988] target_fabric_port_link+0x18/0x100 [target_core_mod]
Jan 22 23:58:52  kernel: [   89.339413] RSP: 0018:88040d45de78  EFLAGS: 
00010286
Jan 22 23:58:52  kernel: [   89.339476] RAX: a04bc840 RBX: 
880404d499dc RCX: 
Jan 22 23:58:52  kernel: [   89.339538] RDX: 0007 RSI: 
88040c70a7b0 RDI: 88040e4d2070
Jan 22 23:58:52  kernel: [   89.339609] RBP: 88040d45de98 R08: 
0002 R09: fefefefefefefeff
Jan 22 23:58:52  kernel: [   89.339677] R10: 2f2f2f2f2f2f2f2f R11: 
 R12: 88040b189440
Jan 22 23:58:52  kernel: [   89.339742] R13: 88040e4d2070 R14: 
88040c70a7b0 R15: 88040c5dfb58
Jan 22 23:58:52  kernel: [   89.339807] FS:  7f3edb7ef700() 
GS:88041f5c() knlGS:
Jan 22 23:58:52  kernel: [   89.339893] CS:  0010 DS:  ES:  CR0: 
80050033
Jan 22 23:58:52  kernel: [   89.339960] CR2:  CR3: 
00040cc92000 CR4: 000407e0
Jan 22 23:58:52  kernel: [   89.340030] DR0:  DR1: 
 DR2: 
Jan 22 23:58:52  kernel: [   89.340098] DR3:  DR6: 
0ff0 DR7: 0400
Jan 22 23:58:52  kernel: [   89.340161] Process ln (pid: 4050, threadinfo 
88040d45c000, task 88040d91c840)
Jan 22 23:58:52  kernel: [   89.340243] Stack:
Jan 22 23:58:52  kernel: [   89.340302]  880404d499dc 88040b189440 
88040e4d2070 88040c70a7b0
Jan 22 23:58:52  kernel: [   89.340559]  88040d45def8 a005f02d 
88040d45deb8 88040ba1e800
Jan 22 23:58:52  kernel: [   89.340802]  88040ebcabe0 880404d49980 
88040d45dee8 
Jan 22 23:58:52  kernel: [   89.341057] Call Trace:
Jan 22 23:58:52  kernel: [   89.341125]  [a005f02d] 
configfs_symlink+0x12d/0x340 [configfs]
Jan 22 23:58:52  kernel: [   89.341189]  [8113aa6d] 
vfs_symlink+0x8d/0xf0
Jan 22 23:58:52  kernel: [   89.341250]  [8113e5b9] 
sys_symlinkat+0x59/0x90
Jan 22 23:58:52  kernel: [   89.341322]  [8113e601] 
sys_symlink+0x11/0x20
Jan 22 23:58:52  kernel: [   89.341391]  [816c1892] 
system_call_fastpath+0x16/0x1b
Jan 22 23:58:52  kernel: [   89.341456] Code: 8b 65 f8 c9 c3 66 66 66 66 66 2e 
0f 1f 84 00 00 00 00 00 55 48 89 e5 48 83 ec 20 48 89 5d e0 4c 89 65
e8 4c 89 6d f0 4c 89 75 f8 81 3c 25 00 00 00 00 ef de ed fe 75 76 48 8b 47 30 
48 83 7f f0
Jan 22 23:58:52  kernel: [   89.344386] RIP  [a049d988] 
target_fabric_port_link+0x18/0x100 [target_core_mod]
Jan 22 23:58:52  kernel: [   89.344526]  RSP 88040d45de78
Jan 22 23:58:52  kernel: [   89.344592] CR2: 
Jan 22 23:58:52  kernel: [   89.344673] ---[ end trace 60b2bd0028e165d0 ]---


At target_fabric_port_link(), 

[RESEND PATCH] libiscsi: avoid unnecessary multiple NULL assignments

2013-01-23 Thread Masatake YAMATO
In iscsi_free_task, NULL is assigned to task-sc twice: before and
after kfifo_in invocatoin. Allocating and freeing iscsi_task are guarded
with session-lock, so multiple NULL assignments cause no trouble. But
people reading the source code may be confused.

The second NULL assignment comes from commit:

3e5c28ad0391389959ccae81c938c7533efb3490

It seems that the line after kfifo_in invocation was introduced
accidentally.

Signed-off-by: Masatake YAMATO yam...@redhat.com
Reviewed-by: Mike Christie micha...@cs.wisc.edu
---
 drivers/scsi/libiscsi.c | 1 -
 1 file changed, 1 deletion(-)

diff --git a/drivers/scsi/libiscsi.c b/drivers/scsi/libiscsi.c
index 82c3fd4..7aacf3a 100644
--- a/drivers/scsi/libiscsi.c
+++ b/drivers/scsi/libiscsi.c
@@ -507,7 +507,6 @@ static void iscsi_free_task(struct iscsi_task *task)
kfifo_in(session-cmdpool.queue, (void*)task, sizeof(void*));
 
if (sc) {
-   task-sc = NULL;
/* SCSI eh reuses commands to verify us */
sc-SCp.ptr = NULL;
/*
-- 
1.7.11.7

--
To unsubscribe from this list: send the line unsubscribe linux-scsi in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH RFC 4/9] [SCSI] Rename scsi_evt_xxx to sdev_evt_xxx and scsi_event to sdev_event

2013-01-23 Thread Ewan Milne
On Tue, 2013-01-22 at 10:38 -0700, Bart Van Assche wrote:
 On Fri, Jan 18, 2013 at 9:27 AM, Ewan D. Milne emi...@redhat.com wrote:
  @@ -2206,7 +2206,7 @@ static void scsi_evt_emit(struct scsi_device *sdev, 
  struct scsi_event *evt)
* Dispatch queued events to their associated scsi_device kobjects
* as uevents.
*/
  -void scsi_evt_thread(struct work_struct *work)
  +void sdev_evt_thread(struct work_struct *work)
   {
  struct scsi_device *sdev;
  LIST_HEAD(event_list);
  @@ -2214,7 +2214,7 @@ void scsi_evt_thread(struct work_struct *work)
  sdev = container_of(work, struct scsi_device, event_work);
 
  while (1) {
  -   struct scsi_event *evt;
  +   struct sdev_event *evt;
  struct list_head *this, *tmp;
  unsigned long flags;
 
  @@ -2226,9 +2226,9 @@ void scsi_evt_thread(struct work_struct *work)
  break;
 
  list_for_each_safe(this, tmp, event_list) {
  -   evt = list_entry(this, struct scsi_event, node);
  +   evt = list_entry(this, struct sdev_event, node);
  list_del(evt-node);
  -   scsi_evt_emit(sdev, evt);
  +   sdev_evt_emit(sdev, evt);
  kfree(evt);
  }
  }
 
 If schedule_work() gets invoked if work is already on a workqueue then
 it will return immediately. Does that mean that the above approach for
 processing the event list is racy and that new events will not get
 processed if schedule_work() is invoked after the while loop finished
 but before the above function returns ?

I thought that the way that the workqueue mechanism did this was that
the work struct was removed from the list and WORK_STRUCT_PENDING_BIT
was cleared in the work_struct before the work function was invoked.

In that case I the code should be OK since the work function will have
to take the lock which is held around the code to add the event to the
list and the call to schedule_work().

But I see your point, and I since I just added more SDEV_EVT_xxx codes
(and an STARGET_EVT_xxx code, which uses the same mechanism), I didn't
inspect this code carefully.  I'll give it some more thought.

It seems to me that the workqueue mechanism would be hard to use if
there weren't some guarantee against the race condition you mention.

 Bart.

Thank you for your comments.


--
To unsubscribe from this list: send the line unsubscribe linux-scsi in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH RFC 4/9] [SCSI] Rename scsi_evt_xxx to sdev_evt_xxx and scsi_event to sdev_event

2013-01-23 Thread Ewan Milne
On Tue, 2013-01-22 at 10:33 -0700, Bart Van Assche wrote:
 On Fri, Jan 18, 2013 at 9:27 AM, Ewan D. Milne emi...@redhat.com wrote:
 
  @@ -2206,7 +2206,7 @@ static void scsi_evt_emit(struct scsi_device *sdev, 
  struct scsi_event *evt)
* Dispatch queued events to their associated scsi_device kobjects
* as uevents.
*/
  -void scsi_evt_thread(struct work_struct *work)
  +void sdev_evt_thread(struct work_struct *work)
   {
  struct scsi_device *sdev;
  LIST_HEAD(event_list);
 
 This code does not run as a long-living thread so please consider
 using the name sdev_evt_work instead.

Good idea.  I'll do that.

 
 Bart.


--
To unsubscribe from this list: send the line unsubscribe linux-scsi in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH RFC 1/9] [SCSI] Detect overflow of sense data buffer

2013-01-23 Thread Ewan Milne
On Wed, 2013-01-23 at 13:06 +, James Bottomley wrote:
 On Tue, 2013-01-22 at 10:08 -0500, Ewan Milne wrote:
  On Fri, 2013-01-18 at 16:46 +, James Bottomley wrote:
   On Fri, 2013-01-18 at 11:27 -0500, Ewan D. Milne wrote:
--- a/drivers/scsi/scsi_error.c
+++ b/drivers/scsi/scsi_error.c
@@ -241,6 +241,9 @@ static int scsi_check_sense(struct scsi_cmnd *scmd)
if (! scsi_command_normalize_sense(scmd, sshdr))
return FAILED;  /* no valid sense data */
 
+   if (sshdr.overflow)
+   scmd_printk(KERN_WARNING, scmd, Sense data overflow);
+
if (scsi_sense_is_deferred(sshdr))
return NEEDS_RETRY;
 
@@ -2059,14 +2062,18 @@ int scsi_normalize_sense(const u8 
*sense_buffer, int sb_len,
sshdr-asc = sense_buffer[2];
if (sb_len  3)
sshdr-ascq = sense_buffer[3];
+   if (sb_len  4)
+   sshdr-overflow = ((sense_buffer[4]  0x80) != 
0);
if (sb_len  7)
sshdr-additional_length = sense_buffer[7];
} else {
/*
 * fixed format
 */
-   if (sb_len  2)
+   if (sb_len  2) {
+   sshdr-overflow = ((sense_buffer[2]  0x10) != 
0);
sshdr-sense_key = (sense_buffer[2]  0xf);
+   }
if (sb_len  7) {
sb_len = (sb_len  (sense_buffer[7] + 8)) ?
 sb_len : (sense_buffer[7] + 8);
   
   This isn't the right way to do it:  The overflow bit is a recent
   introduction in SPC-4.  The correct way to tell if we have an overflow
   or not is to look at the additional sense length and compare it to the
   allocation length; this will work for everything.
  
  Unfortunately, I am not sure that the allocation length that was sent
  to the device is always available.
 
 Well, yes it is, we just don't store it.  scsi_normalize_sense() takes
 as input the length of the sense buffer we gave it.  If we want an
 overflow indication, we can certainly compare that against the
 additional length (assuming we have enough bytes to get the additional
 length).
 
I will look into this more closely
  but it appeared to me that e.g. FC drivers like qla2xxx get the sense
  data automatically from the HBA firmware.  In the case of that driver
  the host sense buffer size looks like it is hard-coded to 32 bytes,
  for all I know the firmware might only asking for 18 bytes.
 
 You mean for their ACA emulation in the transport?  They have to be
 picking up at least the standard minimum in order not to be in
 violation, surely?

I'm sure that's the case, I just don't know if the minimum is big
enough.  See below.

 
  Of course, for a normal REQUEST SENSE command where the allocation
  length is in the CDB, it would indeed be easy to add a check against
  the additional sense length.
  
   
   I'm not even convinced that overflow is important: for a lot of the
   sense probes, we deliberately induce overflows by giving the request
   sense command a short buffer.  Printing a warning in scsi_check_sense
   will get very noisy very fast.
  
  That would indeed be a problem.  I didn't see this behavior when testing
  the changes but I'll need to investigate this further.
  
  The purpose of detecting the sense data overflow was to provide some
  visibility that a device is returning a large amount of sense data that
  is currently being silently ignored.  In the case of descriptor format
  sense data, it is possible that a descriptor we want to examine is
  located after one or more other descriptors, and we might not get it
  at all if the buffer isn't large enough.
 
 But why should we care?  A lot of the time it will be spewing
 descriptors with irrelevant FRU information.  I really think printing
 there's been an overflow isn't a good idea.  I'm not sure there's much
 use in the sshdr indicating there's been one.  It *may* be useful to
 indicate how big the allocation length should have been, but I'm not
 even convinced of that, since the data is now lost.

My thinking was that it was important to log the fact that the device
had reported a Unit Attention queue overflow, which is reported in a
sense key specific descriptor, so I was concerned that if the sense
buffer wasn't big enough, the host would never see that there had
been a UA queue overflow.  That was why I had added the logging of
a sense buffer overflow.  I wasn't so much interested in reporting
sense buffer overflow for its own sake.

So, as it stands right now, I think I'll remove the 1/9 component
of the patch set, unless there is consensus that it is really needed.

 
 James
 
 


--
To unsubscribe from this list: send the line unsubscribe linux-scsi in
the 

[PATCH] mpt2sas: prevent double free on error path

2013-01-23 Thread Jörn Engel
I noticed this one when list_del was called with poisoned list
pointers, but the real problem is a double-free (and a use-after-free
just before that).

Both _scsih_probe_boot_devices() and _scsih_sas_device_add() put the
sas_device onto a list, thereby giving up control.  Next they call
mpt2sas_transport_port_add() and will list_del and free the object on
errors.  If some other function already did the list_del and free, it
will happen again.

This patch adds reference counting to prevent the double free.  One
reference count goes to the caller of mpt2sas_transport_port_add(), the
second to the list.  Whoever removes the object from the list gets to
drop one reference count.  _scsih_probe_boot_devices() and
_scsih_sas_device_add() get a second reference count to ensure the
object is not freed while they are still accessing it.

To prevent the double list_del(), I changed the code to list_del_init()
and added a list_empty() check before that.  Since the
list_empty/list_del_init is always called under a lock, this should be
safe.

I hate the complexity this patch adds, but see no alternative to it.

mpt2sas0: failure at 
drivers/scsi/mpt2sas/mpt2sas_transport.c:708/mpt2sas_transport_port_add()!
general protection fault:  [#1] SMP
CPU 9
Pid: 3097, comm: kworker/u:11 Tainted: GW  O 3.6.10+ #31392.trunk
/0JP31P
RIP: 0010:[a0309744]  [a0309744] 
_scsih_sas_device_remove+0x54/0x90 [mpt2sas]
RSP: 0018:881fed4d7ab0  EFLAGS: 00010046
RAX: dead00200200 RBX: 881ff6a5cd88 RCX: 10e8
RDX: 881ff7dab800 RSI: 881ff7daba00 RDI: dead00100100
RBP: 881fed4d7ad0 R08: dead00200200 R09: 880fff802200
R10: a0317980 R11:  R12: 881ff7daba00
R13: 0286 R14: 500605ba006c9d09 R15: 881ff7daba00
FS:  () GS:88203fc8() knlGS:
CS:  0010 DS:  ES:  CR0: 8005003b
CR2: 7f8ac89ec458 CR3: 001ff4c5c000 CR4: 000407e0
DR0:  DR1:  DR2: 
DR3:  DR6: 0ff0 DR7: 0400
Process kworker/u:11 (pid: 3097, threadinfo 881fed4d6000, task 
881402f3d9c0)
Stack:
 0401 881ff6a5c6b0 0401 0016
 881fed4d7bb0 a030f93e  881ff6a5cd88
 0012000e0f08 006c9d090002000b 00180009500605ba 04010016
Call Trace:
 [a030f93e] _scsih_add_device.clone.32+0x2fe/0x420 [mpt2sas]
 [a03126e5] _scsih_sas_topology_change_event.clone.38+0x285/0x620 
[mpt2sas]
 [81078c90] ? load_balance+0x100/0x7a0
 [a0312a80] ? _scsih_sas_topology_change_event.clone.38+0x620/0x620 
[mpt2sas]
 [a0312d8a] _firmware_event_work+0x30a/0xfc0 [mpt2sas]
 [810015cc] ? __switch_to+0x14c/0x410
 [8106dfdb] ? finish_task_switch+0x4b/0xf0
 [a0312a80] ? _scsih_sas_topology_change_event.clone.38+0x620/0x620 
[mpt2sas]
 [8105bf40] process_one_work+0x140/0x500
 [8105d354] worker_thread+0x194/0x510
 [8106dfdb] ? finish_task_switch+0x4b/0xf0
 [8105d1c0] ? manage_workers+0x320/0x320
 [8106282e] kthread+0x9e/0xb0
 [815bef44] kernel_thread_helper+0x4/0x10
 [815b5e5d] ? retint_restore_args+0x13/0x13
 [81062790] ? kthread_freezable_should_stop+0x70/0x70
 [815bef40] ? gs_change+0x13/0x13

Signed-off-by: Joern Engel jo...@logfs.org
---
 drivers/scsi/mpt2sas/mpt2sas_base.h  |1 +
 drivers/scsi/mpt2sas/mpt2sas_scsih.c |   55 --
 2 files changed, 47 insertions(+), 9 deletions(-)

diff --git a/drivers/scsi/mpt2sas/mpt2sas_base.h 
b/drivers/scsi/mpt2sas/mpt2sas_base.h
index 543d8d6..ceb7d41 100644
--- a/drivers/scsi/mpt2sas/mpt2sas_base.h
+++ b/drivers/scsi/mpt2sas/mpt2sas_base.h
@@ -367,6 +367,7 @@ struct _sas_device {
u16 slot;
u8  phy;
u8  responding;
+   struct kref kref;
 };
 
 /**
diff --git a/drivers/scsi/mpt2sas/mpt2sas_scsih.c 
b/drivers/scsi/mpt2sas/mpt2sas_scsih.c
index c6bdc92..43b3a98 100644
--- a/drivers/scsi/mpt2sas/mpt2sas_scsih.c
+++ b/drivers/scsi/mpt2sas/mpt2sas_scsih.c
@@ -570,6 +570,18 @@ _scsih_sas_device_find_by_handle(struct MPT2SAS_ADAPTER 
*ioc, u16 handle)
return NULL;
 }
 
+static void free_sas_device(struct kref *kref)
+{
+   struct _sas_device *sas_device = container_of(kref, struct _sas_device,
+   kref);
+   kfree(sas_device);
+}
+
+static void put_sas_device(struct _sas_device *sas_device)
+{
+   kref_put(sas_device-kref, free_sas_device);
+}
+
 /**
  * _scsih_sas_device_remove - remove sas_device from list.
  * @ioc: per adapter object
@@ -583,14 +595,19 @@ _scsih_sas_device_remove(struct MPT2SAS_ADAPTER *ioc,
 struct _sas_device *sas_device)
 {
unsigned long flags;
+   int was_on_list = 0;
 
if (!sas_device)
return;
 

Re: [PATCH RFC 0/9] [SCSI] Enhanced sense and Unit Attention handling

2013-01-23 Thread Bart Van Assche
On Fri, Jan 18, 2013 at 9:27 AM, Ewan D. Milne emi...@redhat.com wrote:
 This patch set adds changes to the SCSI mid-layer, sysfs and scsi_debug
 to provide enhanced support for Unit Attention conditions, as well as
 detection of reported sense data overflow conditions and some changes
 to sense data processing.  It also adds a uevent when the reported
 capacity changes on an sd device.

 There was some discussion about this a couple of years ago on the linux-scsi
 mailing list:  http://marc.info/?l=linux-scsim=129702506514742w=2
 Although one approach is to send all SCSI sense data to a userspace daemon
 for processing, this patch set does not take that approach due to the
 difficulty in reliably delivering all of the data.  An interesting UA
 condition might not be delivered due to a flood of media errors, for example.

 The mechanism used is to flag when certain UA ASC/ASCQ codes are received
 that report asynchronous changes to the storage device configuration.
 An appropriate uevent is then generated for the scsi_device or scsi_target
 object.  An aggregation mechanism is used to avoid generating uevents at
 too high a rate, and to coalesce multiple UAs reported by LUNs on the
 same target for a REPORTED LUNS DATA HAS CHANGED sense code.

Does this patch series add a function that allows SCSI LLDs to report
AEN data to the SCSI core ? What if a SCSI target reports a LUN
inventory change via AER to e.g. the iSCSI initiator and that
initiator ignores the AEN data ? Will that result in AEN data being
ignored and no automatic LUN rescanning ?

Bart.
--
To unsubscribe from this list: send the line unsubscribe linux-scsi in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH] mpt2sas: prevent double free on error path

2013-01-23 Thread Bjørn Mork
Jörn Engel jo...@logfs.org writes:

 diff --git a/drivers/scsi/mpt2sas/mpt2sas_scsih.c 
 b/drivers/scsi/mpt2sas/mpt2sas_scsih.c
 index c6bdc92..43b3a98 100644
 --- a/drivers/scsi/mpt2sas/mpt2sas_scsih.c
 +++ b/drivers/scsi/mpt2sas/mpt2sas_scsih.c
 @@ -570,6 +570,18 @@ _scsih_sas_device_find_by_handle(struct MPT2SAS_ADAPTER 
 *ioc, u16 handle)
   return NULL;
  }
  
 +static void free_sas_device(struct kref *kref)
 +{
 + struct _sas_device *sas_device = container_of(kref, struct _sas_device,
 + kref);
 + kfree(sas_device);
 +}
 +
 +static void put_sas_device(struct _sas_device *sas_device)
 +{
 + kref_put(sas_device-kref, free_sas_device);
 +}
 +
  /**
   * _scsih_sas_device_remove - remove sas_device from list.
   * @ioc: per adapter object
 @@ -583,14 +595,19 @@ _scsih_sas_device_remove(struct MPT2SAS_ADAPTER *ioc,
  struct _sas_device *sas_device)
  {
   unsigned long flags;
 + int was_on_list = 0;
  
   if (!sas_device)
   return;
  
   spin_lock_irqsave(ioc-sas_device_lock, flags);
 - list_del(sas_device-list);
 - kfree(sas_device);
 + if (!list_empty(sas_device-list)) {
 + list_del_init(sas_device-list);
 + was_on_list = 1;
 + }
   spin_unlock_irqrestore(ioc-sas_device_lock, flags);
 + if (was_on_list)
 + put_sas_device(sas_device);
  }
  


How about the copy of this code in drivers/scsi/mpt3sas/mpt3sas_scsih.c?
Is that safe, or does it need fixing as well?


Bjørn
--
To unsubscribe from this list: send the line unsubscribe linux-scsi in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html