[ofw] ib_portinfo_record_t padding history?

Smith, Stan stan.smith at intel.com
Tue May 18 14:18:09 PDT 2010


Fab Tillier wrote:
> Sean Hefty wrote on Tue, 18 May 2010 at 12:08:08
>
>>> Thoughts?
>>
>> The padding looks wrong based on the IB spec.  PortInfoRecord should
>> have PortInfo as its last field.  The size of PortInfoRecord should
>> be 58 bytes.
>
> AttributeOffset in the MAD is defined as number of 8-byte words
> between attributes.  I believe the extra pad is there so that you can
> treat the records in a GET_TABLE response as an array of
> PortInfoRecords.  I don't know if any code actually uses it this way,
> but that's what I guess the intent is.
>
>>> #include <complib/cl_packon.h>
>>> typedef struct _ib_portinfo_record
>>> {
>>>        ib_net16_t              lid;
>>>        uint8_t         port_num;
>>>        uint8_t         resv;
>>>        ib_port_info_t  port_info;
>>>        uint8_t         pad[6];         <-- ??
>>> }       PACK_SUFFIX ib_portinfo_record_t;
>>> #include <complib/cl_packoff.h>
>>
>> My guess (and this is only a guess) is that the padding was added to
>> make PortInfoRecord align on a 64-bit boundary, probably in case it
>> were sent as part of an RMPP mad.  The PortInfo structure contains
>> 64- bit values at the top of the structure.
>
> Nah, the attributes end up unaligned anyway thanks to the stellar
> layout of the SA MADs.  I'm pretty sure it's there to allow indexing
> as an array.  While the pad isn't formally documented, it will always
> be there.  It should be harmless.
>
> -Fab

Indeed a problem arises in osmtest when building a fabric inventory file 'osmtest.dat' via 'osmtest -f c'.
The problem is exactly that of an SA response containing an array of ib_portinfo_records.
With the padding the 2nd ib_portinfo_record[1] index computation is incorrectly offset by 2 bytes.
Without the padding the index calculation is correct. This observation led me to the comparison of the Linux vs. Windows ib_portinfo_record_t definitions and subsequent removal of the padding.
I agree the padding should not have been an issue; all things coded correctly.

Digging further into the issue, I find the following Windows vs. Linux definition:

AL_INLINE ib_net16_t AL_API
ib_get_attr_offset(
        IN              const   uint32_t                                        attr_size )
{
        if( attr_size & 0x07 )
                return( cl_hton16( (uint16_t)(attr_size >> 3) + 1 ) );
        else
                return( cl_hton16( (uint16_t)(attr_size >> 3) ) );
}

Linux

static inline ib_net16_t AL_API
ib_get_attr_offset(const uint32_t attr_size )
{
        return( cl_hton16( (uint16_t)(attr_size >> 3) ) );
}

'attr_size' is passed in osmtest.c as 'sizeof(ib_portinfo_record_t)' when building an SA query.
I suspect this is the root of the problem, as osmtest.c code which builds the SA query for all known portinfo records sets the madw attr_size as '(attr_size >> 3)'.
The question becomes 'which is the correct version of ib_get_attr_offset()?'.





More information about the ofw mailing list