[Openib-windows] SRP in x86 machinise

Fabian Tillier ftillier at silverstorm.com
Tue Sep 5 11:37:33 PDT 2006


Hi Yossi,

On 9/4/06, Yossi Leybovich <sleybo at mellanox.co.il> wrote:
>
> Fab
>
> The patch for the former problem indeed help
> ( I guess that that the fact you are not calling to srp_free_hca solve the
> double freeing, I also did not understand fully why ).
> Still I was left with the LOCAL_PROTECTION_ERR , the reason for that is
> casting issue in 32 bit machines
> Because SRP register kernel memory the cast from 32 bit to 64 bit use sign
> extension and :
> 0x89830000 move to 0xffffffff89830000

Sign extension of kernel virtual memory regions is correct.

> this change solve tyhe problem (its just suggestion but the idea is to force
> the cast to ignore sign of the address)
>
>
> Index: kernel/srp_descriptors.c
> ===================================================================
> --- kernel/srp_descriptors.c (revision 1647)
> +++ kernel/srp_descriptors.c (working copy)
> @@ -91,10 +91,12 @@
>   }
>
>   /* Register the data segments array memory */
> - mr_create.vaddr =
> p_descriptors->p_recv_data_segments_array;
> + mr_create.vaddr = (void*
> __ptr64)(uint64_t)(ULONG_PTR)p_descriptors->p_recv_data_segments_array;

I think the original is right - you want the address to be sign extended.

>   mr_create.length = p_descriptors->recv_descriptor_count *
> p_descriptors->recv_data_segment_size;
>   mr_create.access_ctrl = IB_AC_LOCAL_WRITE;
> @@ -124,7 +126,7 @@
>    p_descriptor->wr.num_ds = 1;
>    p_descriptor->wr.ds_array = p_descriptor->ds;
>
> -  p_descriptor->ds[0].vaddr = (uint64_t)((void* __ptr64)p_data_segment);
> +  p_descriptor->ds[0].vaddr =
> (uint64_t)(ULONG_PTR)p_data_segment;

Again, the original is right - sign extend the pointer and then cast
to uint64.  I remember testing SRP on 32-bit with the MT23108 driver,
so I suspect the problem is in how MTHCA registers memory - it must
miss the sign extension.

Looking at the register_mr path in the MTHCA driver, the call to
ibv_reg_mr (hca_memory.c at 89) is wrong:

mr_p = ibv_reg_mr(ib_pd_p, map_qp_ibal_acl(p_mr_create->access_ctrl),
		p_mr_create->vaddr, p_mr_create->length,
		(uint64_t)(ULONG_PTR)(void*)p_mr_create->vaddr, um_call );

The hca_va parameter (second to last) has the wrong cast to it.
p_mr_create->vaddr is already a 64-bit pointer, so a simple cast to
uint64 should work.  The cast to (ULONG_PTR)(void*) is truncating the
upper 32 bits and then failing to sign extend.

- Fab




More information about the ofw mailing list