[Cbe-oss-dev] [PATCH] libspe2: use mapped dma registers to speed up proxy dma

D. Herrendoerfer d.herrendoerfer at herrendoerfer.name
Mon Jun 11 18:56:57 EST 2007


Added.

Thank you very much!

D.Herrendoerfer


On Wed, 2007-06-06 at 11:38 +0200, stenzel at de.ibm.com wrote:
> The following patch speeds up the MFC proxy command functions by
> writing to the dma registers directly via mapped problem state.
> This new implementation has two small side effects, but this should 
> have no impact on existing applications because the current 
> implementation does not support proxy command at all, if the context 
> was created with the SPE_MAP_PS flag.
> 
> The two side effects are, if a context is created with SPE_MAP_PS:
> 
> 1) A mask value of 0 will not be interpreted as "all outsanding tags"
> 2) An event handler can not register for a SPE_EVENT_TAG_GROUP 
> 
> Signed-off-by: Gerhard Stenzel <stenzel at de.ibm.com>
> 
> ===================================================================
> Index: libspe2/spebase/dma.c
> ===================================================================
> --- libspe2/spebase/dma.c	(revision 48)
> +++ libspe2/spebase/dma.c	(working copy)
> @@ -20,6 +20,7 @@
>  #include <errno.h>
>  #include <fcntl.h>
>  #include <stdio.h>
> +#include <stdint.h>
>  #include <string.h>
>  #include <unistd.h>
>  
> @@ -28,8 +29,8 @@
>  #include "create.h"
>  #include "dma.h"
>  
> -static int spe_read_tag_status_block(spe_context_ptr_t spectx, unsigned int *tag_status);
> -static int spe_read_tag_status_noblock(spe_context_ptr_t spectx, unsigned int *tag_status);
> +static int spe_read_tag_status_block(spe_context_ptr_t spectx, unsigned int mask, unsigned int *tag_status);
> +static int spe_read_tag_status_noblock(spe_context_ptr_t spectx, unsigned int mask, unsigned int *tag_status);
>  
>  static int spe_do_mfc_put(spe_context_ptr_t spectx, unsigned src, void *dst,
>  			  unsigned size, unsigned tag, unsigned class,
> @@ -44,15 +45,31 @@ static int spe_do_mfc_put(spe_context_pt
>  		.cmd   = cmd,
>  	};
>  	int ret, fd;
> +	unsigned int eah, eal;
> +	volatile struct spe_mfc_command_area *cmd_area = 
> +                spectx->base_private->mfc_mmap_base;
>  
>  	DEBUG_PRINTF("queuing DMA %x %lx %x %x %x %x\n", parm.lsa,
>  		parm.ea, parm.size, parm.tag, parm.class, parm.cmd);
> -#if 0 // fixme
> +
>  	if (spectx->base_private->flags & SPE_MAP_PS) {
> -		return 0;
> +		_base_spe_context_lock(spectx, FD_MFC);
> +		eal = (uintptr_t) dst & 0xFFFFFFFF;
> +		eah = (unsigned long long)(uintptr_t) dst >> 32;
> +		while ((cmd_area->MFC_QStatus & 0x0000FFFF) == 0) ;
> +		do {
> +			cmd_area->MFC_LSA         = src;
> +			cmd_area->MFC_EAH         = eah;
> +			cmd_area->MFC_EAL         = eal;
> +			cmd_area->MFC_Size_Tag    = (size << 16) | tag;
> +                        cmd_area->MFC_ClassID_CMD = (class << 16) | cmd;
> +
> +			ret = cmd_area->MFC_CMDStatus & 0x00000003;
> +		} while (ret); // at least one of the two bits is set
> +		_base_spe_context_unlock(spectx, FD_MFC);
> +		return ret;
>  	}
> -#endif
> -	DEBUG_PRINTF("%s $d\n", __FUNCTION__, __LINE__);
> +
>  	fd = open_if_closed(spectx, FD_MFC, 0);
>  	if (fd != -1) {
>  		ret = write(fd, &parm, sizeof (parm));
> @@ -79,15 +96,31 @@ static int spe_do_mfc_get(spe_context_pt
>  		.cmd   = cmd,
>  	};
>  	int ret, fd;
> +	unsigned int eah, eal;
> +	volatile struct spe_mfc_command_area *cmd_area = 
> +                spectx->base_private->mfc_mmap_base;
> +
> +	DEBUG_PRINTF("queuing DMA %x %x %x %x %x %x\n", parm.lsa,
> +	                                           parm.ea, parm.size, parm.tag, parm.class, parm.cmd);
> +	
> +
> +        if (spectx->base_private->flags & SPE_MAP_PS) {
> +		_base_spe_context_lock(spectx, FD_MFC);
> +		eal = (uintptr_t) src & 0xFFFFFFFF;
> +		eah = (unsigned long long)(uintptr_t) src >> 32;
> +                while ((cmd_area->MFC_QStatus & 0x0000FFFF) == 0) ;
> +                do {
> +                        cmd_area->MFC_LSA         = dst;
> +                        cmd_area->MFC_EAH         = eah;
> +                        cmd_area->MFC_EAL         = eal;
> +                        cmd_area->MFC_Size_Tag    = (size << 16) | tag;
> +                        cmd_area->MFC_ClassID_CMD = (class << 16) | cmd;
> +                        ret = cmd_area->MFC_CMDStatus & 0x00000003;
> +                } while (ret); // at least one of the two bits is set
> +		_base_spe_context_unlock(spectx, FD_MFC);
> +                return ret;
> +        }
>  
> -	DEBUG_PRINTF("queuing DMA %x %lx %x %x %x %x\n", parm.lsa,
> -		parm.ea, parm.size, parm.tag, parm.class, parm.cmd);
> -#if 0 // fixme
> -	if (spectx->base_private->flags & SPE_MAP_PS) {
> -		return 0;
> -	}
> -#endif
> -	DEBUG_PRINTF("%s $d\n", __FUNCTION__, __LINE__);
>  	fd = open_if_closed(spectx, FD_MFC, 0);
>  	if (fd != -1) {
>  		ret = write(fd, &parm, sizeof (parm));
> @@ -182,8 +215,7 @@ static int spe_mfcio_tag_status_read_all
>  	int fd;
>  
>  	if (spectx->base_private->flags & SPE_MAP_PS) {
> -		// fixme
> -		errno = ENOTSUP;
> +		return spe_read_tag_status_block(spectx, mask, tag_status);
>  	} else {
>  		fd = open_if_closed(spectx, FD_MFC, 0);
>  
> @@ -191,7 +223,7 @@ static int spe_mfcio_tag_status_read_all
>  			return -1;
>  		}
>  
> -		return spe_read_tag_status_block(spectx, tag_status);
> +		return spe_read_tag_status_block(spectx, mask, tag_status);
>  	}
>  	return -1;
>  }
> @@ -199,13 +231,13 @@ static int spe_mfcio_tag_status_read_all
>  static int spe_mfcio_tag_status_read_any(spe_context_ptr_t spectx,
>  					unsigned int mask, unsigned int *tag_status)
>  {
> -	return spe_read_tag_status_block(spectx, tag_status);
> +	return spe_read_tag_status_block(spectx, mask, tag_status);
>  }
>  
>  static int spe_mfcio_tag_status_read_immediate(spe_context_ptr_t spectx,
>  						     unsigned int mask, unsigned int *tag_status)
>  {
> -	return spe_read_tag_status_noblock(spectx, tag_status);
> +	return spe_read_tag_status_noblock(spectx, mask, tag_status);
>  }
>  
> 
> @@ -213,13 +245,21 @@ static int spe_mfcio_tag_status_read_imm
>  /* MFC Read tag status functions
>   *
>   */
> -static int spe_read_tag_status_block(spe_context_ptr_t spectx, unsigned int *tag_status)
> +static int spe_read_tag_status_block(spe_context_ptr_t spectx, unsigned int mask, unsigned int *tag_status)
>  {
>  	int fd;
> +	volatile struct spe_mfc_command_area *cmd_area = 
> +                spectx->base_private->mfc_mmap_base;
>  
>  	if (spectx->base_private->flags & SPE_MAP_PS) {
> -		// fixme
> -		errno = ENOTSUP;
> +		_base_spe_context_lock(spectx, FD_MFC);
> +		cmd_area->Prxy_QueryMask = mask;
> +		__asm__ ("eieio");
> +		*tag_status = 0;
> +		while  (*tag_status ^ mask) 
> +			*tag_status =  cmd_area->Prxy_TagStatus;
> +		_base_spe_context_unlock(spectx, FD_MFC);
> +		return 0;
>  	} else {
>  		fd = open_if_closed(spectx, FD_MFC, 0);
>  		
> @@ -230,16 +270,22 @@ static int spe_read_tag_status_block(spe
>  	return -1;
>  }
>  
> -static int spe_read_tag_status_noblock(spe_context_ptr_t spectx, unsigned int *tag_status)
> +static int spe_read_tag_status_noblock(spe_context_ptr_t spectx, unsigned int mask, unsigned int *tag_status)
>  {
>  	struct pollfd poll_fd;
>  	
>  	int fd;
>  	unsigned int ret;
> +	volatile struct spe_mfc_command_area *cmd_area = 
> +                spectx->base_private->mfc_mmap_base;
>  
>  	if (spectx->base_private->flags & SPE_MAP_PS) {
> -		// fixme
> -		errno = ENOTSUP;
> +		_base_spe_context_lock(spectx, FD_MFC);
> +		cmd_area->Prxy_QueryMask = mask;
> +		__asm__ ("eieio");
> +		*tag_status =  cmd_area->Prxy_TagStatus;
> +		_base_spe_context_unlock(spectx, FD_MFC);
> +		return 0;
>  	} else {
>  		fd = open_if_closed(spectx, FD_MFC, 0);
>  		
> @@ -266,8 +312,8 @@ static int spe_read_tag_status_noblock(s
>  int _base_spe_mfcio_tag_status_read(spe_context_ptr_t spectx, unsigned int mask, unsigned int behavior, unsigned int *tag_status)
>  {
>  	if ( mask != 0 ) {
> -		errno = ENOTSUP;
> -		return -1;
> +		if (!(spectx->base_private->flags & SPE_MAP_PS)) 
> +			mask = 0;
>  	}
>  
>  	switch (behavior) {
> Index: libspe2/speevent/spe_event.c
> ===================================================================
> --- libspe2/speevent/spe_event.c	(revision 48)
> +++ libspe2/speevent/spe_event.c	(working copy)
> @@ -221,6 +221,12 @@ int _event_spe_event_handler_register(sp
>        _event_spe_context_unlock(event->spe);
>        return -1;
>      }
> +
> +    if (event->spe->base_private->flags & SPE_MAP_PS) {
> +	    _event_spe_context_unlock(event->spe);
> +	    errno = ENOTSUP;
> +	    return -1;
> +    }
>      
>      ev_buf = &evctx->events[__SPE_EVENT_TAG_GROUP];
>      ev_buf->events = SPE_EVENT_TAG_GROUP;
> 
> ===================================================================
> 
> Best regards, 
> 
> Gerhard Stenzel, Linux on Cell Development, LTC
> -------------------------------------------------------------------------------------
> IBM Deutschland Entwicklung GmbH
> Vorsitzender des Aufsichtsrats: Martin Jetter | Geschaeftsfuehrung: Herbert Kircher
> Sitz der Gesellschaft: Boeblingen | Registergericht: Amtsgericht Stuttgart, HRB 243294
> 
> _______________________________________________
> cbe-oss-dev mailing list
> cbe-oss-dev at ozlabs.org
> https://ozlabs.org/mailman/listinfo/cbe-oss-dev




More information about the cbe-oss-dev mailing list