SG Engine 520 format alignment issue

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Hello all, I am doing some 520byte per sector testing and utilizing
the sg engine.  so far it is working ok (doesn't seem to be able to
have iodepth > 16 but that is workable with jobs...)

I am running into an issue with 32K block sizes though.
If I want to run 4K transfers  I will transfer 520*8 = 4,160bytes
16K = 520*32 =  16,640 bytes
32K = 520*64 = 33,280 bytes
Unfortunately 33,280 fails with "read/write not sector aligned"

Checking the code engines/sg.c
static int fio_sgio_prep(struct thread_data *td, struct io_u *io_u)
{
        struct sg_io_hdr *hdr = &io_u->hdr;
        struct sg_options *o = td->eo;
        struct sgio_data *sd = td->io_ops_data;
        unsigned long long nr_blocks, lba;
        int offset;

        if (io_u->xfer_buflen & (sd->bs - 1)) {
                log_err("read/write not sector aligned\n");
                return EINVAL;
        }


Issue is with how it is calculating whether the transfer size is
aligned or not. It all works for 512/4096 aligned IO yet it breaks
down when doing 520 bytes aligned IO
Chart below shows different block sizes
519:          10 0000 0111 (sd->bs - 1)
1040:     ‭   100 0001 0000‬ & (sd->bs - 1) = 1
4160:     1 0000 0100 0000 & (sd->bs - 1) = 0 OK
8320:    10 0000 1000 0000‬ & (sd->bs - 1) = 0 OK
16640:  ‭100 0001 0000 0000‬ & (sd->bs - 1) = 0 OK
33280: ‭1000 0010 0000 0000‬ & (sd->bs - 1) = 1

It actually doesn't work for anything below 4160 and block sizes
between 33280 and 66,560

It can be fixed by changing the following
if (io_u->xfer_buflen & (sd->bs - 1)) {
to
if (io_u->xfer_buflen % sd->bs  != 0 ) {

I am sure there is a better way but it works for me.  Is there anyway
to get this change in (or something similar)?

Thank you,
Kurt




[Index of Archives]     [Linux Kernel]     [Linux SCSI]     [Linux IDE]     [Linux USB Devel]     [Video for Linux]     [Linux Audio Users]     [Yosemite News]     [Linux SCSI]

  Powered by Linux