lkml.org 
[lkml]   [2007]   [Aug]   [16]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    From
    Date
    Subject[PATCH 003 of 6] Fix various abuse of bio fields in umem.c

    umem.c:
    advances bi_idx and bi_sector to track where it is up to.
    But it is only ever doing this on one bio, so the updated
    fields can easily be kept elsewhere (current_*).
    updates bi_size, but never uses the updated values, so
    this isn't needed.
    reuses bi_phys_segments to count how many iovecs have been
    completely. As the completion happens sequentiually, we
    can store this information outside the bio too.


    Signed-off-by: Neil Brown <neilb@suse.de>

    ### Diffstat output
    ./drivers/block/umem.c | 38 +++++++++++++++++++++++++-------------
    1 file changed, 25 insertions(+), 13 deletions(-)

    diff .prev/drivers/block/umem.c ./drivers/block/umem.c
    --- .prev/drivers/block/umem.c 2007-08-16 21:10:00.000000000 +1000
    +++ ./drivers/block/umem.c 2007-08-16 21:10:12.000000000 +1000
    @@ -113,6 +113,8 @@ struct cardinfo {
    * have been written
    */
    struct bio *bio, *currentbio, **biotail;
    + int current_idx;
    + sector_t current_sector;

    struct request_queue *queue;

    @@ -121,6 +123,7 @@ struct cardinfo {
    struct mm_dma_desc *desc;
    int cnt, headcnt;
    struct bio *bio, **biotail;
    + int idx;
    } mm_pages[2];
    #define DESC_PER_PAGE ((PAGE_SIZE*2)/sizeof(struct mm_dma_desc))

    @@ -380,12 +383,16 @@ static int add_bio(struct cardinfo *card
    dma_addr_t dma_handle;
    int offset;
    struct bio *bio;
    + struct bio_vec *vec;
    + int idx;
    int rw;
    int len;

    bio = card->currentbio;
    if (!bio && card->bio) {
    card->currentbio = card->bio;
    + card->current_idx = card->bio->bi_idx;
    + card->current_sector = card->bio->bi_sector;
    card->bio = card->bio->bi_next;
    if (card->bio == NULL)
    card->biotail = &card->bio;
    @@ -394,15 +401,17 @@ static int add_bio(struct cardinfo *card
    }
    if (!bio)
    return 0;
    + idx = card->current_idx;

    rw = bio_rw(bio);
    if (card->mm_pages[card->Ready].cnt >= DESC_PER_PAGE)
    return 0;

    - len = bio_iovec(bio)->bv_len;
    - dma_handle = pci_map_page(card->dev,
    - bio_page(bio),
    - bio_offset(bio),
    + vec = bio_iovec_idx(bio, idx);
    + len = vec->bv_len;
    + dma_handle = pci_map_page(card->dev,
    + vec->bv_page,
    + vec->bv_offset,
    len,
    (rw==READ) ?
    PCI_DMA_FROMDEVICE : PCI_DMA_TODEVICE);
    @@ -410,6 +419,8 @@ static int add_bio(struct cardinfo *card
    p = &card->mm_pages[card->Ready];
    desc = &p->desc[p->cnt];
    p->cnt++;
    + if (p->bio == NULL)
    + p->idx = idx;
    if ((p->biotail) != &bio->bi_next) {
    *(p->biotail) = bio;
    p->biotail = &(bio->bi_next);
    @@ -419,7 +430,7 @@ static int add_bio(struct cardinfo *card
    desc->data_dma_handle = dma_handle;

    desc->pci_addr = cpu_to_le64((u64)desc->data_dma_handle);
    - desc->local_addr= cpu_to_le64(bio->bi_sector << 9);
    + desc->local_addr = cpu_to_le64(card->current_sector << 9);
    desc->transfer_size = cpu_to_le32(len);
    offset = ( ((char*)&desc->sem_control_bits) - ((char*)p->desc));
    desc->sem_addr = cpu_to_le64((u64)(p->page_dma+offset));
    @@ -435,10 +446,10 @@ static int add_bio(struct cardinfo *card
    desc->control_bits |= cpu_to_le32(DMASCR_TRANSFER_READ);
    desc->sem_control_bits = desc->control_bits;

    - bio->bi_sector += (len>>9);
    - bio->bi_size -= len;
    - bio->bi_idx++;
    - if (bio->bi_idx >= bio->bi_vcnt)
    + card->current_sector += (len >> 9);
    + idx++;
    + card->current_idx = idx;
    + if (idx >= bio->bi_vcnt)
    card->currentbio = NULL;

    return 1;
    @@ -474,10 +485,12 @@ static void process_page(unsigned long d
    last=1;
    }
    page->headcnt++;
    - idx = bio->bi_phys_segments;
    - bio->bi_phys_segments++;
    - if (bio->bi_phys_segments >= bio->bi_vcnt)
    + idx = page->idx;
    + page->idx++;
    + if (page->idx >= bio->bi_vcnt) {
    page->bio = bio->bi_next;
    + page->idx = page->bio->bi_idx;
    + }

    pci_unmap_page(card->dev, desc->data_dma_handle,
    bio_iovec_idx(bio,idx)->bv_len,
    @@ -547,7 +560,6 @@ static int mm_make_request(struct reques
    pr_debug("mm_make_request %llu %u\n",
    (unsigned long long)bio->bi_sector, bio->bi_size);

    - bio->bi_phys_segments = bio->bi_idx; /* count of completed segments*/
    spin_lock_irq(&card->lock);
    *card->biotail = bio;
    bio->bi_next = NULL;
    -
    To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
    the body of a message to majordomo@vger.kernel.org
    More majordomo info at http://vger.kernel.org/majordomo-info.html
    Please read the FAQ at http://www.tux.org/lkml/
    \
     
     \ /
      Last update: 2007-08-16 13:27    [W:3.491 / U:0.004 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site