Commit Graph

161 Commits

Author SHA1 Message Date
Alexander Motin
79fab7d48a Stop further SCSI recovery attempts after one has failed.
We've got a set of probably damaged hard disks, reporting 0x04,0x02
("Logical unit not ready, initializing command required") in response
to READ CAPACITY(16), where attempts to use START STOP UNIT for recovery
results in 0x44,0x00 ("Internal target failure") after ~1 second delay.
As result of all recovery retries, device open attempt took ~3 seconds
before finally reporting to GEOM that device is opened, but has no media.
If the open was for writing and since it hasn't formally failed, following
close triggered GEOM retaste, opening device few more times with respective
delays.

This change reduces whole time of this cycle from ~12 seconds to ~3 by
giving up on recovery after the first failure.

Reviewed by:	ken
MFC after:	2 weeks
Sponsored by:	iXsystems, Inc.
2018-07-21 21:34:10 +00:00
Scott Long
7631477269 Add and fix comments for cam_periph_runccb()
Sponsored by:	Netflix
2018-05-01 17:48:50 +00:00
Warner Losh
d38677d23c Create a sysctl kern.cam.{,a,n}da.X.invalidate
kern.cam.{,a,n}da.X.invalidate=1 forces *daX to detach by calling
cam_periph_invalidate on the underlying periph. This is for testing
purposes only. Include only with options CAM_TEST_FAILURE and rename
the former [AN]DA_TEST_FAILURE, and fix nda to compile with it set.
We're using it at work to harden geom and the buffer cache to be
resilient in the face of drive failure. Today, it far too often
results in a panic. While much work was done on SIM initiated removal
for the USB thumnb drive removal work, little has been done for periph
initiated removal. This simulates what *daerror() does for some errors
nicely: we get the same panics with it that we do with failing drives.

Sponsored by: Netflix
Differential Revision: https://reviews.freebsd.org/D14581
2018-03-14 17:53:37 +00:00
Warner Losh
bc40691e40 Report the number of remaining retries when we have an error that
we're retrying.
2018-02-15 18:57:54 +00:00
Scott Long
99e7a4ad9e Return a C errno for cam_periph_acquire().
There's no compelling reason to return a cam_status type for this
function and doing so only creates confusion with normal C
coding practices. It's technically an API change, but the periph API
isn't widely used. No efffective change to operation.

Reviewed by:	imp, mav, ken
Sponsored by:	Netflix
Differential Revision:	D14063
2018-02-06 06:42:25 +00:00
Warner Losh
045f8bc8e4 When we crash, we'll stop the scheduler before we call the
shutdown_post_sync event.  For adashutdown, this causes problems
because we need to poll for completion of the commands, but we're not
yet officially dumping yet, so the code from r326964 assumed we could
use the interrupt-driven commands rather than the polled ones. This
lead to a hang. Prevent this by also checking to see if the scheduler
is stopped to do the polling.

Reported by: markj@
Sponsored by: Netflix
Differential Review: https://reviews.freebsd.org/D13845
2018-01-11 03:11:41 +00:00
Scott Long
04e814aecd Don't hold the periph lock when calling into cam_periph_runccb()
from the ada and da dump routines.  This avoids difficult locking
problems from needing to be handled.  While it might seem like this
would leave the periphs unprotected during dump, they were aleady
at risk of unexpected removal due to the dump functions not
keeping refcount state across the many calls that come in during
a dump.  This is an exercise for future work.

Obtained from:	Netflix
2018-01-09 00:10:59 +00:00
Warner Losh
5cf3cd108f When doing a dump, the scheduler is normally not running, so this
changed worked to capture dumps for me. However, the test for
SCHEDULER_STOPPED() isn't right. We can also call the dump routine
from ddb, in which case the scheduler is still running. This leads to
an assertion panic that we're sleeping when we shouldn't. Instead, use
the proper test for dumping or not. This brings us in line with other
places that do special things while we're doing polled I/O like this.

Noticed by: pho@
Differential Revision: https://reviews.freebsd.org/D13531
2017-12-19 04:13:22 +00:00
Warner Losh
762a7f4f5f Define xpt_path_inq.
This provides a nice wrarpper around the XPT_PATH_INQ ccb creation and
calling.

Sponsored by: Netflix
Differential Revision: https://reviews.freebsd.org/D13387
2017-12-06 23:05:22 +00:00
Warner Losh
f93a843cd2 Make cam_periph_runccb be safe to call when we can only do polling.
Sponsored by: Netflix
Differential Revision: https://reviews.freebsd.org/D13388
2017-12-06 23:05:07 +00:00
Warner Losh
553484ae07 Remove unused 4th argument to match the standard error routines.
Sponsored by: Netflix
Differential Revision: https://reviews.freebsd.org/D13386
2017-12-06 00:29:50 +00:00
Warner Losh
d2f3208dda Add NVME as a known device type for devstat processing.
Also, reduce the amount of cut and pasted code a little since only two
args are different in the devstat_end_transaction calls.

Sponsored by: Netflix
2017-12-06 00:29:43 +00:00
Pedro F. Giffuni
bec9534d1d sys/cam: further adoption of SPDX licensing ID tags.
Mainly focus on files that use BSD 2-Clause license, however the tool I
was using misidentified many licenses so this was mostly a manual - error
prone - task.

The Software Package Data Exchange (SPDX) group provides a specification
to make it easier for automated tools to detect and summarize well known
opensource licenses. We are gradually adopting the specification, noting
that the tags are considered only advisory and do not, in any way,
superceed or replace the license texts.
2017-11-27 15:12:43 +00:00
Warner Losh
df4245150a This adds CAM pass(4) support for NVMe IO's. Applications indicate
the IO type (Admin or NVM) using XPT op-codes XPT_NVME_ADMIN or
XPT_NVME_IO.

Submitted by:   Chuck Tuffli <chuck@tuffli.net>
Differential Revision:  https://reviews.freebsd.org/D10247
2017-07-14 14:52:20 +00:00
Warner Losh
a94a63f0a6 An MMC/SD/SDIO stack using CAM
Implement the MMC/SD/SDIO protocol within a CAM framework. CAM's
flexible queueing will make it easier to write non-storage drivers
than the legacy stack. SDIO drivers from both the kernel and as
userland daemons are possible, though much of that functionality will
come later.

Some of the CAM integration isn't complete (there are sleeps in the
device probe state machine, for example), but those minor issues can
be improved in-tree more easily than out of tree and shouldn't gate
progress on other fronts. Appologies to reviews if specific items
have been overlooked.

Submitted by: Ilya Bakulin
Reviewed by: emaste, imp, mav, adrian, ian
Differential Review: https://reviews.freebsd.org/D4761

merge with first commit, various compile hacks.
2017-07-09 16:57:24 +00:00
Kenneth D. Merry
59fe76647c Fix a panic in camperiphfree().
If a peripheral driver (e.g. da, sa, cd) is added or removed from the
peripheral driver list while an unrelated peripheral driver instance (e.g.
da0, sa5, cd2) is going away and is inside camperiphfree(), we could
dereference an invalid pointer.

When peripheral drivers are added or removed (see periphdriver_register()
and periphdriver_unregister()), the peripheral driver array is resized
and existing entries are moved.

Although we hold the topology lock while we traverse the peripheral driver
list, we retain a pointer to the location of the peripheral driver pointer
and then drop the topology lock.  So we are still vulnerable to the list
getting moved around while the lock is dropped.

To solve the problem, cache a copy of the peripheral driver pointer.  If
its storage location in the list changes while we have the lock dropped, it
won't have any effect.

This doesn't solve the issue that peripheral drivers ("da", "cd", as opposed
to individual instances like "da0", "cd0") are not generally part of a
reference counting scheme to guard against deregistering them while there
are instances active.  The caller (generally the person unloading a module)
has to be aware of active drivers and not unload something that is in use.

sys/cam/cam_periph.c:
	In camperiphfree(), cache a pointer to the peripheral driver
	instance to avoid holding a pointer to an invalid memory location
	in the event that the peripheral driver list changes while we have
	the topology lock dropped.

PR:		kern/219701
Submitted by:	avg
MFC after:	3 days
Sponsored by:	Spectra Logic
2017-06-27 19:26:02 +00:00
Scott Long
da0d7209e0 Fix an unsafe malloc usage with sbufs.
Reported by:	ken
Sponsored by:	Netflix
2017-05-03 05:33:15 +00:00
Scott Long
5d01277f59 Add infrastructure to the ATA and SCSI transports that supports
using a driver-supplied sbuf for printing device discovery
announcements. This helps ensure that messages to the console
will be properly serialized (through sbuf_putbuf) and not be
truncated and interleaved with other messages. The
infrastructure mirrors the existing xpt_announce_periph()
entry point and is opt-in for now. No content or formatting
changes are visible to the operator other than the new coherency.

While here, eliminate the stack usage of the temporary
announcement buffer in some of the drivers. It's moved to the
softc for now, but future work will eliminate it entirely by
making the code flow more linear. Future work will also address
locking so that the sbufs can be dynamically sized.

The scsi_da, scs_cd, scsi_ses, and ata_da drivers are converted
at this point, other drivers can be converted at a later date.
A tunable+sysctl, kern.cam.announce_nosbuf, exists for testing
purposes but will be removed later.

TODO:
Eliminate all of the code duplication and temporary buffers.  The
old printf-based methods will be retired, and xpt_announce_periph()
will just be a wrapper that uses a dynamically sized sbuf.  This
requires that the register and deregister paths be made malloc-safe,
which they aren't currently.

Sponsored by:	Netflix
2017-04-19 15:04:52 +00:00
Alexander Motin
94173c3c9b Add mechanism to unload CAM periph drivers.
For now it allows to unload CTL kernel module if there are no target-capable
SIMs in CAM.  As next step full teardown of CAM targets can be implemented.
2017-03-07 17:41:08 +00:00
Alexander Motin
4902e14dc8 Improve CAM_CDB_POINTER support.
MFC after:	2 weeks
2017-01-13 08:31:55 +00:00
Conrad Meyer
8532d381a9 Add BUF_TRACKING and FULL_BUF_TRACKING buffer debugging
Upstream the BUF_TRACKING and FULL_BUF_TRACKING buffer debugging code.
This can be handy in tracking down what code touched hung bios and bufs
last. The full history is especially useful, but adds enough bloat that
it shouldn't be enabled in release builds.

Function names (or arbitrary string constants) are tracked in a
fixed-size ring in bufs. Bios gain a pointer to the upper buf for
tracking. SCSI CCBs gain a pointer to the upper bio for tracking.

Reviewed by:	markj
Sponsored by:	Dell EMC Isilon
Differential Revision:	https://reviews.freebsd.org/D8366
2016-10-31 23:09:52 +00:00
Mark Johnston
991b5d2630 cam_periph_ccbwait could return while ccb in progress
In cam_periph_runccb, cam_periph_ccbwait was using the value of the ccb
pinfo.index and status fields to determine whether the ccb was done,
but these fields are updated without a contending lock and could glitch
into states that would be erroneously interpreted as done.  Instead,
have cam_periph_ccbwait look for the explicit result of the function
cam_periph_done.

Submitted by:	Ryan Libby <rlibby@gmail.com>
Reviewed by:	mav
MFC after:	3 weeks
Sponsored by:	Dell EMC Isilon
Differential Revision:	https://reviews.freebsd.org/D8020
2016-09-30 21:00:09 +00:00
Alexander Motin
cd3752643c Don't report to devd statuses that CAM doesn't consider errors.
Some statuses, such as "ATA pass through information available", are part
part of absolutely normal operation and do not worth reporting.

MFC after:	2 weeks
2016-09-08 13:33:33 +00:00
Eitan Adler
cef367e6a1 Don't repeat the the word 'the'
(one manual change to fix grammar)

Confirmed With: db
Approved by: secteam (not really, but this is a comment typo fix)
2016-05-17 12:52:31 +00:00
Scott Long
de482e7bbb Fix a memory leak in the devctl notify code.
Submitted by:	markj
MFC after:	asap
2016-05-03 14:30:26 +00:00
Pedro F. Giffuni
1ffe58516c sys/cam: spelling fixes in comments.
No functional change.
2016-04-29 21:05:48 +00:00
Warner Losh
e4cc6558b3 tag_action is not used at all in ata. It's set to 1 for ordered
transactions, but that value isn't used. It's bogusly used to report
in devstat, due to a cut and paste error from SCSI. Mark it as unused
in cam_fill_ataio. Reclaim the memory as a new ata_flags. In addition,
tag_id and init_id are completely unused, so reclaim those as 'unused'
now too. These were needlessly copied when ata was split from scsi.

This allows us, in the future, to create structures that can
communicate AUXILIARY regsiter to the SIMs, which cannot be done now.

Differential Revision: https://reviews.freebsd.org/D5598
2016-04-17 05:24:28 +00:00
Scott Long
a30ecd42b8 Add a devctl/devd notification conduit for CAM errors that happen at the
periph level.  When a relevant error is reported to the periph, some
amplifying information is gathered, and the error and information are fed
to devctl with the attributes / keys system=CAM, subsystem=periph.  The
'type' key will be either 'error' or 'timeout', and based on this, various
other keys are also populated.

The purpose of this is to provide a concise mechanism for error reporting
that is less noisy than the system console but higher in resolution and
fidelity than simple sysctl counters.  We will be using it at Netflix to
populate a structured log and database to track errors and error trends
across our world-wide population of drives.

Submitted by:	imp, scottl
Approved by:	kenm
MFC after:	3 days
Sponsored by:	Netflix
Differential Revision:	D5943
2016-04-14 21:55:42 +00:00
Alexander Motin
de2393124c Make pass, sg and targ drivers respect HBA's maxio.
Previous limitation of 64K (DFLTPHYS) is quite annoying.
2015-09-30 13:31:37 +00:00
Jeff Roberson
fade8dd714 Refactor unmapped buffer address handling.
- Use pointer assignment rather than a combination of pointers and
   flags to switch buffers between unmapped and mapped.  This eliminates
   multiple flags and generally simplifies the logic.
 - Eliminate b_saveaddr since it is only used with pager bufs which have
   their b_data re-initialized on each allocation.
 - Gather up some convenience routines in the buffer cache for
   manipulating buf space and buf malloc space.
 - Add an inline, buf_mapped(), to standardize checks around unmapped
   buffers.

In collaboration with: mlaier
Reviewed by:	kib
Tested by:	pho (many small revisions ago)
Sponsored by:	EMC / Isilon Storage Division
2015-07-23 19:13:41 +00:00
Edward Tomasz Napierala
5719711f8b Make periphdriver_register() take XPT lock when modifying the periph_drivers
array.

This fixes a panic that sometimes occured when kldloading ctl.ko.

Reviewed by:	mav@
MFC after:	1 month
Sponsored by:	The FreeBSD Foundation
2015-03-02 22:48:11 +00:00
Kenneth D. Merry
fd8be18f3f Fix I/O size calculation for pass(4) driver requests and add latency
tracking.

It is important to subtract the residual from the requested
transfer size to see how much data was actually transferred.  With
tape drives in particular, it is common to request more data than is
returned.

Also, add I/O latency tracking for CAM requests issued by
cam_periph_runccb().

If the caller supplies a struct devstat, and the I/O is a SCSI or
ATA I/O, we will track the elapsed time to provide I/O latency
statistics for the request.

sys/cam/scsi/cam_periph.c:
	In cam_periph_runccb(), subtract the residual when reporting I/O
	totals to devstat(9) for SCSI and ATA passthrough requests.

	In cam_periph_runccb(), grab the I/O start time and supply
	the start time to devstat_end_transaction() so that it can
	calculate the elapsed I/O time.

Sponsored by:	Spectra Logic
MFC after:	1 week
2015-02-27 21:35:36 +00:00
Alexander Motin
174b32ced4 Retry indefinitely on SCSI BUSY status from VMware disks and CDs.
VMware returns BUSY status when storage has transient connectivity issues.
It is often better to wait and let VM admin fix the problem then crash.

Discussed with:	ken
MFC after:	1 week
2015-02-02 20:23:05 +00:00
Marius Strobl
de6a705e34 Don't denounce peripherals on system shutdown. Together with r267321,
we're now back to the pre-r228483 level of default verbosity. This in
turn again typically allows for reading information that userland might
have printed on the screen before initiating a halt, but still permits
to debug potential device shutdown problems on system shutdown via
CAM_DEBUG etc.

Reviewed by:	mav
MFC after:	3 days
Sponsored by:	Bally Wulff Games & Entertainment GmbH
2014-06-19 09:08:20 +00:00
Alexander Motin
357478a5af Do not retry on CAM_FUNC_NOTAVAIL error, but return immediately.
MFC after:	2 weeks
2014-03-04 15:07:00 +00:00
Alexander Motin
c33e40291b Take additional reference on SCSI probe periph to cover its freeze count.
Otherwise periph may be invalidated and freed before single-stepping freeze
is dropped, causing use after free panic.
2014-01-11 13:35:36 +00:00
Alexander Motin
3231e8bddb Fix memory and references leak due to unfreed path.
Coverity CID:	1054773
2013-10-22 13:56:30 +00:00
Alexander Motin
227d67aa54 Merge CAM locking changes from the projects/camlock branch to radically
reduce lock congestion and improve SMP scalability of the SCSI/ATA stack,
preparing the ground for the coming next GEOM direct dispatch support.

Replace big per-SIM locks with bunch of smaller ones:
 - per-LUN locks to protect device and peripheral drivers state;
 - per-target locks to protect list of LUNs on target;
 - per-bus locks to protect reference counting;
 - per-send queue locks to protect queue of CCBs to be sent;
 - per-done queue locks to protect queue of completed CCBs;
 - remaining per-SIM locks now protect only HBA driver internals.

While holding LUN lock it is allowed (while not recommended for performance
reasons) to take SIM lock.  The opposite acquisition order is forbidden.
All the other locks are leaf locks, that can be taken anywhere, but should
not be cascaded.  Many functions, such as: xpt_action(), xpt_done(),
xpt_async(), xpt_create_path(), etc. are no longer require (but allow) SIM
lock to be held.

To keep compatibility and solve cases where SIM lock can't be dropped, all
xpt_async() calls in addition to xpt_done() calls are queued to completion
threads for async processing in clean environment without SIM lock held.

Instead of single CAM SWI thread, used for commands completion processing
before, use multiple (depending on number of CPUs) threads.  Load balanced
between them using "hash" of the device B:T:L address.

HBA drivers that can drop SIM lock during completion processing and have
sufficient number of completion threads to efficiently scale to multiple
CPUs can use new function xpt_done_direct() to avoid extra context switch.
Make ahci(4) driver to use this mechanism depending on hardware setup.

Sponsored by:	iXsystems, Inc.
MFC after:	2 months
2013-10-21 12:00:26 +00:00
Alexander Motin
8d36a71b76 Unify periph invalidation and destruction reporting.
Print message containing device model and serial number on invalidation.

Requested by:   glebius
MFC after:	1 week
2013-10-15 17:59:41 +00:00
Alexander Motin
0d4f3c316e Add debug trace points for freeze/release device queue. 2013-09-01 17:37:19 +00:00
Alexander Motin
a29779e865 Remove droping topology mutex after iterating 100 periphs in CAMGETPASSTHRU.
That is not so slow and so often operation to handle unneeded otherwise
xsoftc.xpt_generation and respective locking complications.
2013-08-07 11:34:20 +00:00
Alexander Motin
e5736ac88c Make some improvements to r253322 to really rescan target, not a bus.
Add there and in two more places checks for NULL on xpt_alloc_ccb_nowait().
2013-07-15 18:17:31 +00:00
Alexander Motin
0181d54b6b Improve handling of 0x3F/0x0E "Reported LUNs data has changed" and 0x25/0x00
"Logical unit not supported" errors.  First initiates specific target rescan,
second -- destroys specific LUN.  That allows to automatically detect changes
in list of device LUNs.  This mechanism doesn't work when target is completely
idle, but probably that is all what can be done without active polling.

Reviewed by:	ken
Sponsored by:	iXsystems, Inc.
2013-07-13 13:35:09 +00:00
Scott Long
95fbded695 Simplify the checking of flags for cam_periph_mapmem(). This gets rid of
a lot of code redundancy and grossness at very minor expense.

Reviewed by:	smh
Obtained from:	Netflix
MFC after:	3 days
2013-06-07 00:22:38 +00:00
Alexander Motin
d38c0e53a8 MFprojects/camlock r249541:
Give periph validity flag own periph reference.  That slightly simplifies
the release logic and covers hypothetical case if lock is dropped inside
the periph_oninval() method.
2013-04-27 12:39:28 +00:00
Alexander Motin
cccf422080 MFprojects/camlock r248890, r248897, r248898, r248900, r248903, r248905,
r248917, r248918, r248978, r249001, r249014, r249030:

Remove multilevel freezing mechanism, implemented to handle specifics of
the ATA/SATA error recovery, when post-reset recovery commands should be
allocated when queues are already full of payload requests.  Instead of
removing frozen CCBs with specified range of priorities from the queue
to provide free openings, use simple hack, allowing explicit CCBs over-
allocation for requests with priority higher (numerically lower) then
CAM_PRIORITY_OOB threshold.

Simplify CCB allocation logic by removing SIM-level allocation queue.
After that SIM-level queue manages only CCBs execution, while allocation
logic is localized within each single device.

Suggested by:	gibbs
2013-04-14 09:28:14 +00:00
Alexander Motin
dcdf6e7418 MFprojects/camlock:
r249017:
Some cosmetic things:
 - Unify device to target insertion inside xpt_alloc_device() instead of
duplicating it three times.
 - Remove extra checks for empty lists of devices and targets on release
since zero refcount check also implies it.
 - Reformat code to reduce indentation.

r249103:
 - Add lock assertions to every point where reference counters are modified.
 - When reference counters are reaching zero, add assertions that there are
no children items left.
 - Add a bit more locking to the xptpdperiphtraverse().
2013-04-04 20:31:40 +00:00
Edward Tomasz Napierala
9e0d30e20d Fix panic in the error path caused by recursive acquisition of XPT topology
lock.

Reviewed by:	ken
2013-04-02 09:38:04 +00:00
Konstantin Belousov
e81ff91e62 Do not remap usermode pages into KVA for physio.
Sponsored by:	The FreeBSD Foundation
Tested by:	pho
2013-03-19 14:43:57 +00:00
Konstantin Belousov
b4862fafd5 Assert that a ccb passed to cam_periph_mapmem() for XPT_SCSI_IO and
XPT_ATA_IO holds virtual buffer address.

Sponsored by:	The FreeBSD Foundation
Tested by:	pho
2013-03-19 13:10:14 +00:00