diff options
author | Nick Piggin <npiggin@suse.de> | 2008-04-29 08:48:33 -0400 |
---|---|---|
committer | Jens Axboe <jens.axboe@oracle.com> | 2008-04-29 08:48:33 -0400 |
commit | 75ad23bc0fcb4f992a5d06982bf0857ab1738e9e (patch) | |
tree | 8668ef63b1f420252ae41aed9e13737d49fd8054 /drivers | |
parent | 68154e90c9d1492d570671ae181d9a8f8530da55 (diff) |
block: make queue flags non-atomic
We can save some atomic ops in the IO path, if we clearly define
the rules of how to modify the queue flags.
Signed-off-by: Jens Axboe <jens.axboe@oracle.com>
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/block/loop.c | 2 | ||||
-rw-r--r-- | drivers/block/ub.c | 2 | ||||
-rw-r--r-- | drivers/md/dm-table.c | 7 | ||||
-rw-r--r-- | drivers/md/md.c | 3 | ||||
-rw-r--r-- | drivers/scsi/scsi_debug.c | 2 | ||||
-rw-r--r-- | drivers/scsi/scsi_lib.c | 31 | ||||
-rw-r--r-- | drivers/scsi/scsi_transport_sas.c | 3 |
7 files changed, 29 insertions, 21 deletions
diff --git a/drivers/block/loop.c b/drivers/block/loop.c index f7f163557aa0..d3a25b027ff9 100644 --- a/drivers/block/loop.c +++ b/drivers/block/loop.c | |||
@@ -546,7 +546,7 @@ static void loop_unplug(struct request_queue *q) | |||
546 | { | 546 | { |
547 | struct loop_device *lo = q->queuedata; | 547 | struct loop_device *lo = q->queuedata; |
548 | 548 | ||
549 | clear_bit(QUEUE_FLAG_PLUGGED, &q->queue_flags); | 549 | queue_flag_clear_unlocked(QUEUE_FLAG_PLUGGED, q); |
550 | blk_run_address_space(lo->lo_backing_file->f_mapping); | 550 | blk_run_address_space(lo->lo_backing_file->f_mapping); |
551 | } | 551 | } |
552 | 552 | ||
diff --git a/drivers/block/ub.c b/drivers/block/ub.c index 27bfe72aab59..e322cce8c12d 100644 --- a/drivers/block/ub.c +++ b/drivers/block/ub.c | |||
@@ -2399,7 +2399,7 @@ static void ub_disconnect(struct usb_interface *intf) | |||
2399 | del_gendisk(lun->disk); | 2399 | del_gendisk(lun->disk); |
2400 | /* | 2400 | /* |
2401 | * I wish I could do: | 2401 | * I wish I could do: |
2402 | * set_bit(QUEUE_FLAG_DEAD, &q->queue_flags); | 2402 | * queue_flag_set(QUEUE_FLAG_DEAD, q); |
2403 | * As it is, we rely on our internal poisoning and let | 2403 | * As it is, we rely on our internal poisoning and let |
2404 | * the upper levels to spin furiously failing all the I/O. | 2404 | * the upper levels to spin furiously failing all the I/O. |
2405 | */ | 2405 | */ |
diff --git a/drivers/md/dm-table.c b/drivers/md/dm-table.c index 51be53344214..73326e7c54bf 100644 --- a/drivers/md/dm-table.c +++ b/drivers/md/dm-table.c | |||
@@ -873,10 +873,13 @@ void dm_table_set_restrictions(struct dm_table *t, struct request_queue *q) | |||
873 | q->max_hw_sectors = t->limits.max_hw_sectors; | 873 | q->max_hw_sectors = t->limits.max_hw_sectors; |
874 | q->seg_boundary_mask = t->limits.seg_boundary_mask; | 874 | q->seg_boundary_mask = t->limits.seg_boundary_mask; |
875 | q->bounce_pfn = t->limits.bounce_pfn; | 875 | q->bounce_pfn = t->limits.bounce_pfn; |
876 | /* XXX: the below will probably go bug. must ensure there can be no | ||
877 | * concurrency on queue_flags, and use the unlocked versions... | ||
878 | */ | ||
876 | if (t->limits.no_cluster) | 879 | if (t->limits.no_cluster) |
877 | q->queue_flags &= ~(1 << QUEUE_FLAG_CLUSTER); | 880 | queue_flag_clear(QUEUE_FLAG_CLUSTER, q); |
878 | else | 881 | else |
879 | q->queue_flags |= (1 << QUEUE_FLAG_CLUSTER); | 882 | queue_flag_set(QUEUE_FLAG_CLUSTER, q); |
880 | 883 | ||
881 | } | 884 | } |
882 | 885 | ||
diff --git a/drivers/md/md.c b/drivers/md/md.c index 87620b705bee..acd716b657b8 100644 --- a/drivers/md/md.c +++ b/drivers/md/md.c | |||
@@ -282,7 +282,8 @@ static mddev_t * mddev_find(dev_t unit) | |||
282 | kfree(new); | 282 | kfree(new); |
283 | return NULL; | 283 | return NULL; |
284 | } | 284 | } |
285 | set_bit(QUEUE_FLAG_CLUSTER, &new->queue->queue_flags); | 285 | /* Can be unlocked because the queue is new: no concurrency */ |
286 | queue_flag_set_unlocked(QUEUE_FLAG_CLUSTER, new->queue); | ||
286 | 287 | ||
287 | blk_queue_make_request(new->queue, md_fail_request); | 288 | blk_queue_make_request(new->queue, md_fail_request); |
288 | 289 | ||
diff --git a/drivers/scsi/scsi_debug.c b/drivers/scsi/scsi_debug.c index 07103c399fe0..f6600bfb5bde 100644 --- a/drivers/scsi/scsi_debug.c +++ b/drivers/scsi/scsi_debug.c | |||
@@ -1773,7 +1773,7 @@ static int scsi_debug_slave_alloc(struct scsi_device *sdp) | |||
1773 | if (SCSI_DEBUG_OPT_NOISE & scsi_debug_opts) | 1773 | if (SCSI_DEBUG_OPT_NOISE & scsi_debug_opts) |
1774 | printk(KERN_INFO "scsi_debug: slave_alloc <%u %u %u %u>\n", | 1774 | printk(KERN_INFO "scsi_debug: slave_alloc <%u %u %u %u>\n", |
1775 | sdp->host->host_no, sdp->channel, sdp->id, sdp->lun); | 1775 | sdp->host->host_no, sdp->channel, sdp->id, sdp->lun); |
1776 | set_bit(QUEUE_FLAG_BIDI, &sdp->request_queue->queue_flags); | 1776 | queue_flag_set_unlocked(QUEUE_FLAG_BIDI, sdp->request_queue); |
1777 | return 0; | 1777 | return 0; |
1778 | } | 1778 | } |
1779 | 1779 | ||
diff --git a/drivers/scsi/scsi_lib.c b/drivers/scsi/scsi_lib.c index 67f412bb4974..d545ad1cf47a 100644 --- a/drivers/scsi/scsi_lib.c +++ b/drivers/scsi/scsi_lib.c | |||
@@ -536,6 +536,9 @@ static void scsi_run_queue(struct request_queue *q) | |||
536 | !shost->host_blocked && !shost->host_self_blocked && | 536 | !shost->host_blocked && !shost->host_self_blocked && |
537 | !((shost->can_queue > 0) && | 537 | !((shost->can_queue > 0) && |
538 | (shost->host_busy >= shost->can_queue))) { | 538 | (shost->host_busy >= shost->can_queue))) { |
539 | |||
540 | int flagset; | ||
541 | |||
539 | /* | 542 | /* |
540 | * As long as shost is accepting commands and we have | 543 | * As long as shost is accepting commands and we have |
541 | * starved queues, call blk_run_queue. scsi_request_fn | 544 | * starved queues, call blk_run_queue. scsi_request_fn |
@@ -549,19 +552,20 @@ static void scsi_run_queue(struct request_queue *q) | |||
549 | sdev = list_entry(shost->starved_list.next, | 552 | sdev = list_entry(shost->starved_list.next, |
550 | struct scsi_device, starved_entry); | 553 | struct scsi_device, starved_entry); |
551 | list_del_init(&sdev->starved_entry); | 554 | list_del_init(&sdev->starved_entry); |
552 | spin_unlock_irqrestore(shost->host_lock, flags); | 555 | spin_unlock(shost->host_lock); |
553 | 556 | ||
557 | spin_lock(sdev->request_queue->queue_lock); | ||
558 | flagset = test_bit(QUEUE_FLAG_REENTER, &q->queue_flags) && | ||
559 | !test_bit(QUEUE_FLAG_REENTER, | ||
560 | &sdev->request_queue->queue_flags); | ||
561 | if (flagset) | ||
562 | queue_flag_set(QUEUE_FLAG_REENTER, sdev->request_queue); | ||
563 | __blk_run_queue(sdev->request_queue); | ||
564 | if (flagset) | ||
565 | queue_flag_clear(QUEUE_FLAG_REENTER, sdev->request_queue); | ||
566 | spin_unlock(sdev->request_queue->queue_lock); | ||
554 | 567 | ||
555 | if (test_bit(QUEUE_FLAG_REENTER, &q->queue_flags) && | 568 | spin_lock(shost->host_lock); |
556 | !test_and_set_bit(QUEUE_FLAG_REENTER, | ||
557 | &sdev->request_queue->queue_flags)) { | ||
558 | blk_run_queue(sdev->request_queue); | ||
559 | clear_bit(QUEUE_FLAG_REENTER, | ||
560 | &sdev->request_queue->queue_flags); | ||
561 | } else | ||
562 | blk_run_queue(sdev->request_queue); | ||
563 | |||
564 | spin_lock_irqsave(shost->host_lock, flags); | ||
565 | if (unlikely(!list_empty(&sdev->starved_entry))) | 569 | if (unlikely(!list_empty(&sdev->starved_entry))) |
566 | /* | 570 | /* |
567 | * sdev lost a race, and was put back on the | 571 | * sdev lost a race, and was put back on the |
@@ -1585,8 +1589,9 @@ struct request_queue *__scsi_alloc_queue(struct Scsi_Host *shost, | |||
1585 | 1589 | ||
1586 | blk_queue_max_segment_size(q, dma_get_max_seg_size(dev)); | 1590 | blk_queue_max_segment_size(q, dma_get_max_seg_size(dev)); |
1587 | 1591 | ||
1592 | /* New queue, no concurrency on queue_flags */ | ||
1588 | if (!shost->use_clustering) | 1593 | if (!shost->use_clustering) |
1589 | clear_bit(QUEUE_FLAG_CLUSTER, &q->queue_flags); | 1594 | queue_flag_clear_unlocked(QUEUE_FLAG_CLUSTER, q); |
1590 | 1595 | ||
1591 | /* | 1596 | /* |
1592 | * set a reasonable default alignment on word boundaries: the | 1597 | * set a reasonable default alignment on word boundaries: the |
diff --git a/drivers/scsi/scsi_transport_sas.c b/drivers/scsi/scsi_transport_sas.c index 7899e3dda9bf..f4461d35ffb9 100644 --- a/drivers/scsi/scsi_transport_sas.c +++ b/drivers/scsi/scsi_transport_sas.c | |||
@@ -248,8 +248,7 @@ static int sas_bsg_initialize(struct Scsi_Host *shost, struct sas_rphy *rphy) | |||
248 | else | 248 | else |
249 | q->queuedata = shost; | 249 | q->queuedata = shost; |
250 | 250 | ||
251 | set_bit(QUEUE_FLAG_BIDI, &q->queue_flags); | 251 | queue_flag_set_unlocked(QUEUE_FLAG_BIDI, q); |
252 | |||
253 | return 0; | 252 | return 0; |
254 | } | 253 | } |
255 | 254 | ||