ib_srp: free memory correctly in srp_free_iu()

As a potential fix for a race condition in srp_free_iu(),
hold a mutex in srp_free_target_ib() before calling srp_free_iu().

In addition, also clear rx/tx ring after freeing memory.
Both rx_ring[] and tx_ring[] should be reinitialized to NULL,
to prevent other tasks from accessing the freed memory.

Signed-off-by: Dongsu Park <dongsu.park@profitbricks.com>
ib_srp: removed superfluous warning in send timeout case

Signed-off-By: Sebastian Riemer <sebastian.riemer@profitbricks.com>
ib_srp: hold a mutex when adding a new target port

Unter circumstances, srp_rport_add() can make conflicts with
srp_rport_delete(), dumping the call trace written below.
That does not always occur. But its possible reason is adding
sysfs entries for the SRP target too fast, even before the
deletion hasn't finished yet.

The possible solution is therefore holding a scan_mutex when
calling device_add().

Example call trace:

------------[ cut here ]------------
WARNING: at block/genhd.c:1466 __disk_unblock_events+0x10f/0x120()
Pid: 17238, comm: scsi_id Not tainted 3.2.8-pserver #1
Call Trace:
 [<ffffffff81048dbb>] ? warn_slowpath_common+0x7b/0xc0
 [<ffffffff813879bf>] ? __disk_unblock_events+0x10f/0x120
 [<ffffffff81162b30>] ? __blkdev_get+0x190/0x410
 [<ffffffff811630c0>] ? blkdev_get+0x310/0x310
 [<ffffffff81162dfb>] ? blkdev_get+0x4b/0x310
 [<ffffffff811630c0>] ? blkdev_get+0x310/0x310
 [<ffffffff8112d513>] ? __dentry_open+0x263/0x370
 [<ffffffff8113a0fe>] ? path_get+0x1e/0x30
 [<ffffffff8113b4a0>] ? do_last+0x3e0/0x800
 [<ffffffff8113c21b>] ? path_openat+0xdb/0x400
 [<ffffffff8113c66d>] ? do_filp_open+0x4d/0xc0
 [<ffffffff81148c13>] ? alloc_fd+0x43/0x130
 [<ffffffff8112d915>] ? do_sys_open+0x105/0x1e0
 [<ffffffff8165d512>] ? system_call_fastpath+0x16/0x1b
---[ end trace 4edc2747f936431c ]---
------------[ cut here ]------------
WARNING: at fs/sysfs/inode.c:323 sysfs_hash_and_remove+0xa4/0xb0()
Hardware name: H8DGU
sysfs: can not remove 'bsg', no directory
Pid: 15816, comm: kworker/4:8 Tainted: G        W    3.2.8 #1
Call Trace:
 [<ffffffff81048dbb>] ? warn_slowpath_common+0x7b/0xc0
 [<ffffffff81048eb5>] ? warn_slowpath_fmt+0x45/0x50
 [<ffffffff8119a854>] ? sysfs_hash_and_remove+0xa4/0xb0
 [<ffffffff8138aaaf>] ? bsg_unregister_queue+0x3f/0x80
 [<ffffffffa000eda9>] ? __scsi_remove_device+0x99/0xc0 [scsi_mod]
 [<ffffffffa000b3b4>] ? scsi_forget_host+0x64/0x70 [scsi_mod]
 [<ffffffffa00035b1>] ? scsi_remove_host+0x61/0x100 [scsi_mod]
 [<ffffffffa0643097>] ? srp_remove_work+0x137/0x1c0 [ib_srp]
 [<ffffffffa0642f60>] ? srp_free_req_data+0xd0/0xd0 [ib_srp]
 [<ffffffff81063383>] ? process_one_work+0x113/0x470
 [<ffffffff81065a90>] ? manage_workers+0x180/0x200
 [<ffffffff81065c73>] ? worker_thread+0x163/0x3e0
 [<ffffffff81065b10>] ? manage_workers+0x200/0x200
 [<ffffffff81065b10>] ? manage_workers+0x200/0x200
 [<ffffffff8106a126>] ? kthread+0x96/0xa0
 [<ffffffff8165f674>] ? kernel_thread_helper+0x4/0x10
 [<ffffffff8106a090>] ? kthread_worker_fn+0x180/0x180
 [<ffffffff8165f670>] ? gs_change+0x13/0x13
---[ end trace 4edc2747f936431d ]---
------------[ cut here ]------------

Signed-off-by: Dongsu Park <dongsu.park@profitbricks.com>
ib_srp: check if rport->lld_data is NULL before removing rport

After removing rport_delete(), rport->lld_data has to be set to NULL.
In addition to that, both srp_rport_delete() and
rport_dev_loss_timedout() must check if rport->lld_data is NULL,
before accessing to rport->lld_data or any rport's target area.

Without this patch, the initiator's kernel could crash with the
following call trace, especially deleting remote ports as well as
IB link down cases.

How to reproduce:
1. Configure 500+ vdisks on target, and get initiator connected.
2. Exchange data intensively, which works well.
3. (On initiator) delete SRP remote port occasionally, e.g.
   # echo "1" > /sys/class/srp_remote_ports/port-6\:1/delete
   And configure again the SRP target.
4. (On target) disable Infiniband interface, and enable it again.
5. Repeat 3 and 4.

Then the initiator's kernel suddenly crashes. (but not always)

Kernel Call Trace:

BUG: unable to handle kernel paging request at 0000000000010001
IP: [<ffffffff8139ec55>] strnlen+0x5/0x40 PGD 212fea067 PUD 2162f8067 PMD 0
Oops: 0000 [#1] SMP CPU 0
Pid: 2311, comm: kworker/0:2 Not tainted 3.2.8 #1 Supermicro H8DGU/H8DGU
RIP: 0010:[<ffffffff8139ec55>]  [<ffffffff8139ec55>] strnlen+0x5/0x40
Process kworker/0:2 (pid: 2311, threadinfo ffff880215fe2000, task
ffff88020f2ce540)
Call Trace:
 [<ffffffff813a023c>] ? string+0x4c/0xe0
 [<ffffffff813a142d>] ? vsnprintf+0x1ed/0x5b0
 [<ffffffffa0131900>] ? do_srp_rport_del+0x30/0x30 [scsi_transport_srp]
 [<ffffffff813a18a9>] ? vscnprintf+0x9/0x20
 [<ffffffff81049b7f>] ? vprintk+0xaf/0x440
 [<ffffffff810f3cc0>] ? next_online_pgdat+0x20/0x50
 [<ffffffff810f3d20>] ? next_zone+0x30/0x40
 [<ffffffff810f4c60>] ? refresh_cpu_vm_stats+0xf0/0x160
 [<ffffffffa0131900>] ? do_srp_rport_del+0x30/0x30 [scsi_transport_srp]
 [<ffffffff816533b6>] ? printk+0x40/0x4a
 [<ffffffffa013192d>] ? rport_dev_loss_timedout+0x2d/0xa0 [scsi_transport_srp]
 [<ffffffff81063383>] ? process_one_work+0x113/0x470
 [<ffffffff81065c73>] ? worker_thread+0x163/0x3e0
 [<ffffffff81065b10>] ? manage_workers+0x200/0x200
 [<ffffffff81065b10>] ? manage_workers+0x200/0x200
 [<ffffffff8106a126>] ? kthread+0x96/0xa0
 [<ffffffff8165f674>] ? kernel_thread_helper+0x4/0x10
 [<ffffffff8106a090>] ? kthread_worker_fn+0x180/0x180
 [<ffffffff8165f670>] ? gs_change+0x13/0x13
RIP  [<ffffffff8139ec55>] strnlen+0x5/0x40
RSP <ffff880215fe3c28>
CR2: 0000000000010001
---[ end trace d55b61cd78c54a0a ]---
IP: [<ffffffff81069cb7>] kthread_data+0x7/0x10
Oops: 0000 [#2] SMP
CPU 3
Pid: 16745, comm: kworker/3:4 Tainted: G      D    O 3.2.8-pserver+
 #51 System manufacturer System Product Name/M4A89GTD-PRO
RIP: 0010:[<ffffffff81069cb7>]  [<ffffffff81069cb7>] kthread_data+0x7/0x10
Process kworker/3:4 (pid: 16745, threadinfo ffff8801f8162000, task
ffff88020ff91440)
Call Trace:
 [<ffffffff81062fc8>] ? wq_worker_sleeping+0x8/0x90
 [<ffffffff81653ca2>] ? __schedule+0x432/0x7e0
 [<ffffffff8104ce54>] ? do_exit+0x5d4/0x8a0
 [<ffffffff816533b6>] ? printk+0x40/0x4a
 [<ffffffff81656d13>] ? oops_end+0xa3/0xf0
 [<ffffffff8102b33d>] ? no_context+0xfd/0x270
 [<ffffffff8103dd55>] ? check_preempt_wakeup+0x155/0x1d0
 [<ffffffff8165951a>] ? do_page_fault+0x31a/0x440
 [<ffffffff810406d2>] ? select_task_rq_fair+0x432/0x9d0
 [<ffffffff81396b32>] ? cpumask_next_and+0x22/0x40
 [<ffffffff810391f3>] ? find_busiest_group+0x1f3/0xb30
 [<ffffffff81656285>] ? page_fault+0x25/0x30
 [<ffffffff8139ec55>] ? strnlen+0x5/0x40
 [<ffffffff813a023c>] ? string+0x4c/0xe0
 [<ffffffff813a142d>] ? vsnprintf+0x1ed/0x5b0
 [<ffffffffa0121900>] ? do_srp_rport_del+0x30/0x30 [scsi_transport_srp]
 [<ffffffff813a18a9>] ? vscnprintf+0x9/0x20
 [<ffffffff81049b7f>] ? vprintk+0xaf/0x440
 [<ffffffff8104e429>] ? ns_to_timeval+0x9/0x40
 [<ffffffff81062f87>] ? queue_delayed_work_on+0x157/0x170
 [<ffffffffa0121900>] ? do_srp_rport_del+0x30/0x30 [scsi_transport_srp]
 [<ffffffff816533b6>] ? printk+0x40/0x4a
 [<ffffffffa012192d>] ? rport_dev_loss_timedout+0x2d/0xa0 [scsi_transport_srp]
 [<ffffffff814f43f0>] ? cpufreq_governor_dbs+0x4b0/0x4b0
 [<ffffffff81063383>] ? process_one_work+0x113/0x470
 [<ffffffff81065c73>] ? worker_thread+0x163/0x3e0
 [<ffffffff81065b10>] ? manage_workers+0x200/0x200
 [<ffffffff81065b10>] ? manage_workers+0x200/0x200
 [<ffffffff8106a126>] ? kthread+0x96/0xa0
 [<ffffffff8165f674>] ? kernel_thread_helper+0x4/0x10
 [<ffffffff8106a090>] ? kthread_worker_fn+0x180/0x180
 [<ffffffff8165f670>] ? gs_change+0x13/0x13
RIP  [<ffffffff81069cb7>] kthread_data+0x7/0x10
RSP <ffff8801f81638d0>
CR2: fffffffffffffff8
---[ end trace cab7f2c38a7f7ba9 ]---

Signed-off-by: Dongsu Park <dongsu.park@profitbricks.com>
ib_srp: fix an error accessing invalid memory in rport_dev_loss_timedout

In rport_dev_loss_timedout(), rport must be obtained by accessing
the member entry dev_loss_work, not fast_io_fail_work.

Signed-off-By: Bart Van Assche <bvanassche@acm.org>