diff --git a/[refs] b/[refs] index 5427d4f262fd..bb62c6ddfa1e 100644 --- a/[refs] +++ b/[refs] @@ -1,2 +1,2 @@ --- -refs/heads/master: 14591de147f7c9656fa2b9c05680d2b46e286c40 +refs/heads/master: 17fa6e2f115ad734ef802b663071159a1a64d06f diff --git a/trunk/block/elevator.c b/trunk/block/elevator.c index 99a4d7b2f8ad..39dcccc82ada 100644 --- a/trunk/block/elevator.c +++ b/trunk/block/elevator.c @@ -64,7 +64,7 @@ inline int elv_rq_merge_ok(struct request *rq, struct bio *bio) } EXPORT_SYMBOL(elv_rq_merge_ok); -static inline int elv_try_merge(struct request *__rq, struct bio *bio) +inline int elv_try_merge(struct request *__rq, struct bio *bio) { int ret = ELEVATOR_NO_MERGE; @@ -80,6 +80,7 @@ static inline int elv_try_merge(struct request *__rq, struct bio *bio) return ret; } +EXPORT_SYMBOL(elv_try_merge); static struct elevator_type *elevator_find(const char *name) { diff --git a/trunk/block/ll_rw_blk.c b/trunk/block/ll_rw_blk.c index 8e27d0ab0d7c..91d3b4828c49 100644 --- a/trunk/block/ll_rw_blk.c +++ b/trunk/block/ll_rw_blk.c @@ -26,8 +26,7 @@ #include #include #include -#include -#include +#include /* * for max sense size @@ -63,15 +62,13 @@ static wait_queue_head_t congestion_wqh[2] = { /* * Controlling structure to kblockd */ -static struct workqueue_struct *kblockd_workqueue; +static struct workqueue_struct *kblockd_workqueue; unsigned long blk_max_low_pfn, blk_max_pfn; EXPORT_SYMBOL(blk_max_low_pfn); EXPORT_SYMBOL(blk_max_pfn); -static DEFINE_PER_CPU(struct list_head, blk_cpu_done); - /* Amount of time in which a process may batch requests */ #define BLK_BATCH_TIME (HZ/50UL) @@ -210,13 +207,6 @@ void blk_queue_merge_bvec(request_queue_t *q, merge_bvec_fn *mbfn) EXPORT_SYMBOL(blk_queue_merge_bvec); -void blk_queue_softirq_done(request_queue_t *q, softirq_done_fn *fn) -{ - q->softirq_done_fn = fn; -} - -EXPORT_SYMBOL(blk_queue_softirq_done); - /** * blk_queue_make_request - define an alternate make_request function for a device * @q: the request queue for the device to be affected @@ -280,7 +270,6 @@ EXPORT_SYMBOL(blk_queue_make_request); static inline void rq_init(request_queue_t *q, struct request *rq) { INIT_LIST_HEAD(&rq->queuelist); - INIT_LIST_HEAD(&rq->donelist); rq->errors = 0; rq->rq_status = RQ_ACTIVE; @@ -297,7 +286,6 @@ static inline void rq_init(request_queue_t *q, struct request *rq) rq->sense = NULL; rq->end_io = NULL; rq->end_io_data = NULL; - rq->completion_data = NULL; } /** @@ -2747,6 +2735,30 @@ static inline int attempt_front_merge(request_queue_t *q, struct request *rq) return 0; } +/** + * blk_attempt_remerge - attempt to remerge active head with next request + * @q: The &request_queue_t belonging to the device + * @rq: The head request (usually) + * + * Description: + * For head-active devices, the queue can easily be unplugged so quickly + * that proper merging is not done on the front request. This may hurt + * performance greatly for some devices. The block layer cannot safely + * do merging on that first request for these queues, but the driver can + * call this function and make it happen any way. Only the driver knows + * when it is safe to do so. + **/ +void blk_attempt_remerge(request_queue_t *q, struct request *rq) +{ + unsigned long flags; + + spin_lock_irqsave(q->queue_lock, flags); + attempt_back_merge(q, rq); + spin_unlock_irqrestore(q->queue_lock, flags); +} + +EXPORT_SYMBOL(blk_attempt_remerge); + static void init_request_from_bio(struct request *req, struct bio *bio) { req->flags |= REQ_CMD; @@ -3274,87 +3286,6 @@ int end_that_request_chunk(struct request *req, int uptodate, int nr_bytes) EXPORT_SYMBOL(end_that_request_chunk); -/* - * splice the completion data to a local structure and hand off to - * process_completion_queue() to complete the requests - */ -static void blk_done_softirq(struct softirq_action *h) -{ - struct list_head *cpu_list; - LIST_HEAD(local_list); - - local_irq_disable(); - cpu_list = &__get_cpu_var(blk_cpu_done); - list_splice_init(cpu_list, &local_list); - local_irq_enable(); - - while (!list_empty(&local_list)) { - struct request *rq = list_entry(local_list.next, struct request, donelist); - - list_del_init(&rq->donelist); - rq->q->softirq_done_fn(rq); - } -} - -#ifdef CONFIG_HOTPLUG_CPU - -static int blk_cpu_notify(struct notifier_block *self, unsigned long action, - void *hcpu) -{ - /* - * If a CPU goes away, splice its entries to the current CPU - * and trigger a run of the softirq - */ - if (action == CPU_DEAD) { - int cpu = (unsigned long) hcpu; - - local_irq_disable(); - list_splice_init(&per_cpu(blk_cpu_done, cpu), - &__get_cpu_var(blk_cpu_done)); - raise_softirq_irqoff(BLOCK_SOFTIRQ); - local_irq_enable(); - } - - return NOTIFY_OK; -} - - -static struct notifier_block __devinitdata blk_cpu_notifier = { - .notifier_call = blk_cpu_notify, -}; - -#endif /* CONFIG_HOTPLUG_CPU */ - -/** - * blk_complete_request - end I/O on a request - * @req: the request being processed - * - * Description: - * Ends all I/O on a request. It does not handle partial completions, - * unless the driver actually implements this in its completionc callback - * through requeueing. Theh actual completion happens out-of-order, - * through a softirq handler. The user must have registered a completion - * callback through blk_queue_softirq_done(). - **/ - -void blk_complete_request(struct request *req) -{ - struct list_head *cpu_list; - unsigned long flags; - - BUG_ON(!req->q->softirq_done_fn); - - local_irq_save(flags); - - cpu_list = &__get_cpu_var(blk_cpu_done); - list_add_tail(&req->donelist, cpu_list); - raise_softirq_irqoff(BLOCK_SOFTIRQ); - - local_irq_restore(flags); -} - -EXPORT_SYMBOL(blk_complete_request); - /* * queue lock must be held */ @@ -3433,8 +3364,6 @@ EXPORT_SYMBOL(kblockd_flush); int __init blk_dev_init(void) { - int i; - kblockd_workqueue = create_workqueue("kblockd"); if (!kblockd_workqueue) panic("Failed to create kblockd\n"); @@ -3448,14 +3377,6 @@ int __init blk_dev_init(void) iocontext_cachep = kmem_cache_create("blkdev_ioc", sizeof(struct io_context), 0, SLAB_PANIC, NULL, NULL); - for (i = 0; i < NR_CPUS; i++) - INIT_LIST_HEAD(&per_cpu(blk_cpu_done, i)); - - open_softirq(BLOCK_SOFTIRQ, blk_done_softirq, NULL); -#ifdef CONFIG_HOTPLUG_CPU - register_cpu_notifier(&blk_cpu_notifier); -#endif - blk_max_low_pfn = max_low_pfn; blk_max_pfn = max_pfn; diff --git a/trunk/block/scsi_ioctl.c b/trunk/block/scsi_ioctl.c index 18de84c8ccd8..c2ac36dfe4f3 100644 --- a/trunk/block/scsi_ioctl.c +++ b/trunk/block/scsi_ioctl.c @@ -190,21 +190,16 @@ static int verify_command(struct file *file, unsigned char *cmd) safe_for_write(GPCMD_SET_STREAMING), }; unsigned char type = cmd_type[cmd[0]]; - int has_write_perm = 0; /* Anybody who can open the device can do a read-safe command */ if (type & CMD_READ_SAFE) return 0; - /* - * file can be NULL from ioctl_by_bdev()... - */ - if (file) - has_write_perm = file->f_mode & FMODE_WRITE; - /* Write-safe commands just require a writable open.. */ - if ((type & CMD_WRITE_SAFE) && has_write_perm) - return 0; + if (type & CMD_WRITE_SAFE) { + if (file->f_mode & FMODE_WRITE) + return 0; + } /* And root can do any command.. */ if (capable(CAP_SYS_RAWIO)) diff --git a/trunk/drivers/block/cciss.c b/trunk/drivers/block/cciss.c index e4e9f255bd1f..88452c79fb64 100644 --- a/trunk/drivers/block/cciss.c +++ b/trunk/drivers/block/cciss.c @@ -2178,48 +2178,16 @@ static inline void resend_cciss_cmd( ctlr_info_t *h, CommandList_struct *c) start_io(h); } - -static void cciss_softirq_done(struct request *rq) -{ - CommandList_struct *cmd = rq->completion_data; - ctlr_info_t *h = hba[cmd->ctlr]; - u64bit temp64; - int i, ddir; - - if (cmd->Request.Type.Direction == XFER_READ) - ddir = PCI_DMA_FROMDEVICE; - else - ddir = PCI_DMA_TODEVICE; - - /* command did not need to be retried */ - /* unmap the DMA mapping for all the scatter gather elements */ - for(i=0; iHeader.SGList; i++) { - temp64.val32.lower = cmd->SG[i].Addr.lower; - temp64.val32.upper = cmd->SG[i].Addr.upper; - pci_unmap_page(h->pdev, temp64.val, cmd->SG[i].Len, ddir); - } - - complete_buffers(rq->bio, rq->errors); - -#ifdef CCISS_DEBUG - printk("Done with %p\n", rq); -#endif /* CCISS_DEBUG */ - - spin_lock_irq(&h->lock); - end_that_request_last(rq, rq->errors); - cmd_free(h, cmd,1); - spin_unlock_irq(&h->lock); -} - /* checks the status of the job and calls complete buffers to mark all - * buffers for the completed job. Note that this function does not need - * to hold the hba/queue lock. + * buffers for the completed job. */ static inline void complete_command( ctlr_info_t *h, CommandList_struct *cmd, int timeout) { int status = 1; + int i; int retry_cmd = 0; + u64bit temp64; if (timeout) status = 0; @@ -2327,10 +2295,24 @@ static inline void complete_command( ctlr_info_t *h, CommandList_struct *cmd, resend_cciss_cmd(h,cmd); return; } + /* command did not need to be retried */ + /* unmap the DMA mapping for all the scatter gather elements */ + for(i=0; iHeader.SGList; i++) { + temp64.val32.lower = cmd->SG[i].Addr.lower; + temp64.val32.upper = cmd->SG[i].Addr.upper; + pci_unmap_page(hba[cmd->ctlr]->pdev, + temp64.val, cmd->SG[i].Len, + (cmd->Request.Type.Direction == XFER_READ) ? + PCI_DMA_FROMDEVICE : PCI_DMA_TODEVICE); + } + complete_buffers(cmd->rq->bio, status); + +#ifdef CCISS_DEBUG + printk("Done with %p\n", cmd->rq); +#endif /* CCISS_DEBUG */ - cmd->rq->completion_data = cmd; - cmd->rq->errors = status; - blk_complete_request(cmd->rq); + end_that_request_last(cmd->rq, status ? 1 : -EIO); + cmd_free(h,cmd,1); } /* @@ -3217,17 +3199,15 @@ static int __devinit cciss_init_one(struct pci_dev *pdev, drv->queue = q; q->backing_dev_info.ra_pages = READ_AHEAD; - blk_queue_bounce_limit(q, hba[i]->pdev->dma_mask); - - /* This is a hardware imposed limit. */ - blk_queue_max_hw_segments(q, MAXSGENTRIES); + blk_queue_bounce_limit(q, hba[i]->pdev->dma_mask); - /* This is a limit in the driver and could be eliminated. */ - blk_queue_max_phys_segments(q, MAXSGENTRIES); + /* This is a hardware imposed limit. */ + blk_queue_max_hw_segments(q, MAXSGENTRIES); - blk_queue_max_sectors(q, 512); + /* This is a limit in the driver and could be eliminated. */ + blk_queue_max_phys_segments(q, MAXSGENTRIES); - blk_queue_softirq_done(q, cciss_softirq_done); + blk_queue_max_sectors(q, 512); q->queuedata = hba[i]; sprintf(disk->disk_name, "cciss/c%dd%d", i, j); diff --git a/trunk/drivers/ide/ide-cd.c b/trunk/drivers/ide/ide-cd.c index e4d55ad32d2f..d31117eb95aa 100644 --- a/trunk/drivers/ide/ide-cd.c +++ b/trunk/drivers/ide/ide-cd.c @@ -1332,6 +1332,8 @@ static ide_startstop_t cdrom_start_read (ide_drive_t *drive, unsigned int block) if (cdrom_read_from_buffer(drive)) return ide_stopped; + blk_attempt_remerge(drive->queue, rq); + /* Clear the local sector buffer. */ info->nsectors_buffered = 0; @@ -1872,6 +1874,14 @@ static ide_startstop_t cdrom_start_write(ide_drive_t *drive, struct request *rq) return ide_stopped; } + /* + * for dvd-ram and such media, it's a really big deal to get + * big writes all the time. so scour the queue and attempt to + * remerge requests, often the plugging will not have had time + * to do this properly + */ + blk_attempt_remerge(drive->queue, rq); + info->nsectors_buffered = 0; /* use dma, if possible. we don't need to check more, since we diff --git a/trunk/drivers/ide/ide-io.c b/trunk/drivers/ide/ide-io.c index dea2d4dcc698..b5dc6df8e67d 100644 --- a/trunk/drivers/ide/ide-io.c +++ b/trunk/drivers/ide/ide-io.c @@ -55,22 +55,9 @@ #include #include -void ide_softirq_done(struct request *rq) -{ - request_queue_t *q = rq->q; - - add_disk_randomness(rq->rq_disk); - end_that_request_chunk(rq, rq->errors, rq->data_len); - - spin_lock_irq(q->queue_lock); - end_that_request_last(rq, rq->errors); - spin_unlock_irq(q->queue_lock); -} - int __ide_end_request(ide_drive_t *drive, struct request *rq, int uptodate, int nr_sectors) { - unsigned int nbytes; int ret = 1; BUG_ON(!(rq->flags & REQ_STARTED)); @@ -94,28 +81,17 @@ int __ide_end_request(ide_drive_t *drive, struct request *rq, int uptodate, HWGROUP(drive)->hwif->ide_dma_on(drive); } - /* - * For partial completions (or non fs/pc requests), use the regular - * direct completion path. - */ - nbytes = nr_sectors << 9; - if (rq_all_done(rq, nbytes)) { - rq->errors = uptodate; - rq->data_len = nbytes; + if (!end_that_request_first(rq, uptodate, nr_sectors)) { + add_disk_randomness(rq->rq_disk); + + if (blk_rq_tagged(rq)) + blk_queue_end_tag(drive->queue, rq); + blkdev_dequeue_request(rq); HWGROUP(drive)->rq = NULL; - blk_complete_request(rq); + end_that_request_last(rq, uptodate); ret = 0; - } else { - if (!end_that_request_first(rq, uptodate, nr_sectors)) { - add_disk_randomness(rq->rq_disk); - blkdev_dequeue_request(rq); - HWGROUP(drive)->rq = NULL; - end_that_request_last(rq, uptodate); - ret = 0; - } } - return ret; } EXPORT_SYMBOL(__ide_end_request); @@ -137,10 +113,6 @@ int ide_end_request (ide_drive_t *drive, int uptodate, int nr_sectors) unsigned long flags; int ret = 1; - /* - * room for locking improvements here, the calls below don't - * need the queue lock held at all - */ spin_lock_irqsave(&ide_lock, flags); rq = HWGROUP(drive)->rq; diff --git a/trunk/drivers/ide/ide-probe.c b/trunk/drivers/ide/ide-probe.c index 1ddaa71a8f45..02167a5b751d 100644 --- a/trunk/drivers/ide/ide-probe.c +++ b/trunk/drivers/ide/ide-probe.c @@ -1011,8 +1011,6 @@ static int ide_init_queue(ide_drive_t *drive) blk_queue_max_hw_segments(q, max_sg_entries); blk_queue_max_phys_segments(q, max_sg_entries); - blk_queue_softirq_done(q, ide_softirq_done); - /* assign drive queue */ drive->queue = q; diff --git a/trunk/drivers/net/sk98lin/skge.c b/trunk/drivers/net/sk98lin/skge.c index 9a76ac180b11..3302d644011f 100644 --- a/trunk/drivers/net/sk98lin/skge.c +++ b/trunk/drivers/net/sk98lin/skge.c @@ -282,10 +282,11 @@ SK_U32 Val) /* pointer to store the read value */ * Description: * This function initialize the PCI resources and IO * - * Returns: N/A - * + * Returns: + * 0 - indicate everything worked ok. + * != 0 - error indication */ -int SkGeInitPCI(SK_AC *pAC) +static __devinit int SkGeInitPCI(SK_AC *pAC) { struct SK_NET_DEVICE *dev = pAC->dev[0]; struct pci_dev *pdev = pAC->PciDev; @@ -492,7 +493,7 @@ module_param_array(AutoSizing, charp, NULL, 0); * 0, if everything is ok * !=0, on error */ -static int __init SkGeBoardInit(struct SK_NET_DEVICE *dev, SK_AC *pAC) +static int __devinit SkGeBoardInit(struct SK_NET_DEVICE *dev, SK_AC *pAC) { short i; unsigned long Flags; @@ -633,8 +634,7 @@ SK_BOOL DualNet; * SK_TRUE, if all memory could be allocated * SK_FALSE, if not */ -static SK_BOOL BoardAllocMem( -SK_AC *pAC) +static __devinit SK_BOOL BoardAllocMem(SK_AC *pAC) { caddr_t pDescrMem; /* pointer to descriptor memory area */ size_t AllocLength; /* length of complete descriptor area */ @@ -727,8 +727,7 @@ size_t AllocLength; /* length of complete descriptor area */ * * Returns: N/A */ -static void BoardInitMem( -SK_AC *pAC) /* pointer to adapter context */ +static __devinit void BoardInitMem(SK_AC *pAC) { int i; /* loop counter */ int RxDescrSize; /* the size of a rx descriptor rounded up to alignment*/ diff --git a/trunk/drivers/scsi/scsi.c b/trunk/drivers/scsi/scsi.c index ee5f4dfdab14..180676d7115a 100644 --- a/trunk/drivers/scsi/scsi.c +++ b/trunk/drivers/scsi/scsi.c @@ -69,6 +69,7 @@ #include "scsi_logging.h" static void scsi_done(struct scsi_cmnd *cmd); +static int scsi_retry_command(struct scsi_cmnd *cmd); /* * Definitions and constants. @@ -751,7 +752,7 @@ static void scsi_done(struct scsi_cmnd *cmd) * isn't running --- used by scsi_times_out */ void __scsi_done(struct scsi_cmnd *cmd) { - struct request *rq = cmd->request; + unsigned long flags; /* * Set the serial numbers back to zero @@ -762,14 +763,71 @@ void __scsi_done(struct scsi_cmnd *cmd) if (cmd->result) atomic_inc(&cmd->device->ioerr_cnt); - BUG_ON(!rq); - /* - * The uptodate/nbytes values don't matter, as we allow partial - * completes and thus will check this in the softirq callback + * Next, enqueue the command into the done queue. + * It is a per-CPU queue, so we just disable local interrupts + * and need no spinlock. */ - rq->completion_data = cmd; - blk_complete_request(rq); + local_irq_save(flags); + list_add_tail(&cmd->eh_entry, &__get_cpu_var(scsi_done_q)); + raise_softirq_irqoff(SCSI_SOFTIRQ); + local_irq_restore(flags); +} + +/** + * scsi_softirq - Perform post-interrupt processing of finished SCSI commands. + * + * This is the consumer of the done queue. + * + * This is called with all interrupts enabled. This should reduce + * interrupt latency, stack depth, and reentrancy of the low-level + * drivers. + */ +static void scsi_softirq(struct softirq_action *h) +{ + int disposition; + LIST_HEAD(local_q); + + local_irq_disable(); + list_splice_init(&__get_cpu_var(scsi_done_q), &local_q); + local_irq_enable(); + + while (!list_empty(&local_q)) { + struct scsi_cmnd *cmd = list_entry(local_q.next, + struct scsi_cmnd, eh_entry); + /* The longest time any command should be outstanding is the + * per command timeout multiplied by the number of retries. + * + * For a typical command, this is 2.5 minutes */ + unsigned long wait_for + = cmd->allowed * cmd->timeout_per_command; + list_del_init(&cmd->eh_entry); + + disposition = scsi_decide_disposition(cmd); + if (disposition != SUCCESS && + time_before(cmd->jiffies_at_alloc + wait_for, jiffies)) { + sdev_printk(KERN_ERR, cmd->device, + "timing out command, waited %lus\n", + wait_for/HZ); + disposition = SUCCESS; + } + + scsi_log_completion(cmd, disposition); + switch (disposition) { + case SUCCESS: + scsi_finish_command(cmd); + break; + case NEEDS_RETRY: + scsi_retry_command(cmd); + break; + case ADD_TO_MLQUEUE: + scsi_queue_insert(cmd, SCSI_MLQUEUE_DEVICE_BUSY); + break; + default: + if (!scsi_eh_scmd_add(cmd, 0)) + scsi_finish_command(cmd); + } + } } /* @@ -782,7 +840,7 @@ void __scsi_done(struct scsi_cmnd *cmd) * level drivers should not become re-entrant as a result of * this. */ -int scsi_retry_command(struct scsi_cmnd *cmd) +static int scsi_retry_command(struct scsi_cmnd *cmd) { /* * Restore the SCSI command state. @@ -1215,6 +1273,38 @@ int scsi_device_cancel(struct scsi_device *sdev, int recovery) } EXPORT_SYMBOL(scsi_device_cancel); +#ifdef CONFIG_HOTPLUG_CPU +static int scsi_cpu_notify(struct notifier_block *self, + unsigned long action, void *hcpu) +{ + int cpu = (unsigned long)hcpu; + + switch(action) { + case CPU_DEAD: + /* Drain scsi_done_q. */ + local_irq_disable(); + list_splice_init(&per_cpu(scsi_done_q, cpu), + &__get_cpu_var(scsi_done_q)); + raise_softirq_irqoff(SCSI_SOFTIRQ); + local_irq_enable(); + break; + default: + break; + } + return NOTIFY_OK; +} + +static struct notifier_block __devinitdata scsi_cpu_nb = { + .notifier_call = scsi_cpu_notify, +}; + +#define register_scsi_cpu() register_cpu_notifier(&scsi_cpu_nb) +#define unregister_scsi_cpu() unregister_cpu_notifier(&scsi_cpu_nb) +#else +#define register_scsi_cpu() +#define unregister_scsi_cpu() +#endif /* CONFIG_HOTPLUG_CPU */ + MODULE_DESCRIPTION("SCSI core"); MODULE_LICENSE("GPL"); @@ -1248,6 +1338,8 @@ static int __init init_scsi(void) INIT_LIST_HEAD(&per_cpu(scsi_done_q, i)); devfs_mk_dir("scsi"); + open_softirq(SCSI_SOFTIRQ, scsi_softirq, NULL); + register_scsi_cpu(); printk(KERN_NOTICE "SCSI subsystem initialized\n"); return 0; @@ -1275,6 +1367,7 @@ static void __exit exit_scsi(void) devfs_remove("scsi"); scsi_exit_procfs(); scsi_exit_queue(); + unregister_scsi_cpu(); } subsys_initcall(init_scsi); diff --git a/trunk/drivers/scsi/scsi_lib.c b/trunk/drivers/scsi/scsi_lib.c index 00c9bf383e23..ba93d6e66d48 100644 --- a/trunk/drivers/scsi/scsi_lib.c +++ b/trunk/drivers/scsi/scsi_lib.c @@ -1493,41 +1493,6 @@ static void scsi_kill_request(struct request *req, request_queue_t *q) __scsi_done(cmd); } -static void scsi_softirq_done(struct request *rq) -{ - struct scsi_cmnd *cmd = rq->completion_data; - unsigned long wait_for = cmd->allowed * cmd->timeout_per_command; - int disposition; - - INIT_LIST_HEAD(&cmd->eh_entry); - - disposition = scsi_decide_disposition(cmd); - if (disposition != SUCCESS && - time_before(cmd->jiffies_at_alloc + wait_for, jiffies)) { - sdev_printk(KERN_ERR, cmd->device, - "timing out command, waited %lus\n", - wait_for/HZ); - disposition = SUCCESS; - } - - scsi_log_completion(cmd, disposition); - - switch (disposition) { - case SUCCESS: - scsi_finish_command(cmd); - break; - case NEEDS_RETRY: - scsi_retry_command(cmd); - break; - case ADD_TO_MLQUEUE: - scsi_queue_insert(cmd, SCSI_MLQUEUE_DEVICE_BUSY); - break; - default: - if (!scsi_eh_scmd_add(cmd, 0)) - scsi_finish_command(cmd); - } -} - /* * Function: scsi_request_fn() * @@ -1702,7 +1667,6 @@ struct request_queue *scsi_alloc_queue(struct scsi_device *sdev) blk_queue_bounce_limit(q, scsi_calculate_bounce_limit(shost)); blk_queue_segment_boundary(q, shost->dma_boundary); blk_queue_issue_flush_fn(q, scsi_issue_flush_fn); - blk_queue_softirq_done(q, scsi_softirq_done); if (!shost->use_clustering) clear_bit(QUEUE_FLAG_CLUSTER, &q->queue_flags); diff --git a/trunk/drivers/scsi/scsi_priv.h b/trunk/drivers/scsi/scsi_priv.h index 14a6198cb8d2..f04e7e11f57a 100644 --- a/trunk/drivers/scsi/scsi_priv.h +++ b/trunk/drivers/scsi/scsi_priv.h @@ -44,7 +44,6 @@ extern void scsi_init_cmd_from_req(struct scsi_cmnd *cmd, struct scsi_request *sreq); extern void __scsi_release_request(struct scsi_request *sreq); extern void __scsi_done(struct scsi_cmnd *cmd); -extern int scsi_retry_command(struct scsi_cmnd *cmd); #ifdef CONFIG_SCSI_LOGGING void scsi_log_send(struct scsi_cmnd *cmd); void scsi_log_completion(struct scsi_cmnd *cmd, int disposition); diff --git a/trunk/fs/bio.c b/trunk/fs/bio.c index 7b3069589951..dfe242a21eb4 100644 --- a/trunk/fs/bio.c +++ b/trunk/fs/bio.c @@ -126,7 +126,6 @@ static void bio_fs_destructor(struct bio *bio) inline void bio_init(struct bio *bio) { bio->bi_next = NULL; - bio->bi_bdev = NULL; bio->bi_flags = 1 << BIO_UPTODATE; bio->bi_rw = 0; bio->bi_vcnt = 0; diff --git a/trunk/include/linux/blkdev.h b/trunk/include/linux/blkdev.h index 02a585faa62c..fb0985377421 100644 --- a/trunk/include/linux/blkdev.h +++ b/trunk/include/linux/blkdev.h @@ -118,9 +118,9 @@ struct request_list { * try to put the fields that are referenced together in the same cacheline */ struct request { - struct list_head queuelist; - struct list_head donelist; - + struct list_head queuelist; /* looking for ->queue? you must _not_ + * access it directly, use + * blkdev_dequeue_request! */ unsigned long flags; /* see REQ_ bits below */ /* Maintain bio traversal state for part by part I/O submission. @@ -141,7 +141,6 @@ struct request { struct bio *biotail; void *elevator_private; - void *completion_data; unsigned short ioprio; @@ -292,7 +291,6 @@ typedef int (merge_bvec_fn) (request_queue_t *, struct bio *, struct bio_vec *); typedef void (activity_fn) (void *data, int rw); typedef int (issue_flush_fn) (request_queue_t *, struct gendisk *, sector_t *); typedef void (prepare_flush_fn) (request_queue_t *, struct request *); -typedef void (softirq_done_fn)(struct request *); enum blk_queue_state { Queue_down, @@ -334,7 +332,6 @@ struct request_queue activity_fn *activity_fn; issue_flush_fn *issue_flush_fn; prepare_flush_fn *prepare_flush_fn; - softirq_done_fn *softirq_done_fn; /* * Dispatch queue sorting @@ -595,6 +592,7 @@ extern void generic_make_request(struct bio *bio); extern void blk_put_request(struct request *); extern void __blk_put_request(request_queue_t *, struct request *); extern void blk_end_sync_rq(struct request *rq, int error); +extern void blk_attempt_remerge(request_queue_t *, struct request *); extern struct request *blk_get_request(request_queue_t *, int, gfp_t); extern void blk_insert_request(request_queue_t *, struct request *, int, void *); extern void blk_requeue_request(request_queue_t *, struct request *); @@ -648,17 +646,6 @@ extern int end_that_request_first(struct request *, int, int); extern int end_that_request_chunk(struct request *, int, int); extern void end_that_request_last(struct request *, int); extern void end_request(struct request *req, int uptodate); -extern void blk_complete_request(struct request *); - -static inline int rq_all_done(struct request *rq, unsigned int nr_bytes) -{ - if (blk_fs_request(rq)) - return (nr_bytes >= (rq->hard_nr_sectors << 9)); - else if (blk_pc_request(rq)) - return nr_bytes >= rq->data_len; - - return 0; -} /* * end_that_request_first/chunk() takes an uptodate argument. we account @@ -707,7 +694,6 @@ extern void blk_queue_segment_boundary(request_queue_t *, unsigned long); extern void blk_queue_prep_rq(request_queue_t *, prep_rq_fn *pfn); extern void blk_queue_merge_bvec(request_queue_t *, merge_bvec_fn *); extern void blk_queue_dma_alignment(request_queue_t *, int); -extern void blk_queue_softirq_done(request_queue_t *, softirq_done_fn *); extern struct backing_dev_info *blk_get_backing_dev_info(struct block_device *bdev); extern int blk_queue_ordered(request_queue_t *, unsigned, prepare_flush_fn *); extern void blk_queue_issue_flush_fn(request_queue_t *, issue_flush_fn *); diff --git a/trunk/include/linux/elevator.h b/trunk/include/linux/elevator.h index 4a6f50e31c73..fb80fa44c4dd 100644 --- a/trunk/include/linux/elevator.h +++ b/trunk/include/linux/elevator.h @@ -114,6 +114,8 @@ extern ssize_t elv_iosched_store(request_queue_t *, const char *, size_t); extern int elevator_init(request_queue_t *, char *); extern void elevator_exit(elevator_t *); extern int elv_rq_merge_ok(struct request *, struct bio *); +extern int elv_try_merge(struct request *, struct bio *); +extern int elv_try_last_merge(request_queue_t *, struct bio *); /* * Return values from elevator merger diff --git a/trunk/include/linux/ide.h b/trunk/include/linux/ide.h index ef8d0cbb832f..4dd6694963c0 100644 --- a/trunk/include/linux/ide.h +++ b/trunk/include/linux/ide.h @@ -1001,7 +1001,6 @@ extern int noautodma; extern int ide_end_request (ide_drive_t *drive, int uptodate, int nrsecs); extern int __ide_end_request (ide_drive_t *drive, struct request *rq, int uptodate, int nrsecs); -extern void ide_softirq_done(struct request *rq); /* * This is used on exit from the driver to designate the next irq handler diff --git a/trunk/include/linux/interrupt.h b/trunk/include/linux/interrupt.h index 2c08fdc2bdf7..e50a95fbeb11 100644 --- a/trunk/include/linux/interrupt.h +++ b/trunk/include/linux/interrupt.h @@ -112,7 +112,7 @@ enum TIMER_SOFTIRQ, NET_TX_SOFTIRQ, NET_RX_SOFTIRQ, - BLOCK_SOFTIRQ, + SCSI_SOFTIRQ, TASKLET_SOFTIRQ }; diff --git a/trunk/include/linux/rcupdate.h b/trunk/include/linux/rcupdate.h index a1d26cb28925..51747cd88d1a 100644 --- a/trunk/include/linux/rcupdate.h +++ b/trunk/include/linux/rcupdate.h @@ -125,7 +125,36 @@ static inline void rcu_bh_qsctr_inc(int cpu) rdp->passed_quiesc = 1; } -extern int rcu_pending(int cpu); +static inline int __rcu_pending(struct rcu_ctrlblk *rcp, + struct rcu_data *rdp) +{ + /* This cpu has pending rcu entries and the grace period + * for them has completed. + */ + if (rdp->curlist && !rcu_batch_before(rcp->completed, rdp->batch)) + return 1; + + /* This cpu has no pending entries, but there are new entries */ + if (!rdp->curlist && rdp->nxtlist) + return 1; + + /* This cpu has finished callbacks to invoke */ + if (rdp->donelist) + return 1; + + /* The rcu core waits for a quiescent state from the cpu */ + if (rdp->quiescbatch != rcp->cur || rdp->qs_pending) + return 1; + + /* nothing to do */ + return 0; +} + +static inline int rcu_pending(int cpu) +{ + return __rcu_pending(&rcu_ctrlblk, &per_cpu(rcu_data, cpu)) || + __rcu_pending(&rcu_bh_ctrlblk, &per_cpu(rcu_bh_data, cpu)); +} /** * rcu_read_lock - mark the beginning of an RCU read-side critical section. diff --git a/trunk/kernel/rcupdate.c b/trunk/kernel/rcupdate.c index ccc45d49ce71..30b0bba03859 100644 --- a/trunk/kernel/rcupdate.c +++ b/trunk/kernel/rcupdate.c @@ -429,36 +429,6 @@ static void rcu_process_callbacks(unsigned long unused) &__get_cpu_var(rcu_bh_data)); } -static int __rcu_pending(struct rcu_ctrlblk *rcp, struct rcu_data *rdp) -{ - /* This cpu has pending rcu entries and the grace period - * for them has completed. - */ - if (rdp->curlist && !rcu_batch_before(rcp->completed, rdp->batch)) - return 1; - - /* This cpu has no pending entries, but there are new entries */ - if (!rdp->curlist && rdp->nxtlist) - return 1; - - /* This cpu has finished callbacks to invoke */ - if (rdp->donelist) - return 1; - - /* The rcu core waits for a quiescent state from the cpu */ - if (rdp->quiescbatch != rcp->cur || rdp->qs_pending) - return 1; - - /* nothing to do */ - return 0; -} - -int rcu_pending(int cpu) -{ - return __rcu_pending(&rcu_ctrlblk, &per_cpu(rcu_data, cpu)) || - __rcu_pending(&rcu_bh_ctrlblk, &per_cpu(rcu_bh_data, cpu)); -} - void rcu_check_callbacks(int cpu, int user) { if (user || diff --git a/trunk/net/netlink/af_netlink.c b/trunk/net/netlink/af_netlink.c index a67f1b44c9a3..7849cac14d3a 100644 --- a/trunk/net/netlink/af_netlink.c +++ b/trunk/net/netlink/af_netlink.c @@ -402,7 +402,7 @@ static int netlink_create(struct socket *sock, int protocol) groups = nl_table[protocol].groups; netlink_unlock_table(); - if ((err = __netlink_create(sock, protocol)) < 0) + if ((err = __netlink_create(sock, protocol) < 0)) goto out_module; nlk = nlk_sk(sock->sk);