Skip to content

Commit

Permalink
Merge branch 'for-linus' of git://git.kernel.dk/linux-2.6-block
Browse files Browse the repository at this point in the history
* 'for-linus' of git://git.kernel.dk/linux-2.6-block:
  block: remove __generic_unplug_device() from exports
  block: move q->unplug_work initialization
  blktrace: pass zfcp driver data
  blktrace: add support for driver data
  block: fix current kernel-doc warnings
  block: only call ->request_fn when the queue is not stopped
  block: simplify string handling in elv_iosched_store()
  block: fix kernel-doc for blk_alloc_devt()
  block: fix nr_phys_segments miscalculation bug
  block: add partition attribute for partition number
  block: add BIG FAT WARNING to CONFIG_DEBUG_BLOCK_EXT_DEVT
  softirq: Add support for triggering softirq work on softirqs.
  • Loading branch information
Linus Torvalds committed Oct 17, 2008
2 parents b73b636 + f73e2d1 commit c53dbf5
Show file tree
Hide file tree
Showing 20 changed files with 305 additions and 27 deletions.
26 changes: 21 additions & 5 deletions block/blk-core.c
Original file line number Diff line number Diff line change
Expand Up @@ -257,7 +257,6 @@ void __generic_unplug_device(struct request_queue *q)

q->request_fn(q);
}
EXPORT_SYMBOL(__generic_unplug_device);

/**
* generic_unplug_device - fire a request queue
Expand Down Expand Up @@ -325,6 +324,9 @@ EXPORT_SYMBOL(blk_unplug);

static void blk_invoke_request_fn(struct request_queue *q)
{
if (unlikely(blk_queue_stopped(q)))
return;

/*
* one level of recursion is ok and is much faster than kicking
* the unplug handling
Expand Down Expand Up @@ -399,8 +401,13 @@ void blk_sync_queue(struct request_queue *q)
EXPORT_SYMBOL(blk_sync_queue);

/**
* blk_run_queue - run a single device queue
* __blk_run_queue - run a single device queue
* @q: The queue to run
*
* Description:
* See @blk_run_queue. This variant must be called with the queue lock
* held and interrupts disabled.
*
*/
void __blk_run_queue(struct request_queue *q)
{
Expand All @@ -418,6 +425,12 @@ EXPORT_SYMBOL(__blk_run_queue);
/**
* blk_run_queue - run a single device queue
* @q: The queue to run
*
* Description:
* Invoke request handling on this queue, if it has pending work to do.
* May be used to restart queueing when a request has completed. Also
* See @blk_start_queueing.
*
*/
void blk_run_queue(struct request_queue *q)
{
Expand Down Expand Up @@ -501,6 +514,7 @@ struct request_queue *blk_alloc_queue_node(gfp_t gfp_mask, int node_id)
init_timer(&q->unplug_timer);
setup_timer(&q->timeout, blk_rq_timed_out_timer, (unsigned long) q);
INIT_LIST_HEAD(&q->timeout_list);
INIT_WORK(&q->unplug_work, blk_unplug_work);

kobject_init(&q->kobj, &blk_queue_ktype);

Expand Down Expand Up @@ -884,7 +898,8 @@ EXPORT_SYMBOL(blk_get_request);
*
* This is basically a helper to remove the need to know whether a queue
* is plugged or not if someone just wants to initiate dispatch of requests
* for this queue.
* for this queue. Should be used to start queueing on a device outside
* of ->request_fn() context. Also see @blk_run_queue.
*
* The queue lock must be held with interrupts disabled.
*/
Expand Down Expand Up @@ -1003,8 +1018,9 @@ static void part_round_stats_single(int cpu, struct hd_struct *part,
}

/**
* part_round_stats() - Round off the performance stats on a struct
* disk_stats.
* part_round_stats() - Round off the performance stats on a struct disk_stats.
* @cpu: cpu number for stats access
* @part: target partition
*
* The average IO queue length and utilisation statistics are maintained
* by observing the current state of the queue length and the amount of
Expand Down
20 changes: 18 additions & 2 deletions block/blk-merge.c
Original file line number Diff line number Diff line change
Expand Up @@ -77,12 +77,20 @@ void blk_recalc_rq_segments(struct request *rq)
continue;
}
new_segment:
if (nr_phys_segs == 1 && seg_size > rq->bio->bi_seg_front_size)
rq->bio->bi_seg_front_size = seg_size;

nr_phys_segs++;
bvprv = bv;
seg_size = bv->bv_len;
highprv = high;
}

if (nr_phys_segs == 1 && seg_size > rq->bio->bi_seg_front_size)
rq->bio->bi_seg_front_size = seg_size;
if (seg_size > rq->biotail->bi_seg_back_size)
rq->biotail->bi_seg_back_size = seg_size;

rq->nr_phys_segments = nr_phys_segs;
}

Expand All @@ -106,7 +114,8 @@ static int blk_phys_contig_segment(struct request_queue *q, struct bio *bio,
if (!test_bit(QUEUE_FLAG_CLUSTER, &q->queue_flags))
return 0;

if (bio->bi_size + nxt->bi_size > q->max_segment_size)
if (bio->bi_seg_back_size + nxt->bi_seg_front_size >
q->max_segment_size)
return 0;

if (!bio_has_data(bio))
Expand Down Expand Up @@ -309,6 +318,8 @@ static int ll_merge_requests_fn(struct request_queue *q, struct request *req,
struct request *next)
{
int total_phys_segments;
unsigned int seg_size =
req->biotail->bi_seg_back_size + next->bio->bi_seg_front_size;

/*
* First check if the either of the requests are re-queued
Expand All @@ -324,8 +335,13 @@ static int ll_merge_requests_fn(struct request_queue *q, struct request *req,
return 0;

total_phys_segments = req->nr_phys_segments + next->nr_phys_segments;
if (blk_phys_contig_segment(q, req->biotail, next->bio))
if (blk_phys_contig_segment(q, req->biotail, next->bio)) {
if (req->nr_phys_segments == 1)
req->bio->bi_seg_front_size = seg_size;
if (next->nr_phys_segments == 1)
next->biotail->bi_seg_back_size = seg_size;
total_phys_segments--;
}

if (total_phys_segments > q->max_phys_segments)
return 0;
Expand Down
2 changes: 0 additions & 2 deletions block/blk-settings.c
Original file line number Diff line number Diff line change
Expand Up @@ -141,8 +141,6 @@ void blk_queue_make_request(struct request_queue *q, make_request_fn *mfn)
if (q->unplug_delay == 0)
q->unplug_delay = 1;

INIT_WORK(&q->unplug_work, blk_unplug_work);

q->unplug_timer.function = blk_unplug_timeout;
q->unplug_timer.data = (unsigned long)q;

Expand Down
1 change: 1 addition & 0 deletions block/blk.h
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ void blk_unplug_timeout(unsigned long data);
void blk_rq_timed_out_timer(unsigned long data);
void blk_delete_timer(struct request *);
void blk_add_timer(struct request *);
void __generic_unplug_device(struct request_queue *);

/*
* Internal atomic flags for request handling
Expand Down
16 changes: 5 additions & 11 deletions block/elevator.c
Original file line number Diff line number Diff line change
Expand Up @@ -612,7 +612,7 @@ void elv_insert(struct request_queue *q, struct request *rq, int where)
* processing.
*/
blk_remove_plug(q);
q->request_fn(q);
blk_start_queueing(q);
break;

case ELEVATOR_INSERT_SORT:
Expand Down Expand Up @@ -950,7 +950,7 @@ void elv_completed_request(struct request_queue *q, struct request *rq)
blk_ordered_cur_seq(q) == QUEUE_ORDSEQ_DRAIN &&
blk_ordered_req_seq(first_rq) > QUEUE_ORDSEQ_DRAIN) {
blk_ordered_complete_seq(q, QUEUE_ORDSEQ_DRAIN, 0);
q->request_fn(q);
blk_start_queueing(q);
}
}
}
Expand Down Expand Up @@ -1109,8 +1109,7 @@ static int elevator_switch(struct request_queue *q, struct elevator_type *new_e)
elv_drain_elevator(q);

while (q->rq.elvpriv) {
blk_remove_plug(q);
q->request_fn(q);
blk_start_queueing(q);
spin_unlock_irq(q->queue_lock);
msleep(10);
spin_lock_irq(q->queue_lock);
Expand Down Expand Up @@ -1166,15 +1165,10 @@ ssize_t elv_iosched_store(struct request_queue *q, const char *name,
size_t count)
{
char elevator_name[ELV_NAME_MAX];
size_t len;
struct elevator_type *e;

elevator_name[sizeof(elevator_name) - 1] = '\0';
strncpy(elevator_name, name, sizeof(elevator_name) - 1);
len = strlen(elevator_name);

if (len && elevator_name[len - 1] == '\n')
elevator_name[len - 1] = '\0';
strlcpy(elevator_name, name, sizeof(elevator_name));
strstrip(elevator_name);

e = elevator_get(elevator_name);
if (!e) {
Expand Down
3 changes: 1 addition & 2 deletions block/genhd.c
Original file line number Diff line number Diff line change
Expand Up @@ -358,7 +358,6 @@ static int blk_mangle_minor(int minor)
/**
* blk_alloc_devt - allocate a dev_t for a partition
* @part: partition to allocate dev_t for
* @gfp_mask: memory allocation flag
* @devt: out parameter for resulting dev_t
*
* Allocate a dev_t for block device.
Expand Down Expand Up @@ -535,7 +534,7 @@ void unlink_gendisk(struct gendisk *disk)
/**
* get_gendisk - get partitioning information for a given device
* @devt: device to get partitioning information for
* @part: returned partition index
* @partno: returned partition index
*
* This function gets the structure containing partitioning
* information for the given device @devt.
Expand Down
4 changes: 2 additions & 2 deletions drivers/ide/ide-io.c
Original file line number Diff line number Diff line change
Expand Up @@ -1493,8 +1493,8 @@ void ide_do_drive_cmd(ide_drive_t *drive, struct request *rq)

spin_lock_irqsave(&ide_lock, flags);
hwgroup->rq = NULL;
__elv_add_request(drive->queue, rq, ELEVATOR_INSERT_FRONT, 1);
__generic_unplug_device(drive->queue);
__elv_add_request(drive->queue, rq, ELEVATOR_INSERT_FRONT, 0);
blk_start_queueing(drive->queue);
spin_unlock_irqrestore(&ide_lock, flags);
}

Expand Down
2 changes: 2 additions & 0 deletions drivers/s390/scsi/zfcp_def.h
Original file line number Diff line number Diff line change
Expand Up @@ -583,6 +583,8 @@ struct zfcp_fsf_req {
unsigned long long issued; /* request sent time (STCK) */
struct zfcp_unit *unit;
void (*handler)(struct zfcp_fsf_req *);
u16 qdio_outb_usage;/* usage of outbound queue */
u16 qdio_inb_usage; /* usage of inbound queue */
};

/* driver data */
Expand Down
34 changes: 34 additions & 0 deletions drivers/s390/scsi/zfcp_fsf.c
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
* Copyright IBM Corporation 2002, 2008
*/

#include <linux/blktrace_api.h>
#include "zfcp_ext.h"

static void zfcp_fsf_request_timeout_handler(unsigned long data)
Expand Down Expand Up @@ -777,6 +778,7 @@ static int zfcp_fsf_req_send(struct zfcp_fsf_req *req)
list_add_tail(&req->list, &adapter->req_list[idx]);
spin_unlock(&adapter->req_list_lock);

req->qdio_outb_usage = atomic_read(&req_q->count);
req->issued = get_clock();
if (zfcp_qdio_send(req)) {
/* Queues are down..... */
Expand Down Expand Up @@ -2082,6 +2084,36 @@ static void zfcp_fsf_req_latency(struct zfcp_fsf_req *req)
spin_unlock_irqrestore(&unit->latencies.lock, flags);
}

#ifdef CONFIG_BLK_DEV_IO_TRACE
static void zfcp_fsf_trace_latency(struct zfcp_fsf_req *fsf_req)
{
struct fsf_qual_latency_info *lat_inf;
struct scsi_cmnd *scsi_cmnd = (struct scsi_cmnd *)fsf_req->data;
struct request *req = scsi_cmnd->request;
struct zfcp_blk_drv_data trace;
int ticks = fsf_req->adapter->timer_ticks;

trace.flags = 0;
trace.magic = ZFCP_BLK_DRV_DATA_MAGIC;
if (fsf_req->adapter->adapter_features & FSF_FEATURE_MEASUREMENT_DATA) {
trace.flags |= ZFCP_BLK_LAT_VALID;
lat_inf = &fsf_req->qtcb->prefix.prot_status_qual.latency_info;
trace.channel_lat = lat_inf->channel_lat * ticks;
trace.fabric_lat = lat_inf->fabric_lat * ticks;
}
if (fsf_req->status & ZFCP_STATUS_FSFREQ_ERROR)
trace.flags |= ZFCP_BLK_REQ_ERROR;
trace.inb_usage = fsf_req->qdio_inb_usage;
trace.outb_usage = fsf_req->qdio_outb_usage;

blk_add_driver_data(req->q, req, &trace, sizeof(trace));
}
#else
static inline void zfcp_fsf_trace_latency(struct zfcp_fsf_req *fsf_req)
{
}
#endif

static void zfcp_fsf_send_fcp_command_task_handler(struct zfcp_fsf_req *req)
{
struct scsi_cmnd *scpnt = req->data;
Expand Down Expand Up @@ -2114,6 +2146,8 @@ static void zfcp_fsf_send_fcp_command_task_handler(struct zfcp_fsf_req *req)
if (req->adapter->adapter_features & FSF_FEATURE_MEASUREMENT_DATA)
zfcp_fsf_req_latency(req);

zfcp_fsf_trace_latency(req);

if (unlikely(fcp_rsp_iu->validity.bits.fcp_rsp_len_valid)) {
if (fcp_rsp_info[3] == RSP_CODE_GOOD)
set_host_byte(scpnt, DID_OK);
Expand Down
12 changes: 12 additions & 0 deletions drivers/s390/scsi/zfcp_fsf.h
Original file line number Diff line number Diff line change
Expand Up @@ -439,4 +439,16 @@ struct fsf_qtcb {
u8 log[FSF_QTCB_LOG_SIZE];
} __attribute__ ((packed));

struct zfcp_blk_drv_data {
#define ZFCP_BLK_DRV_DATA_MAGIC 0x1
u32 magic;
#define ZFCP_BLK_LAT_VALID 0x1
#define ZFCP_BLK_REQ_ERROR 0x2
u16 flags;
u8 inb_usage;
u8 outb_usage;
u64 channel_lat;
u64 fabric_lat;
} __attribute__ ((packed));

#endif /* FSF_H */
1 change: 1 addition & 0 deletions drivers/s390/scsi/zfcp_qdio.c
Original file line number Diff line number Diff line change
Expand Up @@ -115,6 +115,7 @@ static void zfcp_qdio_reqid_check(struct zfcp_adapter *adapter,
spin_unlock_irqrestore(&adapter->req_list_lock, flags);

fsf_req->sbal_response = sbal_idx;
fsf_req->qdio_inb_usage = atomic_read(&adapter->resp_q.count);
zfcp_fsf_req_complete(fsf_req);
}

Expand Down
2 changes: 1 addition & 1 deletion fs/block_dev.c
Original file line number Diff line number Diff line change
Expand Up @@ -1262,7 +1262,7 @@ EXPORT_SYMBOL(ioctl_by_bdev);

/**
* lookup_bdev - lookup a struct block_device by name
* @pathname: special file representing the block device
* @path: special file representing the block device
*
* Get a reference to the blockdevice at @pathname in the current
* namespace if possible and return it. Return ERR_PTR(error)
Expand Down
10 changes: 10 additions & 0 deletions fs/partitions/check.c
Original file line number Diff line number Diff line change
Expand Up @@ -195,6 +195,14 @@ check_partition(struct gendisk *hd, struct block_device *bdev)
return ERR_PTR(res);
}

static ssize_t part_partition_show(struct device *dev,
struct device_attribute *attr, char *buf)
{
struct hd_struct *p = dev_to_part(dev);

return sprintf(buf, "%d\n", p->partno);
}

static ssize_t part_start_show(struct device *dev,
struct device_attribute *attr, char *buf)
{
Expand Down Expand Up @@ -260,6 +268,7 @@ ssize_t part_fail_store(struct device *dev,
}
#endif

static DEVICE_ATTR(partition, S_IRUGO, part_partition_show, NULL);
static DEVICE_ATTR(start, S_IRUGO, part_start_show, NULL);
static DEVICE_ATTR(size, S_IRUGO, part_size_show, NULL);
static DEVICE_ATTR(stat, S_IRUGO, part_stat_show, NULL);
Expand All @@ -269,6 +278,7 @@ static struct device_attribute dev_attr_fail =
#endif

static struct attribute *part_attrs[] = {
&dev_attr_partition.attr,
&dev_attr_start.attr,
&dev_attr_size.attr,
&dev_attr_stat.attr,
Expand Down
7 changes: 7 additions & 0 deletions include/linux/bio.h
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,13 @@ struct bio {

unsigned int bi_size; /* residual I/O count */

/*
* To keep track of the max segment size, we account for the
* sizes of the first and last mergeable segments in this bio.
*/
unsigned int bi_seg_front_size;
unsigned int bi_seg_back_size;

unsigned int bi_max_vecs; /* max bvl_vecs we can hold */

unsigned int bi_comp_cpu; /* completion CPU */
Expand Down
1 change: 0 additions & 1 deletion include/linux/blkdev.h
Original file line number Diff line number Diff line change
Expand Up @@ -865,7 +865,6 @@ extern void blk_ordered_complete_seq(struct request_queue *, unsigned, int);
extern int blk_rq_map_sg(struct request_queue *, struct request *, struct scatterlist *);
extern void blk_dump_rq_flags(struct request *, char *);
extern void generic_unplug_device(struct request_queue *);
extern void __generic_unplug_device(struct request_queue *);
extern long nr_blockdev_pages(void);

int blk_get_queue(struct request_queue *);
Expand Down
Loading

0 comments on commit c53dbf5

Please sign in to comment.