Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 292811
b: refs/heads/master
c: d5b4a21
h: refs/heads/master
i:
  292809: 57ef550
  292807: ab41f6d
v: v3
  • Loading branch information
Christoph Hellwig authored and Nicholas Bellinger committed Feb 25, 2012
1 parent 4c5a670 commit a243045
Show file tree
Hide file tree
Showing 3 changed files with 38 additions and 18 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: 6e315a066d7d1917f762d2f2a14e9a71a8656fea
refs/heads/master: d5b4a21b3dc116b477c1b1b493233a73aacbb440
52 changes: 36 additions & 16 deletions trunk/drivers/target/target_core_iblock.c
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,9 @@

#include "target_core_iblock.h"

#define IBLOCK_MAX_BIO_PER_TASK 32 /* max # of bios to submit at a time */
#define IBLOCK_BIO_POOL_SIZE 128

static struct se_subsystem_api iblock_template;

static void iblock_bio_done(struct bio *, int);
Expand Down Expand Up @@ -100,10 +103,8 @@ static struct se_device *iblock_create_virtdevice(
return ERR_PTR(ret);
}
memset(&dev_limits, 0, sizeof(struct se_dev_limits));
/*
* These settings need to be made tunable..
*/
ib_dev->ibd_bio_set = bioset_create(32, 0);

ib_dev->ibd_bio_set = bioset_create(IBLOCK_BIO_POOL_SIZE, 0);
if (!ib_dev->ibd_bio_set) {
pr_err("IBLOCK: Unable to create bioset()\n");
return ERR_PTR(-ENOMEM);
Expand All @@ -129,8 +130,8 @@ static struct se_device *iblock_create_virtdevice(
q = bdev_get_queue(bd);
limits = &dev_limits.limits;
limits->logical_block_size = bdev_logical_block_size(bd);
limits->max_hw_sectors = queue_max_hw_sectors(q);
limits->max_sectors = queue_max_sectors(q);
limits->max_hw_sectors = UINT_MAX;
limits->max_sectors = UINT_MAX;
dev_limits.hw_queue_depth = q->nr_requests;
dev_limits.queue_depth = q->nr_requests;

Expand Down Expand Up @@ -204,7 +205,7 @@ iblock_alloc_task(unsigned char *cdb)
return NULL;
}

atomic_set(&ib_req->ib_bio_cnt, 0);
atomic_set(&ib_req->pending, 1);
return &ib_req->ib_task;
}

Expand Down Expand Up @@ -484,24 +485,35 @@ iblock_get_bio(struct se_task *task, sector_t lba, u32 sg_num)
bio->bi_destructor = iblock_bio_destructor;
bio->bi_end_io = &iblock_bio_done;
bio->bi_sector = lba;
atomic_inc(&ib_req->ib_bio_cnt);
atomic_inc(&ib_req->pending);

pr_debug("Set bio->bi_sector: %llu\n", (unsigned long long)bio->bi_sector);
pr_debug("Set ib_req->ib_bio_cnt: %d\n",
atomic_read(&ib_req->ib_bio_cnt));
pr_debug("Set ib_req->pending: %d\n", atomic_read(&ib_req->pending));
return bio;
}

static void iblock_submit_bios(struct bio_list *list, int rw)
{
struct blk_plug plug;
struct bio *bio;

blk_start_plug(&plug);
while ((bio = bio_list_pop(list)))
submit_bio(rw, bio);
blk_finish_plug(&plug);
}

static int iblock_do_task(struct se_task *task)
{
struct se_cmd *cmd = task->task_se_cmd;
struct se_device *dev = cmd->se_dev;
struct iblock_req *ibr = IBLOCK_REQ(task);
struct bio *bio;
struct bio_list list;
struct scatterlist *sg;
u32 i, sg_num = task->task_sg_nents;
sector_t block_lba;
struct blk_plug plug;
unsigned bio_cnt;
int rw;

if (task->task_data_direction == DMA_TO_DEVICE) {
Expand Down Expand Up @@ -546,6 +558,7 @@ static int iblock_do_task(struct se_task *task)

bio_list_init(&list);
bio_list_add(&list, bio);
bio_cnt = 1;

for_each_sg(task->task_sg, sg, task->task_sg_nents, i) {
/*
Expand All @@ -555,22 +568,29 @@ static int iblock_do_task(struct se_task *task)
*/
while (bio_add_page(bio, sg_page(sg), sg->length, sg->offset)
!= sg->length) {
if (bio_cnt >= IBLOCK_MAX_BIO_PER_TASK) {
iblock_submit_bios(&list, rw);
bio_cnt = 0;
}

bio = iblock_get_bio(task, block_lba, sg_num);
if (!bio)
goto fail;
bio_list_add(&list, bio);
bio_cnt++;
}

/* Always in 512 byte units for Linux/Block */
block_lba += sg->length >> IBLOCK_LBA_SHIFT;
sg_num--;
}

blk_start_plug(&plug);
while ((bio = bio_list_pop(&list)))
submit_bio(rw, bio);
blk_finish_plug(&plug);
iblock_submit_bios(&list, rw);

if (atomic_dec_and_test(&ibr->pending)) {
transport_complete_task(task,
!atomic_read(&ibr->ib_bio_err_cnt));
}
return 0;

fail:
Expand Down Expand Up @@ -622,7 +642,7 @@ static void iblock_bio_done(struct bio *bio, int err)

bio_put(bio);

if (!atomic_dec_and_test(&ibr->ib_bio_cnt))
if (!atomic_dec_and_test(&ibr->pending))
return;

pr_debug("done[%p] bio: %p task_lba: %llu bio_lba: %llu err=%d\n",
Expand Down
2 changes: 1 addition & 1 deletion trunk/drivers/target/target_core_iblock.h
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@

struct iblock_req {
struct se_task ib_task;
atomic_t ib_bio_cnt;
atomic_t pending;
atomic_t ib_bio_err_cnt;
} ____cacheline_aligned;

Expand Down

0 comments on commit a243045

Please sign in to comment.