diff --git a/configure.ac b/configure.ac index 9ac2e21..54cbb9b 100644 --- a/configure.ac +++ b/configure.ac @@ -2980,6 +2980,11 @@ else AC_MSG_RESULT([int or better]) fi +# Define strict alignment memory access for alignment-sensitive platform (i.e., SPARC) +if test "$host_cpu" = "sparc" ; then + AC_DEFINE(HAVE_STRICT_ALIGNMENT,1,[Define if strict alignment memory access is required]) +fi + # There are further alignment checks after we test for int64_t etc. below. # Get the size of the C types for encoding in the basic datatypes and for diff --git a/src/mpid/ch3/channels/nemesis/src/ch3_progress.c b/src/mpid/ch3/channels/nemesis/src/ch3_progress.c index 245fe61..0ad94a7 100644 --- a/src/mpid/ch3/channels/nemesis/src/ch3_progress.c +++ b/src/mpid/ch3/channels/nemesis/src/ch3_progress.c @@ -752,12 +752,19 @@ int MPID_nem_handle_pkt(MPIDI_VC_t *vc, char *buf, MPIDI_msg_sz_t buflen) MPIDI_msg_sz_t len = buflen; MPIDI_CH3_Pkt_t *pkt = (MPIDI_CH3_Pkt_t *)buf; +#ifdef HAVE_STRICT_ALIGNMENT + MPIDI_CH3_Pkt_t aligned_pkt_hdr; + MPIDI_CH3_Pkt_t *pkt_ptr = pkt; + + MPIDI_CH3_Pkt_get_aligned_ptr(&aligned_pkt_hdr, buf, &pkt); +#endif + MPIU_DBG_MSG(CH3_CHANNEL, VERBOSE, "received new message"); /* invalid pkt data will result in unpredictable behavior */ MPIU_Assert(pkt->type >= 0 && pkt->type < MPIDI_CH3_PKT_END_ALL); - mpi_errno = pktArray[pkt->type](vc, pkt, &len, &rreq); + mpi_errno = pktArray[pkt->type](vc, buf, &len, &rreq); if (mpi_errno) MPIR_ERR_POP(mpi_errno); buflen -= len; buf += len; diff --git a/src/mpid/ch3/include/mpidimpl.h b/src/mpid/ch3/include/mpidimpl.h index 51d1420..a5944c6 100644 --- a/src/mpid/ch3/include/mpidimpl.h +++ b/src/mpid/ch3/include/mpidimpl.h @@ -1894,4 +1894,35 @@ int MPIDI_CH3I_Progress_deactivate_hook(int id); #define MPID_Progress_activate_hook(id_) MPIDI_CH3I_Progress_activate_hook(id_) #define MPID_Progress_deactivate_hook(id_) MPIDI_CH3I_Progress_deactivate_hook(id_) + +#ifdef HAVE_STRICT_ALIGNMENT +/* The received packet may be stored at unaligned memory address (i.e., eager message + * in TCP netmod), direct access is not allowed on alignment-sensitive platforms + * (i.e., SPARC). This function checks whether the buffer address is aligned and + * returns a pointer to the packet header for safe access. + * If the address is not aligned, then copy the packet header to the aligned + * temporary buffer and returns the pointer to the aligned buffer; otherwise + * returns the pointer to the original buffer. Note that the caller is responsible + * for managing the aligned temporary buffer. */ +static inline void MPIDI_CH3_Pkt_get_aligned_ptr(MPIDI_CH3_Pkt_t * aligned_buf, + MPIDI_CH3_Pkt_t * buf, MPIDI_CH3_Pkt_t ** pkt_ptr) +{ + int align_sz = 8; /* default aligns everything to 8-byte boundaries */ +#ifdef HAVE_MAX_STRUCT_ALIGNMENT + if (align_sz > HAVE_MAX_STRUCT_ALIGNMENT) { + align_sz = HAVE_MAX_STRUCT_ALIGNMENT; + } +#endif + + /* check alignment */ + if (((uintptr_t) buf % align_sz) != 0) { + memcpy(aligned_buf, buf, sizeof(MPIDI_CH3_Pkt_t)); + (*pkt_ptr) = aligned_buf; + } + else { + (*pkt_ptr) = buf; + } +} +#endif + #endif /* !defined(MPICH_MPIDIMPL_H_INCLUDED) */ diff --git a/src/mpid/ch3/src/ch3u_eager.c b/src/mpid/ch3/src/ch3u_eager.c index 1a81c5a..a17fce0 100644 --- a/src/mpid/ch3/src/ch3u_eager.c +++ b/src/mpid/ch3/src/ch3u_eager.c @@ -291,11 +291,21 @@ int MPIDI_CH3_EagerContigShortSend( MPID_Request **sreq_p, int MPIDI_CH3_PktHandler_EagerShortSend( MPIDI_VC_t *vc, MPIDI_CH3_Pkt_t *pkt, MPIDI_msg_sz_t *buflen, MPID_Request **rreqp ) { - MPIDI_CH3_Pkt_eagershort_send_t * eagershort_pkt = &pkt->eagershort_send; + MPIDI_CH3_Pkt_eagershort_send_t * eagershort_pkt = NULL; MPID_Request * rreq; int found; int mpi_errno = MPI_SUCCESS; +#ifdef HAVE_STRICT_ALIGNMENT + MPIDI_CH3_Pkt_t aligned_pkt_hdr; + MPIDI_CH3_Pkt_t *pkt_ptr = pkt; + + MPIDI_CH3_Pkt_get_aligned_ptr(&aligned_pkt_hdr, pkt, &pkt_ptr); + eagershort_pkt = &pkt_ptr->eagershort_send; +#else + eagershort_pkt = &pkt->eagershort_send; +#endif + MPID_THREAD_CS_ENTER(POBJ, MPIR_THREAD_POBJ_MSGQ_MUTEX); /* printf( "Receiving short eager!\n" ); fflush(stdout); */ @@ -607,7 +617,7 @@ int MPIDI_CH3_EagerContigIsend( MPID_Request **sreq_p, int MPIDI_CH3_PktHandler_EagerSend( MPIDI_VC_t *vc, MPIDI_CH3_Pkt_t *pkt, MPIDI_msg_sz_t *buflen, MPID_Request **rreqp ) { - MPIDI_CH3_Pkt_eager_send_t * eager_pkt = &pkt->eager_send; + MPIDI_CH3_Pkt_eager_send_t * eager_pkt = NULL; MPID_Request * rreq; int found; int complete; @@ -615,6 +625,16 @@ int MPIDI_CH3_PktHandler_EagerSend( MPIDI_VC_t *vc, MPIDI_CH3_Pkt_t *pkt, MPIDI_msg_sz_t data_len; int mpi_errno = MPI_SUCCESS; +#ifdef HAVE_STRICT_ALIGNMENT + MPIDI_CH3_Pkt_t aligned_pkt_hdr; + MPIDI_CH3_Pkt_t *pkt_ptr = pkt; + + MPIDI_CH3_Pkt_get_aligned_ptr(&aligned_pkt_hdr, pkt, &pkt_ptr); + eager_pkt = &pkt_ptr->eager_send; +#else + eager_pkt = &pkt->eager_send; +#endif + MPID_THREAD_CS_ENTER(POBJ, MPIR_THREAD_POBJ_MSGQ_MUTEX); MPIU_DBG_MSG_FMT(CH3_OTHER,VERBOSE,(MPIU_DBG_FDEST, @@ -697,7 +717,7 @@ int MPIDI_CH3_PktHandler_EagerSend( MPIDI_VC_t *vc, MPIDI_CH3_Pkt_t *pkt, int MPIDI_CH3_PktHandler_ReadySend( MPIDI_VC_t *vc, MPIDI_CH3_Pkt_t *pkt, MPIDI_msg_sz_t *buflen, MPID_Request **rreqp ) { - MPIDI_CH3_Pkt_ready_send_t * ready_pkt = &pkt->ready_send; + MPIDI_CH3_Pkt_ready_send_t * ready_pkt = NULL; MPID_Request * rreq; int found; int complete; @@ -705,6 +725,16 @@ int MPIDI_CH3_PktHandler_ReadySend( MPIDI_VC_t *vc, MPIDI_CH3_Pkt_t *pkt, MPIDI_msg_sz_t data_len; int mpi_errno = MPI_SUCCESS; +#ifdef HAVE_STRICT_ALIGNMENT + MPIDI_CH3_Pkt_t aligned_pkt_hdr; + MPIDI_CH3_Pkt_t *pkt_ptr = pkt; + + MPIDI_CH3_Pkt_get_aligned_ptr(&aligned_pkt_hdr, pkt, &pkt_ptr); + ready_pkt = &pkt_ptr->ready_send; +#else + ready_pkt = &pkt->ready_send; +#endif + MPIU_DBG_MSG_FMT(CH3_OTHER,VERBOSE,(MPIU_DBG_FDEST, "received ready send pkt, sreq=0x%08x, rank=%d, tag=%d, context=%d", ready_pkt->sender_req_id,