Пример #1
0
static void 
msgringent_free (msgringent * ktmp)
{
  int i;
  for(i=0; i<ktmp->body.n; i++)
    ppage_unpin (kva2pp ((u_long) ktmp->body.r[i].data));
  if (ktmp->owner != NULL) 
    ppage_unpin (kva2pp ((u_long) ktmp->owner));
  free (ktmp);
}
Пример #2
0
void
disk_buf_free (struct buf *bp)
{
  u_int datalen;
  u_int data, next;

  /* unpin pages */
  if (bp->b_flags & B_SCSICMD) {
    struct scsicmd *scsicmd = (struct scsicmd *) bp->b_memaddr;
    data = (u_int) scsicmd->data_addr;
    datalen = scsicmd->datalen;
    free (scsicmd->scsi_cmd);
    free (scsicmd);
  } else {
    data = (u_int)bp->b_memaddr;
    datalen = bp->b_bcount;
  }

  while (datalen > 0) {
    if (bp->b_flags & B_BC_REQ) {
      ppage_unpin (kva2pp (data));
    } else {
      struct Env *e;
      int r;

      e = env_id2env (bp->b_envid, &r);
      assert (e); /* XXX - what if an env with an outstanding request dies? */
      ppage_unpin (&ppages[PGNO (*env_va2ptep (e, data))]);
    }
    /* go to start of next page of data */
    next = (data & ~PGMASK) + NBPG;
    if (next - data >= datalen) break;
    assert (next > data);
    datalen -= next - data;
    data = next;
  }

  if (bp->b_resptr) {
    ppage_unpin (kva2pp ((u_int) bp->b_resptr));
  }

  free (bp);
}
Пример #3
0
Файл: wk.c Проект: aunali1/exopc
void wk_free (struct Env *e) {
  int i;
  struct Ppage *pp;

  if (e->env_pred) {
    free (e->env_pred);
    e->env_pred = NULL;
  }
  if (!e->env_pred_pgs)
    return;
  for (i = 0; e->env_pred_pgs[i]; i++) {
    pp = ppages_get(e->env_pred_pgs[i]);
    ppage_unpin (pp);
  }
  free (e->env_pred_pgs);
  e->env_pred_pgs = NULL;
}
Пример #4
0
int
disk_prepare_bc_request (u_int devno, u_quad_t blkno, void *vaddr, u_int flags,
			 int *resptr, struct buf **headbpp)
{
  struct buf *bp;

  /* XXX - test for big blkno wraparound */
  if ((devno >= si->si_ndisks) ||
      (((blkno * NBPG) / si->si_disks[devno].d_bsize) >=
       si->si_disks[devno].d_size)) {
    warn ("disk_prepare_bc_request: invalid devno (%u) or blkno (%qu)",
	  devno, blkno);
    return (-E_INVAL);
  }

  if (headbpp == NULL) {
    warn ("disk_prepare_bc_request: headbpp == NULL");
    return (-E_INVAL);
  }

  bp = disk_buf_alloc();
  if (!bp)
    return (-E_NO_MEM);

  bp->b_next = NULL;
  bp->b_sgnext = NULL;
  bp->b_flags = flags;
  bp->b_dev = devno;
  bp->b_blkno = (blkno * NBPG) / si->si_disks[devno].d_bsize;
  bp->b_bcount = NBPG;
  bp->b_sgtot = 0;
  bp->b_memaddr = vaddr;
  bp->b_envid = curenv->env_id;
  bp->b_resid = 0;
  bp->b_resptr = NULL;

  ppage_pin (kva2pp((u_int) vaddr));

  if (*headbpp) {
    struct buf *tmpbp = *headbpp;

    while (tmpbp->b_flags & B_SCATGATH) {
      tmpbp = (struct buf *) tmpbp->b_sgnext;
      if (tmpbp == NULL) {
	warn ("disk_prepare_bc_request: bad scatter/gather list");
	ppage_unpin (kva2pp((u_int) vaddr));
	free (bp);
	return (-E_INVAL);
      }
    }

    /* XXX - test for big blkno wraparound */
    if (bp->b_blkno != (tmpbp->b_blkno +
			(tmpbp->b_bcount / 
			 si->si_disks[bp->b_dev].d_bsize))) {
      warn ("disk_prepare_bc_request: noncontiguous requests "
	    "(prevblk %qu, size %u, curblk %qu) can't be merged",
	    tmpbp->b_blkno, tmpbp->b_bcount, bp->b_blkno);
      ppage_unpin (kva2pp((u_int) vaddr));
      free (bp);
      return (-E_INVAL);
    }

    (*headbpp)->b_sgtot += NBPG;
    tmpbp->b_flags |= B_SCATGATH;
    tmpbp->b_sgnext = bp;
  } else {
    *headbpp = bp;
    bp->b_sgtot = NBPG;
  }

  if (resptr) {
    ppage_pin (kva2pp(((u_int) resptr)));
  }
  bp->b_resptr = resptr;

  return (0);
}