Example #1
0
/* Allocates two pointers of given sizes and random characteristics (alignment,
   overlapping, relative-position). */
static void get_random_two_pointers (uword size1, uword size2,
				     void ** ptr1, void ** ptr2,
				     void ** to_free1, void ** to_free2)
{
  uword do_align1, do_align2;
  uword align1, align2;
  uword overlap, two_less_that_one;
  uword min;

  do_align1 = bounded_random_u32 (&g_seed, 0, 1);
  align1 = (do_align1) ? bounded_random_u32 (&g_seed, 0, MAX_LOG2_ALIGN) : (0);
  do_align2 = bounded_random_u32 (&g_seed, 0, 1);
  align2 = (do_align2) ? bounded_random_u32 (&g_seed, 0, MAX_LOG2_ALIGN) : (0);
  overlap = bounded_random_u32 (&g_seed, 0, 1);
  two_less_that_one = (overlap) ? bounded_random_u32 (&g_seed, 0, 1) : (0);

  /* Pick random distance between pointers. */
  if (overlap)
    {
      min = clib_min (size1, size2);
      overlap = bounded_random_u32 (&g_seed, 0, (min) ? (min - 1) : (0));
    }
    
  get_two_pointers (size1, size2, align1, align2,
		    overlap, two_less_that_one,
		    ptr1, ptr2, to_free1, to_free2);

  VERBOSE3 ("size1 %u, size2 %u, align1 %u, align2 %u, overlap %u, "
	    "two_less_that_one %u\n",
	    size1, size2, align1, align2, overlap, two_less_that_one);
  VERBOSE3 ("p1 %U (%p)\n", format_u32_binary, *ptr1, *ptr1);
  VERBOSE3 ("p2 %U (%p)\n", format_u32_binary, *ptr2, *ptr2);
}
Example #2
0
static int mmio_write(struct cxl_afu_h *afu_h, int ctx, uint32_t offset,
		      uint64_t data)
{
	int rc = -1;
	uint32_t offs = (ctx * MMIO_CTX_OFFSET) + offset;

	VERBOSE3("[%s] Enter, Offset: 0x%x data: 0x%016llx\n",
		__func__, offs, (long long)data);
	rc = cxl_mmio_write64(afu_h, offs, data);
	VERBOSE3("[%s] Exit, rc = %d\n", __func__, rc);
	return rc;
}
Example #3
0
static int mmio_read(struct cxl_afu_h *afu_h, int ctx, uint32_t offset,
		     uint64_t *data)
{
	int rc = -1;
	uint32_t offs = (ctx * MMIO_CTX_OFFSET) + offset;

	VERBOSE3("[%s] Enter, CTX: %d Offset: 0x%x\n", __func__, ctx, offs);
	rc = cxl_mmio_read64(afu_h, offs, data);
	VERBOSE3("[%s] Exit, rc = %d data: 0x%016llx\n",
		__func__, rc, (long long)*data);
	return rc;
}
Example #4
0
static int afu_m_close(struct mdev_ctx *mctx)
{
	VERBOSE3("[%s] Enter\n", __func__);
	if (NULL == mctx->afu_h)
		return -1;

	cxl_mmio_unmap(mctx->afu_h);
	cxl_afu_free(mctx->afu_h);
	mctx->afu_h = NULL;

	if (mctx->errinfo)
		free(mctx->errinfo);
	mctx->errinfo = NULL;
	VERBOSE3("[%s] Exit\n", __func__);
	return 0;
}
Example #5
0
/* Allocates randomly-aligned pointer to memory of given size. */
static void get_random_pointer (uword size, void ** ptr, void ** to_free)
{
  uword do_align = bounded_random_u32 (&g_seed, 0, 1);
  uword align, offset;
  
  if (do_align)
    {
      align = bounded_random_u32 (&g_seed, 0, MAX_LOG2_ALIGN);
      *ptr = alloc_aligned (size, align, to_free);
      VERBOSE3 ("size %u, align %u\n", size, align);
    }
  else
    {
      offset = bounded_random_u32 (&g_seed, 0, MAX_UNALIGN_OFFSET);
      *ptr = alloc_unaligned (size, offset, to_free);
      VERBOSE3 ("size %u, offset %u\n", size, offset);
    }

  VERBOSE3 ("ptr %U (%p)\n", format_u32_binary, *ptr, *ptr);
}
Example #6
0
int
xfreelist_release_item(xfreelist_t* list,xfreelist_item_t* item){
  int fstatus=XERROR;
  char* function_name="xfreelist_release_item";
  INIT_DEBUG3_MARK();

  /* check that this item is linked with this freelist */
  if( list->items <= item && item < list->items + list->item_nb ) {

    if(item->free){
      fstatus=XERROR_FREELIST_ITEM_ALREADY_FREE;
    }
    else{

      item->free=1;
      item->previous=NULL;

      if(list->head==NULL){
	/* freelist empty */
	item->next=NULL;
	list->head=item;
	list->tail=item;      
      }
      else{
	/* freelist not empty */
	item->next=list->head;
	list->head->previous=item;
	list->head=item;
      }

      VERBOSE3("item '%x' successfully released to freelist '%x'",item,list);
      fstatus=XSUCCESS;

    }

  }
  /* this item is not linked with this list, we have to try sub lists */
  else {

    if ( list->next != NULL ) {
      VERBOSE("item '%x' is not linked to list '%x', releasing using sublist '%x'",item,list,list->next);
      fstatus=xfreelist_release_item(list->next,item);
    }
    else {
      VERBOSE("item '%x' is not linked to list '%x'",item,list);
      fstatus=XERROR_FREELIST_ITEM_NOT_FOUND;
    }

  }

  EXIT_DEBUG3_MARK(fstatus);
  return fstatus;
}
Example #7
0
int
xfreelist_extract_item(xfreelist_t* list,xfreelist_item_t** pitem){
  int fstatus=-1;
  char* function_name="xfreelist_extract_item";
  INIT_DEBUG3_MARK();

  xfreelist_item_t* item;

  /* if list is empty, just try to extract from a next list */
  if(list->head==NULL){

    VERBOSE("no more items in list '%x'",list);

    if ( list->next == NULL)
      xfreelist_extend(list);

    if ( list->next != NULL) {
      fstatus=xfreelist_extract_item(list->next,pitem);      
    }
    else
      fstatus=XERROR_FREELIST_IS_EMPTY;

  }
  else {

    /* get item from head */
    item=list->head;

    /* shift freelist */
    list->head=item->next;
    if(list->head!=NULL)
      list->head->previous=NULL;
    else
      list->tail=NULL;
    
    item->next=NULL;
    item->previous=NULL;
    item->free=0;

    *pitem=item;

    VERBOSE3("item '%x' successfully extracted from freelist '%x'",item,list);
    fstatus=XSUCCESS;

  }
  
  EXIT_DEBUG3_MARK(fstatus);
  return fstatus;
}
Example #8
0
static int afu_check_stime(struct mdev_ctx *mctx)
{
	int	gsel, bsel = 0, ctx = 0;
	uint64_t gmask = 0, qstat_reg, err_reg, mstat_reg;
	uint64_t wtime;
	uint64_t cid_reg;
	int	n_act = 0;
	uint64_t s_time = 0;
	char s[32];

	for (gsel = 0; gsel < MMIO_CASV_REG_NUM; gsel++) {
		mmio_read(mctx->afu_h, MMIO_MASTER_CTX_NUMBER,
			MMIO_CASV_REG + (gsel*8), &gmask);
		if (0 == gmask)
			continue;	/* No bit set, Skip */

		for (bsel = 0; bsel < MMIO_CASV_REG_CTX; bsel++) {
			if (0 == (gmask & (1ull << bsel)))
				continue;	/* Skip */

			ctx = (gsel * MMIO_CASV_REG_CTX) + bsel;	/* Active */

			mmio_read(mctx->afu_h, ctx+1, MMIO_DDCBQ_STATUS_REG, &qstat_reg);
			if (0 == (qstat_reg & 0xffffffff00000000ull)) {
				VERBOSE3("AFU[%d:%03d] master skip\n",
					mctx->card, ctx);
				continue;	/* Skip Master */
			}
			mmio_read(mctx->afu_h, ctx+1, MMIO_DDCBQ_WT_REG, &wtime);
			wtime = wtime / 250; /* makes time in usec */

			mmio_read(mctx->afu_h, ctx+1, MMIO_DDCBQ_CID_REG, &cid_reg);
			uint16_t cur_cid = (uint16_t)(cid_reg >> 16);	/* Currect Context id */
			uint16_t my_cid = (uint16_t)(cid_reg & 0xffff);	/* My Context id */

			mmio_read(mctx->afu_h, ctx+1, MMIO_DDCBQ_DMAE_REG, &err_reg);

			uint16_t cseq = (uint16_t)(qstat_reg >> 48ull);	/* Currect sequence */
			uint16_t lseq = (uint16_t)(qstat_reg >> 32ull);	/* Last sequence */
			uint8_t qidx = (uint8_t)(qstat_reg >> 24);	/* Q Index */
			uint16_t qnfe = (uint16_t)(qstat_reg >> 8);	/* Context Non Fatal Error Bits */
			uint8_t qstat = (uint8_t)(qstat_reg & 0xff);	/* Context Status */

			/* Generate W for Waiting, I for Idle and R for Running */
			char flag = 'W';		/* Default Context is Waiting to get executed */
			if ((lseq + 1 ) == cseq)
				flag = 'I';		/* Context is Idle, nothing to do */
			else if (0x30 == qstat)		/* if Bits 4 + 5 on ? */
					flag = 'R';	/* Context is Running */

			if (qnfe) {
				VERBOSE0("AFU[%d:%03d] ERR: CurrentCtx: %03d MyCtx: %03d CS: %04X LS: %04X ",
					mctx->card, ctx, cur_cid, my_cid, cseq, lseq);
				VERBOSE0("[%c] IDX: %02d QNFE: %04x QSTAT: %02x Time: %lld usec",
					flag, qidx, qnfe, qstat, (long long)wtime);
				if (0 != err_reg)
					VERBOSE0("DMA Err: 0x%016llx", (long long)err_reg);
				VERBOSE0("\n");
			} else {
				VERBOSE0("AFU[%d:%03d] CurrentCtx: %03d MyCtx: %03d CS: %04X LS: %04X ",
					mctx->card, ctx, cur_cid, my_cid, cseq, lseq);
				VERBOSE0("[%c] IDX: %02d QNFE: %04x QSTAT: %02x Time: %lld usec",
					flag, qidx, qnfe, qstat, (long long)wtime);
				if (0 != err_reg)
					VERBOSE0("DMA Err: 0x%016llx", (long long)err_reg);
				VERBOSE0("\n");
			}
			n_act++;
			s_time += wtime;
		}
	}
	if (n_act) {
		time_t result = time(NULL);
		struct tm * p = localtime(&result);
		strftime(s, 32, "%T", p);

		VERBOSE0("AFU[%d:XXX] at %s Running %d Active Contexts total %lld msec",
			 mctx->card,  s, n_act, (long long)s_time/1000);
		mmio_read(mctx->afu_h, MMIO_MASTER_CTX_NUMBER,
			MMIO_AFU_STATUS_REG, &mstat_reg);
		if (0 != mstat_reg)
			VERBOSE0(" Status: 0x%016llx", (long long)mstat_reg);
		VERBOSE0("\n");
	}
	return mctx->dt;
}
Example #9
0
/*
 * Open AFU Master Device
 */
static int afu_m_open(struct mdev_ctx *mctx)
{
	int rc = 0;
	char device[64];
	long api_version, cr_device, cr_vendor;

	sprintf(device, "/dev/cxl/afu%d.0m", mctx->card);
	VERBOSE3("[%s] Enter, Open Device: %s\n", __func__, device);
	mctx->afu_h = cxl_afu_open_dev(device);
	if (NULL == mctx->afu_h) {
		VERBOSE0("[%s] Exit, Card Open error rc: %d\n", __func__, rc);
		return -1;
	}

	/* Check if the compiled in API version is compatible with the
	   one reported by the kernel driver */
	rc = cxl_get_api_version_compatible(mctx->afu_h, &api_version);
	if ((rc != 0) || (api_version != CXL_KERNEL_API_VERSION)) {
		VERBOSE0(" [%s] ERR: incompatible API version: %ld/%d rc=%d\n",
			 __func__, api_version, CXL_KERNEL_API_VERSION, rc);
		rc = -2;
		goto err_afu_free;
	}

	/* Check vendor id */
	rc = cxl_get_cr_vendor(mctx->afu_h, 0, &cr_vendor);
	if ((rc != 0) || (cr_vendor != CGZIP_CR_VENDOR)) {
		VERBOSE0(" [%s] ERR: vendor_id: %ld/%d rc=%d\n",
			 __func__, (unsigned long)cr_vendor,
			 CGZIP_CR_VENDOR, rc);
		rc = -3;
		goto err_afu_free;
	}

	/* Check device id */
	rc = cxl_get_cr_device(mctx->afu_h, 0, &cr_device);
	if ((rc != 0) || (cr_device != CGZIP_CR_DEVICE)) {
		VERBOSE0(" [%s] ERR: device_id: %ld/%d rc=%d\n",
			 __func__, (unsigned long)cr_device,
			 CGZIP_CR_VENDOR, rc);
		rc = -4;
		goto err_afu_free;
	}

	/* If we cannot get it, continue with warning ... */
	mctx->errinfo = NULL;
	rc = cxl_errinfo_size(mctx->afu_h, &mctx->errinfo_size);
	if (0 == rc) {
		mctx->errinfo = malloc(mctx->errinfo_size);
		if (mctx->errinfo == NULL) {
			rc = -5;
			goto err_afu_free;
		}
	} else
		VERBOSE0(" [%s] WARN: Cannot retrieve errinfo size rc=%d\n",
			 __func__, rc);

	rc = cxl_afu_attach(mctx->afu_h, (__u64)(unsigned long)
			    (void *)mctx->wed);
	if (0 != rc) {
		rc = -6;
		goto err_free_errinfo;
	}

	rc = cxl_mmio_map(mctx->afu_h, CXL_MMIO_BIG_ENDIAN);
	if (rc != 0) {
		rc = -7;
		goto err_free_errinfo;
	}

	return 0;

 err_free_errinfo:
	if (mctx->errinfo)
		free(mctx->errinfo);
	mctx->errinfo = NULL;
 err_afu_free:
	cxl_afu_free(mctx->afu_h);
	mctx->afu_h = NULL;
	VERBOSE3("[%s] Exit rc=%d\n", __func__, rc);
	return rc;
}
Example #10
0
int xstream_receive_timeout(int socket,char* buffer,size_t length,int timeout){
  int fstatus=-1;
  int rc;
  size_t read_bytes;
  
  int sock_flags;
  int nonblock=0;
  struct pollfd ufds;

  struct timeval start_time;
  struct timeval current_time;
  int timeleft;

  /* set non block mode if required */
  if(timeout!=0){
    sock_flags=fcntl(socket,F_GETFL);
    if(fcntl(socket,F_SETFL, sock_flags | O_NONBLOCK)){
      ERROR("unable to set socket non-blocking flag : %s",strerror(errno));
      return XERROR_STREAM_SETSOCKOPT_FAILED;
    }
    else{
      VERBOSE("socket non-blocking flag is now set");
      nonblock=1;

      ufds.fd=socket;
      ufds.events=POLLIN;
    }
  }
  
  /* get start time */
  gettimeofday(&start_time,NULL);

  /* send data */
  read_bytes=0;
  while(read_bytes<length){
    
    /* attempt polling if non block mode is activated */
    if(nonblock){
      VERBOSE3("looking for POLLIN events on socket %d",socket);
      
      gettimeofday(&current_time,NULL);
      timeleft=timeout
	-(current_time.tv_sec-start_time.tv_sec)*1000
	-(current_time.tv_sec-start_time.tv_sec)/1000;
      
      if(timeleft<=0){
	ERROR("receive at %d of %d bytes : timeout",
	      read_bytes,length);
	fstatus=XERROR_STREAM_TIMEOUT;
	break;
      }

      if((rc=poll(&ufds,1,timeleft))<=0){
	if(rc<0 && (errno==EINTR || errno==EAGAIN)){
	  continue;
	}
	else if(rc==0){
	  continue;
	}
	else if(rc<0){
	  ERROR("receive at %d of %d bytes : poll error : %s",
		read_bytes,length,strerror(errno));
	  fstatus=XERROR_STREAM_POLL_ERROR;
	  break;
	}
      }
      
      /* read data from socket */
      rc=read(socket,buffer+read_bytes,length-read_bytes);
      VERBOSE3("read return code is %d (errno=%d)",rc,errno);

    }
    else {

      /* read data from socket */
      do{
	rc=read(socket,buffer+read_bytes,length-read_bytes);
	VERBOSE3("read return code is %d (errno=%d)",rc,errno);
      }
      while(rc<0 && (errno==EINTR || errno==EAGAIN));

    }
    /*_*/ /* attempt polling if required */

    /* process read return code */
    if(rc>0)
      read_bytes+=rc;
    else if (rc==0) {
      ERROR("receive at %d of %d bytes : 0 bytes received during read op",
	    read_bytes,length);
      fstatus=XERROR_STREAM_SOCKET_CLOSED;
      break;
    }
    else {
      ERROR("receive at %d of %d bytes : bad return code on read op : %d",
	    read_bytes,length,rc);
      fstatus=rc;
      break;
    }
    
  }

  if(read_bytes==length){
    fstatus=XSUCCESS;
  }
    
  return fstatus;
}
Example #11
0
int xstream_send_timeout(int socket,char* buffer,size_t length,int timeout){
  int fstatus=XERROR;
  int rc;
  size_t written_bytes;

  char test;

  int sock_flags=0;
  int nonblock=0;
  struct pollfd ufds;

  struct timeval start_time;
  struct timeval current_time;
  int timeleft;

  /* set non block mode if required */
  if(timeout!=0){
    sock_flags=fcntl(socket,F_GETFL);
    if(fcntl(socket,F_SETFL, sock_flags | O_NONBLOCK)){
      ERROR("unable to set socket non-blocking flag : %s",strerror(errno));
      return XERROR_STREAM_SETSOCKOPT_FAILED;
    }
    else{
      VERBOSE("socket non-blocking flag is now set");
      nonblock=1;

      ufds.fd=socket;
      ufds.events=POLLOUT;
    }
  }
  
  /* get start time */
  gettimeofday(&start_time,NULL);

  /* send data */
  written_bytes=0;
  while(written_bytes<length){

    /* attempt polling if non block mode is activated */
    if(nonblock){
      VERBOSE3("looking for POLLOUT events on socket %d",socket);

      gettimeofday(&current_time,NULL);
      timeleft=timeout
	-(current_time.tv_sec-start_time.tv_sec)*1000
	-(current_time.tv_sec-start_time.tv_sec)/1000;
      
      if(timeleft<=0){
	ERROR("send at %d/%d bytes transmitted : timeout",
	      written_bytes,length);
	fstatus=XERROR_STREAM_TIMEOUT;
	break;
      }

      if((rc=poll(&ufds,1,timeleft))<=0){
	if(rc<0 && (errno==EINTR || errno==EAGAIN)){
	  continue;
	}
	else if(rc==0){
	  continue;
	}
	else if(rc<0){
	  ERROR("send at %d/%d bytes transmitted : poll error : %s",
		written_bytes,length,strerror(errno));
	  fstatus=XERROR_STREAM_POLL_ERROR;
	  break;
	}
	else{
	  
	  /* we just check that the socket is still here */
	  /* read from a closed nonblocking socket should return 0 */
	  do{
	    rc=read(socket,&test,1);
	  }
	  while(rc<0 && errno==EINTR);
	  if(rc==0){
	    ERROR("send at %d/%d bytes transmitted : socket is gone",
		  written_bytes,length);
	    fstatus=XERROR_STREAM_SOCKET_CLOSED;
	    break;
	  }
	  
	}
      }
      
      /* send data */
      rc=write(socket,buffer+written_bytes,length-written_bytes);
      VERBOSE3("write return code is %d (errno=%d)",rc,errno);

    }
    else {

      /* send data */
      do{
	rc=write(socket,buffer+written_bytes,length-written_bytes);
	VERBOSE3("write return code is %d (errno=%d)",rc,errno);
      }
      while(rc<0 && (errno==EINTR || errno==EAGAIN));

    }

    /* process write return code */
    if(rc>0)
      written_bytes+=rc;
    else if(rc) {
      fstatus=rc;
      break;
    }
    else
      break;
    
  }
  
  /* reverse socket flags */
  if(timeout!=0){
    fcntl(socket,F_SETFL,sock_flags);
  }

  if(written_bytes==length){
    fstatus=XSUCCESS;
  }
    
  return fstatus;
}