static int acrn_ioreq_dispatch()

in acrn/ioreq.c [502:547]


static int acrn_ioreq_dispatch(struct acrn_vm *vm)
{
	struct acrn_ioreq_client *client;
	struct acrn_io_request *req;
	int i;

	for (i = 0; i < vm->vcpu_num; i++) {
		req = vm->ioreq_buf->req_slot + i;

		/* barrier the read of processed of acrn_io_request */
		if (smp_load_acquire(&req->processed) ==
				     ACRN_IOREQ_STATE_PENDING) {
			/* Complete the IO request directly in clearing stage */
			if (test_bit(ACRN_VM_FLAG_CLEARING_IOREQ, &vm->flags)) {
				ioreq_complete_request(vm, i, req);
				continue;
			}
			if (handle_cf8cfc(vm, req, i))
				continue;

			spin_lock_bh(&vm->ioreq_clients_lock);
			client = find_ioreq_client(vm, req);
			if (!client) {
				dev_err(acrn_dev.this_device,
					"Failed to find ioreq client!\n");
				spin_unlock_bh(&vm->ioreq_clients_lock);
				return -EINVAL;
			}
			if (!client->is_default)
				req->kernel_handled = 1;
			else
				req->kernel_handled = 0;
			/*
			 * Add barrier() to make sure the writes are done
			 * before setting ACRN_IOREQ_STATE_PROCESSING
			 */
			smp_store_release(&req->processed,
					  ACRN_IOREQ_STATE_PROCESSING);
			set_bit(i, client->ioreqs_map);
			wake_up_interruptible(&client->wq);
			spin_unlock_bh(&vm->ioreq_clients_lock);
		}
	}

	return 0;
}