Thanks for looking into this... and going easy on me about the patches:)
I'll test the new ones some night this week and report back.
Thanks again,
Greg
On 03-Jan-11 18:32, Steven Dake wrote:
> Thanks for the patches - They aren't quite right, with comments below.
> I will mail patches to the ml following this email. Would you mind
> testing them? I only have 386 and x86_64 arches to test with here.
>
> Thanks!
>
>
> On 12/31/2010 01:39 PM, Greg Walton wrote:
>> These two patches fix memory alignment issues on arm that I've been
>> slowly working on for a while now.
>>
>> The totemipaddress struct patch is pretty straighforward. I did not run
>> into that in flatiron, since the unaligned access is occuring in a
>> function only present in trunk, totemip_is_mcast() ... specifically the
>> line:
>>
>> addr = ntohl(*(int32_t*)ip_addr->addr);
>>
> another way to address this is to use memcpy to copy ip_addr->addr.
> memcpy is designed to handle unaligned accesses. The method proposed by
> changing the packing breaks onwire compatibility and can't be merged.
>
>> aligned(4) in the struct fixes the problem also but I used 8 since I saw
>> alot of other structs in the project were aligned(8) and I assumed
>> that's better preparation for any 64 bit issues in the future.
>>
>> The dispatch_buffer patch is a bigger deal obviously, so that patch was
>> basically made to be minimally intrusive and let me run corosync
>> successfully. The primary test of "working" was using testcpg with
>> non-multiple of 4 sized messages and a quick run of corosync with
>> pacemaker and watching "crm status" to show the single node online. I
>> haven't yet tested 2 nodes..... I'd rather end the year thinking I got
>> all working, so I'll wait until tomorrow to discover any endian issues
>> with message contents. At least it runs with no bus errors for now:)
>>
>> One idea for a real patch would be to just extend this patch to actually
>> write nulls to the padding byte locations and let it all be done with
>> control_buffer->read,write index fiddling. But there must be something
>> more elegant.
>>
>> I know arm is obviously not major target arch for corosync, meaning this
>> could be considered a big change for not much gain. But hopefully
>> there's some desire to deal with this since there could potentially be
>> alignment issues on another arch some day.
>>
>> I did debate patching pacemaker to add padding to it's messages so they
>> are aligned, but it seemed more proper to deal with it in corosync.
>>
>> To summarize my findings: The alignment issue occurs when a
>> "non-multiple of 4" sized message is written to dispatch_buffer, and the
>> next message is written directly after it and there is a subsequent
>> access to some portion of that message.
>>
>> Even if all the structs and whatnot that comprise the message contents
>> are aligned, all that alignment work with message contents is wasted
>> when the message itself is stored on a odd address, breaking alignment
>> for direct access to probably most everything inside the message.
>>
>> Thanks
>> Greg Walton
>>
>> diff --git a/include/corosync/totem/totemip.h
>> b/include/corosync/totem/totemip.h
>> index e7f1d18..d9af0e0 100644
>> --- a/include/corosync/totem/totemip.h
>> +++ b/include/corosync/totem/totemip.h
>> @@ -59,10 +59,10 @@ void totemip_nosigpipe(int s);
>> #define TOTEM_IP_ADDRESS
>> struct totem_ip_address
>> {
>> - unsigned int nodeid;
>> - unsigned short family;
>> - unsigned char addr[TOTEMIP_ADDRLEN];
>> -} __attribute__((packed));
>> + unsigned int nodeid __attribute__((aligned(8)));
>> + unsigned short family __attribute__((aligned(8)));
>> + unsigned char addr[TOTEMIP_ADDRLEN] __attribute__((aligned(8)));
>> +} __attribute__((aligned(8)));
>>
>>
>> extern int totemip_equal(const struct totem_ip_address *addr1,
>>
>> diff --git a/exec/coroipcs.c b/exec/coroipcs.c
>> index 0ca22d3..d53e4fb 100644
>> --- a/exec/coroipcs.c
>> +++ b/exec/coroipcs.c
>> @@ -1236,11 +1236,28 @@ static int shared_mem_dispatch_bytes_left (const
>> struct conn_info *conn_info)
>> static void memcpy_dwrap (struct conn_info *conn_info, void *msg,
>> unsigned int len)
>> {
>> unsigned int write_idx;
>> + unsigned int padding;
>>
>> write_idx = conn_info->control_buffer->write;
>>
>> + /*
>> + * Calculate padding that would be needed to make the message size a
>> + * multiple of 8 bytes
>> + */
>> + padding = 8 - (len % 8);
>> + if ( padding == 8 ) {
>> + padding=0;
>> + }
>> +
> The logic of this patch looks correct but the implementation isn't very
> tidy :) Could you try my patch instead?
>
> Also thanks for the debug work and making some initial stab at the
> patches. We really need contributions like yours to improve the code base.
>
> Regards
> -steve
>
>> + /*
>> + * Write the message normally, and just pretend we wrote the extra
>> padding bytes
>> + * by increasing control_buffer->write by the padding amount
>> + *
>> + * FIXME: Padding byte memory locations should be zeroed out in a real
>> patch, but
>> + * but for this proof of concept the aim is to be minimally
>> intrusive.
>> + */
>> memcpy (&conn_info->dispatch_buffer[write_idx], msg, len);
>> - conn_info->control_buffer->write = (write_idx + len) %
>> conn_info->dispatch_size;
>> + conn_info->control_buffer->write = (write_idx + len + padding) %
>> conn_info->dispatch_size;
>> }
>>
>> static void msg_send (void *conn, const struct iovec *iov, unsigned int
>> iov_len,
>> diff --git a/lib/coroipcc.c b/lib/coroipcc.c
>> index bbeb95f..ab24b71 100644
>> --- a/lib/coroipcc.c
>> +++ b/lib/coroipcc.c
>> @@ -910,6 +910,7 @@ coroipcc_dispatch_put (hdb_handle_t handle)
>> cs_error_t res;
>> char *addr;
>> unsigned int read_idx;
>> + unsigned int padding;
>>
>> res = hdb_error_to_cs (hdb_handle_get_always (&ipc_hdb, handle, (void
>> **)&ipc_instance));
>> if (res != CS_OK) {
>> @@ -931,8 +932,22 @@ retry_ipc_sem_wait:
>>
>> read_idx = ipc_instance->control_buffer->read;
>> header = (coroipc_response_header_t *) &addr[read_idx];
>> +
>> + /*
>> + * Calculate padding that would be needed to make the message size a
>> + * multiple of 8 bytes
>> + */
>> + padding = 8 - (header->size % 8);
>> + if ( padding == 8 ) {
>> + padding=0;
>> + }
>> +
>> + /*
>> + * coroipcs.c memcpy_dwrap() will have pretended to write padding bytes
>> to
>> + * this message, so here we pretend to have read them.
>> + */
>> ipc_instance->control_buffer->read =
>> - (read_idx + header->size) % ipc_instance->dispatch_size;
>> + (read_idx + header->size + padding) %
>> ipc_instance->dispatch_size;
>> /*
>> * Put from dispatch get and also from this call's get
>> */
>>
>>
>>
>>
>>
>>
>>
>>
>> _______________________________________________
>> Openais mailing list
>> [email protected]
>> https://lists.linux-foundation.org/mailman/listinfo/openais
_______________________________________________
Openais mailing list
[email protected]
https://lists.linux-foundation.org/mailman/listinfo/openais