From patchwork Thu Nov 12 06:39:59 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Parav Pandit X-Patchwork-Id: 1398717 Return-Path: X-Original-To: patchwork-incoming-netdev@ozlabs.org Delivered-To: patchwork-incoming-netdev@ozlabs.org Authentication-Results: ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=vger.kernel.org (client-ip=23.128.96.18; helo=vger.kernel.org; envelope-from=netdev-owner@vger.kernel.org; receiver=) Authentication-Results: ozlabs.org; dmarc=pass (p=none dis=none) header.from=nvidia.com Authentication-Results: ozlabs.org; dkim=pass (2048-bit key; unprotected) header.d=nvidia.com header.i=@nvidia.com header.a=rsa-sha256 header.s=n1 header.b=KxXa+3kC; dkim-atps=neutral Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by ozlabs.org (Postfix) with ESMTP id 4CWsRk1Q7Lz9sRR for ; Thu, 12 Nov 2020 17:40:34 +1100 (AEDT) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1726202AbgKLGkc (ORCPT ); Thu, 12 Nov 2020 01:40:32 -0500 Received: from hqnvemgate26.nvidia.com ([216.228.121.65]:5886 "EHLO hqnvemgate26.nvidia.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1725898AbgKLGkb (ORCPT ); Thu, 12 Nov 2020 01:40:31 -0500 Received: from hqmail.nvidia.com (Not Verified[216.228.121.13]) by hqnvemgate26.nvidia.com (using TLS: TLSv1.2, AES256-SHA) id ; Wed, 11 Nov 2020 22:40:35 -0800 Received: from sw-mtx-036.mtx.labs.mlnx (10.124.1.5) by HQMAIL107.nvidia.com (172.20.187.13) with Microsoft SMTP Server (TLS) id 15.0.1473.3; Thu, 12 Nov 2020 06:40:30 +0000 From: Parav Pandit To: CC: , , , , Subject: [PATCH 1/7] vdpa: Add missing comment for virtqueue count Date: Thu, 12 Nov 2020 08:39:59 +0200 Message-ID: <20201112064005.349268-2-parav@nvidia.com> X-Mailer: git-send-email 2.26.2 In-Reply-To: <20201112064005.349268-1-parav@nvidia.com> References: <20201112064005.349268-1-parav@nvidia.com> MIME-Version: 1.0 X-Originating-IP: [10.124.1.5] X-ClientProxiedBy: HQMAIL101.nvidia.com (172.20.187.10) To HQMAIL107.nvidia.com (172.20.187.13) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=nvidia.com; s=n1; t=1605163235; bh=HisUjgRvMY7IXIfftOHpd8Quijdl8ayptoeXWTLZhqk=; h=From:To:CC:Subject:Date:Message-ID:X-Mailer:In-Reply-To: References:MIME-Version:Content-Transfer-Encoding:Content-Type: X-Originating-IP:X-ClientProxiedBy; b=KxXa+3kCgPdsl+h2Y9LwzJBS64fxr3cEEoLD58Fk5z4CkZOjbXuLvymJmP55+LLRu oNefKcm+45oYNv8wbRBW2KM49LkhydGcG4IzduPqqbdgEmLiSMC8d+vdxrhRry/TW1 uTeXG0wTy1kGXCQ+wtQbVUmZPogLBTBAXEkFhhqu5EKDqYOSRaBo3pcPR1QoXqIoKp RwnnHnDWgqkB97q94er1C98zlFpftcU10K+2COwlT8uZH23NHu6QjvntEu6CRZZtx8 4R24h0yDTeisVc7dvf1VdkRkb2mlzn/Yy7B4MhlKk791GSBSvYe9sBqlRWAF5oSH0o H5cA1JCUrtB4g== Precedence: bulk List-ID: X-Mailing-List: netdev@vger.kernel.org Add missing comment for number of virtqueue. Signed-off-by: Parav Pandit Reviewed-by: Eli Cohen Acked-by: Jason Wang --- include/linux/vdpa.h | 1 + 1 file changed, 1 insertion(+) diff --git a/include/linux/vdpa.h b/include/linux/vdpa.h index 30bc7a7223bb..0fefeb976877 100644 --- a/include/linux/vdpa.h +++ b/include/linux/vdpa.h @@ -42,6 +42,7 @@ struct vdpa_vq_state { * @config: the configuration ops for this device. * @index: device index * @features_valid: were features initialized? for legacy guests + * @nvqs: maximum number of supported virtqueues */ struct vdpa_device { struct device dev; From patchwork Thu Nov 12 06:40:00 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Parav Pandit X-Patchwork-Id: 1398718 Return-Path: X-Original-To: patchwork-incoming-netdev@ozlabs.org Delivered-To: patchwork-incoming-netdev@ozlabs.org Authentication-Results: ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=vger.kernel.org (client-ip=23.128.96.18; helo=vger.kernel.org; envelope-from=netdev-owner@vger.kernel.org; receiver=) Authentication-Results: ozlabs.org; dmarc=pass (p=none dis=none) header.from=nvidia.com Authentication-Results: ozlabs.org; dkim=pass (2048-bit key; unprotected) header.d=nvidia.com header.i=@nvidia.com header.a=rsa-sha256 header.s=n1 header.b=FTdm7feQ; dkim-atps=neutral Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by ozlabs.org (Postfix) with ESMTP id 4CWsRm09Vrz9sRK for ; Thu, 12 Nov 2020 17:40:36 +1100 (AEDT) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1726286AbgKLGke (ORCPT ); Thu, 12 Nov 2020 01:40:34 -0500 Received: from hqnvemgate24.nvidia.com ([216.228.121.143]:13589 "EHLO hqnvemgate24.nvidia.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726107AbgKLGkb (ORCPT ); Thu, 12 Nov 2020 01:40:31 -0500 Received: from hqmail.nvidia.com (Not Verified[216.228.121.13]) by hqnvemgate24.nvidia.com (using TLS: TLSv1.2, AES256-SHA) id ; Wed, 11 Nov 2020 22:40:38 -0800 Received: from sw-mtx-036.mtx.labs.mlnx (10.124.1.5) by HQMAIL107.nvidia.com (172.20.187.13) with Microsoft SMTP Server (TLS) id 15.0.1473.3; Thu, 12 Nov 2020 06:40:30 +0000 From: Parav Pandit To: CC: , , , , Subject: [PATCH 2/7] vdpa: Use simpler version of ida allocation Date: Thu, 12 Nov 2020 08:40:00 +0200 Message-ID: <20201112064005.349268-3-parav@nvidia.com> X-Mailer: git-send-email 2.26.2 In-Reply-To: <20201112064005.349268-1-parav@nvidia.com> References: <20201112064005.349268-1-parav@nvidia.com> MIME-Version: 1.0 X-Originating-IP: [10.124.1.5] X-ClientProxiedBy: HQMAIL101.nvidia.com (172.20.187.10) To HQMAIL107.nvidia.com (172.20.187.13) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=nvidia.com; s=n1; t=1605163239; bh=obxQ+8CkZMWkGpFrT7wuL+J6qEJIL2OCsM+PzwuIu98=; h=From:To:CC:Subject:Date:Message-ID:X-Mailer:In-Reply-To: References:MIME-Version:Content-Transfer-Encoding:Content-Type: X-Originating-IP:X-ClientProxiedBy; b=FTdm7feQL1zGlazsOD1efEw5oJ8haRvqmBTGZcs2EC3wm3StoPvxSn3AkbbEigwC6 KegA4W+NIxFwo2LjwiJ11Zl8u9UBgESdg4GR13HMYeyOSWWXdPGOvqKZtEEsIc0sju M33ikb6LGk9DQryqPmSr0QKGg2cGf9V2la6RbnlCxdG3aS7ojfa5r+delagU1zS3BW 7vIm+rizY/4v3NUvnXDgWgXsHVWuFlCb4WTp1/pc6Zn7Vje6+TK/pn3xi/Zl2Uso4W oi5sBsQU8lclXIJp+0hO3jvqEKeLZQ/Fge4Ugtdt/gvSLfBAhp2H5HthHt69PL0Yco 6Nt4z3fsGAFNA== Precedence: bulk List-ID: X-Mailing-List: netdev@vger.kernel.org vdpa doesn't have any specific need to define start and end range of the device index. Hence use the simper version of the ida allocator. Signed-off-by: Parav Pandit Reviewed-by: Eli Cohen Acked-by: Jason Wang --- drivers/vdpa/vdpa.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/vdpa/vdpa.c b/drivers/vdpa/vdpa.c index a69ffc991e13..c0825650c055 100644 --- a/drivers/vdpa/vdpa.c +++ b/drivers/vdpa/vdpa.c @@ -89,7 +89,7 @@ struct vdpa_device *__vdpa_alloc_device(struct device *parent, if (!vdev) goto err; - err = ida_simple_get(&vdpa_index_ida, 0, 0, GFP_KERNEL); + err = ida_alloc(&vdpa_index_ida, GFP_KERNEL); if (err < 0) goto err_ida; From patchwork Thu Nov 12 06:40:01 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Parav Pandit X-Patchwork-Id: 1398719 Return-Path: X-Original-To: patchwork-incoming-netdev@ozlabs.org Delivered-To: patchwork-incoming-netdev@ozlabs.org Authentication-Results: ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=vger.kernel.org (client-ip=23.128.96.18; helo=vger.kernel.org; envelope-from=netdev-owner@vger.kernel.org; receiver=) Authentication-Results: ozlabs.org; dmarc=pass (p=none dis=none) header.from=nvidia.com Authentication-Results: ozlabs.org; dkim=pass (2048-bit key; unprotected) header.d=nvidia.com header.i=@nvidia.com header.a=rsa-sha256 header.s=n1 header.b=cEorBUDR; dkim-atps=neutral Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by ozlabs.org (Postfix) with ESMTP id 4CWsRp4WhZz9sRK for ; Thu, 12 Nov 2020 17:40:38 +1100 (AEDT) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1726319AbgKLGkh (ORCPT ); Thu, 12 Nov 2020 01:40:37 -0500 Received: from hqnvemgate25.nvidia.com ([216.228.121.64]:15476 "EHLO hqnvemgate25.nvidia.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726203AbgKLGkc (ORCPT ); Thu, 12 Nov 2020 01:40:32 -0500 Received: from hqmail.nvidia.com (Not Verified[216.228.121.13]) by hqnvemgate25.nvidia.com (using TLS: TLSv1.2, AES256-SHA) id ; Wed, 11 Nov 2020 22:40:26 -0800 Received: from sw-mtx-036.mtx.labs.mlnx (10.124.1.5) by HQMAIL107.nvidia.com (172.20.187.13) with Microsoft SMTP Server (TLS) id 15.0.1473.3; Thu, 12 Nov 2020 06:40:31 +0000 From: Parav Pandit To: CC: , , , , Subject: [PATCH 3/7] vdpa: Extend routine to accept vdpa device name Date: Thu, 12 Nov 2020 08:40:01 +0200 Message-ID: <20201112064005.349268-4-parav@nvidia.com> X-Mailer: git-send-email 2.26.2 In-Reply-To: <20201112064005.349268-1-parav@nvidia.com> References: <20201112064005.349268-1-parav@nvidia.com> MIME-Version: 1.0 X-Originating-IP: [10.124.1.5] X-ClientProxiedBy: HQMAIL101.nvidia.com (172.20.187.10) To HQMAIL107.nvidia.com (172.20.187.13) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=nvidia.com; s=n1; t=1605163226; bh=1Lj3uhvlUAqek+U0OdG3uZU0WHYgkHYKA+te4VxyX1E=; h=From:To:CC:Subject:Date:Message-ID:X-Mailer:In-Reply-To: References:MIME-Version:Content-Transfer-Encoding:Content-Type: X-Originating-IP:X-ClientProxiedBy; b=cEorBUDR3PYSlNlGuqprm/ZQA+sNHw6jvxe2MPOXD8048lm87mGGTavVjF84lwzVP E05iOwzIWDbutAuK6qR5rlmBdcmai5D3kBd+k9jeaeeHHiALHG5iiiA3l9cDEuOoWL LG/zYST3ul1ErB6tn9VBZGqysBT5ONPH5ieA9ZQ8Rnwz7ZIyLyZNy5ksdmCoe5kz5h AikyuODijgWo7jVhCEJ8FNKkkjq67vaGSnFmSF85PTjInBkXt88vESuZ2jJhoZWMwG 9SB2OBcUmO6Slzjbf7huP+E6wxEfwYfWlj1r9vD/VGoDIfcb3m9oJyeQyoMc41yJ/5 yCcnI6d0TyBiw== Precedence: bulk List-ID: X-Mailing-List: netdev@vger.kernel.org In a subsequent patch, when user initiated command creates a vdpa device, the user chooses the name of the vdpa device. To support it, extend the device allocation API to consider this name specified by the caller driver. Split the device unregistration to device delete and device put so that device can be removed from the list after its deleted. Signed-off-by: Parav Pandit Reviewed-by: Eli Cohen Acked-by: Jason Wang --- drivers/vdpa/ifcvf/ifcvf_main.c | 2 +- drivers/vdpa/mlx5/net/mlx5_vnet.c | 2 +- drivers/vdpa/vdpa.c | 36 +++++++++++++++++++++++++++---- drivers/vdpa/vdpa_sim/vdpa_sim.c | 2 +- include/linux/vdpa.h | 7 +++--- 5 files changed, 38 insertions(+), 11 deletions(-) diff --git a/drivers/vdpa/ifcvf/ifcvf_main.c b/drivers/vdpa/ifcvf/ifcvf_main.c index 8b4028556cb6..23474af7da40 100644 --- a/drivers/vdpa/ifcvf/ifcvf_main.c +++ b/drivers/vdpa/ifcvf/ifcvf_main.c @@ -439,7 +439,7 @@ static int ifcvf_probe(struct pci_dev *pdev, const struct pci_device_id *id) adapter = vdpa_alloc_device(struct ifcvf_adapter, vdpa, dev, &ifc_vdpa_ops, - IFCVF_MAX_QUEUE_PAIRS * 2); + IFCVF_MAX_QUEUE_PAIRS * 2, NULL); if (adapter == NULL) { IFCVF_ERR(pdev, "Failed to allocate vDPA structure"); return -ENOMEM; diff --git a/drivers/vdpa/mlx5/net/mlx5_vnet.c b/drivers/vdpa/mlx5/net/mlx5_vnet.c index 5316e51e72d4..cf9fc51071c8 100644 --- a/drivers/vdpa/mlx5/net/mlx5_vnet.c +++ b/drivers/vdpa/mlx5/net/mlx5_vnet.c @@ -1958,7 +1958,7 @@ static int mlx5v_probe(struct auxiliary_device *adev, max_vqs = min_t(u32, max_vqs, MLX5_MAX_SUPPORTED_VQS); ndev = vdpa_alloc_device(struct mlx5_vdpa_net, mvdev.vdev, mdev->device, &mlx5_vdpa_ops, - 2 * mlx5_vdpa_max_qps(max_vqs)); + 2 * mlx5_vdpa_max_qps(max_vqs), NULL); if (IS_ERR(ndev)) return PTR_ERR(ndev); diff --git a/drivers/vdpa/vdpa.c b/drivers/vdpa/vdpa.c index c0825650c055..3c9cade05233 100644 --- a/drivers/vdpa/vdpa.c +++ b/drivers/vdpa/vdpa.c @@ -12,6 +12,8 @@ #include #include +/* A global mutex that protects vdpa parent and device level operations. */ +static DEFINE_MUTEX(vdpa_dev_mutex); static DEFINE_IDA(vdpa_index_ida); static int vdpa_dev_probe(struct device *d) @@ -63,6 +65,7 @@ static void vdpa_release_dev(struct device *d) * @config: the bus operations that is supported by this device * @nvqs: number of virtqueues supported by this device * @size: size of the parent structure that contains private data + * @name: name of the vdpa device; optional. * * Driver should use vdpa_alloc_device() wrapper macro instead of * using this directly. @@ -72,8 +75,7 @@ static void vdpa_release_dev(struct device *d) */ struct vdpa_device *__vdpa_alloc_device(struct device *parent, const struct vdpa_config_ops *config, - int nvqs, - size_t size) + int nvqs, size_t size, const char *name) { struct vdpa_device *vdev; int err = -EINVAL; @@ -101,7 +103,10 @@ struct vdpa_device *__vdpa_alloc_device(struct device *parent, vdev->features_valid = false; vdev->nvqs = nvqs; - err = dev_set_name(&vdev->dev, "vdpa%u", vdev->index); + if (name) + err = dev_set_name(&vdev->dev, "%s", name); + else + err = dev_set_name(&vdev->dev, "vdpa%u", vdev->index); if (err) goto err_name; @@ -118,6 +123,13 @@ struct vdpa_device *__vdpa_alloc_device(struct device *parent, } EXPORT_SYMBOL_GPL(__vdpa_alloc_device); +static int vdpa_name_match(struct device *dev, const void *data) +{ + struct vdpa_device *vdev = container_of(dev, struct vdpa_device, dev); + + return (strcmp(dev_name(&vdev->dev), data) == 0); +} + /** * vdpa_register_device - register a vDPA device * Callers must have a succeed call of vdpa_alloc_device() before. @@ -127,7 +139,21 @@ EXPORT_SYMBOL_GPL(__vdpa_alloc_device); */ int vdpa_register_device(struct vdpa_device *vdev) { - return device_add(&vdev->dev); + struct device *dev; + int err; + + mutex_lock(&vdpa_dev_mutex); + dev = bus_find_device(&vdpa_bus, NULL, dev_name(&vdev->dev), vdpa_name_match); + if (dev) { + put_device(dev); + err = -EEXIST; + goto name_err; + } + + err = device_add(&vdev->dev); +name_err: + mutex_unlock(&vdpa_dev_mutex); + return err; } EXPORT_SYMBOL_GPL(vdpa_register_device); @@ -137,7 +163,9 @@ EXPORT_SYMBOL_GPL(vdpa_register_device); */ void vdpa_unregister_device(struct vdpa_device *vdev) { + mutex_lock(&vdpa_dev_mutex); device_unregister(&vdev->dev); + mutex_unlock(&vdpa_dev_mutex); } EXPORT_SYMBOL_GPL(vdpa_unregister_device); diff --git a/drivers/vdpa/vdpa_sim/vdpa_sim.c b/drivers/vdpa/vdpa_sim/vdpa_sim.c index 6a90fdb9cbfc..aed1bb7770ab 100644 --- a/drivers/vdpa/vdpa_sim/vdpa_sim.c +++ b/drivers/vdpa/vdpa_sim/vdpa_sim.c @@ -357,7 +357,7 @@ static struct vdpasim *vdpasim_create(void) else ops = &vdpasim_net_config_ops; - vdpasim = vdpa_alloc_device(struct vdpasim, vdpa, NULL, ops, VDPASIM_VQ_NUM); + vdpasim = vdpa_alloc_device(struct vdpasim, vdpa, NULL, ops, VDPASIM_VQ_NUM, NULL); if (!vdpasim) goto err_alloc; diff --git a/include/linux/vdpa.h b/include/linux/vdpa.h index 0fefeb976877..5700baa22356 100644 --- a/include/linux/vdpa.h +++ b/include/linux/vdpa.h @@ -245,15 +245,14 @@ struct vdpa_config_ops { struct vdpa_device *__vdpa_alloc_device(struct device *parent, const struct vdpa_config_ops *config, - int nvqs, - size_t size); + int nvqs, size_t size, const char *name); -#define vdpa_alloc_device(dev_struct, member, parent, config, nvqs) \ +#define vdpa_alloc_device(dev_struct, member, parent, config, nvqs, name) \ container_of(__vdpa_alloc_device( \ parent, config, nvqs, \ sizeof(dev_struct) + \ BUILD_BUG_ON_ZERO(offsetof( \ - dev_struct, member))), \ + dev_struct, member)), name), \ dev_struct, member) int vdpa_register_device(struct vdpa_device *vdev); From patchwork Thu Nov 12 06:40:02 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Parav Pandit X-Patchwork-Id: 1398720 Return-Path: X-Original-To: patchwork-incoming-netdev@ozlabs.org Delivered-To: patchwork-incoming-netdev@ozlabs.org Authentication-Results: ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=vger.kernel.org (client-ip=23.128.96.18; helo=vger.kernel.org; envelope-from=netdev-owner@vger.kernel.org; receiver=) Authentication-Results: ozlabs.org; dmarc=pass (p=none dis=none) header.from=nvidia.com Authentication-Results: ozlabs.org; dkim=pass (2048-bit key; unprotected) header.d=nvidia.com header.i=@nvidia.com header.a=rsa-sha256 header.s=n1 header.b=qY0qKh9Y; dkim-atps=neutral Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by ozlabs.org (Postfix) with ESMTP id 4CWsRr005sz9sRR for ; Thu, 12 Nov 2020 17:40:39 +1100 (AEDT) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1726419AbgKLGkj (ORCPT ); Thu, 12 Nov 2020 01:40:39 -0500 Received: from hqnvemgate25.nvidia.com ([216.228.121.64]:15480 "EHLO hqnvemgate25.nvidia.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1725898AbgKLGkd (ORCPT ); Thu, 12 Nov 2020 01:40:33 -0500 Received: from hqmail.nvidia.com (Not Verified[216.228.121.13]) by hqnvemgate25.nvidia.com (using TLS: TLSv1.2, AES256-SHA) id ; Wed, 11 Nov 2020 22:40:27 -0800 Received: from sw-mtx-036.mtx.labs.mlnx (10.124.1.5) by HQMAIL107.nvidia.com (172.20.187.13) with Microsoft SMTP Server (TLS) id 15.0.1473.3; Thu, 12 Nov 2020 06:40:32 +0000 From: Parav Pandit To: CC: , , , , Subject: [PATCH 4/7] vdpa: Define vdpa parent device, ops and a netlink interface Date: Thu, 12 Nov 2020 08:40:02 +0200 Message-ID: <20201112064005.349268-5-parav@nvidia.com> X-Mailer: git-send-email 2.26.2 In-Reply-To: <20201112064005.349268-1-parav@nvidia.com> References: <20201112064005.349268-1-parav@nvidia.com> MIME-Version: 1.0 X-Originating-IP: [10.124.1.5] X-ClientProxiedBy: HQMAIL101.nvidia.com (172.20.187.10) To HQMAIL107.nvidia.com (172.20.187.13) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=nvidia.com; s=n1; t=1605163227; bh=yC5mgzfv1lLHopRQpKqnz5FiMVMn9kXtHUZHvKGSVos=; h=From:To:CC:Subject:Date:Message-ID:X-Mailer:In-Reply-To: References:MIME-Version:Content-Transfer-Encoding:Content-Type: X-Originating-IP:X-ClientProxiedBy; b=qY0qKh9Yg0CkuLWfJslhfafSvTpiTcjgDmDV6tQQSlbdLRb1F/rk2GjMPmPuCQe/G 5A80XjJgsztSsYXTTg1ZeDjhm7bwhQ68KrPVjeW5BeQnZfdELkqMyAXBaH58lGsPPc 3MbGzUW5sm+64cS7va7VI9zB8K0DeNR/DD1bHA43lePXFOxJsvCYl9sd60HBMr2mzl 5ccj+VzABhG0OKC0LYjMt9/bZKRyVtTk+q/9RwdfYy5tyOdFZEqo5cmf3ajIEsMntu eR9q8cbCBi239hnbMtHnjG48+YQjkelfS17rHPgS6MkfvU8wldPaGkxuGGVbolQnHz wbRTVj5eP75Zg== Precedence: bulk List-ID: X-Mailing-List: netdev@vger.kernel.org To add one or more VDPA devices, define a parent device which allows adding or removing vdpa device. A parent device defines set of callbacks to manage vdpa devices. To begin with, it defines add and remove callbacks through which a user defined vdpa device can be added or removed. A unique parent device is identified by its unique handle identified by parent device name and optionally the bus name. Hence, introduce routine through which driver can register a parent device and its callback operations for adding and remove a vdpa device. Introduce vdpa netlink socket family so that user can query parent device and its attributes. Example of show vdpa parent device which allows creating vdpa device of networking class (device id = 0x1) of virtio specification 1.1 section 5.1.1. $ vdpa parentdev show vdpasim: supported_classes: net Example of showing vdpa parent device in JSON format. $ vdpa parentdev show -jp { "show": { "vdpasim": { "supported_classes": [ "net" ] } } } Signed-off-by: Parav Pandit Reviewed-by: Eli Cohen Reviewed-by: Jason Wang --- drivers/vdpa/Kconfig | 1 + drivers/vdpa/vdpa.c | 213 +++++++++++++++++++++++++++++++++++++- include/linux/vdpa.h | 32 ++++++ include/uapi/linux/vdpa.h | 32 ++++++ 4 files changed, 277 insertions(+), 1 deletion(-) create mode 100644 include/uapi/linux/vdpa.h diff --git a/drivers/vdpa/Kconfig b/drivers/vdpa/Kconfig index d7d32b656102..8ae491a74ebb 100644 --- a/drivers/vdpa/Kconfig +++ b/drivers/vdpa/Kconfig @@ -1,6 +1,7 @@ # SPDX-License-Identifier: GPL-2.0-only menuconfig VDPA tristate "vDPA drivers" + depends on NET help Enable this module to support vDPA device that uses a datapath which complies with virtio specifications with diff --git a/drivers/vdpa/vdpa.c b/drivers/vdpa/vdpa.c index 3c9cade05233..273639038851 100644 --- a/drivers/vdpa/vdpa.c +++ b/drivers/vdpa/vdpa.c @@ -11,11 +11,17 @@ #include #include #include +#include +#include +#include +static LIST_HEAD(pdev_head); /* A global mutex that protects vdpa parent and device level operations. */ static DEFINE_MUTEX(vdpa_dev_mutex); static DEFINE_IDA(vdpa_index_ida); +static struct genl_family vdpa_nl_family; + static int vdpa_dev_probe(struct device *d) { struct vdpa_device *vdev = dev_to_vdpa(d); @@ -195,13 +201,218 @@ void vdpa_unregister_driver(struct vdpa_driver *drv) } EXPORT_SYMBOL_GPL(vdpa_unregister_driver); +/** + * vdpa_parentdev_register - register a vdpa parent device + * + * @pdev: Pointer to vdpa parent device + * vdpa_parentdev_register() register a vdpa parent device which supports + * vdpa device management. + */ +int vdpa_parentdev_register(struct vdpa_parent_dev *pdev) +{ + if (!pdev->device || !pdev->ops || !pdev->ops->dev_add || !pdev->ops->dev_del) + return -EINVAL; + + INIT_LIST_HEAD(&pdev->list); + mutex_lock(&vdpa_dev_mutex); + list_add_tail(&pdev->list, &pdev_head); + mutex_unlock(&vdpa_dev_mutex); + return 0; +} +EXPORT_SYMBOL_GPL(vdpa_parentdev_register); + +void vdpa_parentdev_unregister(struct vdpa_parent_dev *pdev) +{ + mutex_lock(&vdpa_dev_mutex); + list_del(&pdev->list); + mutex_unlock(&vdpa_dev_mutex); +} +EXPORT_SYMBOL_GPL(vdpa_parentdev_unregister); + +static bool parentdev_handle_match(const struct vdpa_parent_dev *pdev, + const char *busname, const char *devname) +{ + /* Bus name is optional for simulated parent device, so ignore the parent + * when bus is provided. + */ + if ((busname && !pdev->device->bus) || (!busname && pdev->device->bus)) + return false; + + if (!busname && strcmp(dev_name(pdev->device), devname) == 0) + return true; + + if (busname && (strcmp(pdev->device->bus->name, busname) == 0) && + (strcmp(dev_name(pdev->device), devname) == 0)) + return true; + + return false; +} + +static struct vdpa_parent_dev *vdpa_parentdev_get_from_attr(struct nlattr **attrs) +{ + struct vdpa_parent_dev *pdev; + const char *busname = NULL; + const char *devname; + + if (!attrs[VDPA_ATTR_PARENTDEV_DEV_NAME]) + return ERR_PTR(-EINVAL); + devname = nla_data(attrs[VDPA_ATTR_PARENTDEV_DEV_NAME]); + if (attrs[VDPA_ATTR_PARENTDEV_BUS_NAME]) + busname = nla_data(attrs[VDPA_ATTR_PARENTDEV_BUS_NAME]); + + list_for_each_entry(pdev, &pdev_head, list) { + if (parentdev_handle_match(pdev, busname, devname)) + return pdev; + } + return ERR_PTR(-ENODEV); +} + +static int vdpa_nl_parentdev_handle_fill(struct sk_buff *msg, const struct vdpa_parent_dev *pdev) +{ + if (pdev->device->bus && + nla_put_string(msg, VDPA_ATTR_PARENTDEV_BUS_NAME, pdev->device->bus->name)) + return -EMSGSIZE; + if (nla_put_string(msg, VDPA_ATTR_PARENTDEV_DEV_NAME, dev_name(pdev->device))) + return -EMSGSIZE; + return 0; +} + +static int vdpa_parentdev_fill(const struct vdpa_parent_dev *pdev, struct sk_buff *msg, + u32 portid, u32 seq, int flags) +{ + u64 supported_classes = 0; + void *hdr; + int i = 0; + int err; + + hdr = genlmsg_put(msg, portid, seq, &vdpa_nl_family, flags, VDPA_CMD_PARENTDEV_NEW); + if (!hdr) + return -EMSGSIZE; + err = vdpa_nl_parentdev_handle_fill(msg, pdev); + if (err) + goto msg_err; + + while (pdev->id_table[i].device) { + supported_classes |= BIT(pdev->id_table[i].device); + i++; + } + + if (nla_put_u64_64bit(msg, VDPA_ATTR_PARENTDEV_SUPPORTED_CLASSES, + supported_classes, VDPA_ATTR_UNSPEC)) { + err = -EMSGSIZE; + goto msg_err; + } + + genlmsg_end(msg, hdr); + return 0; + +msg_err: + genlmsg_cancel(msg, hdr); + return err; +} + +static int vdpa_nl_cmd_parentdev_get_doit(struct sk_buff *skb, struct genl_info *info) +{ + struct vdpa_parent_dev *pdev; + struct sk_buff *msg; + int err; + + msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL); + if (!msg) + return -ENOMEM; + + mutex_lock(&vdpa_dev_mutex); + pdev = vdpa_parentdev_get_from_attr(info->attrs); + if (IS_ERR(pdev)) { + mutex_unlock(&vdpa_dev_mutex); + NL_SET_ERR_MSG_MOD(info->extack, "Fail to find the specified parent device"); + err = PTR_ERR(pdev); + goto out; + } + + err = vdpa_parentdev_fill(pdev, msg, info->snd_portid, info->snd_seq, 0); + mutex_unlock(&vdpa_dev_mutex); + if (err) + goto out; + err = genlmsg_reply(msg, info); + return err; + +out: + nlmsg_free(msg); + return err; +} + +static int +vdpa_nl_cmd_parentdev_get_dumpit(struct sk_buff *msg, struct netlink_callback *cb) +{ + struct vdpa_parent_dev *pdev; + int start = cb->args[0]; + int idx = 0; + int err; + + mutex_lock(&vdpa_dev_mutex); + list_for_each_entry(pdev, &pdev_head, list) { + if (idx < start) { + idx++; + continue; + } + err = vdpa_parentdev_fill(pdev, msg, NETLINK_CB(cb->skb).portid, + cb->nlh->nlmsg_seq, NLM_F_MULTI); + if (err) + goto out; + idx++; + } +out: + mutex_unlock(&vdpa_dev_mutex); + cb->args[0] = idx; + return msg->len; +} + +static const struct nla_policy vdpa_nl_policy[VDPA_ATTR_MAX] = { + [VDPA_ATTR_PARENTDEV_BUS_NAME] = { .type = NLA_NUL_STRING }, + [VDPA_ATTR_PARENTDEV_DEV_NAME] = { .type = NLA_STRING }, +}; + +static const struct genl_ops vdpa_nl_ops[] = { + { + .cmd = VDPA_CMD_PARENTDEV_GET, + .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP, + .doit = vdpa_nl_cmd_parentdev_get_doit, + .dumpit = vdpa_nl_cmd_parentdev_get_dumpit, + }, +}; + +static struct genl_family vdpa_nl_family __ro_after_init = { + .name = VDPA_GENL_NAME, + .version = VDPA_GENL_VERSION, + .maxattr = VDPA_ATTR_MAX, + .policy = vdpa_nl_policy, + .netnsok = false, + .module = THIS_MODULE, + .ops = vdpa_nl_ops, + .n_ops = ARRAY_SIZE(vdpa_nl_ops), +}; + static int vdpa_init(void) { - return bus_register(&vdpa_bus); + int err; + + err = bus_register(&vdpa_bus); + if (err) + return err; + err = genl_register_family(&vdpa_nl_family); + if (err) + goto err; + return 0; + +err: + bus_unregister(&vdpa_bus); + return err; } static void __exit vdpa_exit(void) { + genl_unregister_family(&vdpa_nl_family); bus_unregister(&vdpa_bus); ida_destroy(&vdpa_index_ida); } diff --git a/include/linux/vdpa.h b/include/linux/vdpa.h index 5700baa22356..3d6bc1fb909d 100644 --- a/include/linux/vdpa.h +++ b/include/linux/vdpa.h @@ -35,6 +35,8 @@ struct vdpa_vq_state { u16 avail_index; }; +struct vdpa_parent_dev; + /** * vDPA device - representation of a vDPA device * @dev: underlying device @@ -335,4 +337,34 @@ static inline void vdpa_get_config(struct vdpa_device *vdev, unsigned offset, ops->get_config(vdev, offset, buf, len); } +/** + * vdpa_dev_ops - vdpa device ops + * @dev_add: Add a vdpa device using alloc and register + * @pdev: parent device to use for device addition + * @name: name of the new vdpa device + * @device_id: device id of the new vdpa device + * Driver need to add a new device using vdpa_register_device() after + * fully initializing the vdpa device. On successful addition driver + * must return a valid pointer of vdpa device or ERR_PTR for the error. + * @dev_del: Remove a vdpa device using unregister + * @pdev: parent device to use for device removal + * @dev: vdpa device to remove + * Driver need to remove the specified device by calling vdpa_unregister_device(). + */ +struct vdpa_dev_ops { + struct vdpa_device* (*dev_add)(struct vdpa_parent_dev *pdev, const char *name, + u32 device_id); + void (*dev_del)(struct vdpa_parent_dev *pdev, struct vdpa_device *dev); +}; + +struct vdpa_parent_dev { + struct device *device; + const struct vdpa_dev_ops *ops; + const struct virtio_device_id *id_table; /* supported ids */ + struct list_head list; +}; + +int vdpa_parentdev_register(struct vdpa_parent_dev *pdev); +void vdpa_parentdev_unregister(struct vdpa_parent_dev *pdev); + #endif /* _LINUX_VDPA_H */ diff --git a/include/uapi/linux/vdpa.h b/include/uapi/linux/vdpa.h new file mode 100644 index 000000000000..6d88022f6a95 --- /dev/null +++ b/include/uapi/linux/vdpa.h @@ -0,0 +1,32 @@ +/* SPDX-License-Identifier: GPL-2.0+ WITH Linux-syscall-note */ +/* + * vdpa device management interface + * Copyright (c) 2020 Mellanox Technologies Ltd. All rights reserved. + */ + +#ifndef _UAPI_LINUX_VDPA_H_ +#define _UAPI_LINUX_VDPA_H_ + +#define VDPA_GENL_NAME "vdpa" +#define VDPA_GENL_VERSION 0x1 +#define VDPA_GENL_MCGRP_CONFIG_NAME "config" + +enum vdpa_command { + VDPA_CMD_UNSPEC, + VDPA_CMD_PARENTDEV_NEW, + VDPA_CMD_PARENTDEV_GET, /* can dump */ +}; + +enum vdpa_attr { + VDPA_ATTR_UNSPEC, + + /* bus name (optional) + dev name together make the parent device handle */ + VDPA_ATTR_PARENTDEV_BUS_NAME, /* string */ + VDPA_ATTR_PARENTDEV_DEV_NAME, /* string */ + VDPA_ATTR_PARENTDEV_SUPPORTED_CLASSES, /* u64 */ + + /* new attributes must be added above here */ + VDPA_ATTR_MAX, +}; + +#endif From patchwork Thu Nov 12 06:40:03 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Parav Pandit X-Patchwork-Id: 1398723 Return-Path: X-Original-To: patchwork-incoming-netdev@ozlabs.org Delivered-To: patchwork-incoming-netdev@ozlabs.org Authentication-Results: ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=vger.kernel.org (client-ip=23.128.96.18; helo=vger.kernel.org; envelope-from=netdev-owner@vger.kernel.org; receiver=) Authentication-Results: ozlabs.org; dmarc=pass (p=none dis=none) header.from=nvidia.com Authentication-Results: ozlabs.org; dkim=pass (2048-bit key; unprotected) header.d=nvidia.com header.i=@nvidia.com header.a=rsa-sha256 header.s=n1 header.b=fGLNVK4+; dkim-atps=neutral Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by ozlabs.org (Postfix) with ESMTP id 4CWsS00TCQz9sRK for ; Thu, 12 Nov 2020 17:40:48 +1100 (AEDT) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1726579AbgKLGkr (ORCPT ); Thu, 12 Nov 2020 01:40:47 -0500 Received: from hqnvemgate26.nvidia.com ([216.228.121.65]:5890 "EHLO hqnvemgate26.nvidia.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726233AbgKLGke (ORCPT ); Thu, 12 Nov 2020 01:40:34 -0500 Received: from hqmail.nvidia.com (Not Verified[216.228.121.13]) by hqnvemgate26.nvidia.com (using TLS: TLSv1.2, AES256-SHA) id ; Wed, 11 Nov 2020 22:40:37 -0800 Received: from sw-mtx-036.mtx.labs.mlnx (10.124.1.5) by HQMAIL107.nvidia.com (172.20.187.13) with Microsoft SMTP Server (TLS) id 15.0.1473.3; Thu, 12 Nov 2020 06:40:32 +0000 From: Parav Pandit To: CC: , , , , Subject: [PATCH 5/7] vdpa: Enable a user to add and delete a vdpa device Date: Thu, 12 Nov 2020 08:40:03 +0200 Message-ID: <20201112064005.349268-6-parav@nvidia.com> X-Mailer: git-send-email 2.26.2 In-Reply-To: <20201112064005.349268-1-parav@nvidia.com> References: <20201112064005.349268-1-parav@nvidia.com> MIME-Version: 1.0 X-Originating-IP: [10.124.1.5] X-ClientProxiedBy: HQMAIL101.nvidia.com (172.20.187.10) To HQMAIL107.nvidia.com (172.20.187.13) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=nvidia.com; s=n1; t=1605163237; bh=FbnxGUSw/au84kScV+/AAWX3SShki3kIEmf9eO9tD+g=; h=From:To:CC:Subject:Date:Message-ID:X-Mailer:In-Reply-To: References:MIME-Version:Content-Transfer-Encoding:Content-Type: X-Originating-IP:X-ClientProxiedBy; b=fGLNVK4+8D2P5VDceDq6TTWibmMjFl77ItsSzV4KIXJL8i1zY3V/UhKc9hGVBE/Jg SN0asuUIssD+8lok7OEnyZ7TI+PkK8LEMFqNd6HyMyc1PGdhwAKy5ZhYECXslY+on3 DbYopCJFeTray830LsPibm7wsK1k4COs8ciwMS2AckhtHXDdrVbF9UPiywLo6aL48g CbhrseroAx4dffP9t1qrlpYzQPZoL+KOlbP2LeQaAigLGCtcVEXF/iPfqhVc36iOxw n22W4xpXUndDEZJm0tqbTeFLsgFoYVAgUjxfCQ+jyZ4XGCLJYcrNFQOCU1t00f5ad/ OqBI735xyjntg== Precedence: bulk List-ID: X-Mailing-List: netdev@vger.kernel.org Add the ability to add and delete a vdpa device. Examples: Create a vdpa device of type network named "foo2" from the parent device vdpasim: $ vdpa dev add parentdev vdpasim type net name foo2 Delete the vdpa device after its use: $ vdpa dev del foo2 Signed-off-by: Parav Pandit Reviewed-by: Eli Cohen Reviewed-by: Jason Wang --- drivers/vdpa/vdpa.c | 149 +++++++++++++++++++++++++++++++++++--- include/linux/vdpa.h | 6 ++ include/uapi/linux/vdpa.h | 5 ++ 3 files changed, 150 insertions(+), 10 deletions(-) diff --git a/drivers/vdpa/vdpa.c b/drivers/vdpa/vdpa.c index 273639038851..fcbdc8f10206 100644 --- a/drivers/vdpa/vdpa.c +++ b/drivers/vdpa/vdpa.c @@ -136,6 +136,37 @@ static int vdpa_name_match(struct device *dev, const void *data) return (strcmp(dev_name(&vdev->dev), data) == 0); } +static int __vdpa_register_device(struct vdpa_device *vdev) +{ + struct device *dev; + + lockdep_assert_held(&vdpa_dev_mutex); + dev = bus_find_device(&vdpa_bus, NULL, dev_name(&vdev->dev), vdpa_name_match); + if (dev) { + put_device(dev); + return -EEXIST; + } + return device_add(&vdev->dev); +} + +/** + * _vdpa_register_device - register a vDPA device with vdpa lock held + * Caller must have a succeed call of vdpa_alloc_device() before. + * Caller must invoke this routine as part of parent device dev_add() callback + * after setting up valid parentdev for this vdpa device. + * @vdev: the vdpa device to be registered to vDPA bus + * + * Returns an error when fail to add device to vDPA bus + */ +int _vdpa_register_device(struct vdpa_device *vdev) +{ + if (!vdev->pdev) + return -EINVAL; + + return __vdpa_register_device(vdev); +} +EXPORT_SYMBOL_GPL(_vdpa_register_device); + /** * vdpa_register_device - register a vDPA device * Callers must have a succeed call of vdpa_alloc_device() before. @@ -145,24 +176,28 @@ static int vdpa_name_match(struct device *dev, const void *data) */ int vdpa_register_device(struct vdpa_device *vdev) { - struct device *dev; int err; mutex_lock(&vdpa_dev_mutex); - dev = bus_find_device(&vdpa_bus, NULL, dev_name(&vdev->dev), vdpa_name_match); - if (dev) { - put_device(dev); - err = -EEXIST; - goto name_err; - } - - err = device_add(&vdev->dev); -name_err: + err = __vdpa_register_device(vdev); mutex_unlock(&vdpa_dev_mutex); return err; } EXPORT_SYMBOL_GPL(vdpa_register_device); +/** + * _vdpa_unregister_device - unregister a vDPA device + * Caller must invoke this routine as part of parent device dev_del() callback. + * @vdev: the vdpa device to be unregisted from vDPA bus + */ +void _vdpa_unregister_device(struct vdpa_device *vdev) +{ + lockdep_assert_held(&vdpa_dev_mutex); + WARN_ON(!vdev->pdev); + device_unregister(&vdev->dev); +} +EXPORT_SYMBOL_GPL(_vdpa_unregister_device); + /** * vdpa_unregister_device - unregister a vDPA device * @vdev: the vdpa device to be unregisted from vDPA bus @@ -221,10 +256,25 @@ int vdpa_parentdev_register(struct vdpa_parent_dev *pdev) } EXPORT_SYMBOL_GPL(vdpa_parentdev_register); +static int vdpa_match_remove(struct device *dev, void *data) +{ + struct vdpa_device *vdev = container_of(dev, struct vdpa_device, dev); + struct vdpa_parent_dev *pdev = vdev->pdev; + + if (pdev == data) + pdev->ops->dev_del(pdev, vdev); + return 0; +} + void vdpa_parentdev_unregister(struct vdpa_parent_dev *pdev) { mutex_lock(&vdpa_dev_mutex); + list_del(&pdev->list); + + /* Filter out all the entries belong to this parent device and delete it. */ + bus_for_each_dev(&vdpa_bus, NULL, pdev, vdpa_match_remove); + mutex_unlock(&vdpa_dev_mutex); } EXPORT_SYMBOL_GPL(vdpa_parentdev_unregister); @@ -368,9 +418,76 @@ vdpa_nl_cmd_parentdev_get_dumpit(struct sk_buff *msg, struct netlink_callback *c return msg->len; } +static int vdpa_nl_cmd_dev_add_set_doit(struct sk_buff *skb, struct genl_info *info) +{ + struct vdpa_parent_dev *pdev; + struct vdpa_device *vdev; + const char *name; + u32 device_id; + int err = 0; + + if (!info->attrs[VDPA_ATTR_DEV_NAME] || !info->attrs[VDPA_ATTR_DEV_ID]) + return -EINVAL; + + name = nla_data(info->attrs[VDPA_ATTR_DEV_NAME]); + device_id = nla_get_u32(info->attrs[VDPA_ATTR_DEV_ID]); + + mutex_lock(&vdpa_dev_mutex); + pdev = vdpa_parentdev_get_from_attr(info->attrs); + if (IS_ERR(pdev)) { + NL_SET_ERR_MSG_MOD(info->extack, "Fail to find the specified parent device"); + err = PTR_ERR(pdev); + goto err; + } + + vdev = pdev->ops->dev_add(pdev, name, device_id); + if (IS_ERR(vdev)) + goto err; + +err: + mutex_unlock(&vdpa_dev_mutex); + return err; +} + +static int vdpa_nl_cmd_dev_del_set_doit(struct sk_buff *skb, struct genl_info *info) +{ + struct vdpa_parent_dev *pdev; + struct vdpa_device *vdev; + struct device *dev; + const char *name; + int err = 0; + + if (!info->attrs[VDPA_ATTR_DEV_NAME]) + return -EINVAL; + name = nla_data(info->attrs[VDPA_ATTR_DEV_NAME]); + + mutex_lock(&vdpa_dev_mutex); + dev = bus_find_device(&vdpa_bus, NULL, name, vdpa_name_match); + if (!dev) { + NL_SET_ERR_MSG_MOD(info->extack, "device not found"); + err = -ENODEV; + goto dev_err; + } + vdev = container_of(dev, struct vdpa_device, dev); + if (!vdev->pdev) { + NL_SET_ERR_MSG_MOD(info->extack, "Only user created device can be deleted by user"); + err = -EINVAL; + goto pdev_err; + } + pdev = vdev->pdev; + pdev->ops->dev_del(pdev, vdev); +pdev_err: + put_device(dev); +dev_err: + mutex_unlock(&vdpa_dev_mutex); + return err; +} + static const struct nla_policy vdpa_nl_policy[VDPA_ATTR_MAX] = { [VDPA_ATTR_PARENTDEV_BUS_NAME] = { .type = NLA_NUL_STRING }, [VDPA_ATTR_PARENTDEV_DEV_NAME] = { .type = NLA_STRING }, + [VDPA_ATTR_DEV_NAME] = { .type = NLA_STRING }, + [VDPA_ATTR_DEV_ID] = { .type = NLA_U32 }, }; static const struct genl_ops vdpa_nl_ops[] = { @@ -380,6 +497,18 @@ static const struct genl_ops vdpa_nl_ops[] = { .doit = vdpa_nl_cmd_parentdev_get_doit, .dumpit = vdpa_nl_cmd_parentdev_get_dumpit, }, + { + .cmd = VDPA_CMD_DEV_NEW, + .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP, + .doit = vdpa_nl_cmd_dev_add_set_doit, + .flags = GENL_ADMIN_PERM, + }, + { + .cmd = VDPA_CMD_DEV_DEL, + .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP, + .doit = vdpa_nl_cmd_dev_del_set_doit, + .flags = GENL_ADMIN_PERM, + }, }; static struct genl_family vdpa_nl_family __ro_after_init = { diff --git a/include/linux/vdpa.h b/include/linux/vdpa.h index 3d6bc1fb909d..cb5a3d847af3 100644 --- a/include/linux/vdpa.h +++ b/include/linux/vdpa.h @@ -45,6 +45,8 @@ struct vdpa_parent_dev; * @index: device index * @features_valid: were features initialized? for legacy guests * @nvqs: maximum number of supported virtqueues + * @pdev: parent device pointer; caller must setup when registering device as part + * of dev_add() parentdev ops callback before invoking _vdpa_register_device(). */ struct vdpa_device { struct device dev; @@ -53,6 +55,7 @@ struct vdpa_device { unsigned int index; bool features_valid; int nvqs; + struct vdpa_parent_dev *pdev; }; /** @@ -260,6 +263,9 @@ struct vdpa_device *__vdpa_alloc_device(struct device *parent, int vdpa_register_device(struct vdpa_device *vdev); void vdpa_unregister_device(struct vdpa_device *vdev); +int _vdpa_register_device(struct vdpa_device *vdev); +void _vdpa_unregister_device(struct vdpa_device *vdev); + /** * vdpa_driver - operations for a vDPA driver * @driver: underlying device driver diff --git a/include/uapi/linux/vdpa.h b/include/uapi/linux/vdpa.h index 6d88022f6a95..c528a9cfd6c9 100644 --- a/include/uapi/linux/vdpa.h +++ b/include/uapi/linux/vdpa.h @@ -15,6 +15,8 @@ enum vdpa_command { VDPA_CMD_UNSPEC, VDPA_CMD_PARENTDEV_NEW, VDPA_CMD_PARENTDEV_GET, /* can dump */ + VDPA_CMD_DEV_NEW, + VDPA_CMD_DEV_DEL, }; enum vdpa_attr { @@ -25,6 +27,9 @@ enum vdpa_attr { VDPA_ATTR_PARENTDEV_DEV_NAME, /* string */ VDPA_ATTR_PARENTDEV_SUPPORTED_CLASSES, /* u64 */ + VDPA_ATTR_DEV_NAME, /* string */ + VDPA_ATTR_DEV_ID, /* u32 */ + /* new attributes must be added above here */ VDPA_ATTR_MAX, }; From patchwork Thu Nov 12 06:40:04 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Parav Pandit X-Patchwork-Id: 1398721 Return-Path: X-Original-To: patchwork-incoming-netdev@ozlabs.org Delivered-To: patchwork-incoming-netdev@ozlabs.org Authentication-Results: ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=vger.kernel.org (client-ip=23.128.96.18; helo=vger.kernel.org; envelope-from=netdev-owner@vger.kernel.org; receiver=) Authentication-Results: ozlabs.org; dmarc=pass (p=none dis=none) header.from=nvidia.com Authentication-Results: ozlabs.org; dkim=pass (2048-bit key; unprotected) header.d=nvidia.com header.i=@nvidia.com header.a=rsa-sha256 header.s=n1 header.b=BBAJXmNz; dkim-atps=neutral Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by ozlabs.org (Postfix) with ESMTP id 4CWsRs4sLKz9sRK for ; Thu, 12 Nov 2020 17:40:41 +1100 (AEDT) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1726459AbgKLGkk (ORCPT ); Thu, 12 Nov 2020 01:40:40 -0500 Received: from hqnvemgate26.nvidia.com ([216.228.121.65]:5893 "EHLO hqnvemgate26.nvidia.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726251AbgKLGke (ORCPT ); Thu, 12 Nov 2020 01:40:34 -0500 Received: from hqmail.nvidia.com (Not Verified[216.228.121.13]) by hqnvemgate26.nvidia.com (using TLS: TLSv1.2, AES256-SHA) id ; Wed, 11 Nov 2020 22:40:38 -0800 Received: from sw-mtx-036.mtx.labs.mlnx (10.124.1.5) by HQMAIL107.nvidia.com (172.20.187.13) with Microsoft SMTP Server (TLS) id 15.0.1473.3; Thu, 12 Nov 2020 06:40:33 +0000 From: Parav Pandit To: CC: , , , , Subject: [PATCH 6/7] vdpa: Enable user to query vdpa device info Date: Thu, 12 Nov 2020 08:40:04 +0200 Message-ID: <20201112064005.349268-7-parav@nvidia.com> X-Mailer: git-send-email 2.26.2 In-Reply-To: <20201112064005.349268-1-parav@nvidia.com> References: <20201112064005.349268-1-parav@nvidia.com> MIME-Version: 1.0 X-Originating-IP: [10.124.1.5] X-ClientProxiedBy: HQMAIL101.nvidia.com (172.20.187.10) To HQMAIL107.nvidia.com (172.20.187.13) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=nvidia.com; s=n1; t=1605163238; bh=Hdk1FRDwYZoc183SbD09+7k3Ug3LOo5biJ6yLjJm35g=; h=From:To:CC:Subject:Date:Message-ID:X-Mailer:In-Reply-To: References:MIME-Version:Content-Transfer-Encoding:Content-Type: X-Originating-IP:X-ClientProxiedBy; b=BBAJXmNzzEC7kMxEt5J7+04SX4s5FmQY7Nad/02N/4Ab4ZYJZdragKz8SOETz8cAV +B/ISU+OkJvwlY4vDmjaCxcY/B7TI6DzyO2h2oppkuroaPMvgaP75nkmP9M43XxiOJ 5x1cogISbU/VnpKvJfcgKWuJprL/4DN2rO6aeC1j1VwLnDBnvNDXHomJiQbkot8ART fVMecefdVRNiZ/USy7UNlprtXi8AP7RfV3iLZY8iegt4ACy+tFu7fr9rqlLwBRm9Gg 5z0LMWErGkezwLMlUXRtTNItt7CD/vzYQiu57KNOxvAIKKvQTrwlK/kGbzha2b4bJu g/ByMsXQXMX4g== Precedence: bulk List-ID: X-Mailing-List: netdev@vger.kernel.org Enable user to query vdpa device information. $ vdpa dev add parentdev vdpasim type net name foo2 Show the newly created vdpa device by its name: $ vdpa dev show foo2 foo2: type network parentdev vdpasim vendor_id 0 max_vqs 2 max_vq_size 256 $ vdpa dev show foo2 -jp { "dev": { "foo2": { "type": "network", "parentdev": "vdpasim", "vendor_id": 0, "max_vqs": 2, "max_vq_size": 256 } } } Signed-off-by: Parav Pandit Reviewed-by: Eli Cohen Reviewed-by: Jason Wang --- drivers/vdpa/vdpa.c | 131 ++++++++++++++++++++++++++++++++++++++ include/uapi/linux/vdpa.h | 4 ++ 2 files changed, 135 insertions(+) diff --git a/drivers/vdpa/vdpa.c b/drivers/vdpa/vdpa.c index fcbdc8f10206..32bd48baffab 100644 --- a/drivers/vdpa/vdpa.c +++ b/drivers/vdpa/vdpa.c @@ -483,6 +483,131 @@ static int vdpa_nl_cmd_dev_del_set_doit(struct sk_buff *skb, struct genl_info *i return err; } +static int +vdpa_dev_fill(struct vdpa_device *vdev, struct sk_buff *msg, u32 portid, u32 seq, + int flags, struct netlink_ext_ack *extack) +{ + u16 max_vq_size; + u32 device_id; + u32 vendor_id; + void *hdr; + int err; + + hdr = genlmsg_put(msg, portid, seq, &vdpa_nl_family, flags, VDPA_CMD_DEV_NEW); + if (!hdr) + return -EMSGSIZE; + + err = vdpa_nl_parentdev_handle_fill(msg, vdev->pdev); + if (err) + goto msg_err; + + device_id = vdev->config->get_device_id(vdev); + vendor_id = vdev->config->get_vendor_id(vdev); + max_vq_size = vdev->config->get_vq_num_max(vdev); + + err = -EMSGSIZE; + if (nla_put_string(msg, VDPA_ATTR_DEV_NAME, dev_name(&vdev->dev))) + goto msg_err; + if (nla_put_u32(msg, VDPA_ATTR_DEV_ID, device_id)) + goto msg_err; + if (nla_put_u32(msg, VDPA_ATTR_DEV_VENDOR_ID, vendor_id)) + goto msg_err; + if (nla_put_u32(msg, VDPA_ATTR_DEV_MAX_VQS, vdev->nvqs)) + goto msg_err; + if (nla_put_u16(msg, VDPA_ATTR_DEV_MAX_VQ_SIZE, max_vq_size)) + goto msg_err; + + genlmsg_end(msg, hdr); + return 0; + +msg_err: + genlmsg_cancel(msg, hdr); + return err; +} + +static int vdpa_nl_cmd_dev_get_doit(struct sk_buff *skb, struct genl_info *info) +{ + struct vdpa_device *vdev; + struct sk_buff *msg; + const char *devname; + struct device *dev; + int err; + + if (!info->attrs[VDPA_ATTR_DEV_NAME]) + return -EINVAL; + devname = nla_data(info->attrs[VDPA_ATTR_DEV_NAME]); + msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL); + if (!msg) + return -ENOMEM; + + mutex_lock(&vdpa_dev_mutex); + dev = bus_find_device(&vdpa_bus, NULL, devname, vdpa_name_match); + if (!dev) { + mutex_unlock(&vdpa_dev_mutex); + NL_SET_ERR_MSG_MOD(info->extack, "device not found"); + return -ENODEV; + } + vdev = container_of(dev, struct vdpa_device, dev); + if (!vdev->pdev) { + mutex_unlock(&vdpa_dev_mutex); + put_device(dev); + return -EINVAL; + } + err = vdpa_dev_fill(vdev, msg, info->snd_portid, info->snd_seq, 0, info->extack); + if (!err) + err = genlmsg_reply(msg, info); + put_device(dev); + mutex_unlock(&vdpa_dev_mutex); + + if (err) + nlmsg_free(msg); + return err; +} + +struct vdpa_dev_dump_info { + struct sk_buff *msg; + struct netlink_callback *cb; + int start_idx; + int idx; +}; + +static int vdpa_dev_dump(struct device *dev, void *data) +{ + struct vdpa_device *vdev = container_of(dev, struct vdpa_device, dev); + struct vdpa_dev_dump_info *info = data; + int err; + + if (!vdev->pdev) + return 0; + if (info->idx < info->start_idx) { + info->idx++; + return 0; + } + err = vdpa_dev_fill(vdev, info->msg, NETLINK_CB(info->cb->skb).portid, + info->cb->nlh->nlmsg_seq, NLM_F_MULTI, info->cb->extack); + if (err) + return err; + + info->idx++; + return 0; +} + +static int vdpa_nl_cmd_dev_get_dumpit(struct sk_buff *msg, struct netlink_callback *cb) +{ + struct vdpa_dev_dump_info info; + + info.msg = msg; + info.cb = cb; + info.start_idx = cb->args[0]; + info.idx = 0; + + mutex_lock(&vdpa_dev_mutex); + bus_for_each_dev(&vdpa_bus, NULL, &info, vdpa_dev_dump); + mutex_unlock(&vdpa_dev_mutex); + cb->args[0] = info.idx; + return msg->len; +} + static const struct nla_policy vdpa_nl_policy[VDPA_ATTR_MAX] = { [VDPA_ATTR_PARENTDEV_BUS_NAME] = { .type = NLA_NUL_STRING }, [VDPA_ATTR_PARENTDEV_DEV_NAME] = { .type = NLA_STRING }, @@ -509,6 +634,12 @@ static const struct genl_ops vdpa_nl_ops[] = { .doit = vdpa_nl_cmd_dev_del_set_doit, .flags = GENL_ADMIN_PERM, }, + { + .cmd = VDPA_CMD_DEV_GET, + .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP, + .doit = vdpa_nl_cmd_dev_get_doit, + .dumpit = vdpa_nl_cmd_dev_get_dumpit, + }, }; static struct genl_family vdpa_nl_family __ro_after_init = { diff --git a/include/uapi/linux/vdpa.h b/include/uapi/linux/vdpa.h index c528a9cfd6c9..bba8b83a94b5 100644 --- a/include/uapi/linux/vdpa.h +++ b/include/uapi/linux/vdpa.h @@ -17,6 +17,7 @@ enum vdpa_command { VDPA_CMD_PARENTDEV_GET, /* can dump */ VDPA_CMD_DEV_NEW, VDPA_CMD_DEV_DEL, + VDPA_CMD_DEV_GET, /* can dump */ }; enum vdpa_attr { @@ -29,6 +30,9 @@ enum vdpa_attr { VDPA_ATTR_DEV_NAME, /* string */ VDPA_ATTR_DEV_ID, /* u32 */ + VDPA_ATTR_DEV_VENDOR_ID, /* u32 */ + VDPA_ATTR_DEV_MAX_VQS, /* u32 */ + VDPA_ATTR_DEV_MAX_VQ_SIZE, /* u16 */ /* new attributes must be added above here */ VDPA_ATTR_MAX, From patchwork Thu Nov 12 06:40:05 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Parav Pandit X-Patchwork-Id: 1398722 Return-Path: X-Original-To: patchwork-incoming-netdev@ozlabs.org Delivered-To: patchwork-incoming-netdev@ozlabs.org Authentication-Results: ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=vger.kernel.org (client-ip=23.128.96.18; helo=vger.kernel.org; envelope-from=netdev-owner@vger.kernel.org; receiver=) Authentication-Results: ozlabs.org; dmarc=pass (p=none dis=none) header.from=nvidia.com Authentication-Results: ozlabs.org; dkim=pass (2048-bit key; unprotected) header.d=nvidia.com header.i=@nvidia.com header.a=rsa-sha256 header.s=n1 header.b=X3AME2CE; dkim-atps=neutral Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by ozlabs.org (Postfix) with ESMTP id 4CWsRy2h8Xz9sRK for ; Thu, 12 Nov 2020 17:40:46 +1100 (AEDT) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1726478AbgKLGkm (ORCPT ); Thu, 12 Nov 2020 01:40:42 -0500 Received: from hqnvemgate25.nvidia.com ([216.228.121.64]:15487 "EHLO hqnvemgate25.nvidia.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726287AbgKLGke (ORCPT ); Thu, 12 Nov 2020 01:40:34 -0500 Received: from hqmail.nvidia.com (Not Verified[216.228.121.13]) by hqnvemgate25.nvidia.com (using TLS: TLSv1.2, AES256-SHA) id ; Wed, 11 Nov 2020 22:40:29 -0800 Received: from sw-mtx-036.mtx.labs.mlnx (10.124.1.5) by HQMAIL107.nvidia.com (172.20.187.13) with Microsoft SMTP Server (TLS) id 15.0.1473.3; Thu, 12 Nov 2020 06:40:34 +0000 From: Parav Pandit To: CC: , , , , Subject: [PATCH 7/7] vdpa/vdpa_sim: Enable user to create vdpasim net devices Date: Thu, 12 Nov 2020 08:40:05 +0200 Message-ID: <20201112064005.349268-8-parav@nvidia.com> X-Mailer: git-send-email 2.26.2 In-Reply-To: <20201112064005.349268-1-parav@nvidia.com> References: <20201112064005.349268-1-parav@nvidia.com> MIME-Version: 1.0 X-Originating-IP: [10.124.1.5] X-ClientProxiedBy: HQMAIL101.nvidia.com (172.20.187.10) To HQMAIL107.nvidia.com (172.20.187.13) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=nvidia.com; s=n1; t=1605163229; bh=KJ3AOJWMJTMztY+TXdCv61rtyZGand4171XiGUabLAI=; h=From:To:CC:Subject:Date:Message-ID:X-Mailer:In-Reply-To: References:MIME-Version:Content-Transfer-Encoding:Content-Type: X-Originating-IP:X-ClientProxiedBy; b=X3AME2CEGukSsNJizi2DRuLJDHos1YyLKY9cOrHZFFXkoj/mtFQgJ27+8gYsA3DTm 1W/3RVB7+LaLpNszZOu1MfeP/fVjfpD1NJMqGEeOK/dT2+1xo7SSumUw3X48rdfZQX C4XxqO3HVRY/Jhf4sJZeQq0Krqu9HuKq4ddWqlVe91oKkNRwhm/gt1odNlM4uiqiVr /u3dIPJpE7f1xq6FGAFIaGE5HukcuhnPr8s/W+VjQnkv3klAJZPUEe2O1kq4IIErCX eryY7iuEpfSCkQm/DJRpqbNsMhIJmgEAcg8uWhpzi6MRm+FcVmx9wTisQChP7BeH7S hO3dwU1arQYFQ== Precedence: bulk List-ID: X-Mailing-List: netdev@vger.kernel.org Enable user to create vdpasim net simulate devices. Show vdpa parent device that supports creating, deleting vdpa devices. $ vdpa parentdev show vdpasim: supported_classes net $ vdpa parentdev show -jp { "show": { "vdpasim": { "supported_classes": { "net" } } } Create a vdpa device of type networking named as "foo2" from the parent device vdpasim: $ vdpa dev add parentdev vdpasim type net name foo2 Show the newly created vdpa device by its name: $ vdpa dev show foo2 foo2: type network parentdev vdpasim vendor_id 0 max_vqs 2 max_vq_size 256 $ vdpa dev show foo2 -jp { "dev": { "foo2": { "type": "network", "parentdev": "vdpasim", "vendor_id": 0, "max_vqs": 2, "max_vq_size": 256 } } } Delete the vdpa device after its use: $ vdpa dev del foo2 Signed-off-by: Parav Pandit Reviewed-by: Eli Cohen Acked-by: Jason Wang --- drivers/vdpa/vdpa_sim/vdpa_sim.c | 81 +++++++++++++++++++++++++++----- 1 file changed, 69 insertions(+), 12 deletions(-) diff --git a/drivers/vdpa/vdpa_sim/vdpa_sim.c b/drivers/vdpa/vdpa_sim/vdpa_sim.c index aed1bb7770ab..85776e4e6749 100644 --- a/drivers/vdpa/vdpa_sim/vdpa_sim.c +++ b/drivers/vdpa/vdpa_sim/vdpa_sim.c @@ -28,6 +28,7 @@ #include #include #include +#include #define DRV_VERSION "0.1" #define DRV_AUTHOR "Jason Wang " @@ -42,6 +43,17 @@ static char *macaddr; module_param(macaddr, charp, 0); MODULE_PARM_DESC(macaddr, "Ethernet MAC address"); +static struct vdpa_parent_dev parent_dev; + +static void vdpasim_parent_release(struct device *dev) +{ +} + +static struct device vdpasim_parent = { + .init_name = "vdpasim", + .release = vdpasim_parent_release, +}; + struct vdpasim_virtqueue { struct vringh vring; struct vringh_kiov iov; @@ -101,8 +113,6 @@ static inline __virtio16 cpu_to_vdpasim16(struct vdpasim *vdpasim, u16 val) return __cpu_to_virtio16(vdpasim_is_little_endian(vdpasim), val); } -static struct vdpasim *vdpasim_dev; - static struct vdpasim *vdpa_to_sim(struct vdpa_device *vdpa) { return container_of(vdpa, struct vdpasim, vdpa); @@ -345,7 +355,7 @@ static const struct dma_map_ops vdpasim_dma_ops = { static const struct vdpa_config_ops vdpasim_net_config_ops; static const struct vdpa_config_ops vdpasim_net_batch_config_ops; -static struct vdpasim *vdpasim_create(void) +static struct vdpasim *vdpasim_create(const char *name) { const struct vdpa_config_ops *ops; struct vdpasim *vdpasim; @@ -357,7 +367,7 @@ static struct vdpasim *vdpasim_create(void) else ops = &vdpasim_net_config_ops; - vdpasim = vdpa_alloc_device(struct vdpasim, vdpa, NULL, ops, VDPASIM_VQ_NUM, NULL); + vdpasim = vdpa_alloc_device(struct vdpasim, vdpa, NULL, ops, VDPASIM_VQ_NUM, name); if (!vdpasim) goto err_alloc; @@ -393,7 +403,8 @@ static struct vdpasim *vdpasim_create(void) vringh_set_iotlb(&vdpasim->vqs[1].vring, vdpasim->iommu); vdpasim->vdpa.dma_dev = dev; - ret = vdpa_register_device(&vdpasim->vdpa); + vdpasim->vdpa.pdev = &parent_dev; + ret = _vdpa_register_device(&vdpasim->vdpa); if (ret) goto err_iommu; @@ -714,21 +725,67 @@ static const struct vdpa_config_ops vdpasim_net_batch_config_ops = { .free = vdpasim_free, }; +static struct vdpa_device * +vdpa_dev_add(struct vdpa_parent_dev *pdev, const char *name, u32 device_id) +{ + struct vdpasim *simdev; + + if (device_id != VIRTIO_ID_NET) + return ERR_PTR(-EOPNOTSUPP); + + simdev = vdpasim_create(name); + if (IS_ERR(simdev)) + return (struct vdpa_device *)simdev; + + return &simdev->vdpa; +} + +static void vdpa_dev_del(struct vdpa_parent_dev *pdev, struct vdpa_device *dev) +{ + struct vdpasim *simdev = container_of(dev, struct vdpasim, vdpa); + + _vdpa_unregister_device(&simdev->vdpa); +} + +static const struct vdpa_dev_ops vdpa_dev_parent_ops = { + .dev_add = vdpa_dev_add, + .dev_del = vdpa_dev_del +}; + +static struct virtio_device_id id_table[] = { + { VIRTIO_ID_NET, VIRTIO_DEV_ANY_ID }, + { 0 }, +}; + +static struct vdpa_parent_dev parent_dev = { + .device = &vdpasim_parent, + .id_table = id_table, + .ops = &vdpa_dev_parent_ops, +}; + static int __init vdpasim_dev_init(void) { - vdpasim_dev = vdpasim_create(); + int ret; - if (!IS_ERR(vdpasim_dev)) - return 0; + ret = device_register(&vdpasim_parent); + if (ret) + return ret; + + ret = vdpa_parentdev_register(&parent_dev); + if (ret) + goto parent_err; - return PTR_ERR(vdpasim_dev); + return 0; + +parent_err: + device_unregister(&vdpasim_parent); + return ret; } static void __exit vdpasim_dev_exit(void) { - struct vdpa_device *vdpa = &vdpasim_dev->vdpa; - - vdpa_unregister_device(vdpa); + vdpa_parentdev_unregister(&parent_dev); + device_unregister(&vdpasim_parent); } module_init(vdpasim_dev_init)