Date: Mon, 29 Jul 1996 22:55:30 -0700 From: "Justin T. Gibbs" <gibbs@freefall.freebsd.org> To: scsi Subject: Large changes to the SCSI system -- please review Message-ID: <199607300555.WAA21852@freefall.freebsd.org>
next in thread | raw e-mail | index | archive | help
I've made some large changes to FreeBSD's SCSI system - changes that touch evey type driver and every controller driver. I've decided to upload the pathes for review and testing before I commit them. I have only tested these on the Adaptec 2742T with a scsi disk, dat tape, and cdrom drive, so I would only recommend you try these at this stage if you are interrested in debugging any problems you encounter. The patches to the NCR driver are not complete as the resource management is complex for that driver and I didn't feel I knew the code well enough (yet) to make them. Hopefully Stephan will be able to finish them off. Here's a list of what I've done: 1) Removed unnecessary members in data structures: There is still lots of work to be done on the current set of data structures. This was just a preliminary pass killing the obvious cruft. 2) Renamed flags and data structure members to lessen the differences with NetBSD: There are lots of gratuitous and some not so gratuitous differences between the two camps' SCSI code. I hope to bring the two code bases closer together over the next few months so that we can easily share controller drivers again. 3) Changed how transfers are queued, started, and completed: The original scsi system has had a long standing problem with how queued transactions are handled. The root of the problem comes from the policy of deferring the reservation of controller resources until way down in the controller scsi_cmd routine where we may not have a process context and thus cannot always sleep. With these patches, the scsi system relies almost entirely on queue management instead of sleeping to manage resources. More specifically, I've introduced a new data structure, the scsi_queue, that relates devices that share common controller resources. A scsi_queue has "openings" as do the individual scsi_links. A scsi_link is on the scsi_queue's run queue only when it has spare openings and work to do. When running a scsi_queue, the scsi_links are handled in round-robin fashion with each link allowed to send a single transaction per round. Before a transaction is dequeued, controller resources are obtained through scsi_link->get_cdb and attached to the scsi_xfer structure. get_cdb and free_cdb are two entry points provided by the controller drivers that encapsulate controller resource management. They should never be called directly by the controller driver (the wd7000 driver is the only exception to this rule). Transaction ordering is also maintained by locking the scsi_link off the run queue until the controller drivers acknowleges a command is started by calling scsi_xs_started(). This strategy should yield greater performance since a freed controller resource can start any scsi_link attached to that device instead of only attempting to start pending transactions on the device that just completed a transaction. The round-robin scheme also ensures resource fairness when devices with multiple openings compete for a small number of resources. The scheduling algorithm should be changed to support real-time priorities and the scsi_queue structure is an opaque type to the controller drivers to make this easier to accomplish. 4) Centralized error handling and "done" processing: The scsi_cmd entry point now returns void. The controller drivers now use exclusively scsi_done() along with a properly set scsi_xfer->error to report errors. This removes superflous code paths and duplicated code. 5) Commands are built directly in the scsi_xfer structure instead of on the stack: The original design forced each and every command structure to be copied into the scsi_xfer by the scsi_scsi_cmd routine. The scsi_xfer is now obtained up front and the command built directly into the scsi_xfer->cmd_store. The members of the scsi_xfer structure are filled in directly via an inline scsi_prepare_xs instead of stuffing all of them on the stack to simply be assigned into the scsi_xfer by scsi_scsi_cmd. scsi_scsi_cmd has also been replaced by scsi_schedule_xs(). 6) Converted individual controller resource management to use the queue(3) macros. Many of the drivers performed complicated list manipulations that were simplified by using the queue macros. The generic scsi layer's queue managment is also queue(3) based. 7) Removed error detection and reporting from the xxstart routines: The goal here is to make the xxstart routines as small and efficient as possible. Error detection occurs in the strategy routine or in the sense handlers. If an error is detected that may affect queued transactions, the new driver entry point clean_queue() is called to synchronously remove any entries that would have been gradually drained by the start routines in the past. 8) Added the complete driver entry point: The complete entry point is called as the last operation on a scsi_xfer before it is freed. This is the place where device usage statistic hooks should be added. In NetBSD, they have overloaded the scsi_done routine by adding an additional argument to serve this purpose which I think is the wrong approach. 9) Removed the async driver entry point: This entry point has never been used. 10) Brough in Jason Thorpe's ch driver. I haven't added the quirk entries for the supported changers yet, but we should probably invert the meaning of our quirks (probe multiple luns by default) first. For those of you who have made it this far, and want to brave all of these changes, the diffs can be found at: ftp://freefall.FreeBSD.org/incoming/scsi-diffs.970729.gz Architectural discussion, comments, diffs, and bug reports welcome. Thanks, -- Justin T. Gibbs =========================================== FreeBSD: Turning PCs into workstations ===========================================
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?199607300555.WAA21852>