···2626#include <linux/slab.h>2727#include <linux/swap.h>2828#include <linux/writeback.h>2929+#include <linux/interrupt.h>3030+#include <linux/cpu.h>29313032/*3133 * for max sense size···6361/*6462 * Controlling structure to kblockd6563 */6666-static struct workqueue_struct *kblockd_workqueue; 6464+static struct workqueue_struct *kblockd_workqueue;67656866unsigned long blk_max_low_pfn, blk_max_pfn;69677068EXPORT_SYMBOL(blk_max_low_pfn);7169EXPORT_SYMBOL(blk_max_pfn);7070+7171+static DEFINE_PER_CPU(struct list_head, blk_cpu_done);72727373/* Amount of time in which a process may batch requests */7474#define BLK_BATCH_TIME (HZ/50UL)···210206211207EXPORT_SYMBOL(blk_queue_merge_bvec);212208209209+void blk_queue_softirq_done(request_queue_t *q, softirq_done_fn *fn)210210+{211211+ q->softirq_done_fn = fn;212212+}213213+214214+EXPORT_SYMBOL(blk_queue_softirq_done);215215+213216/**214217 * blk_queue_make_request - define an alternate make_request function for a device215218 * @q: the request queue for the device to be affected···280269static inline void rq_init(request_queue_t *q, struct request *rq)281270{282271 INIT_LIST_HEAD(&rq->queuelist);272272+ INIT_LIST_HEAD(&rq->donelist);283273284274 rq->errors = 0;285275 rq->rq_status = RQ_ACTIVE;···297285 rq->sense = NULL;298286 rq->end_io = NULL;299287 rq->end_io_data = NULL;288288+ rq->completion_data = NULL;300289}301290302291/**···32753262EXPORT_SYMBOL(end_that_request_chunk);3276326332773264/*32653265+ * splice the completion data to a local structure and hand off to32663266+ * process_completion_queue() to complete the requests32673267+ */32683268+static void blk_done_softirq(struct softirq_action *h)32693269+{32703270+ struct list_head *cpu_list;32713271+ LIST_HEAD(local_list);32723272+32733273+ local_irq_disable();32743274+ cpu_list = &__get_cpu_var(blk_cpu_done);32753275+ list_splice_init(cpu_list, &local_list);32763276+ local_irq_enable();32773277+32783278+ while (!list_empty(&local_list)) {32793279+ struct request *rq = list_entry(local_list.next, struct request, donelist);32803280+32813281+ list_del_init(&rq->donelist);32823282+ rq->q->softirq_done_fn(rq);32833283+ }32843284+}32853285+32863286+#ifdef CONFIG_HOTPLUG_CPU32873287+32883288+static int blk_cpu_notify(struct notifier_block *self, unsigned long action,32893289+ void *hcpu)32903290+{32913291+ /*32923292+ * If a CPU goes away, splice its entries to the current CPU32933293+ * and trigger a run of the softirq32943294+ */32953295+ if (action == CPU_DEAD) {32963296+ int cpu = (unsigned long) hcpu;32973297+32983298+ local_irq_disable();32993299+ list_splice_init(&per_cpu(blk_cpu_done, cpu),33003300+ &__get_cpu_var(blk_cpu_done));33013301+ raise_softirq_irqoff(BLOCK_SOFTIRQ);33023302+ local_irq_enable();33033303+ }33043304+33053305+ return NOTIFY_OK;33063306+}33073307+33083308+33093309+static struct notifier_block __devinitdata blk_cpu_notifier = {33103310+ .notifier_call = blk_cpu_notify,33113311+};33123312+33133313+#endif /* CONFIG_HOTPLUG_CPU */33143314+33153315+/**33163316+ * blk_complete_request - end I/O on a request33173317+ * @req: the request being processed33183318+ *33193319+ * Description:33203320+ * Ends all I/O on a request. It does not handle partial completions,33213321+ * unless the driver actually implements this in its completionc callback33223322+ * through requeueing. Theh actual completion happens out-of-order,33233323+ * through a softirq handler. The user must have registered a completion33243324+ * callback through blk_queue_softirq_done().33253325+ **/33263326+33273327+void blk_complete_request(struct request *req)33283328+{33293329+ struct list_head *cpu_list;33303330+ unsigned long flags;33313331+33323332+ BUG_ON(!req->q->softirq_done_fn);33333333+33343334+ local_irq_save(flags);33353335+33363336+ cpu_list = &__get_cpu_var(blk_cpu_done);33373337+ list_add_tail(&req->donelist, cpu_list);33383338+ raise_softirq_irqoff(BLOCK_SOFTIRQ);33393339+33403340+ local_irq_restore(flags);33413341+}33423342+33433343+EXPORT_SYMBOL(blk_complete_request);33443344+33453345+/*32783346 * queue lock must be held32793347 */32803348void end_that_request_last(struct request *req, int uptodate)···3433333934343340int __init blk_dev_init(void)34353341{33423342+ int i;33433343+34363344 kblockd_workqueue = create_workqueue("kblockd");34373345 if (!kblockd_workqueue)34383346 panic("Failed to create kblockd\n");···3447335134483352 iocontext_cachep = kmem_cache_create("blkdev_ioc",34493353 sizeof(struct io_context), 0, SLAB_PANIC, NULL, NULL);33543354+33553355+ for (i = 0; i < NR_CPUS; i++)33563356+ INIT_LIST_HEAD(&per_cpu(blk_cpu_done, i));33573357+33583358+ open_softirq(BLOCK_SOFTIRQ, blk_done_softirq, NULL);33593359+#ifdef CONFIG_HOTPLUG_CPU33603360+ register_cpu_notifier(&blk_cpu_notifier);33613361+#endif3450336234513363 blk_max_low_pfn = max_low_pfn;34523364 blk_max_pfn = max_pfn;
+46-26
drivers/block/cciss.c
···2178217821792179 start_io(h);21802180}21812181+21822182+static void cciss_softirq_done(struct request *rq)21832183+{21842184+ CommandList_struct *cmd = rq->completion_data;21852185+ ctlr_info_t *h = hba[cmd->ctlr];21862186+ u64bit temp64;21872187+ int i, ddir;21882188+21892189+ if (cmd->Request.Type.Direction == XFER_READ)21902190+ ddir = PCI_DMA_FROMDEVICE;21912191+ else21922192+ ddir = PCI_DMA_TODEVICE;21932193+21942194+ /* command did not need to be retried */21952195+ /* unmap the DMA mapping for all the scatter gather elements */21962196+ for(i=0; i<cmd->Header.SGList; i++) {21972197+ temp64.val32.lower = cmd->SG[i].Addr.lower;21982198+ temp64.val32.upper = cmd->SG[i].Addr.upper;21992199+ pci_unmap_page(h->pdev, temp64.val, cmd->SG[i].Len, ddir);22002200+ }22012201+22022202+ complete_buffers(rq->bio, rq->errors);22032203+22042204+#ifdef CCISS_DEBUG22052205+ printk("Done with %p\n", rq);22062206+#endif /* CCISS_DEBUG */ 22072207+22082208+ spin_lock_irq(&h->lock);22092209+ end_that_request_last(rq, rq->errors);22102210+ cmd_free(h, cmd,1);22112211+ spin_unlock_irq(&h->lock);22122212+}22132213+21812214/* checks the status of the job and calls complete buffers to mark all 21822182- * buffers for the completed job. 22152215+ * buffers for the completed job. Note that this function does not need22162216+ * to hold the hba/queue lock.21832217 */ 21842218static inline void complete_command( ctlr_info_t *h, CommandList_struct *cmd,21852219 int timeout)21862220{21872221 int status = 1;21882188- int i;21892222 int retry_cmd = 0;21902190- u64bit temp64;2191222321922224 if (timeout)21932225 status = 0; ···23272295 resend_cciss_cmd(h,cmd);23282296 return;23292297 } 23302330- /* command did not need to be retried */23312331- /* unmap the DMA mapping for all the scatter gather elements */23322332- for(i=0; i<cmd->Header.SGList; i++) {23332333- temp64.val32.lower = cmd->SG[i].Addr.lower;23342334- temp64.val32.upper = cmd->SG[i].Addr.upper;23352335- pci_unmap_page(hba[cmd->ctlr]->pdev,23362336- temp64.val, cmd->SG[i].Len,23372337- (cmd->Request.Type.Direction == XFER_READ) ?23382338- PCI_DMA_FROMDEVICE : PCI_DMA_TODEVICE);23392339- }23402340- complete_buffers(cmd->rq->bio, status);2341229823422342-#ifdef CCISS_DEBUG23432343- printk("Done with %p\n", cmd->rq);23442344-#endif /* CCISS_DEBUG */ 23452345-23462346- end_that_request_last(cmd->rq, status ? 1 : -EIO);23472347- cmd_free(h,cmd,1);22992299+ cmd->rq->completion_data = cmd;23002300+ cmd->rq->errors = status;23012301+ blk_complete_request(cmd->rq);23482302}2349230323502304/* ···32173199 drv->queue = q;3218320032193201 q->backing_dev_info.ra_pages = READ_AHEAD;32203220- blk_queue_bounce_limit(q, hba[i]->pdev->dma_mask);32023202+ blk_queue_bounce_limit(q, hba[i]->pdev->dma_mask);3221320332223222- /* This is a hardware imposed limit. */32233223- blk_queue_max_hw_segments(q, MAXSGENTRIES);32043204+ /* This is a hardware imposed limit. */32053205+ blk_queue_max_hw_segments(q, MAXSGENTRIES);3224320632253225- /* This is a limit in the driver and could be eliminated. */32263226- blk_queue_max_phys_segments(q, MAXSGENTRIES);32073207+ /* This is a limit in the driver and could be eliminated. */32083208+ blk_queue_max_phys_segments(q, MAXSGENTRIES);3227320932283228- blk_queue_max_sectors(q, 512);32103210+ blk_queue_max_sectors(q, 512);32113211+32123212+ blk_queue_softirq_done(q, cciss_softirq_done);3229321332303214 q->queuedata = hba[i];32313215 sprintf(disk->disk_name, "cciss/c%dd%d", i, j);
+35-7
drivers/ide/ide-io.c
···5555#include <asm/io.h>5656#include <asm/bitops.h>57575858+void ide_softirq_done(struct request *rq)5959+{6060+ request_queue_t *q = rq->q;6161+6262+ add_disk_randomness(rq->rq_disk);6363+ end_that_request_chunk(rq, rq->errors, rq->data_len);6464+6565+ spin_lock_irq(q->queue_lock);6666+ end_that_request_last(rq, rq->errors);6767+ spin_unlock_irq(q->queue_lock);6868+}6969+5870int __ide_end_request(ide_drive_t *drive, struct request *rq, int uptodate,5971 int nr_sectors)6072{7373+ unsigned int nbytes;6174 int ret = 1;62756376 BUG_ON(!(rq->flags & REQ_STARTED));···9481 HWGROUP(drive)->hwif->ide_dma_on(drive);9582 }96839797- if (!end_that_request_first(rq, uptodate, nr_sectors)) {9898- add_disk_randomness(rq->rq_disk);9999-100100- if (blk_rq_tagged(rq))101101- blk_queue_end_tag(drive->queue, rq);102102-8484+ /*8585+ * For partial completions (or non fs/pc requests), use the regular8686+ * direct completion path.8787+ */8888+ nbytes = nr_sectors << 9;8989+ if (rq_all_done(rq, nbytes)) {9090+ rq->errors = uptodate;9191+ rq->data_len = nbytes;10392 blkdev_dequeue_request(rq);10493 HWGROUP(drive)->rq = NULL;105105- end_that_request_last(rq, uptodate);9494+ blk_complete_request(rq);10695 ret = 0;9696+ } else {9797+ if (!end_that_request_first(rq, uptodate, nr_sectors)) {9898+ add_disk_randomness(rq->rq_disk);9999+ blkdev_dequeue_request(rq);100100+ HWGROUP(drive)->rq = NULL;101101+ end_that_request_last(rq, uptodate);102102+ ret = 0;103103+ }107104 }105105+108106 return ret;109107}110108EXPORT_SYMBOL(__ide_end_request);···137113 unsigned long flags;138114 int ret = 1;139115116116+ /*117117+ * room for locking improvements here, the calls below don't118118+ * need the queue lock held at all119119+ */140120 spin_lock_irqsave(&ide_lock, flags);141121 rq = HWGROUP(drive)->rq;142122
···6969#include "scsi_logging.h"70707171static void scsi_done(struct scsi_cmnd *cmd);7272-static int scsi_retry_command(struct scsi_cmnd *cmd);73727473/*7574 * Definitions and constants.···751752 * isn't running --- used by scsi_times_out */752753void __scsi_done(struct scsi_cmnd *cmd)753754{754754- unsigned long flags;755755+ struct request *rq = cmd->request;755756756757 /*757758 * Set the serial numbers back to zero···762763 if (cmd->result)763764 atomic_inc(&cmd->device->ioerr_cnt);764765766766+ BUG_ON(!rq);767767+765768 /*766766- * Next, enqueue the command into the done queue.767767- * It is a per-CPU queue, so we just disable local interrupts768768- * and need no spinlock.769769+ * The uptodate/nbytes values don't matter, as we allow partial770770+ * completes and thus will check this in the softirq callback769771 */770770- local_irq_save(flags);771771- list_add_tail(&cmd->eh_entry, &__get_cpu_var(scsi_done_q));772772- raise_softirq_irqoff(SCSI_SOFTIRQ);773773- local_irq_restore(flags);774774-}775775-776776-/**777777- * scsi_softirq - Perform post-interrupt processing of finished SCSI commands.778778- *779779- * This is the consumer of the done queue.780780- *781781- * This is called with all interrupts enabled. This should reduce782782- * interrupt latency, stack depth, and reentrancy of the low-level783783- * drivers.784784- */785785-static void scsi_softirq(struct softirq_action *h)786786-{787787- int disposition;788788- LIST_HEAD(local_q);789789-790790- local_irq_disable();791791- list_splice_init(&__get_cpu_var(scsi_done_q), &local_q);792792- local_irq_enable();793793-794794- while (!list_empty(&local_q)) {795795- struct scsi_cmnd *cmd = list_entry(local_q.next,796796- struct scsi_cmnd, eh_entry);797797- /* The longest time any command should be outstanding is the798798- * per command timeout multiplied by the number of retries.799799- *800800- * For a typical command, this is 2.5 minutes */801801- unsigned long wait_for 802802- = cmd->allowed * cmd->timeout_per_command;803803- list_del_init(&cmd->eh_entry);804804-805805- disposition = scsi_decide_disposition(cmd);806806- if (disposition != SUCCESS &&807807- time_before(cmd->jiffies_at_alloc + wait_for, jiffies)) {808808- sdev_printk(KERN_ERR, cmd->device,809809- "timing out command, waited %lus\n",810810- wait_for/HZ);811811- disposition = SUCCESS;812812- }813813-814814- scsi_log_completion(cmd, disposition);815815- switch (disposition) {816816- case SUCCESS:817817- scsi_finish_command(cmd);818818- break;819819- case NEEDS_RETRY:820820- scsi_retry_command(cmd);821821- break;822822- case ADD_TO_MLQUEUE:823823- scsi_queue_insert(cmd, SCSI_MLQUEUE_DEVICE_BUSY);824824- break;825825- default:826826- if (!scsi_eh_scmd_add(cmd, 0))827827- scsi_finish_command(cmd);828828- }829829- }772772+ rq->completion_data = cmd;773773+ blk_complete_request(rq);830774}831775832776/*···782840 * level drivers should not become re-entrant as a result of783841 * this.784842 */785785-static int scsi_retry_command(struct scsi_cmnd *cmd)843843+int scsi_retry_command(struct scsi_cmnd *cmd)786844{787845 /*788846 * Restore the SCSI command state.···12151273}12161274EXPORT_SYMBOL(scsi_device_cancel);1217127512181218-#ifdef CONFIG_HOTPLUG_CPU12191219-static int scsi_cpu_notify(struct notifier_block *self,12201220- unsigned long action, void *hcpu)12211221-{12221222- int cpu = (unsigned long)hcpu;12231223-12241224- switch(action) {12251225- case CPU_DEAD:12261226- /* Drain scsi_done_q. */12271227- local_irq_disable();12281228- list_splice_init(&per_cpu(scsi_done_q, cpu),12291229- &__get_cpu_var(scsi_done_q));12301230- raise_softirq_irqoff(SCSI_SOFTIRQ);12311231- local_irq_enable();12321232- break;12331233- default:12341234- break;12351235- }12361236- return NOTIFY_OK;12371237-}12381238-12391239-static struct notifier_block __devinitdata scsi_cpu_nb = {12401240- .notifier_call = scsi_cpu_notify,12411241-};12421242-12431243-#define register_scsi_cpu() register_cpu_notifier(&scsi_cpu_nb)12441244-#define unregister_scsi_cpu() unregister_cpu_notifier(&scsi_cpu_nb)12451245-#else12461246-#define register_scsi_cpu()12471247-#define unregister_scsi_cpu()12481248-#endif /* CONFIG_HOTPLUG_CPU */12491249-12501276MODULE_DESCRIPTION("SCSI core");12511277MODULE_LICENSE("GPL");12521278···12481338 INIT_LIST_HEAD(&per_cpu(scsi_done_q, i));1249133912501340 devfs_mk_dir("scsi");12511251- open_softirq(SCSI_SOFTIRQ, scsi_softirq, NULL);12521252- register_scsi_cpu();12531341 printk(KERN_NOTICE "SCSI subsystem initialized\n");12541342 return 0;12551343···12751367 devfs_remove("scsi");12761368 scsi_exit_procfs();12771369 scsi_exit_queue();12781278- unregister_scsi_cpu();12791370}1280137112811372subsys_initcall(init_scsi);
+36
drivers/scsi/scsi_lib.c
···14931493 __scsi_done(cmd);14941494}1495149514961496+static void scsi_softirq_done(struct request *rq)14971497+{14981498+ struct scsi_cmnd *cmd = rq->completion_data;14991499+ unsigned long wait_for = cmd->allowed * cmd->timeout_per_command;15001500+ int disposition;15011501+15021502+ INIT_LIST_HEAD(&cmd->eh_entry);15031503+15041504+ disposition = scsi_decide_disposition(cmd);15051505+ if (disposition != SUCCESS &&15061506+ time_before(cmd->jiffies_at_alloc + wait_for, jiffies)) {15071507+ sdev_printk(KERN_ERR, cmd->device,15081508+ "timing out command, waited %lus\n",15091509+ wait_for/HZ);15101510+ disposition = SUCCESS;15111511+ }15121512+15131513+ scsi_log_completion(cmd, disposition);15141514+15151515+ switch (disposition) {15161516+ case SUCCESS:15171517+ scsi_finish_command(cmd);15181518+ break;15191519+ case NEEDS_RETRY:15201520+ scsi_retry_command(cmd);15211521+ break;15221522+ case ADD_TO_MLQUEUE:15231523+ scsi_queue_insert(cmd, SCSI_MLQUEUE_DEVICE_BUSY);15241524+ break;15251525+ default:15261526+ if (!scsi_eh_scmd_add(cmd, 0))15271527+ scsi_finish_command(cmd);15281528+ }15291529+}15301530+14961531/*14971532 * Function: scsi_request_fn()14981533 *···17021667 blk_queue_bounce_limit(q, scsi_calculate_bounce_limit(shost));17031668 blk_queue_segment_boundary(q, shost->dma_boundary);17041669 blk_queue_issue_flush_fn(q, scsi_issue_flush_fn);16701670+ blk_queue_softirq_done(q, scsi_softirq_done);1705167117061672 if (!shost->use_clustering)17071673 clear_bit(QUEUE_FLAG_CLUSTER, &q->queue_flags);
···118118 * try to put the fields that are referenced together in the same cacheline119119 */120120struct request {121121- struct list_head queuelist; /* looking for ->queue? you must _not_122122- * access it directly, use123123- * blkdev_dequeue_request! */121121+ struct list_head queuelist;122122+ struct list_head donelist;123123+124124 unsigned long flags; /* see REQ_ bits below */125125126126 /* Maintain bio traversal state for part by part I/O submission.···141141 struct bio *biotail;142142143143 void *elevator_private;144144+ void *completion_data;144145145146 unsigned short ioprio;146147···292291typedef void (activity_fn) (void *data, int rw);293292typedef int (issue_flush_fn) (request_queue_t *, struct gendisk *, sector_t *);294293typedef void (prepare_flush_fn) (request_queue_t *, struct request *);294294+typedef void (softirq_done_fn)(struct request *);295295296296enum blk_queue_state {297297 Queue_down,···334332 activity_fn *activity_fn;335333 issue_flush_fn *issue_flush_fn;336334 prepare_flush_fn *prepare_flush_fn;335335+ softirq_done_fn *softirq_done_fn;337336338337 /*339338 * Dispatch queue sorting···648645extern int end_that_request_chunk(struct request *, int, int);649646extern void end_that_request_last(struct request *, int);650647extern void end_request(struct request *req, int uptodate);648648+extern void blk_complete_request(struct request *);649649+650650+static inline int rq_all_done(struct request *rq, unsigned int nr_bytes)651651+{652652+ if (blk_fs_request(rq))653653+ return (nr_bytes >= (rq->hard_nr_sectors << 9));654654+ else if (blk_pc_request(rq))655655+ return nr_bytes >= rq->data_len;656656+657657+ return 0;658658+}651659652660/*653661 * end_that_request_first/chunk() takes an uptodate argument. we account···707693extern void blk_queue_prep_rq(request_queue_t *, prep_rq_fn *pfn);708694extern void blk_queue_merge_bvec(request_queue_t *, merge_bvec_fn *);709695extern void blk_queue_dma_alignment(request_queue_t *, int);696696+extern void blk_queue_softirq_done(request_queue_t *, softirq_done_fn *);710697extern struct backing_dev_info *blk_get_backing_dev_info(struct block_device *bdev);711698extern int blk_queue_ordered(request_queue_t *, unsigned, prepare_flush_fn *);712699extern void blk_queue_issue_flush_fn(request_queue_t *, issue_flush_fn *);
+1
include/linux/ide.h
···1001100110021002extern int ide_end_request (ide_drive_t *drive, int uptodate, int nrsecs);10031003extern int __ide_end_request (ide_drive_t *drive, struct request *rq, int uptodate, int nrsecs);10041004+extern void ide_softirq_done(struct request *rq);1004100510051006/*10061007 * This is used on exit from the driver to designate the next irq handler