Re: [PATCH 32/32] target: Increase MAX_LUNS_PER_TPG to 16384
On 12/14/2013 12:59 AM, Andy Grover wrote: Indicate support for hierarchical LUN addressing. Set address method field in each LUN reported by REPORT LUNS to 1, in accordance with SCSI SAM specs. Signed-off-by: Andy Grover agro...@redhat.com --- drivers/target/target_core_spc.c |8 ++-- include/target/target_core_base.h |4 ++-- 2 files changed, 8 insertions(+), 4 deletions(-) diff --git a/drivers/target/target_core_spc.c b/drivers/target/target_core_spc.c index 0b678fc..04690bf 100644 --- a/drivers/target/target_core_spc.c +++ b/drivers/target/target_core_spc.c @@ -79,7 +79,7 @@ spc_emulate_inquiry_std(struct se_cmd *cmd, unsigned char *buf) buf[2] = 0x05; /* SPC-3 */ /* - * NORMACA and HISUP = 0, RESPONSE DATA FORMAT = 2 + * NORMACA = 0, HISUP = 1, RESPONSE DATA FORMAT = 2 * * SPC4 says: * A RESPONSE DATA FORMAT field set to 2h indicates that the @@ -88,7 +88,7 @@ spc_emulate_inquiry_std(struct se_cmd *cmd, unsigned char *buf) * obsolete. Response data format values greater than 2h are * reserved. */ - buf[3] = 2; + buf[3] = 0x12; /* * Enable SCCS and TPGS fields for Emulated ALUA @@ -1164,6 +1164,10 @@ sense_reason_t spc_emulate_report_luns(struct se_cmd *cmd) break; int_to_scsilun(deve-mapped_lun, (struct scsi_lun *)buf[offset]); + + /* Address method 1 for hier flat-space address. see SAM-5 */ + buf[offset] |= (1 6); + offset += 8; } spin_unlock_irq(sess-se_node_acl-device_list_lock); diff --git a/include/target/target_core_base.h b/include/target/target_core_base.h index 08ecfed..537cc67 100644 --- a/include/target/target_core_base.h +++ b/include/target/target_core_base.h @@ -14,8 +14,8 @@ #define TARGET_CORE_VERSION TARGET_CORE_MOD_VERSION /* Maximum Number of LUNs per Target Portal Group */ -/* Don't raise above 511 or REPORT_LUNS needs to handle 1 page */ -#define TRANSPORT_MAX_LUNS_PER_TPG 256 +/* Don't raise above 16384 or a different format in report_luns is needed */ +#define TRANSPORT_MAX_LUNS_PER_TPG 16384 /* * By default we use 32-byte CDBs in TCM Core and subsystem plugin code. * NO WAY. TCM is (currently) keeping the LUNs in a static array. Which is sort-of-okay if the number of LUNs is somewhat reasonable, as it was for 256. But 16k is way beyond any sensible number and will increase the memory footprint by a massive amount, irrespective whether someone will actually _use_ such a large number of LUNs. Before attempting that one would need to convert the LUN array into something scalable, like a linked list or somesuch. 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 32/32] target: Increase MAX_LUNS_PER_TPG to 16384
On 12/16/2013 10:20 AM, Hannes Reinecke wrote: On 12/14/2013 12:59 AM, Andy Grover wrote: Indicate support for hierarchical LUN addressing. Set address method field in each LUN reported by REPORT LUNS to 1, in accordance with SCSI SAM specs. Signed-off-by: Andy Grover agro...@redhat.com --- drivers/target/target_core_spc.c |8 ++-- include/target/target_core_base.h |4 ++-- 2 files changed, 8 insertions(+), 4 deletions(-) diff --git a/drivers/target/target_core_spc.c b/drivers/target/target_core_spc.c index 0b678fc..04690bf 100644 --- a/drivers/target/target_core_spc.c +++ b/drivers/target/target_core_spc.c @@ -79,7 +79,7 @@ spc_emulate_inquiry_std(struct se_cmd *cmd, unsigned char *buf) buf[2] = 0x05; /* SPC-3 */ /* - * NORMACA and HISUP = 0, RESPONSE DATA FORMAT = 2 + * NORMACA = 0, HISUP = 1, RESPONSE DATA FORMAT = 2 * * SPC4 says: * A RESPONSE DATA FORMAT field set to 2h indicates that the @@ -88,7 +88,7 @@ spc_emulate_inquiry_std(struct se_cmd *cmd, unsigned char *buf) * obsolete. Response data format values greater than 2h are * reserved. */ -buf[3] = 2; +buf[3] = 0x12; /* * Enable SCCS and TPGS fields for Emulated ALUA @@ -1164,6 +1164,10 @@ sense_reason_t spc_emulate_report_luns(struct se_cmd *cmd) break; int_to_scsilun(deve-mapped_lun, (struct scsi_lun *)buf[offset]); + +/* Address method 1 for hier flat-space address. see SAM-5 */ +buf[offset] |= (1 6); + offset += 8; } spin_unlock_irq(sess-se_node_acl-device_list_lock); diff --git a/include/target/target_core_base.h b/include/target/target_core_base.h index 08ecfed..537cc67 100644 --- a/include/target/target_core_base.h +++ b/include/target/target_core_base.h @@ -14,8 +14,8 @@ #define TARGET_CORE_VERSION TARGET_CORE_MOD_VERSION /* Maximum Number of LUNs per Target Portal Group */ -/* Don't raise above 511 or REPORT_LUNS needs to handle 1 page */ -#define TRANSPORT_MAX_LUNS_PER_TPG 256 +/* Don't raise above 16384 or a different format in report_luns is needed */ +#define TRANSPORT_MAX_LUNS_PER_TPG 16384 /* * By default we use 32-byte CDBs in TCM Core and subsystem plugin code. * NO WAY. TCM is (currently) keeping the LUNs in a static array. Which is sort-of-okay if the number of LUNs is somewhat reasonable, as it was for 256. But 16k is way beyond any sensible number and will increase the memory footprint by a massive amount, irrespective whether someone will actually _use_ such a large number of LUNs. Before attempting that one would need to convert the LUN array into something scalable, like a linked list or somesuch. Ouch. Please ignore this mail. One should _really_ read the entire patchset before jumping to conclusions. Monday morning and all that ... Sorry for the noise. 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: Possible locking bug in pm8xxx/pm8001
Jason, I have sent you the patch for testing. Could you please help testing this patch? Will submit it here once it is tested by you. Regards, Suresh -Original Message- From: Suresh Thiagarajan [mailto:sureshka...@gmail.com] Sent: Wednesday, November 27, 2013 11:11 AM To: Jason Seba Cc: linux-scsi@vger.kernel.org; Suresh Thiagarajan Subject: Re: Possible locking bug in pm8xxx/pm8001 Hi Jason On Sat, Oct 12, 2013 at 2:02 AM, Jason Seba jason.seb...@gmail.com wrote: The pm8xxx driver uses a per-adapter spinlock (pm8001_ha-lock) which is usually acquired and released with the irqsave routines. However, some functions which are called with the lock held (mpi_sata_completion, mpi_sata_event, pm8001_chip_sata_req) will temporary release the lock to complete a task. However, when releasing and reacquiring the lock in this case, the irqsave routine are not used; instead spin_unlock_irq/spin_lock_irq are used. As far as I can tell, this is wrong and dangerous, and appears to result in the hard lockup shown below. It isn't obvious to me what the best way to fix this is. Suggestions? This can be fixed by using flag variable from pm8001_hba_info structure instead of taking it as local variable in all the functions. Will send out a patch soon to fix this. Regards, Suresh [ 2048.017802] [ cut here ] [ 2048.022621] WARNING: CPU: 0 PID: 1606 at kernel/watchdog.c:245 watchdog_overflow_callback+0xac/0xd0() [ 2048.031827] Watchdog detected hard LOCKUP on cpu 0 [ 2048.036439] Modules linked in: ses enclosure xt_CHECKSUM iptable_mangle ipt_MASQUERADE iptable_nat nf_nat_ipv4 nf_nat bridge sunrpc fcoe 8021q mrp garp libfcoe libfc scsi_transport_fc stp llc scsi_tgt xt_physdev nf_conntrack_ipv4 nf_defrag_ipv4 ip6t_REJECT nf_conntrack_ipv6 nf_defrag_ipv6 xt_state nf_conntrack ip6table_filter ip6_tables binfmt_misc uinput iTCO_wdt iTCO_vendor_support mgag200 ttm drm_kms_helper drm i2c_algo_bit sysimgblt sysfillrect syscopyarea pm80xx libsas scsi_transport_sas joydev dcdbas pcspkr i2c_i801 i2c_core lpc_ich mfd_core tg3 ptp pps_core [last unloaded: speedstep_lib] [ 2048.090159] CPU: 0 PID: 1606 Comm: libvirtd Not tainted 3.11.0-rc5+ #2 [ 2048.096682] Hardware name: Dell Inc. PowerEdge T110 II/015TH9, BIOS 2.0.5 03/13/2012 [ 2048.104410] 00f5 f3401828 c1580fe3 c1710301 f3401858 c10418e4 c17061bc f3401884 [ 2048.112277] 0646 c1710301 00f5 c10c415c c10c415c f5822800 c10c40b0 [ 2048.120153] f3401870 c10419a3 0009 f3401868 c17061bc f3401884 f3401888 c10c415c [ 2048.128022] Call Trace: [ 2048.130476] [c1580fe3] dump_stack+0x41/0x56 [ 2048.134921] [c10418e4] warn_slowpath_common+0x84/0xa0 [ 2048.140231] [c10c415c] ? watchdog_overflow_callback+0xac/0xd0 [ 2048.146236] [c10c415c] ? watchdog_overflow_callback+0xac/0xd0 [ 2048.152239] [c10c40b0] ? watchdog_cleanup+0x10/0x10 [ 2048.157369] [c10419a3] warn_slowpath_fmt+0x33/0x40 [ 2048.162420] [c10c415c] watchdog_overflow_callback+0xac/0xd0 [ 2048.168243] [c10fbbef] __perf_event_overflow+0xaf/0x280 [ 2048.173729] [c101322a] ? x86_perf_event_set_period+0x12a/0x1e0 [ 2048.179819] [c10fc685] perf_event_overflow+0x15/0x20 [ 2048.185043] [c1019d9b] intel_pmu_handle_irq+0x1bb/0x390 [ 2048.190519] [c107019d] ? sched_clock_cpu+0x11d/0x1a0 [ 2048.195744] [c1586871] perf_event_nmi_handler+0x31/0x50 [ 2048.201229] [c1585f52] nmi_handle+0x52/0x190 [ 2048.205762] [c1342b60] ? serial8250_modem_status+0xb0/0xb0 [ 2048.211504] [c1586172] do_nmi+0xe2/0x3d0 [ 2048.215681] [c15856bb] nmi_stack_correct+0x2f/0x34 [ 2048.220732] [c15800d8] ? __pci_bus_size_bridges+0x868/0x890 [ 2048.226563] [c1584c12] ? _raw_spin_lock_irqsave+0x22/0x30 [ 2048.232215] [f80f018e] process_oq+0x6ae/0x1820 [pm80xx] [ 2048.237698] [f80f1323] pm8001_chip_isr+0x23/0x40 [pm80xx] [ 2048.243356] [f80e501f] pm8001_tasklet+0x1f/0x30 [pm80xx] [ 2048.248925] [c10458de] tasklet_action+0x8e/0xa0 [ 2048.253709] [c104616f] __do_softirq+0xaf/0x200 [ 2048.258406] [c10463a5] irq_exit+0xa5/0xb0 [ 2048.262676] [c158c45b] do_IRQ+0x4b/0xc0 [ 2048.266768] [c105f67b] ? add_wait_queue+0x3b/0x50 [ 2048.271730] [c158c333] common_interrupt+0x33/0x38 [ 2048.276687] [c14800d8] ? qi_flush_dev_iotlb+0x98/0xf0 [ 2048.282001] [c1167fb1] ? poll_schedule_timeout+0x1/0xb0 [ 2048.287483] [c1168eed] ? do_sys_poll+0x4ad/0x530 [ 2048.292352] [c11681e0] ? __pollwait+0xe0/0xe0 [ 2048.296962] [c11681e0] ? __pollwait+0xe0/0xe0 [ 2048.301581] [c11681e0] ? __pollwait+0xe0/0xe0 [ 2048.306197] [c11681e0] ? __pollwait+0xe0/0xe0 [ 2048.310808] [c11681e0] ? __pollwait+0xe0/0xe0 [ 2048.315416] [c11681e0] ? __pollwait+0xe0/0xe0 [ 2048.320026] [c14c4ef4] ? netlink_recvmsg+0x294/0x340 [ 2048.325244] [c123827d] ? selinux_socket_recvmsg+0x1d/0x20 [ 2048.330901] [c148d5b0] ? sock_recvmsg+0xc0/0xf0 [ 2048.335692] [c10733c7] ? update_curr+0x1e7/0x290 [ 2048.340572] [c148b56d] ?
[PATCH 14/24] qla4xxx: Driver not able to collect minidump for ISP84xx
From: Tej Parkash tej.park...@qlogic.com Issue: minidump data collection fails as driver reports data mismatch Fix: When the driver encounters a new entry type that it cannot process, it should just skip the entry and adjust the total buffer size by subtracting the skipped bytes from it. This is to ensure that there is no data mismatch because of the new entries. Signed-off-by: Tej Parkash tej.park...@qlogic.com Signed-off-by: Vikas Chaudhary vikas.chaudh...@qlogic.com --- drivers/scsi/qla4xxx/ql4_def.h | 1 + drivers/scsi/qla4xxx/ql4_nx.c | 8 +++- 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/drivers/scsi/qla4xxx/ql4_def.h b/drivers/scsi/qla4xxx/ql4_def.h index c2deaa0..73a5022 100644 --- a/drivers/scsi/qla4xxx/ql4_def.h +++ b/drivers/scsi/qla4xxx/ql4_def.h @@ -769,6 +769,7 @@ struct scsi_qla_host { uint32_t fw_dump_capture_mask; void *fw_dump_tmplt_hdr; uint32_t fw_dump_tmplt_size; + uint32_t fw_dump_skip_size; struct completion mbx_intr_comp; diff --git a/drivers/scsi/qla4xxx/ql4_nx.c b/drivers/scsi/qla4xxx/ql4_nx.c index bcf3e43..d2040b4 100644 --- a/drivers/scsi/qla4xxx/ql4_nx.c +++ b/drivers/scsi/qla4xxx/ql4_nx.c @@ -2383,6 +2383,11 @@ static void qla4_8xxx_mark_entry_skipped(struct scsi_qla_host *ha, scsi(%ld): Skipping entry[%d]: ETYPE[0x%x]-ELEVEL[0x%x]\n, ha-host_no, index, entry_hdr-entry_type, entry_hdr-d_ctrl.entry_capture_mask)); + /* If driver encounters a new entry type that it cannot process, +* it should just skip the entry and adjust the total buffer size by +* from subtracting the skipped bytes from it +*/ + ha-fw_dump_skip_size += entry_hdr-entry_capture_size; } /* ISP83xx functions to process new minidump entries... */ @@ -2590,6 +2595,7 @@ static int qla4_8xxx_collect_md_data(struct scsi_qla_host *ha) uint64_t now; uint32_t timestamp; + ha-fw_dump_skip_size = 0; if (!ha-fw_dump) { ql4_printk(KERN_INFO, ha, %s(%ld) No buffer to dump\n, __func__, ha-host_no); @@ -2761,7 +2767,7 @@ skip_nxt_entry: entry_hdr-entry_size); } - if (data_collected != ha-fw_dump_size) { + if ((data_collected + ha-fw_dump_skip_size) != ha-fw_dump_size) { ql4_printk(KERN_INFO, ha, Dump data mismatch: Data collected: [0x%x], total_data_size:[0x%x]\n, data_collected, ha-fw_dump_size); -- 1.8.2.GIT -- 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
[PATCH 15/24] qla4xxx: Reduce rom-lock contention during reset recovery.
From: Vikas Chaudhary vikas.chaudh...@qlogic.com Issue: Driver holds rom-lock for too long during reset recovery. During adapter reset testing, it was found that the driver holds the rom-lock for too long, because of which other drivers fail to acquire the rom-lock, leading to reset failures. The primary cause is, in the bootstrap code, while holding the rom-lock, the driver checks if the peg is halted, causing a 2 second contention. Fix: When a reset recovery starts, the driver deduces the cause, and sets appropriate flags in watchdog recover_adapter routines. This flag should be used to determine if bootstrap is invoked from probe or reset context, reducing the rom-lock footprint of the drivers. Signed-off-by: Vikas Chaudhary vikas.chaudh...@qlogic.com --- drivers/scsi/qla4xxx/ql4_nx.c | 33 - 1 file changed, 12 insertions(+), 21 deletions(-) diff --git a/drivers/scsi/qla4xxx/ql4_nx.c b/drivers/scsi/qla4xxx/ql4_nx.c index d2040b4..63328c8 100644 --- a/drivers/scsi/qla4xxx/ql4_nx.c +++ b/drivers/scsi/qla4xxx/ql4_nx.c @@ -2828,37 +2828,28 @@ int qla4_8xxx_device_bootstrap(struct scsi_qla_host *ha) int rval = QLA_ERROR; int i; uint32_t old_count, count; - int need_reset = 0, peg_stuck = 1; + int need_reset = 0; need_reset = ha-isp_ops-need_reset(ha); - old_count = qla4_8xxx_rd_direct(ha, QLA8XXX_PEG_ALIVE_COUNTER); - - for (i = 0; i 10; i++) { - msleep(200); - count = qla4_8xxx_rd_direct(ha, QLA8XXX_PEG_ALIVE_COUNTER); - if (count != old_count) - peg_stuck = 0; - } if (need_reset) { /* We are trying to perform a recovery here. */ - if (peg_stuck) + if (test_bit(AF_FW_RECOVERY, ha-flags)) ha-isp_ops-rom_lock_recovery(ha); - goto dev_initialize; } else { - /* Start of day for this ha context. */ - if (peg_stuck) { - /* Either we are the first or recovery in progress. */ - ha-isp_ops-rom_lock_recovery(ha); - goto dev_initialize; - } else { - /* Firmware already running. */ - rval = QLA_SUCCESS; - goto dev_ready; + old_count = qla4_8xxx_rd_direct(ha, QLA8XXX_PEG_ALIVE_COUNTER); + for (i = 0; i 10; i++) { + msleep(200); + count = qla4_8xxx_rd_direct(ha, + QLA8XXX_PEG_ALIVE_COUNTER); + if (count != old_count) { + rval = QLA_SUCCESS; + goto dev_ready; + } } + ha-isp_ops-rom_lock_recovery(ha); } -dev_initialize: /* set to DEV_INITIALIZING */ ql4_printk(KERN_INFO, ha, HW State: INITIALIZING\n); qla4_8xxx_wr_direct(ha, QLA8XXX_CRB_DEV_STATE, -- 1.8.2.GIT -- 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
[PATCH 11/24] qla4xxx: Fix failure of IDC Time Extend mailbox command
From: Vikas Chaudhary vikas.chaudh...@qlogic.com Issue: Mailbox command 0x102 (IDC Time Extend) failure seen while applying changes to iface using iscsiadm Fix: Added fix to extend IDC timeout only for ISP84xx when IDC ACK needs to be posted and disable ACB mailbox command completion is in intermediate state. Signed-off-by: Vikas Chaudhary vikas.chaudh...@qlogic.com --- drivers/scsi/qla4xxx/ql4_mbx.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/scsi/qla4xxx/ql4_mbx.c b/drivers/scsi/qla4xxx/ql4_mbx.c index 023f2dd..1d8f485 100644 --- a/drivers/scsi/qla4xxx/ql4_mbx.c +++ b/drivers/scsi/qla4xxx/ql4_mbx.c @@ -1922,6 +1922,7 @@ int qla4xxx_disable_acb(struct scsi_qla_host *ha) mbox_sts[0], mbox_sts[1], mbox_sts[2])); } else { if (is_qla8042(ha) + test_bit(DPC_POST_IDC_ACK, ha-dpc_flags) (mbox_sts[0] != MBOX_STS_COMMAND_COMPLETE)) { /* * Disable ACB mailbox command takes time to complete -- 1.8.2.GIT -- 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
[PATCH 13/24] qla4xxx: Fix pending IO completion in reset path before initiating chip reset
From: Tej Parkash tej.park...@qlogic.com Issue: Pending IO wait does not complete after triggering Graceful reset, causing ack timeout and call traces. Fix: 1. Reducing the IO command wait timeout before triggering reset, as logically also timeout should be less than reset timeout (10sec). 2. Moving the abort IO after chip reset, because only after chip reset, driver owns the IO otherwise it is with firmware and can still revert back with response. Signed-off-by: Tej Parkash tej.park...@qlogic.com Signed-off-by: Vikas Chaudhary vikas.chaudh...@qlogic.com --- drivers/scsi/qla4xxx/ql4_def.h | 2 +- drivers/scsi/qla4xxx/ql4_os.c | 16 2 files changed, 13 insertions(+), 5 deletions(-) diff --git a/drivers/scsi/qla4xxx/ql4_def.h b/drivers/scsi/qla4xxx/ql4_def.h index 33eae2e..c2deaa0 100644 --- a/drivers/scsi/qla4xxx/ql4_def.h +++ b/drivers/scsi/qla4xxx/ql4_def.h @@ -194,7 +194,7 @@ #define ADAPTER_INIT_TOV 30 #define ADAPTER_RESET_TOV 180 #define EXTEND_CMD_TOV 60 -#define WAIT_CMD_TOV 30 +#define WAIT_CMD_TOV 5 #define EH_WAIT_CMD_TOV120 #define FIRMWARE_UP_TOV60 #define RESET_FIRMWARE_TOV 30 diff --git a/drivers/scsi/qla4xxx/ql4_os.c b/drivers/scsi/qla4xxx/ql4_os.c index 3fec116..a27da31 100644 --- a/drivers/scsi/qla4xxx/ql4_os.c +++ b/drivers/scsi/qla4xxx/ql4_os.c @@ -4561,11 +4561,19 @@ static int qla4xxx_cmd_wait(struct scsi_qla_host *ha) uint32_t index = 0; unsigned long flags; struct scsi_cmnd *cmd; + unsigned long wtime; + uint32_t wtmo; - unsigned long wtime = jiffies + (WAIT_CMD_TOV * HZ); + if (is_qla40XX(ha)) + wtmo = WAIT_CMD_TOV; + else + wtmo = ha-nx_reset_timeout / 2; - DEBUG2(ql4_printk(KERN_INFO, ha, Wait up to %d seconds for cmds to - complete\n, WAIT_CMD_TOV)); + wtime = jiffies + (wtmo * HZ); + + DEBUG2(ql4_printk(KERN_INFO, ha, + Wait up to %u seconds for cmds to complete\n, + wtmo)); while (!time_after_eq(jiffies, wtime)) { spin_lock_irqsave(ha-hardware_lock, flags); @@ -4868,11 +4876,11 @@ chip_reset: qla4xxx_cmd_wait(ha); qla4xxx_process_aen(ha, FLUSH_DDB_CHANGED_AENS); - qla4xxx_abort_active_cmds(ha, DID_RESET 16); DEBUG2(ql4_printk(KERN_INFO, ha, scsi%ld: %s - Performing chip reset..\n, ha-host_no, __func__)); status = ha-isp_ops-reset_chip(ha); + qla4xxx_abort_active_cmds(ha, DID_RESET 16); } /* Flush any pending ddb changed AENs */ -- 1.8.2.GIT -- 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
[PATCH 07/24] qla4xxx: Correctly handle msleep_interruptible
From: Vikas Chaudhary vikas.chaudh...@qlogic.com If waiting for signals was interrupted then the device was put to FAILED state. Use msleep instead of msleep_interruptible to handle this correctly. Signed-off-by: Vikas Chaudhary vikas.chaudh...@qlogic.com --- drivers/scsi/qla4xxx/ql4_nx.c | 10 ++ 1 file changed, 2 insertions(+), 8 deletions(-) diff --git a/drivers/scsi/qla4xxx/ql4_nx.c b/drivers/scsi/qla4xxx/ql4_nx.c index 0ec07ec..cbc68f9 100644 --- a/drivers/scsi/qla4xxx/ql4_nx.c +++ b/drivers/scsi/qla4xxx/ql4_nx.c @@ -2820,7 +2820,7 @@ void qla4_8xxx_get_minidump(struct scsi_qla_host *ha) int qla4_8xxx_device_bootstrap(struct scsi_qla_host *ha) { int rval = QLA_ERROR; - int i, timeout; + int i; uint32_t old_count, count; int need_reset = 0, peg_stuck = 1; @@ -2828,13 +2828,7 @@ int qla4_8xxx_device_bootstrap(struct scsi_qla_host *ha) old_count = qla4_8xxx_rd_direct(ha, QLA8XXX_PEG_ALIVE_COUNTER); for (i = 0; i 10; i++) { - timeout = msleep_interruptible(200); - if (timeout) { - qla4_8xxx_wr_direct(ha, QLA8XXX_CRB_DEV_STATE, - QLA8XXX_DEV_FAILED); - return rval; - } - + msleep(200); count = qla4_8xxx_rd_direct(ha, QLA8XXX_PEG_ALIVE_COUNTER); if (count != old_count) peg_stuck = 0; -- 1.8.2.GIT -- 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
[PATCH 24/24] qla4xxx: Update driver version to 5.04.00-k4
From: Vikas Chaudhary vikas.chaudh...@qlogic.com Signed-off-by: Vikas Chaudhary vikas.chaudh...@qlogic.com --- drivers/scsi/qla4xxx/ql4_version.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/scsi/qla4xxx/ql4_version.h b/drivers/scsi/qla4xxx/ql4_version.h index 9b29466..c6ba0a6 100644 --- a/drivers/scsi/qla4xxx/ql4_version.h +++ b/drivers/scsi/qla4xxx/ql4_version.h @@ -5,4 +5,4 @@ * See LICENSE.qla4xxx for copyright and licensing details. */ -#define QLA4XXX_DRIVER_VERSION 5.04.00-k3 +#define QLA4XXX_DRIVER_VERSION 5.04.00-k4 -- 1.8.2.GIT -- 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
[PATCH 09/24] qla4xxx: Return correct error status from func qla4xxx_request_irqs()
From: Vikas Chaudhary vikas.chaudh...@qlogic.com Signed-off-by: Vikas Chaudhary vikas.chaudh...@qlogic.com --- drivers/scsi/qla4xxx/ql4_isr.c | 6 -- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/drivers/scsi/qla4xxx/ql4_isr.c b/drivers/scsi/qla4xxx/ql4_isr.c index e56c6b4..49032f6 100644 --- a/drivers/scsi/qla4xxx/ql4_isr.c +++ b/drivers/scsi/qla4xxx/ql4_isr.c @@ -1488,6 +1488,7 @@ void qla4xxx_process_aen(struct scsi_qla_host * ha, uint8_t process_aen) int qla4xxx_request_irqs(struct scsi_qla_host *ha) { int ret; + int rval = QLA_ERROR; if (is_qla40XX(ha)) goto try_intx; @@ -1568,9 +1569,10 @@ irq_attached: set_bit(AF_IRQ_ATTACHED, ha-flags); ha-host-irq = ha-pdev-irq; ql4_printk(KERN_INFO, ha, %s: irq %d attached\n, - __func__, ha-pdev-irq); + __func__, ha-pdev-irq); + rval = QLA_SUCCESS; irq_not_attached: - return ret; + return rval; } void qla4xxx_free_irqs(struct scsi_qla_host *ha) -- 1.8.2.GIT -- 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
[PATCH 01/24] qla4xxx: ISP8xxx: Correct retry of adapter initialization
From: Nilesh Javali nilesh.jav...@qlogic.com Issue: For ISP8xxx, adapter initialization is not retried if qla4xxx_initialize_adapter fails. Fix: If qla4xxx_initialize_adapter fails, first check if failure is due to IRQs not attached in order to skip retrial, then free the IRQs and then retry initializing the adapter. Signed-off-by: Nilesh Javali nilesh.jav...@qlogic.com Signed-off-by: Vikas Chaudhary vikas.chaudh...@qlogic.com --- drivers/scsi/qla4xxx/ql4_glbl.h | 1 + drivers/scsi/qla4xxx/ql4_init.c | 7 +-- drivers/scsi/qla4xxx/ql4_nx.c | 21 + drivers/scsi/qla4xxx/ql4_os.c | 27 ++- 4 files changed, 45 insertions(+), 11 deletions(-) diff --git a/drivers/scsi/qla4xxx/ql4_glbl.h b/drivers/scsi/qla4xxx/ql4_glbl.h index d67c50e..6d72e1d 100644 --- a/drivers/scsi/qla4xxx/ql4_glbl.h +++ b/drivers/scsi/qla4xxx/ql4_glbl.h @@ -279,6 +279,7 @@ int qla4_83xx_ms_mem_write_128b(struct scsi_qla_host *ha, uint8_t qla4xxx_set_ipaddr_state(uint8_t fw_ipaddr_state); int qla4_83xx_get_port_config(struct scsi_qla_host *ha, uint32_t *config); int qla4_83xx_set_port_config(struct scsi_qla_host *ha, uint32_t *config); +int qla4_8xxx_check_init_adapter_retry(struct scsi_qla_host *ha); extern int ql4xextended_error_logging; extern int ql4xdontresethba; diff --git a/drivers/scsi/qla4xxx/ql4_init.c b/drivers/scsi/qla4xxx/ql4_init.c index 7456eeb..28fbece 100644 --- a/drivers/scsi/qla4xxx/ql4_init.c +++ b/drivers/scsi/qla4xxx/ql4_init.c @@ -959,13 +959,8 @@ int qla4xxx_initialize_adapter(struct scsi_qla_host *ha, int is_reset) qla4xxx_build_ddb_list(ha, is_reset); set_bit(AF_ONLINE, ha-flags); -exit_init_hba: - if (is_qla80XX(ha) (status == QLA_ERROR)) { - /* Since interrupts are registered in start_firmware for -* 80XX, release them here if initialize_adapter fails */ - qla4xxx_free_irqs(ha); - } +exit_init_hba: DEBUG2(printk(scsi%ld: initialize adapter: %s\n, ha-host_no, status == QLA_ERROR ? FAILED : SUCCEEDED)); return status; diff --git a/drivers/scsi/qla4xxx/ql4_nx.c b/drivers/scsi/qla4xxx/ql4_nx.c index d001202..bbe8361 100644 --- a/drivers/scsi/qla4xxx/ql4_nx.c +++ b/drivers/scsi/qla4xxx/ql4_nx.c @@ -3836,3 +3836,24 @@ qla4_8xxx_enable_msix(struct scsi_qla_host *ha) msix_out: return ret; } + +int qla4_8xxx_check_init_adapter_retry(struct scsi_qla_host *ha) +{ + int status = QLA_SUCCESS; + + /* Dont retry adapter initialization if IRQ allocation failed */ + if (!test_bit(AF_IRQ_ATTACHED, ha-flags)) { + ql4_printk(KERN_WARNING, ha, %s: Skipping retry of adapter initialization as IRQs are not attached\n, + __func__); + status = QLA_ERROR; + goto exit_init_adapter_failure; + } + + /* Since interrupts are registered in start_firmware for +* 8xxx, release them here if initialize_adapter fails +* and retry adapter initialization */ + qla4xxx_free_irqs(ha); + +exit_init_adapter_failure: + return status; +} diff --git a/drivers/scsi/qla4xxx/ql4_os.c b/drivers/scsi/qla4xxx/ql4_os.c index c21adc3..9803c9e 100644 --- a/drivers/scsi/qla4xxx/ql4_os.c +++ b/drivers/scsi/qla4xxx/ql4_os.c @@ -4881,8 +4881,21 @@ recover_ha_init_adapter: ssleep(6); /* NOTE: AF_ONLINE flag set upon successful completion of -* qla4xxx_initialize_adapter */ +* qla4xxx_initialize_adapter */ status = qla4xxx_initialize_adapter(ha, RESET_ADAPTER); + if (is_qla80XX(ha) (status == QLA_ERROR)) { + status = qla4_8xxx_check_init_adapter_retry(ha); + if (status == QLA_ERROR) { + ql4_printk(KERN_INFO, ha, scsi%ld: %s: Don't retry recover adapter\n, + ha-host_no, __func__); + qla4xxx_dead_adapter_cleanup(ha); + clear_bit(DPC_RETRY_RESET_HA, ha-dpc_flags); + clear_bit(DPC_RESET_HA, ha-dpc_flags); + clear_bit(DPC_RESET_HA_FW_CONTEXT, + ha-dpc_flags); + goto exit_recover; + } + } } /* Retry failed adapter initialization, if necessary @@ -8681,11 +8694,8 @@ static int qla4xxx_probe_adapter(struct pci_dev *pdev, status = qla4xxx_initialize_adapter(ha, INIT_ADAPTER); /* Dont retry adapter initialization if IRQ allocation failed */ - if (is_qla80XX(ha) !test_bit(AF_IRQ_ATTACHED, ha-flags)) { - ql4_printk(KERN_WARNING, ha, %s: Skipping retry of adapter initialization\n, - __func__); + if (is_qla80XX(ha) (status == QLA_ERROR))
[PATCH 03/24] qla4xxx: Fix comments in code
From: Vikas Chaudhary vikas.chaudh...@qlogic.com Signed-off-by: Vikas Chaudhary vikas.chaudh...@qlogic.com --- drivers/scsi/qla4xxx/ql4_def.h | 8 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/drivers/scsi/qla4xxx/ql4_def.h b/drivers/scsi/qla4xxx/ql4_def.h index aa67bb9..e9df4ad 100644 --- a/drivers/scsi/qla4xxx/ql4_def.h +++ b/drivers/scsi/qla4xxx/ql4_def.h @@ -595,10 +595,10 @@ struct scsi_qla_host { #define DPC_AEN9 /* 0x0200 */ #define DPC_GET_DHCP_IP_ADDR 15 /* 0x8000 */ #define DPC_LINK_CHANGED 18 /* 0x0004 */ -#define DPC_RESET_ACTIVE 20 /* 0x0004 */ -#define DPC_HA_UNRECOVERABLE 21 /* 0x0008 ISP-82xx only*/ -#define DPC_HA_NEED_QUIESCENT 22 /* 0x0010 ISP-82xx only*/ -#define DPC_POST_IDC_ACK 23 /* 0x0020 */ +#define DPC_RESET_ACTIVE 20 /* 0x0010 */ +#define DPC_HA_UNRECOVERABLE 21 /* 0x0020 ISP-82xx only*/ +#define DPC_HA_NEED_QUIESCENT 22 /* 0x0040 ISP-82xx only*/ +#define DPC_POST_IDC_ACK 23 /* 0x0080 */ #define DPC_RESTORE_ACB24 /* 0x0100 */ struct Scsi_Host *host; /* pointer to host data */ -- 1.8.2.GIT -- 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
[PATCH 23/24] qla4xxx: Fix sparse warnings
From: Vikas Chaudhary vikas.chaudh...@qlogic.com Fix following sparse warnings:- drivers/scsi/qla4xxx/ql4_os.c:2109:33: warning: cast truncates bits from constant value (7fff becomes 7fff) drivers/scsi/qla4xxx/ql4_os.c:2306:33: warning: cast truncates bits from constant value (7fff becomes 7fff) Signed-off-by: Vikas Chaudhary vikas.chaudh...@qlogic.com --- drivers/scsi/qla4xxx/ql4_os.c | 6 -- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/drivers/scsi/qla4xxx/ql4_os.c b/drivers/scsi/qla4xxx/ql4_os.c index e8a8a7d..3c2240c 100644 --- a/drivers/scsi/qla4xxx/ql4_os.c +++ b/drivers/scsi/qla4xxx/ql4_os.c @@ -2109,7 +2109,8 @@ static void qla4xxx_set_ipv6(struct scsi_qla_host *ha, cpu_to_le16(IPV6_TCPOPT_DELAYED_ACK_DISABLE); else init_fw_cb-ipv6_tcp_opts = - cpu_to_le16(~IPV6_TCPOPT_DELAYED_ACK_DISABLE); + cpu_to_le16(~IPV6_TCPOPT_DELAYED_ACK_DISABLE + 0x); break; case ISCSI_NET_PARAM_TCP_NAGLE_DISABLE: if (iface_param-iface_num 0x1) @@ -2306,7 +2307,8 @@ static void qla4xxx_set_ipv4(struct scsi_qla_host *ha, cpu_to_le16(TCPOPT_DELAYED_ACK_DISABLE); else init_fw_cb-ipv4_tcp_opts = - cpu_to_le16(~TCPOPT_DELAYED_ACK_DISABLE); + cpu_to_le16(~TCPOPT_DELAYED_ACK_DISABLE + 0x); break; case ISCSI_NET_PARAM_TCP_NAGLE_DISABLE: if (iface_param-iface_num 0x1) -- 1.8.2.GIT -- 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
[PATCH 18/24] qla4xxx: Updated print for device login, logout path
From: Vikas Chaudhary vikas.chaudh...@qlogic.com Signed-off-by: Vikas Chaudhary vikas.chaudh...@qlogic.com --- drivers/scsi/qla4xxx/ql4_os.c | 59 +++ 1 file changed, 43 insertions(+), 16 deletions(-) diff --git a/drivers/scsi/qla4xxx/ql4_os.c b/drivers/scsi/qla4xxx/ql4_os.c index ce20c75..d0a8695 100644 --- a/drivers/scsi/qla4xxx/ql4_os.c +++ b/drivers/scsi/qla4xxx/ql4_os.c @@ -1670,16 +1670,13 @@ qla4xxx_ep_connect(struct Scsi_Host *shost, struct sockaddr *dst_addr, struct sockaddr_in *addr; struct sockaddr_in6 *addr6; - DEBUG2(printk(KERN_INFO Func: %s\n, __func__)); if (!shost) { ret = -ENXIO; - printk(KERN_ERR %s: shost is NULL\n, - __func__); + pr_err(%s: shost is NULL\n, __func__); return ERR_PTR(ret); } ha = iscsi_host_priv(shost); - ep = iscsi_create_endpoint(sizeof(struct qla_endpoint)); if (!ep) { ret = -ENOMEM; @@ -1699,6 +1696,9 @@ qla4xxx_ep_connect(struct Scsi_Host *shost, struct sockaddr *dst_addr, addr6 = (struct sockaddr_in6 *)qla_ep-dst_addr; DEBUG2(ql4_printk(KERN_INFO, ha, %s: %pI6\n, __func__, (char *)addr6-sin6_addr)); + } else { + ql4_printk(KERN_WARNING, ha, %s: Invalid endpoint\n, + __func__); } qla_ep-host = shost; @@ -1712,9 +1712,9 @@ static int qla4xxx_ep_poll(struct iscsi_endpoint *ep, int timeout_ms) struct scsi_qla_host *ha; int ret = 0; - DEBUG2(printk(KERN_INFO Func: %s\n, __func__)); qla_ep = ep-dd_data; ha = to_qla_host(qla_ep-host); + DEBUG2(pr_info_ratelimited(%s: host: %ld\n, __func__, ha-host_no)); if (adapter_up(ha) !test_bit(AF_BUILD_DDB_LIST, ha-flags)) ret = 1; @@ -1724,7 +1724,13 @@ static int qla4xxx_ep_poll(struct iscsi_endpoint *ep, int timeout_ms) static void qla4xxx_ep_disconnect(struct iscsi_endpoint *ep) { - DEBUG2(printk(KERN_INFO Func: %s\n, __func__)); + struct qla_endpoint *qla_ep; + struct scsi_qla_host *ha; + + qla_ep = ep-dd_data; + ha = to_qla_host(qla_ep-host); + DEBUG2(ql4_printk(KERN_INFO, ha, %s: host: %ld\n, __func__, + ha-host_no)); iscsi_destroy_endpoint(ep); } @@ -1734,8 +1740,11 @@ static int qla4xxx_get_ep_param(struct iscsi_endpoint *ep, { struct qla_endpoint *qla_ep = ep-dd_data; struct sockaddr *dst_addr; + struct scsi_qla_host *ha; - DEBUG2(printk(KERN_INFO Func: %s\n, __func__)); + ha = to_qla_host(qla_ep-host); + DEBUG2(ql4_printk(KERN_INFO, ha, %s: host: %ld\n, __func__, + ha-host_no)); switch (param) { case ISCSI_PARAM_CONN_PORT: @@ -1766,13 +1775,13 @@ static void qla4xxx_conn_get_stats(struct iscsi_cls_conn *cls_conn, int ret; dma_addr_t iscsi_stats_dma; - DEBUG2(printk(KERN_INFO Func: %s\n, __func__)); - cls_sess = iscsi_conn_to_session(cls_conn); sess = cls_sess-dd_data; ddb_entry = sess-dd_data; ha = ddb_entry-ha; + DEBUG2(ql4_printk(KERN_INFO, ha, %s: host: %ld\n, __func__, + ha-host_no)); stats_size = PAGE_ALIGN(sizeof(struct ql_iscsi_stats)); /* Allocate memory */ ql_iscsi_stats = dma_alloc_coherent(ha-pdev-dev, stats_size, @@ -3045,7 +3054,6 @@ qla4xxx_session_create(struct iscsi_endpoint *ep, struct sockaddr *dst_addr; int ret; - DEBUG2(printk(KERN_INFO Func: %s\n, __func__)); if (!ep) { printk(KERN_ERR qla4xxx: missing ep.\n); return NULL; @@ -3054,6 +3062,8 @@ qla4xxx_session_create(struct iscsi_endpoint *ep, qla_ep = ep-dd_data; dst_addr = (struct sockaddr *)qla_ep-dst_addr; ha = to_qla_host(qla_ep-host); + DEBUG2(ql4_printk(KERN_INFO, ha, %s: host: %ld\n, __func__, + ha-host_no)); ret = qla4xxx_get_ddb_index(ha, ddb_index); if (ret == QLA_ERROR) @@ -3093,10 +3103,11 @@ static void qla4xxx_session_destroy(struct iscsi_cls_session *cls_sess) uint32_t ddb_state; int ret; - DEBUG2(printk(KERN_INFO Func: %s\n, __func__)); sess = cls_sess-dd_data; ddb_entry = sess-dd_data; ha = ddb_entry-ha; + DEBUG2(ql4_printk(KERN_INFO, ha, %s: host: %ld\n, __func__, + ha-host_no)); fw_ddb_entry = dma_alloc_coherent(ha-pdev-dev, sizeof(*fw_ddb_entry), fw_ddb_entry_dma, GFP_KERNEL); @@ -3143,17 +3154,23 @@ qla4xxx_conn_create(struct iscsi_cls_session *cls_sess, uint32_t conn_idx) struct iscsi_cls_conn *cls_conn; struct iscsi_session *sess; struct ddb_entry *ddb_entry; +
[PATCH 16/24] qla4xxx: Fix failure of mbox 0x31
From: Vikas Chaudhary vikas.chaudh...@qlogic.com Issue: While unloading driver MBOX 0x31 fail as DDB logout (MBOX 0x56) operation is not completed. Fix: Wait for DDB Logout completion before MBOX 0x31 Signed-off-by: Vikas Chaudhary vikas.chaudh...@qlogic.com --- drivers/scsi/qla4xxx/ql4_os.c | 54 --- 1 file changed, 46 insertions(+), 8 deletions(-) diff --git a/drivers/scsi/qla4xxx/ql4_os.c b/drivers/scsi/qla4xxx/ql4_os.c index a27da31..ce20c75 100644 --- a/drivers/scsi/qla4xxx/ql4_os.c +++ b/drivers/scsi/qla4xxx/ql4_os.c @@ -8886,10 +8886,54 @@ static void qla4xxx_prevent_other_port_reinit(struct scsi_qla_host *ha) } } +static void qla4xxx_destroy_ddb(struct scsi_qla_host *ha, + struct ddb_entry *ddb_entry) +{ + struct dev_db_entry *fw_ddb_entry = NULL; + dma_addr_t fw_ddb_entry_dma; + unsigned long wtime; + uint32_t ddb_state; + int options; + int status; + + options = LOGOUT_OPTION_CLOSE_SESSION; + if (qla4xxx_session_logout_ddb(ha, ddb_entry, options) == QLA_ERROR) { + ql4_printk(KERN_ERR, ha, %s: Logout failed\n, __func__); + goto clear_ddb; + } + + fw_ddb_entry = dma_alloc_coherent(ha-pdev-dev, sizeof(*fw_ddb_entry), + fw_ddb_entry_dma, GFP_KERNEL); + if (!fw_ddb_entry) { + ql4_printk(KERN_ERR, ha, + %s: Unable to allocate dma buffer\n, __func__); + goto clear_ddb; + } + + wtime = jiffies + (HZ * LOGOUT_TOV); + do { + status = qla4xxx_get_fwddb_entry(ha, ddb_entry-fw_ddb_index, +fw_ddb_entry, fw_ddb_entry_dma, +NULL, NULL, ddb_state, NULL, +NULL, NULL); + if (status == QLA_ERROR) + goto clear_ddb; + + if ((ddb_state == DDB_DS_NO_CONNECTION_ACTIVE) || + (ddb_state == DDB_DS_SESSION_FAILED)) + goto clear_ddb; + + schedule_timeout_uninterruptible(HZ); + } while ((time_after(wtime, jiffies))); + +clear_ddb: + qla4xxx_clear_ddb_entry(ha, ddb_entry-fw_ddb_index); + return; +} + static void qla4xxx_destroy_fw_ddb_session(struct scsi_qla_host *ha) { struct ddb_entry *ddb_entry; - int options; int idx; for (idx = 0; idx MAX_DDB_ENTRIES; idx++) { @@ -8898,13 +8942,7 @@ static void qla4xxx_destroy_fw_ddb_session(struct scsi_qla_host *ha) if ((ddb_entry != NULL) (ddb_entry-ddb_type == FLASH_DDB)) { - options = LOGOUT_OPTION_CLOSE_SESSION; - if (qla4xxx_session_logout_ddb(ha, ddb_entry, options) - == QLA_ERROR) - ql4_printk(KERN_ERR, ha, %s: Logout failed\n, - __func__); - - qla4xxx_clear_ddb_entry(ha, ddb_entry-fw_ddb_index); + qla4xxx_destroy_ddb(ha, ddb_entry); /* * we have decremented the reference count of the driver * when we setup the session to have the driver unload -- 1.8.2.GIT -- 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
[PATCH 17/24] qla4xxx: Remove unused code from qla4xxx_set_ifcb()
From: Vikas Chaudhary vikas.chaudh...@qlogic.com Removing unused code as FW does not need any value in mbox-5. Signed-off-by: Vikas Chaudhary vikas.chaudh...@qlogic.com --- drivers/scsi/qla4xxx/ql4_mbx.c | 1 - 1 file changed, 1 deletion(-) diff --git a/drivers/scsi/qla4xxx/ql4_mbx.c b/drivers/scsi/qla4xxx/ql4_mbx.c index cc27d7f..782a94586 100644 --- a/drivers/scsi/qla4xxx/ql4_mbx.c +++ b/drivers/scsi/qla4xxx/ql4_mbx.c @@ -383,7 +383,6 @@ qla4xxx_set_ifcb(struct scsi_qla_host *ha, uint32_t *mbox_cmd, mbox_cmd[2] = LSDW(init_fw_cb_dma); mbox_cmd[3] = MSDW(init_fw_cb_dma); mbox_cmd[4] = sizeof(struct addr_ctrl_blk); - mbox_cmd[5] = (IFCB_VER_MAX 8) | IFCB_VER_MIN; if (qla4xxx_mailbox_command(ha, 6, 6, mbox_cmd, mbox_sts) != QLA_SUCCESS) { -- 1.8.2.GIT -- 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
[PATCH 04/24] qla4xxx: Use IDC_CTRL bit1 directly instead of AF_83XX_NO_FWDUMP flag.
From: Vikas Chaudhary vikas.chaudh...@qlogic.com Removed AF_83XX_NO_FWDUMP flag and directly checking IDC_CTRL bit1 while taking minidump, to check for graceful reset. Signed-off-by: Vikas Chaudhary vikas.chaudh...@qlogic.com --- drivers/scsi/qla4xxx/ql4_83xx.c | 16 ++-- drivers/scsi/qla4xxx/ql4_def.h | 1 - drivers/scsi/qla4xxx/ql4_nx.c | 15 +-- 3 files changed, 15 insertions(+), 17 deletions(-) diff --git a/drivers/scsi/qla4xxx/ql4_83xx.c b/drivers/scsi/qla4xxx/ql4_83xx.c index 43c1688..e80e82f 100644 --- a/drivers/scsi/qla4xxx/ql4_83xx.c +++ b/drivers/scsi/qla4xxx/ql4_83xx.c @@ -1304,12 +1304,24 @@ static void qla4_83xx_process_init_seq(struct scsi_qla_host *ha) static int qla4_83xx_restart(struct scsi_qla_host *ha) { int ret_val = QLA_SUCCESS; + uint32_t idc_ctrl; qla4_83xx_process_stop_seq(ha); - /* Collect minidump*/ - if (!test_and_clear_bit(AF_83XX_NO_FW_DUMP, ha-flags)) + /* +* Collect minidump. +* If IDC_CTRL BIT1 is set, clear it on going to INIT state and +* don't collect minidump +*/ + idc_ctrl = qla4_83xx_rd_reg(ha, QLA83XX_IDC_DRV_CTRL); + if (idc_ctrl GRACEFUL_RESET_BIT1) { + qla4_83xx_wr_reg(ha, QLA83XX_IDC_DRV_CTRL, +(idc_ctrl ~GRACEFUL_RESET_BIT1)); + ql4_printk(KERN_INFO, ha, %s: Graceful RESET: Not collecting minidump\n, + __func__); + } else { qla4_8xxx_get_minidump(ha); + } qla4_83xx_process_init_seq(ha); diff --git a/drivers/scsi/qla4xxx/ql4_def.h b/drivers/scsi/qla4xxx/ql4_def.h index e9df4ad..5236337 100644 --- a/drivers/scsi/qla4xxx/ql4_def.h +++ b/drivers/scsi/qla4xxx/ql4_def.h @@ -580,7 +580,6 @@ struct scsi_qla_host { #define AF_82XX_FW_DUMPED 24 /* 0x0100 */ #define AF_8XXX_RST_OWNER 25 /* 0x0200 */ #define AF_82XX_DUMP_READING 26 /* 0x0400 */ -#define AF_83XX_NO_FW_DUMP 27 /* 0x0800 */ #define AF_83XX_IOCB_INTR_ON 28 /* 0x1000 */ #define AF_83XX_MBOX_INTR_ON 29 /* 0x2000 */ diff --git a/drivers/scsi/qla4xxx/ql4_nx.c b/drivers/scsi/qla4xxx/ql4_nx.c index bbe8361..0ec07ec 100644 --- a/drivers/scsi/qla4xxx/ql4_nx.c +++ b/drivers/scsi/qla4xxx/ql4_nx.c @@ -2821,7 +2821,7 @@ int qla4_8xxx_device_bootstrap(struct scsi_qla_host *ha) { int rval = QLA_ERROR; int i, timeout; - uint32_t old_count, count, idc_ctrl; + uint32_t old_count, count; int need_reset = 0, peg_stuck = 1; need_reset = ha-isp_ops-need_reset(ha); @@ -2864,19 +2864,6 @@ dev_initialize: qla4_8xxx_wr_direct(ha, QLA8XXX_CRB_DEV_STATE, QLA8XXX_DEV_INITIALIZING); - /* -* For ISP8324 and ISP8042, if IDC_CTRL GRACEFUL_RESET_BIT1 is set, -* reset it after device goes to INIT state. -*/ - if (is_qla8032(ha) || is_qla8042(ha)) { - idc_ctrl = qla4_83xx_rd_reg(ha, QLA83XX_IDC_DRV_CTRL); - if (idc_ctrl GRACEFUL_RESET_BIT1) { - qla4_83xx_wr_reg(ha, QLA83XX_IDC_DRV_CTRL, -(idc_ctrl ~GRACEFUL_RESET_BIT1)); - set_bit(AF_83XX_NO_FW_DUMP, ha-flags); - } - } - ha-isp_ops-idc_unlock(ha); if (is_qla8022(ha)) -- 1.8.2.GIT -- 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
[PATCH 08/24] qla4xxx: Fixed AER reset sequence for ISP83xx/ISP84xx
From: Tej Parkash tej.park...@qlogic.com Signed-off-by: Vikas Chaudhary vikas.chaudh...@qlogic.com --- drivers/scsi/qla4xxx/ql4_def.h | 3 ++- drivers/scsi/qla4xxx/ql4_os.c | 46 +- 2 files changed, 29 insertions(+), 20 deletions(-) diff --git a/drivers/scsi/qla4xxx/ql4_def.h b/drivers/scsi/qla4xxx/ql4_def.h index 5236337..4e11133 100644 --- a/drivers/scsi/qla4xxx/ql4_def.h +++ b/drivers/scsi/qla4xxx/ql4_def.h @@ -909,7 +909,8 @@ static inline int is_qla80XX(struct scsi_qla_host *ha) static inline int is_aer_supported(struct scsi_qla_host *ha) { return ((ha-pdev-device == PCI_DEVICE_ID_QLOGIC_ISP8022) || - (ha-pdev-device == PCI_DEVICE_ID_QLOGIC_ISP8324)); + (ha-pdev-device == PCI_DEVICE_ID_QLOGIC_ISP8324) || + (ha-pdev-device == PCI_DEVICE_ID_QLOGIC_ISP8042)); } static inline int adapter_up(struct scsi_qla_host *ha) diff --git a/drivers/scsi/qla4xxx/ql4_os.c b/drivers/scsi/qla4xxx/ql4_os.c index e6fa19c..a78edc3 100644 --- a/drivers/scsi/qla4xxx/ql4_os.c +++ b/drivers/scsi/qla4xxx/ql4_os.c @@ -9579,28 +9579,36 @@ static uint32_t qla4_8xxx_error_recovery(struct scsi_qla_host *ha) } fn = PCI_FUNC(ha-pdev-devfn); - while (fn 0) { - fn--; - ql4_printk(KERN_INFO, ha, scsi%ld: %s: Finding PCI device at - func %x\n, ha-host_no, __func__, fn); - /* Get the pci device given the domain, bus, -* slot/function number */ - other_pdev = - pci_get_domain_bus_and_slot(pci_domain_nr(ha-pdev-bus), - ha-pdev-bus-number, PCI_DEVFN(PCI_SLOT(ha-pdev-devfn), - fn)); - - if (!other_pdev) - continue; + if (is_qla8022(ha)) { + while (fn 0) { + fn--; + ql4_printk(KERN_INFO, ha, scsi%ld: %s: Finding PCI device at func %x\n, + ha-host_no, __func__, fn); + /* Get the pci device given the domain, bus, +* slot/function number */ + other_pdev = pci_get_domain_bus_and_slot( + pci_domain_nr(ha-pdev-bus), + ha-pdev-bus-number, + PCI_DEVFN(PCI_SLOT(ha-pdev-devfn), + fn)); + + if (!other_pdev) + continue; - if (atomic_read(other_pdev-enable_cnt)) { - ql4_printk(KERN_INFO, ha, scsi%ld: %s: Found PCI - func in enabled state%x\n, ha-host_no, - __func__, fn); + if (atomic_read(other_pdev-enable_cnt)) { + ql4_printk(KERN_INFO, ha, scsi%ld: %s: Found PCI func in enabled state%x\n, + ha-host_no, __func__, fn); + pci_dev_put(other_pdev); + break; + } pci_dev_put(other_pdev); - break; } - pci_dev_put(other_pdev); + } else { + /* this case is meant for ISP83xx/ISP84xx only */ + if (qla4_83xx_can_perform_reset(ha)) { + /* reset fn as iSCSI is going to perform the reset */ + fn = 0; + } } /* The first function on the card, the reset owner will -- 1.8.2.GIT -- 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
[PATCH 22/24] qla4xxx: Handle IPv6 AEN notifications
From: Nilesh Javali nilesh.jav...@qlogic.com Signed-off-by: Nilesh Javali nilesh.jav...@qlogic.com Signed-off-by: Vikas Chaudhary vikas.chaudh...@qlogic.com --- drivers/scsi/qla4xxx/ql4_fw.h | 6 +++--- drivers/scsi/qla4xxx/ql4_isr.c | 30 ++ 2 files changed, 33 insertions(+), 3 deletions(-) diff --git a/drivers/scsi/qla4xxx/ql4_fw.h b/drivers/scsi/qla4xxx/ql4_fw.h index a94593a..209853c 100644 --- a/drivers/scsi/qla4xxx/ql4_fw.h +++ b/drivers/scsi/qla4xxx/ql4_fw.h @@ -506,9 +506,9 @@ struct qla_flt_region { #define MBOX_ASTS_RESPONSE_QUEUE_FULL 0x8028 #define MBOX_ASTS_IP_ADDR_STATE_CHANGED0x8029 #define MBOX_ASTS_IPV6_DEFAULT_ROUTER_CHANGED 0x802A -#define MBOX_ASTS_IPV6_PREFIX_EXPIRED 0x802B -#define MBOX_ASTS_IPV6_ND_PREFIX_IGNORED 0x802C -#define MBOX_ASTS_IPV6_LCL_PREFIX_IGNORED 0x802D +#define MBOX_ASTS_IPV6_LINK_MTU_CHANGE 0x802B +#define MBOX_ASTS_IPV6_AUTO_PREFIX_IGNORED 0x802C +#define MBOX_ASTS_IPV6_ND_LOCAL_PREFIX_IGNORED 0x802D #define MBOX_ASTS_ICMPV6_ERROR_MSG_RCVD0x802E #define MBOX_ASTS_INITIALIZATION_FAILED0x8031 #define MBOX_ASTS_SYSTEM_WARNING_EVENT 0x8036 diff --git a/drivers/scsi/qla4xxx/ql4_isr.c b/drivers/scsi/qla4xxx/ql4_isr.c index df3fd9b..bb34ef8 100644 --- a/drivers/scsi/qla4xxx/ql4_isr.c +++ b/drivers/scsi/qla4xxx/ql4_isr.c @@ -635,6 +635,18 @@ static void qla4xxx_update_ipaddr_state(struct scsi_qla_host *ha, } } +static void qla4xxx_default_router_changed(struct scsi_qla_host *ha, + uint32_t *mbox_sts) +{ + memcpy(ha-ip_config.ipv6_default_router_addr.s6_addr32[0], + mbox_sts[2], sizeof(uint32_t)); + memcpy(ha-ip_config.ipv6_default_router_addr.s6_addr32[1], + mbox_sts[3], sizeof(uint32_t)); + memcpy(ha-ip_config.ipv6_default_router_addr.s6_addr32[2], + mbox_sts[4], sizeof(uint32_t)); + memcpy(ha-ip_config.ipv6_default_router_addr.s6_addr32[3], + mbox_sts[5], sizeof(uint32_t)); +} /** * qla4xxx_isr_decode_mailbox - decodes mailbox status @@ -802,6 +814,23 @@ static void qla4xxx_isr_decode_mailbox(struct scsi_qla_host * ha, } break; + case MBOX_ASTS_IPV6_LINK_MTU_CHANGE: + case MBOX_ASTS_IPV6_AUTO_PREFIX_IGNORED: + case MBOX_ASTS_IPV6_ND_LOCAL_PREFIX_IGNORED: + /* No action */ + DEBUG2(ql4_printk(KERN_INFO, ha, scsi%ld: AEN %04x\n, + ha-host_no, mbox_status)); + break; + + case MBOX_ASTS_ICMPV6_ERROR_MSG_RCVD: + DEBUG2(ql4_printk(KERN_INFO, ha, + scsi%ld: AEN %04x, IPv6 ERROR, + mbox_sts[1]=%08x, mbox_sts[2]=%08x, mbox_sts[3}=%08x, mbox_sts[4]=%08x mbox_sts[5]=%08x\n, + ha-host_no, mbox_sts[0], mbox_sts[1], + mbox_sts[2], mbox_sts[3], mbox_sts[4], + mbox_sts[5])); + break; + case MBOX_ASTS_MAC_ADDRESS_CHANGED: case MBOX_ASTS_DNS: /* No action */ @@ -939,6 +968,7 @@ static void qla4xxx_isr_decode_mailbox(struct scsi_qla_host * ha, DEBUG2(ql4_printk(KERN_INFO, ha, scsi%ld: AEN %04x Received IPv6 default router changed notification\n, ha-host_no, mbox_sts[0])); + qla4xxx_default_router_changed(ha, mbox_sts); break; case MBOX_ASTS_IDC_TIME_EXTEND_NOTIFICATION: -- 1.8.2.GIT -- 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
[PATCH 05/24] qla4xxx: Improve loopback failure messages
From: Nilesh Javali nilesh.jav...@qlogic.com Signed-off-by: Vikas Chaudhary vikas.chaudh...@qlogic.com --- drivers/scsi/qla4xxx/ql4_bsg.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/scsi/qla4xxx/ql4_bsg.c b/drivers/scsi/qla4xxx/ql4_bsg.c index 04a0027..9f92cbf 100644 --- a/drivers/scsi/qla4xxx/ql4_bsg.c +++ b/drivers/scsi/qla4xxx/ql4_bsg.c @@ -517,7 +517,7 @@ static int qla4_83xx_wait_for_loopback_config_comp(struct scsi_qla_host *ha, (ha-idc_extend_tmo * HZ))) { ha-notify_idc_comp = 0; ha-notify_link_up_comp = 0; - ql4_printk(KERN_WARNING, ha, %s: IDC Complete notification not received, + ql4_printk(KERN_WARNING, ha, %s: Aborting: IDC Complete notification not received, __func__); status = QLA_ERROR; goto exit_wait; @@ -538,7 +538,7 @@ static int qla4_83xx_wait_for_loopback_config_comp(struct scsi_qla_host *ha, if (!wait_for_completion_timeout(ha-link_up_comp, (IDC_COMP_TOV * HZ))) { ha-notify_link_up_comp = 0; - ql4_printk(KERN_WARNING, ha, %s: LINK UP notification not received, + ql4_printk(KERN_WARNING, ha, %s: Aborting: LINK UP notification not received, __func__); status = QLA_ERROR; goto exit_wait; -- 1.8.2.GIT -- 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
[PATCH 06/24] qla4xxx: Rename ACB_STATE macros with IP_ADDRSTATE macros
From: Nilesh Javali nilesh.jav...@qlogic.com Signed-off-by: Nilesh Javali nilesh.jav...@qlogic.com Signed-off-by: Vikas Chaudhary vikas.chaudh...@qlogic.com --- drivers/scsi/qla4xxx/ql4_fw.h | 24 drivers/scsi/qla4xxx/ql4_isr.c | 14 +++--- 2 files changed, 15 insertions(+), 23 deletions(-) diff --git a/drivers/scsi/qla4xxx/ql4_fw.h b/drivers/scsi/qla4xxx/ql4_fw.h index 8d4092b..e3242df 100644 --- a/drivers/scsi/qla4xxx/ql4_fw.h +++ b/drivers/scsi/qla4xxx/ql4_fw.h @@ -528,14 +528,14 @@ struct qla_flt_region { #define ACB_CONFIG_DISABLE 0x00 #define ACB_CONFIG_SET 0x01 -/* ACB State Defines */ -#define ACB_STATE_UNCONFIGURED 0x00 -#define ACB_STATE_INVALID 0x01 -#define ACB_STATE_ACQUIRING0x02 -#define ACB_STATE_TENTATIVE0x03 -#define ACB_STATE_DEPRICATED 0x04 -#define ACB_STATE_VALID0x05 -#define ACB_STATE_DISABLING0x06 +/* ACB/IP Address State Defines */ +#define IP_ADDRSTATE_UNCONFIGURED 0 +#define IP_ADDRSTATE_INVALID 1 +#define IP_ADDRSTATE_ACQUIRING 2 +#define IP_ADDRSTATE_TENTATIVE 3 +#define IP_ADDRSTATE_DEPRICATED4 +#define IP_ADDRSTATE_PREFERRED 5 +#define IP_ADDRSTATE_DISABLING 6 /* FLASH offsets */ #define FLASH_SEGMENT_IFCB 0x0400 @@ -698,14 +698,6 @@ struct addr_ctrl_blk { uint8_t ipv6_lnk_lcl_addr_state;/* 222 */ uint8_t ipv6_addr0_state; /* 223 */ uint8_t ipv6_addr1_state; /* 224 */ -#define IP_ADDRSTATE_UNCONFIGURED 0 -#define IP_ADDRSTATE_INVALID 1 -#define IP_ADDRSTATE_ACQUIRING 2 -#define IP_ADDRSTATE_TENTATIVE 3 -#define IP_ADDRSTATE_DEPRICATED4 -#define IP_ADDRSTATE_PREFERRED 5 -#define IP_ADDRSTATE_DISABLING 6 - uint8_t ipv6_dflt_rtr_state;/* 225 */ #define IPV6_RTRSTATE_UNKNOWN 0 #define IPV6_RTRSTATE_MANUAL1 diff --git a/drivers/scsi/qla4xxx/ql4_isr.c b/drivers/scsi/qla4xxx/ql4_isr.c index a3c8bc7..e56c6b4 100644 --- a/drivers/scsi/qla4xxx/ql4_isr.c +++ b/drivers/scsi/qla4xxx/ql4_isr.c @@ -781,21 +781,21 @@ static void qla4xxx_isr_decode_mailbox(struct scsi_qla_host * ha, mbox_sts[3]); /* mbox_sts[2] = Old ACB state * mbox_sts[3] = new ACB state */ - if ((mbox_sts[3] == ACB_STATE_VALID) - ((mbox_sts[2] == ACB_STATE_TENTATIVE) || - (mbox_sts[2] == ACB_STATE_ACQUIRING))) { + if ((mbox_sts[3] == IP_ADDRSTATE_PREFERRED) + ((mbox_sts[2] == IP_ADDRSTATE_TENTATIVE) || +(mbox_sts[2] == IP_ADDRSTATE_ACQUIRING))) { set_bit(DPC_GET_DHCP_IP_ADDR, ha-dpc_flags); - } else if ((mbox_sts[3] == ACB_STATE_ACQUIRING) - (mbox_sts[2] == ACB_STATE_VALID)) { + } else if ((mbox_sts[3] == IP_ADDRSTATE_ACQUIRING) + (mbox_sts[2] == IP_ADDRSTATE_PREFERRED)) { if (is_qla80XX(ha)) set_bit(DPC_RESET_HA_FW_CONTEXT, ha-dpc_flags); else set_bit(DPC_RESET_HA, ha-dpc_flags); - } else if (mbox_sts[3] == ACB_STATE_DISABLING) { + } else if (mbox_sts[3] == IP_ADDRSTATE_DISABLING) { ql4_printk(KERN_INFO, ha, scsi%ld: %s: ACB in disabling state\n, ha-host_no, __func__); - } else if ((mbox_sts[3] == ACB_STATE_UNCONFIGURED)) { + } else if (mbox_sts[3] == IP_ADDRSTATE_UNCONFIGURED) { complete(ha-disable_acb_comp); ql4_printk(KERN_INFO, ha, scsi%ld: %s: ACB state unconfigured\n, ha-host_no, __func__); -- 1.8.2.GIT -- 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
[PATCH 0/24] qla4xxx: 5.04.00-k4: Updates for scsi misc branch
From: Vikas Chaudhary vikas.chaudh...@qlogic.com James, Please apply the following patches to the scsi tree at your earliest convenience. These patches are on top of other qla4xxx patch posted on list here: http://marc.info/?l=linux-scsim=138511809612830w=2 Nilesh Javali (5): qla4xxx: ISP8xxx: Correct retry of adapter initialization qla4xxx: Improve loopback failure messages qla4xxx: Rename ACB_STATE macros with IP_ADDRSTATE macros qla4xxx: Clear DDB index map upon connection close failure qla4xxx: Handle IPv6 AEN notifications Tej Parkash (4): qla4xxx: Fixed AER reset sequence for ISP83xx/ISP84xx qla4xxx: Fix processing response queue during probe qla4xxx: Fix pending IO completion in reset path before initiating chip reset qla4xxx: Driver not able to collect minidump for ISP84xx Vikas Chaudhary (15): qla4xxx: Print WARN_ONCE() if iSCSI function presence bit removed qla4xxx: Fix comments in code qla4xxx: Use IDC_CTRL bit1 directly instead of AF_83XX_NO_FWDUMP flag. qla4xxx: Correctly handle msleep_interruptible qla4xxx: Return correct error status from func qla4xxx_request_irqs() qla4xxx: Fix failure of IDC Time Extend mailbox command qla4xxx: Reduce rom-lock contention during reset recovery. qla4xxx: Fix failure of mbox 0x31 qla4xxx: Remove unused code from qla4xxx_set_ifcb() qla4xxx: Updated print for device login, logout path qla4xxx: Update print statements in qla4xxx_mailbox_command() qla4xxx: Update print statements in func qla4xxx_eh_abort() qla4xxx: Update print statements in func qla4xxx_do_dpc() qla4xxx: Fix sparse warnings qla4xxx: Update driver version to 5.04.00-k4 Thanks, Vikas. -- 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
[PATCH 02/24] qla4xxx: Print WARN_ONCE() if iSCSI function presence bit removed
From: Vikas Chaudhary vikas.chaudh...@qlogic.com Signed-off-by: Vikas Chaudhary vikas.chaudh...@qlogic.com --- drivers/scsi/qla4xxx/ql4_83xx.c | 20 drivers/scsi/qla4xxx/ql4_glbl.h | 1 + drivers/scsi/qla4xxx/ql4_os.c | 5 + 3 files changed, 26 insertions(+) diff --git a/drivers/scsi/qla4xxx/ql4_83xx.c b/drivers/scsi/qla4xxx/ql4_83xx.c index 8196c2f..43c1688 100644 --- a/drivers/scsi/qla4xxx/ql4_83xx.c +++ b/drivers/scsi/qla4xxx/ql4_83xx.c @@ -1664,3 +1664,23 @@ void qla4_83xx_disable_pause(struct scsi_qla_host *ha) __qla4_83xx_disable_pause(ha); ha-isp_ops-idc_unlock(ha); } + +/** + * qla4_83xx_is_detached - Check if we are marked invisible. + * @ha: Pointer to host adapter structure. + **/ +int qla4_83xx_is_detached(struct scsi_qla_host *ha) +{ + uint32_t drv_active; + + drv_active = qla4_8xxx_rd_direct(ha, QLA8XXX_CRB_DRV_ACTIVE); + + if (test_bit(AF_INIT_DONE, ha-flags) + !(drv_active (1 ha-func_num))) { + DEBUG2(ql4_printk(KERN_INFO, ha, %s: drv_active = 0x%X\n, + __func__, drv_active)); + return QLA_SUCCESS; + } + + return QLA_ERROR; +} diff --git a/drivers/scsi/qla4xxx/ql4_glbl.h b/drivers/scsi/qla4xxx/ql4_glbl.h index 6d72e1d..b1a19cd 100644 --- a/drivers/scsi/qla4xxx/ql4_glbl.h +++ b/drivers/scsi/qla4xxx/ql4_glbl.h @@ -280,6 +280,7 @@ uint8_t qla4xxx_set_ipaddr_state(uint8_t fw_ipaddr_state); int qla4_83xx_get_port_config(struct scsi_qla_host *ha, uint32_t *config); int qla4_83xx_set_port_config(struct scsi_qla_host *ha, uint32_t *config); int qla4_8xxx_check_init_adapter_retry(struct scsi_qla_host *ha); +int qla4_83xx_is_detached(struct scsi_qla_host *ha); extern int ql4xextended_error_logging; extern int ql4xdontresethba; diff --git a/drivers/scsi/qla4xxx/ql4_os.c b/drivers/scsi/qla4xxx/ql4_os.c index 9803c9e..e6fa19c 100644 --- a/drivers/scsi/qla4xxx/ql4_os.c +++ b/drivers/scsi/qla4xxx/ql4_os.c @@ -4372,6 +4372,11 @@ void qla4_8xxx_watchdog(struct scsi_qla_host *ha) uint32_t dev_state; uint32_t idc_ctrl; + if (is_qla8032(ha) + (qla4_83xx_is_detached(ha) == QLA_SUCCESS)) + WARN_ONCE(1, %s: iSCSI function %d marked invisible\n, + __func__, ha-func_num); + /* don't poll if reset is going on */ if (!(test_bit(DPC_RESET_ACTIVE, ha-dpc_flags) || test_bit(DPC_RESET_HA, ha-dpc_flags) || -- 1.8.2.GIT -- 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
[PATCH 10/24] qla4xxx: Clear DDB index map upon connection close failure
From: Nilesh Javali nilesh.jav...@qlogic.com Issue: qla4xxx Unable to clear DDB indices when logout fails due to failure of connection close mbox command. Root cause: If login to session fail, iscsiadm make call to destroy_session. qla4xxx driver does not free ddb index map before free_ddb() Fix: Clear DDB Index map before free_ddb in destroy_session in case of connection close mailbox command failure with 4005h. Signed-off-by: Nilesh Javali nilesh.jav...@qlogic.com Signed-off-by: Vikas Chaudhary vikas.chaudh...@qlogic.com --- drivers/scsi/qla4xxx/ql4_def.h | 2 ++ drivers/scsi/qla4xxx/ql4_fw.h | 1 + drivers/scsi/qla4xxx/ql4_mbx.c | 4 drivers/scsi/qla4xxx/ql4_os.c | 4 +++- 4 files changed, 10 insertions(+), 1 deletion(-) diff --git a/drivers/scsi/qla4xxx/ql4_def.h b/drivers/scsi/qla4xxx/ql4_def.h index 4e11133..33eae2e 100644 --- a/drivers/scsi/qla4xxx/ql4_def.h +++ b/drivers/scsi/qla4xxx/ql4_def.h @@ -297,6 +297,8 @@ struct ddb_entry { /* Driver Re-login */ unsigned long flags; /* DDB Flags */ +#define DDB_CONN_CLOSE_FAILURE 0 /* 0x0001 */ + uint16_t default_relogin_timeout; /* Max time to wait for * relogin to complete */ atomic_t retry_relogin_timer; /* Min Time between relogins diff --git a/drivers/scsi/qla4xxx/ql4_fw.h b/drivers/scsi/qla4xxx/ql4_fw.h index e3242df..a94593a 100644 --- a/drivers/scsi/qla4xxx/ql4_fw.h +++ b/drivers/scsi/qla4xxx/ql4_fw.h @@ -390,6 +390,7 @@ struct qla_flt_region { #define MBOX_CMD_CLEAR_DATABASE_ENTRY 0x0031 #define MBOX_CMD_CONN_OPEN 0x0074 #define MBOX_CMD_CONN_CLOSE_SESS_LOGOUT0x0056 +#define DDB_NOT_LOGGED_IN 0x09 #define LOGOUT_OPTION_CLOSE_SESSION0x0002 #define LOGOUT_OPTION_RELOGIN 0x0004 #define LOGOUT_OPTION_FREE_DDB 0x0008 diff --git a/drivers/scsi/qla4xxx/ql4_mbx.c b/drivers/scsi/qla4xxx/ql4_mbx.c index 7da0646..023f2dd 100644 --- a/drivers/scsi/qla4xxx/ql4_mbx.c +++ b/drivers/scsi/qla4xxx/ql4_mbx.c @@ -1002,6 +1002,10 @@ int qla4xxx_session_logout_ddb(struct scsi_qla_host *ha, %s: MBOX_CMD_CONN_CLOSE_SESS_LOGOUT failed sts %04X %04X, __func__, mbox_sts[0], mbox_sts[1])); + if ((mbox_sts[0] == MBOX_STS_COMMAND_ERROR) + (mbox_sts[1] == DDB_NOT_LOGGED_IN)) { + set_bit(DDB_CONN_CLOSE_FAILURE, ddb_entry-flags); + } } return status; diff --git a/drivers/scsi/qla4xxx/ql4_os.c b/drivers/scsi/qla4xxx/ql4_os.c index a78edc3..3fec116 100644 --- a/drivers/scsi/qla4xxx/ql4_os.c +++ b/drivers/scsi/qla4xxx/ql4_os.c @@ -3074,6 +3074,7 @@ qla4xxx_session_create(struct iscsi_endpoint *ep, ddb_entry-sess = cls_sess; ddb_entry-unblock_sess = qla4xxx_unblock_ddb; ddb_entry-ddb_change = qla4xxx_ddb_change; + clear_bit(DDB_CONN_CLOSE_FAILURE, ddb_entry-flags); cls_sess-recovery_tmo = ql4xsess_recovery_tmo; ha-fw_ddb_index_map[ddb_entry-fw_ddb_index] = ddb_entry; ha-tot_ddbs++; @@ -3123,7 +3124,8 @@ static void qla4xxx_session_destroy(struct iscsi_cls_session *cls_sess) destroy_session: qla4xxx_clear_ddb_entry(ha, ddb_entry-fw_ddb_index); - + if (test_and_clear_bit(DDB_CONN_CLOSE_FAILURE, ddb_entry-flags)) + clear_bit(ddb_entry-fw_ddb_index, ha-ddb_idx_map); spin_lock_irqsave(ha-hardware_lock, flags); qla4xxx_free_ddb(ha, ddb_entry); spin_unlock_irqrestore(ha-hardware_lock, flags); -- 1.8.2.GIT -- 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
[PATCH 20/24] qla4xxx: Update print statements in func qla4xxx_eh_abort()
From: Vikas Chaudhary vikas.chaudh...@qlogic.com Signed-off-by: Vikas Chaudhary vikas.chaudh...@qlogic.com --- drivers/scsi/qla4xxx/ql4_os.c | 7 --- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/drivers/scsi/qla4xxx/ql4_os.c b/drivers/scsi/qla4xxx/ql4_os.c index d0a8695..410fe02 100644 --- a/drivers/scsi/qla4xxx/ql4_os.c +++ b/drivers/scsi/qla4xxx/ql4_os.c @@ -9230,14 +9230,15 @@ static int qla4xxx_eh_abort(struct scsi_cmnd *cmd) int ret = SUCCESS; int wait = 0; - ql4_printk(KERN_INFO, ha, - scsi%ld:%d:%d: Abort command issued cmd=%p\n, - ha-host_no, id, lun, cmd); + ql4_printk(KERN_INFO, ha, scsi%ld:%d:%d: Abort command issued cmd=%p, cdb=0x%x\n, + ha-host_no, id, lun, cmd, cmd-cmnd[0]); spin_lock_irqsave(ha-hardware_lock, flags); srb = (struct srb *) CMD_SP(cmd); if (!srb) { spin_unlock_irqrestore(ha-hardware_lock, flags); + ql4_printk(KERN_INFO, ha, scsi%ld:%d:%d: Specified command has already completed.\n, + ha-host_no, id, lun); return SUCCESS; } kref_get(srb-srb_ref); -- 1.8.2.GIT -- 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
[PATCH 19/24] qla4xxx: Update print statements in qla4xxx_mailbox_command()
From: Vikas Chaudhary vikas.chaudh...@qlogic.com Signed-off-by: Vikas Chaudhary vikas.chaudh...@qlogic.com --- drivers/scsi/qla4xxx/ql4_mbx.c | 16 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/drivers/scsi/qla4xxx/ql4_mbx.c b/drivers/scsi/qla4xxx/ql4_mbx.c index 782a94586..1345c0e 100644 --- a/drivers/scsi/qla4xxx/ql4_mbx.c +++ b/drivers/scsi/qla4xxx/ql4_mbx.c @@ -212,9 +212,8 @@ int qla4xxx_mailbox_command(struct scsi_qla_host *ha, uint8_t inCount, ha-host_no, __func__)); goto mbox_exit; } - DEBUG2(printk(scsi%ld: Mailbox Cmd 0x%08X timed out ..., - Scheduling Adapter Reset\n, ha-host_no, - mbx_cmd[0])); + ql4_printk(KERN_WARNING, ha, scsi%ld: Mailbox Cmd 0x%08X timed out, Scheduling Adapter Reset\n, + ha-host_no, mbx_cmd[0]); ha-mailbox_timeout_count++; mbx_sts[0] = (-1); set_bit(DPC_RESET_HA, ha-dpc_flags); @@ -251,15 +250,16 @@ int qla4xxx_mailbox_command(struct scsi_qla_host *ha, uint8_t inCount, break; case MBOX_STS_BUSY: - DEBUG2( printk(scsi%ld: %s: Cmd = %08X, ISP BUSY\n, - ha-host_no, __func__, mbx_cmd[0])); + ql4_printk(KERN_WARNING, ha, scsi%ld: %s: Cmd = %08X, ISP BUSY\n, + ha-host_no, __func__, mbx_cmd[0]); ha-mailbox_timeout_count++; break; default: - DEBUG2(printk(scsi%ld: %s: FAILED, cmd = %08X, - sts = %08X \n, ha-host_no, __func__, - mbx_cmd[0], mbx_sts[0])); + ql4_printk(KERN_WARNING, ha, scsi%ld: %s: FAILED, MBOX CMD = %08X, MBOX STS = %08X %08X %08X %08X %08X %08X %08X %08X\n, + ha-host_no, __func__, mbx_cmd[0], mbx_sts[0], + mbx_sts[1], mbx_sts[2], mbx_sts[3], mbx_sts[4], + mbx_sts[5], mbx_sts[6], mbx_sts[7]); break; } spin_unlock_irqrestore(ha-hardware_lock, flags); -- 1.8.2.GIT -- 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
[PATCH 12/24] qla4xxx: Fix processing response queue during probe
From: Tej Parkash tej.park...@qlogic.com Issue: While booting with kdump kernel, driver receive IOCB interrupts for which it is not ready which results in processing them before init_firmware during driver probe Fix: Two steps solution 1. Make driver ready to process the interrupt before interupts handlers is registered. 2. Stop driver processing iocb interrupts if not generated as per firmware protocol i.e R2H bit set Signed-off-by: Tej Parkash tej.park...@qlogic.com Signed-off-by: Vikas Chaudhary vikas.chaudh...@qlogic.com --- drivers/scsi/qla4xxx/ql4_isr.c | 15 --- drivers/scsi/qla4xxx/ql4_mbx.c | 3 --- drivers/scsi/qla4xxx/ql4_nx.c | 4 3 files changed, 16 insertions(+), 6 deletions(-) diff --git a/drivers/scsi/qla4xxx/ql4_isr.c b/drivers/scsi/qla4xxx/ql4_isr.c index 49032f6..df3fd9b 100644 --- a/drivers/scsi/qla4xxx/ql4_isr.c +++ b/drivers/scsi/qla4xxx/ql4_isr.c @@ -1022,7 +1022,8 @@ void qla4_82xx_interrupt_service_routine(struct scsi_qla_host *ha, uint32_t intr_status) { /* Process response queue interrupt. */ - if (intr_status HSRX_RISC_IOCB_INT) + if ((intr_status HSRX_RISC_IOCB_INT) + test_bit(AF_INIT_DONE, ha-flags)) qla4xxx_process_response_queue(ha); /* Process mailbox/asynch event interrupt.*/ @@ -1399,6 +1400,7 @@ qla4_8xxx_msix_rsp_q(int irq, void *dev_id) { struct scsi_qla_host *ha = dev_id; unsigned long flags; + int intr_status; uint32_t ival = 0; spin_lock_irqsave(ha-hardware_lock, flags); @@ -1412,8 +1414,15 @@ qla4_8xxx_msix_rsp_q(int irq, void *dev_id) qla4xxx_process_response_queue(ha); writel(0, ha-qla4_83xx_reg-iocb_int_mask); } else { - qla4xxx_process_response_queue(ha); - writel(0, ha-qla4_82xx_reg-host_int); + intr_status = readl(ha-qla4_82xx_reg-host_status); + if (intr_status HSRX_RISC_IOCB_INT) { + qla4xxx_process_response_queue(ha); + writel(0, ha-qla4_82xx_reg-host_int); + } else { + ql4_printk(KERN_INFO, ha, %s: spurious iocb interrupt...\n, + __func__); + goto exit_msix_rsp_q; + } } ha-isr_count++; exit_msix_rsp_q: diff --git a/drivers/scsi/qla4xxx/ql4_mbx.c b/drivers/scsi/qla4xxx/ql4_mbx.c index 1d8f485..cc27d7f 100644 --- a/drivers/scsi/qla4xxx/ql4_mbx.c +++ b/drivers/scsi/qla4xxx/ql4_mbx.c @@ -648,9 +648,6 @@ int qla4xxx_initialize_fw_cb(struct scsi_qla_host * ha) goto exit_init_fw_cb; } - /* Initialize request and response queues. */ - qla4xxx_init_rings(ha); - /* Fill in the request and response queue information. */ init_fw_cb-rqq_consumer_idx = cpu_to_le16(ha-request_out); init_fw_cb-compq_producer_idx = cpu_to_le16(ha-response_in); diff --git a/drivers/scsi/qla4xxx/ql4_nx.c b/drivers/scsi/qla4xxx/ql4_nx.c index cbc68f9..bcf3e43 100644 --- a/drivers/scsi/qla4xxx/ql4_nx.c +++ b/drivers/scsi/qla4xxx/ql4_nx.c @@ -3190,6 +3190,10 @@ int qla4_8xxx_load_risc(struct scsi_qla_host *ha) retval = qla4_8xxx_device_state_handler(ha); + /* Initialize request and response queues. */ + if (retval == QLA_SUCCESS) + qla4xxx_init_rings(ha); + if (retval == QLA_SUCCESS !test_bit(AF_IRQ_ATTACHED, ha-flags)) retval = qla4xxx_request_irqs(ha); -- 1.8.2.GIT -- 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
[PATCH 21/24] qla4xxx: Update print statements in func qla4xxx_do_dpc()
From: Vikas Chaudhary vikas.chaudh...@qlogic.com Signed-off-by: Vikas Chaudhary vikas.chaudh...@qlogic.com --- drivers/scsi/qla4xxx/ql4_os.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/scsi/qla4xxx/ql4_os.c b/drivers/scsi/qla4xxx/ql4_os.c index 410fe02..e8a8a7d 100644 --- a/drivers/scsi/qla4xxx/ql4_os.c +++ b/drivers/scsi/qla4xxx/ql4_os.c @@ -5283,9 +5283,9 @@ static void qla4xxx_do_dpc(struct work_struct *work) container_of(work, struct scsi_qla_host, dpc_work); int status = QLA_ERROR; - DEBUG2(printk(scsi%ld: %s: DPC handler waking up. - flags = 0x%08lx, dpc_flags = 0x%08lx\n, - ha-host_no, __func__, ha-flags, ha-dpc_flags)) + DEBUG2(ql4_printk(KERN_INFO, ha, + scsi%ld: %s: DPC handler waking up. flags = 0x%08lx, dpc_flags = 0x%08lx\n, + ha-host_no, __func__, ha-flags, ha-dpc_flags)); /* Initialization not yet finished. Don't do anything yet. */ if (!test_bit(AF_INIT_DONE, ha-flags)) -- 1.8.2.GIT -- 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
[RFC 0/2] target refcounting infrastructure fixes for usb
This set should fix our target problems with USB by making the target visibility properly reference counted. Since it's a major change to the infrastructure, we'll incubate upstream first before backporting to stable. James --- James Bottomley (2): [SCSI] fix our current target reap infrastructure. [SCSI] dual scan thread bug fix drivers/scsi/scsi_scan.c | 102 - drivers/scsi/scsi_sysfs.c | 15 --- include/scsi/scsi_device.h | 3 +- 3 files changed, 74 insertions(+), 46 deletions(-) -- 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
[RFC 1/2] fix our current target reap infrastructure.
This patch eliminates the reap_ref and replaces it with a proper kref. On last put of this kref, the target is removed from visibility in sysfs. The final call to scsi_target_reap() for the device is done from __scsi_remove_device() and only if the device was made visible. This ensures that the target disappears as soon as the last device is gone rather than waiting until final release of the device (which is often too long). --- drivers/scsi/scsi_scan.c | 89 +++--- drivers/scsi/scsi_sysfs.c | 15 include/scsi/scsi_device.h | 3 +- 3 files changed, 63 insertions(+), 44 deletions(-) diff --git a/drivers/scsi/scsi_scan.c b/drivers/scsi/scsi_scan.c index 307a811..39e5c85 100644 --- a/drivers/scsi/scsi_scan.c +++ b/drivers/scsi/scsi_scan.c @@ -371,6 +371,31 @@ static struct scsi_target *__scsi_find_target(struct device *parent, } /** + * scsi_target_reap_ref_release - remove target from visibility + * @kref: the reap_ref in the target being released + * + * Called on last put of reap_ref, which is the indication that no device + * under this target is visible anymore, so render the target invisible in + * sysfs. Note: we have to be in user context here because the target reaps + * should be done in places where the scsi device visibility is being removed. + */ +static void scsi_target_reap_ref_release(struct kref *kref) +{ + struct scsi_target *starget + = container_of(kref, struct scsi_target, reap_ref); + + transport_remove_device(starget-dev); + device_del(starget-dev); + starget-state = STARGET_DEL; + scsi_target_destroy(starget); +} + +static void scsi_target_reap_ref_put(struct scsi_target *starget) +{ + kref_put(starget-reap_ref, scsi_target_reap_ref_release); +} + +/** * scsi_alloc_target - allocate a new or find an existing target * @parent:parent of the target (need not be a scsi host) * @channel: target channel number (zero if no channels) @@ -401,7 +426,7 @@ static struct scsi_target *scsi_alloc_target(struct device *parent, } dev = starget-dev; device_initialize(dev); - starget-reap_ref = 1; + kref_init(starget-reap_ref); dev-parent = get_device(parent); dev_set_name(dev, target%d:%d:%d, shost-host_no, channel, id); dev-bus = scsi_bus_type; @@ -441,29 +466,32 @@ static struct scsi_target *scsi_alloc_target(struct device *parent, return starget; found: - found_target-reap_ref++; + if (!kref_get_unless_zero(found_target-reap_ref)) + /* +* release routine already fired. Target is dead, but +* STARGET_DEL may not yet be set (set in the release +* routine), so set here as well, just in case +*/ + found_target-state = STARGET_DEL; spin_unlock_irqrestore(shost-host_lock, flags); if (found_target-state != STARGET_DEL) { put_device(dev); return found_target; } - /* Unfortunately, we found a dying target; need to -* wait until it's dead before we can get a new one */ + /* +* Unfortunately, we found a dying target; need to wait until it's +* dead before we can get a new one. There is an anomaly here. We +* *should* call scsi_target_reap() to balance the kref_get() of the +* reap_ref above. However, since the target is in state STARGET_DEL, +* it's already invisible and the reap_ref is irrelevant. If we call +* scsi_target_reap() we might spuriously do another device_del() on +* an already invisible target. +*/ put_device(found_target-dev); flush_scheduled_work(); goto retry; } -static void scsi_target_reap_usercontext(struct work_struct *work) -{ - struct scsi_target *starget = - container_of(work, struct scsi_target, ew.work); - - transport_remove_device(starget-dev); - device_del(starget-dev); - scsi_target_destroy(starget); -} - /** * scsi_target_reap - check to see if target is in use and destroy if not * @starget: target to be checked @@ -474,28 +502,11 @@ static void scsi_target_reap_usercontext(struct work_struct *work) */ void scsi_target_reap(struct scsi_target *starget) { - struct Scsi_Host *shost = dev_to_shost(starget-dev.parent); - unsigned long flags; - enum scsi_target_state state; - int empty = 0; - - spin_lock_irqsave(shost-host_lock, flags); - state = starget-state; - if (--starget-reap_ref == 0 list_empty(starget-devices)) { - empty = 1; - starget-state = STARGET_DEL; - } - spin_unlock_irqrestore(shost-host_lock, flags); - - if (!empty) - return; - - BUG_ON(state == STARGET_DEL); - if (state == STARGET_CREATED) + BUG_ON(starget-state == STARGET_DEL); +
[RFC 2/2] dual scan thread bug fix
In the highly unusual case where two threads are running concurrently through the scanning code scanning the same target, we run into the situation where one may allocate the target while the other is still using it. In this case, because the reap checks for STARGET_CREATED and kills the target without reference counting, the second thread will do the wrong thing on reap. Fix this by reference counting even creates and doing the STARGET_CREATED check in the final put. --- drivers/scsi/scsi_scan.c | 23 --- 1 file changed, 16 insertions(+), 7 deletions(-) diff --git a/drivers/scsi/scsi_scan.c b/drivers/scsi/scsi_scan.c index 39e5c85..2d7aafa 100644 --- a/drivers/scsi/scsi_scan.c +++ b/drivers/scsi/scsi_scan.c @@ -320,6 +320,7 @@ static void scsi_target_destroy(struct scsi_target *starget) struct Scsi_Host *shost = dev_to_shost(dev-parent); unsigned long flags; + starget-state = STARGET_DEL; transport_destroy_device(dev); spin_lock_irqsave(shost-host_lock, flags); if (shost-hostt-target_destroy) @@ -384,9 +385,15 @@ static void scsi_target_reap_ref_release(struct kref *kref) struct scsi_target *starget = container_of(kref, struct scsi_target, reap_ref); - transport_remove_device(starget-dev); - device_del(starget-dev); - starget-state = STARGET_DEL; + /* +* if we get here and the target is still in the CREATED state that +* means it was allocated but never made visible (because a scan +* turned up no LUNs), so don't call device_del() on it. +*/ + if (starget-state == STARGET_RUNNING) { + transport_remove_device(starget-dev); + device_del(starget-dev); + } scsi_target_destroy(starget); } @@ -502,11 +509,13 @@ static struct scsi_target *scsi_alloc_target(struct device *parent, */ void scsi_target_reap(struct scsi_target *starget) { + /* +* serious problem if this triggers: STARGET_DEL is only set in the +* kref release routine, so we're doing another final put on an +* already released kref +*/ BUG_ON(starget-state == STARGET_DEL); - if (starget-state == STARGET_CREATED) - scsi_target_destroy(starget); - else - scsi_target_reap_ref_put(starget); + scsi_target_reap_ref_put(starget); } /** -- 1.8.4.3 -- 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: [RFC 1/2] fix our current target reap infrastructure.
On Mon, 16 Dec 2013, James Bottomley wrote: This patch eliminates the reap_ref and replaces it with a proper kref. On last put of this kref, the target is removed from visibility in sysfs. The final call to scsi_target_reap() for the device is done from __scsi_remove_device() and only if the device was made visible. This ensures that the target disappears as soon as the last device is gone rather than waiting until final release of the device (which is often too long). Reviewed-by: Alan Stern st...@rowland.harvard.edu Two small suggested changes: @@ -441,29 +466,32 @@ static struct scsi_target *scsi_alloc_target(struct device *parent, return starget; found: - found_target-reap_ref++; + if (!kref_get_unless_zero(found_target-reap_ref)) + /* + * release routine already fired. Target is dead, but + * STARGET_DEL may not yet be set (set in the release + * routine), so set here as well, just in case + */ + found_target-state = STARGET_DEL; spin_unlock_irqrestore(shost-host_lock, flags); if (found_target-state != STARGET_DEL) { put_device(dev); return found_target; } - /* Unfortunately, we found a dying target; need to - * wait until it's dead before we can get a new one */ + /* + * Unfortunately, we found a dying target; need to wait until it's + * dead before we can get a new one. There is an anomaly here. We + * *should* call scsi_target_reap() to balance the kref_get() of the + * reap_ref above. However, since the target is in state STARGET_DEL, + * it's already invisible and the reap_ref is irrelevant. If we call + * scsi_target_reap() we might spuriously do another device_del() on + * an already invisible target. + */ put_device(found_target-dev); flush_scheduled_work(); goto retry; Since scsi_target_reap_usercontext() is now gone, scsi_target_destroy() doesn't rely on a work queue any more. Therefore something like msleep(1) would be more appropriate than flush_scheduled_work(). --- a/include/scsi/scsi_device.h +++ b/include/scsi/scsi_device.h @@ -257,7 +257,7 @@ struct scsi_target { struct list_headsiblings; struct list_headdevices; struct device dev; - unsigned intreap_ref; /* protected by the host lock */ + struct kref reap_ref; /* last put renders device invisible */ s/device/target/ Alan Stern -- 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 1/3] st.ko: fix enlarge_buffer
On 2.12.2013, at 21.00, Bodo Stroesser bstroes...@ts.fujitsu.com wrote: From: Bodo Stroesser bstroes...@ts.fujitsu.com Date: Mon, 2 Dec 2013 18:52:10 +0100 Subject: [PATCH 1/3] st.ko: fix enlarge_buffer This patch removes a bug in enlarge_buffer() that can make a read or write fail under special conditions. After changing TRY_DIRECT_IO to 0 and ST_MAX_SG to 32 in st_options.h, a program that writes a first block of 128k and than a second bigger block (e.g. 256k) fails. The second write returns errno EOVERFLOW, as enlarge_buffer() checks the sg list and detects that it already is full. As enlarge_buffer uses different page allocation orders depending on the size of the buffer needed, the check does not make sense. Yes, it is not useful any more. It may have been necessary at some time but I am now not sure about that either ;-) Cc: Kai Makisara kai.makis...@kolumbus.fi Acked-by: Kai Mäkisara kai.makis...@kolumbus.fi Thanks, Kai Signed-off-by: Bodo Stroesser bstroes...@ts.fujitsu.com --- --- a/drivers/scsi/st.c 2013-12-02 18:52:10.0 +0100 +++ b/drivers/scsi/st.c 2013-12-02 18:52:10.0 +0100 @@ -3719,7 +3719,7 @@ static struct st_buffer *new_tape_buffer static int enlarge_buffer(struct st_buffer * STbuffer, int new_size, int need_dma) { - int segs, nbr, max_segs, b_size, order, got; + int segs, max_segs, b_size, order, got; gfp_t priority; if (new_size = STbuffer-buffer_size) @@ -3729,9 +3729,6 @@ static int enlarge_buffer(struct st_buff normalize_buffer(STbuffer); /* Avoid extra segment */ max_segs = STbuffer-use_sg; - nbr = max_segs - STbuffer-frp_segs; - if (nbr = 0) - return 0; priority = GFP_KERNEL | __GFP_NOWARN; if (need_dma) -- 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 2/3] st.ko: remove unnecessary normalize_buffer
On 2.12.2013, at 21.00, Bodo Stroesser bstroes...@ts.fujitsu.com wrote: From: Bodo Stroesser bstroes...@ts.fujitsu.com Date: Mon, 2 Dec 2013 18:52:10 +0100 Subject: [PATCH 2/3] st.ko: remove unnecessary normalize_buffer This patch removes an unnecessary call to normalize_buffer() in enlarge_buffer() In st_open() always a buffer of one page is allocated. When the buffer needs to be enlarged later, it does not make sense to free this page unconditionally. The original reason for this was to make the function to allocate the minimum number of segments for maximum efficiency. In some cases it was essential not to waste one segment because that would have made the allocation fail. Now there is another reason to have this “optimization”. Reading the code you probably have noticed that nowadays all segments must have the same size. If the first segment is only one page, the first allocation may it may not be possible to allocate the buffer using single page segments. This leads to freeing the pages and trying again. This is not efficient. So, I think this fragment of code should not be removed. Thanks, Kai Cc: Kai Makisara kai.makis...@kolumbus.fi Signed-off-by: Bodo Stroesser bstroes...@ts.fujitsu.com --- --- a/drivers/scsi/st.c 2013-12-02 18:52:10.0 +0100 +++ b/drivers/scsi/st.c 2013-12-02 18:52:10.0 +0100 @@ -3725,9 +3725,6 @@ static int enlarge_buffer(struct st_buff if (new_size = STbuffer-buffer_size) return 1; - if (STbuffer-buffer_size = PAGE_SIZE) - normalize_buffer(STbuffer); /* Avoid extra segment */ - max_segs = STbuffer-use_sg; priority = GFP_KERNEL | __GFP_NOWARN; -- 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 3/3] st.ko: change enlarge_buffer result
On 2.12.2013, at 21.00, Bodo Stroesser bstroes...@ts.fujitsu.com wrote: From: Bodo Stroesser bstroes...@ts.fujitsu.com Date: Mon, 2 Dec 2013 18:52:10 +0100 Subject: [PATCH 3/3] st.ko: change enlarge_buffer result enlarge_buffer() just returns 1 or 0 if it could or could not allocate the requested buffer. In case of result 0, the callers always set the error to EOVERFLOW. I think, this is not a good errno for those cases, where enlarge_buffer() could not allocate the pages it needed. So I changed enlarge_buffer() to return a meaningful result (-ENOMEM or -EOVERFLOW in case of error, 0 in case of success) and the callers to use this result. ENOMEM is used for telling the user that, in variable block mode, the byte count in read() is smaller than the next block. This may not sound like proper use of this code but this is how the tape drivers have done. When ENOMEM is not used, the patch would be only cosmetic. Thanks, Kai -- 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 2/3] st.ko: remove unnecessary normalize_buffer
-Original Message- From: Kai Mäkisara (Kolumbus) [mailto:kai.makis...@kolumbus.fi] Sent: Monday, December 16, 2013 7:45 PM To: Strösser, Bodo Cc: linux-scsi@vger.kernel.org Subject: Re: [PATCH 2/3] st.ko: remove unnecessary normalize_buffer On 2.12.2013, at 21.00, Bodo Stroesser bstroes...@ts.fujitsu.com wrote: From: Bodo Stroesser bstroes...@ts.fujitsu.com Date: Mon, 2 Dec 2013 18:52:10 +0100 Subject: [PATCH 2/3] st.ko: remove unnecessary normalize_buffer This patch removes an unnecessary call to normalize_buffer() in enlarge_buffer() In st_open() always a buffer of one page is allocated. When the buffer needs to be enlarged later, it does not make sense to free this page unconditionally. The original reason for this was to make the function to allocate the minimum number of segments for maximum efficiency. In some cases it was essential not to waste one segment because that would have made the allocation fail. The method of enlarge_buffer now seems to have changed. It tries to find out the minimum size of a segment that can be used with the given sg list length. I assume, this method is used to be able to allocate very big buffers, while in case of normal buffer still small chunks of memory can be used, which under memory pressure are more likely to be granted. Now there is another reason to have this “optimization”. Reading the code you probably have noticed that nowadays all segments must have the same size. If the first segment is only one page, the first allocation may it may not be possible to allocate the buffer using single page segments. This leads to freeing the pages and trying again. This is not efficient. OTOH, if the size of the currently allocated segments is too small for the buffer that needs to be allocated now, enlarge_buffer will free all current segments and do a completely new allocation using bigger segments anyway. The lines, that the patch would remove, currently free one segment, if it is the smallest possible and the only one, even if the same segment size will be allocated again a few lines below. So I'd still call it a not optimal handling of a special case, that not needs to be handled specially. Thanks, Bodo So, I think this fragment of code should not be removed. Thanks, Kai Cc: Kai Makisara kai.makis...@kolumbus.fi Signed-off-by: Bodo Stroesser bstroes...@ts.fujitsu.com --- --- a/drivers/scsi/st.c 2013-12-02 18:52:10.0 +0100 +++ b/drivers/scsi/st.c 2013-12-02 18:52:10.0 +0100 @@ -3725,9 +3725,6 @@ static int enlarge_buffer(struct st_buff if (new_size = STbuffer-buffer_size) return 1; - if (STbuffer-buffer_size = PAGE_SIZE) - normalize_buffer(STbuffer); /* Avoid extra segment */ - max_segs = STbuffer-use_sg; priority = GFP_KERNEL | __GFP_NOWARN; -- 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 3/3] st.ko: change enlarge_buffer result
-Original Message- From: Kai Mäkisara (Kolumbus) [mailto:kai.makis...@kolumbus.fi] Sent: Monday, December 16, 2013 7:49 PM To: Strösser, Bodo Cc: linux-scsi@vger.kernel.org Subject: Re: [PATCH 3/3] st.ko: change enlarge_buffer result On 2.12.2013, at 21.00, Bodo Stroesser bstroes...@ts.fujitsu.com wrote: From: Bodo Stroesser bstroes...@ts.fujitsu.com Date: Mon, 2 Dec 2013 18:52:10 +0100 Subject: [PATCH 3/3] st.ko: change enlarge_buffer result enlarge_buffer() just returns 1 or 0 if it could or could not allocate the requested buffer. In case of result 0, the callers always set the error to EOVERFLOW. I think, this is not a good errno for those cases, where enlarge_buffer() could not allocate the pages it needed. So I changed enlarge_buffer() to return a meaningful result (-ENOMEM or -EOVERFLOW in case of error, 0 in case of success) and the callers to use this result. ENOMEM is used for telling the user that, in variable block mode, the byte count in read() is smaller than the next block. This may not sound like proper use of this code but this is how the tape drivers have done. Oops, sorry, I missed that. So I agree fully, that the patch does not make sense. Thank you, Bodo When ENOMEM is not used, the patch would be only cosmetic. Thanks, Kai -- 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] iscsi_target: race condition on shutdown
Hey Hannes, On Thu, 2013-12-12 at 09:05 +0100, Hannes Reinecke wrote: On 12/12/2013 08:54 AM, Nicholas A. Bellinger wrote: On Thu, 2013-12-12 at 08:18 +0100, Hannes Reinecke wrote: [ .. ] SNIP Mmmm, point taken.. I would love to be proven wrong, as I'm not keen on the 'schedule()' in there. But I fail to see another way out here, short of converting the entire kthread into a workqueue item ... Thinking about this a bit more, I think the pre-kthread API np_thead_state check to exit at the out: label in __iscsi_target_login_thread() is the culprit.. How about following to only exit when iscsit_del_np() - kthread_stop() has been called, and kthread_should_stop() is true..? --nab diff --git a/drivers/target/iscsi/iscsi_target.c b/drivers/target/iscsi/iscsi_target.c index 02182ab..0086719 100644 --- a/drivers/target/iscsi/iscsi_target.c +++ b/drivers/target/iscsi/iscsi_target.c @@ -465,6 +465,7 @@ int iscsit_del_np(struct iscsi_np *np) */ send_sig(SIGINT, np-np_thread, 1); kthread_stop(np-np_thread); + np-np_thread = NULL; } np-np_transport-iscsit_free_np(np); diff --git a/drivers/target/iscsi/iscsi_target_login.c b/drivers/target/iscsi/iscsi_target_login.c index 4eb93b2..e29279e 100644 --- a/drivers/target/iscsi/iscsi_target_login.c +++ b/drivers/target/iscsi/iscsi_target_login.c @@ -1403,11 +1403,6 @@ old_sess_out: out: stop = kthread_should_stop(); - if (!stop signal_pending(current)) { - spin_lock_bh(np-np_thread_lock); - stop = (np-np_thread_state == ISCSI_NP_THREAD_SHUTDOWN); - spin_unlock_bh(np-np_thread_lock); - } /* Wait for another socket.. */ if (!stop) return 1; @@ -1415,7 +1410,6 @@ exit: iscsi_stop_login_thread_timer(np); spin_lock_bh(np-np_thread_lock); np-np_thread_state = ISCSI_NP_THREAD_EXIT; - np-np_thread = NULL; spin_unlock_bh(np-np_thread_lock); return 0; Yes. Far better. I'll give it a spin. Any chance to confirm this patch..? I'd like to include this in the -rc5 PULL request over the next days. --nab -- 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 01/32] target: Remove unused ua_dev_list member in struct se_ua
On Fri, 2013-12-13 at 15:58 -0800, Andy Grover wrote: Initialized but not used. Signed-off-by: Andy Grover agro...@redhat.com --- drivers/target/target_core_ua.c |1 - include/target/target_core_base.h |1 - 2 files changed, 0 insertions(+), 2 deletions(-) Applied to for-next. --nab -- 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 02/32] target: Don't keep looping in report_luns if too big
On Fri, 2013-12-13 at 15:58 -0800, Andy Grover wrote: All further loops will still fail the conditional so just bail right away. Signed-off-by: Andy Grover agro...@redhat.com --- drivers/target/target_core_spc.c |2 +- 1 files changed, 1 insertions(+), 1 deletions(-) diff --git a/drivers/target/target_core_spc.c b/drivers/target/target_core_spc.c index 021c3f4..8f52974 100644 --- a/drivers/target/target_core_spc.c +++ b/drivers/target/target_core_spc.c @@ -1162,7 +1162,7 @@ sense_reason_t spc_emulate_report_luns(struct se_cmd *cmd) */ lun_count++; if ((offset + 8) cmd-data_length) - continue; + break; int_to_scsilun(deve-mapped_lun, (struct scsi_lun *)buf[offset]); offset += 8; NAK. REPORT_LUNS is supposed to return the total lun_count, even if there is no more buffer space to fill.. This is how the initiator knows it should send another REPORT_LUNS with a larger payload to receive the complete layout. --nab -- 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 03/32] target: Allocate more room for port default groups
On Fri, 2013-12-13 at 15:58 -0800, Andy Grover wrote: See target_stat_setup_port_default_groups, we need a 4 element array. Signed-off-by: Andy Grover agro...@redhat.com --- drivers/target/target_core_fabric_configfs.c |2 +- 1 files changed, 1 insertions(+), 1 deletions(-) diff --git a/drivers/target/target_core_fabric_configfs.c b/drivers/target/target_core_fabric_configfs.c index dae2ad6..fdadc4d 100644 --- a/drivers/target/target_core_fabric_configfs.c +++ b/drivers/target/target_core_fabric_configfs.c @@ -906,7 +906,7 @@ static struct config_group *target_fabric_make_lun( lun_cg-default_groups[1] = NULL; port_stat_grp = lun-port_stat_grps.stat_group; - port_stat_grp-default_groups = kzalloc(sizeof(struct config_group) * 3, + port_stat_grp-default_groups = kzalloc(sizeof(struct config_group) * 4, GFP_KERNEL); if (!port_stat_grp-default_groups) { pr_err(Unable to allocate port_stat_grp-default_groups\n); Applied to for-next. --nab -- 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 04/32] target: Fix sizeof in kmalloc for some default_groups arrays
On Fri, 2013-12-13 at 15:58 -0800, Andy Grover wrote: Allocating an array of pointers, not the objects themselves. These two sites now match all the other sites. Signed-off-by: Andy Grover agro...@redhat.com --- drivers/target/target_core_configfs.c|2 +- drivers/target/target_core_fabric_configfs.c |2 +- 2 files changed, 2 insertions(+), 2 deletions(-) Applied to for-next. --nab diff --git a/drivers/target/target_core_configfs.c b/drivers/target/target_core_configfs.c index 272755d..a1c23d1 100644 --- a/drivers/target/target_core_configfs.c +++ b/drivers/target/target_core_configfs.c @@ -2937,7 +2937,7 @@ static int __init target_core_init_configfs(void) * and ALUA Logical Unit Group and Target Port Group infrastructure. */ target_cg = subsys-su_group; - target_cg-default_groups = kmalloc(sizeof(struct config_group) * 2, + target_cg-default_groups = kmalloc(sizeof(struct config_group *) * 2, GFP_KERNEL); if (!target_cg-default_groups) { pr_err(Unable to allocate target_cg-default_groups\n); diff --git a/drivers/target/target_core_fabric_configfs.c b/drivers/target/target_core_fabric_configfs.c index fdadc4d..7de9f04 100644 --- a/drivers/target/target_core_fabric_configfs.c +++ b/drivers/target/target_core_fabric_configfs.c @@ -906,7 +906,7 @@ static struct config_group *target_fabric_make_lun( lun_cg-default_groups[1] = NULL; port_stat_grp = lun-port_stat_grps.stat_group; - port_stat_grp-default_groups = kzalloc(sizeof(struct config_group) * 4, + port_stat_grp-default_groups = kzalloc(sizeof(struct config_group *) * 4, GFP_KERNEL); if (!port_stat_grp-default_groups) { pr_err(Unable to allocate port_stat_grp-default_groups\n); -- 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 05/32] target: Rename some list heads used as nodes
On Fri, 2013-12-13 at 15:58 -0800, Andy Grover wrote: Since everything's a list_head, naming it _node makes it clearer it's to put the struct on a list, not a list head itself. Rename ua_nacl_list to ua_nacl_node Rename alua_port_list to alua_port_node Rename lu_gp_mem_list to lu_gp_mem_node Rename tg_pt_gp_mem_list to tg_pt_gp_mem_node Rename sep_list to sep_node Rename tg_pt_gp_list to tg_pt_gp_node Rename se_session sess_list to sess_node Rename se_node_acl acl_list to acl_node Signed-off-by: Andy Grover agro...@redhat.com --- drivers/target/iscsi/iscsi_target.c |2 +- drivers/target/iscsi/iscsi_target_login.c |4 +- drivers/target/sbp/sbp_target.c |6 ++-- drivers/target/target_core_alua.c | 52 ++-- drivers/target/target_core_configfs.c |4 +- drivers/target/target_core_device.c | 18 +- drivers/target/target_core_pr.c |8 ++-- drivers/target/target_core_tpg.c | 20 +- drivers/target/target_core_transport.c|8 ++-- drivers/target/target_core_ua.c | 28 drivers/target/target_core_xcopy.c|6 ++-- drivers/target/tcm_fc/tfc_conf.c |2 +- include/target/target_core_base.h | 16 13 files changed, 87 insertions(+), 87 deletions(-) Holding off on this one for the moment, as it conflict's with Hannes's patches for ALUA + Referrals. --nab -- 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 06/32] target: Convert lu_gp_ref_cnt to kref
On Fri, 2013-12-13 at 15:58 -0800, Andy Grover wrote: Use kref to handle reference counting Signed-off-by: Andy Grover agro...@redhat.com --- drivers/target/target_core_alua.c | 37 - include/target/target_core_base.h |2 +- 2 files changed, 21 insertions(+), 18 deletions(-) diff --git a/drivers/target/target_core_alua.c b/drivers/target/target_core_alua.c index 2ac2f11..8c01ade 100644 --- a/drivers/target/target_core_alua.c +++ b/drivers/target/target_core_alua.c @@ -54,6 +54,16 @@ static LIST_HEAD(lu_gps_list); struct t10_alua_lu_gp *default_lu_gp; +static void release_alua_lu_gp(struct kref *ref) +{ + struct t10_alua_lu_gp *lu_gp = container_of(ref, struct t10_alua_lu_gp, refcount); + + kmem_cache_free(t10_alua_lu_gp_cache, lu_gp); +} + +#define get_alua_lu_gp(x) kref_get(x-refcount) +#define put_alua_lu_gp(x) kref_put(x-refcount, release_alua_lu_gp) + /* * REPORT_TARGET_PORT_GROUPS * @@ -898,8 +908,7 @@ int core_alua_do_port_transition( local_lu_gp_mem = l_dev-dev_alua_lu_gp_mem; spin_lock(local_lu_gp_mem-lu_gp_mem_lock); lu_gp = local_lu_gp_mem-lu_gp; - atomic_inc(lu_gp-lu_gp_ref_cnt); - smp_mb__after_atomic_inc(); + get_alua_lu_gp(lu_gp); spin_unlock(local_lu_gp_mem-lu_gp_mem_lock); /* * For storage objects that are members of the 'default_lu_gp', @@ -913,8 +922,8 @@ int core_alua_do_port_transition( */ core_alua_do_transition_tg_pt(l_tg_pt_gp, l_port, l_nacl, md_buf, new_state, explicit); - atomic_dec(lu_gp-lu_gp_ref_cnt); - smp_mb__after_atomic_dec(); + + put_alua_lu_gp(lu_gp); kfree(md_buf); return 0; } @@ -985,8 +994,7 @@ int core_alua_do_port_transition( l_tg_pt_gp-tg_pt_gp_id, (explicit) ? explicit : implicit, core_alua_dump_state(new_state)); - atomic_dec(lu_gp-lu_gp_ref_cnt); - smp_mb__after_atomic_dec(); + put_alua_lu_gp(lu_gp); kfree(md_buf); return 0; } @@ -1107,7 +1115,8 @@ core_alua_allocate_lu_gp(const char *name, int def_group) INIT_LIST_HEAD(lu_gp-lu_gp_node); INIT_LIST_HEAD(lu_gp-lu_gp_mem_list); spin_lock_init(lu_gp-lu_gp_lock); - atomic_set(lu_gp-lu_gp_ref_cnt, 0); + + kref_init(lu_gp-refcount); if (def_group) { lu_gp-lu_gp_id = alua_lu_gps_counter++; @@ -1200,13 +1209,7 @@ void core_alua_free_lu_gp(struct t10_alua_lu_gp *lu_gp) list_del(lu_gp-lu_gp_node); alua_lu_gps_count--; spin_unlock(lu_gps_lock); - /* - * Allow struct t10_alua_lu_gp * referenced by core_alua_get_lu_gp_by_name() - * in target_core_configfs.c:target_core_store_alua_lu_gp() to be - * released with core_alua_put_lu_gp_from_name() - */ - while (atomic_read(lu_gp-lu_gp_ref_cnt)) - cpu_relax(); + /* * Release reference to struct t10_alua_lu_gp * from all associated * struct se_device. @@ -1241,7 +1244,7 @@ void core_alua_free_lu_gp(struct t10_alua_lu_gp *lu_gp) } spin_unlock(lu_gp-lu_gp_lock); - kmem_cache_free(t10_alua_lu_gp_cache, lu_gp); + put_alua_lu_gp(lu_gp); } The assumption that it's safe to 'Release reference to struct t10_alua_lu_gp * from all associated struct device' below the original cpu_relax(), while there are still other process contexts doing their respective put_alua_lu_gp() is totally wrong. Furthermore, allowing a configfs_group_ops-drop_item() to return while there are still active references from other process contexts means that the parent struct config_group is no longer referenced counted (eg: configfs child is removed), and introduces a whole host of potential bugs. So that said, NAK on this patch. --nab -- 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 07/32] target: Convert struct alua_lu_gp_member to kref
On Fri, 2013-12-13 at 15:58 -0800, Andy Grover wrote: Signed-off-by: Andy Grover agro...@redhat.com --- drivers/target/target_core_alua.c | 24 +++- include/target/target_core_base.h |2 +- 2 files changed, 16 insertions(+), 10 deletions(-) diff --git a/drivers/target/target_core_alua.c b/drivers/target/target_core_alua.c index 8c01ade..fe2eada 100644 --- a/drivers/target/target_core_alua.c +++ b/drivers/target/target_core_alua.c @@ -64,6 +64,16 @@ static void release_alua_lu_gp(struct kref *ref) #define get_alua_lu_gp(x) kref_get(x-refcount) #define put_alua_lu_gp(x) kref_put(x-refcount, release_alua_lu_gp) +static void release_alua_lu_gp_mem(struct kref *ref) +{ + struct t10_alua_lu_gp_member *lu_gp_mem = container_of(ref, struct t10_alua_lu_gp_member, refcount); + + kmem_cache_free(t10_alua_lu_gp_mem_cache, lu_gp_mem); +} + +#define get_alua_lu_gp_mem(x) kref_get(x-refcount) +#define put_alua_lu_gp_mem(x) kref_put(x-refcount, release_alua_lu_gp_mem) + /* * REPORT_TARGET_PORT_GROUPS * @@ -937,8 +947,7 @@ int core_alua_do_port_transition( lu_gp_mem_node) { dev = lu_gp_mem-lu_gp_mem_dev; - atomic_inc(lu_gp_mem-lu_gp_mem_ref_cnt); - smp_mb__after_atomic_inc(); + get_alua_lu_gp_mem(lu_gp_mem); spin_unlock(lu_gp-lu_gp_lock); spin_lock(dev-t10_alua.tg_pt_gps_lock); @@ -983,8 +992,7 @@ int core_alua_do_port_transition( spin_unlock(dev-t10_alua.tg_pt_gps_lock); spin_lock(lu_gp-lu_gp_lock); - atomic_dec(lu_gp_mem-lu_gp_mem_ref_cnt); - smp_mb__after_atomic_dec(); + put_alua_lu_gp_mem(lu_gp_mem); } spin_unlock(lu_gp-lu_gp_lock); @@ -1186,7 +1194,8 @@ core_alua_allocate_lu_gp_mem(struct se_device *dev) } INIT_LIST_HEAD(lu_gp_mem-lu_gp_mem_node); spin_lock_init(lu_gp_mem-lu_gp_mem_lock); - atomic_set(lu_gp_mem-lu_gp_mem_ref_cnt, 0); + + kref_init(lu_gp_mem-refcount); lu_gp_mem-lu_gp_mem_dev = dev; dev-dev_alua_lu_gp_mem = lu_gp_mem; @@ -1256,9 +1265,6 @@ void core_alua_free_lu_gp_mem(struct se_device *dev) if (!lu_gp_mem) return; - while (atomic_read(lu_gp_mem-lu_gp_mem_ref_cnt)) - cpu_relax(); - spin_lock(lu_gp_mem-lu_gp_mem_lock); lu_gp = lu_gp_mem-lu_gp; if (lu_gp) { @@ -1273,7 +1279,7 @@ void core_alua_free_lu_gp_mem(struct se_device *dev) } spin_unlock(lu_gp_mem-lu_gp_mem_lock); - kmem_cache_free(t10_alua_lu_gp_mem_cache, lu_gp_mem); + put_alua_lu_gp_mem(lu_gp_mem); } Same problem on this one as well. Assuming that it's safe to clear the lu_gp_mem-lu_gp association while there are still active references is wrong. Also, considering that core_alua_free_lu_gp_mem() is called from target_free_device(), it absolutely needs to wait until the reference drops before target_free_device() completes. So that being the case, NAK. --nab -- 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 09/32] target: convert tg_pt_gp_mem_ref_cnt to kref
On Fri, 2013-12-13 at 15:58 -0800, Andy Grover wrote: Use kref to handle reference counting. Signed-off-by: Andy Grover agro...@redhat.com --- drivers/target/target_core_alua.c | 23 ++- include/target/target_core_base.h |2 +- 2 files changed, 15 insertions(+), 10 deletions(-) diff --git a/drivers/target/target_core_alua.c b/drivers/target/target_core_alua.c index ba7b3d6..4ee08a2 100644 --- a/drivers/target/target_core_alua.c +++ b/drivers/target/target_core_alua.c @@ -84,6 +84,16 @@ static void release_alua_tg_pt_gp(struct kref *ref) #define get_alua_tg_pt_gp(x) kref_get(x-refcount) #define put_alua_tg_pt_gp(x) kref_put(x-refcount, release_alua_tg_pt_gp) +static void release_alua_tg_pt_gp_mem(struct kref *ref) +{ + struct t10_alua_tg_pt_gp_member *tg_pt_gp_mem = container_of(ref, struct t10_alua_tg_pt_gp_member, refcount); + + kmem_cache_free(t10_alua_tg_pt_gp_mem_cache, tg_pt_gp_mem); +} + +#define get_alua_tg_pt_gp_mem(x) kref_get(x-refcount) +#define put_alua_tg_pt_gp_mem(x) kref_put(x-refcount, release_alua_tg_pt_gp_mem) + /* * REPORT_TARGET_PORT_GROUPS * @@ -834,8 +844,7 @@ static int core_alua_do_transition_tg_pt( * every I_T nexus other than the I_T nexus on which the SET * TARGET PORT GROUPS command */ - atomic_inc(mem-tg_pt_gp_mem_ref_cnt); - smp_mb__after_atomic_inc(); + get_alua_tg_pt_gp_mem(mem); spin_unlock(tg_pt_gp-tg_pt_gp_lock); spin_lock_bh(port-sep_alua_lock); @@ -861,8 +870,7 @@ static int core_alua_do_transition_tg_pt( spin_unlock_bh(port-sep_alua_lock); spin_lock(tg_pt_gp-tg_pt_gp_lock); - atomic_dec(mem-tg_pt_gp_mem_ref_cnt); - smp_mb__after_atomic_dec(); + put_alua_tg_pt_gp_mem(mem); } spin_unlock(tg_pt_gp-tg_pt_gp_lock); /* @@ -1463,7 +1471,7 @@ struct t10_alua_tg_pt_gp_member *core_alua_allocate_tg_pt_gp_mem( } INIT_LIST_HEAD(tg_pt_gp_mem-tg_pt_gp_mem_node); spin_lock_init(tg_pt_gp_mem-tg_pt_gp_mem_lock); - atomic_set(tg_pt_gp_mem-tg_pt_gp_mem_ref_cnt, 0); + kref_init(tg_pt_gp_mem-refcount); tg_pt_gp_mem-tg_pt = port; port-sep_alua_tg_pt_gp_mem = tg_pt_gp_mem; @@ -1536,9 +1544,6 @@ void core_alua_free_tg_pt_gp_mem(struct se_port *port) if (!tg_pt_gp_mem) return; - while (atomic_read(tg_pt_gp_mem-tg_pt_gp_mem_ref_cnt)) - cpu_relax(); - spin_lock(tg_pt_gp_mem-tg_pt_gp_mem_lock); tg_pt_gp = tg_pt_gp_mem-tg_pt_gp; if (tg_pt_gp) { @@ -1553,7 +1558,7 @@ void core_alua_free_tg_pt_gp_mem(struct se_port *port) } spin_unlock(tg_pt_gp_mem-tg_pt_gp_mem_lock); - kmem_cache_free(t10_alua_tg_pt_gp_mem_cache, tg_pt_gp_mem); + put_alua_tg_pt_gp_mem(tg_pt_gp_mem); } Same issue here between original cpu_relax() location and put_alua_tg_pt_gp_mem(). It's not safe to drop the tg_pt_gp_mem-tg_pt_gp association while there are still active references in other process contexts. Also, the same problem exists with configfs reference counting here, where core_alua_free_tg_pt_gp_mem() is called from core_dev_unexport() - core_release_port(), where the struct lun could be immediately be reused, or the struct device be removed before the final put_alua_tg_pt_gp() is called from the other process contexts. NAK. --nab -- 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 10/32] target: Change sep_tg_pt_ref_cnt to use kref
On Fri, 2013-12-13 at 15:58 -0800, Andy Grover wrote: Use the kernel's std kref for refcounting. Signed-off-by: Andy Grover agro...@redhat.com --- drivers/target/target_core_device.c | 12 ++-- drivers/target/target_core_internal.h | 10 ++ drivers/target/target_core_pr.c | 12 include/target/target_core_base.h |2 +- 4 files changed, 17 insertions(+), 19 deletions(-) diff --git a/drivers/target/target_core_device.c b/drivers/target/target_core_device.c index 3350467..1954b0f 100644 --- a/drivers/target/target_core_device.c +++ b/drivers/target/target_core_device.c @@ -472,6 +472,7 @@ static struct se_port *core_alloc_port(struct se_device *dev) atomic_set(port-sep_tg_pt_secondary_offline, 0); spin_lock_init(port-sep_alua_lock); mutex_init(port-sep_tg_pt_md_mutex); + kref_init(port-refcount); spin_lock(dev-se_port_lock); if (dev-dev_port_count == 0x) { @@ -555,20 +556,11 @@ static void core_export_port( static void core_release_port(struct se_device *dev, struct se_port *port) __releases(dev-se_port_lock) __acquires(dev-se_port_lock) { - /* - * Wait for any port reference for PR ALL_TG_PT=1 operation - * to complete in __core_scsi3_alloc_registration() - */ - spin_unlock(dev-se_port_lock); - if (atomic_read(port-sep_tg_pt_ref_cnt)) - cpu_relax(); - spin_lock(dev-se_port_lock); - core_alua_free_tg_pt_gp_mem(port); list_del(port-sep_node); dev-dev_port_count--; - kfree(port); + put_port(port); } Same problem yet again. It's not safe to release the se_port from it's tg_pt_gp_mem association, while there are active references from other process contexts. Also the same issue with the configfs child / parent reference here, where returning (instead of waiting for references to drop) introduces a whole new host of reference counting issues. NAK. --nab -- 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 11/32] target: Convert se_dev_entry to kref
On Fri, 2013-12-13 at 15:58 -0800, Andy Grover wrote: Signed-off-by: Andy Grover agro...@redhat.com --- drivers/target/target_core_device.c | 12 +++--- drivers/target/target_core_internal.h | 12 ++ drivers/target/target_core_pr.c | 38 drivers/target/target_core_tpg.c |2 +- include/target/target_core_base.h |3 +- 5 files changed, 32 insertions(+), 35 deletions(-) diff --git a/drivers/target/target_core_device.c b/drivers/target/target_core_device.c index 1954b0f..295b5e4 100644 --- a/drivers/target/target_core_device.c +++ b/drivers/target/target_core_device.c @@ -224,8 +224,7 @@ struct se_dev_entry *core_get_se_deve_from_rtpi( if (port-sep_rtpi != rtpi) continue; - atomic_inc(deve-pr_ref_count); - smp_mb__after_atomic_inc(); + get_deve(deve); spin_unlock_irq(nacl-device_list_lock); return deve; @@ -401,12 +400,6 @@ int core_disable_device_list_for_node( spin_lock_bh(port-sep_alua_lock); list_del(deve-alua_port_node); spin_unlock_bh(port-sep_alua_lock); - /* - * Wait for any in process SPEC_I_PT=1 or REGISTER_AND_MOVE - * PR operation to complete. - */ - while (atomic_read(deve-pr_ref_count) != 0) - cpu_relax(); spin_lock_irq(nacl-device_list_lock); /* @@ -421,6 +414,9 @@ int core_disable_device_list_for_node( spin_unlock_irq(nacl-device_list_lock); core_scsi3_free_pr_reg_from_nacl(lun-lun_se_dev, nacl); + + put_deve(deve); + return 0; } Same issue yet again. It's not safe to release all of the se_dev_entry pointers, UAs, and PR associations until the other references from different process contexts have been released. Also the issue with reuse of se_dev_entry also exists here. configfs_group_operations-drop_item() callbacks should not return until all references have completed. NAK. --nab -- 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 12/32] target: Convert t10_pr_registration to kref
On Fri, 2013-12-13 at 15:59 -0800, Andy Grover wrote: Free struct when kref becomes 0. Signed-off-by: Andy Grover agro...@redhat.com --- drivers/target/target_core_pr.c | 99 +++- include/target/target_core_base.h |2 +- 2 files changed, 42 insertions(+), 59 deletions(-) diff --git a/drivers/target/target_core_pr.c b/drivers/target/target_core_pr.c index 9155df0..17a4c3b 100644 --- a/drivers/target/target_core_pr.c +++ b/drivers/target/target_core_pr.c @@ -75,6 +75,17 @@ enum preempt_type { PREEMPT_AND_ABORT, }; +static void release_pr_reg(struct kref *kref) +{ + struct t10_pr_registration *pr_reg = container_of(kref, + struct t10_pr_registration, refcount); + + kmem_cache_free(t10_pr_reg_cache, pr_reg); +} + +#define get_pr_reg(x) kref_get(x-refcount) +#define put_pr_reg(x) kref_put(x-refcount, release_pr_reg) + static void __core_scsi3_complete_pro_release(struct se_device *, struct se_node_acl *, struct t10_pr_registration *, int); @@ -109,7 +120,6 @@ target_scsi2_reservation_check(struct se_cmd *cmd) static struct t10_pr_registration *core_scsi3_locate_pr_reg(struct se_device *, struct se_node_acl *, struct se_session *); -static void core_scsi3_put_pr_reg(struct t10_pr_registration *); static int target_check_scsi2_reservation_conflict(struct se_cmd *cmd) { @@ -144,17 +154,17 @@ static int target_check_scsi2_reservation_conflict(struct se_cmd *cmd) * as defined in SPC-2. */ if (pr_reg-pr_res_holder) { - core_scsi3_put_pr_reg(pr_reg); + put_pr_reg(pr_reg); return 1; } if ((pr_reg-pr_res_type == PR_TYPE_WRITE_EXCLUSIVE_REGONLY) || (pr_reg-pr_res_type == PR_TYPE_EXCLUSIVE_ACCESS_REGONLY) || (pr_reg-pr_res_type == PR_TYPE_WRITE_EXCLUSIVE_ALLREG) || (pr_reg-pr_res_type == PR_TYPE_EXCLUSIVE_ACCESS_ALLREG)) { - core_scsi3_put_pr_reg(pr_reg); + put_pr_reg(pr_reg); return 1; } - core_scsi3_put_pr_reg(pr_reg); + put_pr_reg(pr_reg); conflict = 1; } else { /* @@ -611,7 +621,7 @@ static struct t10_pr_registration *__core_scsi3_do_alloc_registration( INIT_LIST_HEAD(pr_reg-pr_reg_aptpl_list); INIT_LIST_HEAD(pr_reg-pr_reg_atp_list); INIT_LIST_HEAD(pr_reg-pr_reg_atp_mem_list); - atomic_set(pr_reg-pr_res_holders, 0); + kref_init(pr_reg-refcount); pr_reg-pr_reg_nacl = nacl; pr_reg-pr_reg_deve = deve; pr_reg-pr_res_mapped_lun = deve-mapped_lun; @@ -795,7 +805,7 @@ int core_scsi3_alloc_aptpl_registration( INIT_LIST_HEAD(pr_reg-pr_reg_aptpl_list); INIT_LIST_HEAD(pr_reg-pr_reg_atp_list); INIT_LIST_HEAD(pr_reg-pr_reg_atp_mem_list); - atomic_set(pr_reg-pr_res_holders, 0); + kref_init(pr_reg-refcount); pr_reg-pr_reg_nacl = NULL; pr_reg-pr_reg_deve = NULL; pr_reg-pr_res_mapped_lun = mapped_lun; @@ -1102,8 +1112,7 @@ static struct t10_pr_registration *__core_scsi3_locate_pr_reg( if (dev-dev_attrib.enforce_pr_isids) continue; } - atomic_inc(pr_reg-pr_res_holders); - smp_mb__after_atomic_inc(); + get_pr_reg(pr_reg); spin_unlock(pr_tmpl-registration_lock); return pr_reg; } @@ -1117,8 +1126,7 @@ static struct t10_pr_registration *__core_scsi3_locate_pr_reg( if (strcmp(isid, pr_reg-pr_reg_isid)) continue; - atomic_inc(pr_reg-pr_res_holders); - smp_mb__after_atomic_inc(); + get_pr_reg(pr_reg); spin_unlock(pr_tmpl-registration_lock); return pr_reg; } @@ -1145,12 +1153,6 @@ static struct t10_pr_registration *core_scsi3_locate_pr_reg( return __core_scsi3_locate_pr_reg(dev, nacl, isid_ptr); } -static void core_scsi3_put_pr_reg(struct t10_pr_registration *pr_reg) -{ - atomic_dec(pr_reg-pr_res_holders); - smp_mb__after_atomic_dec(); -} - static int core_scsi3_check_implicit_release( struct se_device *dev, struct t10_pr_registration *pr_reg) @@ -1213,7 +1215,6 @@ static void __core_scsi3_free_registration( { struct target_core_fabric_ops *tfo = pr_reg-pr_reg_nacl-se_tpg-se_tpg_tfo; - struct t10_reservation *pr_tmpl = dev-t10_pr; char i_buf[PR_REG_ISID_ID_LEN]; memset(i_buf, 0, PR_REG_ISID_ID_LEN); @@ -1227,20 +1228,7 @@ static void
Re: [PATCH 15/32] target: Refer to u32 luns as unpacked_lun
On Fri, 2013-12-13 at 15:59 -0800, Andy Grover wrote: It's clearer to refer to pointers to the struct se_lun as lun and the actual number itself as unpacked_lun. Signed-off-by: Andy Grover agro...@redhat.com --- drivers/target/target_core_device.c | 16 1 files changed, 8 insertions(+), 8 deletions(-) Applied to target-pending/for-next. --nab -- 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 14/32] target: Remove extra percpu_ref_init
On Fri, 2013-12-13 at 15:59 -0800, Andy Grover wrote: lun-lun_ref is also initialized in core_tpg_post_addlun, so it doesn't need to be done in core_tpg_setup_virtual_lun0. Signed-off-by: Andy Grover agro...@redhat.com --- drivers/target/target_core_tpg.c |4 1 files changed, 0 insertions(+), 4 deletions(-) diff --git a/drivers/target/target_core_tpg.c b/drivers/target/target_core_tpg.c index 8771b23..2f6df57 100644 --- a/drivers/target/target_core_tpg.c +++ b/drivers/target/target_core_tpg.c @@ -658,10 +658,6 @@ static int core_tpg_setup_virtual_lun0(struct se_portal_group *se_tpg) spin_lock_init(lun-lun_sep_lock); init_completion(lun-lun_ref_comp); - ret = percpu_ref_init(lun-lun_ref, core_tpg_lun_ref_release); - if (ret 0) - return ret; - ret = core_tpg_post_addlun(se_tpg, lun, lun_access, dev); if (ret 0) { percpu_ref_cancel_init(lun-lun_ref); Applied to target-pending/queue, and will be including in the next -rc5 PULL request. --nab -- 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 16/32] target: Rename core_tpg_{pre,post}_addlun for clarity
On Fri, 2013-12-13 at 15:59 -0800, Andy Grover wrote: pre is really an allocation function. The only time it isn't called is for virtual_lun0, which is statically allocated. Renaming that to alloc lets the other function not need to be post, and just be called core_tpg_add_lun. Signed-off-by: Andy Grover agro...@redhat.com --- drivers/target/target_core_device.c |4 ++-- drivers/target/target_core_internal.h |4 ++-- drivers/target/target_core_tpg.c |6 +++--- 3 files changed, 7 insertions(+), 7 deletions(-) Applied, with minor patch fuzz in core_tpg_setup_virtual_lun0(). --nab -- 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 17/32] target: Don't use void* when passing dev in core_tpg_add_lun
On Fri, 2013-12-13 at 15:59 -0800, Andy Grover wrote: Especially since it's actually a device. Signed-off-by: Andy Grover agro...@redhat.com --- drivers/target/target_core_internal.h |2 +- drivers/target/target_core_tpg.c |4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) Applied to target-pending/for-next. --nab diff --git a/drivers/target/target_core_internal.h b/drivers/target/target_core_internal.h index 4093936..aabb730 100644 --- a/drivers/target/target_core_internal.h +++ b/drivers/target/target_core_internal.h @@ -89,7 +89,7 @@ voidcore_tpg_add_node_to_devs(struct se_node_acl *, struct se_portal_group *); void core_tpg_wait_for_nacl_pr_ref(struct se_node_acl *); struct se_lun *core_tpg_alloc_lun(struct se_portal_group *, u32); int core_tpg_add_lun(struct se_portal_group *, struct se_lun *, - u32, void *); + u32, struct se_device *); struct se_lun *core_tpg_pre_dellun(struct se_portal_group *, u32 unpacked_lun); int core_tpg_post_dellun(struct se_portal_group *, struct se_lun *); diff --git a/drivers/target/target_core_tpg.c b/drivers/target/target_core_tpg.c index 55a9d38..da7febb 100644 --- a/drivers/target/target_core_tpg.c +++ b/drivers/target/target_core_tpg.c @@ -819,7 +819,7 @@ int core_tpg_add_lun( struct se_portal_group *tpg, struct se_lun *lun, u32 lun_access, - void *lun_ptr) + struct se_device *dev) { int ret; @@ -827,7 +827,7 @@ int core_tpg_add_lun( if (ret 0) return ret; - ret = core_dev_export(lun_ptr, tpg, lun); + ret = core_dev_export(dev, tpg, lun); if (ret 0) { percpu_ref_cancel_init(lun-lun_ref); return ret; -- 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 18/32] target: More core_dev_del cleanups
On Fri, 2013-12-13 at 15:59 -0800, Andy Grover wrote: core_dev_del_lun needs no return value. Also change it to take a se_lun* instead of the unpacked lun. Rename core_tpg_pre_dellun to core_tpg_free_lun, and post_dellun to remove_lun. Swap the order they are called, and hold off on setting lun_status to STATUS_FREE until the end of free_lun. The swapping of the order makes no sense here.. Why should the checks now happen after everything released to the se_lun has been released, and yet still ignore the return value. !? NAK. --nab Signed-off-by: Andy Grover agro...@redhat.com --- drivers/target/target_core_device.c | 16 - drivers/target/target_core_fabric_configfs.c |2 +- drivers/target/target_core_internal.h|6 ++-- drivers/target/target_core_tpg.c | 32 +- 4 files changed, 20 insertions(+), 36 deletions(-) diff --git a/drivers/target/target_core_device.c b/drivers/target/target_core_device.c index faa17a4..af12456 100644 --- a/drivers/target/target_core_device.c +++ b/drivers/target/target_core_device.c @@ -1140,24 +1140,18 @@ struct se_lun *core_dev_add_lun( * * */ -int core_dev_del_lun( +void core_dev_del_lun( struct se_portal_group *tpg, - u32 unpacked_lun) + struct se_lun *lun) { - struct se_lun *lun; - - lun = core_tpg_pre_dellun(tpg, unpacked_lun); - if (IS_ERR(lun)) - return PTR_ERR(lun); - - core_tpg_post_dellun(tpg, lun); + core_tpg_remove_lun(tpg, lun); pr_debug(%s_TPG[%u]_LUN[%u] - Deactivated %s Logical Unit from device object\n, tpg-se_tpg_tfo-get_fabric_name(), - tpg-se_tpg_tfo-tpg_get_tag(tpg), unpacked_lun, + tpg-se_tpg_tfo-tpg_get_tag(tpg), lun-unpacked_lun, tpg-se_tpg_tfo-get_fabric_name()); - return 0; + core_tpg_free_lun(tpg, lun); } struct se_lun *core_get_lun_from_tpg(struct se_portal_group *tpg, u32 unpacked_lun) diff --git a/drivers/target/target_core_fabric_configfs.c b/drivers/target/target_core_fabric_configfs.c index 7de9f04..64cc4dc 100644 --- a/drivers/target/target_core_fabric_configfs.c +++ b/drivers/target/target_core_fabric_configfs.c @@ -821,7 +821,7 @@ static int target_fabric_port_unlink( tf-tf_ops.fabric_pre_unlink(se_tpg, lun); } - core_dev_del_lun(se_tpg, lun-unpacked_lun); + core_dev_del_lun(se_tpg, lun); return 0; } diff --git a/drivers/target/target_core_internal.h b/drivers/target/target_core_internal.h index aabb730..5d1e4ec 100644 --- a/drivers/target/target_core_internal.h +++ b/drivers/target/target_core_internal.h @@ -44,7 +44,7 @@ int se_dev_set_fabric_max_sectors(struct se_device *, u32); int se_dev_set_optimal_sectors(struct se_device *, u32); int se_dev_set_block_size(struct se_device *, u32); struct se_lun *core_dev_add_lun(struct se_portal_group *, struct se_device *, u32); -int core_dev_del_lun(struct se_portal_group *, u32); +void core_dev_del_lun(struct se_portal_group *, struct se_lun *); struct se_lun *core_get_lun_from_tpg(struct se_portal_group *, u32); struct se_lun_acl *core_dev_init_initiator_node_lun_acl(struct se_portal_group *, struct se_node_acl *, u32, int *); @@ -90,8 +90,8 @@ voidcore_tpg_wait_for_nacl_pr_ref(struct se_node_acl *); struct se_lun *core_tpg_alloc_lun(struct se_portal_group *, u32); int core_tpg_add_lun(struct se_portal_group *, struct se_lun *, u32, struct se_device *); -struct se_lun *core_tpg_pre_dellun(struct se_portal_group *, u32 unpacked_lun); -int core_tpg_post_dellun(struct se_portal_group *, struct se_lun *); +void core_tpg_free_lun(struct se_portal_group *, struct se_lun *); +void core_tpg_remove_lun(struct se_portal_group *, struct se_lun *); static inline void release_deve(struct kref *kref) { diff --git a/drivers/target/target_core_tpg.c b/drivers/target/target_core_tpg.c index da7febb..e6f9dfb 100644 --- a/drivers/target/target_core_tpg.c +++ b/drivers/target/target_core_tpg.c @@ -336,7 +336,7 @@ void core_tpg_clear_object_luns(struct se_portal_group *tpg) continue; spin_unlock(tpg-tpg_lun_lock); - core_dev_del_lun(tpg, lun-unpacked_lun); + core_dev_del_lun(tpg, lun); spin_lock(tpg-tpg_lun_lock); } spin_unlock(tpg-tpg_lun_lock); @@ -671,7 +671,7 @@ static void core_tpg_release_virtual_lun0(struct se_portal_group *se_tpg) { struct se_lun *lun = se_tpg-tpg_virt_lun0; - core_tpg_post_dellun(se_tpg, lun); + core_tpg_remove_lun(se_tpg, lun); } int core_tpg_register( @@ -841,48 +841,38 @@ int core_tpg_add_lun( return 0; } -struct se_lun *core_tpg_pre_dellun( +void core_tpg_free_lun( struct se_portal_group *tpg, - u32 unpacked_lun) + struct
Re: [PATCH 19/32] target: Convert to rbtree for se_dev_entry in se_node_acl
On Fri, 2013-12-13 at 15:59 -0800, Andy Grover wrote: Instead of an array, use a rbtree. Less memory use on average, and can allow 255 entries. We go from O(1) to O(log n) on lookups. If this shows up on profiling (it won't) then transition to other kernel lookup methods is straightforward from here. Ugh. There is no reason to be using rbtrees in a performance critical path here. The number of pointer lookups is what ends up hurting the most vs. a flat array, so given that 256 LUNs per endpoint is currently not an issue, and there is no hard limit on the number of endpoints with virtual addressing, I don't see the benefit of this patch. NAK. --nab Change core_disable_device_list_for_node to be called with device_list_lock held, and tweaked params a little. TRANSPORT_LUNFLAGS_INITIATOR_ACCESS no longer needed, presence in the rbtree is equivalent to this being set. Signed-off-by: Andy Grover agro...@redhat.com --- drivers/target/target_core_device.c | 213 ++--- drivers/target/target_core_fabric_configfs.c | 24 ++-- drivers/target/target_core_internal.h| 15 +- drivers/target/target_core_pr.c | 25 +++- drivers/target/target_core_spc.c | 11 +- drivers/target/target_core_stat.c| 72 +- drivers/target/target_core_tpg.c | 53 +-- drivers/target/target_core_ua.c | 18 ++- include/target/target_core_base.h|8 +- 9 files changed, 222 insertions(+), 217 deletions(-) diff --git a/drivers/target/target_core_device.c b/drivers/target/target_core_device.c index af12456..a18724b 100644 --- a/drivers/target/target_core_device.c +++ b/drivers/target/target_core_device.c @@ -54,6 +54,51 @@ static struct se_hba *lun0_hba; /* not static, needed by tpg.c */ struct se_device *g_lun0_dev; +bool transport_insert_deve(struct se_node_acl *nacl, struct se_dev_entry *deve) +{ + struct rb_root *root = nacl-rb_device_list; + struct rb_node **new = (root-rb_node), *parent = NULL; + + /* Figure out where to put new node */ + while (*new) { + struct se_dev_entry *this = rb_entry(*new, struct se_dev_entry, rb_node); + + parent = *new; + if (deve-mapped_lun this-mapped_lun) + new = ((*new)-rb_left); + else if (deve-mapped_lun this-mapped_lun) + new = ((*new)-rb_right); + else + return false; + } + + /* Add new node and rebalance tree. */ + rb_link_node(deve-rb_node, parent, new); + rb_insert_color(deve-rb_node, root); + + return true; +} + + +struct se_dev_entry *transport_search_deve(struct se_node_acl *nacl, u32 mapped_lun) +{ + struct rb_root *root = nacl-rb_device_list; + struct rb_node *node = root-rb_node; + + while (node) { + struct se_dev_entry *deve = rb_entry(node, struct se_dev_entry, rb_node); + + if (mapped_lun deve-mapped_lun) + node = node-rb_left; + else if (mapped_lun deve-mapped_lun) + node = node-rb_right; + else + return deve; + } + return NULL; +} + + sense_reason_t transport_lookup_cmd_lun(struct se_cmd *se_cmd, u32 unpacked_lun) { @@ -66,8 +111,8 @@ transport_lookup_cmd_lun(struct se_cmd *se_cmd, u32 unpacked_lun) return TCM_NON_EXISTENT_LUN; spin_lock_irqsave(se_sess-se_node_acl-device_list_lock, flags); - se_cmd-se_deve = se_sess-se_node_acl-device_list[unpacked_lun]; - if (se_cmd-se_deve-lun_flags TRANSPORT_LUNFLAGS_INITIATOR_ACCESS) { + se_cmd-se_deve = transport_search_deve(se_sess-se_node_acl, unpacked_lun); + if (se_cmd-se_deve) { struct se_dev_entry *deve = se_cmd-se_deve; deve-total_cmds++; @@ -153,10 +198,10 @@ int transport_lookup_tmr_lun(struct se_cmd *se_cmd, u32 unpacked_lun) return -ENODEV; spin_lock_irqsave(se_sess-se_node_acl-device_list_lock, flags); - se_cmd-se_deve = se_sess-se_node_acl-device_list[unpacked_lun]; - deve = se_cmd-se_deve; + se_cmd-se_deve = transport_search_deve(se_sess-se_node_acl, unpacked_lun); + if (se_cmd-se_deve) { + deve = se_cmd-se_deve; - if (deve-lun_flags TRANSPORT_LUNFLAGS_INITIATOR_ACCESS) { se_tmr-tmr_lun = deve-se_lun; se_cmd-se_lun = deve-se_lun; se_lun = deve-se_lun; @@ -187,25 +232,22 @@ EXPORT_SYMBOL(transport_lookup_tmr_lun); /* * This function is called from core_scsi3_emulate_pro_register_and_move() - * and core_scsi3_decode_spec_i_port(), and will increment deve-pr_ref_count + * and core_scsi3_decode_spec_i_port(), and will increment deve-refcount * when a matching rtpi is found. */ struct se_dev_entry
Re: [PATCH 21/32] target: Remove lun_link and device magic
On Fri, 2013-12-13 at 15:59 -0800, Andy Grover wrote: Not needed. Big NAK on this one. It most certainly is still required in order to prevent any random pointer from being passed into a configfs symlink sink for Port/LUN and MappedLUN creation. --nab Signed-off-by: Andy Grover agro...@redhat.com --- drivers/target/target_core_device.c |1 - drivers/target/target_core_fabric_configfs.c | 11 --- drivers/target/target_core_tpg.c |2 -- include/target/target_core_base.h|4 4 files changed, 0 insertions(+), 18 deletions(-) diff --git a/drivers/target/target_core_device.c b/drivers/target/target_core_device.c index f2e1415..e85a647 100644 --- a/drivers/target/target_core_device.c +++ b/drivers/target/target_core_device.c @@ -1350,7 +1350,6 @@ struct se_device *target_alloc_device(struct se_hba *hba, const char *name) if (!dev) return NULL; - dev-dev_link_magic = SE_DEV_LINK_MAGIC; dev-se_hba = hba; dev-transport = hba-transport; diff --git a/drivers/target/target_core_fabric_configfs.c b/drivers/target/target_core_fabric_configfs.c index 1a31b46..4715836 100644 --- a/drivers/target/target_core_fabric_configfs.c +++ b/drivers/target/target_core_fabric_configfs.c @@ -71,11 +71,6 @@ static int target_fabric_mappedlun_link( struct config_item *nacl_ci, *tpg_ci, *tpg_ci_s, *wwn_ci, *wwn_ci_s; int ret = 0, lun_access; - if (lun-lun_link_magic != SE_LUN_LINK_MAGIC) { - pr_err(Bad lun-lun_link_magic, not a valid lun_ci pointer: - %p to struct lun: %p\n, lun_ci, lun); - return -EFAULT; - } /* * Ensure that the source port exists */ @@ -762,12 +757,6 @@ static int target_fabric_port_link( struct target_fabric_configfs *tf; int ret; - if (dev-dev_link_magic != SE_DEV_LINK_MAGIC) { - pr_err(Bad dev-dev_link_magic, not a valid se_dev_ci pointer: - %p to struct se_device: %p\n, se_dev_ci, dev); - return -EFAULT; - } - if (!(dev-dev_flags DF_CONFIGURED)) { pr_err(se_device not configured yet, cannot port link\n); return -ENODEV; diff --git a/drivers/target/target_core_tpg.c b/drivers/target/target_core_tpg.c index 0467ad8..977b05c 100644 --- a/drivers/target/target_core_tpg.c +++ b/drivers/target/target_core_tpg.c @@ -617,7 +617,6 @@ static int core_tpg_setup_virtual_lun0(struct se_portal_group *se_tpg) int ret; lun-unpacked_lun = 0; - lun-lun_link_magic = SE_LUN_LINK_MAGIC; atomic_set(lun-lun_acl_count, 0); init_completion(lun-lun_shutdown_comp); INIT_LIST_HEAD(lun-lun_acl_list); @@ -749,7 +748,6 @@ struct se_lun *core_tpg_alloc_lun( return ERR_PTR(-ENOMEM); lun-unpacked_lun = unpacked_lun; - lun-lun_link_magic = SE_LUN_LINK_MAGIC; atomic_set(lun-lun_acl_count, 0); init_completion(lun-lun_shutdown_comp); INIT_LIST_HEAD(lun-lun_acl_list); diff --git a/include/target/target_core_base.h b/include/target/target_core_base.h index 06f9bea..2c0a595 100644 --- a/include/target/target_core_base.h +++ b/include/target/target_core_base.h @@ -629,8 +629,6 @@ struct se_port_stat_grps { struct se_lun { struct rb_node rb_node; -#define SE_LUN_LINK_MAGIC0x7771 - u32 lun_link_magic; u32 lun_access; u32 lun_flags; u32 unpacked_lun; @@ -655,8 +653,6 @@ struct se_dev_stat_grps { }; struct se_device { -#define SE_DEV_LINK_MAGIC0xfeeddeef - u32 dev_link_magic; /* RELATIVE TARGET PORT IDENTIFER Counter */ u16 dev_rpti_counter; /* Used for SAM Task Attribute ordering */ -- 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 20/32] target: Convert to rbtree for se_lun list in se_portal_group
On Fri, 2013-12-13 at 15:59 -0800, Andy Grover wrote: As with previous commit, this results in less average memory use, and allows lun count to no longer be restrained by the array size. NAK for the same reasons as the previous patch. rbtree introduces many extra memory addresses for pointer chasing during lookup vs. a flat array, so for a performance critical path this needs to be avoided. --nab Remove array_free and array_zalloc. For some reason, sbp fabric needs core_search lun, so export it for now. Remove core_alloc_lun, it duplicates core_tpg_alloc_lun. Change core_dev_add_lun to take a se_lun and return int Signed-off-by: Andy Grover agro...@redhat.com --- drivers/target/sbp/sbp_target.c | 25 ++--- drivers/target/target_core_device.c | 79 +--- drivers/target/target_core_fabric_configfs.c | 27 ++--- drivers/target/target_core_internal.h|5 +- drivers/target/target_core_tpg.c | 168 - include/target/target_core_base.h| 11 +-- include/target/target_core_fabric.h |3 + 7 files changed, 116 insertions(+), 202 deletions(-) diff --git a/drivers/target/sbp/sbp_target.c b/drivers/target/sbp/sbp_target.c index e1ceae5..103998c 100644 --- a/drivers/target/sbp/sbp_target.c +++ b/drivers/target/sbp/sbp_target.c @@ -185,9 +185,8 @@ static struct se_lun *sbp_get_lun_from_tpg(struct sbp_tpg *tpg, int lun) return ERR_PTR(-EINVAL); spin_lock(se_tpg-tpg_lun_lock); - se_lun = se_tpg-tpg_lun_list[lun]; - - if (se_lun-lun_status != TRANSPORT_LUN_STATUS_ACTIVE) + se_lun = core_search_lun(se_tpg, lun); + if (!se_lun) se_lun = ERR_PTR(-ENODEV); spin_unlock(se_tpg-tpg_lun_lock); @@ -1936,15 +1935,11 @@ static char *sbp_parse_pr_out_transport_id( static int sbp_count_se_tpg_luns(struct se_portal_group *tpg) { - int i, count = 0; + int count = 0; + struct rb_node *node; spin_lock(tpg-tpg_lun_lock); - for (i = 0; i TRANSPORT_MAX_LUNS_PER_TPG; i++) { - struct se_lun *se_lun = tpg-tpg_lun_list[i]; - - if (se_lun-lun_status == TRANSPORT_LUN_STATUS_FREE) - continue; - + for (node = rb_first(tpg-rb_tpg_lun_list); node; node = rb_next(node)) { count++; } spin_unlock(tpg-tpg_lun_lock); @@ -1954,8 +1949,9 @@ static int sbp_count_se_tpg_luns(struct se_portal_group *tpg) static int sbp_update_unit_directory(struct sbp_tport *tport) { - int num_luns, num_entries, idx = 0, mgt_agt_addr, ret, i; + int num_luns, num_entries, idx = 0, mgt_agt_addr, ret; u32 *data; + struct rb_node *node; if (tport-unit_directory.data) { fw_core_remove_descriptor(tport-unit_directory); @@ -2017,14 +2013,11 @@ static int sbp_update_unit_directory(struct sbp_tport *tport) data[idx++] = 0x8d00 | (num_luns + 1); spin_lock(tport-tpg-se_tpg.tpg_lun_lock); - for (i = 0; i TRANSPORT_MAX_LUNS_PER_TPG; i++) { - struct se_lun *se_lun = tport-tpg-se_tpg.tpg_lun_list[i]; + for (node = rb_first(tport-tpg-se_tpg.rb_tpg_lun_list); node; node = rb_next(node)) { + struct se_lun *se_lun = container_of(node, struct se_lun, rb_node); struct se_device *dev; int type; - if (se_lun-lun_status == TRANSPORT_LUN_STATUS_FREE) - continue; - spin_unlock(tport-tpg-se_tpg.tpg_lun_lock); dev = se_lun-lun_se_dev; diff --git a/drivers/target/target_core_device.c b/drivers/target/target_core_device.c index a18724b..f2e1415 100644 --- a/drivers/target/target_core_device.c +++ b/drivers/target/target_core_device.c @@ -1117,22 +1117,17 @@ int se_dev_set_block_size(struct se_device *dev, u32 block_size) return 0; } -struct se_lun *core_dev_add_lun( +int core_dev_add_lun( struct se_portal_group *tpg, struct se_device *dev, - u32 unpacked_lun) + struct se_lun *lun) { - struct se_lun *lun; int rc; - lun = core_tpg_alloc_lun(tpg, unpacked_lun); - if (IS_ERR(lun)) - return lun; - rc = core_tpg_add_lun(tpg, lun, TRANSPORT_LUNFLAGS_READ_WRITE, dev); if (rc 0) - return ERR_PTR(rc); + return rc; pr_debug(%s_TPG[%u]_LUN[%u] - Activated %s Logical Unit from CORE HBA: %u\n, tpg-se_tpg_tfo-get_fabric_name(), @@ -1157,7 +1152,7 @@ struct se_lun *core_dev_add_lun( spin_unlock_irq(tpg-acl_node_lock); } - return lun; + return rc; } /* core_dev_del_lun(): @@ -1178,68 +1173,6 @@ void core_dev_del_lun( core_tpg_free_lun(tpg, lun); } -struct se_lun *core_get_lun_from_tpg(struct se_portal_group *tpg, u32
Re: [PATCH 25/32] target: Call remove_lun instead of del_lun in fabric_port_unlink
On Fri, 2013-12-13 at 15:59 -0800, Andy Grover wrote: We want to be freeing the port here, not freeing the lun. Signed-off-by: Andy Grover agro...@redhat.com --- drivers/target/target_core_fabric_configfs.c |2 +- 1 files changed, 1 insertions(+), 1 deletions(-) Skipping this one as well. --nab diff --git a/drivers/target/target_core_fabric_configfs.c b/drivers/target/target_core_fabric_configfs.c index 4715836..fe940d4 100644 --- a/drivers/target/target_core_fabric_configfs.c +++ b/drivers/target/target_core_fabric_configfs.c @@ -808,7 +808,7 @@ static int target_fabric_port_unlink( tf-tf_ops.fabric_pre_unlink(se_tpg, lun); } - core_dev_del_lun(se_tpg, lun); + core_tpg_remove_lun(se_tpg, lun); return 0; } -- 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 24/32] target: Remove tpg from core_dev_export/unexport params
On Fri, 2013-12-13 at 15:59 -0800, Andy Grover wrote: lun-lun_tpg should always be set. Signed-off-by: Andy Grover agro...@redhat.com --- drivers/target/target_core_device.c | 17 +++-- drivers/target/target_core_internal.h |6 ++ drivers/target/target_core_tpg.c |4 ++-- 3 files changed, 11 insertions(+), 16 deletions(-) Ditto here, skipping.. --nab diff --git a/drivers/target/target_core_device.c b/drivers/target/target_core_device.c index 753e7ca..a432d7b 100644 --- a/drivers/target/target_core_device.c +++ b/drivers/target/target_core_device.c @@ -583,7 +583,6 @@ static void core_release_port(struct se_device *dev, struct se_port *port) int core_dev_export( struct se_device *dev, - struct se_portal_group *tpg, struct se_lun *lun) { struct se_hba *hba = dev-se_hba; @@ -599,17 +598,13 @@ int core_dev_export( dev-export_count++; spin_unlock(hba-device_lock); - core_export_port(dev, tpg, port, lun); + core_export_port(dev, lun-lun_tpg, port, lun); return 0; } -void core_dev_unexport( - struct se_device *dev, - struct se_portal_group *tpg, - struct se_lun *lun) +void core_dev_unexport(struct se_lun *lun) { - struct se_hba *hba = dev-se_hba; - struct se_port *port = lun-lun_sep; + struct se_hba *hba; spin_lock(lun-lun_sep_lock); if (lun-lun_se_dev == NULL) { @@ -618,10 +613,12 @@ void core_dev_unexport( } spin_unlock(lun-lun_sep_lock); - core_release_port(dev, port); + core_release_port(lun-lun_se_dev, lun-lun_sep); + + hba = lun-lun_se_dev-se_hba; spin_lock(hba-device_lock); - dev-export_count--; + lun-lun_se_dev-export_count--; spin_unlock(hba-device_lock); lun-lun_se_dev = NULL; diff --git a/drivers/target/target_core_internal.h b/drivers/target/target_core_internal.h index 4d3b559..5b232a7 100644 --- a/drivers/target/target_core_internal.h +++ b/drivers/target/target_core_internal.h @@ -16,10 +16,8 @@ intcore_enable_device_list_for_node(struct se_lun *, struct se_lun_acl *, void core_disable_device_list_for_node(struct se_lun *, struct se_dev_entry *, u32, struct se_node_acl *, struct se_portal_group *); void core_clear_lun_from_tpg(struct se_lun *, struct se_portal_group *); -int core_dev_export(struct se_device *, struct se_portal_group *, - struct se_lun *); -void core_dev_unexport(struct se_device *, struct se_portal_group *, - struct se_lun *); +int core_dev_export(struct se_device *, struct se_lun *); +void core_dev_unexport(struct se_lun *); int se_dev_set_task_timeout(struct se_device *, u32); int se_dev_set_max_unmap_lba_count(struct se_device *, u32); int se_dev_set_max_unmap_block_desc_count(struct se_device *, u32); diff --git a/drivers/target/target_core_tpg.c b/drivers/target/target_core_tpg.c index c63f6cd..d9fbdd0 100644 --- a/drivers/target/target_core_tpg.c +++ b/drivers/target/target_core_tpg.c @@ -765,7 +765,7 @@ int core_tpg_add_lun( { int ret; - ret = core_dev_export(dev, tpg, lun); + ret = core_dev_export(dev, lun); if (ret 0) return ret; @@ -803,6 +803,6 @@ void core_tpg_remove_lun( struct se_lun *lun) { core_clear_lun_from_tpg(lun, tpg); - core_dev_unexport(lun-lun_se_dev, tpg, lun); + core_dev_unexport(lun); put_lun(lun); } -- 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 27/32] target: Move call to remove_lun to the release function from drop_link
On Fri, 2013-12-13 at 15:59 -0800, Andy Grover wrote: Configfs is still using the memory until release() is called, so it's not safe to free it in drop_link(). Signed-off-by: Andy Grover agro...@redhat.com --- drivers/target/target_core_fabric_configfs.c | 10 +- 1 files changed, 9 insertions(+), 1 deletions(-) No longer is applicable, given the previous NAKs. --nab diff --git a/drivers/target/target_core_fabric_configfs.c b/drivers/target/target_core_fabric_configfs.c index 45a1763..1e584fa 100644 --- a/drivers/target/target_core_fabric_configfs.c +++ b/drivers/target/target_core_fabric_configfs.c @@ -809,11 +809,19 @@ static int target_fabric_port_unlink( tf-tf_ops.fabric_pre_unlink(se_tpg, lun); } - core_tpg_remove_lun(se_tpg, lun); return 0; } +static void target_fabric_release_lun(struct config_item *item) +{ + struct se_lun *lun = container_of(to_config_group(item), + struct se_lun, lun_group); + + core_tpg_remove_lun(lun-lun_tpg, lun); +} + static struct configfs_item_operations target_fabric_port_item_ops = { + .release= target_fabric_release_lun, .show_attribute = target_fabric_port_attr_show, .store_attribute= target_fabric_port_attr_store, .allow_link = target_fabric_port_link, -- 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 28/32] target: Convert acl_pr_ref_count to kref
On Fri, 2013-12-13 at 15:59 -0800, Andy Grover wrote: In fabrics' drop_nodeacl function, do not kfree the nacl. We are now calling fabrics' tpg_release_fabric_acl later when its refcount goes to zero, which will kfree it. Signed-off-by: Andy Grover agro...@redhat.com --- Documentation/target/tcm_mod_builder.py |1 - drivers/infiniband/ulp/srpt/ib_srpt.c|1 - drivers/scsi/qla2xxx/tcm_qla2xxx.c |7 + drivers/target/iscsi/iscsi_target_configfs.c |2 - drivers/target/sbp/sbp_target.c |4 --- drivers/target/target_core_internal.h| 22 - drivers/target/target_core_pr.c | 24 ++ drivers/target/target_core_tpg.c | 34 + drivers/target/target_core_transport.c | 12 ++--- drivers/target/tcm_fc/tfc_conf.c |1 - drivers/usb/gadget/tcm_usb_gadget.c |3 -- drivers/vhost/scsi.c |3 -- include/target/target_core_base.h|3 +- 13 files changed, 41 insertions(+), 76 deletions(-) diff --git a/Documentation/target/tcm_mod_builder.py b/Documentation/target/tcm_mod_builder.py index 230ce71..c8e0572 100755 --- a/Documentation/target/tcm_mod_builder.py +++ b/Documentation/target/tcm_mod_builder.py @@ -285,7 +285,6 @@ def tcm_mod_build_configfs(proto_ident, fabric_mod_dir_var, fabric_mod_name): buf += struct + fabric_mod_name + _nacl *nacl = container_of(se_acl,\n buf += struct + fabric_mod_name + _nacl, se_node_acl);\n buf += core_tpg_del_initiator_node_acl(se_acl-se_tpg, se_acl, 1);\n - buf += kfree(nacl);\n buf += }\n\n buf += static struct se_portal_group * + fabric_mod_name + _make_tpg(\n diff --git a/drivers/infiniband/ulp/srpt/ib_srpt.c b/drivers/infiniband/ulp/srpt/ib_srpt.c index 520a7e5..4995b91 100644 --- a/drivers/infiniband/ulp/srpt/ib_srpt.c +++ b/drivers/infiniband/ulp/srpt/ib_srpt.c @@ -3645,7 +3645,6 @@ static void srpt_drop_nodeacl(struct se_node_acl *se_nacl) list_del(nacl-list); spin_unlock_irq(sport-port_acl_lock); core_tpg_del_initiator_node_acl(sport-port_tpg_1, se_nacl, 1); - srpt_release_fabric_acl(NULL, se_nacl); } static ssize_t srpt_tpg_attrib_show_srp_max_rdma_size( diff --git a/drivers/scsi/qla2xxx/tcm_qla2xxx.c b/drivers/scsi/qla2xxx/tcm_qla2xxx.c index 7eb19be..4fe684a 100644 --- a/drivers/scsi/qla2xxx/tcm_qla2xxx.c +++ b/drivers/scsi/qla2xxx/tcm_qla2xxx.c @@ -828,12 +828,7 @@ static struct se_node_acl *tcm_qla2xxx_make_nodeacl( static void tcm_qla2xxx_drop_nodeacl(struct se_node_acl *se_acl) { - struct se_portal_group *se_tpg = se_acl-se_tpg; - struct tcm_qla2xxx_nacl *nacl = container_of(se_acl, - struct tcm_qla2xxx_nacl, se_node_acl); - - core_tpg_del_initiator_node_acl(se_tpg, se_acl, 1); - kfree(nacl); + core_tpg_del_initiator_node_acl(se_acl-se_tpg, se_acl, 1); } /* Start items for tcm_qla2xxx_tpg_attrib_cit */ diff --git a/drivers/target/iscsi/iscsi_target_configfs.c b/drivers/target/iscsi/iscsi_target_configfs.c index e3318ed..bd05ab5 100644 --- a/drivers/target/iscsi/iscsi_target_configfs.c +++ b/drivers/target/iscsi/iscsi_target_configfs.c @@ -916,7 +916,6 @@ static struct se_node_acl *lio_target_make_nodeacl( pr_err(Unable to allocate memory for stats_cg-default_groups\n); core_tpg_del_initiator_node_acl(se_tpg, se_nacl, 1); - kfree(acl); return ERR_PTR(-ENOMEM); } @@ -947,7 +946,6 @@ static void lio_target_drop_nodeacl( kfree(stats_cg-default_groups); core_tpg_del_initiator_node_acl(se_tpg, se_nacl, 1); - kfree(acl); } /* End items for lio_target_acl_cit */ diff --git a/drivers/target/sbp/sbp_target.c b/drivers/target/sbp/sbp_target.c index 103998c..6fabd9c 100644 --- a/drivers/target/sbp/sbp_target.c +++ b/drivers/target/sbp/sbp_target.c @@ -2126,11 +2126,7 @@ static struct se_node_acl *sbp_make_nodeacl( static void sbp_drop_nodeacl(struct se_node_acl *se_acl) { - struct sbp_nacl *nacl = - container_of(se_acl, struct sbp_nacl, se_node_acl); - core_tpg_del_initiator_node_acl(se_acl-se_tpg, se_acl, 1); - kfree(nacl); } static int sbp_post_link_lun( diff --git a/drivers/target/target_core_internal.h b/drivers/target/target_core_internal.h index 5b232a7..65a4de9 100644 --- a/drivers/target/target_core_internal.h +++ b/drivers/target/target_core_internal.h @@ -82,10 +82,11 @@ int core_tmr_lun_reset(struct se_device *, struct se_tmr_req *, /* target_core_tpg.c */ extern struct se_device *g_lun0_dev; +void core_clear_initiator_node_from_tpg(struct se_node_acl *, +
Re: [PATCH 29/32] target: Simplify params to core_tpg_del_initiator_node_acl
On Fri, 2013-12-13 at 15:59 -0800, Andy Grover wrote: 'force' parameter is not used. tpg parameter is not needed, since we have acl-se_tpg. Signed-off-by: Andy Grover agro...@redhat.com --- Documentation/target/tcm_mod_builder.py |2 +- drivers/infiniband/ulp/srpt/ib_srpt.c|2 +- drivers/scsi/qla2xxx/tcm_qla2xxx.c |2 +- drivers/target/iscsi/iscsi_target_configfs.c |5 ++--- drivers/target/sbp/sbp_target.c |2 +- drivers/target/target_core_tpg.c |6 ++ drivers/target/tcm_fc/tfc_conf.c |2 +- drivers/usb/gadget/tcm_usb_gadget.c |2 +- drivers/vhost/scsi.c |2 +- include/target/target_core_fabric.h |3 +-- 10 files changed, 12 insertions(+), 16 deletions(-) I'm OK to take this one, but it does not apply without #28. --nab diff --git a/Documentation/target/tcm_mod_builder.py b/Documentation/target/tcm_mod_builder.py index c8e0572..bfebc66 100755 --- a/Documentation/target/tcm_mod_builder.py +++ b/Documentation/target/tcm_mod_builder.py @@ -284,7 +284,7 @@ def tcm_mod_build_configfs(proto_ident, fabric_mod_dir_var, fabric_mod_name): buf += {\n buf += struct + fabric_mod_name + _nacl *nacl = container_of(se_acl,\n buf += struct + fabric_mod_name + _nacl, se_node_acl);\n - buf += core_tpg_del_initiator_node_acl(se_acl-se_tpg, se_acl, 1);\n + buf += core_tpg_del_initiator_node_acl(se_acl);\n buf += }\n\n buf += static struct se_portal_group * + fabric_mod_name + _make_tpg(\n diff --git a/drivers/infiniband/ulp/srpt/ib_srpt.c b/drivers/infiniband/ulp/srpt/ib_srpt.c index 4995b91..7a23e75 100644 --- a/drivers/infiniband/ulp/srpt/ib_srpt.c +++ b/drivers/infiniband/ulp/srpt/ib_srpt.c @@ -3644,7 +3644,7 @@ static void srpt_drop_nodeacl(struct se_node_acl *se_nacl) spin_lock_irq(sport-port_acl_lock); list_del(nacl-list); spin_unlock_irq(sport-port_acl_lock); - core_tpg_del_initiator_node_acl(sport-port_tpg_1, se_nacl, 1); + core_tpg_del_initiator_node_acl(se_nacl); } static ssize_t srpt_tpg_attrib_show_srp_max_rdma_size( diff --git a/drivers/scsi/qla2xxx/tcm_qla2xxx.c b/drivers/scsi/qla2xxx/tcm_qla2xxx.c index 4fe684a..05967eb 100644 --- a/drivers/scsi/qla2xxx/tcm_qla2xxx.c +++ b/drivers/scsi/qla2xxx/tcm_qla2xxx.c @@ -828,7 +828,7 @@ static struct se_node_acl *tcm_qla2xxx_make_nodeacl( static void tcm_qla2xxx_drop_nodeacl(struct se_node_acl *se_acl) { - core_tpg_del_initiator_node_acl(se_acl-se_tpg, se_acl, 1); + core_tpg_del_initiator_node_acl(se_acl); } /* Start items for tcm_qla2xxx_tpg_attrib_cit */ diff --git a/drivers/target/iscsi/iscsi_target_configfs.c b/drivers/target/iscsi/iscsi_target_configfs.c index bd05ab5..3bc1443 100644 --- a/drivers/target/iscsi/iscsi_target_configfs.c +++ b/drivers/target/iscsi/iscsi_target_configfs.c @@ -915,7 +915,7 @@ static struct se_node_acl *lio_target_make_nodeacl( if (!stats_cg-default_groups) { pr_err(Unable to allocate memory for stats_cg-default_groups\n); - core_tpg_del_initiator_node_acl(se_tpg, se_nacl, 1); + core_tpg_del_initiator_node_acl(se_nacl); return ERR_PTR(-ENOMEM); } @@ -930,7 +930,6 @@ static struct se_node_acl *lio_target_make_nodeacl( static void lio_target_drop_nodeacl( struct se_node_acl *se_nacl) { - struct se_portal_group *se_tpg = se_nacl-se_tpg; struct iscsi_node_acl *acl = container_of(se_nacl, struct iscsi_node_acl, se_node_acl); struct config_item *df_item; @@ -945,7 +944,7 @@ static void lio_target_drop_nodeacl( } kfree(stats_cg-default_groups); - core_tpg_del_initiator_node_acl(se_tpg, se_nacl, 1); + core_tpg_del_initiator_node_acl(se_nacl); } /* End items for lio_target_acl_cit */ diff --git a/drivers/target/sbp/sbp_target.c b/drivers/target/sbp/sbp_target.c index 6fabd9c..1078ee6 100644 --- a/drivers/target/sbp/sbp_target.c +++ b/drivers/target/sbp/sbp_target.c @@ -2126,7 +2126,7 @@ static struct se_node_acl *sbp_make_nodeacl( static void sbp_drop_nodeacl(struct se_node_acl *se_acl) { - core_tpg_del_initiator_node_acl(se_acl-se_tpg, se_acl, 1); + core_tpg_del_initiator_node_acl(se_acl); } static int sbp_post_link_lun( diff --git a/drivers/target/target_core_tpg.c b/drivers/target/target_core_tpg.c index 6aaf50f..1233d04 100644 --- a/drivers/target/target_core_tpg.c +++ b/drivers/target/target_core_tpg.c @@ -402,13 +402,11 @@ EXPORT_SYMBOL(core_tpg_add_initiator_node_acl); * * */ -int core_tpg_del_initiator_node_acl( - struct se_portal_group *tpg, - struct se_node_acl *acl, - int force) +int
Re: [PATCH 30/32] target: Change nacl's session refcount to use existing refcount
On Fri, 2013-12-13 at 15:59 -0800, Andy Grover wrote: core_tpg_del_initiator_node_acl is now safe to call with spinlocks, since it no longer potentially sleeps. Signed-off-by: Andy Grover agro...@redhat.com --- drivers/target/target_core_tpg.c | 10 -- drivers/target/target_core_transport.c | 17 ++--- include/target/target_core_base.h |2 -- include/target/target_core_fabric.h|1 - 4 files changed, 2 insertions(+), 28 deletions(-) Ignoring, given the other NAKs. --nab diff --git a/drivers/target/target_core_tpg.c b/drivers/target/target_core_tpg.c index 1233d04..30af019 100644 --- a/drivers/target/target_core_tpg.c +++ b/drivers/target/target_core_tpg.c @@ -247,8 +247,6 @@ struct se_node_acl *core_tpg_check_initiator_node_acl( INIT_LIST_HEAD(acl-acl_node); INIT_LIST_HEAD(acl-acl_sess_list); - kref_init(acl-acl_kref); - init_completion(acl-acl_free_comp); spin_lock_init(acl-device_list_lock); spin_lock_init(acl-nacl_sess_lock); kref_init(acl-refcount); @@ -363,8 +361,6 @@ struct se_node_acl *core_tpg_add_initiator_node_acl( INIT_LIST_HEAD(acl-acl_node); INIT_LIST_HEAD(acl-acl_sess_list); - kref_init(acl-acl_kref); - init_completion(acl-acl_free_comp); spin_lock_init(acl-device_list_lock); spin_lock_init(acl-nacl_sess_lock); kref_init(acl-refcount); @@ -440,12 +436,6 @@ int core_tpg_del_initiator_node_acl(struct se_node_acl *acl) continue; target_put_session(sess); } - target_put_nacl(acl); - /* - * Wait for last target_put_nacl() to complete in target_complete_nacl() - * for active fabric session transport_deregister_session() callbacks. - */ - wait_for_completion(acl-acl_free_comp); put_nacl(acl); diff --git a/drivers/target/target_core_transport.c b/drivers/target/target_core_transport.c index 51e294b..e5e054e 100644 --- a/drivers/target/target_core_transport.c +++ b/drivers/target/target_core_transport.c @@ -311,7 +311,7 @@ void __transport_register_session( buf[0], PR_REG_ISID_LEN); se_sess-sess_bin_isid = get_unaligned_be64(buf[0]); } - kref_get(se_nacl-acl_kref); + get_nacl(se_nacl); spin_lock_irq(se_nacl-nacl_sess_lock); /* @@ -372,19 +372,6 @@ void target_put_session(struct se_session *se_sess) } EXPORT_SYMBOL(target_put_session); -static void target_complete_nacl(struct kref *kref) -{ - struct se_node_acl *nacl = container_of(kref, - struct se_node_acl, acl_kref); - - complete(nacl-acl_free_comp); -} - -void target_put_nacl(struct se_node_acl *nacl) -{ - kref_put(nacl-acl_kref, target_complete_nacl); -} - void transport_deregister_session_configfs(struct se_session *se_sess) { struct se_node_acl *se_nacl; @@ -471,7 +458,7 @@ void transport_deregister_session(struct se_session *se_sess) * removal context. */ if (se_nacl) - target_put_nacl(se_nacl); + put_nacl(se_nacl); transport_free_session(se_sess); } diff --git a/include/target/target_core_base.h b/include/target/target_core_base.h index 393bcfd..08ecfed 100644 --- a/include/target/target_core_base.h +++ b/include/target/target_core_base.h @@ -527,8 +527,6 @@ struct se_node_acl { struct config_group *acl_default_groups[5]; struct list_headacl_node; struct list_headacl_sess_list; - struct completion acl_free_comp; - struct kref acl_kref; }; struct se_session { diff --git a/include/target/target_core_fabric.h b/include/target/target_core_fabric.h index 35a77af..c6b9303 100644 --- a/include/target/target_core_fabric.h +++ b/include/target/target_core_fabric.h @@ -94,7 +94,6 @@ voidtransport_register_session(struct se_portal_group *, void target_get_session(struct se_session *); void target_put_session(struct se_session *); void transport_free_session(struct se_session *); -void target_put_nacl(struct se_node_acl *); void transport_deregister_session_configfs(struct se_session *); void transport_deregister_session(struct se_session *); -- 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 31/32] target: Don't release and re-acquire some spinlocks in loops
On Fri, 2013-12-13 at 15:59 -0800, Andy Grover wrote: Here are some instances where we're looping, but then dropping the spinlock around the loop in the loop, because we need to be able to sleep in the calls. Since everything is refcounted now, this should no longer be needed and we can just hold the locks the whole time. Signed-off-by: Andy Grover agro...@redhat.com --- drivers/target/target_core_device.c |4 drivers/target/target_core_tpg.c|5 - 2 files changed, 0 insertions(+), 9 deletions(-) Ignoring, given the other NAKs. --nab diff --git a/drivers/target/target_core_device.c b/drivers/target/target_core_device.c index a432d7b..3896c99 100644 --- a/drivers/target/target_core_device.c +++ b/drivers/target/target_core_device.c @@ -463,7 +463,6 @@ void core_clear_lun_from_tpg(struct se_lun *lun, struct se_portal_group *tpg) spin_lock_irq(tpg-acl_node_lock); list_for_each_entry(nacl, tpg-acl_node_list, acl_node) { - spin_unlock_irq(tpg-acl_node_lock); spin_lock_irq(nacl-device_list_lock); rbtree_postorder_for_each_entry_safe(deve, _tmp, nacl-rb_device_list, rb_node) { @@ -473,7 +472,6 @@ void core_clear_lun_from_tpg(struct se_lun *lun, struct se_portal_group *tpg) } spin_unlock_irq(nacl-device_list_lock); - spin_lock_irq(tpg-acl_node_lock); } spin_unlock_irq(tpg-acl_node_lock); } @@ -1141,9 +1139,7 @@ int core_dev_add_lun( if (acl-dynamic_node_acl (!tpg-se_tpg_tfo-tpg_check_demo_mode_login_only || !tpg-se_tpg_tfo-tpg_check_demo_mode_login_only(tpg))) { - spin_unlock_irq(tpg-acl_node_lock); core_tpg_add_node_to_devs(acl, tpg); - spin_lock_irq(tpg-acl_node_lock); } } spin_unlock_irq(tpg-acl_node_lock); diff --git a/drivers/target/target_core_tpg.c b/drivers/target/target_core_tpg.c index 30af019..1bcb665 100644 --- a/drivers/target/target_core_tpg.c +++ b/drivers/target/target_core_tpg.c @@ -172,8 +172,6 @@ void core_tpg_add_node_to_devs( for (node = rb_first(tpg-rb_tpg_lun_list); node; node = rb_next(node)) { struct se_lun *lun = rb_entry(node, struct se_lun, rb_node); - spin_unlock(tpg-tpg_lun_lock); - dev = lun-lun_se_dev; /* * By default in LIO-Target $FABRIC_MOD, @@ -201,7 +199,6 @@ void core_tpg_add_node_to_devs( core_enable_device_list_for_node(lun, NULL, lun-unpacked_lun, lun_access, acl, tpg); - spin_lock(tpg-tpg_lun_lock); } spin_unlock(tpg-tpg_lun_lock); } @@ -299,9 +296,7 @@ void core_tpg_clear_object_luns(struct se_portal_group *tpg) if (!lun-lun_se_dev) continue; - spin_unlock(tpg-tpg_lun_lock); core_dev_del_lun(tpg, lun); - spin_lock(tpg-tpg_lun_lock); } spin_unlock(tpg-tpg_lun_lock); } -- 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 0/32] Refcounts and rbtrees to increase luns above 255
On Fri, 2013-12-13 at 15:58 -0800, Andy Grover wrote: Hi Nicholas, This patchset uses krefs to refcount structures shared across threads. LIO is full of these because configfs-based configuration actions can be removing an object, even while that object is being used by a SCSI command. Using kref to free the struct on whichever thread drops the last reference allows us to avoid busy-waiting in configfs removal functions. Next, this set removes the statically-sized tpg lun and deve arrays in favor of dynamically adding entries into rbtrees. This reduces memory consumption and allows more than 255 luns per tpg and initiator mapping. Except for some rbtree lookups, these changes are entirely in the configuration paths of Lio. I have tested these as extensively as I can, and it's ready for wider testing. Note: patch 22 converts a percpu refcount to a normal kref. I'd argue the benefit is really in the refcount part rather than the percpu, so a simpler kref does the job, but we might want to discuss this some more. It would be helpful to breakup future patches into different series based on: * Bugfixes * New features * Minor improvements Thanks, --nab -- 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 32/32] target: Increase MAX_LUNS_PER_TPG to 16384
On Fri, 2013-12-13 at 15:59 -0800, Andy Grover wrote: Indicate support for hierarchical LUN addressing. Set address method field in each LUN reported by REPORT LUNS to 1, in accordance with SCSI SAM specs. Signed-off-by: Andy Grover agro...@redhat.com --- drivers/target/target_core_spc.c |8 ++-- include/target/target_core_base.h |4 ++-- 2 files changed, 8 insertions(+), 4 deletions(-) And ignoring, given the other NAKs. --nab diff --git a/drivers/target/target_core_spc.c b/drivers/target/target_core_spc.c index 0b678fc..04690bf 100644 --- a/drivers/target/target_core_spc.c +++ b/drivers/target/target_core_spc.c @@ -79,7 +79,7 @@ spc_emulate_inquiry_std(struct se_cmd *cmd, unsigned char *buf) buf[2] = 0x05; /* SPC-3 */ /* - * NORMACA and HISUP = 0, RESPONSE DATA FORMAT = 2 + * NORMACA = 0, HISUP = 1, RESPONSE DATA FORMAT = 2 * * SPC4 says: * A RESPONSE DATA FORMAT field set to 2h indicates that the @@ -88,7 +88,7 @@ spc_emulate_inquiry_std(struct se_cmd *cmd, unsigned char *buf) * obsolete. Response data format values greater than 2h are * reserved. */ - buf[3] = 2; + buf[3] = 0x12; /* * Enable SCCS and TPGS fields for Emulated ALUA @@ -1164,6 +1164,10 @@ sense_reason_t spc_emulate_report_luns(struct se_cmd *cmd) break; int_to_scsilun(deve-mapped_lun, (struct scsi_lun *)buf[offset]); + + /* Address method 1 for hier flat-space address. see SAM-5 */ + buf[offset] |= (1 6); + offset += 8; } spin_unlock_irq(sess-se_node_acl-device_list_lock); diff --git a/include/target/target_core_base.h b/include/target/target_core_base.h index 08ecfed..537cc67 100644 --- a/include/target/target_core_base.h +++ b/include/target/target_core_base.h @@ -14,8 +14,8 @@ #define TARGET_CORE_VERSION TARGET_CORE_MOD_VERSION /* Maximum Number of LUNs per Target Portal Group */ -/* Don't raise above 511 or REPORT_LUNS needs to handle 1 page */ -#define TRANSPORT_MAX_LUNS_PER_TPG 256 +/* Don't raise above 16384 or a different format in report_luns is needed */ +#define TRANSPORT_MAX_LUNS_PER_TPG 16384 /* * By default we use 32-byte CDBs in TCM Core and subsystem plugin code. * -- 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
[PATCH 0/6] Let sleeping disks lie
This is the set I currently have. I fixed libata to implement the REQUEST SENSE scsi command, and set up sd to use blk_pre_runtime_suspend to force the queue to the RPM_SUSPENDING state while issuing the REQUEST SENSE command to make sure other requests are blocked, then if REQUEST SENSE indicates that the drive does not need started, then complete suspending the device, otherwise cancel the suspend by passing an error value to blk_post_runtime_suspend. For some reason, the system hangs on resume if I issue the REQUEST SENSE command after blk_pre_runtime_suspend. My understanding is that the REQ_PM flag should make the command process even though the queue is RPM_SUSPENDING, but it doesn't seem to work. Anyone have any idea why? Phillip Susi (6): libata: use sleep instead of standby command libata: avoid waking disk for several commands libata: resume in the background libata: don't start disks on resume sd: don't start disks on system resume libata: return power status in REQUEST SENSE command drivers/ata/libata-core.c | 38 +++ drivers/ata/libata-eh.c | 10 - drivers/ata/libata-scsi.c | 44 ++ drivers/ata/libata.h | 1 + drivers/scsi/sd.c | 94 ++- drivers/scsi/sd.h | 1 + include/linux/libata.h| 1 + 7 files changed, 162 insertions(+), 27 deletions(-) -- 1.8.3.2 -- 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
[PATCH 3/6] libata: resume in the background
Don't block the resume path waiting for the disk to spin up. --- drivers/ata/libata-core.c | 10 -- 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/drivers/ata/libata-core.c b/drivers/ata/libata-core.c index 8f856bb..4a28caf 100644 --- a/drivers/ata/libata-core.c +++ b/drivers/ata/libata-core.c @@ -5430,20 +5430,18 @@ static int __ata_port_resume_common(struct ata_port *ap, pm_message_t mesg, static int ata_port_resume_common(struct device *dev, pm_message_t mesg) { struct ata_port *ap = to_ata_port(dev); + static int dontcare; - return __ata_port_resume_common(ap, mesg, NULL); + return __ata_port_resume_common(ap, mesg, dontcare); } static int ata_port_resume(struct device *dev) { int rc; + if (pm_runtime_suspended(dev)) + return 0; rc = ata_port_resume_common(dev, PMSG_RESUME); - if (!rc) { - pm_runtime_disable(dev); - pm_runtime_set_active(dev); - pm_runtime_enable(dev); - } return rc; } -- 1.8.3.2 -- 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
[PATCH 4/6] libata: don't start disks on resume
Disks with Power Up In Standby enabled that required the SET FEATURES command to start up were being issued the command during resume. Suppress this until the disk is actually accessed. --- drivers/ata/libata-core.c | 12 ++-- drivers/ata/libata-eh.c | 10 -- drivers/ata/libata.h | 1 + include/linux/libata.h| 1 + 4 files changed, 20 insertions(+), 4 deletions(-) diff --git a/drivers/ata/libata-core.c b/drivers/ata/libata-core.c index 4a28caf..c9a1fa5a 100644 --- a/drivers/ata/libata-core.c +++ b/drivers/ata/libata-core.c @@ -1993,7 +1993,13 @@ retry: goto err_out; } - if (!tried_spinup (id[2] == 0x37c8 || id[2] == 0x738c)) { + if (flags ATA_READID_NOSTART id[2] == 0x37c8) + { + dev-flags |= ATA_DFLAG_SLEEPING; + return -EAGAIN; + } + if (!(flags ATA_READID_NOSTART) + !tried_spinup (id[2] == 0x37c8 || id[2] == 0x738c)) { tried_spinup = 1; /* * Drive powered-up in standby mode, and requires a specific @@ -4024,6 +4030,8 @@ int ata_dev_revalidate(struct ata_device *dev, unsigned int new_class, /* re-read ID */ rc = ata_dev_reread_id(dev, readid_flags); + if (rc == -EAGAIN) + return rc; if (rc) goto fail; @@ -5423,7 +5431,7 @@ static int __ata_port_resume_common(struct ata_port *ap, pm_message_t mesg, int rc; rc = ata_port_request_pm(ap, mesg, ATA_EH_RESET, - ATA_EHI_NO_AUTOPSY | ATA_EHI_QUIET, async); + ATA_EHI_NO_AUTOPSY | ATA_EHI_QUIET | ATA_EHI_NOSTART, async); return rc; } diff --git a/drivers/ata/libata-eh.c b/drivers/ata/libata-eh.c index 92d7797..0147b0d 100644 --- a/drivers/ata/libata-eh.c +++ b/drivers/ata/libata-eh.c @@ -3094,6 +3094,8 @@ static int ata_eh_revalidate_and_attach(struct ata_link *link, if (ehc-i.flags ATA_EHI_DID_RESET) readid_flags |= ATA_READID_POSTRESET; + if (ehc-i.flags ATA_EHI_NOSTART) + readid_flags |= ATA_READID_NOSTART; if ((action ATA_EH_REVALIDATE) ata_dev_enabled(dev)) { WARN_ON(dev-class == ATA_DEV_PMP); @@ -3106,6 +3108,10 @@ static int ata_eh_revalidate_and_attach(struct ata_link *link, ata_eh_about_to_do(link, dev, ATA_EH_REVALIDATE); rc = ata_dev_revalidate(dev, ehc-classes[dev-devno], readid_flags); + if (rc == -EAGAIN) { + rc = 0; /* start required but suppressed, handle later */ + continue; + } if (rc) goto err; @@ -3432,7 +3438,7 @@ static int ata_eh_set_lpm(struct ata_link *link, enum ata_lpm_policy policy, hints = ~ATA_LPM_HIPM; /* disable DIPM before changing link config */ - if (policy != ATA_LPM_MIN_POWER dipm) { + if (policy != ATA_LPM_MIN_POWER dipm !(dev-flags ATA_DFLAG_SLEEPING)) { err_mask = ata_dev_set_feature(dev, SETFEATURES_SATA_DISABLE, SATA_DIPM); if (err_mask err_mask != AC_ERR_DEV) { @@ -3476,7 +3482,7 @@ static int ata_eh_set_lpm(struct ata_link *link, enum ata_lpm_policy policy, /* host config updated, enable DIPM if transitioning to MIN_POWER */ ata_for_each_dev(dev, link, ENABLED) { if (policy == ATA_LPM_MIN_POWER !no_dipm - ata_id_has_dipm(dev-id)) { + ata_id_has_dipm(dev-id) !(dev-flags ATA_DFLAG_SLEEPING)) { err_mask = ata_dev_set_feature(dev, SETFEATURES_SATA_ENABLE, SATA_DIPM); if (err_mask err_mask != AC_ERR_DEV) { diff --git a/drivers/ata/libata.h b/drivers/ata/libata.h index 45b5ab3..8939345 100644 --- a/drivers/ata/libata.h +++ b/drivers/ata/libata.h @@ -42,6 +42,7 @@ struct ata_scsi_args { enum { /* flags for ata_dev_read_id() */ ATA_READID_POSTRESET= (1 0), /* reading ID after reset */ + ATA_READID_NOSTART = (1 1), /* do not start drive */ /* selector for ata_down_xfermask_limit() */ ATA_DNXFER_PIO = 0,/* speed down PIO */ diff --git a/include/linux/libata.h b/include/linux/libata.h index 0e23c26..3929bb8 100644 --- a/include/linux/libata.h +++ b/include/linux/libata.h @@ -362,6 +362,7 @@ enum { /* ata_eh_info-flags */ ATA_EHI_HOTPLUGGED = (1 0), /* could have been hotplugged */ + ATA_EHI_NOSTART = (1 1), /* don't start the disk */ ATA_EHI_NO_AUTOPSY = (1 2), /* no autopsy */ ATA_EHI_QUIET
[PATCH 1/6] libata: use sleep instead of standby command
The ATA SLEEP mode saves some more power than SUSPEND, and has basically the same recovery time, so use it instead. --- drivers/ata/libata-scsi.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/ata/libata-scsi.c b/drivers/ata/libata-scsi.c index db6dfcf..f92eb21 100644 --- a/drivers/ata/libata-scsi.c +++ b/drivers/ata/libata-scsi.c @@ -1362,8 +1362,8 @@ static unsigned int ata_scsi_start_stop_xlat(struct ata_queued_cmd *qc) system_entering_hibernation()) goto skip; - /* Issue ATA STANDBY IMMEDIATE command */ - tf-command = ATA_CMD_STANDBYNOW1; + /* Issue ATA SLEEP command */ + tf-command = ATA_CMD_SLEEP; } /* -- 1.8.3.2 -- 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
[PATCH 2/6] libata: avoid waking disk for several commands
When a disk is in SLEEP mode it can not respond to any commands. Instead of waking up the sleeping disk, fake the commands. The commands include: CHECK POWER FLUSH CACHE SLEEP STANDBY IMMEDIATE IDENTIFY If we konw the disk is sleeping, we don't need to wake it up to to find out if it is in standby, so just pretend it is in standby. While alseep, there's no dirty pages in the cache, so there's no need to flush it. There's no point in waking a disk from sleep just to put it back to sleep. We also have a cache of the IDENTIFY information so just return that instead of waking the disk. --- drivers/ata/libata-core.c | 16 1 file changed, 16 insertions(+) diff --git a/drivers/ata/libata-core.c b/drivers/ata/libata-core.c index 81a94a3..8f856bb 100644 --- a/drivers/ata/libata-core.c +++ b/drivers/ata/libata-core.c @@ -5085,6 +5085,22 @@ void ata_qc_issue(struct ata_queued_cmd *qc) /* if device is sleeping, schedule reset and abort the link */ if (unlikely(qc-dev-flags ATA_DFLAG_SLEEPING)) { + if (unlikely(qc-tf.command == ATA_CMD_CHK_POWER || +qc-tf.command == ATA_CMD_SLEEP || +qc-tf.command == ATA_CMD_FLUSH || +qc-tf.command == ATA_CMD_FLUSH_EXT || +qc-tf.command == ATA_CMD_STANDBYNOW1 || +(qc-tf.command == ATA_CMD_ID_ATA + !ata_tag_internal(qc-tag + { + /* fake reply to avoid waking drive */ + qc-flags = ~ATA_QCFLAG_RESULT_TF; + qc-result_tf.nsect = 0; + if (qc-tf.command == ATA_CMD_ID_ATA) + sg_copy_from_buffer(qc-sg, 1, qc-dev-id, 2 * ATA_ID_WORDS); + ata_qc_complete(qc); + return; + } link-eh_info.action |= ATA_EH_RESET; ata_ehi_push_desc(link-eh_info, waking up from sleep); ata_link_abort(link); -- 1.8.3.2 -- 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
[PATCH 5/6] sd: don't start disks on system resume
Instead of forcing a disk to start up with the START STOP UNIT command when the system resumes, let it stay asleep if runtime pm is enabled, and it will start the drive when it is accessed. Query the drive to see if it starts up on its own ( like most ATA disks do ) and update the runtime pm status if so. --- drivers/scsi/sd.c | 94 +-- drivers/scsi/sd.h | 1 + 2 files changed, 86 insertions(+), 9 deletions(-) diff --git a/drivers/scsi/sd.c b/drivers/scsi/sd.c index e6c4bff..98c082a 100644 --- a/drivers/scsi/sd.c +++ b/drivers/scsi/sd.c @@ -107,7 +107,8 @@ static int sd_remove(struct device *); static void sd_shutdown(struct device *); static int sd_suspend_system(struct device *); static int sd_suspend_runtime(struct device *); -static int sd_resume(struct device *); +static int sd_resume_system(struct device *); +static int sd_resume_runtime(struct device *dev); static void sd_rescan(struct device *); static int sd_done(struct scsi_cmnd *); static int sd_eh_action(struct scsi_cmnd *, unsigned char *, int, int); @@ -486,11 +487,11 @@ static struct class sd_disk_class = { static const struct dev_pm_ops sd_pm_ops = { .suspend= sd_suspend_system, - .resume = sd_resume, + .resume = sd_resume_system, .poweroff = sd_suspend_system, - .restore= sd_resume, + .restore= sd_resume_system, .runtime_suspend= sd_suspend_runtime, - .runtime_resume = sd_resume, + .runtime_resume = sd_resume_runtime, }; static struct scsi_driver sd_template = { @@ -3166,22 +3167,97 @@ static int sd_suspend_runtime(struct device *dev) return sd_suspend_common(dev, false); } -static int sd_resume(struct device *dev) +static int sd_resume_runtime(struct device *dev) { struct scsi_disk *sdkp = scsi_disk_get_from_dev(dev); int ret = 0; - if (!sdkp-device-manage_start_stop) - goto done; - sd_printk(KERN_NOTICE, sdkp, Starting disk\n); + dump_stack(); ret = sd_start_stop_device(sdkp, 1); -done: scsi_disk_put(sdkp); return ret; } +#ifdef CONFIG_PM_RUNTIME +static void sd_resume_work(struct work_struct *work) +{ + struct scsi_disk *sdkp = container_of(work, struct scsi_disk, resume_work.work); + struct scsi_device *sdp = sdkp-device; + struct device *dev = sdkp-dev; + int res; + unsigned char cmd[10] = { 0 }; + struct scsi_sense_hdr sshdr; + const int timeout = sdp-request_queue-rq_timeout; + + cmd[0] = REQUEST_SENSE; + printk(KERN_NOTICE Requesting sense\n); + res = scsi_execute_req_flags(sdp, cmd, DMA_NONE, NULL, 0, +sshdr, timeout, SD_MAX_RETRIES, +NULL, REQ_PM); + if (res) { + sd_print_result(sdkp, res); + goto wakeup; + } + if (driver_byte(res) DRIVER_SENSE) + sd_print_sense_hdr(sdkp, sshdr); + /* we need to evaluate the error return */ + if (scsi_sense_valid(sshdr) + sshdr.sense_key == 0 + sshdr.asc == 0 + sshdr.ascq == 0) + goto wakeup; + + /* finalize suspend */ + printk(KERN_NOTICE Finalizing suspend\n); + pm_runtime_disable(dev); + pm_runtime_set_suspended(dev); + pm_runtime_enable(dev); + blk_post_runtime_suspend(sdp-request_queue, 0); + scsi_disk_put(sdkp); + return; + +wakeup: + /* abort suspend */ + sd_printk(KERN_NOTICE, sdkp, Activating disk %s\n, kobject_name(dev-kobj)); + blk_post_runtime_suspend(sdp-request_queue, -EBUSY); + scsi_disk_put(sdkp); +} +#endif + + +static int sd_resume_system(struct device *dev) +{ + struct scsi_disk *sdkp; +#ifdef CONFIG_PM_RUNTIME + struct scsi_device *sdp; + int ret = 0; + + sdkp = scsi_disk_get_from_dev(dev); + sdp = sdkp-device; + if (!scsi_device_online(sdp)) + { + ret = -ENODEV; + goto err; + } + sd_printk(KERN_NOTICE, sdkp, Suspending disk\n); + /* force runtime pm status to suspending */ + blk_pre_runtime_suspend(sdp-request_queue); + execute_in_process_context(sd_resume_work, + sdkp-resume_work); + +err: + scsi_disk_put(sdkp); + return ret; +#else + if (sdkp-device-manage_start_stop) + return sd_resume_runtime(dev); + return 0; +#endif +} + + /** * init_sd - entry point for this driver (both when built in or when * a module). diff --git a/drivers/scsi/sd.h b/drivers/scsi/sd.h index 26895ff..0b8afb3 100644 --- a/drivers/scsi/sd.h +++ b/drivers/scsi/sd.h @@ -90,6 +90,7 @@ struct scsi_disk { unsignedlbpvpd : 1; unsignedws10 :
[PATCH 6/6] libata: return power status in REQUEST SENSE command
SAT-3 says REQUEST SENSE should issue CHECK POWER and return a sense status indicating the drive's power status. --- drivers/ata/libata-scsi.c | 40 ++-- 1 file changed, 34 insertions(+), 6 deletions(-) diff --git a/drivers/ata/libata-scsi.c b/drivers/ata/libata-scsi.c index f92eb21..8b17352 100644 --- a/drivers/ata/libata-scsi.c +++ b/drivers/ata/libata-scsi.c @@ -3313,6 +3313,38 @@ static unsigned int ata_scsi_mode_select_xlat(struct ata_queued_cmd *qc) return 1; } +static void ata_scsi_request_sense_complete(struct ata_queued_cmd *qc) +{ + struct scsi_cmnd *cmd = qc-scsicmd; + cmd-result = (DRIVER_SENSE 24); + if (qc-result_tf.nsect == 0) + /* POWER STATE CHANGE TO STANDBY */ + { + scsi_build_sense_buffer(0, cmd-sense_buffer, 0, 0x5E, 0x43); + } + else scsi_build_sense_buffer(0, cmd-sense_buffer, 0, 0, 0); + qc-scsidone(cmd); + ata_qc_free(qc); +} + +/** + * ata_scsi_request_sense_xlat - Simulate REQUEST SENSE command + * @qc: Storage for translated ATA taskfile + * + * Converts a REQUEST SENSE command to an ATA CHECK POWER MODE taskfile. + * + * LOCKING: + * spin_lock_irqsave(host lock) + */ +static unsigned int ata_scsi_request_sense_xlat(struct ata_queued_cmd *qc) +{ + qc-tf.command = ATA_CMD_CHK_POWER; + qc-flags |= ATA_QCFLAG_RESULT_TF; + qc-tf.protocol = ATA_PROT_NODATA; + qc-complete_fn = ata_scsi_request_sense_complete; + return 0; +} + /** * ata_get_xlat_func - check if SCSI to ATA translation is possible * @dev: ATA device @@ -3360,6 +3392,8 @@ static inline ata_xlat_func_t ata_get_xlat_func(struct ata_device *dev, u8 cmd) case START_STOP: return ata_scsi_start_stop_xlat; + case REQUEST_SENSE: + return ata_scsi_request_sense_xlat; } return NULL; @@ -3565,12 +3599,6 @@ void ata_scsi_simulate(struct ata_device *dev, struct scsi_cmnd *cmd) ata_scsi_rbuf_fill(args, ata_scsiop_report_luns); break; - case REQUEST_SENSE: - ata_scsi_set_sense(cmd, 0, 0, 0); - cmd-result = (DRIVER_SENSE 24); - cmd-scsi_done(cmd); - break; - /* if we reach this, then writeback caching is disabled, * turning this into a no-op. */ -- 1.8.3.2 -- 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 19/32] target: Convert to rbtree for se_dev_entry in se_node_acl
On 12/16/2013 01:40 PM, Nicholas A. Bellinger wrote: On Fri, 2013-12-13 at 15:59 -0800, Andy Grover wrote: Instead of an array, use a rbtree. Less memory use on average, and can allow 255 entries. We go from O(1) to O(log n) on lookups. If this shows up on profiling (it won't) then transition to other kernel lookup methods is straightforward from here. Ugh. There is no reason to be using rbtrees in a performance critical path here. The number of pointer lookups is what ends up hurting the most vs. a flat array, so given that 256 LUNs per endpoint is currently not an issue, and there is no hard limit on the number of endpoints with virtual addressing, I don't see the benefit of this patch. NAK. What does virtual addressing mean in this context? I'm not familiar -- so instead of reporting 257+ luns per tpg, it would get split up somehow? -- Andy -- 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 0/32] Refcounts and rbtrees to increase luns above 255
On 12/16/2013 02:03 PM, Nicholas A. Bellinger wrote: On Fri, 2013-12-13 at 15:58 -0800, Andy Grover wrote: Hi Nicholas, This patchset uses krefs to refcount structures shared across threads. LIO is full of these because configfs-based configuration actions can be removing an object, even while that object is being used by a SCSI command. Using kref to free the struct on whichever thread drops the last reference allows us to avoid busy-waiting in configfs removal functions. Next, this set removes the statically-sized tpg lun and deve arrays in favor of dynamically adding entries into rbtrees. This reduces memory consumption and allows more than 255 luns per tpg and initiator mapping. Except for some rbtree lookups, these changes are entirely in the configuration paths of Lio. I have tested these as extensively as I can, and it's ready for wider testing. Note: patch 22 converts a percpu refcount to a normal kref. I'd argue the benefit is really in the refcount part rather than the percpu, so a simpler kref does the job, but we might want to discuss this some more. It would be helpful to breakup future patches into different series based on: * Bugfixes * New features * Minor improvements Thanks for all the reviews. For the remaining changes, it'll be after the new year before a v2. I'm still hopeful we can work out the issues preventing the use of krefs. I'm somewhat surprised over the resistance to rbtrees. I guess I'll need to hold off on resubmitting that until I have some performance data on their effect. Regards -- Andy -- 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 19/32] target: Convert to rbtree for se_dev_entry in se_node_acl
On Mon, 2013-12-16 at 17:00 -0800, Andy Grover wrote: On 12/16/2013 01:40 PM, Nicholas A. Bellinger wrote: On Fri, 2013-12-13 at 15:59 -0800, Andy Grover wrote: Instead of an array, use a rbtree. Less memory use on average, and can allow 255 entries. We go from O(1) to O(log n) on lookups. If this shows up on profiling (it won't) then transition to other kernel lookup methods is straightforward from here. Ugh. There is no reason to be using rbtrees in a performance critical path here. The number of pointer lookups is what ends up hurting the most vs. a flat array, so given that 256 LUNs per endpoint is currently not an issue, and there is no hard limit on the number of endpoints with virtual addressing, I don't see the benefit of this patch. NAK. What does virtual addressing mean in this context? I'm not familiar -- so instead of reporting 257+ luns per tpg, it would get split up somehow? Virtual addressing meaning /sys/kernel/config/target/$FABRIC/$WWPN/ endpoints that are not tied to a specific hardware mapping, so any arbitrary number of $WWPNs can be created. Right now the only use-case where people are using more than a few dozen LUNs per endpoint is with non NPIV qla2xxx mode, where a single physical Fibre Channel WWPN is exporting 256-512 LUNs, with different per NodeACL LUN mappings for different initiators. With NPIV mode for qla2xxx (currently in development), the WWPN becomes virtualized like iSCSI, and a unsigned short about of virtual port addresses can be configured per physical FC port. --nab -- 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 0/32] Refcounts and rbtrees to increase luns above 255
On Mon, 2013-12-16 at 17:49 -0800, Andy Grover wrote: On 12/16/2013 02:03 PM, Nicholas A. Bellinger wrote: On Fri, 2013-12-13 at 15:58 -0800, Andy Grover wrote: Hi Nicholas, This patchset uses krefs to refcount structures shared across threads. LIO is full of these because configfs-based configuration actions can be removing an object, even while that object is being used by a SCSI command. Using kref to free the struct on whichever thread drops the last reference allows us to avoid busy-waiting in configfs removal functions. Next, this set removes the statically-sized tpg lun and deve arrays in favor of dynamically adding entries into rbtrees. This reduces memory consumption and allows more than 255 luns per tpg and initiator mapping. Except for some rbtree lookups, these changes are entirely in the configuration paths of Lio. I have tested these as extensively as I can, and it's ready for wider testing. Note: patch 22 converts a percpu refcount to a normal kref. I'd argue the benefit is really in the refcount part rather than the percpu, so a simpler kref does the job, but we might want to discuss this some more. It would be helpful to breakup future patches into different series based on: * Bugfixes * New features * Minor improvements Thanks for all the reviews. For the remaining changes, it'll be after the new year before a v2. I'm still hopeful we can work out the issues preventing the use of krefs. So I'd like to see krefs implemented for these cases, but the rub is that configfs_group_operations-drop_items() cannot return before the last reference has dropped. I'm somewhat surprised over the resistance to rbtrees. I guess I'll need to hold off on resubmitting that until I have some performance data on their effect. I do appreciate the effort, but the extra pointer chasing here makes rbtrees prohibitively expensive for fast past operations. --nab -- 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 0/32] Refcounts and rbtrees to increase luns above 255
On 12/16/2013 05:59 PM, Nicholas A. Bellinger wrote: I do appreciate the effort, but the extra pointer chasing here makes rbtrees prohibitively expensive for fast past operations. Hmm, were they actually implemented and tried at some point? -- 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 0/32] Refcounts and rbtrees to increase luns above 255
On Mon, 2013-12-16 at 18:03 -0800, Andy Grover wrote: On 12/16/2013 05:59 PM, Nicholas A. Bellinger wrote: I do appreciate the effort, but the extra pointer chasing here makes rbtrees prohibitively expensive for fast past operations. Hmm, were they actually implemented and tried at some point? This is based upon experiences with PCIe IOV addressing using rbtrees. --nab -- 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] virtio-scsi: Fix hotcpu_notifier use-after-free with virtscsi_freeze
Jason Wang jasow...@redhat.com writes: On 10/28/2013 04:01 PM, Asias He wrote: vqs are freed in virtscsi_freeze but the hotcpu_notifier is not unregistered. We will have a use-after-free usage when the notifier callback is called after virtscsi_freeze. Signed-off-by: Asias He as...@redhat.com Please include a Fixes: line, especially if you want the CC: stable. Thanks, Rusty. --- drivers/scsi/virtio_scsi.c | 15 ++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/drivers/scsi/virtio_scsi.c b/drivers/scsi/virtio_scsi.c index 74b88ef..b26f1a5 100644 --- a/drivers/scsi/virtio_scsi.c +++ b/drivers/scsi/virtio_scsi.c @@ -957,6 +957,10 @@ static void virtscsi_remove(struct virtio_device *vdev) #ifdef CONFIG_PM static int virtscsi_freeze(struct virtio_device *vdev) { +struct Scsi_Host *sh = virtio_scsi_host(vdev); +struct virtio_scsi *vscsi = shost_priv(sh); + +unregister_hotcpu_notifier(vscsi-nb); virtscsi_remove_vqs(vdev); return 0; } @@ -965,8 +969,17 @@ static int virtscsi_restore(struct virtio_device *vdev) { struct Scsi_Host *sh = virtio_scsi_host(vdev); struct virtio_scsi *vscsi = shost_priv(sh); +int err; + +err = virtscsi_init(vdev, vscsi); +if (err) +return err; + +err = register_hotcpu_notifier(vscsi-nb); +if (err) +vdev-config-del_vqs(vdev); -return virtscsi_init(vdev, vscsi); +return err; } #endif Ping. Rusty, could you please review and apply this patch? Thanks -- 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 16/20] qla2xxx: Simplyfy the ISPFX00 interrupt handler code for ISPFX00.
Hi Bart, Thanks for the feedback, I will be submitting the updated patches soon. Thanks, ~Saurav On 12/13/13 21:03, Saurav Kashyap wrote: [ ... ] Shouldn't the subject of this patch read Simplify instead of Simplyfy ? Bart. attachment: winmail.dat
[PATCH V2 01/20] qla2xxx: Add mutex around optrom calls to serialize accesses.
From: Chad Dupuis chad.dup...@qlogic.com Signed-off-by: Chad Dupuis chad.dup...@qlogic.com Signed-off-by: Saurav Kashyap saurav.kash...@qlogic.com --- drivers/scsi/qla2xxx/qla_attr.c | 61 ++ drivers/scsi/qla2xxx/qla_bsg.c | 12 ++- drivers/scsi/qla2xxx/qla_def.h |1 + drivers/scsi/qla2xxx/qla_os.c |1 + 4 files changed, 54 insertions(+), 21 deletions(-) diff --git a/drivers/scsi/qla2xxx/qla_attr.c b/drivers/scsi/qla2xxx/qla_attr.c index 570c7fc..aafc92f 100644 --- a/drivers/scsi/qla2xxx/qla_attr.c +++ b/drivers/scsi/qla2xxx/qla_attr.c @@ -241,12 +241,17 @@ qla2x00_sysfs_read_optrom(struct file *filp, struct kobject *kobj, struct scsi_qla_host *vha = shost_priv(dev_to_shost(container_of(kobj, struct device, kobj))); struct qla_hw_data *ha = vha-hw; + ssize_t rval = 0; if (ha-optrom_state != QLA_SREADING) return 0; - return memory_read_from_buffer(buf, count, off, ha-optrom_buffer, - ha-optrom_region_size); + mutex_lock(ha-optrom_mutex); + rval = memory_read_from_buffer(buf, count, off, ha-optrom_buffer, + ha-optrom_region_size); + mutex_unlock(ha-optrom_mutex); + + return rval; } static ssize_t @@ -265,7 +270,9 @@ qla2x00_sysfs_write_optrom(struct file *filp, struct kobject *kobj, if (off + count ha-optrom_region_size) count = ha-optrom_region_size - off; + mutex_lock(ha-optrom_mutex); memcpy(ha-optrom_buffer[off], buf, count); + mutex_unlock(ha-optrom_mutex); return count; } @@ -288,10 +295,10 @@ qla2x00_sysfs_write_optrom_ctl(struct file *filp, struct kobject *kobj, struct scsi_qla_host *vha = shost_priv(dev_to_shost(container_of(kobj, struct device, kobj))); struct qla_hw_data *ha = vha-hw; - uint32_t start = 0; uint32_t size = ha-optrom_size; int val, valid; + ssize_t rval = count; if (off) return -EINVAL; @@ -304,12 +311,14 @@ qla2x00_sysfs_write_optrom_ctl(struct file *filp, struct kobject *kobj, if (start ha-optrom_size) return -EINVAL; + mutex_lock(ha-optrom_mutex); switch (val) { case 0: if (ha-optrom_state != QLA_SREADING - ha-optrom_state != QLA_SWRITING) - return -EINVAL; - + ha-optrom_state != QLA_SWRITING) { + rval = -EINVAL; + goto out; + } ha-optrom_state = QLA_SWAITING; ql_dbg(ql_dbg_user, vha, 0x7061, @@ -320,8 +329,10 @@ qla2x00_sysfs_write_optrom_ctl(struct file *filp, struct kobject *kobj, ha-optrom_buffer = NULL; break; case 1: - if (ha-optrom_state != QLA_SWAITING) - return -EINVAL; + if (ha-optrom_state != QLA_SWAITING) { + rval = -EINVAL; + goto out; + } ha-optrom_region_start = start; ha-optrom_region_size = start + size ha-optrom_size ? @@ -335,13 +346,15 @@ qla2x00_sysfs_write_optrom_ctl(struct file *filp, struct kobject *kobj, (%x).\n, ha-optrom_region_size); ha-optrom_state = QLA_SWAITING; - return -ENOMEM; + rval = -ENOMEM; + goto out; } if (qla2x00_wait_for_hba_online(vha) != QLA_SUCCESS) { ql_log(ql_log_warn, vha, 0x7063, HBA not online, failing NVRAM update.\n); - return -EAGAIN; + rval = -EAGAIN; + goto out; } ql_dbg(ql_dbg_user, vha, 0x7064, @@ -353,8 +366,10 @@ qla2x00_sysfs_write_optrom_ctl(struct file *filp, struct kobject *kobj, ha-optrom_region_start, ha-optrom_region_size); break; case 2: - if (ha-optrom_state != QLA_SWAITING) - return -EINVAL; + if (ha-optrom_state != QLA_SWAITING) { + rval = -EINVAL; + goto out; + } /* * We need to be more restrictive on which FLASH regions are @@ -388,7 +403,8 @@ qla2x00_sysfs_write_optrom_ctl(struct file *filp, struct kobject *kobj, if (!valid) { ql_log(ql_log_warn, vha, 0x7065, Invalid start region 0x%x/0x%x.\n, start, size); - return -EINVAL; + rval = -EINVAL; + goto out; } ha-optrom_region_start = start; @@ -403,7 +419,8 @@
[PATCH V2 14/20] qla2xxx: Add changes in the IOCB structures to adjust driver source codes to ISPFX00 firmware spec.
From: Armen Baloyan armen.balo...@qlogic.com Signed-off-by: Armen Baloyan armen.balo...@qlogic.com Signed-off-by: Saurav Kashyap saurav.kash...@qlogic.com --- drivers/scsi/qla2xxx/qla_mr.c | 10 +- drivers/scsi/qla2xxx/qla_mr.h | 26 +- 2 files changed, 18 insertions(+), 18 deletions(-) diff --git a/drivers/scsi/qla2xxx/qla_mr.c b/drivers/scsi/qla2xxx/qla_mr.c index 893e56d..03e2050 100644 --- a/drivers/scsi/qla2xxx/qla_mr.c +++ b/drivers/scsi/qla2xxx/qla_mr.c @@ -2343,8 +2343,7 @@ qlafx00_ioctl_iosb_entry(scsi_qla_host_t *vha, struct req_que *req, fstatus.ioctl_flags = pkt-fw_iotcl_flags; fstatus.ioctl_data = pkt-dataword_r; fstatus.adapid = pkt-adapid; - fstatus.adapid_hi = pkt-adapid_hi; - fstatus.reserved_2 = pkt-reserved_1; + fstatus.reserved_2 = pkt-dataword_r_extra; fstatus.res_count = pkt-residuallen; fstatus.status = pkt-status; fstatus.seq_number = pkt-seq_no; @@ -3262,7 +3261,9 @@ qlafx00_start_scsi(srb_t *sp) memset(lcmd_pkt, 0, REQUEST_ENTRY_SIZE); lcmd_pkt.handle = MAKE_HANDLE(req-id, sp-handle); - lcmd_pkt.handle_hi = 0; + lcmd_pkt.reserved_0 = 0; + lcmd_pkt.port_path_ctrl = 0; + lcmd_pkt.reserved_1 = 0; lcmd_pkt.dseg_count = cpu_to_le16(tot_dsds); lcmd_pkt.tgt_idx = cpu_to_le16(sp-fcport-tgt_id); @@ -3342,8 +3343,7 @@ qlafx00_tm_iocb(srb_t *sp, struct tsk_mgmt_entry_fx00 *ptm_iocb) tm_iocb.entry_type = TSK_MGMT_IOCB_TYPE_FX00; tm_iocb.entry_count = 1; tm_iocb.handle = cpu_to_le32(MAKE_HANDLE(req-id, sp-handle)); - tm_iocb.handle_hi = 0; - tm_iocb.timeout = cpu_to_le16(qla2x00_get_async_timeout(vha) + 2); + tm_iocb.reserved_0 = 0; tm_iocb.tgt_id = cpu_to_le16(sp-fcport-tgt_id); tm_iocb.control_flags = cpu_to_le32(fxio-u.tmf.flags); if (tm_iocb.control_flags == cpu_to_le32((uint32_t)TCF_LUN_RESET)) { diff --git a/drivers/scsi/qla2xxx/qla_mr.h b/drivers/scsi/qla2xxx/qla_mr.h index 1e60ca2..3cf5ddc 100644 --- a/drivers/scsi/qla2xxx/qla_mr.h +++ b/drivers/scsi/qla2xxx/qla_mr.h @@ -22,13 +22,16 @@ struct cmd_type_7_fx00 { uint8_t entry_status; /* Entry Status. */ uint32_t handle;/* System handle. */ - uint32_t handle_hi; + uint8_t reserved_0; + uint8_t port_path_ctrl; + uint16_t reserved_1; __le16 tgt_idx; /* Target Idx. */ uint16_t timeout; /* Command timeout. */ __le16 dseg_count; /* Data segment count. */ - uint16_t scsi_rsp_dsd_len; + uint8_t scsi_rsp_dsd_len; + uint8_t reserved_2; struct scsi_lun lun;/* LUN (LE). */ @@ -55,7 +58,7 @@ struct sts_entry_fx00 { uint8_t entry_status; /* Entry Status. */ uint32_t handle;/* System handle. */ - uint32_t handle_hi; /* System handle. */ + uint32_t reserved_3;/* System handle. */ __le16 comp_status; /* Completion status. */ uint16_t reserved_0;/* OX_ID used by the firmware. */ @@ -78,7 +81,7 @@ struct sts_entry_fx00 { struct multi_sts_entry_fx00 { uint8_t entry_type; /* Entry type. */ - uint8_t sys_define; /* System defined. */ + uint8_t entry_count;/* Entry count. */ uint8_t handle_count; uint8_t entry_status; @@ -94,15 +97,13 @@ struct tsk_mgmt_entry_fx00 { __le32 handle; /* System handle. */ - uint32_t handle_hi; /* System handle. */ + uint32_t reserved_0; __le16 tgt_id; /* Target Idx. */ uint16_t reserved_1; - - uint16_t delay; /* Activity delay in seconds. */ - - __le16 timeout; /* Command timeout. */ + uint16_t reserved_3; + uint16_t reserved_4; struct scsi_lun lun;/* LUN (LE). */ @@ -120,13 +121,13 @@ struct abort_iocb_entry_fx00 { uint8_t entry_status; /* Entry Status. */ __le32 handle; /* System handle. */ - __le32 handle_hi; /* System handle. */ + __le32 reserved_0; __le16 tgt_id_sts; /* Completion status. */ __le16 options; __le32 abort_handle;/* System handle. */ - __le32 abort_handle_hi; /* System handle. */ + __le32 reserved_2; __le16 req_que_no; uint8_t reserved_1[38]; @@ -147,8 +148,7 @@ struct ioctl_iocb_entry_fx00 { __le32 dataword_r; /* Data word returned */ uint32_t adapid;/* Adapter ID */ - uint32_t adapid_hi; /* Adapter ID high */ - uint32_t reserved_1; + uint32_t dataword_r_extra; __le32
[PATCH V2 04/20] qla2xxx: Use proper message for Non owner reset ACK Timeout.
From: Atul Deshmukh atul.deshm...@qlogic.com Signed-off-by: Atul Deshmukh atul.deshm...@qlogic.com Signed-off-by: Saurav Kashyap saurav.kash...@qlogic.com --- drivers/scsi/qla2xxx/qla_nx2.c |4 ++-- 1 files changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/scsi/qla2xxx/qla_nx2.c b/drivers/scsi/qla2xxx/qla_nx2.c index b45f4d7..eda7787 100644 --- a/drivers/scsi/qla2xxx/qla_nx2.c +++ b/drivers/scsi/qla2xxx/qla_nx2.c @@ -1578,8 +1578,8 @@ qla8044_need_reset_handler(struct scsi_qla_host *vha) do { if (time_after_eq(jiffies, dev_init_timeout)) { ql_log(ql_log_info, vha, 0xb0c4, - %s: Non Reset owner DEV INIT - TIMEOUT!\n, __func__); + %s: Non Reset owner: + Reset Ack Timeout!\n, __func__); break; } -- 1.7.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
[PATCH V2 03/20] qla2xxx: Replace constant value for IOCTL IOCB abort execution status with a macro for ISPFX00.
From: Armen Baloyan armen.balo...@qlogic.com Signed-off-by: Armen Baloyan armen.balo...@qlogic.com Signed-off-by: Saurav Kashyap saurav.kash...@qlogic.com --- drivers/scsi/qla2xxx/qla_mr.c |3 ++- drivers/scsi/qla2xxx/qla_mr.h |3 +++ 2 files changed, 5 insertions(+), 1 deletions(-) diff --git a/drivers/scsi/qla2xxx/qla_mr.c b/drivers/scsi/qla2xxx/qla_mr.c index 6ca4807..7c7849d 100644 --- a/drivers/scsi/qla2xxx/qla_mr.c +++ b/drivers/scsi/qla2xxx/qla_mr.c @@ -2017,7 +2017,8 @@ qlafx00_fx_disc(scsi_qla_host_t *vha, fc_port_t *fcport, uint16_t fx_type) memcpy(vha-hw-gid_list, pinfo, QLAFX00_TGT_NODE_LIST_SIZE); } else if (fx_type == FXDISC_ABORT_IOCTL) fdisc-u.fxiocb.result = - (fdisc-u.fxiocb.result == cpu_to_le32(0x68)) ? + (fdisc-u.fxiocb.result == + cpu_to_le32(QLAFX00_IOCTL_ICOB_ABORT_SUCCESS)) ? cpu_to_le32(QLA_SUCCESS) : cpu_to_le32(QLA_FUNCTION_FAILED); rval = le32_to_cpu(fdisc-u.fxiocb.result); diff --git a/drivers/scsi/qla2xxx/qla_mr.h b/drivers/scsi/qla2xxx/qla_mr.h index 6cd7072..5f3ed8b 100644 --- a/drivers/scsi/qla2xxx/qla_mr.h +++ b/drivers/scsi/qla2xxx/qla_mr.h @@ -548,4 +548,7 @@ struct mr_data_fx00 { /* Max conncurrent IOs that can be queued */ #define QLAFX00_MAX_CANQUEUE 1024 +/* IOCTL IOCB abort success */ +#define QLAFX00_IOCTL_ICOB_ABORT_SUCCESS 0x68 + #endif -- 1.7.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
[PATCH V2 07/20] qla2xxx: Enable the Flash Access Control (FAC) mailbox command.
From: Joe Carnuccio joe.carnuc...@qlogic.com Signed-off-by: Joe Carnuccio joe.carnuc...@qlogic.com Signed-off-by: Saurav Kashyap saurav.kash...@qlogic.com --- drivers/scsi/qla2xxx/qla_init.c |5 + 1 files changed, 1 insertions(+), 4 deletions(-) diff --git a/drivers/scsi/qla2xxx/qla_init.c b/drivers/scsi/qla2xxx/qla_init.c index e7e5f4f..9b271cc 100644 --- a/drivers/scsi/qla2xxx/qla_init.c +++ b/drivers/scsi/qla2xxx/qla_init.c @@ -1718,9 +1718,6 @@ enable_82xx_npiv: spin_unlock_irqrestore(ha-hardware_lock, flags); } - if (IS_QLA83XX(ha)) - goto skip_fac_check; - if (rval == QLA_SUCCESS IS_FAC_REQUIRED(ha)) { uint32_t size; @@ -1733,7 +1730,7 @@ enable_82xx_npiv: Unsupported FAC firmware (%d.%02d.%02d).\n, ha-fw_major_version, ha-fw_minor_version, ha-fw_subminor_version); -skip_fac_check: + if (IS_QLA83XX(ha)) { ha-flags.fac_supported = 0; rval = QLA_SUCCESS; -- 1.7.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
[PATCH V2 19/20] qla2xxx: Fix multiqueue MSI-X registration.
From: Chad Dupuis chad.dup...@qlogic.com This fixes requesting of the MSI-X vectors for the base response queue. The iteration in the for loop in qla24xx_enable_msix() was incorrect. We should only iterate of the first two MSI-X vectors and not the total number of MSI-X vectors that have given to the driver for this device from pci_enable_msix() in this function. Cc: sta...@vger.kernel.org Signed-off-by: Chad Dupuis chad.dup...@qlogic.com Signed-off-by: Saurav Kashyap saurav.kash...@qlogic.com --- drivers/scsi/qla2xxx/qla_isr.c | 46 ++-- 1 files changed, 30 insertions(+), 16 deletions(-) diff --git a/drivers/scsi/qla2xxx/qla_isr.c b/drivers/scsi/qla2xxx/qla_isr.c index da5f466..c2aaf6a 100644 --- a/drivers/scsi/qla2xxx/qla_isr.c +++ b/drivers/scsi/qla2xxx/qla_isr.c @@ -2882,6 +2882,7 @@ static int qla24xx_enable_msix(struct qla_hw_data *ha, struct rsp_que *rsp) { #define MIN_MSIX_COUNT 2 +#define ATIO_VECTOR2 int i, ret; struct msix_entry *entries; struct qla_msix_entry *qentry; @@ -2938,34 +2939,47 @@ msix_failed: } /* Enable MSI-X vectors for the base queue */ - for (i = 0; i ha-msix_count; i++) { + for (i = 0; i 2; i++) { qentry = ha-msix_entries[i]; - if (QLA_TGT_MODE_ENABLED() IS_ATIO_MSIX_CAPABLE(ha)) { - ret = request_irq(qentry-vector, - qla83xx_msix_entries[i].handler, - 0, qla83xx_msix_entries[i].name, rsp); - } else if (IS_P3P_TYPE(ha)) { + if (IS_P3P_TYPE(ha)) ret = request_irq(qentry-vector, qla82xx_msix_entries[i].handler, 0, qla82xx_msix_entries[i].name, rsp); - } else { + else ret = request_irq(qentry-vector, msix_entries[i].handler, 0, msix_entries[i].name, rsp); - } - if (ret) { - ql_log(ql_log_fatal, vha, 0x00cb, - MSI-X: unable to register handler -- %x/%d.\n, - qentry-vector, ret); - qla24xx_disable_msix(ha); - ha-mqenable = 0; - goto msix_out; - } + if (ret) + goto msix_register_fail; qentry-have_irq = 1; qentry-rsp = rsp; rsp-msix = qentry; } + /* +* If target mode is enable, also request the vector for the ATIO +* queue. +*/ + if (QLA_TGT_MODE_ENABLED() IS_ATIO_MSIX_CAPABLE(ha)) { + qentry = ha-msix_entries[ATIO_VECTOR]; + ret = request_irq(qentry-vector, + qla83xx_msix_entries[ATIO_VECTOR].handler, + 0, qla83xx_msix_entries[ATIO_VECTOR].name, rsp); + qentry-have_irq = 1; + qentry-rsp = rsp; + rsp-msix = qentry; + } + +msix_register_fail: + if (ret) { + ql_log(ql_log_fatal, vha, 0x00cb, + MSI-X: unable to register handler -- %x/%d.\n, + qentry-vector, ret); + qla24xx_disable_msix(ha); + ha-mqenable = 0; + goto msix_out; + } + /* Enable MSI-X vector for response queue update for queue 0 */ if (IS_QLA83XX(ha) || IS_QLA27XX(ha)) { if (ha-msixbase ha-mqiobase -- 1.7.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
[PATCH V2 06/20] qla2xxx: Select correct request queue for error type IOCB for ISPFX00.
Signed-off-by: Giridhar Malavali giridhar.malav...@qlogic.com Signed-off-by: Saurav Kashyap saurav.kash...@qlogic.com --- drivers/scsi/qla2xxx/qla_mr.c |2 +- 1 files changed, 1 insertions(+), 1 deletions(-) diff --git a/drivers/scsi/qla2xxx/qla_mr.c b/drivers/scsi/qla2xxx/qla_mr.c index 4542247..9839da8 100644 --- a/drivers/scsi/qla2xxx/qla_mr.c +++ b/drivers/scsi/qla2xxx/qla_mr.c @@ -2794,7 +2794,7 @@ qlafx00_error_entry(scsi_qla_host_t *vha, struct rsp_que *rsp, srb_t *sp; struct qla_hw_data *ha = vha-hw; const char func[] = ERROR-IOCB; - uint16_t que = MSW(pkt-handle); + uint16_t que = 0; struct req_que *req = NULL; int res = DID_ERROR 16; -- 1.7.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
[PATCH V2 20/20] qla2xxx: Update the driver version to 8.07.00.02-k.
Signed-off-by: Saurav Kashyap saurav.kash...@qlogic.com Signed-off-by: Giridhar Malavali giridhar.malav...@qlogic.com --- drivers/scsi/qla2xxx/qla_version.h |4 ++-- 1 files changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/scsi/qla2xxx/qla_version.h b/drivers/scsi/qla2xxx/qla_version.h index 31d1953..e36b947 100644 --- a/drivers/scsi/qla2xxx/qla_version.h +++ b/drivers/scsi/qla2xxx/qla_version.h @@ -7,9 +7,9 @@ /* * Driver version */ -#define QLA2XXX_VERSION 8.06.00.12-k +#define QLA2XXX_VERSION 8.07.00.02-k #define QLA_DRIVER_MAJOR_VER 8 -#define QLA_DRIVER_MINOR_VER 6 +#define QLA_DRIVER_MINOR_VER 7 #define QLA_DRIVER_PATCH_VER 0 #define QLA_DRIVER_BETA_VER0 -- 1.7.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
[PATCH V2 10/20] scsi_transport_fc: Add 32Gbps speed definition.
From: Chad Dupuis chad.dup...@qlogic.com Signed-off-by: Chad Dupuis chad.dup...@qlogic.com Signed-off-by: Saurav Kashyap saurav.kash...@qlogic.com --- drivers/scsi/scsi_transport_fc.c |1 + include/scsi/scsi_transport_fc.h |1 + 2 files changed, 2 insertions(+), 0 deletions(-) diff --git a/drivers/scsi/scsi_transport_fc.c b/drivers/scsi/scsi_transport_fc.c index 4628fd5..f80908f 100644 --- a/drivers/scsi/scsi_transport_fc.c +++ b/drivers/scsi/scsi_transport_fc.c @@ -261,6 +261,7 @@ static const struct { { FC_PORTSPEED_10GBIT, 10 Gbit }, { FC_PORTSPEED_8GBIT, 8 Gbit }, { FC_PORTSPEED_16GBIT, 16 Gbit }, + { FC_PORTSPEED_32GBIT, 32 Gbit }, { FC_PORTSPEED_NOT_NEGOTIATED, Not Negotiated }, }; fc_bitfield_name_search(port_speed, fc_port_speed_names) diff --git a/include/scsi/scsi_transport_fc.h b/include/scsi/scsi_transport_fc.h index b797e8f..8c79980 100644 --- a/include/scsi/scsi_transport_fc.h +++ b/include/scsi/scsi_transport_fc.h @@ -130,6 +130,7 @@ enum fc_vport_state { #define FC_PORTSPEED_4GBIT 8 #define FC_PORTSPEED_8GBIT 0x10 #define FC_PORTSPEED_16GBIT0x20 +#define FC_PORTSPEED_32GBIT0x40 #define FC_PORTSPEED_NOT_NEGOTIATED(1 15) /* Speed not established */ /* -- 1.7.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
[PATCH V2 16/20] qla2xxx: Simplify the ISPFX00 interrupt handler code for ISPFX00.
Signed-off-by: Giridhar Malavali giridhar.malav...@qlogic.com Signed-off-by: Saurav Kashyap saurav.kash...@qlogic.com --- drivers/scsi/qla2xxx/qla_mr.c | 25 + drivers/scsi/qla2xxx/qla_mr.h |4 2 files changed, 9 insertions(+), 20 deletions(-) diff --git a/drivers/scsi/qla2xxx/qla_mr.c b/drivers/scsi/qla2xxx/qla_mr.c index 290322f..046a169 100644 --- a/drivers/scsi/qla2xxx/qla_mr.c +++ b/drivers/scsi/qla2xxx/qla_mr.c @@ -3014,6 +3014,7 @@ qlafx00_intr_handler(int irq, void *dev_id) struct rsp_que *rsp; unsigned long flags; uint32_t clr_intr = 0; + uint32_t intr_stat = 0; rsp = (struct rsp_que *) dev_id; if (!rsp) { @@ -3035,34 +3036,26 @@ qlafx00_intr_handler(int irq, void *dev_id) stat = QLAFX00_RD_INTR_REG(ha); if (qla2x00_check_reg_for_disconnect(vha, stat)) break; - if ((stat QLAFX00_HST_INT_STS_BITS) == 0) + intr_stat = stat QLAFX00_HST_INT_STS_BITS; + if (!intr_stat) break; - switch (stat QLAFX00_HST_INT_STS_BITS) { - case QLAFX00_INTR_MB_CMPLT: - case QLAFX00_INTR_MB_RSP_CMPLT: - case QLAFX00_INTR_MB_ASYNC_CMPLT: - case QLAFX00_INTR_ALL_CMPLT: + if (stat QLAFX00_INTR_MB_CMPLT) { mb[0] = RD_REG_WORD(reg-mailbox16); qlafx00_mbx_completion(vha, mb[0]); status |= MBX_INTERRUPT; clr_intr |= QLAFX00_INTR_MB_CMPLT; - break; - case QLAFX00_INTR_ASYNC_CMPLT: - case QLAFX00_INTR_RSP_ASYNC_CMPLT: + } + if (intr_stat QLAFX00_INTR_ASYNC_CMPLT) { ha-aenmb[0] = RD_REG_WORD(reg-aenmailbox0); qlafx00_async_event(vha); clr_intr |= QLAFX00_INTR_ASYNC_CMPLT; - break; - case QLAFX00_INTR_RSP_CMPLT: + } + if (intr_stat QLAFX00_INTR_RSP_CMPLT) { qlafx00_process_response_queue(vha, rsp); clr_intr |= QLAFX00_INTR_RSP_CMPLT; - break; - default: - ql_dbg(ql_dbg_async, vha, 0x507a, - Unrecognized interrupt type (%d).\n, stat); - break; } + QLAFX00_CLR_INTR_REG(ha, clr_intr); QLAFX00_RD_INTR_REG(ha); } diff --git a/drivers/scsi/qla2xxx/qla_mr.h b/drivers/scsi/qla2xxx/qla_mr.h index 3cf5ddc..e529dfa 100644 --- a/drivers/scsi/qla2xxx/qla_mr.h +++ b/drivers/scsi/qla2xxx/qla_mr.h @@ -336,11 +336,7 @@ struct config_info_data { #define QLAFX00_INTR_MB_CMPLT 0x1 #define QLAFX00_INTR_RSP_CMPLT 0x2 -#define QLAFX00_INTR_MB_RSP_CMPLT 0x3 #define QLAFX00_INTR_ASYNC_CMPLT 0x4 -#define QLAFX00_INTR_MB_ASYNC_CMPLT0x5 -#define QLAFX00_INTR_RSP_ASYNC_CMPLT 0x6 -#define QLAFX00_INTR_ALL_CMPLT 0x7 #define QLAFX00_MBA_SYSTEM_ERR 0x8002 #define QLAFX00_MBA_TEMP_OVER 0x8005 -- 1.7.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
[PATCH V2 05/20] qla2xxx: Remove init control block related dead code for ISPFX00.
Signed-off-by: Giridhar Malavali giridhar.malav...@qlogic.com Signed-off-by: Saurav Kashyap saurav.kash...@qlogic.com --- drivers/scsi/qla2xxx/qla_def.h | 24 drivers/scsi/qla2xxx/qla_mr.c | 14 -- drivers/scsi/qla2xxx/qla_os.c |1 - 3 files changed, 0 insertions(+), 39 deletions(-) diff --git a/drivers/scsi/qla2xxx/qla_def.h b/drivers/scsi/qla2xxx/qla_def.h index 02ad5d8..d7184f5 100644 --- a/drivers/scsi/qla2xxx/qla_def.h +++ b/drivers/scsi/qla2xxx/qla_def.h @@ -1197,30 +1197,6 @@ typedef struct { uint8_t reserved_3[26]; } init_cb_t; - -struct init_cb_fx { - uint16_tversion; - uint16_treserved_1[13]; - __le16 request_q_outpointer; - __le16 response_q_inpointer; - uint16_treserved_2[2]; - __le16 response_q_length; - __le16 request_q_length; - uint16_treserved_3[2]; - __le32 request_q_address[2]; - __le32 response_q_address[2]; - uint16_treserved_4[4]; - uint8_t response_q_msivec; - uint8_t reserved_5[19]; - uint16_tinterrupt_delay_timer; - uint16_treserved_6; - uint32_tfwoptions1; - uint32_tfwoptions2; - uint32_tfwoptions3; - uint8_t reserved_7[24]; -}; - - /* * Get Link Status mailbox command return buffer. */ diff --git a/drivers/scsi/qla2xxx/qla_mr.c b/drivers/scsi/qla2xxx/qla_mr.c index 7c7849d..4542247 100644 --- a/drivers/scsi/qla2xxx/qla_mr.c +++ b/drivers/scsi/qla2xxx/qla_mr.c @@ -631,20 +631,6 @@ qlafx00_config_rings(struct scsi_qla_host *vha) { struct qla_hw_data *ha = vha-hw; struct device_reg_fx00 __iomem *reg = ha-iobase-ispfx00; - struct init_cb_fx *icb; - struct req_que *req = ha-req_q_map[0]; - struct rsp_que *rsp = ha-rsp_q_map[0]; - - /* Setup ring parameters in initialization control block. */ - icb = (struct init_cb_fx *)ha-init_cb; - icb-request_q_outpointer = __constant_cpu_to_le16(0); - icb-response_q_inpointer = __constant_cpu_to_le16(0); - icb-request_q_length = cpu_to_le16(req-length); - icb-response_q_length = cpu_to_le16(rsp-length); - icb-request_q_address[0] = cpu_to_le32(LSD(req-dma)); - icb-request_q_address[1] = cpu_to_le32(MSD(req-dma)); - icb-response_q_address[0] = cpu_to_le32(LSD(rsp-dma)); - icb-response_q_address[1] = cpu_to_le32(MSD(rsp-dma)); WRT_REG_DWORD(reg-req_q_in, 0); WRT_REG_DWORD(reg-req_q_out, 0); diff --git a/drivers/scsi/qla2xxx/qla_os.c b/drivers/scsi/qla2xxx/qla_os.c index 53edc4b..c698e10 100644 --- a/drivers/scsi/qla2xxx/qla_os.c +++ b/drivers/scsi/qla2xxx/qla_os.c @@ -2489,7 +2489,6 @@ qla2x00_probe_one(struct pci_dev *pdev, const struct pci_device_id *id) ha-aen_mbx_count = AEN_MAILBOX_REGISTER_COUNT_FX00; req_length = REQUEST_ENTRY_CNT_FX00; rsp_length = RESPONSE_ENTRY_CNT_FX00; - ha-init_cb_size = sizeof(struct init_cb_fx); ha-isp_ops = qlafx00_isp_ops; ha-port_down_retry_count = 30; /* default value */ ha-mr.fw_hbt_cnt = QLAFX00_HEARTBEAT_INTERVAL; -- 1.7.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
[PATCH V2 18/20] qla2xxx: Correctly set the read_optrom pointer for ISP8044.
Signed-off-by: Giridhar Malavali giridhar.malav...@qlogic.com Signed-off-by: Saurav Kashyap saurav.kash...@qlogic.com --- drivers/scsi/qla2xxx/qla_os.c |2 +- 1 files changed, 1 insertions(+), 1 deletions(-) diff --git a/drivers/scsi/qla2xxx/qla_os.c b/drivers/scsi/qla2xxx/qla_os.c index 3f69e7c..24af8e0 100644 --- a/drivers/scsi/qla2xxx/qla_os.c +++ b/drivers/scsi/qla2xxx/qla_os.c @@ -2017,7 +2017,7 @@ static struct isp_operations qla8044_isp_ops = { .beacon_on = qla82xx_beacon_on, .beacon_off = qla82xx_beacon_off, .beacon_blink = NULL, - .read_optrom= qla82xx_read_optrom_data, + .read_optrom= qla8044_read_optrom_data, .write_optrom = qla8044_write_optrom_data, .get_flash_version = qla82xx_get_flash_version, .start_scsi = qla82xx_start_scsi, -- 1.7.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
[PATCH V2 02/20] qla2xxx: Add handling for boot indication progress AENs for ISPFX00.
From: Armen Baloyan armen.balo...@qlogic.com Signed-off-by: Armen Baloyan armen.balo...@qlogic.com Signed-off-by: Saurav Kashyap saurav.kash...@qlogic.com --- drivers/scsi/qla2xxx/qla_def.h |2 +- drivers/scsi/qla2xxx/qla_mr.c |3 +++ 2 files changed, 4 insertions(+), 1 deletions(-) diff --git a/drivers/scsi/qla2xxx/qla_def.h b/drivers/scsi/qla2xxx/qla_def.h index 859c63a..02ad5d8 100644 --- a/drivers/scsi/qla2xxx/qla_def.h +++ b/drivers/scsi/qla2xxx/qla_def.h @@ -808,7 +808,7 @@ struct mbx_cmd_32 { Notification */ #define MBA_FW_POLL_STATE 0x8600 /* Firmware in poll diagnostic state */ #define MBA_FW_RESET_FCT 0x8502 /* Firmware reset factory defaults */ - +#define MBA_FW_INIT_INPROGRESS 0x8500 /* Firmware boot in progress */ /* 83XX FCoE specific */ #define MBA_IDC_AEN0x8200 /* FCoE: NIC Core state change AEN */ diff --git a/drivers/scsi/qla2xxx/qla_mr.c b/drivers/scsi/qla2xxx/qla_mr.c index ba6f8b1..6ca4807 100644 --- a/drivers/scsi/qla2xxx/qla_mr.c +++ b/drivers/scsi/qla2xxx/qla_mr.c @@ -997,6 +997,9 @@ qlafx00_init_fw_ready(scsi_qla_host_t *vha) break; default: + if ((aenmbx 0xFF00) == MBA_FW_INIT_INPROGRESS) + break; + /* If fw is apparently not ready. In order to continue, * we might need to issue Mbox cmd, but the problem is * that the DoorBell vector values that come with the -- 1.7.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
[PATCH V2 08/20] qla2xxx: Properly handle 32 bit mailbox register for ISPFX00.
Signed-off-by: Saurav Kashyap saurav.kash...@qlogic.com Signed-off-by: Giridhar Malavali giridhar.malav...@qlogic.com --- drivers/scsi/qla2xxx/qla_mr.c | 12 ++-- 1 files changed, 6 insertions(+), 6 deletions(-) diff --git a/drivers/scsi/qla2xxx/qla_mr.c b/drivers/scsi/qla2xxx/qla_mr.c index 9839da8..ed44ec6 100644 --- a/drivers/scsi/qla2xxx/qla_mr.c +++ b/drivers/scsi/qla2xxx/qla_mr.c @@ -2916,9 +2916,9 @@ qlafx00_async_event(scsi_qla_host_t *vha) break; case QLAFX00_MBA_PORT_UPDATE: /* Port database update */ - ha-aenmb[1] = RD_REG_WORD(reg-aenmailbox1); - ha-aenmb[2] = RD_REG_WORD(reg-aenmailbox2); - ha-aenmb[3] = RD_REG_WORD(reg-aenmailbox3); + ha-aenmb[1] = RD_REG_DWORD(reg-aenmailbox1); + ha-aenmb[2] = RD_REG_DWORD(reg-aenmailbox2); + ha-aenmb[3] = RD_REG_DWORD(reg-aenmailbox3); ql_dbg(ql_dbg_async, vha, 0x5077, Asynchronous port Update received aenmb[0]: %x, aenmb[1]: %x, aenmb[2]: %x, aenmb[3]: %x\n, @@ -2975,7 +2975,7 @@ static void qlafx00_mbx_completion(scsi_qla_host_t *vha, uint32_t mb0) { uint16_tcnt; - uint16_t __iomem *wptr; + uint32_t __iomem *wptr; struct qla_hw_data *ha = vha-hw; struct device_reg_fx00 __iomem *reg = ha-iobase-ispfx00; @@ -2985,10 +2985,10 @@ qlafx00_mbx_completion(scsi_qla_host_t *vha, uint32_t mb0) /* Load return mailbox registers. */ ha-flags.mbox_int = 1; ha-mailbox_out32[0] = mb0; - wptr = (uint16_t __iomem *)reg-mailbox17; + wptr = (uint32_t __iomem *)reg-mailbox17; for (cnt = 1; cnt ha-mbx_count; cnt++) { - ha-mailbox_out32[cnt] = RD_REG_WORD(wptr); + ha-mailbox_out32[cnt] = RD_REG_DWORD(wptr); wptr++; } } -- 1.7.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
[PATCH V2 09/20] qla2xxx: Set host can_queue value based on available resources.
From: Chad Dupuis chad.dup...@qlogic.com Tell the mid-layer that number of commands we can queue is the available resources we have minus a small amount for internal commands. Signed-off-by: Chad Dupuis chad.dup...@qlogic.com Signed-off-by: Saurav Kashyap saurav.kash...@qlogic.com --- drivers/scsi/qla2xxx/qla_os.c | 20 +++- 1 files changed, 11 insertions(+), 9 deletions(-) diff --git a/drivers/scsi/qla2xxx/qla_os.c b/drivers/scsi/qla2xxx/qla_os.c index c698e10..464bb2b 100644 --- a/drivers/scsi/qla2xxx/qla_os.c +++ b/drivers/scsi/qla2xxx/qla_os.c @@ -2561,10 +2561,6 @@ qla2x00_probe_one(struct pci_dev *pdev, const struct pci_device_id *id) host = base_vha-host; base_vha-req = req; - if (IS_QLAFX00(ha)) - host-can_queue = QLAFX00_MAX_CANQUEUE; - else - host-can_queue = req-length + 128; if (IS_QLA2XXX_MIDTYPE(ha)) base_vha-mgmt_svr_loop_id = 10 + base_vha-vp_idx; else @@ -2587,11 +2583,6 @@ qla2x00_probe_one(struct pci_dev *pdev, const struct pci_device_id *id) if (!IS_QLA82XX(ha)) host-sg_tablesize = QLA_SG_ALL; } - ql_dbg(ql_dbg_init, base_vha, 0x0032, - can_queue=%d, req=%p, - mgmt_svr_loop_id=%d, sg_tablesize=%d.\n, - host-can_queue, base_vha-req, - base_vha-mgmt_svr_loop_id, host-sg_tablesize); host-max_id = ha-max_fibre_devices; host-cmd_per_lun = 3; host-unique_id = host-host_no; @@ -2707,6 +2698,17 @@ que_init: goto probe_failed; } + if (IS_QLAFX00(ha)) + host-can_queue = QLAFX00_MAX_CANQUEUE; + else + host-can_queue = req-num_outstanding_cmds - 10; + + ql_dbg(ql_dbg_init, base_vha, 0x0032, + can_queue=%d, req=%p, + mgmt_svr_loop_id=%d, sg_tablesize=%d.\n, + host-can_queue, base_vha-req, + base_vha-mgmt_svr_loop_id, host-sg_tablesize); + if (ha-mqenable) { if (qla25xx_setup_mode(base_vha)) { ql_log(ql_log_warn, base_vha, 0x00ec, -- 1.7.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
[PATCH V2 17/20] qla2xxx: Read capture firmware dump on mailbox timeout for ISP8044 and ISP82XX.
From: Chad Dupuis chad.dup...@qlogic.com Allow for the capture of a firmware dump but have a sysfs node (allow_cna_fw_dump) to allow the feature to be enabled/disabled dynamically. The default is off. Signed-off-by: Chad Dupuis chad.dup...@qlogic.com Signed-off-by: Saurav Kashyap saurav.kash...@qlogic.com --- drivers/scsi/qla2xxx/qla_attr.c | 35 +++ drivers/scsi/qla2xxx/qla_def.h |1 + drivers/scsi/qla2xxx/qla_gbl.h |2 ++ drivers/scsi/qla2xxx/qla_nx.c | 17 + drivers/scsi/qla2xxx/qla_nx2.c | 16 drivers/scsi/qla2xxx/qla_os.c |4 ++-- 6 files changed, 73 insertions(+), 2 deletions(-) diff --git a/drivers/scsi/qla2xxx/qla_attr.c b/drivers/scsi/qla2xxx/qla_attr.c index 7e5bcaf..b918bd4 100644 --- a/drivers/scsi/qla2xxx/qla_attr.c +++ b/drivers/scsi/qla2xxx/qla_attr.c @@ -1503,6 +1503,37 @@ qla2x00_fw_dump_size_show(struct device *dev, struct device_attribute *attr, return scnprintf(buf, PAGE_SIZE, %d\n, size); } +static ssize_t +qla2x00_allow_cna_fw_dump_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + scsi_qla_host_t *vha = shost_priv(class_to_shost(dev)); + + if (!IS_P3P_TYPE(vha-hw)) + return scnprintf(buf, PAGE_SIZE, \n); + else + return scnprintf(buf, PAGE_SIZE, %s\n, + vha-hw-allow_cna_fw_dump ? true : false); +} + +static ssize_t +qla2x00_allow_cna_fw_dump_store(struct device *dev, + struct device_attribute *attr, const char *buf, size_t count) +{ + scsi_qla_host_t *vha = shost_priv(class_to_shost(dev)); + int val = 0; + + if (!IS_P3P_TYPE(vha-hw)) + return -EINVAL; + + if (sscanf(buf, %d, val) != 1) + return -EINVAL; + + vha-hw-allow_cna_fw_dump = val != 0; + + return strlen(buf); +} + static DEVICE_ATTR(driver_version, S_IRUGO, qla2x00_drvr_version_show, NULL); static DEVICE_ATTR(fw_version, S_IRUGO, qla2x00_fw_version_show, NULL); static DEVICE_ATTR(serial_num, S_IRUGO, qla2x00_serial_num_show, NULL); @@ -1544,6 +1575,9 @@ static DEVICE_ATTR(thermal_temp, S_IRUGO, qla2x00_thermal_temp_show, NULL); static DEVICE_ATTR(diag_requests, S_IRUGO, qla2x00_diag_requests_show, NULL); static DEVICE_ATTR(diag_megabytes, S_IRUGO, qla2x00_diag_megabytes_show, NULL); static DEVICE_ATTR(fw_dump_size, S_IRUGO, qla2x00_fw_dump_size_show, NULL); +static DEVICE_ATTR(allow_cna_fw_dump, S_IRUGO | S_IWUSR, + qla2x00_allow_cna_fw_dump_show, + qla2x00_allow_cna_fw_dump_store); struct device_attribute *qla2x00_host_attrs[] = { dev_attr_driver_version, @@ -1576,6 +1610,7 @@ struct device_attribute *qla2x00_host_attrs[] = { dev_attr_diag_requests, dev_attr_diag_megabytes, dev_attr_fw_dump_size, + dev_attr_allow_cna_fw_dump, NULL, }; diff --git a/drivers/scsi/qla2xxx/qla_def.h b/drivers/scsi/qla2xxx/qla_def.h index 143fe4f..f8521da 100644 --- a/drivers/scsi/qla2xxx/qla_def.h +++ b/drivers/scsi/qla2xxx/qla_def.h @@ -3299,6 +3299,7 @@ struct qla_hw_data { struct mr_data_fx00 mr; struct qlt_hw_data tgt; + int allow_cna_fw_dump; }; /* diff --git a/drivers/scsi/qla2xxx/qla_gbl.h b/drivers/scsi/qla2xxx/qla_gbl.h index 19a0662..dcd084a 100644 --- a/drivers/scsi/qla2xxx/qla_gbl.h +++ b/drivers/scsi/qla2xxx/qla_gbl.h @@ -511,6 +511,8 @@ extern void qla2300_fw_dump(scsi_qla_host_t *, int); extern void qla24xx_fw_dump(scsi_qla_host_t *, int); extern void qla25xx_fw_dump(scsi_qla_host_t *, int); extern void qla81xx_fw_dump(scsi_qla_host_t *, int); +extern void qla82xx_fw_dump(scsi_qla_host_t *, int); +extern void qla8044_fw_dump(scsi_qla_host_t *, int); extern void qla27xx_fwdump(scsi_qla_host_t *, int); extern ulong qla27xx_fwdt_calculate_dump_size(struct scsi_qla_host *); diff --git a/drivers/scsi/qla2xxx/qla_nx.c b/drivers/scsi/qla2xxx/qla_nx.c index 26326f3..5511e24 100644 --- a/drivers/scsi/qla2xxx/qla_nx.c +++ b/drivers/scsi/qla2xxx/qla_nx.c @@ -4502,3 +4502,20 @@ exit: qla82xx_idc_unlock(ha); return rval; } + +void +qla82xx_fw_dump(scsi_qla_host_t *vha, int hardware_locked) +{ + struct qla_hw_data *ha = vha-hw; + + if (!ha-allow_cna_fw_dump) + return; + + scsi_block_requests(vha-host); + ha-flags.isp82xx_no_md_cap = 1; + qla82xx_idc_lock(ha); + qla82xx_set_reset_owner(vha); + qla82xx_idc_unlock(ha); + qla2x00_wait_for_chip_reset(vha); + scsi_unblock_requests(vha-host); +} diff --git a/drivers/scsi/qla2xxx/qla_nx2.c b/drivers/scsi/qla2xxx/qla_nx2.c index 0350a59..0ea061b 100644 --- a/drivers/scsi/qla2xxx/qla_nx2.c +++ b/drivers/scsi/qla2xxx/qla_nx2.c @@ -3713,3 +3713,19 @@ exit_isp_reset: return rval; } +void +qla8044_fw_dump(scsi_qla_host_t *vha, int hardware_locked) +{ + struct qla_hw_data *ha = vha-hw; + + if
[PATCH V2 12/20] qla2xxx: Remove Marker type IOCB logic for ISPFX00.
From: Armen Baloyan armen.balo...@qlogic.com Signed-off-by: Armen Baloyan armen.balo...@qlogic.com Signed-off-by: Saurav Kashyap saurav.kash...@qlogic.com --- drivers/scsi/qla2xxx/qla_iocb.c | 11 +-- drivers/scsi/qla2xxx/qla_mr.c | 12 drivers/scsi/qla2xxx/qla_mr.h | 24 3 files changed, 1 insertions(+), 46 deletions(-) diff --git a/drivers/scsi/qla2xxx/qla_iocb.c b/drivers/scsi/qla2xxx/qla_iocb.c index 5e6ac6c..0aad5e4 100644 --- a/drivers/scsi/qla2xxx/qla_iocb.c +++ b/drivers/scsi/qla2xxx/qla_iocb.c @@ -524,7 +524,6 @@ __qla2x00_marker(struct scsi_qla_host *vha, struct req_que *req, { mrk_entry_t *mrk; struct mrk_entry_24xx *mrk24 = NULL; - struct mrk_entry_fx00 *mrkfx = NULL; struct qla_hw_data *ha = vha-hw; scsi_qla_host_t *base_vha = pci_get_drvdata(ha-pdev); @@ -541,15 +540,7 @@ __qla2x00_marker(struct scsi_qla_host *vha, struct req_que *req, mrk-entry_type = MARKER_TYPE; mrk-modifier = type; if (type != MK_SYNC_ALL) { - if (IS_QLAFX00(ha)) { - mrkfx = (struct mrk_entry_fx00 *) mrk; - mrkfx-handle = MAKE_HANDLE(req-id, mrkfx-handle); - mrkfx-handle_hi = 0; - mrkfx-tgt_id = cpu_to_le16(loop_id); - mrkfx-lun[1] = LSB(lun); - mrkfx-lun[2] = MSB(lun); - host_to_fcp_swap(mrkfx-lun, sizeof(mrkfx-lun)); - } else if (IS_FWI2_CAPABLE(ha)) { + if (IS_FWI2_CAPABLE(ha)) { mrk24 = (struct mrk_entry_24xx *) mrk; mrk24-nport_handle = cpu_to_le16(loop_id); mrk24-lun[1] = LSB(lun); diff --git a/drivers/scsi/qla2xxx/qla_mr.c b/drivers/scsi/qla2xxx/qla_mr.c index a9b5cf4..893e56d 100644 --- a/drivers/scsi/qla2xxx/qla_mr.c +++ b/drivers/scsi/qla2xxx/qla_mr.c @@ -2140,7 +2140,6 @@ qlafx00_initialize_adapter(scsi_qla_host_t *vha) vha-device_flags = DFLG_NO_CABLE; vha-dpc_flags = 0; vha-flags.management_server_logged_in = 0; - vha-marker_needed = 0; ha-isp_abort_cnt = 0; ha-beacon_blink_led = 0; @@ -3213,17 +3212,6 @@ qlafx00_start_scsi(srb_t *sp) /* So we know we haven't pci_map'ed anything yet */ tot_dsds = 0; - /* Forcing marker needed for now */ - vha-marker_needed = 0; - - /* Send marker if required */ - if (vha-marker_needed != 0) { - if (qla2x00_marker(vha, req, rsp, 0, 0, MK_SYNC_ALL) != - QLA_SUCCESS) - return QLA_FUNCTION_FAILED; - vha-marker_needed = 0; - } - /* Acquire ring specific lock */ spin_lock_irqsave(ha-hardware_lock, flags); diff --git a/drivers/scsi/qla2xxx/qla_mr.h b/drivers/scsi/qla2xxx/qla_mr.h index 5f3ed8b..1e60ca2 100644 --- a/drivers/scsi/qla2xxx/qla_mr.h +++ b/drivers/scsi/qla2xxx/qla_mr.h @@ -47,30 +47,6 @@ struct cmd_type_7_fx00 { uint32_t dseg_0_len;/* Data segment 0 length. */ }; -/* - * ISP queue - marker entry structure definition. - */ -struct mrk_entry_fx00 { - uint8_t entry_type; /* Entry type. */ - uint8_t entry_count;/* Entry count. */ - uint8_t handle_count; /* Handle count. */ - uint8_t entry_status; /* Entry Status. */ - - uint32_t handle;/* System handle. */ - uint32_t handle_hi; /* System handle. */ - - uint16_t tgt_id;/* Target ID. */ - - uint8_t modifier; /* Modifier (7-0). */ - uint8_t reserved_1; - - uint8_t reserved_2[5]; - - uint8_t lun[8]; /* FCP LUN (BE). */ - uint8_t reserved_3[36]; -}; - - #defineSTATUS_TYPE_FX000x01/* Status entry. */ struct sts_entry_fx00 { uint8_t entry_type; /* Entry type. */ -- 1.7.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
[PATCH V2 15/20] qla2xxx: Avoid poisoning in the response queue for ISPFX00.
Signed-off-by: Giridhar Malavali giridhar.malav...@qlogic.com Signed-off-by: Saurav Kashyap saurav.kash...@qlogic.com --- drivers/scsi/qla2xxx/qla_mr.c | 15 --- 1 files changed, 8 insertions(+), 7 deletions(-) diff --git a/drivers/scsi/qla2xxx/qla_mr.c b/drivers/scsi/qla2xxx/qla_mr.c index 03e2050..290322f 100644 --- a/drivers/scsi/qla2xxx/qla_mr.c +++ b/drivers/scsi/qla2xxx/qla_mr.c @@ -2821,16 +2821,22 @@ qlafx00_process_response_queue(struct scsi_qla_host *vha, { struct sts_entry_fx00 *pkt; response_t *lptr; + uint16_t lreq_q_in = 0; + uint16_t lreq_q_out = 0; - while (RD_REG_DWORD((void __iomem *)(rsp-ring_ptr-signature)) != - RESPONSE_PROCESSED) { + lreq_q_in = RD_REG_DWORD(rsp-rsp_q_in); + lreq_q_out = RD_REG_DWORD(rsp-rsp_q_out); + + while (lreq_q_in != lreq_q_out) { lptr = rsp-ring_ptr; memcpy_fromio(rsp-rsp_pkt, (void __iomem *)lptr, sizeof(rsp-rsp_pkt)); pkt = (struct sts_entry_fx00 *)rsp-rsp_pkt; rsp-ring_index++; + lreq_q_out++; if (rsp-ring_index == rsp-length) { + lreq_q_out = 0; rsp-ring_index = 0; rsp-ring_ptr = rsp-ring; } else { @@ -2842,7 +2848,6 @@ qlafx00_process_response_queue(struct scsi_qla_host *vha, qlafx00_error_entry(vha, rsp, (struct sts_entry_fx00 *)pkt, pkt-entry_status, pkt-entry_type); - goto next_iter; continue; } @@ -2876,10 +2881,6 @@ qlafx00_process_response_queue(struct scsi_qla_host *vha, pkt-entry_type, pkt-entry_status); break; } -next_iter: - WRT_REG_DWORD((void __iomem *)lptr-signature, - RESPONSE_PROCESSED); - wmb(); } /* Adjust ring index */ -- 1.7.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] virtio-scsi: Fix hotcpu_notifier use-after-free with virtscsi_freeze
On 12/17/2013 11:09 AM, Rusty Russell wrote: Jason Wang jasow...@redhat.com writes: On 10/28/2013 04:01 PM, Asias He wrote: vqs are freed in virtscsi_freeze but the hotcpu_notifier is not unregistered. We will have a use-after-free usage when the notifier callback is called after virtscsi_freeze. Signed-off-by: Asias He as...@redhat.com Please include a Fixes: line, especially if you want the CC: stable. Thanks, Rusty. Ok, will post V2 soon. -- 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