Mike Christie [Tue, 25 May 2021 18:18:20 +0000 (13:18 -0500)]
scsi: qedi: Complete TMF works before disconnect
We need to make sure that abort and reset completion work has completed
before ep_disconnect returns. After ep_disconnect we can't manipulate
cmds because libiscsi will call conn_stop and take onwership.
We are trying to make sure abort work and reset completion work has
completed before we do the cmd clean up in ep_disconnect. The problem is
that:
1. the work function sets the QEDI_CONN_FW_CLEANUP bit, so if the work was
still pending we would not see the bit set. We need to do this before
the work is queued.
2. If we had multiple works queued then we could break from the loop in
qedi_ep_disconnect early because when abort work 1 completes it could
clear QEDI_CONN_FW_CLEANUP. qedi_ep_disconnect could then see that
before work 2 has run.
3. A TMF reset completion work could run after ep_disconnect starts
cleaning up cmds via qedi_clearsq. ep_disconnect's call to qedi_clearsq
-> qedi_cleanup_all_io would might think it's done cleaning up cmds,
but the reset completion work could still be running. We then return
from ep_disconnect while still doing cleanup.
This replaces the bit with a counter to track the number of queued TMF
works, and adds a bool to prevent new works from starting from the
completion path once a ep_disconnect starts.
Mike Christie [Tue, 25 May 2021 18:18:18 +0000 (13:18 -0500)]
scsi: qedi: Fix cleanup session block/unblock use
Drivers shouldn't be calling block/unblock session for cmd cleanup because
the functions can change the session state from under libiscsi. This adds
a new a driver level bit so it can block all I/O the host while it drains
the card.
Mike Christie [Tue, 25 May 2021 18:18:17 +0000 (13:18 -0500)]
scsi: qedi: Fix TMF session block/unblock use
Drivers shouldn't be calling block/unblock session for tmf handling because
the functions can change the session state from under libiscsi.
iscsi_queuecommand's call to iscsi_prep_scsi_cmd_pdu->
iscsi_check_tmf_restrictions will prevent new cmds from being sent to qedi
after we've started handling a TMF. So we don't need to try and block it in
the driver, and we can remove these block calls.
Mike Christie [Tue, 25 May 2021 18:18:15 +0000 (13:18 -0500)]
scsi: qedi: Fix TMF tid allocation
qedi_iscsi_abort_work and qedi_tmf_work both allocate a tid then call
qedi_send_iscsi_tmf which also allocates a tid. This removes the tid
allocation from the callers.
Mike Christie [Tue, 25 May 2021 18:18:14 +0000 (13:18 -0500)]
scsi: qedi: Fix use after free during abort cleanup
If qedi_tmf_work's qedi_wait_for_cleanup_request call times out we will
also force the clean up of the qedi_work_map but
qedi_process_cmd_cleanup_resp could still be accessing the qedi_cmd.
To fix this issue we extend where we hold the tmf_work_lock and back_lock
so the qedi_process_cmd_cleanup_resp access is serialized with the cleanup
done in qedi_tmf_work and any completion handling for the iscsi_task.
Mike Christie [Tue, 25 May 2021 18:18:13 +0000 (13:18 -0500)]
scsi: qedi: Fix race during abort timeouts
If the SCSI cmd completes after qedi_tmf_work calls iscsi_itt_to_task then
the qedi qedi_cmd->task_id could be freed and used for another cmd. If we
then call qedi_iscsi_cleanup_task with that task_id we will be cleaning up
the wrong cmd.
Wait to release the task_id until the last put has been done on the
iscsi_task. Because libiscsi grabs a ref to the task when sending the
abort, we know that for the non-abort timeout case that the task_id we are
referencing is for the cmd that was supposed to be aborted.
A latter commit will fix the case where the abort times out while we are
running qedi_tmf_work.
Mike Christie [Tue, 25 May 2021 18:18:12 +0000 (13:18 -0500)]
scsi: qedi: Fix null ref during abort handling
If qedi_process_cmd_cleanup_resp finds the cmd it frees the work and sets
list_tmf_work to NULL, so qedi_tmf_work should check if list_tmf_work is
non-NULL when it wants to force cleanup.
Mike Christie [Tue, 25 May 2021 18:18:11 +0000 (13:18 -0500)]
scsi: iscsi: Move pool freeing
This doesn't fix any bugs, but it makes more sense to free the pool after
we have removed the session. At that time we know nothing is touching any
of the session fields, because all devices have been removed and scans are
stopped.
Mike Christie [Tue, 25 May 2021 18:18:10 +0000 (13:18 -0500)]
scsi: iscsi: Hold task ref during TMF timeout handling
For aborts, qedi needs to cleanup the FW then send the TMF from a worker
thread. While it's doing these the cmd could complete normally and the TMF
could time out. libiscsi would then complete the iscsi_task which will call
into the driver to cleanup the driver level resources while it still might
be accessing them for the cleanup/abort.
This has iscsi_eh_abort keep the iscsi_task ref if the TMF times out, so
qedi does not have to worry about if the task is being freed while in use
and does not need to get its own ref.
Mike Christie [Tue, 25 May 2021 18:18:09 +0000 (13:18 -0500)]
scsi: iscsi: Flush block work before unblock
We set the max_active iSCSI EH works to 1, so all work is going to execute
in order by default. However, userspace can now override this in sysfs. If
max_active > 1, we can end up with the block_work on CPU1 and
iscsi_unblock_session running the unblock_work on CPU2 and the session and
target/device state will end up out of sync with each other.
This adds a flush of the block_work in iscsi_unblock_session.
Mike Christie [Tue, 25 May 2021 18:18:07 +0000 (13:18 -0500)]
scsi: iscsi: Fix shost->max_id use
The iscsi offload drivers are setting the shost->max_id to the max number
of sessions they support. The problem is that max_id is not the max number
of targets but the highest identifier the targets can have. To use it to
limit the number of targets we need to set it to max sessions - 1, or we
can end up with a session we might not have preallocated resources for.
Mike Christie [Tue, 25 May 2021 18:18:06 +0000 (13:18 -0500)]
scsi: iscsi: Fix conn use after free during resets
If we haven't done a unbind target call we can race where
iscsi_conn_teardown wakes up the EH thread and then frees the conn while
those threads are still accessing the conn ehwait.
We can only do one TMF per session so this just moves the TMF fields from
the conn to the session. We can then rely on the
iscsi_session_teardown->iscsi_remove_session->__iscsi_unbind_session call
to remove the target and it's devices, and know after that point there is
no device or scsi-ml callout trying to access the session.
Mike Christie [Tue, 25 May 2021 18:18:05 +0000 (13:18 -0500)]
scsi: iscsi: Get ref to conn during reset handling
The comment in iscsi_eh_session_reset is wrong and we don't wait for the
EH to complete before tearing down the conn. This has us get a ref to the
conn when we are not holding the eh_mutex/frwd_lock so it does not get
freed from under us.
Mike Christie [Tue, 25 May 2021 18:18:04 +0000 (13:18 -0500)]
scsi: iscsi: Have abort handler get ref to conn
If SCSI midlayer is aborting a task when we are tearing down the conn we
could free the conn while the abort thread is accessing the conn. This has
the abort handler get a ref to the conn so it won't be freed from under it.
Note: this is not needed for device/target reset because we are holding the
eh_mutex when accessing the conn.
Mike Christie [Tue, 25 May 2021 18:18:03 +0000 (13:18 -0500)]
scsi: iscsi: Add iscsi_cls_conn refcount helpers
There are a couple places where we could free the iscsi_cls_conn while it's
still in use. This adds some helpers to get/put a refcount on the struct
and converts an exiting user. Subsequent commits will then use the helpers
to fix 2 bugs in the eh code.
Mike Christie [Tue, 25 May 2021 18:18:01 +0000 (13:18 -0500)]
scsi: iscsi: iscsi_tcp: Set no linger
Userspace (open-iscsi based tools at least) sets no linger on the socket to
prevent stale data from being sent. However, with the in-kernel cleanup if
userspace is not up the sockfd_put will release the socket without having
set that sockopt.
iscsid sets that opt at socket close time, but it seems ok to set this at
setup time in the kernel for all tools.
Mike Christie [Tue, 25 May 2021 18:18:00 +0000 (13:18 -0500)]
scsi: iscsi: Fix in-kernel conn failure handling
Commit 0ab710458da1 ("scsi: iscsi: Perform connection failure entirely in
kernel space") has the following regressions/bugs that this patch fixes:
1. It can return cmds to upper layers like dm-multipath where that can
retry them. After they are successful the fs/app can send new I/O to the
same sectors, but we've left the cmds running in FW or in the net layer.
We need to be calling ep_disconnect if userspace is not up.
This patch only fixes the issue for offload drivers. iscsi_tcp will be
fixed in separate commit because it doesn't have a ep_disconnect call.
2. The drivers that implement ep_disconnect expect that it's called before
conn_stop. Besides crashes, if the cleanup_task callout is called before
ep_disconnect it might free up driver/card resources for session1 then they
could be allocated for session2. But because the driver's ep_disconnect is
not called it has not cleaned up the firmware so the card is still using
the resources for the original cmd.
3. The stop_conn_work_fn can run after userspace has done its recovery and
we are happily using the session. We will then end up with various bugs
depending on what is going on at the time.
We may also run stop_conn_work_fn late after userspace has called stop_conn
and ep_disconnect and is now going to call start/bind conn. If
stop_conn_work_fn runs after bind but before start, we would leave the conn
in a unbound but sort of started state where IO might be allowed even
though the drivers have been set in a state where they no longer expect
I/O.
4. Returning -EAGAIN in iscsi_if_destroy_conn if we haven't yet run the in
kernel stop_conn function is breaking userspace. We should have been doing
this for the caller.
Mike Christie [Tue, 25 May 2021 18:17:59 +0000 (13:17 -0500)]
scsi: iscsi: Rel ref after iscsi_lookup_endpoint()
Subsequent commits allow the kernel to do ep_disconnect. In that case we
will have to get a proper refcount on the ep so one thread does not delete
it from under another.
Mike Christie [Tue, 25 May 2021 18:17:57 +0000 (13:17 -0500)]
scsi: iscsi: Force immediate failure during shutdown
If the system is not up, we can just fail immediately since iscsid is not
going to ever answer our netlink events. We are already setting the
recovery_tmo to 0, but by passing stop_conn STOP_CONN_TERM we never will
block the session and start the recovery timer, because for that flag
userspace will do the unbind and destroy events which would remove the
devices and wake up and kill the eh.
Since the conn is dead and the system is going dowm this just has us use
STOP_CONN_RECOVER with recovery_tmo=0 so we fail immediately. However, if
the user has set the recovery_tmo=-1 we let the system hang like they
requested since they might have used that setting for specific reasons
(one known reason is for buggy cluster software).
Mike Christie [Tue, 25 May 2021 18:17:55 +0000 (13:17 -0500)]
scsi: iscsi: Stop queueing during ep_disconnect
During ep_disconnect we have been doing iscsi_suspend_tx/queue to block new
I/O but every driver except cxgbi and iscsi_tcp can still get I/O from
__iscsi_conn_send_pdu() if we haven't called iscsi_conn_failure() before
ep_disconnect. This could happen if we were terminating the session, and
the logout timed out before it was even sent to libiscsi.
Fix the issue by adding a helper which reverses the bind_conn call that
allows new I/O to be queued. Drivers implementing ep_disconnect can use this
to make sure new I/O is not queued to them when handling the disconnect.
scsi: megaraid_sas: Handle missing interrupts while re-enabling IRQs
While reenabling the IRQ after IRQ poll there may be a small window for the
firmware to post the replies with interrupts raised. In that case the
driver will not see the interrupts which leads to I/O timeout.
This issue only happens when there are many I/O completions on a single
reply queue. This forces the driver to switch between the interrupt and IRQ
context.
Make the driver process the reply queue one more time after enabling the
IRQ.
Kashyap Desai [Fri, 28 May 2021 13:13:05 +0000 (18:43 +0530)]
scsi: megaraid_sas: Early detection of VD deletion through RaidMap update
Consider the case where a VD is deleted and the targetID of that VD is
assigned to a newly created VD. If the sequence of deletion/addition of VD
happens very quickly there is a possibility that second event (VD add)
occurs even before the driver processes the first event (VD delete). As
event processing is done in deferred context the device list remains the
same (but targetID is re-used) so driver will not learn the VD
deletion/additon. I/Os meant for the older VD will be directed to new VD
which may lead to data corruption.
Make driver detect the deleted VD as soon as possible based on the RaidMap
update and block further I/O to that device.
scsi: megaraid_sas: Send all non-RW I/Os for TYPE_ENCLOSURE device through firmware
The driver issues all non-ReadWrite I/Os for TYPE_ENCLOSURE devices through
the fast path with invalid dev handle. Fast path in turn directs all the
I/Os to the firmware. As firmware stopped handling those I/Os from SAS3.5
generation of controllers (Ventura generation and onwards) this will lead
to I/O failures.
Switch the driver to issue all the non-ReadWrite I/Os for TYPE_ENCLOSURE
devices directly to firmware for SAS3.5 generation of controllers and
later.
Kashyap Desai [Thu, 20 May 2021 15:25:43 +0000 (20:55 +0530)]
scsi: mpi3mr: Add support for DSN secure firmware check
Read PCI_EXT_CAP_ID_DSN to query security status.
The driver will throw a warning message when a non-secure type controller
is detected. The purpose of this interface is to avoid interacting with any
firmware which is not secured/signed by Broadcom. Any tampering on
firmware component will be detected by hardware and it will be communicated
to the driver to avoid any further interaction with that component.
Kashyap Desai [Thu, 20 May 2021 15:25:39 +0000 (20:55 +0530)]
scsi: mpi3mr: Complete support for soft reset
Unlock the host diagnostic register, write the specific reset type to that
and wait for reset acknowledgment from the controller. If the reset is not
successful retry for the predefined number of times
Kashyap Desai [Thu, 20 May 2021 15:25:38 +0000 (20:55 +0530)]
scsi: mpi3mr: Add support for threaded ISR
Register driver for threaded interrupts.
By default the driver will attempt I/O completion from interrupt context
(primary handler). Since the driver tracks per reply queue outstanding
I/Os, it will schedule threaded ISR if there are any outstanding I/Os
expected on that particular reply queue.
Threaded ISR (secondary handler) will loop for I/O completion as long as
there are outstanding I/Os (speculative method using same per reply queue
outstanding counter) or it has completed some X amount of commands
(something like budget).
Kashyap Desai [Thu, 20 May 2021 15:25:37 +0000 (20:55 +0530)]
scsi: mpi3mr: Hardware workaround for UNMAP commands to NVMe drives
The controller hardware can not handle certain UNMAP commands for NVMe
drives. Add support in the driver for checking those commands and handle
them appropriately.
Kashyap Desai [Thu, 20 May 2021 15:25:36 +0000 (20:55 +0530)]
scsi: mpi3mr: Allow certain commands during pci-remove hook
Instead of driver returning DID_NO_CONNECT during driver unload allow SSU
and Sync Cache commands to be sent to the controller to flush any cached
data from the drive.
Kashyap Desai [Thu, 20 May 2021 15:25:31 +0000 (20:55 +0530)]
scsi: mpi3mr: Add support for timestamp sync with firmware
This operation requests that the IOC update the TimeStamp.
When the I/O Unit is powered on it sets the TimeStamp field value to
0x0000_0000_0000_0000 and increments the current value every millisecond.
A host driver sets the TimeStamp field to the current time by using an
IOCInit request. The TimeStamp field is periodically updated by the host
driver.
Kashyap Desai [Thu, 20 May 2021 15:25:30 +0000 (20:55 +0530)]
scsi: mpi3mr: Add support for recovering controller
Detection of firmware fault or any kind of unresponsiveness in the
controller (any admin command which times out) results in resetting the
controller. The primary reset mechanisms used are either soft reset or diag
fault reset. A reset is performed if the host sets the ResetAction field in
the HostDiagnostic register to either 001b (soft reset) or 007b (diag fault
reset). After successfully resetting the controller the driver
reinitializes the controller by going through start of the day
initialization procedure. Pending I/Os during the reset are returned back
to the SCSI midlayer for retry.
Kashyap Desai [Thu, 20 May 2021 15:25:26 +0000 (20:55 +0530)]
scsi: mpi3mr: Add support for internal watchdog thread
The watchdog thread is the driver's internal thread which does a few things
such as detecting firmware faults, resetting the controller, performing
timestamp sync, etc.
Kashyap Desai [Thu, 20 May 2021 15:25:25 +0000 (20:55 +0530)]
scsi: mpi3mr: Add support for queue command processing
Send Port Enable Request to FW for Device Discovery. As part of port
enable completion driver calls scan_start and scan_finished hooks. SCSI
layer references like sdev, starget, etc. are added but actual device
discovery will be supported once driver adds complete event process
handling.
Kashyap Desai [Thu, 20 May 2021 15:25:24 +0000 (20:55 +0530)]
scsi: mpi3mr: Create operational request and reply queue pair
Create operational request and reply queue pair.
The MPI3 transport interface consists of an Administrative Request Queue,
an Administrative Reply Queue, and Operational Messaging Queues. The
Operational Messaging Queues are the primary communication mechanism
between the host and the I/O Controller (IOC). Request messages, allocated
in host memory, identify I/O operations to be performed by the IOC. These
operations are queued on an Operational Request Queue by the host driver.
Reply descriptors track I/O operations as they complete. The IOC queues
these completions in an Operational Reply Queue.
To fulfil large contiguous memory requirement, driver creates multiple
segments and provide the list of segments. Each segment size should be 4K
which is a hardware requirement. An element array is contiguous or
segmented. A contiguous element array is located in contiguous physical
memory. A contiguous element array must be aligned on an element size
boundary. An element's physical address within the array may be directly
calculated from the base address, the Producer/Consumer index, and the
element size.
Expected phased identifier bit is used to find out valid entry on reply
queue. Driver sets <ephase> bit and IOC inverts the value of this bit on
each pass.
Kees Cook [Fri, 28 May 2021 18:13:37 +0000 (11:13 -0700)]
scsi: isci: Use correctly sized target buffer for memcpy()
In preparation for FORTIFY_SOURCE performing compile-time and run-time
field bounds checking for memcpy(), avoid intentionally writing across
neighboring array fields.
Switch from rsp_ui to resp_buf, since resp_ui isn't SSP_RESP_IU_MAX_SIZE
bytes in length. This avoids future compile-time warnings.
Kees Cook [Fri, 28 May 2021 18:13:36 +0000 (11:13 -0700)]
scsi: esas2r: Switch to flexible array member
In preparation for FORTIFY_SOURCE performing compile-time and run-time
field bounds checking for memcpy(), avoid intentionally writing across
neighboring array fields.
Remove old-style 1-byte array in favor of a flexible array[1] to avoid
future false-positive cross-field memcpy() warning in:
Randy Dunlap [Sat, 29 May 2021 23:48:57 +0000 (16:48 -0700)]
scsi: FlashPoint: Rename si_flags field
The BusLogic driver has build errors on ia64 due to a name collision (in
the #included FlashPoint.c file). Rename the struct field in struct
sccb_mgr_info from si_flags to si_mflags (manager flags) to mend the build.
This is the first problem. There are 50+ others after this one:
In file included from ../include/uapi/linux/signal.h:6,
from ../include/linux/signal_types.h:10,
from ../include/linux/sched.h:29,
from ../include/linux/hardirq.h:9,
from ../include/linux/interrupt.h:11,
from ../drivers/scsi/BusLogic.c:27:
../arch/ia64/include/uapi/asm/siginfo.h:15:27: error: expected ':', ',', ';', '}' or '__attribute__' before '.' token
15 | #define si_flags _sifields._sigfault._flags
| ^
../drivers/scsi/FlashPoint.c:43:6: note: in expansion of macro 'si_flags'
43 | u16 si_flags;
| ^~~~~~~~
In file included from ../drivers/scsi/BusLogic.c:51:
../drivers/scsi/FlashPoint.c: In function 'FlashPoint_ProbeHostAdapter':
../drivers/scsi/FlashPoint.c:1076:11: error: 'struct sccb_mgr_info' has no member named '_sifields'
1076 | pCardInfo->si_flags = 0x0000;
| ^~
../drivers/scsi/FlashPoint.c:1079:12: error: 'struct sccb_mgr_info' has no member named '_sifields'
scsi: mpt3sas: Fix fall-through warnings for Clang
In preparation to enable -Wimplicit-fallthrough for Clang, fix a couple
of warnings by explicitly adding break statements instead of just letting
the code fall through to the next case.
Resetting interrupt aggregation counters first and reading the
DOOR_BELL afterward allows us to handle all the completed requests. In
order to prevent other interrupts starvation the DB is read once after
reset. The down side of this solution is the possibility of false
interrupt if device completes another request after resetting
aggregation and before reading the DB.
Prevent that ufshcd_intr() reports a false positive "Unhandled interrupt"
message if the above scenario is triggered.
Suganath Prabu S [Tue, 18 May 2021 05:16:25 +0000 (10:46 +0530)]
scsi: mpt3sas: Handle firmware faults during second half of IOC init
If a firmware fault occurs while scanning the devices during IOC
initialization then the driver issues the hard reset operation to recover
the IOC. However, the driver is not issuing a Port enable request
message as part of hard reset operation during IOC initialization. Due to
this, the driver will not receive get any device discovery-related events
and hence devices will not be accessible.
Teach the driver to gracefully handle firmware faults while scanning for
target devices during IOC initialization. Make the driver issue a port
enable request message as part of hard reset operation. This permits
receiving device discovery-related events from the firmware after the hard
reset operation completes.
Suganath Prabu S [Tue, 18 May 2021 05:16:24 +0000 (10:46 +0530)]
scsi: mpt3sas: Handle firmware faults during first half of IOC init
During first half of IOC initialization (i.e. before going for device
scanning), if any firmware fault occurs then driver is aborting the IOC
initialization operation.
Modify the driver to issue a diag reset operation to recover IOC from fault
state and reinitialize the IOC.
Suganath Prabu S [Tue, 18 May 2021 05:16:23 +0000 (10:46 +0530)]
scsi: mpt3sas: Fix deadlock while cancelling the running firmware event
Do not cancel current running firmware event work if the event type is
different from MPT3SAS_REMOVE_UNRESPONDING_DEVICES. Otherwise a deadlock
can be observed while cancelling the current firmware event work if a hard
reset operation is called as part of processing the current event.
John Garry [Wed, 19 May 2021 14:31:02 +0000 (22:31 +0800)]
scsi: core: Cap scsi_host cmd_per_lun at can_queue
The sysfs handling function sdev_store_queue_depth() enforces that the sdev
queue depth cannot exceed shost can_queue. The initial sdev queue depth
comes from shost cmd_per_lun. However, the LLDD may manually set
cmd_per_lun to be larger than can_queue, which leads to an initial sdev
queue depth greater than can_queue.
Such an issue was reported in [0], which caused a hang. That has since been
fixed in commit fc09acb7de31 ("scsi: scsi_debug: Fix cmd_per_lun, set to
max_queue").
Stop this possibly happening for other drivers by capping shost cmd_per_lun
at shost can_queue.
James Smart [Fri, 14 May 2021 19:55:58 +0000 (12:55 -0700)]
scsi: lpfc: Reregister FPIN types if ELS_RDF is received from fabric controller
FC-LS-5 specifies that a received RDF implies a possible change to fabric
supported diagnostic functions. Endpoints are to re-perform the RDF
exchange with the fabric to enable possible new features or adapt to
changes in values.
This patch adds the logic to RDF receive to re-perform the RDF exchange
with the switch.
James Smart [Fri, 14 May 2021 19:55:57 +0000 (12:55 -0700)]
scsi: lpfc: Add a option to enable interlocked ABTS before job completion
Default behavior for the driver, when aborting an I/O, is to terminate the
I/O with the adapter. The adapter will initiate an ABTS to terminate the
exchange on the link and mark the exchange is terminated so that no further
use of the sgl or any traffic for the exchange is worked on. Completion on
the Abort is then posted to the driver, which as the I/O is terminated can
complete the I/O to the OS. This completion may occur prior to the ABTS
handshake completing on the wire. The ABTS handshake can take a long time
to complete with timeouts and retries reaching 60+ seconds. Note: if
retries fail, LOGO occurs.
Some devices want to ensure that the ABTS handshake fully completes (this
device has fully ack'd it) before the I/O completion is posted back to the
OS, where a failed I/O may be retried via a different path.
To support this behavior, an option was added to the driver to change I/O
completion from the Abort cmd completion to the Exchange termination (aka
ABTS) completion.
James Smart [Fri, 14 May 2021 19:55:55 +0000 (12:55 -0700)]
scsi: lpfc: Ignore GID-FT response that may be received after a link flip
When a link bounce happens, there is a possibility that responses to
requests posted prior to the link bounce could be received. This is
problematic as the counter to track reglogin completion after link up can
become out of sync with the real state.
As there is no reason to process a request made in a prior link up context,
eliminate all the disturbance by tagging the request with the event_tag
maintained by the SLI Port for the link. The event_tag will change on every
link state transition. As long as the tag matches the current event_tag,
the response can be processed. If it doesn't match, just discard the
response.
James Smart [Fri, 14 May 2021 19:55:54 +0000 (12:55 -0700)]
scsi: lpfc: Fix node handling for Fabric Controller and Domain Controller
During link bounce testing, RPI counts were seen to differ from the number
of nodes. For fabric and domain controllers, a temporary RPI is assigned,
but the code isn't registering it. If the nodes do go away, such as on link
down, the temporary RPI isn't being released.
Change the way these two fabric services are managed, make them behave like
any other remote port. Register the RPI and register with the transport.
Never leave the nodes in a NPR or UNUSED state where their RPI is in limbo.
This allows them to follow normal dev_loss_tmo handling, RPI refcounting,
and normal removal rules. It also allows fabric I/Os to use the RPI for
traffic requests.
Note: There is some logic that still has a couple of exceptions when the
Domain controller (0xfffcXX). There are cases where the fabric won't have a
valid login but will send RDP. Other times, it will it send a LOGO then an
RDP. It makes for ad-hoc behavior to manage the node. Exceptions are
documented in the code.
James Smart [Fri, 14 May 2021 19:55:53 +0000 (12:55 -0700)]
scsi: lpfc: Fix Node recovery when driver is handling simultaneous PLOGIs
When lpfc is handling a solicited and unsolicited PLOGI with another
initiator, the remote initiator is never recovered. The node for the
initiator is erroneouosly removed and all resources released.
In lpfc_cmpl_els_plogi(), when lpfc_els_retry() returns a failure code, the
driver is calling the state machine with a device remove event because the
remote port is not currently registered with the SCSI or NVMe
transports. The issue is that on a PLOGI "collision" the driver correctly
aborts the solicited PLOGI and allows the unsolicited PLOGI to complete the
process, but this process is interrupted with a device_rm event.
Introduce logic in the PLOGI completion to capture the PLOGI collision
event and jump out of the routine. This will avoid removal of the node.
If there is no collision, the normal node removal will occur.
James Smart [Fri, 14 May 2021 19:55:52 +0000 (12:55 -0700)]
scsi: lpfc: Add ndlp kref accounting for resume RPI path
The driver is crashing due to a bad pointer during driver load due in an
adisc acc receive routine. The driver is missing node get/put in the
mbx_resume_rpi paths.
Fix by adding the proper gets and puts into the resume_rpi path.
James Smart [Fri, 14 May 2021 19:55:51 +0000 (12:55 -0700)]
scsi: lpfc: Fix "Unexpected timeout" error in direct attach topology
An 'unexpected timeout' message may be seen in a point-2-point topology.
The message occurs when a PLOGI is received before the driver is notified
of FLOGI completion. The FLOGI completion failure causes discovery to be
triggered for a second time. The discovery timer is restarted but no new
discovery activity is initiated, thus the timeout message eventually
appears.
In point-2-point, when discovery has progressed before the FLOGI completion
is processed, it is not a failure. Add code to FLOGI completion to detect
that discovery has progressed and exit the FLOGI handling (noop'ing it).
James Smart [Fri, 14 May 2021 19:55:50 +0000 (12:55 -0700)]
scsi: lpfc: Fix non-optimized ERSP handling
When processing an NVMe ERSP IU which didn't match the optimized CQE-only
path, the status was being left to the WQE status. WQE status is non-zero
as it is indicating a non-optimized completion that needs to be handled by
the driver.
Fix by clearing the status field when falling into the non-optimized
case. Log message added to track optimized vs non-optimized debug.
James Smart [Fri, 14 May 2021 19:55:49 +0000 (12:55 -0700)]
scsi: lpfc: Fix unreleased RPIs when NPIV ports are created
While testing NPIV and watching logins and used RPI levels, it was seen the
used RPI count was much higher than the number of remote ports discovered.
Code inspection showed that remote port removals on any NPIV instance are
releasing the RPI, but not performing an UNREG_RPI with the adapter thus
the reference counting never fully drops and the RPI is never fully
released. This was happening on NPIV nodes due to a log of fabric ELS's to
fabric addresses. This lack of UNREG_RPI was introduced by a prior node
rework patch that performed the UNREG_RPI as part of node cleanup.
To resolve the issue, do the following:
- Restore the RPI release code, but move the location to so that it is in
line with the new node cleanup design.
- NPIV ports now release the RPI and drop the node when the caller sets
the NLP_RELEASE_RPI flag.
- Set the NLP_RELEASE_RPI flag in node cleanup which will trigger a
release of RPI to free pool.
- Ensure there's an UNREG_RPI at LOGO completion so that RPI release is
completed.
- Stop offline_prep from skipping nodes that are UNUSED. The RPI may
not have been released.
- Stop the default RPI handling in lpfc_cmpl_els_rsp() for SLI4.
- Fixed up debugfs RPI displays for better debugging.
Martin Wilck [Fri, 14 May 2021 15:32:14 +0000 (17:32 +0200)]
scsi: scsi_dh_alua: Retry RTPG on a different path after failure
If an RTPG fails, we can't infer anything wrt. the state of the ports in
the port group except that we were unable to reach the one port on which
the RTPG had failed. "offline" is just a secondary port state, which means
that we can't infer the state of any port in the PG from the failure (in
fact, even the failed port might still be in "active/optimized" primary
port access state).
Therefore, when we encounter an RTPG failure, we should retry the RTPG on a
different port. This avoids falsely setting port states to offline for
unreachable ports. To do this, ports on which an RTPG has failed are
temporarily set to "disabled" to avoid repeating the failed I/O on the same
target port. Once the RTPG has either succeeded on one port or failed on
all ports of the PG, the ports are enabled again.
Bart Van Assche [Wed, 19 May 2021 20:20:58 +0000 (13:20 -0700)]
scsi: ufs: Use designated initializers in ufs_pm_lvl_states[]
The comments in the enum ufs_pm_level definition are redundant. Remove the
comments from the ufs_pm_level enum and use designated initializers in the
ufs_pm_lvl_states[] definition instead.
Sergey Shtylyov [Wed, 19 May 2021 19:20:15 +0000 (22:20 +0300)]
scsi: hisi_sas: Propagate errors in interrupt_init_v1_hw()
After commit 6c11dc060427 ("scsi: hisi_sas: Fix IRQ checks") we have the
error codes returned by platform_get_irq() ready for the propagation
upsream in interrupt_init_v1_hw() -- that will fix still broken deferred
probing. Let's propagate the error codes from devm_request_irq() as well
since I don't see the reason to override them with -ENOENT...
Daniel Wagner [Thu, 20 May 2021 07:31:27 +0000 (09:31 +0200)]
scsi: scsi_transport_fc: Remove double FC_FPORT_DELETED in mask creation
Remove the double listed FC_FPORT_DELETING from the mask creation.
Commit 260f4aeddb48 ("scsi: scsi_transport_fc: return -EBUSY for deleted
vport") added VC_VPORT_DELETING to the flag masks. This is not necessary as
FC_FPORT_DEL is defined as VC_FPORT_DELETED | FC_FPORT_DELETING.
Bart Van Assche [Sun, 9 May 2021 21:38:17 +0000 (14:38 -0700)]
scsi: ufs: ufs-exynos: Move definitions from .h to .c
In the Linux kernel definitions of data structures should occur in .c
files. Hence move the exynos7_uic_attr definition from a .h into a .c
file. Additionally, declare exynos_ufs_drvs static. This patch fixes the
following two sparse warnings:
drivers/scsi/ufs/ufs-exynos.h:248:28: warning: symbol 'exynos_ufs_drvs' was not declared. Should it be static?
drivers/scsi/ufs/ufs-exynos.h:250:28: warning: symbol 'exynos7_uic_attr' was not declared. Should it be static?
Samuel Holland [Tue, 27 Apr 2021 23:59:15 +0000 (18:59 -0500)]
scsi: 3w-9xxx: Fix endianness issues in command packets
The controller expects all data it sends/receives to be little-endian.
Therefore, the packet struct definitions should use the __le16/32/64
types. Once those are correct, sparse reports several issues with the
driver code, which are fixed here as well.
The main issue observed was at the call to scsi_set_resid(), where the
byteswapped parameter would eventually trigger the alignment check at
drivers/scsi/sd.c:2009. At that point, the kernel would continuously
complain about an "Unaligned partial completion", and no further I/O could
occur.
This gets the controller working on big endian powerpc64.
Samuel Holland [Tue, 27 Apr 2021 23:59:14 +0000 (18:59 -0500)]
scsi: 3w-9xxx: Reduce scope of structure packing
Currently, all command packet structs used by this driver are packed.
However, only one (TW_SG_Entry) actually needs to be packed, because it
uses 64-bit addresses at 32-bit alignment. To improve the quality of
generated code, stop packing all of the other command packet structs. This
requires adjusting the type of one misaligned "reserved" member.
After this change, pahole reports that only one type had its layout change:
the tw_compat_info member of TW_Device_Extension is now naturally aligned.