Hi Martin,

On 3/24/21 20:18, Martin K. Petersen wrote:
> 
> Hi Gustavo!
> 
> Your changes and the original code do not appear to be functionally
> equivalent.
> 
>> @@ -1235,8 +1235,8 @@ static int aac_read_raw_io(struct fib * fib, struct 
>> scsi_cmnd * cmd, u64 lba, u3
>>              if (ret < 0)
>>                      return ret;
>>              command = ContainerRawIo2;
>> -            fibsize = sizeof(struct aac_raw_io2) +
>> -                    ((le32_to_cpu(readcmd2->sgeCnt)-1) * sizeof(struct 
>> sge_ieee1212));
>> +            fibsize = struct_size(readcmd2, sge,
>> +                                 le32_to_cpu(readcmd2->sgeCnt));
> 
> The old code allocated sgeCnt-1 elements (whether that was a mistake or
> not I do not know) whereas the new code would send a larger fib to the
> ASIC. I don't have any aacraid adapters and I am hesitant to merging
> changes that have not been validated on real hardware.

Precisely this sort of confusion is one of the things we want to avoid
by using flexible-array members instead of one-element arrays.

fibsize is actually the same for both the old and the new code. The
difference is that in the original code, the one-element array _sge_
at the bottom of struct aac_raw_io2, contributes to the size of the
structure, as it occupies at least as much space as a single object
of its type. On the other hand, flexible-array members don't contribute
to the size of the enclosing structure. See below...

Old code:

$ pahole -C aac_raw_io2 drivers/scsi/aacraid/aachba.o
struct aac_raw_io2 {
        __le32                     blockLow;             /*     0     4 */
        __le32                     blockHigh;            /*     4     4 */
        __le32                     byteCount;            /*     8     4 */
        __le16                     cid;                  /*    12     2 */
        __le16                     flags;                /*    14     2 */
        __le32                     sgeFirstSize;         /*    16     4 */
        __le32                     sgeNominalSize;       /*    20     4 */
        u8                         sgeCnt;               /*    24     1 */
        u8                         bpTotal;              /*    25     1 */
        u8                         bpComplete;           /*    26     1 */
        u8                         sgeFirstIndex;        /*    27     1 */
        u8                         unused[4];            /*    28     4 */
        struct sge_ieee1212        sge[1];               /*    32    16 */

        /* size: 48, cachelines: 1, members: 13 */
        /* last cacheline: 48 bytes */
};

New code:

$ pahole -C aac_raw_io2 drivers/scsi/aacraid/aachba.o
struct aac_raw_io2 {
        __le32                     blockLow;             /*     0     4 */
        __le32                     blockHigh;            /*     4     4 */
        __le32                     byteCount;            /*     8     4 */
        __le16                     cid;                  /*    12     2 */
        __le16                     flags;                /*    14     2 */
        __le32                     sgeFirstSize;         /*    16     4 */
        __le32                     sgeNominalSize;       /*    20     4 */
        u8                         sgeCnt;               /*    24     1 */
        u8                         bpTotal;              /*    25     1 */
        u8                         bpComplete;           /*    26     1 */
        u8                         sgeFirstIndex;        /*    27     1 */
        u8                         unused[4];            /*    28     4 */
        struct sge_ieee1212        sge[];                /*    32     0 */

        /* size: 32, cachelines: 1, members: 13 */
        /* last cacheline: 32 bytes */
};

So, the old code allocates sgeCnt-1 elements because sizeof(struct aac_raw_io2) 
is
already counting one element of the _sge_ array.

Please, let me know if this is clear now.

Thanks!
--
Gustavo

Reply via email to