int viomb_deflate_intr(struct virtqueue *vq) { struct virtio_softc *vsc = vq->vq_owner; struct viomb_softc *sc = (struct viomb_softc *)vsc->sc_child; struct balloon_req *b; u_int64_t nvpages; if (viomb_vq_dequeue(vq)) return(1); b = &sc->sc_req; nvpages = b->bl_nentries; bus_dmamap_sync(vsc->sc_dmat, b->bl_dmamap, 0, sizeof(u_int32_t) * nvpages, BUS_DMASYNC_POSTWRITE); if (vsc->sc_features & VIRTIO_BALLOON_F_MUST_TELL_HOST) uvm_pglistfree(&b->bl_pglist); VIOMBDEBUG(sc, "updating sc->sc_actual from %u to %llu\n", sc->sc_actual, sc->sc_actual - nvpages); virtio_write_device_config_4(vsc, VIRTIO_BALLOON_CONFIG_ACTUAL, sc->sc_actual - nvpages); viomb_read_config(sc); /* if we have more work to do, add it to tasks list */ if (sc->sc_npages < sc->sc_actual) task_add(sc->sc_taskq, &sc->sc_task); return(1); }
/* * interrupt handling for vq's */ int viomb_inflate_intr(struct virtqueue *vq) { struct virtio_softc *vsc = vq->vq_owner; struct viomb_softc *sc = (struct viomb_softc *)vsc->sc_child; struct balloon_req *b; struct vm_page *p; u_int64_t nvpages; if (viomb_vq_dequeue(vq)) return(1); b = &sc->sc_req; nvpages = b->bl_nentries; bus_dmamap_sync(vsc->sc_dmat, b->bl_dmamap, 0, sizeof(u_int32_t) * nvpages, BUS_DMASYNC_POSTWRITE); while (!TAILQ_EMPTY(&b->bl_pglist)) { p = TAILQ_FIRST(&b->bl_pglist); TAILQ_REMOVE(&b->bl_pglist, p, pageq); TAILQ_INSERT_TAIL(&sc->sc_balloon_pages, p, pageq); } VIOMBDEBUG(sc, "updating sc->sc_actual from %u to %llu\n", sc->sc_actual, sc->sc_actual + nvpages); virtio_write_device_config_4(vsc, VIRTIO_BALLOON_CONFIG_ACTUAL, sc->sc_actual + nvpages); viomb_read_config(sc); /* if we have more work to do, add it to the task list */ if (sc->sc_npages > sc->sc_actual) task_add(sc->sc_taskq, &sc->sc_task); return (1); }
void viomb_worker(void *arg1, void *arg2) { struct viomb_softc *sc = (struct viomb_softc *)arg1; int s; s = splbio(); viomb_read_config(sc); if (sc->sc_npages > sc->sc_actual){ VIOMBDEBUG(sc, "inflating balloon from %u to %u.\n", sc->sc_actual, sc->sc_npages); viomb_inflate(sc); } else if (sc->sc_npages < sc->sc_actual){ viomb_deflate(sc); VIOMBDEBUG(sc, "deflating balloon from %u to %u.\n", sc->sc_actual, sc->sc_npages); } splx(s); }
void viomb_read_config(struct viomb_softc *sc) { struct virtio_softc *vsc = (struct virtio_softc *)sc->sc_virtio; u_int32_t reg; /* these values are explicitly specified as little-endian */ reg = virtio_read_device_config_4(vsc, VIRTIO_BALLOON_CONFIG_NUM_PAGES); sc->sc_npages = letoh32(reg); reg = virtio_read_device_config_4(vsc, VIRTIO_BALLOON_CONFIG_ACTUAL); sc->sc_actual = letoh32(reg); VIOMBDEBUG(sc, "sc->sc_npages %u, sc->sc_actual %u\n", sc->sc_npages, sc->sc_actual); }
void viomb_worker(void *arg1) { struct viomb_softc *sc = (struct viomb_softc *)arg1; int s; s = splbio(); viomb_read_config(sc); if (sc->sc_npages > sc->sc_actual) { VIOMBDEBUG(sc, "inflating balloon from %u to %u.\n", sc->sc_actual, sc->sc_npages); viomb_inflate(sc); } else if (sc->sc_npages < sc->sc_actual) { VIOMBDEBUG(sc, "deflating balloon from %u to %u.\n", sc->sc_actual, sc->sc_npages); viomb_deflate(sc); } sc->sc_sens[0].value = sc->sc_npages << PAGE_SHIFT; sc->sc_sens[1].value = sc->sc_actual << PAGE_SHIFT; splx(s); }