static inline void virtblk_scsi_reques_done(struct request *req) { struct virtblk_req *vbr = blk_mq_rq_to_pdu(req); struct virtio_blk *vblk = req->q->queuedata; struct scsi_request *sreq = &vbr->sreq; sreq->resid_len = virtio32_to_cpu(vblk->vdev, vbr->in_hdr.residual); sreq->sense_len = virtio32_to_cpu(vblk->vdev, vbr->in_hdr.sense_len); req->errors = virtio32_to_cpu(vblk->vdev, vbr->in_hdr.errors); }
static inline void virtblk_request_done(struct request *req) { struct virtblk_req *vbr = blk_mq_rq_to_pdu(req); struct virtio_blk *vblk = req->q->queuedata; int error = virtblk_result(vbr); if (req->cmd_type == REQ_TYPE_BLOCK_PC) { req->resid_len = virtio32_to_cpu(vblk->vdev, vbr->in_hdr.residual); req->sense_len = virtio32_to_cpu(vblk->vdev, vbr->in_hdr.sense_len); req->errors = virtio32_to_cpu(vblk->vdev, vbr->in_hdr.errors); } else if (req->cmd_type == REQ_TYPE_DRV_PRIV) { req->errors = (error != 0); } blk_mq_end_request(req, error); }
static void virtballoon_changed(struct virtio_device *vdev) { struct virtio_balloon *vb = vdev->priv; unsigned long flags; s64 diff = towards_target(vb); if (diff) { spin_lock_irqsave(&vb->stop_update_lock, flags); if (!vb->stop_update) queue_work(system_freezable_wq, &vb->update_balloon_size_work); spin_unlock_irqrestore(&vb->stop_update_lock, flags); } if (virtio_has_feature(vdev, VIRTIO_BALLOON_F_FREE_PAGE_HINT)) { virtio_cread(vdev, struct virtio_balloon_config, free_page_report_cmd_id, &vb->cmd_id_received); if (vb->cmd_id_received == VIRTIO_BALLOON_CMD_ID_DONE) { /* Pass ULONG_MAX to give back all the free pages */ return_free_pages_to_mm(vb, ULONG_MAX); } else if (vb->cmd_id_received != VIRTIO_BALLOON_CMD_ID_STOP && vb->cmd_id_received != virtio32_to_cpu(vdev, vb->cmd_id_active)) { spin_lock_irqsave(&vb->stop_update_lock, flags); if (!vb->stop_update) { queue_work(vb->balloon_wq, &vb->report_free_page_work); } spin_unlock_irqrestore(&vb->stop_update_lock, flags); } } }
static int send_free_pages(struct virtio_balloon *vb) { int err; u32 cmd_id_active; while (1) { /* * If a stop id or a new cmd id was just received from host, * stop the reporting. */ cmd_id_active = virtio32_to_cpu(vb->vdev, vb->cmd_id_active); if (cmd_id_active != vb->cmd_id_received) break; /* * The free page blocks are allocated and sent to host one by * one. */ err = get_free_page_and_send(vb); if (err == -EINTR) break; else if (unlikely(err)) return err; } return 0; }
static void release_pages_balloon(struct virtio_balloon *vb) { unsigned int i; struct page *page; /* Find pfns pointing at start of each page, get pages and free them. */ for (i = 0; i < vb->num_pfns; i += VIRTIO_BALLOON_PAGES_PER_PAGE) { page = balloon_pfn_to_page(virtio32_to_cpu(vb->vdev, vb->pfns[i])); if (!virtio_has_feature(vb->vdev, VIRTIO_BALLOON_F_DEFLATE_ON_OOM)) adjust_managed_page_count(page, 1); put_page(page); /* balloon reference */ } }