drivers/vfio/pci/mlx5/main.c

Source file repositories/reference/linux-study-clean/drivers/vfio/pci/mlx5/main.c

File Facts

System
Linux kernel
Corpus path
drivers/vfio/pci/mlx5/main.c
Extension
.c
Size
38704 bytes
Lines
1466
Domain
Driver Families
Bucket
drivers/vfio
Inferred role
Driver Families: operation-table or driver-model contract
Status
pattern implementation candidate

Why This File Exists

Repeatable hardware-adapter layer. Deep compatibility for every driver is out of scope; this atlas records patterns, probe lifecycles, bus glue, IRQ/DMA usage, and links back to core abstractions.

Dependency Surface

Detected Declarations

Annotated Snippet

static const struct file_operations mlx5vf_save_fops = {
	.owner = THIS_MODULE,
	.read = mlx5vf_save_read,
	.poll = mlx5vf_save_poll,
	.unlocked_ioctl = mlx5vf_precopy_ioctl,
	.compat_ioctl = compat_ptr_ioctl,
	.release = mlx5vf_release_file,
};

static int mlx5vf_pci_save_device_inc_data(struct mlx5vf_pci_core_device *mvdev)
{
	struct mlx5_vf_migration_file *migf = mvdev->saving_migf;
	struct mlx5_vhca_data_buffer *buf;
	size_t length;
	int ret;

	if (migf->state == MLX5_MIGF_STATE_ERROR)
		return -ENODEV;

	ret = mlx5vf_cmd_query_vhca_migration_state(mvdev, &length, NULL, NULL,
				MLX5VF_QUERY_INC | MLX5VF_QUERY_FINAL);
	if (ret)
		goto err;

	buf = mlx5vf_mig_file_get_stop_copy_buf(migf, 0, length);
	if (IS_ERR(buf)) {
		ret = PTR_ERR(buf);
		goto err;
	}

	ret = mlx5vf_cmd_save_vhca_state(mvdev, migf, buf, true, false);
	if (ret)
		goto err_save;

	return 0;

err_save:
	mlx5vf_put_data_buffer(buf);
err:
	mlx5vf_mark_err(migf);
	return ret;
}

static struct mlx5_vf_migration_file *
mlx5vf_pci_save_device_data(struct mlx5vf_pci_core_device *mvdev, bool track)
{
	struct mlx5_vf_migration_file *migf;
	struct mlx5_vhca_data_buffer *buf;
	size_t length;
	u64 full_size;
	int ret;

	migf = kzalloc_obj(*migf, GFP_KERNEL_ACCOUNT);
	if (!migf)
		return ERR_PTR(-ENOMEM);

	migf->filp = anon_inode_getfile("mlx5vf_mig", &mlx5vf_save_fops, migf,
					O_RDONLY);
	if (IS_ERR(migf->filp)) {
		ret = PTR_ERR(migf->filp);
		kfree(migf);
		return ERR_PTR(ret);
	}

	migf->mvdev = mvdev;
	stream_open(migf->filp->f_inode, migf->filp);
	mutex_init(&migf->lock);
	init_waitqueue_head(&migf->poll_wait);
	init_completion(&migf->save_comp);
	/*
	 * save_comp is being used as a binary semaphore built from
	 * a completion. A normal mutex cannot be used because the lock is
	 * passed between kernel threads and lockdep can't model this.
	 */
	complete(&migf->save_comp);
	mlx5_cmd_init_async_ctx(mvdev->mdev, &migf->async_ctx);
	INIT_WORK(&migf->async_data.work, mlx5vf_mig_file_cleanup_cb);
	INIT_LIST_HEAD(&migf->buf_list);
	INIT_LIST_HEAD(&migf->avail_list);
	spin_lock_init(&migf->list_lock);

	ret = mlx5vf_cmd_alloc_pd(migf);
	if (ret)
		goto out;

	ret = mlx5vf_cmd_query_vhca_migration_state(mvdev, &length, &full_size, NULL, 0);
	if (ret)
		goto out_pd;

	ret = mlx5vf_prep_stop_copy(mvdev, migf, length, full_size, track);

Annotation

Implementation Notes