protect the registers so it was trivially possible for a sync command and
i/o command to fight each other and confuse the controller. Make the
sync fib alloc/release functions inline and remove the somewhat worthless
AAC_SYNC_LOCK_FORCE flag. Thanks to Adil Katchi for helping me to track
this down in RELENG_4.
every iteration of aac_startio(). This ensures that a command that is
deferred for lack of resources doesn't immediately get retried in the
aac_startio() loop. This avoids an almost certain livelock.
Introduce d_version field in struct cdevsw, this must always be
initialized to D_VERSION.
Flip sense of D_NOGIANT flag to D_NEEDGIANT, this involves removing
four D_NOGIANT flags and adding 145 D_NEEDGIANT flags.
Previously the "struct disk" were owned by the device driver and this
gave us problems when the device disappared and the users of that device
were not immediately disappearing.
Now the struct disk is allocate with a new call, disk_alloc() and owned
by geom_disk and just abandonned by the device driver when disk_create()
is called.
Unfortunately, this results in a ton of "s/\./->/" changes to device
drivers.
Since I'm doing the sweep anyway, a couple of other API improvements
have been carried out at the same time:
The Giant awareness flag has been flipped from DISKFLAG_NOGIANT to
DISKFLAG_NEEDSGIANT
A version number have been added to disk_create() so that we can detect,
report and ignore binary drivers with old ABI in the future.
Manual page update to follow shortly.
on the card, unmap it first. This allows it to be picked up properly when
the queue gets kicked again. This was the root problem for the lost command
(i.e. stuck in getblk/vinvalb) problem. While here, panic if commands don't
map correctly instead of just silently ignoring the problem and dropping
command. Also slow down the dynamic allocation of new commands.
It should be safe to go back into the aac waters. Thanks to everyone who
suffered through this and provided good feedback.
edge cases in the loop.
- Try to grab a command before dequeueing the bio from the bioq. The old
behaviour of requeuing deferred bios to the end of the bioq is arguably
wrong. This should be fixed in the future to check the bioq head without
automatically dequeueing the bio.
interrupt handler so that no locks are needed, and schedules the
command completion routine with a taskqueue_fast. This also corrects the
locking in the command thread and removes the need for operation flags.
Simple load tests show that this is now considerably faster than FreeBSD 4.x
in the SMP case when multiple i/o tasks are running.
thread being waken up. The thread waken up can run at a priority as
high as after tsleep().
- Replace selwakeup()s with selwakeuppri()s and pass appropriate
priorities.
- Add cv_broadcastpri() which raises the priority of the broadcast
threads. Used by selwakeuppri() if collision occurs.
Not objected in: -arch, -current
- Correct the logic for the AIF array index pointers so that correct slot is
always looked at.
- Copy the full FIB payload size when copying AIF's, not just the first 64
bytes.
Thanks to Mirapoint, Inc, for pointing these problems out and offering a
solution.
a problem for command responses since we rarely ever filled the queue.
However, adapter-initiated commands have a much smaller queue and could
tickle this bug. It's possible that this might fix the recently reported
problems with the aac-2120s, though I haven't been able to reproduce the
problem locally.
MFC-After: 1 day
Add two new arguments to bus_dma_tag_create(): lockfunc and lockfuncarg.
Lockfunc allows a driver to provide a function for managing its locking
semantics while using busdma. At the moment, this is used for the
asynchronous busdma_swi and callback mechanism. Two lockfunc implementations
are provided: busdma_lock_mutex() performs standard mutex operations on the
mutex that is specified from lockfuncarg. dftl_lock() is a panic
implementation and is defaulted to when NULL, NULL are passed to
bus_dma_tag_create(). The only time that NULL, NULL should ever be used is
when the driver ensures that bus_dmamap_load() will not be deferred.
Drivers that do not provide their own locking can pass
busdma_lock_mutex,&Giant args in order to preserve the former behaviour.
sparc64 and powerpc do not provide real busdma_swi functions, so this is
largely a noop on those platforms. The busdma_swi on is64 is not properly
locked yet, so warnings will be emitted on this platform when busdma
callback deferrals happen.
If anyone gets panics or warnings from dflt_lock() being called, please
let me know right away.
Reviewed by: tmm, gibbs
as 64-bit architectures won't like this. Use virtual array indexes
instead. This *should* allow the driver to work on 64-bit platforms,
though it's still not endian clean.
Retain the mistake of not updating the devstat API for now.
Spell bioq_disksort() consistently with the remaining bioq_*().
#include <geom/geom_disk.h> where this is more appropriate.
is enabled when both the size of bus_addr_t > 4 and the card claims support.
Don't wake up the kthread to allocate more commands if we know that we've
already allocated the max number of commands.
- Add data structuress for doing 64-bit scatter/gather
- Move busdma tag creations around so that only the parent is
created in aac_pci.c.
- Retrieve the capabilities word from the firmware before setting
up command structures and tags. This allows the driver to decide
whether to do 64-bit commands, and if work-arounds are needed for
systems with >2GB of RAM.
- Only enable the SCSI passthrough if it's enabled in the capabilities
word in the firmware.
This should fix problems with the 2120S and 2200S cards in systems with more
than 2GB of RAM. Full 64-bit support is forthcoming.
MFC-After: 1 week
in geom_disk.c.
As a side effect this makes a lot of #include <sys/devicestat.h>
lines not needed and some biofinish() calls can be reduced to
biodone() again.
branches:
Initialize struct cdevsw using C99 sparse initializtion and remove
all initializations to default values.
This patch is automatically generated and has been tested by compiling
LINT with all the fields in struct cdevsw in reverse order on alpha,
sparc64 and i386.
Approved by: re(scottl)
- the mutex aac_io_lock protects the main codepaths which handle queues and
hardware registers. Only one acquire/release is done in the top-half and
the taskqueue. This mutex also applies to the userland command path and
CAM data path.
- Move the taskqueue to the new Giant-free version.
- Register the disk device with DISKFLAG_NOGIANT so the top-half processing
runs without Giant.
- Move the dynamic command allocator to the worker thread to avoid locking
issues with bus_dmamem_alloc().
This gives about 20% improvement in most of my benchmarks.
turns runs its tasks free of Giant too. It is intended that as drivers
become locked down, they will move out of the old, Giant-bound taskqueue
and into this new one. The old taskqueue has been renamed to
taskqueue_swi_giant, and the new one keeps the name taskqueue_swi.
field for holding driver-dependant data. Instead of putting the pointer
to the driver command struct in there, take advantage of these structs
being a (virtually) contiguous array and just put the array index in the
field.
that a command completion happened, all further processing is deferred to
a taskqueue. The taskqueue itself runs implicetely under Giant, but we
already used a taskqueue for the biodone() processing, so this at least
saves the contesting of Giant in the interrupt handler.
retain symetry with aac_alloc_commans(). Since aac_alloc_commands()
allocates fib maps and places them onto the fib lists, aac_free_commands()
should reverse those operations.
o Combine two ifs with the same body with an ||.
o Switch from uintptr_t to uint32_t for fib map load operations.
The target is a uint32_t so using this type for the map load call
avoids an extra cast. uintptr_t should only be used when you need
an "int sized the same as the machine's poitner size" which is not
the case here.
o Removed the commented out M_WAITOK flag in the allocation in
aac_alloc_commands(). The kernel will only block in the allocator
if it can grow the size of the kernel. This usually results in a
page-out which could involve this aac device. Thus, sleeping here
could deadlock the machine. Assuming this operation is occurring outside
of attach time, we have enough fibs to operate anyway, so waiting for
fibs to free up is okay if not optimal.
o In aac_alloc_commands(), if we cannot dmamem_alloc additional fib
space, free the fib map.
o In aac_alloc_commands(), if we cannot create per-command dmamaps, don't
lose track of the fib map that is mapping all of the commands that we
have already released into the free pool. Instead, just cut out of
the loop and modify aac_free_commands to not attempt to free maps that
have not been allocated.
o Don't use a magic number when pre-allocating fibs.
o Use PAGE_SIZE to allocate in page sized chunks instead of an
architecture specific constant.
Submitted by: gibbs