void acrn_ioreq_request_clear()

in acrn/ioreq.c [212:261]


void acrn_ioreq_request_clear(struct acrn_vm *vm)
{
	struct acrn_ioreq_client *client;
	bool has_pending = false;
	unsigned long vcpu;
	int retry = 10;

	/*
	 * IO requests of this VM will be completed directly in
	 * acrn_ioreq_dispatch if ACRN_VM_FLAG_CLEARING_IOREQ flag is set.
	 */
	set_bit(ACRN_VM_FLAG_CLEARING_IOREQ, &vm->flags);

	/*
	 * acrn_ioreq_request_clear is only called in VM reset case. Simply
	 * wait 100ms in total for the IO requests' completion.
	 */
	do {
		spin_lock_bh(&vm->ioreq_clients_lock);
		list_for_each_entry(client, &vm->ioreq_clients, list) {
			has_pending = has_pending_request(client);
			if (has_pending)
				break;
		}
		spin_unlock_bh(&vm->ioreq_clients_lock);

		if (has_pending)
			schedule_timeout_interruptible(HZ / 100);
	} while (has_pending && --retry > 0);
	if (retry == 0)
		dev_warn(acrn_dev.this_device,
			 "%s cannot flush pending request!\n", client->name);

	/* Clear all ioreqs belonging to the default client */
	spin_lock_bh(&vm->ioreq_clients_lock);
	client = vm->default_client;
	if (client) {
		vcpu = find_next_bit(client->ioreqs_map,
				     ACRN_IO_REQUEST_MAX, 0);
		while (vcpu < ACRN_IO_REQUEST_MAX) {
			acrn_ioreq_complete_request(client, vcpu, NULL);
			vcpu = find_next_bit(client->ioreqs_map,
					     ACRN_IO_REQUEST_MAX, vcpu + 1);
		}
	}
	spin_unlock_bh(&vm->ioreq_clients_lock);

	/* Clear ACRN_VM_FLAG_CLEARING_IOREQ flag after the clearing */
	clear_bit(ACRN_VM_FLAG_CLEARING_IOREQ, &vm->flags);
}