From patchwork Thu Mar 13 05:18:02 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Mike Christie X-Patchwork-Id: 14014338 Received: from mx0a-00069f02.pphosted.com (mx0a-00069f02.pphosted.com [205.220.165.32]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id BB7841F91C5 for ; Thu, 13 Mar 2025 05:22:47 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=fail smtp.client-ip=205.220.165.32 ARC-Seal: i=2; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1741843369; cv=fail; b=HMNf8gkoultE4sD4NK4bqMh9KBNAcUqTu5v6AfpVCiR7+AOdvDSsxjXgLntOZdSlGuhge7ydYOl2DokDn6M0Hm0kJviRSY63OGjgiGipfx9DxNBMwgpHWW9rp+WsB9X8H+RzrROhvlZ07vWP8SNiZwwVKSBbAoMKis3APCd4co0= ARC-Message-Signature: i=2; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1741843369; c=relaxed/simple; bh=RejOUFbxSBrWATdd6Cx43POhDS4hPkh+CQIFcBWGPZQ=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: Content-Type:MIME-Version; b=rTS2DxoZWwHC517v9S0GsbxXNLD3e6KdK1RcP7/cUg8XqYSNkiYx0l/hZxFWHux66mLA7p4NW0Az3f+xIV+vCV5iKiw2nhA2f7+aVCwz9Mz70p6Vbt/1zf5tSTshGnIqyxwYZXAciNenRyhTh+Mel/5dEMsVKUDheRfWp4Z6F+U= ARC-Authentication-Results: i=2; smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=oracle.com; spf=pass smtp.mailfrom=oracle.com; dkim=pass (2048-bit key) header.d=oracle.com header.i=@oracle.com header.b=MnOkguJX; dkim=pass (1024-bit key) header.d=oracle.onmicrosoft.com header.i=@oracle.onmicrosoft.com header.b=xN1FYV65; arc=fail smtp.client-ip=205.220.165.32 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=oracle.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=oracle.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=oracle.com header.i=@oracle.com header.b="MnOkguJX"; dkim=pass (1024-bit key) header.d=oracle.onmicrosoft.com header.i=@oracle.onmicrosoft.com header.b="xN1FYV65" Received: from pps.filterd (m0246629.ppops.net [127.0.0.1]) by mx0b-00069f02.pphosted.com (8.18.1.2/8.18.1.2) with ESMTP id 52D3uMfN013592; Thu, 13 Mar 2025 05:22:30 GMT DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=oracle.com; h=cc :content-transfer-encoding:content-type:date:from:in-reply-to :message-id:mime-version:references:subject:to; s= corp-2023-11-20; bh=krIQnO/UD+DQIJKuGHEwUvgzVTuMUH1FJ+dtD5lIIU8=; b= MnOkguJXxtL4o07+QPp41otf54GJcI4HgFUsQlub4gPCjhkbUfT2BOCmGHbj5sQ0 /MFJM/kLQjjuF7na2o+D+LzW6pjHqmNkto0oxmVF3MZob0UlFq2VXbAjHTVG6Nt8 +qYisKSWemh1HAxFlZoq1/5sBJ51fqlStkRL74jSs8657DZ6qBPtMILzHsEZHv4Y waZJpB7Yo9kNKtnSDiccV/c8p+83xAJ/YsCrO/ADQ0tfCMzyfcbiupKHg97ne2rv 70/4XXmWlQ3ZJ+JuXtrthWPlleWERsnO3gtBUlPNA4IbYe5jgFF8WBD75uMHuKaU KMyjcTpNQOW+KtAK0d36yA== Received: from iadpaimrmta02.imrmtpd1.prodappiadaev1.oraclevcn.com (iadpaimrmta02.appoci.oracle.com [147.154.18.20]) by mx0b-00069f02.pphosted.com (PPS) with ESMTPS id 45au4dudq4-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=OK); Thu, 13 Mar 2025 05:22:29 +0000 (GMT) Received: from pps.filterd (iadpaimrmta02.imrmtpd1.prodappiadaev1.oraclevcn.com [127.0.0.1]) by iadpaimrmta02.imrmtpd1.prodappiadaev1.oraclevcn.com (8.18.1.2/8.18.1.2) with ESMTP id 52D3boGi002306; Thu, 13 Mar 2025 05:22:28 GMT Received: from nam10-dm6-obe.outbound.protection.outlook.com (mail-dm6nam10lp2046.outbound.protection.outlook.com [104.47.58.46]) by iadpaimrmta02.imrmtpd1.prodappiadaev1.oraclevcn.com (PPS) with ESMTPS id 45atn87qp7-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=OK); Thu, 13 Mar 2025 05:22:28 +0000 ARC-Seal: i=1; a=rsa-sha256; s=arcselector10001; d=microsoft.com; cv=none; b=DcdRtfxxr31MICZY3CeO2TDt06I9+LCOSOBM3TjqMIjhEvvakUhUeNcVk+PVrcwYGZ5xbupGdfE3ni/GNyuZECUYHKX9S+RB/Tun+B8gfzJbgVXrhDdIj4koCv2soHWcMqOVV+QtOaSNjnyFzJInEaotWgSqx5UEyzLk5JJVlahdIJ8is87mPtQ9SJ8/q+bI2KSO000xuyRfb7taOxcugpdTRchdEDDCdXBB6MgHznJ7WYJQRgYMKo884eaN+Cz6dSxCVfyk0sAciIu+FqR6wHttsDVydN4Admmqngs3fLb1+GuHufOIOX0QLMRpr83ekahsKF3ekapHECcJSXoc0Q== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=microsoft.com; s=arcselector10001; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-AntiSpam-MessageData-ChunkCount:X-MS-Exchange-AntiSpam-MessageData-0:X-MS-Exchange-AntiSpam-MessageData-1; bh=krIQnO/UD+DQIJKuGHEwUvgzVTuMUH1FJ+dtD5lIIU8=; b=r8EVa/F5QZVi5mru0Yj3cU6znS9+L5ya7bg1HUksOsTvnesCusKJzh3JUj+7vllLHB5QYWuMH6jAINIxtZQ7x+HqoIgEHm1azntOaIiEe+SD3AofvhHFqQU4gqXPVmXKvG6/u1hOGxdao5VXMiepJyafWbxCwrzwEF1vOe+5aCkKUFegdYbCsDrnLWrKmzEglw+CeVSAnMsiEgnRcEGYstn8WmLC2oyq5Jhc9bn5yMG4YA0PanslL8WblS1dqDOZgrc9/utOsp3mBIhXBIXsIb7N/bdCm8QDMo/YvPlXloimaLrjByl84PJmeno/H9HX3+RG72RSZI/DhZNUFcOXIg== ARC-Authentication-Results: i=1; mx.microsoft.com 1; spf=pass smtp.mailfrom=oracle.com; dmarc=pass action=none header.from=oracle.com; dkim=pass header.d=oracle.com; arc=none DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=oracle.onmicrosoft.com; s=selector2-oracle-onmicrosoft-com; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck; bh=krIQnO/UD+DQIJKuGHEwUvgzVTuMUH1FJ+dtD5lIIU8=; b=xN1FYV658P5sC8w7eda7GrnFdM/JWYGrGjnnA8dwnMZhd6qHy+RKPJpnGYeZVfvvXy8FIvywDM/CZAlV6YdZj75BDdyEFaq0OwNhWSX3mcvFOl7J6vlOkOcbBxlrl2ZwKdxVoK/gyvSxKnYsYGxlWmbFunlK9jkhdWjksb53fEE= Received: from CY8PR10MB7243.namprd10.prod.outlook.com (2603:10b6:930:7c::10) by IA0PR10MB6724.namprd10.prod.outlook.com (2603:10b6:208:43e::5) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.8511.27; Thu, 13 Mar 2025 05:22:26 +0000 Received: from CY8PR10MB7243.namprd10.prod.outlook.com ([fe80::b779:d0be:9e3a:34f0]) by CY8PR10MB7243.namprd10.prod.outlook.com ([fe80::b779:d0be:9e3a:34f0%4]) with mapi id 15.20.8511.026; Thu, 13 Mar 2025 05:22:26 +0000 From: Mike Christie To: chaitanyak@nvidia.com, kbusch@kernel.org, hch@lst.de, sagi@grimberg.me, joao.m.martins@oracle.com, linux-nvme@lists.infradead.org, kvm@vger.kernel.org, kwankhede@nvidia.com, alex.williamson@redhat.com, mlevitsk@redhat.com Cc: Mike Christie Subject: [PATCH RFC 01/11] nvmet: Remove duplicate uuid_copy Date: Thu, 13 Mar 2025 00:18:02 -0500 Message-ID: <20250313052222.178524-2-michael.christie@oracle.com> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20250313052222.178524-1-michael.christie@oracle.com> References: <20250313052222.178524-1-michael.christie@oracle.com> X-ClientProxiedBy: CH0PR03CA0403.namprd03.prod.outlook.com (2603:10b6:610:11b::13) To CY8PR10MB7243.namprd10.prod.outlook.com (2603:10b6:930:7c::10) Precedence: bulk X-Mailing-List: kvm@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 X-MS-PublicTrafficType: Email X-MS-TrafficTypeDiagnostic: CY8PR10MB7243:EE_|IA0PR10MB6724:EE_ X-MS-Office365-Filtering-Correlation-Id: a4f6bb1e-ec58-4232-01f8-08dd61ef0ae9 X-MS-Exchange-SenderADCheck: 1 X-MS-Exchange-AntiSpam-Relay: 0 X-Microsoft-Antispam: BCL:0;ARA:13230040|376014|366016|1800799024|921020; X-Microsoft-Antispam-Message-Info: fE+N6tyN5qUZCY1PRgmD+H4JTwRZZDE/vXoh+OdH9OCUzDb/SEQyG8w9zHY/oK0v15XlyJKAe0C7SX/Y0aAYnCkiU+YpcyPiD8GJR5/Z7Jt+UWU+SpO6zQmM8qtebeezERoqnI5vuNJcoFkhALW1wwg9h7+RkdJ5952OWox2y5Edx5PTQxCEVUzIZMkXzoJaUCpBuktSBb6f8uvulioDn9bhTqHLMoiJ5iU3J7hfipVZXAwpXztIkIcflk5+bFGZag3KEmzRMverDECXgVGgNWqTGqxlWipV1RUctfRSGx5FobE6hD+aG5hc4RLR+L35a63S+OzfT9UqAN9QvWD/twpZ9SH41xvmVizotrcKwWrY/NOZo9zn4T2KKctDHx39WNTKp7vtue0JjDql4LeajrPM+6yGmk6tu+LtB+/eQCNs8H1/pC4G4i9Z/dWiNv2IsbL8s2BPN7TBZ2zBCJkoe99v85WvWcrQDPTfb9klciygciKP498Ss1gRNRZnhi7wLdQPb5cAqZJzE3RpRNxFHQrgjqfsEaWJ4fDYeSgPdp3zabrgOCmkADC+1aPUOUC9MPBPnFCrbKHI2NHs+DgM+Z4kSMJxFGKB6RRmbhEcfpVTcDya006Y3ZkRCkYvOGcf0lrA8JAa8RuSzFZVKCETonabOroXf/rgvB3nETJ8pllvvx3F7nOoQyaXKqoglEdSqmyUDXuAb2NUIP+nk7GmDIh6+Yq8IR1i1oHjFa4QrFyKUhquxG14crsYV9FpiiFVpja4grA5bssrAvIx9KectEVpzPsLl/+oN1Do8b05FVlF1RHVlKlo5ir9z4A63n9+rhmpd7t4iBkcMwEK9RPSAPrwhPjRK2F8G3cklpdyHgt/AVVtb+CaUwJfYWkmCYawTEQSB7hBIz+7MxGb18HdpbQi0xc6lkZhRR2iXC08dGxJsL4J2a0aszYMJfmtUU+3HtVBdRIFtcz9LQ+uFyz9SX6moijrxDRcZsPLAwR+0d4XKvUkC6Bl8mEk2jpTxe1gmVnbVIOMKE8/FaH5GIXmIh4n8ZFG/VbY2MmmzKKRpayigxbALTthJC9xsvjJ0GbFS9pJfsi6OFBD4P36kt/S9trUDj7rtC1OOQTZQnO0h/zV4Gn+2NKDQ4DtuY91lrWGeM5XIPBnYdA6fntKMlOwdyrLAEHaT/TV1rGGgjNJ2YTUH9Umchu4Q0eGgar9yQKgOFfz/pDpwDG03yCsg2Eqkop470nfSUOLbHyrrOtDeG6jlBAgtyLCGFqfm9OI+hEQTpDSqF498pA2WZe1J5SM687uG6g1dY4HYQw8xI09NV447i2Rp/SQf2uwv7/GOMlOoSFsFC6kABuCOyThU6NcRoVRePdEJ8NSHeo+kpzn+UAxZiLuuC1lYv/HSowFgne8/6SC7c+w5z8cjsd44PDTrZia7vvtW7oTZD6o5q+he8k= X-Forefront-Antispam-Report: CIP:255.255.255.255;CTRY:;LANG:en;SCL:1;SRV:;IPV:NLI;SFV:NSPM;H:CY8PR10MB7243.namprd10.prod.outlook.com;PTR:;CAT:NONE;SFS:(13230040)(376014)(366016)(1800799024)(921020);DIR:OUT;SFP:1101; X-MS-Exchange-AntiSpam-MessageData-ChunkCount: 1 X-MS-Exchange-AntiSpam-MessageData-0: vxW5Un+bEQrTcLsIt3O5VE/sojGvqqcdrRtnwHzavuxRo1LkDWNPddbh3GIQ9NiHKP2Ry4mTBf2Fx1bRch7qTJmAP/v+vL7MViWbEYFaIIshuFiaOND13bLFbONW5T0LwB1IF5DiC/pp7NEImH9L80hI9vv0SYqzMtsWNETmvFSGXuCccjMCtui41yHibqHbTcvNOM4O5oJoybSI8OFWxHTFMy17xqvM3IwkP6kVlO1/E7sWVOP0cCjLUeEvJ3qiQPANTChKp/QSsIQ+DV6iRt2rF1MxtgjgTF6vbamnQkb3OaxGwLnw+iJQjCQXtcFXlfE7RgcNmwdQ1q53m4p0U9jEzvRmmhDsr7Kk9Fkgk5g2Ac8EYryQWZn8cwsR1zKSXQ6WFJOIwGPt02oWGEf0ECjzGQdRXcJtc8oysSHjPhIIYiWnjyh3ITgYuQelBnPINIbfz3ZA87d27A4EaXjoNu2MYy8SOAbktuOy4CrM9ni5btiIZOPGlCYqQRZbdORxjEj73hl3PLCDYHqi54J29gprKwJN6Jo4LH9WZT/ntxmybTanMP9oJRGs48v3OMECCDg8w8sU5+mpilfLrHP9EepZXccszwfHB55z7uW/FeNNkNHSv8DCg1LXuxliMupRQnsL49FXqMABGcswEYsDl172510tWQlUaU7JNHvwiYhHHPjM9PUDxW7M0teWdFwbdQocewWtE9NUVGV3Z0ZygWrTeBHb1dFyLO0Ye2zR/ql7ky3sZCc7i44tt9a9s1wXhKgWBXHfUvF9uLCHa4QfdC59ZxP7BAkstrb/iPUbPxqh89gkaB89lMj6aJq0yxCSg7OP4zFtQHqPy+4cLp2UeT9ECBSipZIDtocugSKi6k0/GegOKyHKr9jFwnEC8awOme8o1OnCwcXnn23ARy9ux6xhEHOXOG5r4aYiWDhEoibZ+15ghJTB6LZz1HdnbhmqnIu8RGmIHVuY4e+SOnTycr+anpzkLAWoG7mFdUDdEs+oKIOdI3Op4VfthhFJcZOnxWhUGauIlRilKBhfktd/jQKYz2MV24nnjIPt7FManqSEvK5cy+oEx1exPyLy4X45fPEsg3OJHfo6Q0KjK1r3Ccavg6VXfjCBvS4q+tIIKupZWK26ztcmytnGWtW78HUzhP6Op2KQIexbjvbzOm+4lH8kzvcwfcE6hrOaSbHELDcLN4zuGxg5vqE0Rt9o5oD1y0uGGfbCYTrdqAd/gVE7S6RqXC1TQkHqdMwNYFyO+1J5IKOqt9NG2tHZd92fat+KB+yRhBHdlmen/thjlvvtrv1RWiNrkfMPJXirpNBSkvb3pghTY27eGs+obAquqHW6TgmKWsLmg2PVfGZebyIGbRLNjTD4o8tRBxcZ1oTWxELeC1MwlKMIUL6rXBC1eaDKrBxBhOnNuTdzaMBYEkEppSAcO8mb5fnZE8uDLF1wdAfXgBf0Ctt93EPxy+w7iNdsvMTU2zfTyPJ6l4pglbtRhD+uq0dxLLRRAXc+4SL4biF1N1cBd18hlz1iTevHY/XAiQTnOsJ2BgukHC+NaLmKFt1ilaDZOVBmQxzDwxzekE9r9Kucsn94KGw8KM6ObVeZ2WJBV6hVUSO3UMoyVRzUyQ== X-MS-Exchange-AntiSpam-ExternalHop-MessageData-ChunkCount: 1 X-MS-Exchange-AntiSpam-ExternalHop-MessageData-0: ODFXaVUCTsN8/EetAh57jQCEZkdwgfx7NPQuGvcJOhO4nv7455jeUQc//2Bcs+PGUglYElvD1/uKcD67QwSEVQdgmbT9lqcaPePSnsfkewxyZiFbmAW3tVPfA2D8O+1JDZupUWfzHLkcff291jLPk5nTEG7gKuCONzcpCKvcUA47QV9R2JIgF0P2l+wHmV5VIHNnQ2OJD+ZEpzWtjzYd7zMfm57tdHBsDRWxoZ2oDquPiEfdv372M8l5ZAHbl+9b4O1wkmLJ/7zT5jyxMBDwoePYzFj9JIliw2KI4ho0EGm+P25UkZPxi59J4D7F/5E3Q8LtROqp9RFf1dWpaP5qAwhE4v3/gnAy1H5TCwWM7i4MVyyIEHT0UIks5izL3DEQdlz8fjaxGLN0Jij2/yPcy+EnQtokDUYZvPvZuc6+WMG5asy3TuXGtC/ENHPYTueGrfc3ORHwxYz5t3Vnz76eQruhCpSPV//O8x+GucNZBUyh3ea2Aj/oXPzaIkZN7YVaF0IkXkU4KPX0u3tlI+mo3GX6R8hPm9ypVk32UJxumabOyHtzCB3j6dAfc50k70+u8vo/fVYWpiktsbiiM7uZhoO3Y4c2hwA5QfhdwPOvGys= X-OriginatorOrg: oracle.com X-MS-Exchange-CrossTenant-Network-Message-Id: a4f6bb1e-ec58-4232-01f8-08dd61ef0ae9 X-MS-Exchange-CrossTenant-AuthSource: CY8PR10MB7243.namprd10.prod.outlook.com X-MS-Exchange-CrossTenant-AuthAs: Internal X-MS-Exchange-CrossTenant-OriginalArrivalTime: 13 Mar 2025 05:22:26.5475 (UTC) X-MS-Exchange-CrossTenant-FromEntityHeader: Hosted X-MS-Exchange-CrossTenant-Id: 4e2c6054-71cb-48f1-bd6c-3a9705aca71b X-MS-Exchange-CrossTenant-MailboxType: HOSTED X-MS-Exchange-CrossTenant-UserPrincipalName: iOy3n2bt6cy1EImizmBYboeXihmZ4v5C30zZjIC+RL9A840ltaJZuD+Gk5KG7INOrRFqQ7o/oRpmCpnuMtIpT+6aK9fJKIG8oLvivxV+ppA= X-MS-Exchange-Transport-CrossTenantHeadersStamped: IA0PR10MB6724 X-Proofpoint-Virus-Version: vendor=baseguard engine=ICAP:2.0.293,Aquarius:18.0.1093,Hydra:6.0.680,FMLib:17.12.68.34 definitions=2025-03-13_02,2025-03-11_02,2024-11-22_01 X-Proofpoint-Spam-Details: rule=notspam policy=default score=0 mlxlogscore=999 phishscore=0 suspectscore=0 adultscore=0 spamscore=0 mlxscore=0 bulkscore=0 malwarescore=0 classifier=spam adjust=0 reason=mlx scancount=1 engine=8.12.0-2502280000 definitions=main-2503130040 X-Proofpoint-GUID: VOGBr_UJDSFoLoFAypH9ulu0c0UOdrMM X-Proofpoint-ORIG-GUID: VOGBr_UJDSFoLoFAypH9ulu0c0UOdrMM We do uuid_copy twice in nvmet_alloc_ctrl so this patch deletes one of the calls. Signed-off-by: Mike Christie Reviewed-by: Christoph Hellwig --- drivers/nvme/target/core.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/drivers/nvme/target/core.c b/drivers/nvme/target/core.c index 2e741696f371..f896d1fd3326 100644 --- a/drivers/nvme/target/core.c +++ b/drivers/nvme/target/core.c @@ -1618,8 +1618,6 @@ struct nvmet_ctrl *nvmet_alloc_ctrl(struct nvmet_alloc_ctrl_args *args) } ctrl->cntlid = ret; - uuid_copy(&ctrl->hostid, args->hostid); - /* * Discovery controllers may use some arbitrary high value * in order to cleanup stale discovery sessions From patchwork Thu Mar 13 05:18:03 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Mike Christie X-Patchwork-Id: 14014337 Received: from mx0a-00069f02.pphosted.com (mx0a-00069f02.pphosted.com [205.220.165.32]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id B12FB1F8EFF for ; Thu, 13 Mar 2025 05:22:47 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=fail smtp.client-ip=205.220.165.32 ARC-Seal: i=2; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1741843369; cv=fail; b=Z6f0aMGY7SXb23hXsPMnoC9rLHDubvYkhigOhHlOQS4bSPoesv/0G3onCZsz/kn5RrD6qMRlDNYPpG10RUEVbtE7OoUks8MiXGeWIGnNQNG9oHvrLauC+2rsf6rIMgcTv5ts5q64XOMRGAx2+Fuzv9QTu9DsTTze2eNuhffVreA= ARC-Message-Signature: i=2; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1741843369; c=relaxed/simple; bh=n5GMfygwILBVetH5xpdbDrWe1FmC0tI3pTd3F9K/uw0=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: Content-Type:MIME-Version; b=CSsM9TV4io+Ansyr7VuEeZ27xKz8g5f03U6G/xwzLkdrGzodGFcl8TtXlbnxhlmR4nY74eS4d9ZUUzSt/T1hKISguZmj11ly5nTG7VfMUkoG5lyPbuIm2nnnhujap3cIIOUdhL2Yl25jOnzN+758a79ACrtdIurrgfK7uQ8K42o= ARC-Authentication-Results: i=2; smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=oracle.com; spf=pass smtp.mailfrom=oracle.com; dkim=pass (2048-bit key) header.d=oracle.com header.i=@oracle.com header.b=g1+RNE6F; dkim=pass (1024-bit key) header.d=oracle.onmicrosoft.com header.i=@oracle.onmicrosoft.com header.b=aL7nkstz; arc=fail smtp.client-ip=205.220.165.32 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=oracle.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=oracle.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=oracle.com header.i=@oracle.com header.b="g1+RNE6F"; dkim=pass (1024-bit key) header.d=oracle.onmicrosoft.com header.i=@oracle.onmicrosoft.com header.b="aL7nkstz" Received: from pps.filterd (m0333521.ppops.net [127.0.0.1]) by mx0b-00069f02.pphosted.com (8.18.1.2/8.18.1.2) with ESMTP id 52D3uAqq019315; Thu, 13 Mar 2025 05:22:31 GMT DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=oracle.com; h=cc :content-transfer-encoding:content-type:date:from:in-reply-to :message-id:mime-version:references:subject:to; s= corp-2023-11-20; bh=MhstusFrebtg2CVvK1T0jLZmsPovB255F3YpTwT8I5E=; b= g1+RNE6FvpAM1TeIYWexE0HqrTesuqZrRBWbKB4IT2Vh7RGgSgKCOmUr/DHLfoya wi+lsa4bfuWHod8j28SzWezneTCXB/lKk+2I13XorSppm8d+w1hqUYPmdmFaar+U l+9fbNR1bWUiRe+5+D7/8leE5PGV9EhajEcQI0BaDrhwoYgZ1XwvwLHc/A4C26he zp7l8oIKu6PakCMzShKyGnTnU8aBmuiWAeQtGwF9wVUeiGxP6BkznvV4ZQsyiv6T rRFOhc2i3pLoULAQyblEDXRNqjw5FyYHrhmdAr87Y8Oe+5PhIQ7PElN8gbtx0xsr rTeQWRNlKx1fOtHJ+CyVig== Received: from iadpaimrmta01.imrmtpd1.prodappiadaev1.oraclevcn.com (iadpaimrmta01.appoci.oracle.com [130.35.100.223]) by mx0b-00069f02.pphosted.com (PPS) with ESMTPS id 45au4hbfrb-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=OK); Thu, 13 Mar 2025 05:22:31 +0000 (GMT) Received: from pps.filterd (iadpaimrmta01.imrmtpd1.prodappiadaev1.oraclevcn.com [127.0.0.1]) by iadpaimrmta01.imrmtpd1.prodappiadaev1.oraclevcn.com (8.18.1.2/8.18.1.2) with ESMTP id 52D3RH9R012272; Thu, 13 Mar 2025 05:22:30 GMT Received: from nam10-dm6-obe.outbound.protection.outlook.com (mail-dm6nam10lp2046.outbound.protection.outlook.com [104.47.58.46]) by iadpaimrmta01.imrmtpd1.prodappiadaev1.oraclevcn.com (PPS) with ESMTPS id 45atn272mx-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=OK); Thu, 13 Mar 2025 05:22:30 +0000 ARC-Seal: i=1; a=rsa-sha256; s=arcselector10001; d=microsoft.com; cv=none; b=W+RnWGFs8w00PL77PkJi1LaRIG5FxJ2lQcs7JQjvKXAGRwzW7L0/v0RdP2Xpin+fAA1n13PzrEn1O0AwssdrlRWFXsEUDEit1sU0wgl4bfDVB4o67+n7wuF3GjtGokQKJb+pDwj1GSXG/ztxsPhNqObeuw+jatGuaCk41fuuawq5xsZuDTsA5FK1i6hGuD7op3drMq05y+UE1RKwPpPK0+ahnUBzWiojyXEJInKuuSElU/EudXtoFFKx9JHbRxvd/yxK/FRw1Ju0eQhL+ezcxEHSuSMxxT7hVxDUWTLuFhtxdSLehU4IHOYoRhY3kAouj8/bgpv66Xe/d6szWOPW5Q== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=microsoft.com; s=arcselector10001; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-AntiSpam-MessageData-ChunkCount:X-MS-Exchange-AntiSpam-MessageData-0:X-MS-Exchange-AntiSpam-MessageData-1; bh=MhstusFrebtg2CVvK1T0jLZmsPovB255F3YpTwT8I5E=; b=viXkZ534GgDgFfGLmTSEMseVlbMx40ZYOqAjUlgAH1XJ+q6lei7yDsW2vXKCaKSe4NLuEcJScswRiZWDssSs0Fq/ipHZxEWmXII67LvaajCYbqUDne20w0GXUNMsYmssZHmx0a2MezsiFkYQEXOvFNgdtGz20YDoTivT6kuM1gY5rqNwoXiO8zqMkjY8x9SCWHKxGR4Xf+9W+HSEkinr7Ivuyaimf2HiB6BOGktfYWJViszW8gnKjrUBRgrMSYDyOPOhheeBVi59gDm0F9biSGQMimqzCqeCglHvB4laHxLOKIGOXOC/DhtidI06p0nSLqmp+wEjYxuHJHGaQ+Go0Q== ARC-Authentication-Results: i=1; mx.microsoft.com 1; spf=pass smtp.mailfrom=oracle.com; dmarc=pass action=none header.from=oracle.com; dkim=pass header.d=oracle.com; arc=none DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=oracle.onmicrosoft.com; s=selector2-oracle-onmicrosoft-com; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck; bh=MhstusFrebtg2CVvK1T0jLZmsPovB255F3YpTwT8I5E=; b=aL7nkstzxaK5SoriNlI191EWo/wpsXcZf1FhWKNRjT4ReRV0yIR9pKY67ul+0oKNDdtDNLZ0v0AWaZooaYSAWTcfzODtBmK+x2YDyUsiMvaJIJiZzH+LF4BpGnh5MVMfSWltJJXdA7cYUW6YLP8hRSAyfGWEmcbL1o9w12YqwJ8= Received: from CY8PR10MB7243.namprd10.prod.outlook.com (2603:10b6:930:7c::10) by IA0PR10MB6724.namprd10.prod.outlook.com (2603:10b6:208:43e::5) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.8511.27; Thu, 13 Mar 2025 05:22:28 +0000 Received: from CY8PR10MB7243.namprd10.prod.outlook.com ([fe80::b779:d0be:9e3a:34f0]) by CY8PR10MB7243.namprd10.prod.outlook.com ([fe80::b779:d0be:9e3a:34f0%4]) with mapi id 15.20.8511.026; Thu, 13 Mar 2025 05:22:28 +0000 From: Mike Christie To: chaitanyak@nvidia.com, kbusch@kernel.org, hch@lst.de, sagi@grimberg.me, joao.m.martins@oracle.com, linux-nvme@lists.infradead.org, kvm@vger.kernel.org, kwankhede@nvidia.com, alex.williamson@redhat.com, mlevitsk@redhat.com Cc: Mike Christie Subject: [PATCH RFC 02/11] nvmet: Export nvmet_add_async_event and add definitions Date: Thu, 13 Mar 2025 00:18:03 -0500 Message-ID: <20250313052222.178524-3-michael.christie@oracle.com> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20250313052222.178524-1-michael.christie@oracle.com> References: <20250313052222.178524-1-michael.christie@oracle.com> X-ClientProxiedBy: CH0PR13CA0040.namprd13.prod.outlook.com (2603:10b6:610:b2::15) To CY8PR10MB7243.namprd10.prod.outlook.com (2603:10b6:930:7c::10) Precedence: bulk X-Mailing-List: kvm@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 X-MS-PublicTrafficType: Email X-MS-TrafficTypeDiagnostic: CY8PR10MB7243:EE_|IA0PR10MB6724:EE_ X-MS-Office365-Filtering-Correlation-Id: 4805b95e-32d4-4dea-afc7-08dd61ef0be9 X-MS-Exchange-SenderADCheck: 1 X-MS-Exchange-AntiSpam-Relay: 0 X-Microsoft-Antispam: BCL:0;ARA:13230040|376014|366016|1800799024|921020; X-Microsoft-Antispam-Message-Info: gNxul4C0NbVxCnZrn4XkwhHZTvvzCDRKUWM8NgUerc5tBrtugkVv8OlYnNojlkjxmffDqDL3DQWvJrffRCqoiM/tJtZ6YQnEJteTe4Bq4+20dGnQBbC4p51OX2BjWg6UkMOP6280NrXutUmSiq2jm3L5lcgjdZyS2N7O0ojrPxO9qtcf/vKntwJpEGkQRH9mLWzl5ENkemA85Wpt2ebVm50nMCkTKjBWp/JK2Uc9yFKcobMGzb8uNSyb8coj3ojSreBe5aUPeoR07uNk8az6YZKwga0nvYTF6tymjkMIioeogNLkHui224IW5A2eSndeZM6hvfCOSIYETi8SP0sFnHu5RwPTyBzVRtXLikKNo+jcb0+C/Fl0qolnVhWsnn2i5ql5q/jltu4i/48pD3siEAxfez0ZX9TaQsrC63MkvKCKvQN7Uv2xSgz4ggl4cnYWwSwRnjpr2BP1wGp2kq//yKYLnLJtihFvZQLKhcvH7le7e2qkHnAl0ulc1Z4/vMxo+aT6QXHJY+MgNegW50L4sJMjCvmzv8MGduyT47mS8gTbaZCU1ZlVov+oxMhpy0Tf9laahbMEdZsF3IEgxom++Roe5a4kKE/bGA+DJ0NLlmTgB1MCWEoycOAXQ2g0+/Eg40GA8DzYGkngPwPLLzeJXwLAf7v5uCMgyBrZpkHFP31O0MiUHYR7jljzxik+WR34ORNPUUSufBNR1fvQPXR4euTIZumcObfr4y6oRO13HX4CfuROD+5XnztSW38MJ8HlV6iZOiYxo+jyDsQnLzL/XePgVTgLqRILdccO3r5eWBQwyiBDBmbfPp5mniW1cmxgfwDWUbgiJrqz05/RJ1CPW3Wep48e+/0KkzSLAPZ4eVXCiLwNdh9Y0SlDoN7hxczqVG8gNYiqJ0t/B71AaU3uDhZFkBgEfQMbA2mZZIs08GJ+9vX2Nn7C6mxmA3DsS1pYLF2RceNRJ/OC/yqy+ZDZoMbL/csXdeF7TzfSo00TrmgupOGTBPmr4cAyXmXjvMUxuapLNf5hqbXUh9ZjUlG0uXk8ARK5Z7HOeFJD9bHmiSgyUqVpLkrkjG4S0z7LaSgCOoAd6IDoQJZR7tx2v58NMhUrhC2CRCkpjU6GNx/axN7xbK+hTENa37jJ5VUg6C/Ci1K59F27MZ2TBllrjRpJ/FOcI4z2zqOSOGGeNxMuGCkUnJKKn/ozyMLxZ1gHS78Egy7pFnUX3WV0yHsgJKwSFBjJqblgjBQnRb2Vcc8WaMBdOBBPFzKQXamIQynDiCrRz/exlD16CztyFLgfWwO2udNL/qYWxssanUrcZVSewls4JWuhH07ABwBtTkrQQI8QnMND+M5D17/5iqVVGBQHoDm8vTukJn/hVRCpQoi2Uudt2nqOeYu4TBcGb0x4X4HfdqQ8Yhv/WMEVXz7n3e6e6BZOAIEEM0eYeypUL+6jj48= X-Forefront-Antispam-Report: CIP:255.255.255.255;CTRY:;LANG:en;SCL:1;SRV:;IPV:NLI;SFV:NSPM;H:CY8PR10MB7243.namprd10.prod.outlook.com;PTR:;CAT:NONE;SFS:(13230040)(376014)(366016)(1800799024)(921020);DIR:OUT;SFP:1101; X-MS-Exchange-AntiSpam-MessageData-ChunkCount: 1 X-MS-Exchange-AntiSpam-MessageData-0: KCxmrtvl+lk9+QcupEHBci0uqXzGtIOo+z54gDxLk8oR+p6VRyAJtICtTzP44ebsLLuK+GzgAe4dZYmWlWbvg0tuQdRwxOO/mmdD69G87iveWZHFrYq1bfH2V1M7yw8jzqxstMNuKEaNWmJqVH+oz7moPaB9fUpKcJQmaBewVGSQNgkNj2gfxSDlwTr72xSi7GetaH3cukbBlHrtGB4PvEp6IIdjKjxqUsUS8drapcnpM2QR/3jYarzpT50jFsLi3oc+q8ppWTM3MYJ4EHrhFnjvWagb8r0UorR9YZaN87ipFtooMv++FXMwcv2H9h/0rBkVE9JPMpSmAKBpe+ywucKX4Zu2DYGQeT7hs7MoyJRb231ld6ahBvIvDf1tYHj6LArLuF7rSjAOZq4wZcLLSxb1n2RG5MlYGB+UDUzY+nR0s1c3KHdMwgXIfm68kqfmDFe1ICgW6OWMmEbx+TcdaADXzXlxeueeU5AgcmT7KAHWa6Cmd9+roH0otPNcYFouP9U/CqPzsaxD4HvmkGYIFPS9oU54myT/c0U6bOjRxlL0ORnif/0HAB3QQ8l/087LcAxD3teYPvmqrgsEFX3gnd/XgHRiFLtr80Srd3uaVIQnKYK78dkYJzszBYtgKRleNNo4Ui4QG8rV4w5gU0HYOpfFvCHNI5H2v0GkfQ32c4rG02lED8FxUHhPNTIqrdxFBa2x+Sk0vDg72NU7d6aa79bBCHKIqbciI9prdKvgomlCDn/G83/3rcQnC1g1bHZRnf0B4bEJpMxD3UEhHtITERgHdPivISRtw4GGZGMXoVeZnwlPCHs4zTjq/71b9A4rE55XQ6SnSeO88LYQXcqtzS7mu9E4OmXu+lSzbhZFBuqfUzsZXQ4+pe/CCTaVUqe76j/YZ+0zPtJMseP/E73kUObsga28WjbrT4Zn26ONGxNp4jd427AXmhuQVqE3aaoRByqV/DCWowEQw2uLCBJdle7pOF/d6xuy6YaMUjzLw5jMNTTUC67LhNk+wrwR4tcDQWQaAFpi+WRpAN2mOT3wcQic9KBaCCZ5UqlvHkxecmN09JZAQV7C+PmUfdZbwXzN9yvqdsUk1w5opu5F2mQ8Rqd3riy3D6+pl1IgIC6GKMnjxnwo/1aKdBEazVYzuQXzxe+nBONEvvoYFyMoXx43FWQM6On/iu/19OM8RCVEK9TIRJU1h36qCXrpRebRMCuY5VRy1zJ7GAvHaBc+OyoH0zJvLJzwwvSk1AhdfDDu1YqB/ANq1EnocaXVD+lkN47S6uSwMp0vMwPz83N1kzaOrA6r6mr/E+laEo2Arx7SffpuXtoK9mOEA8SZYhRdPBCLEAZBAnNrkG2vzm7MO2H13ailqIWAlqi1SA1Zgy/kcy6e4T6opyGVihxyivXKVh43dRSdvVox5FzKDTq2o7G5486QAKmxbX/6cTATiGn35OYEoeB2qt0+bBLxjfzkA64dmUBA/xIcOZb7EZvomRYC4M2Sb37x0Z/SLa5SdVHLeZj7SH+tVnDeiTftjQAILVWxkeVK6TzGTy9R7GX9+V2CGIsjMMe1r2Z6URODxzjs+uGnwrd5Z2vtx8PpoV4c/hXqYdDIUfUkUhbaIrQavZCLsg== X-MS-Exchange-AntiSpam-ExternalHop-MessageData-ChunkCount: 1 X-MS-Exchange-AntiSpam-ExternalHop-MessageData-0: 3IJkq6KBjPlewBZzO3EIAQACwrmxihOgVMK9tjA9FjOLuaI4Lh6Jcd5eRpxaiqH1ZSRg5MX5odIA6oGEToKbZ7tICES040rzetXzMTPyB8heXLwvYDk7O990v9hGOBELacZGFUfkhtc5Kf1HxMxzJ0eftqfEgFpo53uAoJmMJxYv8XIzZu4GP0icCsZIAHnR5TOqFLp5mQZ737BjRoxMx3pJJ1lUPmESH1lWD5LJiRzdw8Z/7P0MpZ5fnEzXmkwFEtfdX/LQ0xZmyxd58bt0XKaeGvjfPZT7298ZXptb8JHbc6kMLF+cAjqpw01kn/IFESUVBo4G8dJMlFQaflY4Grl1mKDVwG8LGX0hj45qwY4eHWNGPmyy/TMzROX+v+hAMN5XcsT9pRjqKFUJzkE78h8hnUxi5q0fqlFCgpzp1X+8XD1JrHYnTUNCygWJAVY03/b3KAxCPxYwOYbPLtYTm7nTWxt8u4eJnmrvHqWpMVcDJ/FUzdcqi18j81Z/8Anh1f7A5NSezRE5XnAIQuI0gVYExRynRWN631YRBK4Xeh7e3WOfWcVTAMQhxsdm0nN9RFJPaSsjbTd1wXm31r4bSw14jpljuaJmmE4VvkueWZE= X-OriginatorOrg: oracle.com X-MS-Exchange-CrossTenant-Network-Message-Id: 4805b95e-32d4-4dea-afc7-08dd61ef0be9 X-MS-Exchange-CrossTenant-AuthSource: CY8PR10MB7243.namprd10.prod.outlook.com X-MS-Exchange-CrossTenant-AuthAs: Internal X-MS-Exchange-CrossTenant-OriginalArrivalTime: 13 Mar 2025 05:22:28.2349 (UTC) X-MS-Exchange-CrossTenant-FromEntityHeader: Hosted X-MS-Exchange-CrossTenant-Id: 4e2c6054-71cb-48f1-bd6c-3a9705aca71b X-MS-Exchange-CrossTenant-MailboxType: HOSTED X-MS-Exchange-CrossTenant-UserPrincipalName: +mBXZuJMoDvcFWyJdWHsCpyeUaGCLnrxz/IQ1ADmxPar6w1FIUXLQ78Nw6kjwMFSv/8N0ITXLNZtNZFaEkhnBmIxxgPGInx2rbH4UxoN7HU= X-MS-Exchange-Transport-CrossTenantHeadersStamped: IA0PR10MB6724 X-Proofpoint-Virus-Version: vendor=baseguard engine=ICAP:2.0.293,Aquarius:18.0.1093,Hydra:6.0.680,FMLib:17.12.68.34 definitions=2025-03-13_02,2025-03-11_02,2024-11-22_01 X-Proofpoint-Spam-Details: rule=notspam policy=default score=0 bulkscore=0 phishscore=0 spamscore=0 mlxscore=0 mlxlogscore=999 adultscore=0 malwarescore=0 suspectscore=0 classifier=spam adjust=0 reason=mlx scancount=1 engine=8.12.0-2502280000 definitions=main-2503130040 X-Proofpoint-GUID: V7znLuM4V4ZNnX3T31AKitIfxNeFgsJ4 X-Proofpoint-ORIG-GUID: V7znLuM4V4ZNnX3T31AKitIfxNeFgsJ4 This exports nvmet_add_async_event and adds some AER definitions that will be used by the nvmet_mdev_pci driver. Signed-off-by: Mike Christie --- drivers/nvme/target/core.c | 1 + include/linux/nvme.h | 2 ++ 2 files changed, 3 insertions(+) diff --git a/drivers/nvme/target/core.c b/drivers/nvme/target/core.c index f896d1fd3326..4de534eafd89 100644 --- a/drivers/nvme/target/core.c +++ b/drivers/nvme/target/core.c @@ -214,6 +214,7 @@ void nvmet_add_async_event(struct nvmet_ctrl *ctrl, u8 event_type, queue_work(nvmet_wq, &ctrl->async_event_work); } +EXPORT_SYMBOL_GPL(nvmet_add_async_event); static void nvmet_add_to_changed_ns_log(struct nvmet_ctrl *ctrl, __le32 nsid) { diff --git a/include/linux/nvme.h b/include/linux/nvme.h index 2dc05b1c3283..a7b8bcef20fb 100644 --- a/include/linux/nvme.h +++ b/include/linux/nvme.h @@ -806,6 +806,8 @@ enum { }; enum { + NVME_AER_ERROR_INVALID_DB_REG = 0x00, + NVME_AER_ERROR_INVALID_DB_VALUE = 0x01, NVME_AER_ERROR_PERSIST_INT_ERR = 0x03, }; From patchwork Thu Mar 13 05:18:04 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Mike Christie X-Patchwork-Id: 14014341 Received: from mx0b-00069f02.pphosted.com (mx0b-00069f02.pphosted.com [205.220.177.32]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 4284B1D5CDE for ; Thu, 13 Mar 2025 05:22:46 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=fail smtp.client-ip=205.220.177.32 ARC-Seal: i=2; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1741843370; cv=fail; b=I7gua2URa2EnEOYx8uKFx4IBYw59LbQ6no1R1CYO/Dk06GT/cTzgUnvL4828IIoRv6ETkgsXFtBCN3/ut8rbdbBszIj5GxEI8ELSPw4FPCfCuCjuOry5g4YuRvXN+tz7Wi3ROufIAgOYASCol7oJuUl4BRE3Hb6NU3YWlHJMhxA= ARC-Message-Signature: i=2; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1741843370; c=relaxed/simple; bh=HFhZx+GqvP0TlkRrQYFVYTtHlZpasAABhLaeglYRCcc=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: Content-Type:MIME-Version; b=qn0aSM50Vc9xK3IAKC0KKxb8BYt98NbcrLsqIeg3QpWUcXYG9yFVgKKvAcnJ7yADL83eahpxJrRF/h0g33TY/gYuS/niFSM6ZcIuqkapwISUuYmZ/VgSFbfkIiELqeuVgVO+oFQ9XOndpT6TmSYHre7brlEQ170bM0CwdfkJiD4= ARC-Authentication-Results: i=2; smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=oracle.com; spf=pass smtp.mailfrom=oracle.com; dkim=pass (2048-bit key) header.d=oracle.com header.i=@oracle.com header.b=ZBit9rvl; dkim=pass (1024-bit key) header.d=oracle.onmicrosoft.com header.i=@oracle.onmicrosoft.com header.b=PwcZeefz; arc=fail smtp.client-ip=205.220.177.32 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=oracle.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=oracle.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=oracle.com header.i=@oracle.com header.b="ZBit9rvl"; dkim=pass (1024-bit key) header.d=oracle.onmicrosoft.com header.i=@oracle.onmicrosoft.com header.b="PwcZeefz" Received: from pps.filterd (m0333520.ppops.net [127.0.0.1]) by mx0b-00069f02.pphosted.com (8.18.1.2/8.18.1.2) with ESMTP id 52D3tjGr008203; Thu, 13 Mar 2025 05:22:33 GMT DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=oracle.com; h=cc :content-transfer-encoding:content-type:date:from:in-reply-to :message-id:mime-version:references:subject:to; s= corp-2023-11-20; bh=1ZZ0IZCL1f7yGfGrQOrKQnJntnKYkDGedUQ3OPYpeJM=; b= ZBit9rvlqBQBWdqYUxDLHynPOOUXrTMt2QjOS9m1bxvqlji3GzsQewcGLMrRfn0a 42yNtCA8jsENtNUTPdMLMsRKYwkCGM7DebgiaZghtgkW+8IBYkkmZReWb5IHNFQn lSZV5cjdIWXWmfDDXWnBZWC8O5vAEjQ/q1y4cb9/zrOpq9bXS2+L2fYt4Uf3I7YM +a7DWoO0mvavBtACeEH4LGoq4jMirFKFGM3IOeImiQ38b6dVWVKMyKAgBhjBf8Pc 30CErXKy/fCG9oGVsayTfbhXtGEDhK0tpRUq3yYBp3KvocMqqr7nkRSYEeQHBMhQ 5ZeBGGhWnJ+w47uKsmPtnw== Received: from phxpaimrmta02.imrmtpd1.prodappphxaev1.oraclevcn.com (phxpaimrmta02.appoci.oracle.com [147.154.114.232]) by mx0b-00069f02.pphosted.com (PPS) with ESMTPS id 45au4duffc-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=OK); Thu, 13 Mar 2025 05:22:33 +0000 (GMT) Received: from pps.filterd (phxpaimrmta02.imrmtpd1.prodappphxaev1.oraclevcn.com [127.0.0.1]) by phxpaimrmta02.imrmtpd1.prodappphxaev1.oraclevcn.com (8.18.1.2/8.18.1.2) with ESMTP id 52D4RGLc022384; Thu, 13 Mar 2025 05:22:32 GMT Received: from nam10-dm6-obe.outbound.protection.outlook.com (mail-dm6nam10lp2041.outbound.protection.outlook.com [104.47.58.41]) by phxpaimrmta02.imrmtpd1.prodappphxaev1.oraclevcn.com (PPS) with ESMTPS id 45atmw5mpy-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=OK); Thu, 13 Mar 2025 05:22:32 +0000 ARC-Seal: i=1; a=rsa-sha256; s=arcselector10001; d=microsoft.com; cv=none; b=UsMmXEHeOWgnjALvi3Vw6cV18ZImoqZj5y+/XulTnY+iDDXeu7oXzOSPphzI41el5TzLM94P9IW7891wzdma1uqi9/7Ea5/cUue144SVC1Diga3MUI20lD+SJPjOyoir7447Og4f1Wk1nT4ejGoCQgLaNxNna3cKallc8s8m+ZzpE0nH8O3ICLX7rNg5/6uKvDZGVoFeqJFPBNrZ0wfQEqSMblKkerH4Olu6Sgr30wViKuSBBvEF7lfAAvGyHHn8o9YgNqY9rOhvDJlQ0ksi1s9Vph2vIFUuCT4sJAPcGXw8m+wrdR70MBQJmIs1d5A8LVUkoMrczDMc2IyTstfZWw== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=microsoft.com; s=arcselector10001; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-AntiSpam-MessageData-ChunkCount:X-MS-Exchange-AntiSpam-MessageData-0:X-MS-Exchange-AntiSpam-MessageData-1; bh=1ZZ0IZCL1f7yGfGrQOrKQnJntnKYkDGedUQ3OPYpeJM=; b=d3lTY9oIpq+fvoOnTGG3dWbpe51leYOpDDZHRBOAISozY/VPBjGehJAYUdRXozIR7E9JKP1WAL5piouxDpTZ+gGBlLXL8MQt9JVey3tyClhHgi0GzN9NfhTldNwy6s6GZQIEUppCOvrJS6sEmAm/D5dW04IjM40viGpfpuK2XgYggPHzHEZcCws+XL3YWBDus8ROLLNw6VK7kdJjCTWwz78Y00B6xOuIvFiYpTUi5pUB/T/GnjUWd7sODDmF+DpVTZlhKV1cz5atG/AIu2tNJOVurFWiEmFj2ujzMbQiDqtUREYoP8CxvYkjTCUfg7cEFNgN1fLFCrDYcIFC387O5g== ARC-Authentication-Results: i=1; mx.microsoft.com 1; spf=pass smtp.mailfrom=oracle.com; dmarc=pass action=none header.from=oracle.com; dkim=pass header.d=oracle.com; arc=none DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=oracle.onmicrosoft.com; s=selector2-oracle-onmicrosoft-com; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck; bh=1ZZ0IZCL1f7yGfGrQOrKQnJntnKYkDGedUQ3OPYpeJM=; b=PwcZeefzQJGmAXHkmoIiAG9tEbE0lKcnz+GR3KChfNG8kegonSrNciPGSGx1Lmvhmn9F2EZtQapfFXkqNOqWAUtDmhfmYNCipHBY4gz1YRedHUJdiDPCNxsUYaJPiAc+LNf0LVo7s1HwMu3YqQdQCevbVaES4ARcaDewsahkTrM= Received: from CY8PR10MB7243.namprd10.prod.outlook.com (2603:10b6:930:7c::10) by IA0PR10MB6724.namprd10.prod.outlook.com (2603:10b6:208:43e::5) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.8511.27; Thu, 13 Mar 2025 05:22:30 +0000 Received: from CY8PR10MB7243.namprd10.prod.outlook.com ([fe80::b779:d0be:9e3a:34f0]) by CY8PR10MB7243.namprd10.prod.outlook.com ([fe80::b779:d0be:9e3a:34f0%4]) with mapi id 15.20.8511.026; Thu, 13 Mar 2025 05:22:29 +0000 From: Mike Christie To: chaitanyak@nvidia.com, kbusch@kernel.org, hch@lst.de, sagi@grimberg.me, joao.m.martins@oracle.com, linux-nvme@lists.infradead.org, kvm@vger.kernel.org, kwankhede@nvidia.com, alex.williamson@redhat.com, mlevitsk@redhat.com Cc: Mike Christie Subject: [PATCH RFC 03/11] nvmet: Add nvmet_fabrics_ops flag to indicate SGLs not supported Date: Thu, 13 Mar 2025 00:18:04 -0500 Message-ID: <20250313052222.178524-4-michael.christie@oracle.com> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20250313052222.178524-1-michael.christie@oracle.com> References: <20250313052222.178524-1-michael.christie@oracle.com> X-ClientProxiedBy: CH0PR13CA0012.namprd13.prod.outlook.com (2603:10b6:610:b1::17) To CY8PR10MB7243.namprd10.prod.outlook.com (2603:10b6:930:7c::10) Precedence: bulk X-Mailing-List: kvm@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 X-MS-PublicTrafficType: Email X-MS-TrafficTypeDiagnostic: CY8PR10MB7243:EE_|IA0PR10MB6724:EE_ X-MS-Office365-Filtering-Correlation-Id: a1baa92c-73aa-4239-ca59-08dd61ef0cf0 X-MS-Exchange-SenderADCheck: 1 X-MS-Exchange-AntiSpam-Relay: 0 X-Microsoft-Antispam: BCL:0;ARA:13230040|376014|366016|1800799024|921020; X-Microsoft-Antispam-Message-Info: 7bhBDHF/mp82v+b72ERQwI0yooNOn6brD7IjVqJ/6x6bQIZSpoh1tnkdeYNeBTOMXm0oLZt1WgLHdVesNlsTUSQ/97Rh1FNY54y2BQSuhErti8VdzT5+xWY5pHaJt3D5U8vcd/AgC2i13gZNZMFwyz2BnOt4eCGt0uz6/ZmoVbe4SgTTZVKKbwfPdeRVp7JaZDyTRtuTt62tdh6ptkQx0x14dbStpoX926anzSIYLuctlxfLWEExulkh5PjNAocgXrTxAM1Y56VeXipYATVPIOoEvLhaRIhXQTGka4zXsOYSbFqLft/3emN/WyLxmdNjbqDLZhUSCimMAYL31qghim1gCY9jpDZh9RrDsAFoN4+1Zt9oEKkazWHHd5xivm/0Yc7Bnm73ETbL6v4FKD7Dhs1K6mhpOqaaW9a/mhktZobEts6euSH3eFqG4psVAcRRe6FutR60NLcWbDmzGE199oRVE7zfBvyvDdMlnibEOH2BiATIm8O49Zt7HQxzT08J3YOgJVItVOfHQF/1uYpZ+eU8lwNkbQkvIeOfvRmpqPVBJPTnHMlY5HQnMpphohx/Ab6KCq8zBkJ6LhSTIpLyaUPdnPBWJioOx6LwCZD7XAblT6yZTONd+Qk1cBw1vOfTUBNxTuLHD0yQ5YYjGbNo4KhkCNocEW1wYk1Sj8ai3VyTkzbJeOB4dfE6PqX9FVqQzJtBNWOzVjanD4WrfWgYMJn+MBAXlwGheO1AdfgQynrsBKN59nQY1lv7qWSszjliFGtNPRI0dyt/2YgV77dYSRugf7ocxj/6MMayxp50M/+Q+jaVJFw+mGSY3uwPROTlC9orHZ7mQFEjrEuJXKTTkO43vAxof/12o54QCMH48ggmZD8m6pfyVjtr2P5jqr7UVczICPeijn7VgNxko9lwbrOC/2azpti1dQQrtLOY7wi9Jqhh9webgbAghajFjeTvAM3sRl/7aa8/j8Ps1nL4eV8wGd9mMsEq+2IlIvcydpM6Glmt7RBYfK671vdJHPDQbPC6EYCq9Wz78lNw6vCFAvZvVMz4IXNbLiIc3uynM3WG+mxLXMJGw0Tc+yGKIaztHY7Nk6GBmVglLsi2f/4FJm4NOPe6F6q38OA5rENxsKZov+rFpV1yNfD3lEDp2CTgeqlPGaZ9EzzIvreEZZqILLA75NvdWlMHZKm0Y1S+F1zgEx0RObwCKpPgFyuoKSoe5pQS3aDTYNrGe3RN70epLagMAhqUqZZthEWizTr3Fpv+Cc+QD3N2q+1Knr5nkzvFB4TpsDzIqbICW9l1KYK+wnP3MDIKXur0cdMuXPpIHirc1HpBswdw7qJn25A2rzTn/r15n31JK9nzbdC/cHmGiAzXA4T+8ypRS36aNpmu8oZkWvMcCNewICxKxk/CKWyzX4aOQ6eBzSayvECWcosW5VM9soy8D3atsUSz3s48Gbs= X-Forefront-Antispam-Report: CIP:255.255.255.255;CTRY:;LANG:en;SCL:1;SRV:;IPV:NLI;SFV:NSPM;H:CY8PR10MB7243.namprd10.prod.outlook.com;PTR:;CAT:NONE;SFS:(13230040)(376014)(366016)(1800799024)(921020);DIR:OUT;SFP:1101; X-MS-Exchange-AntiSpam-MessageData-ChunkCount: 1 X-MS-Exchange-AntiSpam-MessageData-0: XfZPkBQVlDBlSuRePhL+9rVZs891eM1IF4AMqiVbehWzvyT3Yatbd3grCw0/FD3h6WH0XZUfO04ZH89RC5rALRVHUJizdUCH0NvACMEoY9sCWx+tSmPUAAnM0YbeyhH8ZNE0vFJ3FBzlTfGYzLBC81QSA9B3oEXbfPmBo/gX+HnL/GQAaBwL8jPdW8NHmMmgI7b4Mv7a8S8WzPQz685v0uNiK9VBDZnd9VEAJ5ErMkzB2qn3bjcEhdzhsI/X4su97o/QVJoUDwahdddtOdjloGU/yvgYuQO1fc0ASl/qdEBzXlSTMMZMYGIsLQe0N1SJLWDdbc9FFSECM49kbY0Dk4vhGKQRnSc96r75FBL6mz1XQ1R6MxjCG1gR6Tv4tI6rnNcntIqIu/sRHC9I07SD94MhfC/TVDIU8S1sa74ZjjEWCX9G8r+NbVXtsPiGDgU5BPupbns7+mM8fsMEuC3FfvC7uqDa8dCZH1UYyST7uM71K80eRHAY+oh4t4AZti71IJSpzZNUPMOvSUh3wyqg/v7/NwKoZkTjlwg1r4/vsKbKpW9TUdRK2ntZW7L4VTYJTRGpkbLXUpVlZxyHCWpYH24EgS6nhJOLfvm5XdNpfVWDRdJVNvbQ2C1bn0i2d3TcHSPXEGB3qTtvHrtZdXEv3nRy02PrM0pwU1heRlwndTh3W7hca+9d+mE9x1cItOQXkxJpdILTfGJSdBjChytWSX7MIiTC4TmKLWj8Pd2ILKDxu9Ul8oT6XKgtsufAAzITB0oIVIFs34tSU50T6P0az5CD6e2JCssriNQiDmG9VCA6TPtOLJ1yxUHkCLH9gWs5lULGaFkUG6faAGBsgLn1PsfbByTuetOZBtdCiBVjJIalwV329/tdg8ETevsmKZ/mKEaLLIW5w6isPXiMjlqLBOGq0X12lQOYlx8XdNCyGYp3RKaYoAhUfVKviYNTXWXo3RxBHK4zFNYK4Fwx/GQQFifM2Zw7edtPGDl2FXnKS095pKZLUKIh+jNqMU+1Y0KPkmwl8VOB2DbgLOSgn1JIt353pq2FDF2USgYKoNXEh8F+SHrTfN69s7cT3Av/v3aN1ZsaffXIPF6LZsnVT0HZAEd5pp6muVRC4taGoTmMCAHrQygWy6kRyk/gOM89vlw61yDOGjCcrmIxD1Z+OAyM+fYuSEFCF/v66TBrsNFWXk67o4EzeOHe6NrLzKwMbdIV2KQT7F8kXkz33cFNC9zpkV4BeMWdl+CUsQzmt+mXEdqRSEf5fVAOLOzRvdp+ikWGNqJwDTJXaM3lGGwPRW8iCy8RZN9lzxzdJ99DbKhtJk4UhOGw8Ruwc6/3E7ukQ9KB5+MxmTvTn8VUWSPz6u6HzjBWWCikeoXl3UNkbu8RiibUgcoznv9AzrYQPQrC+yaFg5tXCeGGGlvswlYvMtZuW5C2XSlENIozYcEspVZ02Z3oBUfeg6r3/JQBFiSjB+Q4ewC9f47A8BSrToU8rVUQmUJnGJxb/FB9D1ukwe61UCHO6vsBcNPgbfrIpGWXsThsIKYgEYRowu9IWW5vXaKFw1/Fonm2Ffo+Bo+dDA8XXFPFd+vVxq76tFQB/b7EiuZSuJvRzrZduFadYrr8Fh9dCg== X-MS-Exchange-AntiSpam-ExternalHop-MessageData-ChunkCount: 1 X-MS-Exchange-AntiSpam-ExternalHop-MessageData-0: bNclBdoLqpjavORqnRCSJB2HgwLfrNIgJjwf/eyPFNhg0pPE4RJIaNQWYL8qkRwFN7ZyW8ITCZSVhWO2ihcgSeULizaQdESgpPQNYXA4lho41UK4RP72SBu53MccP2FYYhU5K/L+H6hMhHrxY3Colnsxomi0JCsz3kTwsY1ogSH37MXsbPOGwfxDYiyiK1mYVtqkGVH9MHU+r0LGzL6qOwqcPnsduxG5onFaHGpDA9ZlhPh3PTTDm2Fa5JQEzBxS/Yjef7To21PRJO+mD5q1pg0j3YXmAlOU5qLZiZVVbMRbVJ8fUzBaKkZ/gFRtcIzZ0M83zUX2gL4bbfAlJIzfLg2lYAJlZH9Lft729ztE1ZJc87nfGObxP4QkX1sm9+6/AlkageVvi7c3aMrekxVfPSqKnNrTyqCXBcuA7cZp5ZMaTdD0sfpA/6BcTYO2yosAXaG1TaLnC2Mw1gGlT1GgUw9fwXZA7644kTpq76FG/wviqzaeINzrhgdQhAf+NNfG1tdI/KUdj6W/zVvoytXHOqnq6991hi06gByl8stSzYBJ0bPtiRbfeYFuKSMWJs2g9AwoH2Y91xQYtX8PE7LprNIEHE3TXy/kRhqFUmUyJkI= X-OriginatorOrg: oracle.com X-MS-Exchange-CrossTenant-Network-Message-Id: a1baa92c-73aa-4239-ca59-08dd61ef0cf0 X-MS-Exchange-CrossTenant-AuthSource: CY8PR10MB7243.namprd10.prod.outlook.com X-MS-Exchange-CrossTenant-AuthAs: Internal X-MS-Exchange-CrossTenant-OriginalArrivalTime: 13 Mar 2025 05:22:29.9494 (UTC) X-MS-Exchange-CrossTenant-FromEntityHeader: Hosted X-MS-Exchange-CrossTenant-Id: 4e2c6054-71cb-48f1-bd6c-3a9705aca71b X-MS-Exchange-CrossTenant-MailboxType: HOSTED X-MS-Exchange-CrossTenant-UserPrincipalName: 99/MjLhAJe5Q8dCI2YdFSk7vJmvW66Nwx9cfoEc2Zp8K0gLl3SB+D8jZFKJ14BzFpM3WbnLkiawJabLRY06mvgXhE3h4XbNOdhC3oflX40c= X-MS-Exchange-Transport-CrossTenantHeadersStamped: IA0PR10MB6724 X-Proofpoint-Virus-Version: vendor=baseguard engine=ICAP:2.0.293,Aquarius:18.0.1093,Hydra:6.0.680,FMLib:17.12.68.34 definitions=2025-03-13_02,2025-03-11_02,2024-11-22_01 X-Proofpoint-Spam-Details: rule=notspam policy=default score=0 malwarescore=0 phishscore=0 mlxscore=0 spamscore=0 mlxlogscore=999 bulkscore=0 adultscore=0 suspectscore=0 classifier=spam adjust=0 reason=mlx scancount=1 engine=8.12.0-2502280000 definitions=main-2503130040 X-Proofpoint-ORIG-GUID: 8QU0jSUWpEU1ruOegEw8jGFCnz43NgtW X-Proofpoint-GUID: 8QU0jSUWpEU1ruOegEw8jGFCnz43NgtW The nvmet_mdev_pci driver does not initially support SGLs. In some prelim testing I don't think there will be a perf gain (the virt related interface may be the major bottleneck so I may not notice) so I wasn't sure if they will be required/needed. This adds a nvmet_fabrics_ops flag so we can tell nvmet core to tell the host we do not supports SGLS. Signed-off-by: Mike Christie --- drivers/nvme/target/admin-cmd.c | 13 +++++++------ drivers/nvme/target/nvmet.h | 1 + 2 files changed, 8 insertions(+), 6 deletions(-) diff --git a/drivers/nvme/target/admin-cmd.c b/drivers/nvme/target/admin-cmd.c index acc138bbf8f2..486ed6f7b717 100644 --- a/drivers/nvme/target/admin-cmd.c +++ b/drivers/nvme/target/admin-cmd.c @@ -755,12 +755,13 @@ static void nvmet_execute_identify_ctrl(struct nvmet_req *req) id->awun = 0; id->awupf = 0; - /* we always support SGLs */ - id->sgls = cpu_to_le32(NVME_CTRL_SGLS_BYTE_ALIGNED); - if (ctrl->ops->flags & NVMF_KEYED_SGLS) - id->sgls |= cpu_to_le32(NVME_CTRL_SGLS_KSDBDS); - if (req->port->inline_data_size) - id->sgls |= cpu_to_le32(NVME_CTRL_SGLS_SAOS); + if (!(ctrl->ops->flags & NVMF_SGLS_NOT_SUPP)) { + id->sgls = cpu_to_le32(NVME_CTRL_SGLS_BYTE_ALIGNED); + if (ctrl->ops->flags & NVMF_KEYED_SGLS) + id->sgls |= cpu_to_le32(NVME_CTRL_SGLS_KSDBDS); + if (req->port->inline_data_size) + id->sgls |= cpu_to_le32(NVME_CTRL_SGLS_SAOS); + } strscpy(id->subnqn, ctrl->subsys->subsysnqn, sizeof(id->subnqn)); diff --git a/drivers/nvme/target/nvmet.h b/drivers/nvme/target/nvmet.h index fcf4f460dc9a..ec3d10eb316a 100644 --- a/drivers/nvme/target/nvmet.h +++ b/drivers/nvme/target/nvmet.h @@ -403,6 +403,7 @@ struct nvmet_fabrics_ops { unsigned int flags; #define NVMF_KEYED_SGLS (1 << 0) #define NVMF_METADATA_SUPPORTED (1 << 1) +#define NVMF_SGLS_NOT_SUPP (1 << 2) void (*queue_response)(struct nvmet_req *req); int (*add_port)(struct nvmet_port *port); void (*remove_port)(struct nvmet_port *port); From patchwork Thu Mar 13 05:18:05 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Mike Christie X-Patchwork-Id: 14014340 Received: from mx0a-00069f02.pphosted.com (mx0a-00069f02.pphosted.com [205.220.165.32]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id B560C1F9A85 for ; Thu, 13 Mar 2025 05:22:48 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=fail smtp.client-ip=205.220.165.32 ARC-Seal: i=2; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1741843370; cv=fail; b=axeaMkmSG9vn3y6spGuniNOkS++93YIPt9zgmblSgvGTh01ExhV0nOFfZtZ/m4jH/lKAjH2jhB23Ah/ZsLgYwFwpjjm7h+cVlOd4+W3HxmhVqmHQSlEXtcxezcHfH5/nr7OR6EmE3VV7GPez8BaKCxSCW7xnhuJ7VoDFyAxpVlA= ARC-Message-Signature: i=2; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1741843370; c=relaxed/simple; bh=UD+6E6JjGudSURNrzU/E7g5eN8sOh0vGHjkXR098sDo=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: Content-Type:MIME-Version; b=kj7FFvv3odSDWauMvlF/HbgjIu9YI/bS4S6epvq0NxO6b8NwkAmCZp2ithM/WQqnrMGl/AwyDyuGOBtsYeka+OWOgIyVTCptSuNlZcwa1sIqmaJPHvgXOy+lmgDVJwcMgjel4ytJKDa9iTbsmEEHAlMtK6xxRztrPEsOrVweoWo= ARC-Authentication-Results: i=2; smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=oracle.com; spf=pass smtp.mailfrom=oracle.com; dkim=pass (2048-bit key) header.d=oracle.com header.i=@oracle.com header.b=CaPK5HaR; dkim=pass (1024-bit key) header.d=oracle.onmicrosoft.com header.i=@oracle.onmicrosoft.com header.b=IVE7js5U; arc=fail smtp.client-ip=205.220.165.32 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=oracle.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=oracle.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=oracle.com header.i=@oracle.com header.b="CaPK5HaR"; dkim=pass (1024-bit key) header.d=oracle.onmicrosoft.com header.i=@oracle.onmicrosoft.com header.b="IVE7js5U" Received: from pps.filterd (m0246627.ppops.net [127.0.0.1]) by mx0b-00069f02.pphosted.com (8.18.1.2/8.18.1.2) with ESMTP id 52D3uISq019090; Thu, 13 Mar 2025 05:22:35 GMT DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=oracle.com; h=cc :content-transfer-encoding:content-type:date:from:in-reply-to :message-id:mime-version:references:subject:to; s= corp-2023-11-20; bh=y9Wn79rLekMEBO8c+SuIr7jFk1qrAJ0CweOE0hPYT+E=; b= CaPK5HaRbgxT838GKbdO9odfsUiwCPJTO40EEDZoleeyFHrsV2aQ68i5gsLQZa+A n+RzQjzH9jAgQB1u7IjLXc8go8+BPsJ9sJskeArRzfiFT67ZgGzeA0XKiNMU5IsL EhJlSBDPOCrs9Z5+xniFYWf2OlNpUhSzSGwHtNGrATZdLvSNFO36Ou+52pLcQ1IX 4OiHpSAf7Z28nXGGEnwEgdmU8FuhusMiHrwGF4u48PVFfewZb7y7If5G2Nu9h2WN 8w6+J7/2GBM0YAZ/44rQyyxzj0SlMTlE1Dz3Zgm7ybaMz7FzBMWL/Hwmuz3FGRAP cHBLOkdoX3QVMIKtZn4XoA== Received: from iadpaimrmta01.imrmtpd1.prodappiadaev1.oraclevcn.com (iadpaimrmta01.appoci.oracle.com [130.35.100.223]) by mx0b-00069f02.pphosted.com (PPS) with ESMTPS id 45au6vkes2-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=OK); Thu, 13 Mar 2025 05:22:34 +0000 (GMT) Received: from pps.filterd (iadpaimrmta01.imrmtpd1.prodappiadaev1.oraclevcn.com [127.0.0.1]) by iadpaimrmta01.imrmtpd1.prodappiadaev1.oraclevcn.com (8.18.1.2/8.18.1.2) with ESMTP id 52D4jrOb012313; Thu, 13 Mar 2025 05:22:33 GMT Received: from nam10-dm6-obe.outbound.protection.outlook.com (mail-dm6nam10lp2046.outbound.protection.outlook.com [104.47.58.46]) by iadpaimrmta01.imrmtpd1.prodappiadaev1.oraclevcn.com (PPS) with ESMTPS id 45atn272ny-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=OK); Thu, 13 Mar 2025 05:22:33 +0000 ARC-Seal: i=1; a=rsa-sha256; s=arcselector10001; d=microsoft.com; cv=none; b=t7FLjtIIi2h67/dK7SzN7n8q+Pp3XWELn0ow2fMifoPjsQsQX62+3U2LRTQS2QW6zwhmiMVPntFg7sjR1SfsQBf7THUL/n/mG9zYeLshdrpRRI19487VrLv+AkPLAw7CNnwvnlpQ7MC2qNP7+wXl09EtckCJeAmUEfCaW3+OGQkWxZlqlwBU92n+lEuJJUuh7DEzFdC6fWXf7atoj66bNErs8Y9y+fcuLEnAg8yKg57mM1cJy4HfyC0O1LeGNO7PHjwNTSgaPz7nnd2rOnDDNZxn0BY5lH7ZKZ+c1S2lCl7kniiXRHgvSifzxWndwspB5Md8UGnVx2u5fyc1Fi+kFA== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=microsoft.com; s=arcselector10001; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-AntiSpam-MessageData-ChunkCount:X-MS-Exchange-AntiSpam-MessageData-0:X-MS-Exchange-AntiSpam-MessageData-1; bh=y9Wn79rLekMEBO8c+SuIr7jFk1qrAJ0CweOE0hPYT+E=; b=RY4wfj/s64jH5v9fWnh1eJh5NjaRr1ClucUE1SstQOsaegiAQE1N84Zy0aopAIIBS3boLaJHnWNdVrG+gi8JeaQy0+7I0/TOiX48fnEDrNNFKvmHP0knA8TNTK055RnHIXR21ExKJLLlrrReWVIXVqLefdbt1oAW0RgZ6VH3alhS5JUM+OeYW+/o8X3O9kNlEq89ZbN6tIb54jjxl3Vbo+A+XgxDzB9rYqPgw46pizefuuTsWWZtjP2flNXkrGGxt6hNj7hvtTKpWFQLKRDgSXsvIbQoc+rQtDhLICzDlCVxBcavbChg3saj5itBcsTcNVqmf64lVZ1DEc1MZ5MfqQ== ARC-Authentication-Results: i=1; mx.microsoft.com 1; spf=pass smtp.mailfrom=oracle.com; dmarc=pass action=none header.from=oracle.com; dkim=pass header.d=oracle.com; arc=none DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=oracle.onmicrosoft.com; s=selector2-oracle-onmicrosoft-com; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck; bh=y9Wn79rLekMEBO8c+SuIr7jFk1qrAJ0CweOE0hPYT+E=; b=IVE7js5UEcvuFBMKk6Aanwkw+DKetggwF4RtWwSgXdxB7swNDd7J3RHHDT5Ol2OrF1u8x9vpQMuQ7Dn7eEuc2eCjChGpntjwJOw3FJL5VFfh6Q8CZ3mKb4aCptV8RLF2EHasMffwpiunnPZQSW0FsXRl2Xnojt036jYjdjRiDtY= Received: from CY8PR10MB7243.namprd10.prod.outlook.com (2603:10b6:930:7c::10) by IA0PR10MB6724.namprd10.prod.outlook.com (2603:10b6:208:43e::5) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.8511.27; Thu, 13 Mar 2025 05:22:31 +0000 Received: from CY8PR10MB7243.namprd10.prod.outlook.com ([fe80::b779:d0be:9e3a:34f0]) by CY8PR10MB7243.namprd10.prod.outlook.com ([fe80::b779:d0be:9e3a:34f0%4]) with mapi id 15.20.8511.026; Thu, 13 Mar 2025 05:22:31 +0000 From: Mike Christie To: chaitanyak@nvidia.com, kbusch@kernel.org, hch@lst.de, sagi@grimberg.me, joao.m.martins@oracle.com, linux-nvme@lists.infradead.org, kvm@vger.kernel.org, kwankhede@nvidia.com, alex.williamson@redhat.com, mlevitsk@redhat.com Cc: Mike Christie Subject: [PATCH RFC 04/11] nvmet: Add function to get nvmet_fabrics_ops from trtype Date: Thu, 13 Mar 2025 00:18:05 -0500 Message-ID: <20250313052222.178524-5-michael.christie@oracle.com> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20250313052222.178524-1-michael.christie@oracle.com> References: <20250313052222.178524-1-michael.christie@oracle.com> X-ClientProxiedBy: CH2PR12CA0028.namprd12.prod.outlook.com (2603:10b6:610:57::38) To CY8PR10MB7243.namprd10.prod.outlook.com (2603:10b6:930:7c::10) Precedence: bulk X-Mailing-List: kvm@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 X-MS-PublicTrafficType: Email X-MS-TrafficTypeDiagnostic: CY8PR10MB7243:EE_|IA0PR10MB6724:EE_ X-MS-Office365-Filtering-Correlation-Id: 6a9db3d6-15e2-409d-b8fe-08dd61ef0de3 X-MS-Exchange-SenderADCheck: 1 X-MS-Exchange-AntiSpam-Relay: 0 X-Microsoft-Antispam: BCL:0;ARA:13230040|376014|366016|1800799024|921020; X-Microsoft-Antispam-Message-Info: +hvHznkCWM3SC3P68okzXCtCmj2FRmxhun5L3WhHgQh5h3aYN/NPvA9A3Zof8vldBBPyHIdf2ZoQkENjXDPLGYH7enaqPqr4/opax6mrd2buy/8wwunbU+RFKquJoIw9pDcV6TO0304K07Qjr43vBZ0hTYL9d1sZF1ihrYHiCp8tB9XzNSgIjRnueJ/GxzmcGGVcoxMcfqVvADfU51uI6BImESBEVNfqRpTkDKF/QwiORd/+0JPTaVYeYmTqMxWA1XTjY4PJQ10Aza7uZzAFocO6WJoSxfH7hE3MUNBAz4LRnCrBSrJ7JChIhnBQr+1Ckjmk5231AGTN+3aBi4TOFU+bjJbV2EARj/odXk1Y29pJu2bqnE6zx8J1RrLQ30L6M82hfVk8OZrLh4pVlc8ddY0Ua5adDY0GMPyu9j3VTF6QUO7d6sN69THhJwMrGKcfDa/0H2FtFxYRHvntdpXJswrxXaTRLGaM9DpFJVOqgnrHowjZFd9OHQvymjYDMvvo3V8ayRpXfJfYy3WgoOj37EshFPmMpmtu2x8wmq4YrTN46GyCcAG4Mh56NtCIw4NRH13YSLe2+LJMWzwYSj+faqqhxCLlCmLLutQdJqPUgXtcchHdM7/ubZo0dJj879mZ6vZ4n9wyBC5Og+tf+lNHosX8OJMRhDRQRN97ImJPldasNnyhaWMiQt3vAReCkmw9vhguwe3fI3ONM/BUtQfUrpb0x3amHqJY7l5fSpL7MzK19reHuxcQSjdwHa89+6eML7NE5rcWw6J4UQSiAlUG9NRATrn/I4CM7X2k+8juMKRsosoRJkX0mG35U1zzs5GjiMZqJFTKtjcfPuuqGgbqA3BvqfeGogstvbG1Yt3bozM20QhdH0hAvMJ3GulwmkzKlcui2KK8bKxz/Kch2YH3XxGS/l5Pq8RlHs/KRMhgh41XM0prNrhgWS0tomTOeZpCTaa5+fDoilw3gwa4V1TI5AwDrJZisnheVp9/5fHcAaWbQBRGqBJeNO6hWTkI6y5FlugDpTSxe5vXCMG42If8NF5Ma36z2G5YylZq5R977yy0jC0YsSTWPNMrf3CNUdIUdcqSsCahFSPNI6BLLeBLjP7+cSNxmui9dvhkcUnNnxZJwMgWHZ/uWCpzTJnjOjK0hThoOhrVfEzsGiWOji6dQW/xfrbeR28bzCAV8NhXTdfnhTyhABxaqRqKRZ5PadPqjibQGyVj02FhzI+x7VS+CLvUm69kBhxLLHth+Te32ved/o8pMOgspazk69TV5MvyOfifa6NUIt8/vTXKzQDeSJM0CjahCbuDbTLFh01gGB6QPZnHwB64urES/mMPysJwy+8LsUeKWbii1g3K0cCW0ob+mM9kCNSo8YTfiw76QrkvDkS/V3SGo9UwGs3GNe2rcz6WZFaJSfLlOU5HNaFlnqLm3T5PNN75Nc9KWtEdMws= X-Forefront-Antispam-Report: CIP:255.255.255.255;CTRY:;LANG:en;SCL:1;SRV:;IPV:NLI;SFV:NSPM;H:CY8PR10MB7243.namprd10.prod.outlook.com;PTR:;CAT:NONE;SFS:(13230040)(376014)(366016)(1800799024)(921020);DIR:OUT;SFP:1101; X-MS-Exchange-AntiSpam-MessageData-ChunkCount: 1 X-MS-Exchange-AntiSpam-MessageData-0: UOLaxUN9P1+qtCHdUbUz4pwXP4+SEt15troFiH0xHOQ6mAUdmaoFndNTIbIK/rxOZpjy1MfEcn9PmvQwjFMCa736ZFHzVvJZ6QCA94CKlvqhQViRbdDxg4vF3Yp0H7PiBRnEcz3tvTeKroNlLvh4IJF6L7Nx5uLrbR5AXxXnZlKbBu7Vke7o+6p/74HlihouaE7vclqKfRUP/TacLtGNrhkXtumIrQNeoxY2hPKmidRQMUBw3IA3NTCXLJfv+LOHbRb71udDhyMkvdz9GAWpgUd7PwW8kHiJBsaXlsalTa9yJAGSzHBoSwZDcLrrzQTcc3FYwGwxk/eMwMtGR8cL9gON3jztOVQUA1JKKRShk+fPOYYcy/l3fz1LNkxFiJ2El1ca/vrCQNuqTIKFCD/i/qNIqYpoOGNX2qGjMWXA4vHbFaSOqGOtoA9vKsJjegTAmxxFo1uWd1mO4i1Y9U8jjU1KO6kCVU+vqxuGDJltJ9O4+dAvb8bfEFWF9kyZlmxvSH99Bew47PKP/NRM2HmwmNpXDCSKd+5Mpkhwn2Nk1nhhN93DyZIWscgVM7FvdELPawQBD/UqAKZXTIHGeufP53pQDyftVM5UeoLwMthoU0cblblFZgFEVh3S7TY0DXzqIysu4bY/S/UkNK3ODfsPRZh6tpsz9sJyasvxSWuGvIyLFjSiWqlgHg/p+MlahL2eUOLULATzNGWphTTcVOqBPNBjOEELj20x0TJesObgU6EWvaSbS/lvH5GMnpRYz7xZHWL7qXjJa+2ssLwkCu5CMJY5d8SLmS0T8nEWkf37kEuYh/0NIZR6QLS/RDJBsNQToqxGUorRFcAK3o3Rwk6b9kiqoniwGtQS8n1p+qHTD1tyEnEQj9f6y8SR6bQDyAispSEikOdh3kfm5NiQXzqbg3QLsiGXMu0qreBZKHdlp/YieI0RXKLJQb+GTrtF7S37SyUDOmJMiFin68eCohGGUI0/KiMszou9kAWAfXMoezwbWbRpU5EcLJe2jBZdIys+yqKs8lxtiM9U7s1lOw/l3CbqZUIBLRlkfxeuQyUmCOqUjeZaSFdpJsZrxx5xS5nack/l4sJTze8TFT/t8Nw8Ys8JUajKQkRBw8kOziDYNowjsWRMdY4DIkDn6KO9PE6CVlz6WKxe7cNpUfKNXT7epBavbchQYrDWIDuXetFWL6DhZPoZ4UgGuquMgUEhpDYKdxqNWjwxP+eFrrGFt1WzlTG2kr3eYRFqLQKCAHyKK7hqyf+VRV8gVam8lsGiBaqrR7MssIX/z253ZyQ4H6SwWb1uAtcNHBGctcn2Ub+LAvhvzofEtJ1lmi2jby1qyFO5p4P2uIodr7NyWt8ceAD1wSITH5+MwACnzPntJ4zZyMQOqr2No/LWuikzKkFKpMuu6GCOCqvri3Ux5phaYJEILmZ0oR/6jwlTAFnUZ+Ux34KUxrHYI2E/5YJkUNivkS/eBtgolJk1C+4YMwGiOoLDDKuB16xVAMDPdOMB01A5ogLW68js3GsMp47189rf7C9+mosu2yhe0YefT/wqqpHpZezOSqFsWNeWzBYzPdz5+f1Q01POjU23SNWtnpKS13Fk116U4o9mybT/mto1cj5hJg== X-MS-Exchange-AntiSpam-ExternalHop-MessageData-ChunkCount: 1 X-MS-Exchange-AntiSpam-ExternalHop-MessageData-0: WHbLQyTQnKf4h8htsiNBNKbxV+VFVZrmbsXeZIHB6Dhv9U2+Hr+4sZkxjMU+Zg/kWx4P1HDMfONehQbmbW2evshmUdopJwU7Q03KTSlERlo/mo+vJYpgTPYOV7iYfYFiJkDQ0y7yxNGedk6KUlvt4AfSiFlOSvvGo1/+gXY8G0X2aWGNdOvRjYhPWzlWBd2KVBWSXToM+E5U6acpP8sjYSyWhg5/js1RHMh/hffH2QzYlzWoAim/PRO9XhFQ72FE5RGlvcLm4NIvGaKAWkWDnSpdHa7lLryDjr6CbL5CVLWhGcjSwWnTo1lJINrSz3Lh4OesLwHEbFGuscm/nqbSaCtcLzJounqfhg7yS1mn5TXUn0woYkfN2bzNrHxnZkKbTLYJTGmZrMcSua49cYjKKymhXVECirsiFhgiPd3QkXjHy1N3rhHXGVr8QyD2N3oACOVOnPc5Q7M1Rx3ES2Nalcu27+H6+zbLWkgDkUHbj/XDtAVa/z8z0YeazgHomLir2kfAeVVdSqOsGHgzzjBFF/CU7sr2S3bNeO5EqP5I9LTUPs/NbMKoPC6vZZz/RVE7Smm6Z7DLVWzXaaPj7cvahlZrjurw8DC3iUfWJIj71kM= X-OriginatorOrg: oracle.com X-MS-Exchange-CrossTenant-Network-Message-Id: 6a9db3d6-15e2-409d-b8fe-08dd61ef0de3 X-MS-Exchange-CrossTenant-AuthSource: CY8PR10MB7243.namprd10.prod.outlook.com X-MS-Exchange-CrossTenant-AuthAs: Internal X-MS-Exchange-CrossTenant-OriginalArrivalTime: 13 Mar 2025 05:22:31.5912 (UTC) X-MS-Exchange-CrossTenant-FromEntityHeader: Hosted X-MS-Exchange-CrossTenant-Id: 4e2c6054-71cb-48f1-bd6c-3a9705aca71b X-MS-Exchange-CrossTenant-MailboxType: HOSTED X-MS-Exchange-CrossTenant-UserPrincipalName: CTZ+YJFq+Gw9YBBsicKJBanJHmCrOzo076M93/qjFY0xvr9NHxvi2QHjC7v+u/qBZN+BN6kJEvgJgdrtKPVqQjr4PI+MTZJ/E0bv0Amlo7U= X-MS-Exchange-Transport-CrossTenantHeadersStamped: IA0PR10MB6724 X-Proofpoint-Virus-Version: vendor=baseguard engine=ICAP:2.0.293,Aquarius:18.0.1093,Hydra:6.0.680,FMLib:17.12.68.34 definitions=2025-03-13_02,2025-03-11_02,2024-11-22_01 X-Proofpoint-Spam-Details: rule=notspam policy=default score=0 bulkscore=0 phishscore=0 spamscore=0 mlxscore=0 mlxlogscore=999 adultscore=0 malwarescore=0 suspectscore=0 classifier=spam adjust=0 reason=mlx scancount=1 engine=8.12.0-2502280000 definitions=main-2503130040 X-Proofpoint-GUID: Y8v74U7Omy3nt60MxwkDvOG4pbKICSL5 X-Proofpoint-ORIG-GUID: Y8v74U7Omy3nt60MxwkDvOG4pbKICSL5 In the next patches we allow users to create static controllers if the driver supports it. To get this info we need the nvmet_fabrics_ops a little sooner then port enablement so this creates a function to go from trtype to nvmet_fabrics_ops. Signed-off-by: Mike Christie --- drivers/nvme/target/core.c | 41 +++++++++++++++++++++++-------------- drivers/nvme/target/nvmet.h | 1 + 2 files changed, 27 insertions(+), 15 deletions(-) diff --git a/drivers/nvme/target/core.c b/drivers/nvme/target/core.c index 4de534eafd89..06967c00e9a2 100644 --- a/drivers/nvme/target/core.c +++ b/drivers/nvme/target/core.c @@ -306,6 +306,30 @@ void nvmet_unregister_transport(const struct nvmet_fabrics_ops *ops) } EXPORT_SYMBOL_GPL(nvmet_unregister_transport); +const struct nvmet_fabrics_ops *nvmet_get_ops_by_transport(int trtype) +{ + const struct nvmet_fabrics_ops *ops; + + lockdep_assert_held(&nvmet_config_sem); + + ops = nvmet_transports[trtype]; + if (!ops) { + up_write(&nvmet_config_sem); + request_module("nvmet-transport-%d", trtype); + down_write(&nvmet_config_sem); + ops = nvmet_transports[trtype]; + if (!ops) { + pr_err("transport type %d not supported\n", trtype); + return NULL; + } + } + + if (!try_module_get(ops->owner)) + return NULL; + + return ops; +} + void nvmet_port_del_ctrls(struct nvmet_port *port, struct nvmet_subsys *subsys) { struct nvmet_ctrl *ctrl; @@ -325,22 +349,9 @@ int nvmet_enable_port(struct nvmet_port *port) lockdep_assert_held(&nvmet_config_sem); - ops = nvmet_transports[port->disc_addr.trtype]; - if (!ops) { - up_write(&nvmet_config_sem); - request_module("nvmet-transport-%d", port->disc_addr.trtype); - down_write(&nvmet_config_sem); - ops = nvmet_transports[port->disc_addr.trtype]; - if (!ops) { - pr_err("transport type %d not supported\n", - port->disc_addr.trtype); - return -EINVAL; - } - } - - if (!try_module_get(ops->owner)) + ops = nvmet_get_ops_by_transport(port->disc_addr.trtype); + if (!ops) return -EINVAL; - /* * If the user requested PI support and the transport isn't pi capable, * don't enable the port. diff --git a/drivers/nvme/target/nvmet.h b/drivers/nvme/target/nvmet.h index ec3d10eb316a..052ea4a105fc 100644 --- a/drivers/nvme/target/nvmet.h +++ b/drivers/nvme/target/nvmet.h @@ -622,6 +622,7 @@ void nvmet_port_send_ana_event(struct nvmet_port *port); int nvmet_register_transport(const struct nvmet_fabrics_ops *ops); void nvmet_unregister_transport(const struct nvmet_fabrics_ops *ops); +const struct nvmet_fabrics_ops *nvmet_get_ops_by_transport(int trtype); void nvmet_port_del_ctrls(struct nvmet_port *port, struct nvmet_subsys *subsys); From patchwork Thu Mar 13 05:18:06 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Mike Christie X-Patchwork-Id: 14014339 Received: from mx0b-00069f02.pphosted.com (mx0b-00069f02.pphosted.com [205.220.177.32]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 03FD01F91E3 for ; Thu, 13 Mar 2025 05:22:47 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=fail smtp.client-ip=205.220.177.32 ARC-Seal: i=2; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1741843370; cv=fail; b=Kdr3KO2+35XswHx1+jP81SsU7jIjaotV1Ob6hWO/Rjb+6zJyOFpjy1mukeS5HojVy3gY06xK7zuJL64wMl4xIPhT4nHfjDrtm1FN6HBwgwJuvCgprAK342tl32t3U+7lEbjtdsdG6mT7cwWrUZVAeRYlsB2lZ+wO5R3+s5aeiCA= ARC-Message-Signature: i=2; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1741843370; c=relaxed/simple; bh=dvHyv0cZFtxy8xHH2BYbH3lu5IpmWIk/STtUYJ6fWfA=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: Content-Type:MIME-Version; b=NrmW5uXCMJkrK7jeMlj9k1pTQ3Bt+A5pl7UK6cBHATW7C8NzDIavaYqWgYLhvYDgu9xICBttXyk3PLEUJ/f5RfDJ+UIle7kp85G0035SrVE1qZQ6nEUJ7I7YFlowP8+QwBXD0w1AozJyvlA+5onzlARun/HB/YCo1cZQw+Fte1E= ARC-Authentication-Results: i=2; smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=oracle.com; spf=pass smtp.mailfrom=oracle.com; dkim=pass (2048-bit key) header.d=oracle.com header.i=@oracle.com header.b=EiUnOdWX; dkim=pass (1024-bit key) header.d=oracle.onmicrosoft.com header.i=@oracle.onmicrosoft.com header.b=sIQiBBDB; arc=fail smtp.client-ip=205.220.177.32 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=oracle.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=oracle.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=oracle.com header.i=@oracle.com header.b="EiUnOdWX"; dkim=pass (1024-bit key) header.d=oracle.onmicrosoft.com header.i=@oracle.onmicrosoft.com header.b="sIQiBBDB" Received: from pps.filterd (m0246631.ppops.net [127.0.0.1]) by mx0b-00069f02.pphosted.com (8.18.1.2/8.18.1.2) with ESMTP id 52D3tkuN011499; Thu, 13 Mar 2025 05:22:36 GMT DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=oracle.com; h=cc :content-transfer-encoding:content-type:date:from:in-reply-to :message-id:mime-version:references:subject:to; s= corp-2023-11-20; bh=0/MHOLNF8xYhRI2n3JY2gUGqgYW8aASMA044TZvicgk=; b= EiUnOdWXL0uCadVdN0BOoTwQp7frKwhJHReZ3szkqp5NB2czRtaPq0lnAYX3Eaj1 h4JX9+Y7rbUKOwj1KGtLCIrbCI9JmtScv+e8t0ivqGWkKh4YUlCAGoxz/MuKUBJu nsCKqPEuB3f07OeTmXmpLu4xldOjpRIIa4SRPbPidXXLV4Rj4f9+cg1yL4gPuciA G0ODH1wnAzLKjbh1yUBjtx9ROnd35Is8U4xLGF4e955JuUfPTqlUpaYXdklBQgyE dd2jjveCqZxX+TWbS3qBMivJjVeWGwoQXoJr9XVbPftrnBnd997tK7pyP9HlZ3Ph rGbPXi/t7exkcImbr4XM3Q== Received: from iadpaimrmta01.imrmtpd1.prodappiadaev1.oraclevcn.com (iadpaimrmta01.appoci.oracle.com [130.35.100.223]) by mx0b-00069f02.pphosted.com (PPS) with ESMTPS id 45au4hbedy-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=OK); Thu, 13 Mar 2025 05:22:36 +0000 (GMT) Received: from pps.filterd (iadpaimrmta01.imrmtpd1.prodappiadaev1.oraclevcn.com [127.0.0.1]) by iadpaimrmta01.imrmtpd1.prodappiadaev1.oraclevcn.com (8.18.1.2/8.18.1.2) with ESMTP id 52D43sND012355; Thu, 13 Mar 2025 05:22:35 GMT Received: from nam10-dm6-obe.outbound.protection.outlook.com (mail-dm6nam10lp2043.outbound.protection.outlook.com [104.47.58.43]) by iadpaimrmta01.imrmtpd1.prodappiadaev1.oraclevcn.com (PPS) with ESMTPS id 45atn272pk-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=OK); Thu, 13 Mar 2025 05:22:35 +0000 ARC-Seal: i=1; a=rsa-sha256; s=arcselector10001; d=microsoft.com; cv=none; b=eiVSBzc3/t+cc0bTWJR00I4z5bWyOwqU1EgWG5zuXJCtoWDpWb4z1fUn7p+K6L5AqwOV/Uqafdcsvif4anT6Hyw77ukHehpJSMXRlI6CnmPMe3G+kiWpitXwWrlUrO6e4COP531ryCxjW9NCzoUZNP52uc37uuDoxAx1j+lUrmFGOhejhyEH+A4NJpO9hGthw44pvfPG4LUYWhGNkwE0TfUPKmjCmw2yLA21In52rxi0CSwo5LiDjQyPC1uSEkgXycImBaP9f6FE7GhSZjv+rKpVUWCQgJ0H1CbBJFK2dDDrBr/UFCdbwKAGNKj50QK8XG6MRoLXUcJR6JXmJXv0+Q== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=microsoft.com; s=arcselector10001; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-AntiSpam-MessageData-ChunkCount:X-MS-Exchange-AntiSpam-MessageData-0:X-MS-Exchange-AntiSpam-MessageData-1; bh=0/MHOLNF8xYhRI2n3JY2gUGqgYW8aASMA044TZvicgk=; b=rbheR9KJ1IT5+lMOyJ6rwHo+FIsmSg0+7CaYtrpuH0Xegivp+DW850iIG9/1eKOTbWwo1uFKt4W+X6V2ZTmqvaa970zBo0bs9JwB30mYgzLtVTN2zbXpEs9kLg1TtK55P+hwEs5DI0BSXczZ4AzOs4rp0mGmlat6MwGIdp9QJ9gaZRU1hmdB0WBjqfj6R7wa0yJIRlEca3sGmmpmu6nu8ZMvbD2GHM3ax69KTGST5Mdq6aDAduFIS0bFQ/YMcgUWoPRHy4VFOw0KEFSapFvhLwn5uu12fHPkFR/h25om1aRscRqZtI76IzIw0hUDBGtntH5HccJKUXrgoRjzL4xBRg== ARC-Authentication-Results: i=1; mx.microsoft.com 1; spf=pass smtp.mailfrom=oracle.com; dmarc=pass action=none header.from=oracle.com; dkim=pass header.d=oracle.com; arc=none DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=oracle.onmicrosoft.com; s=selector2-oracle-onmicrosoft-com; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck; bh=0/MHOLNF8xYhRI2n3JY2gUGqgYW8aASMA044TZvicgk=; b=sIQiBBDBLukldiuIH9DIms1eljYKZiF3hBvNfFch4mDQhmyz1Qdd0E/K//EFlOTeTx3d9SFe0KEkiIxqD7qPZNoLcjxFJxChXomKTdtg7JKqYHPPN8uBgZXUx3UO2tlx74+Bko1dk4d+uy+HhMYjzXPJNcPr8JnGIT4MkeRGv/Y= Received: from CY8PR10MB7243.namprd10.prod.outlook.com (2603:10b6:930:7c::10) by IA0PR10MB6724.namprd10.prod.outlook.com (2603:10b6:208:43e::5) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.8511.27; Thu, 13 Mar 2025 05:22:33 +0000 Received: from CY8PR10MB7243.namprd10.prod.outlook.com ([fe80::b779:d0be:9e3a:34f0]) by CY8PR10MB7243.namprd10.prod.outlook.com ([fe80::b779:d0be:9e3a:34f0%4]) with mapi id 15.20.8511.026; Thu, 13 Mar 2025 05:22:33 +0000 From: Mike Christie To: chaitanyak@nvidia.com, kbusch@kernel.org, hch@lst.de, sagi@grimberg.me, joao.m.martins@oracle.com, linux-nvme@lists.infradead.org, kvm@vger.kernel.org, kwankhede@nvidia.com, alex.williamson@redhat.com, mlevitsk@redhat.com Cc: Mike Christie Subject: [PATCH RFC 05/11] nvmet: Add function to print trtype Date: Thu, 13 Mar 2025 00:18:06 -0500 Message-ID: <20250313052222.178524-6-michael.christie@oracle.com> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20250313052222.178524-1-michael.christie@oracle.com> References: <20250313052222.178524-1-michael.christie@oracle.com> X-ClientProxiedBy: CH2PR07CA0045.namprd07.prod.outlook.com (2603:10b6:610:5b::19) To CY8PR10MB7243.namprd10.prod.outlook.com (2603:10b6:930:7c::10) Precedence: bulk X-Mailing-List: kvm@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 X-MS-PublicTrafficType: Email X-MS-TrafficTypeDiagnostic: CY8PR10MB7243:EE_|IA0PR10MB6724:EE_ X-MS-Office365-Filtering-Correlation-Id: da78177d-c4f9-4712-1fbf-08dd61ef0f04 X-MS-Exchange-SenderADCheck: 1 X-MS-Exchange-AntiSpam-Relay: 0 X-Microsoft-Antispam: BCL:0;ARA:13230040|376014|366016|1800799024|921020; X-Microsoft-Antispam-Message-Info: KA5H3f7mwHkz7322WpCBo+6+5rxNjvpcT5Mupj/DwjLEla2mkfmb6ZiXa5mro5WuZtTny1qRbwQ7rIyap4kRN4WZVfdZ3IisOSU5wCnwgT3o35ozvdBjJ3NMwRVpR72JcfayJkn6YUbve78K0cnwLug8uB51Dx4uUXcuFLueZISRcwTAHcnI2VHmjtuURw1fwZ9WjzGs6h6LBgWsqy7UUBmPtBPLBQXpiScwqLXLp3O0kBrFX8oM7de4/93+wBp95XuOQ9m+7j3IJCHFtyomGxRZp6GxVHup2CeCrt98uwgS+RBzRBApoJu4NnEfm/Afu0N+6PzNo+I5qxVsrsNLbfXqsWgxuq2u0rl5pSLvbjoIpAJsKGJZqJe1nFehb+ae3bmpbMdVmzNW79xeeXUtpxF1rwd0h59a/kL5LlLYadcUcFzELSJyVENmDJPKuq+BfOOrIDjDIFmMpub0cdMiE0vDJAgjo6rbLGtXbleKg47jzEulQDm/qQzwCRXwLP2YasMPuPi7Ty3VwiEeVLb6LoczG/S5NNZwuglYhYmzy7MkwMK+y1PXIRfyQwDkBSUVG2M2enrCHErrZiRcmIaIm7h78cume0bp95wa6sC4CW7yV+UkzAHy+AJuXu36Dl8D5AvlaxRwrNkWOF1nKPHZjWdH/CV5lxzJqAhIzQABLqdpNKaTJQ8ikB1Gg6ZLm7Sl7vXNEZzeUgMZQEcFntAHHR3BEq8XRfXhdthR4Xh9GJdBAwmI8Gg3W06NCE0a23PvHfThFHP90Sw4M8Or+8DaXrJ4w0kTCUHuZQZhCGBt4DiTkdXo3xj9JRg4iJtBg5CeSb7/DRGalQskwKZDyBN13h2x2NkgVmZf5tGziLa1gI8bxPSCerKItew/B9wQb7LQll2yUHd+QkwoZF1q7JS4YRXJlo18Z4ujtRZQtKalz092is88nuHkFfNdhB4uSI0FGNUpx/7EkYO+PMSzC3BtWwZOo4ILqRYWDQqFdZVAaXXRVtT9uOzZA+eFE4QpZswLh2goGOCVnj5IALT1QjRluII+1MVm6ytOLSWJMz/ZTxMQP1ClJdl/hrxnZAvFo/C23IoyBPAVLfjYjjgYMWD9HoEDx8RmCELJpIL1TGPscwx+mL7wI0W2QYarnnBI1Ay6T6TOqdkFw45HMA5tKrNJF0cDOY20XoVldynvXWDPXalM1UWtWLu0KJG2dOCju4vnVxVITwa2929UatIkmKjsFrg1zL2PiisAIaXztucIN5WQBsDTYbjAGBSRc2ayn++BHk82gW2OCTkrG4Cd2Ac6O3cGeBCr7pRxjmWtEO+CAI1XieAvy100RThTQ+tkDqXPjQQrYh3MZyL4FxFovleLNMWfCO9433XhJjw31Kl+0XtbhFqsFSO40EL+PGMuXCKBPvAoBDyfmCrm8rBYuFyN4PxcyqGwiZYhmmVfY3qAcrU= X-Forefront-Antispam-Report: CIP:255.255.255.255;CTRY:;LANG:en;SCL:1;SRV:;IPV:NLI;SFV:NSPM;H:CY8PR10MB7243.namprd10.prod.outlook.com;PTR:;CAT:NONE;SFS:(13230040)(376014)(366016)(1800799024)(921020);DIR:OUT;SFP:1101; X-MS-Exchange-AntiSpam-MessageData-ChunkCount: 1 X-MS-Exchange-AntiSpam-MessageData-0: ERwomIojeL6oZ63/+6cfW27P2J2hKX5vdewM41VM5/2d2v4tI/Q8wVVf84gd/TL+6l9qqOONrAfMUyMKVuF665IrzMS0Ssb3kftxxfRA1dNojkvI68Cgqv27D8Tw5Ao0g3yqtu4FrJSiJCfCN0GcZ6CbXJ+kFFXTk5NV913eH46wYfgOc8Y3WJ7GzQA8LeLMg5CPzkl6ynJXRDFl4LITGbqwz36pfhyMf6gjwczVLeNojkv9LZ4CZoUDVIBXGg0s47bs37WNr4JZkZIv3XFsGqN1VLnUaF2w40QAUltC26sLu1l42p+yWVGwesV09bO0SmorV0l7clemQ071BpigHASM1aTdHRu4w3/UWvHygZxJs0lRq7Ubbcv5qm2a4kWA8S+4Kzvb5sQemDnswVSJjKVy492aLoVks/I99yUxlqT7UyThw8Rx58G2laCJmCx8ETRFA42UzKonAd89L/v0oFNSbb2Zp76VBaOYCbaA6bamt49ohu1qpUCVXtsAvDlXnS2nh/342uyP5Q8MAuSH5flNmnO2vf+aw+2oJkKvvFiRa+akalFa8OkMK92t7ufdKvWIR2+dl23XmwsawfzlXkCMLE3ptS0z9WaADUM5fxVa0dLpZjkvq8E6Tb5faC5hdXR1elH6yaMDw9l1Wb0y4BI11Da4BJ89UJqm8xNWSY5kt/75d3ymIVMtk6SSwsHxM/FhgeDr18adhyBDxRsZZYkvUer5uyl23ZYzVC/6PbSKNoLpidjMfVyE7TEHDJVibrH/frhZdFECtshBy2kKGBdpD5p5pYbKdHiQ76urlDMCynU6wksTJ3i8JGaRUwBVExvQkR0T/LOieDX5Nu+C4U/kWdt0HeaBBJ1htarclaryaUnvREoKJf9IA1rlVxfoIF7/xTjqzpaa9jQ3IUtpV8B20VEXLs9VLkAtJnQ8sGgrFMOb/drN1oorgOyYhiFWog/s8P8mdE2KdsclIrfTm24TXwhY4Atj+I6CAnqAsrH+p0u/g+f3OJ3LmBXFPxjRhwH24z/4yj4pX9fcGsXivevuZeTwmG8BWBRMUQ4y2vC3zm8HkiKaesErcP0VjHbLzo+npiBJWFOTsfE+K3Lx6k6b86bJWvBWJl87Mh+ApIPOBb+xW/uLfjqYv5i4nhNcQ/zs2lpqTuoKyWCD/vIvZ3omPbfInRUfgZVBXF1BP7wZCp+dA+TVHl1VnW1nwD2ngA9Itn6awlHHEWlJPHhpar/Hqc+k2Jgk4zUntMIdTrOicOgiJQwGnCg752Fv57cZ5Bc9RuAv/Jk9PaFRUkByT801ZpkvGUUC+NW2r8YBZrOFP8gZEHwdySWmFTWzdHs+aBvY27ZhMsJcnowcl9Mecv0UCrQjBIqMr9J2oPKxU7cH9zv4PTlYvtFR8QaNW5mMJFf3zzF2QSa4GXVAMr2kqdlRSvcYBRe+8C6vXAiuPGQjMIm9sDDlFBtjZ/LLa8ucQqBNhA5LA5EpPILE0FatxxEDAbyTnLuBnCkXwR8kjIZ4Xy6hKNAmFkRQFy5ymNiil9xEm6HTeTtE+TPFsQ+/bB5MFBrvZo7kCuqOypFvDjjIG1lJIMlWQwIACJHH9OjmTe6tyAiY7z1NMc9WTnj7FA== X-MS-Exchange-AntiSpam-ExternalHop-MessageData-ChunkCount: 1 X-MS-Exchange-AntiSpam-ExternalHop-MessageData-0: UaMkxERpksyrE9c8TIZUVFH0ROiRtPl6atqhEEQ/jThcO88o6GbNolEcReKJT3Lf1rG5iIJZTOHWSQuSKMvIHWbtNBh7FDHBoJ1/+dvSBnOS8t2OWowVpMR0huWexZ1792TAr8OcsQmlT4Ap4Qf590nWV17FQ8Gy9HFaA61LkAnoNRqizpCaVEpWCaK9nEAAvnyfjQfPRCLPVZGjqVOldLqO3L8YyB5M9wXQpB68VAXVeGLUJ6HXLoC/vZ5Hto1EcJ5Z/OQs7Fwqt/IIxOftNC7uGPqwYumVrRsNdxuU+Zwju4kQTSWcOQZK14eTFvwgRtAZx/V+L+HizEGAmHpPfSRga3sWXmv/aqJlh9w2Skv6puKdNf+qQB4WZDq0p7U4WtqAwwO+bLCDsjubajdrFWBnm5QoJgYxrSgtOAgW7nQ02iqxe7r1+oarpW7G3/NgXVe0+q3MaXZzKtyTCny7J5bqOF7/EpQLUeHkutxxXoFksNybyzQr/ecHzzKiJoouBGmSVWbvuwx3sBB60t9dmUysKdKO7KxQTPonxh9BBkujays8CjjDqcbb74Ll3mWydNv4SqqgkPc9HIWWcjtNkXK3d0RcDilCM3PVIWjG+KY= X-OriginatorOrg: oracle.com X-MS-Exchange-CrossTenant-Network-Message-Id: da78177d-c4f9-4712-1fbf-08dd61ef0f04 X-MS-Exchange-CrossTenant-AuthSource: CY8PR10MB7243.namprd10.prod.outlook.com X-MS-Exchange-CrossTenant-AuthAs: Internal X-MS-Exchange-CrossTenant-OriginalArrivalTime: 13 Mar 2025 05:22:33.4466 (UTC) X-MS-Exchange-CrossTenant-FromEntityHeader: Hosted X-MS-Exchange-CrossTenant-Id: 4e2c6054-71cb-48f1-bd6c-3a9705aca71b X-MS-Exchange-CrossTenant-MailboxType: HOSTED X-MS-Exchange-CrossTenant-UserPrincipalName: dZS6l1YeICvjqTnUaWuuywpalOVp4pyvYv4nTJza6Gc5A60zHijKgHSRrIJIPMFurXXdVKtjJiEfS+OiVSZel61oksfrlxNTwx0DuLGUAR4= X-MS-Exchange-Transport-CrossTenantHeadersStamped: IA0PR10MB6724 X-Proofpoint-Virus-Version: vendor=baseguard engine=ICAP:2.0.293,Aquarius:18.0.1093,Hydra:6.0.680,FMLib:17.12.68.34 definitions=2025-03-13_02,2025-03-11_02,2024-11-22_01 X-Proofpoint-Spam-Details: rule=notspam policy=default score=0 bulkscore=0 phishscore=0 spamscore=0 mlxscore=0 mlxlogscore=999 adultscore=0 malwarescore=0 suspectscore=0 classifier=spam adjust=0 reason=mlx scancount=1 engine=8.12.0-2502280000 definitions=main-2503130040 X-Proofpoint-GUID: X1DfEgBCqz3iuRmT0dKysGqV-TLV2gBG X-Proofpoint-ORIG-GUID: X1DfEgBCqz3iuRmT0dKysGqV-TLV2gBG This adds a helper to print the trtype. It will be used by the configs controller code. Signed-off-by: Mike Christie --- drivers/nvme/target/configfs.c | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/drivers/nvme/target/configfs.c b/drivers/nvme/target/configfs.c index e44ef69dffc2..896ae65e4918 100644 --- a/drivers/nvme/target/configfs.c +++ b/drivers/nvme/target/configfs.c @@ -329,14 +329,12 @@ static ssize_t nvmet_param_pi_enable_store(struct config_item *item, CONFIGFS_ATTR(nvmet_, param_pi_enable); #endif -static ssize_t nvmet_addr_trtype_show(struct config_item *item, - char *page) +static ssize_t nvmet_trtype_show(int trtype, char *page) { - struct nvmet_port *port = to_nvmet_port(item); int i; for (i = 0; i < ARRAY_SIZE(nvmet_transport); i++) { - if (port->disc_addr.trtype == nvmet_transport[i].type) + if (trtype == nvmet_transport[i].type) return snprintf(page, PAGE_SIZE, "%s\n", nvmet_transport[i].name); } @@ -344,6 +342,14 @@ static ssize_t nvmet_addr_trtype_show(struct config_item *item, return sprintf(page, "\n"); } +static ssize_t nvmet_addr_trtype_show(struct config_item *item, + char *page) +{ + struct nvmet_port *port = to_nvmet_port(item); + + return nvmet_trtype_show(port->disc_addr.trtype, page); +} + static void nvmet_port_init_tsas_rdma(struct nvmet_port *port) { port->disc_addr.tsas.rdma.qptype = NVMF_RDMA_QPTYPE_CONNECTED; From patchwork Thu Mar 13 05:18:07 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Mike Christie X-Patchwork-Id: 14014346 Received: from mx0b-00069f02.pphosted.com (mx0b-00069f02.pphosted.com [205.220.177.32]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id B88F71D5CDE for ; Thu, 13 Mar 2025 05:24:49 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=fail smtp.client-ip=205.220.177.32 ARC-Seal: i=2; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1741843491; cv=fail; b=IIv3FWAKdqxpGdw9aMwZrO22Hc/z9TnbcqCDyqaCAxyvyD/z56Uns/5Momck7NOoUAHH85T77dLhtUkCPD41WmXaz0pcHKT60tUr7QizJvva547HK2LdbN6kHk6DTKa/c69qBJWd63O6qLh4wGNGdg3AiGYkraj1ZOneeINmHI4= ARC-Message-Signature: i=2; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1741843491; c=relaxed/simple; bh=rVVSQVCzVc/lLYCy6Oi+9zVr3fTLyJ89iS8elMjfmDM=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: Content-Type:MIME-Version; b=L4lJn7HFmbJgmkrxLIif7N67Ts2F7uFgLugaCwztFGBZ6qMRaqARXR3vsB+sSx3eHbzFY1OQzQcinC5XfZC5MFFpX5mheXpLxEgrXftqTEsgPBwMuutaIvsd04UrH/nbc1Z52khjvzmZQd0GyrAKZoSQqjjzF4cfAGN+aUaGHg0= ARC-Authentication-Results: i=2; smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=oracle.com; spf=pass smtp.mailfrom=oracle.com; dkim=pass (2048-bit key) header.d=oracle.com header.i=@oracle.com header.b=JnstH6xV; dkim=pass (1024-bit key) header.d=oracle.onmicrosoft.com header.i=@oracle.onmicrosoft.com header.b=l7L1VcrQ; arc=fail smtp.client-ip=205.220.177.32 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=oracle.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=oracle.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=oracle.com header.i=@oracle.com header.b="JnstH6xV"; dkim=pass (1024-bit key) header.d=oracle.onmicrosoft.com header.i=@oracle.onmicrosoft.com header.b="l7L1VcrQ" Received: from pps.filterd (m0246632.ppops.net [127.0.0.1]) by mx0b-00069f02.pphosted.com (8.18.1.2/8.18.1.2) with ESMTP id 52D3txBS021525; Thu, 13 Mar 2025 05:22:38 GMT DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=oracle.com; h=cc :content-transfer-encoding:content-type:date:from:in-reply-to :message-id:mime-version:references:subject:to; s= corp-2023-11-20; bh=xhcMxAWxREmkgEGTJLc/YWJ11DsIymV4DfsxcQWP/V4=; b= JnstH6xVOW6UxuHXfcy0hqTjMtjRPub0ZSf8jHLrWMzLSCulP2GsgiFdCGFCFaAi HSqlwMy+9ugcx6gyrvS4gJ6eDrbpj8v4gb0REw/Dnr9pha/mFp27vVBO3hsaRgKb HvZybnm/GVpSmJY1Jr4PeWr8dkt1J1Lkix+meRk2jsre97CXK4ZVYsrFaGeKGkgZ NAEhSQaZn1sC4JmajzTohM9ZOd2phyJtGeoaBNi7cxyhrSTe5Jn0EqqoJHwy4aAj lI45nErFCXJpYlTWUQAlEq6RDh7ssQPtmi6/NK/XloGjXwDHRf/QdRhMHsFMjqAu KpuzsiRse3tV7rKfNw5V4w== Received: from iadpaimrmta02.imrmtpd1.prodappiadaev1.oraclevcn.com (iadpaimrmta02.appoci.oracle.com [147.154.18.20]) by mx0b-00069f02.pphosted.com (PPS) with ESMTPS id 45au4h3dac-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=OK); Thu, 13 Mar 2025 05:22:38 +0000 (GMT) Received: from pps.filterd (iadpaimrmta02.imrmtpd1.prodappiadaev1.oraclevcn.com [127.0.0.1]) by iadpaimrmta02.imrmtpd1.prodappiadaev1.oraclevcn.com (8.18.1.2/8.18.1.2) with ESMTP id 52D3YpSe001569; Thu, 13 Mar 2025 05:22:37 GMT Received: from nam10-dm6-obe.outbound.protection.outlook.com (mail-dm6nam10lp2043.outbound.protection.outlook.com [104.47.58.43]) by iadpaimrmta02.imrmtpd1.prodappiadaev1.oraclevcn.com (PPS) with ESMTPS id 45atn87qrg-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=OK); Thu, 13 Mar 2025 05:22:37 +0000 ARC-Seal: i=1; a=rsa-sha256; s=arcselector10001; d=microsoft.com; cv=none; b=Ag93Cwq1TBpk80Gu0tJjomNLTYee76zGS3t15tn4DfeVjuD5O3r2HvzQ2iXSkBrn8xL6T6s9dVHiVWRDknuAbvrj+KXWMXmkG0pLDd3b558228LJwUmIgG6AfzYdsCMLn6JAt7RVTGIVCbRooNxl0FTdcpxuecBHRmKgx2a26XBaKOujNIshcVqLgjFAOwx8O7SsRYisUnbAybvS35sTqyqhEhXacOaSqfwyYM+I70jrWdxtnXYf8NxbRdHLvTAF1i3pxqxm3hRFhKM6UbUNPV8yZk4e9R9mTEp4kyfFNV3MdHP5c1dmg/zHAZTYRtzLLB2oxA5kPYCzrPzq4NlDlQ== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=microsoft.com; s=arcselector10001; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-AntiSpam-MessageData-ChunkCount:X-MS-Exchange-AntiSpam-MessageData-0:X-MS-Exchange-AntiSpam-MessageData-1; bh=xhcMxAWxREmkgEGTJLc/YWJ11DsIymV4DfsxcQWP/V4=; b=p9bXKEzxVm2s0FKbn07StT+E/F1I4YU9du2Iwe7jOPZ7zRPNCYv1VmUVi0CxKNKfRSTYkur3uAPkg0Vnuxh2Fa5CfaxV77RTlWH2s5tmJ9yHe15wJnpeezWPtGCmqtsCdthDHRBK2yst3IbIGz7NVqdVK2E//3BY/jXqnnL3P814bk/C22HdVbdJr4EE2PcHPeCFrmOlzAktNiBmqWbiwzE4ZKkuy7TCp83PjpUDnuLPeI/85IIt0dJUor2N0/6rkTCmIL21z3WFBfppTYlKWDCtVJy9jrd1//07xsaXw0unm2+qWfSRtV47rodcCYSADehjxqWHwKn8T7a1EYjs/g== ARC-Authentication-Results: i=1; mx.microsoft.com 1; spf=pass smtp.mailfrom=oracle.com; dmarc=pass action=none header.from=oracle.com; dkim=pass header.d=oracle.com; arc=none DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=oracle.onmicrosoft.com; s=selector2-oracle-onmicrosoft-com; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck; bh=xhcMxAWxREmkgEGTJLc/YWJ11DsIymV4DfsxcQWP/V4=; b=l7L1VcrQ49MM/6qvTN5q8CReSlPN3PRjYqz4TYp3L5Ck7j+KPfTT+NAEJmiX9G89tutB7YWVvu9iCZ4RFRBwE3NFW/EwJEUCoiEZco0hvtCXh0JuYASKdRfTfQJrdtxeHaUX6tryaQ3c31kkfcwXSIoEhVB9/enkhRp2DwSDz00= Received: from CY8PR10MB7243.namprd10.prod.outlook.com (2603:10b6:930:7c::10) by IA0PR10MB6724.namprd10.prod.outlook.com (2603:10b6:208:43e::5) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.8511.27; Thu, 13 Mar 2025 05:22:35 +0000 Received: from CY8PR10MB7243.namprd10.prod.outlook.com ([fe80::b779:d0be:9e3a:34f0]) by CY8PR10MB7243.namprd10.prod.outlook.com ([fe80::b779:d0be:9e3a:34f0%4]) with mapi id 15.20.8511.026; Thu, 13 Mar 2025 05:22:35 +0000 From: Mike Christie To: chaitanyak@nvidia.com, kbusch@kernel.org, hch@lst.de, sagi@grimberg.me, joao.m.martins@oracle.com, linux-nvme@lists.infradead.org, kvm@vger.kernel.org, kwankhede@nvidia.com, alex.williamson@redhat.com, mlevitsk@redhat.com Cc: Mike Christie Subject: [PATCH RFC 06/11] nvmet: Allow nvmet_alloc_ctrl users to specify the cntlid Date: Thu, 13 Mar 2025 00:18:07 -0500 Message-ID: <20250313052222.178524-7-michael.christie@oracle.com> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20250313052222.178524-1-michael.christie@oracle.com> References: <20250313052222.178524-1-michael.christie@oracle.com> X-ClientProxiedBy: CH2PR07CA0056.namprd07.prod.outlook.com (2603:10b6:610:5b::30) To CY8PR10MB7243.namprd10.prod.outlook.com (2603:10b6:930:7c::10) Precedence: bulk X-Mailing-List: kvm@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 X-MS-PublicTrafficType: Email X-MS-TrafficTypeDiagnostic: CY8PR10MB7243:EE_|IA0PR10MB6724:EE_ X-MS-Office365-Filtering-Correlation-Id: 442dc3bf-6d44-4683-0fe9-08dd61ef1016 X-MS-Exchange-SenderADCheck: 1 X-MS-Exchange-AntiSpam-Relay: 0 X-Microsoft-Antispam: BCL:0;ARA:13230040|376014|366016|1800799024|921020; X-Microsoft-Antispam-Message-Info: hsLK2/O0za8FNE9BEO6A0nKTunxh7epzLxqh3YSpcpHTZiW/QWChAMfYE7NXPEt+Ey/m+jwLC4FMy+BztU/Nj1tY93diRcpUJnx7T+Cm0/7DLClKlDJlL9zJKTxm93nw5vJdzmZ+vAYUJ2nL5h99de1HqiYfloGPMz0XYfNP6jT6JWKEcK5uVfYQcAjDThPyQBo/kt/YMOy8IuJAIv6tnvGIMsokXLbwK/TCCgiqbyfaoJUMBsu8C3OAKqxCZpB6dhwPdy4SW1VGJgJG31UqkjUEqgaXdFaUvYDtSpuiYbSWpZmNmHBWvRLAtddbAgimF1IFatiNcUwQ/q3Y5YbujiHIPQtPSHfpD4dgxhcigzyEC7/Zow7en9fyRKVfjQZeZIVTp4g9iIEJTIE+lFx+np6shW2xgmKpLOeJ0ZzENifGCmk4ABvcMxwlf+AsA7mwhI6jJlcgwkzadssUa6eUEthAn1mruA9+1OOk5c2DgtGynnJiy//Kii0ovwYS55BL4UXSQ2pGAQ/YAA6hrev+BYiXtlPJd5ewT6nFQ4PwEJhCKKOy3WAJ+PZ8ujxNs8ENA1gVa67cLNoh3lbYSldpMMgYvyFyw763ZiviQGHvRDkvZKrTTMxzOeP8rb+VEtp+JaQeTnec5ejyHTkwRUyrXy8YvORMdzA4hOP4Iiwfc1qLtpHD3tYGPKfxKhoUWYxBL7vgHIEvUMshUfyb3noKt0ayPRUn8D47FPw5vJB1zj20QVdjX81z/BiLqAb28JU61xvt0GIHehTEjxLMp4KZBhGzvjrGU++KA9zFAoAtirWJmC6GxzjoWJZ9+utIpwx1fo/cY3Gold6sOF/tMqO7K9vr/lT6WULhXrmVx1M5OQn8z4BuEdW2DDPSNHyrzpPllT7c0zwTOwsHmam6jw/84UJPS2PHNdrCIAe+/Z5TcbMAmwaZcHPGfBFrFC4vP+pTYqsuwvgBglEKucdPuwjQkdiyNh02j86mSHG3Nk9PoRnSb0N5kW2Rz4ipzvAYy6TUetqeIg2F5qn+8FQTKYtOuyYQMB0HAmpSRqwp9tVYWGaaW1BtlbHZWJi9bvmwYJGKUB6DQ45+h+OCcJ4v0MCWUNBaxAUa+wOhcJg3q2qPQLfmokTS//ZVvT9tLIcxXpS6GEg6ZH9nKkEw1A1xy2c5wdlTKvHSA2gwKBwAMnuSiE3xXWk+N+1NrGmaAKN9RPuqxsReqC2oBhLkoJHTK8VJCz2nWZ4Q8ETzUqbufXe87MGTPgNaC+BSPlXPwzVayhdMYPGUeyw7DSvt1ItWUlKIEyW+ii3LP+B2hhoPIc8AimiiSq91pp3V0c2bGR0vi9bGmTx+gzg2RS4akanBJvaUR2WaaVMCUwmA616cDiqCGt3thv1zKS2d88c85A4nEbZrp178DaAL2Ir0G9EgH2ptWx14OWqVVH8yr2LX5UKmyns= X-Forefront-Antispam-Report: CIP:255.255.255.255;CTRY:;LANG:en;SCL:1;SRV:;IPV:NLI;SFV:NSPM;H:CY8PR10MB7243.namprd10.prod.outlook.com;PTR:;CAT:NONE;SFS:(13230040)(376014)(366016)(1800799024)(921020);DIR:OUT;SFP:1101; X-MS-Exchange-AntiSpam-MessageData-ChunkCount: 1 X-MS-Exchange-AntiSpam-MessageData-0: vDWlvJM/KNSMBgsgYHSA9OBJf5bcHMyVo5sxCQ6oMa83rhAJP1raAWjCVIGqc/pI3VSXINX3/FvR2wYK3e427ELh1XvYqF49kxM2qNC7QYroRj48x4W9GOfKRRDCMl5AmDJ7OMauLsTQVvtRYGhaiDrqv7DEDWZDfHEUJYvfAE0DG2rL355YNTbyAey2bKLdhJomuFKa0a3DM3YH1Qed5u726SRwYiObg+dx9whSG7r8yFD2cOMU5IFtyykHuV2hJLRmcqrFc5dNQ5ywsPfWdZbqgOSOMR/We48tyhJ3+0ZPDfcqnDye1k2FM9pS3xJo8PQbO9TyIbzRKOXItPTnJawM+gznnm2IHEV+taPTen1Dyc4ku1bP9/UmCd9TqBUHVEIsLa3bvxYyFHNNzA9fSYmGwfIt31Xt8iGfXDHeQRKlIGLXIqaBfXFFbZGmX9OuwglyjWWTnuIQWVjdRWxbf7kfGM0tYGcLqF71XA9lh0GBaE3cusB0M88NB0XPCeK+FpkMnQgfbYwlugC9nAGUCMRise6cfG2bX/iKHE7l14qmrWrl5ez2oyKcCJu7NbADiRJfiFFDAzNffdXNGqVK2iz1bviZy+bhi5KqVLpBCOeMxRA7b06bb+mD0hYDJh/0fVCmzueKl1A4G7x00MWhOZLqvHg8lXLzMQtnE9/BT7KNrC9ZpZrvWUuxuTNuHAkU2BqPvkYOPKESePP7d+9ITjL+5gsXx/MW8gcFUomesOvO44tS1++lkJAPm80FDWSSaAO+yskWRX2v7Q2Ygpe3rQXqH+Q2I2pNRbQsz5R2Ag/idKD4jm0Pjf5t4Yd4CEvFmllCmMAyWFez3I0/1OCKc/l4g0W/4yYfvhH+4nrvhfEIrKT/eVOQD0R9tREvbaTn2b++L8sfYc/fHiBBCozj3FRRSyPYs1+8F7BFphVHmbmaxk4BpDTM9Jnidv4E2ELC4hlceoBUWUVCbqOQ1VkIDBfxONhgV2vltFu/LVSKQEhbH0LOBO9vUZCE/qEiBrFx+r49/GNpyqbJFBqRO0t3f/EZHyPeDgnhDtfAjxj0qtZmo4z3JYp4651sGYEGtKB/KwU2v9pM0ZA/ngrLEuBQqhvjAamz7TmHBSMNQ1DDVzzybpawOLIj3wN1UHQlb3W58Z+7V/SIqSv4v6J8nm9TXYhfJpMYvFjlm1ezq69oFmYH4WzSsqiMu2+5zdxVHgFo0M+VV2ehy7wcWJ1Gp6rbdt4DwWK1jeKNOK78Vu5vFixLLXUxRIbGT1bp3kqIRls5oXDyOk5AUbWX6t+i+ls2a+kBd4GRHT9D+wdxn5w0mdvUHXdAIpnBZCM2VjPBVWP62CpJEPCQqnAL4bXxemaLE+HO3GSxAHOik2haaiuOf2Xq+t5XfRhO/HoZQWFe6ZLiGGe4AbKun1fD3myvj15vHiKQUDRVBaczE/bjfpwSNlzL6SSB3/FXw52P559Go62Mjlibtf7CQBBxzPNvfqsLDYAgHhu+wDn5UpXmzuvBhwTLi7AMdkUMZliXXdHhFrDgSgWz8FPB5j+om93wRCcMKOuC1dvANIzX6ZYCTSx5IIpJddjkfdPZHxhbClvAUbxxFMHZkaaYr4NVoN0VapAHWA== X-MS-Exchange-AntiSpam-ExternalHop-MessageData-ChunkCount: 1 X-MS-Exchange-AntiSpam-ExternalHop-MessageData-0: aQdLo/DssEb1656L3b+GDzemiabK8hdy4PMtsruGDxLqt5bLrcDBA3rNndKV2G5ml1RvUEc4mLC1RGAHTqehx0QQQwj1EFTRK84Yf6Rk1nUoPdNFGCfn8R2FS7v/ImH8KePiuhvwSr2lY2qlUyDq+ny2+Rt20b2AifvZQu7XyNoF+HnEuwDKPXz5geahdEe83D2KS6HBBSdmqMQIfdHjm8lCLCiM3IR2XrUerJ5Iq+S+FXm3TpPSCPdXVewzfbfbGeCeGGDr6FGPJ2yf2ARxd/WAcoxdzAeafSwvhvWONgXw0ObNKzzcI9nujDlJebQhUmjGiotNbw0Jl1iEtfoeYgPjJPSC0ytyr88E7TKdF17px3WpKbFBmf/SNiL5QkRLbJRpQ7crgtzZOOa1Wb+iGx9iimpOiaMjNbneReo4f20lQf8+ntXGUZwCvXTlC6BTht3nFfGmZld3S70FbravONj/qLyfinkDI87iDzhkIkwpI9qrfoYhwO1eYWOF+LjnTZGoIoLS/2lI2yJuPYSIPQ/G8QgDOr7H90+AdFioUVmDLAf2Mclv0mXxnCmlik3q0XuAp74OGCFIMvK0AEXfZPWy/5SBW0x2/vYbyRaYhLI= X-OriginatorOrg: oracle.com X-MS-Exchange-CrossTenant-Network-Message-Id: 442dc3bf-6d44-4683-0fe9-08dd61ef1016 X-MS-Exchange-CrossTenant-AuthSource: CY8PR10MB7243.namprd10.prod.outlook.com X-MS-Exchange-CrossTenant-AuthAs: Internal X-MS-Exchange-CrossTenant-OriginalArrivalTime: 13 Mar 2025 05:22:35.2466 (UTC) X-MS-Exchange-CrossTenant-FromEntityHeader: Hosted X-MS-Exchange-CrossTenant-Id: 4e2c6054-71cb-48f1-bd6c-3a9705aca71b X-MS-Exchange-CrossTenant-MailboxType: HOSTED X-MS-Exchange-CrossTenant-UserPrincipalName: XtwRuvbxGiP7QYXCgLJ9xFXDazZbj3OwocFt25aby7anz6Ues4V4noe/2Smf9cj5wXj3tUX046zSix7FNh/IaIPcfcr7kOij0+KQK5DR6uE= X-MS-Exchange-Transport-CrossTenantHeadersStamped: IA0PR10MB6724 X-Proofpoint-Virus-Version: vendor=baseguard engine=ICAP:2.0.293,Aquarius:18.0.1093,Hydra:6.0.680,FMLib:17.12.68.34 definitions=2025-03-13_02,2025-03-11_02,2024-11-22_01 X-Proofpoint-Spam-Details: rule=notspam policy=default score=0 mlxlogscore=999 phishscore=0 suspectscore=0 adultscore=0 spamscore=0 mlxscore=0 bulkscore=0 malwarescore=0 classifier=spam adjust=0 reason=mlx scancount=1 engine=8.12.0-2502280000 definitions=main-2503130040 X-Proofpoint-ORIG-GUID: PN6r_lSdGSaOFLRIeDx80zwZcK3_nrGS X-Proofpoint-GUID: PN6r_lSdGSaOFLRIeDx80zwZcK3_nrGS For the configfs controller interface we will want to pass in the cntlid from userspace. This modifies nvmet_alloc_ctrl so the caller can pass in the cntlid or allow nvmet code to allocate it like it does today for dynamic controllers. Signed-off-by: Mike Christie --- drivers/nvme/target/core.c | 9 ++++++--- drivers/nvme/target/fabrics-cmd.c | 1 + drivers/nvme/target/nvmet.h | 3 +++ drivers/nvme/target/pci-epf.c | 1 + 4 files changed, 11 insertions(+), 3 deletions(-) diff --git a/drivers/nvme/target/core.c b/drivers/nvme/target/core.c index 06967c00e9a2..f587ec410023 100644 --- a/drivers/nvme/target/core.c +++ b/drivers/nvme/target/core.c @@ -1621,9 +1621,12 @@ struct nvmet_ctrl *nvmet_alloc_ctrl(struct nvmet_alloc_ctrl_args *args) if (!ctrl->sqs) goto out_free_changed_ns_list; - ret = ida_alloc_range(&cntlid_ida, - subsys->cntlid_min, subsys->cntlid_max, - GFP_KERNEL); + if (args->cntlid == NVMET_MAX_CNTLID) + ret = ida_alloc_range(&cntlid_ida, subsys->cntlid_min, + subsys->cntlid_max, GFP_KERNEL); + else + ret = ida_alloc_range(&cntlid_ida, args->cntlid, args->cntlid, + GFP_KERNEL); if (ret < 0) { args->status = NVME_SC_CONNECT_CTRL_BUSY | NVME_STATUS_DNR; goto out_free_sqs; diff --git a/drivers/nvme/target/fabrics-cmd.c b/drivers/nvme/target/fabrics-cmd.c index eb406c90c167..b26e60d41e8c 100644 --- a/drivers/nvme/target/fabrics-cmd.c +++ b/drivers/nvme/target/fabrics-cmd.c @@ -288,6 +288,7 @@ static void nvmet_execute_admin_connect(struct nvmet_req *req) args.hostnqn = d->hostnqn; args.hostid = &d->hostid; args.kato = le32_to_cpu(c->kato); + args.cntlid = NVMET_MAX_CNTLID; ctrl = nvmet_alloc_ctrl(&args); if (!ctrl) diff --git a/drivers/nvme/target/nvmet.h b/drivers/nvme/target/nvmet.h index 052ea4a105fc..990dd43df5c9 100644 --- a/drivers/nvme/target/nvmet.h +++ b/drivers/nvme/target/nvmet.h @@ -582,6 +582,8 @@ void nvmet_ctrl_fatal_error(struct nvmet_ctrl *ctrl); void nvmet_update_cc(struct nvmet_ctrl *ctrl, u32 new); +#define NVMET_MAX_CNTLID 0xFFF0 + struct nvmet_alloc_ctrl_args { struct nvmet_port *port; char *subsysnqn; @@ -590,6 +592,7 @@ struct nvmet_alloc_ctrl_args { const struct nvmet_fabrics_ops *ops; struct device *p2p_client; u32 kato; + u16 cntlid; __le32 result; u16 error_loc; u16 status; diff --git a/drivers/nvme/target/pci-epf.c b/drivers/nvme/target/pci-epf.c index 565d2bd36dcd..b0e14e8aae7b 100644 --- a/drivers/nvme/target/pci-epf.c +++ b/drivers/nvme/target/pci-epf.c @@ -2031,6 +2031,7 @@ static int nvmet_pci_epf_create_ctrl(struct nvmet_pci_epf *nvme_epf, args.hostid = &id; args.hostnqn = hostnqn; args.ops = &nvmet_pci_epf_fabrics_ops; + args.cntlid = NVMET_MAX_CNTLID; ctrl->tctrl = nvmet_alloc_ctrl(&args); if (!ctrl->tctrl) { From patchwork Thu Mar 13 05:18:08 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Mike Christie X-Patchwork-Id: 14014344 Received: from mx0a-00069f02.pphosted.com (mx0a-00069f02.pphosted.com [205.220.165.32]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 66F2B8635C for ; Thu, 13 Mar 2025 05:23:50 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=fail smtp.client-ip=205.220.165.32 ARC-Seal: i=2; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1741843432; cv=fail; b=fG1xxjs9WtlRTxa16zv1CQX2bRiNRJ5FIW+ojJ+KH/uVEnExSql5AE8BwW5XseMJUBfEvUxrT7szQs19GZq1ISBc0qeV+gVIz3I2kFKFG028kZkXrGBPUT+UlzZ5g1i3rGvvik1SrVnaxEPXhObLfs4ZW+vSuh7BDPUrnh7sBgQ= ARC-Message-Signature: i=2; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1741843432; c=relaxed/simple; bh=6wXylgjiSNtmNqQCqfxNCfPZ/wXptf02jeUQlpRlHZw=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: Content-Type:MIME-Version; b=JC/YWUbWRPeaZNhdja82T9BBUhzJK8JiF0IdjGjuKhkqGMQOTphOhtOforW3aVDDkTS2L0f2QmC4ycKiFRulfzABnRvgxbC+hHcKWAb+QNYZC9GXPBnW0WOIwPqNA5eWR7ERYKNc67kovD0FJZE1It4NMVgW88uhIpo/P69qf2U= ARC-Authentication-Results: i=2; smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=oracle.com; spf=pass smtp.mailfrom=oracle.com; dkim=pass (2048-bit key) header.d=oracle.com header.i=@oracle.com header.b=Xf98aaGh; dkim=pass (1024-bit key) header.d=oracle.onmicrosoft.com header.i=@oracle.onmicrosoft.com header.b=dkFq/KJA; arc=fail smtp.client-ip=205.220.165.32 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=oracle.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=oracle.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=oracle.com header.i=@oracle.com header.b="Xf98aaGh"; dkim=pass (1024-bit key) header.d=oracle.onmicrosoft.com header.i=@oracle.onmicrosoft.com header.b="dkFq/KJA" Received: from pps.filterd (m0246617.ppops.net [127.0.0.1]) by mx0b-00069f02.pphosted.com (8.18.1.2/8.18.1.2) with ESMTP id 52D3uBjP025124; Thu, 13 Mar 2025 05:22:40 GMT DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=oracle.com; h=cc :content-transfer-encoding:content-type:date:from:in-reply-to :message-id:mime-version:references:subject:to; s= corp-2023-11-20; bh=hcdzFMqVjPWQKhriYZOK6gLu6RwCQN0UuuZji+qxLKs=; b= Xf98aaGhaG73Je9fDAqTfCBmFDbu/lt4jROWRTuIdTl2ddSP7JCeKDgwmonJ6q8T RPufjcGEyZbJoGLLUdp1zzwWRmt+YkS1pjhYHc16yhCZeg7zeIdh4OqhzJXGglQa ha4kEyKlBx8tEbP9A2ItsFllTo3dD2e9pqAJe/ql7QmHDZiXW/2QBR2yIk6Lyh80 KaxrUCRg9DBRHH3RiFpQfKJIaGNfFogFPeaXNFyScyw/36S8/6VgY10Y1zy3haSF upAK1cW2gXZa49c/2fWAAcZ3VYLNLThsSNHIcPUkR/F5vAc2jMPwmzSVD+zBRRiw z+hY2MxmoxVYfFn9pHkQvQ== Received: from iadpaimrmta02.imrmtpd1.prodappiadaev1.oraclevcn.com (iadpaimrmta02.appoci.oracle.com [147.154.18.20]) by mx0b-00069f02.pphosted.com (PPS) with ESMTPS id 45au4dkf1c-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=OK); Thu, 13 Mar 2025 05:22:40 +0000 (GMT) Received: from pps.filterd (iadpaimrmta02.imrmtpd1.prodappiadaev1.oraclevcn.com [127.0.0.1]) by iadpaimrmta02.imrmtpd1.prodappiadaev1.oraclevcn.com (8.18.1.2/8.18.1.2) with ESMTP id 52D3g3mo002143; Thu, 13 Mar 2025 05:22:38 GMT Received: from nam10-bn7-obe.outbound.protection.outlook.com (mail-bn7nam10lp2041.outbound.protection.outlook.com [104.47.70.41]) by iadpaimrmta02.imrmtpd1.prodappiadaev1.oraclevcn.com (PPS) with ESMTPS id 45atn87qs6-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=OK); Thu, 13 Mar 2025 05:22:38 +0000 ARC-Seal: i=1; a=rsa-sha256; s=arcselector10001; d=microsoft.com; cv=none; b=UmjCRZ300RaqTYSwq4zCyXhtOpnTjkeLuSMyv2P10izRcBxyYKLRJDwSO2nQytwiNHapFEr+ufCF1So7KozdU56Yws6MBZ2WlTHwmEX04BjmdqHbs16PFbX/LP+01P617MyChMKq0xgH5CZkpK6KVoSPJU5taNVupeAphz1rakOwyRoa2GQaE+Ouzn8CVHhcLn5cqpo1gpE35M8vdgbB+iZCQ+oHc5Rp9htfcZ7Pbv/S9HafKClJ6V7ugXwxUBS9T1d7arWIr9O6t/enREhCVhni+uQcQaAMrb5WW2WhrbUECZnNubh4Wv+9xGx09N2mo0Y2qPGO5w1eZix7fYM68Q== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=microsoft.com; s=arcselector10001; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-AntiSpam-MessageData-ChunkCount:X-MS-Exchange-AntiSpam-MessageData-0:X-MS-Exchange-AntiSpam-MessageData-1; bh=hcdzFMqVjPWQKhriYZOK6gLu6RwCQN0UuuZji+qxLKs=; b=LSW69rjVGJzDPaelUCxydv0GpNc35GbqBUy/Royc1Rz08S5ka68WOsxhxnTbtcpf2lsvprwLSHQmPNdFRLbQRuswj4PDxJ0HMExhWL028nxDyoaDFHR6vqw4w4RjMXioAhmMo/e3BqLoAtRJNZ2u+J8O7ZotN2UIQLb9ZPC/dnAVb4Fux1pXRX9GlrcsGIMnwqeIu+tYx7xTkI9YYaEhE9GEUq/3kzJXRQPUx1u8CWPh+gsln6pUkNBcxnpEW4vc46NL5wZJQoM+f3AI9sL/X4PhJjMNJ3BJxlXJ2NUSv54zIwUN0BJyYZIy1VYBdcyeChD8mQ/XY93eAkZIldQP+w== ARC-Authentication-Results: i=1; mx.microsoft.com 1; spf=pass smtp.mailfrom=oracle.com; dmarc=pass action=none header.from=oracle.com; dkim=pass header.d=oracle.com; arc=none DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=oracle.onmicrosoft.com; s=selector2-oracle-onmicrosoft-com; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck; bh=hcdzFMqVjPWQKhriYZOK6gLu6RwCQN0UuuZji+qxLKs=; b=dkFq/KJAIdXEeDHJTAlydPTrrHl7s6NbIULZxjH6lwLyMA+8pwhWzhGj85mAYjgkZycYIBwmHpZJnzHWY1F2J8muBYCDcnlB0hNv2/cMizs4j1Udybx+GTatHbn4OsD1juuCJ4LFwFfxoOse492qHzVGhAcOdWjRptLO1SasoX0= Received: from CY8PR10MB7243.namprd10.prod.outlook.com (2603:10b6:930:7c::10) by IA0PR10MB6724.namprd10.prod.outlook.com (2603:10b6:208:43e::5) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.8511.27; Thu, 13 Mar 2025 05:22:37 +0000 Received: from CY8PR10MB7243.namprd10.prod.outlook.com ([fe80::b779:d0be:9e3a:34f0]) by CY8PR10MB7243.namprd10.prod.outlook.com ([fe80::b779:d0be:9e3a:34f0%4]) with mapi id 15.20.8511.026; Thu, 13 Mar 2025 05:22:37 +0000 From: Mike Christie To: chaitanyak@nvidia.com, kbusch@kernel.org, hch@lst.de, sagi@grimberg.me, joao.m.martins@oracle.com, linux-nvme@lists.infradead.org, kvm@vger.kernel.org, kwankhede@nvidia.com, alex.williamson@redhat.com, mlevitsk@redhat.com Cc: Mike Christie Subject: [PATCH RFC 07/11] nvmet: Add static controller support to configfs Date: Thu, 13 Mar 2025 00:18:08 -0500 Message-ID: <20250313052222.178524-8-michael.christie@oracle.com> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20250313052222.178524-1-michael.christie@oracle.com> References: <20250313052222.178524-1-michael.christie@oracle.com> X-ClientProxiedBy: CH2PR16CA0014.namprd16.prod.outlook.com (2603:10b6:610:50::24) To CY8PR10MB7243.namprd10.prod.outlook.com (2603:10b6:930:7c::10) Precedence: bulk X-Mailing-List: kvm@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 X-MS-PublicTrafficType: Email X-MS-TrafficTypeDiagnostic: CY8PR10MB7243:EE_|IA0PR10MB6724:EE_ X-MS-Office365-Filtering-Correlation-Id: 1804c362-c86a-4437-d09f-08dd61ef1119 X-MS-Exchange-SenderADCheck: 1 X-MS-Exchange-AntiSpam-Relay: 0 X-Microsoft-Antispam: BCL:0;ARA:13230040|376014|366016|1800799024|921020; X-Microsoft-Antispam-Message-Info: YjchA9JAiepVp9HpD9dzV1nKe6JrPKuwyh+Y/515ckHXG+n5vZAJcuVz4j5Sp/oEZyyEzsGXp69YsfUfTmzwTat/aeDbB90mWKoghKy60pbBQgn8XwLIXpgXOBylj8gCQy8IFqMGaN2h+VYkkJFQmQOd4eIxyNBFUFX3IFxaXCyJSkzBnLERi7EabVs2Cvp4C/azawP490ff98eiXwBMhprSkvid3dmIFPpLNJBBcuLWf9IQzk2WQDP3Wv1o6yrGItvhRgrMyyOi2XNbBjcZaZ04RVYGMR1NshekP7ykMxbPOzwMfv+hyi+wND/IysG/klbWCvtU1JmQk/16iJzuH0Bxnq60NNPmZP1OEYdiMuD3Ri/2iaknfcyNh5cub9ms4j+x6eCuppqrCs+K3PNopibcdRbQ7GdDF/LacylJ9pz2F7S/HR4d8TZLyXPzJQ3eAmGt0QE40hSWENfpo0k4G+cyUowRww9uADbft1skyOoNcALaUkoICMTtr06hp0yA3UdF3sj1gP9cNGhxpYSWr09zIef4c5mM1a1xHVbzMzAZn+4PotPTH+dLVXOyDDN2zXD0/Mlhr2g+I32Bw1YK1YqZl1wMcjqcNNOoO5eXoPj4sCfW36d98UPRAZbKw0H9qVan2qOgxUX3quKFvTUMAZ4GhUIQBc389ao2wERq1Kr4VLxnS0zgI5uW5fEutGW8epkBGV43Mv5c3J+Uf2yKW50/ZJhrmME13N47z4IGu08H2BM3MgHGYuYBD8E/5yxi/zBrBtJgD6wcjBSY3dKLv6Zi5BhY5eUruOUGHffxdV3aHimL7yfdSAKF1g/7OL/z/lONKsQLu77B0OmLMhwAYW3dZ0Nooysw9ydlsdy5CnfSFsDQfa87lvRQMf6WODC5o4DfqE5Io7mwExFHx1C8RUkseyNfk30UMbhN+KzMD8es40eRsP87tCFkeLwylFvPJFD8ZjMKpH6/nlOhC5YmEJN/V6XsOjHiCuaE6oyGGgK44qKy+2JCnEG+0hsk4kSLvK7I//LdLSJHwgomNUDRbQLGWhS6eXHEkEzR96rPM71SDNDI4xjSmHIcXDNUTjNCt00HwdvgYesL68EGRerVoldgd2Z9N2oBAL2sxuZqJVbtUtFAvfFKQhXQ9nkqbwKWwCMe2Djgoc5CrcBhSBJvlaaioQg6krt7tLmJyym6MnZk7CY3j4CB9quavul5xcrWEwMafSOPIklX+QbFAJCb6P/Ep2ID6eIjoMy8CpEMsAbFnb+Le9Iug6MEAjxPRYhfF1gZ4tRAP6YP2rF260DUfBloU4zd4jBKhxXBAtNYIcTjEs/zoFitnO/ymIZ/pM5ykBEIR39KNK2hv3OuJMR9OFcvnt03GLB+7g8BHmlqYiyDN75hBxWPN/Snfdhm8588KRC1MFlBeLkv3CRD4bIUrkQnA3viJZ4U8+ObJiS/xWQ= X-Forefront-Antispam-Report: CIP:255.255.255.255;CTRY:;LANG:en;SCL:1;SRV:;IPV:NLI;SFV:NSPM;H:CY8PR10MB7243.namprd10.prod.outlook.com;PTR:;CAT:NONE;SFS:(13230040)(376014)(366016)(1800799024)(921020);DIR:OUT;SFP:1101; X-MS-Exchange-AntiSpam-MessageData-ChunkCount: 1 X-MS-Exchange-AntiSpam-MessageData-0: 8KCotQkqutOnpFisZAMB1x6KQ7SOLa/OPOB58i1F7fGtK4DOgTMfw80jAEILHlz4zKO4k7OGVMtuuLKEceThI/l3yzA7tcCRg9+rXMLIsbA1GdTGqfAtfyd4ovQIrqpFqwnjsOVj8LIBCYUlJ3lGBszqaqI6icgd08O8k6jNDYNblaKEfw/aTy+1qeNCff7DZqNUCDxL1HvzbfpEvV8PDPVP2NLkb7lk5NsgAoU65W6NrY9tSDJeS3nj36YOovyoHUrTscDDzvHLu9hkrC6J6XP9paH00Ypk8t8lZXDlnE/kcaGzxcBVoo0+K324wVqm1oMOG6JpOjWzSU6m89Z6PNrg8cmzX2wGH+f0JJujV+qz4s1J7/JOxJ9NCZ21FP7qspEk0LGjTUUqjsJCAhjoF+F3N8FDR3DwbtakytA9xnvoe8ibLa6NTRQP2OQW9GJvngJ7sSO1539iETG4aT0PX+DtjW/XxuBkVsJo+CoQQ38pgradvtmNhMQ5sjal5OE5QVrDDQPEhPOxfXvYQoQOrjJkxYg1ZXcqxQqv/FwzML+S9wlSQJrtnP7B1Bf3wQWLRbftVy+TSvHI8z9xCpqC0VZc2GhXwa5ywxwBkVn3zRFgW/suSYdT3aJ5laTMtcb10T6adUYcULqj7Rbje9PZw1qPlko7zj8QlKU/3dzXLec/gmxpTtVmBrjWSuW1WtadVPviweqbQY/+tgUAg8MVhs3dvNo8QYa8jISu6aeLRorUx1U0C180T5ngxsES0hQX+JbVWMB35xBeNdaHx+17QcB7p1jaC50BfasOxaz/bB1r0oJkBaiMORfjL+dXyP7fAc7ztNzc1JJ18SV5S/djbC/lII5PzpGJcMmdGaAtTeAg45vju46OfLOJh3wfIWQERK/OVV35hGblibBFieZG3YFAhr5aCbIyCenpYhQjg7O752Lr/w0wbGQNPx/1+nzpJaVFPJtrFNAhZ8Okp7WUVGesJZqFb8Vy2BhkH9x8jXqt1gFGmWTQpWidePBRru6wt+h64aOuoHnv5BLwj/uLtW0hc+sYbBnA9Cwwn2KWJYIGV4giQCYYUiqXSBKYC5f4wbxdI0R1NJbOOlPnzo19dfXjhGUHoXbIvZKN0ULkKXqQil8bp1eI/fhRSPzYCgI1GhMXUb7CHDtwQbQ1C0u+7XMj0hBAW7881hSfE3YnBl3haDzeIt9A1w+tdyt8+BS6cgZ2mvbXagDd62CLfqWT/WiZ1aeGJVgvaWGyckmpQtdWD73iCwVM0rCEsjgY3phBolWspOXgyxAZOSc4stWA8/1HY5e+o3VpnIim0nI6ZF2GvJElIxRGXb1NVu7yf+r8arMkWra0H3MQFH2u/Dco+WmMi2IpaJKLeDNcBUeNP8CWIv+Dqfw66Hbxul4X8OC1Or7DNI8KGv51evHgyT7o/IBeiTobJyER1+YpJzOIyPJZo9AUA6Q+I8RceV5iUf0HVmwdYNn1ukJ1X7IEvo1qdkxOl9vI4MoqJapHSlt3xywBLgI1uS7Nw7IxRnK3iaXNWMA4WoP6vKA4gD55rO3AU3e2CUudPNqvY1MX7Kc+DxvvnVMIXW19iikxQBiVbew/KRuCGkC1vMF2ggq9fFFPsw== X-MS-Exchange-AntiSpam-ExternalHop-MessageData-ChunkCount: 1 X-MS-Exchange-AntiSpam-ExternalHop-MessageData-0: GbM8OQPYYZu4A6H8t2w5L6Qpp7Pybc1bNk7UhlwcAaZkiIPsUEXROGRh+l633aRelq6w6OCtN/VdzuUh8dqdT9+FhnC+f+ReZn7pSmNpQnY/MYS5U0eVjEWkPACg16D3GGDKny70AConVbrd9OGUVjNv/uv3RLmXGdkftOD5XUBDFM1Rk25pI7it8N+8FoUKk8ey2Ke890fqTP6S33dLYF3Ohqfoae+ajU2kB368AeILhHgTN5d+gBgerO5kAXYRD8HW6oQBjUHzDnPOBcsVPtvxbVOjKuI3qMFlxp1Pd6tN6BYKAaAHb59PpXwROXHXh0RvqzeZISGpOa3SXFuoLCu91DkC+1no/q1Wnp4avmu/YI8VU7/ul0WSU3FVqXKoWanD8zBt3Re/Sk3fYZ5BwS8B8BJe+Pt7z8sUa/poDTTxQHCT5UStqT09qE7an7NQhq4siADYLIuMLFy5Ov7u94rM2jP9EgEu93FdesdC5RDsFie8RHtE629qII9ePjFzrtsTDHz0dkJ6vhtgEIs74zXYBPUi80gD7H5aID7D+UHpqZWvrJEuJ/BjkXZWA8mhqNhIFRyzwMABDmxhMCsypmG1d/5yAOtT9SWTtOCPaao= X-OriginatorOrg: oracle.com X-MS-Exchange-CrossTenant-Network-Message-Id: 1804c362-c86a-4437-d09f-08dd61ef1119 X-MS-Exchange-CrossTenant-AuthSource: CY8PR10MB7243.namprd10.prod.outlook.com X-MS-Exchange-CrossTenant-AuthAs: Internal X-MS-Exchange-CrossTenant-OriginalArrivalTime: 13 Mar 2025 05:22:36.9616 (UTC) X-MS-Exchange-CrossTenant-FromEntityHeader: Hosted X-MS-Exchange-CrossTenant-Id: 4e2c6054-71cb-48f1-bd6c-3a9705aca71b X-MS-Exchange-CrossTenant-MailboxType: HOSTED X-MS-Exchange-CrossTenant-UserPrincipalName: 6wUMUkrFI1xiKVYCkQqqx3Wi7thC9UiRYMcBscLNKKmseOZDpluDw1mjT8YYCqKD0R3c3k/rvaKuN2QL2NM1T6fFCc3uul6xHyRM+getcVw= X-MS-Exchange-Transport-CrossTenantHeadersStamped: IA0PR10MB6724 X-Proofpoint-Virus-Version: vendor=baseguard engine=ICAP:2.0.293,Aquarius:18.0.1093,Hydra:6.0.680,FMLib:17.12.68.34 definitions=2025-03-13_02,2025-03-11_02,2024-11-22_01 X-Proofpoint-Spam-Details: rule=notspam policy=default score=0 mlxlogscore=999 phishscore=0 suspectscore=0 adultscore=0 spamscore=0 mlxscore=0 bulkscore=0 malwarescore=0 classifier=spam adjust=0 reason=mlx scancount=1 engine=8.12.0-2502280000 definitions=main-2503130040 X-Proofpoint-GUID: s0DM4rn1R6X2mYOlPvghvSaACmmNKSel X-Proofpoint-ORIG-GUID: s0DM4rn1R6X2mYOlPvghvSaACmmNKSel The nvmet_mdev_pci driver is going to look like a local PCI driver to the guest so this patch adds support to create static controllers. Because the current code assumes dynamic controllers, this new interface is a little odd so both can co-exist. There's 2 major differences: 1. Instead of enabling the port when we link a subsys, it's enabled when we enable a controller under the port (the controller enablement requires a subsystem linked to it). 2. You have to make a controller in configfs. You make and setup the subsystem, namespace, and host like normal. You then make the port like before, but you now have a static_controller dir under the port. In this dir, you can create controllers and then link them to subsystems. You then enable the controller. Here is a manual (if we are ok with this I'll fix up nvmetcli) that assumes the subsystem, namespace, and host and port have been created already: Here we create a controller with cntrlid 1 under port 1: mkdir .../nvmet/ports/1/static_controllers/1 You then set the type: echo mdev-pci > .../nvmet/ports/1/static_controllers/1/trtype and instead of linking the subsys to the old dir, you use the controller's dir: ln -s ...nvmet/subsystems/nqn.my.subsys \ ...nvmet/ports/1/static_controllers/1/subsystem/nqn.my.subsys" You then enable the controller: echo 1 > .../nvmet/ports/1/static_controllers/1/enable Signed-off-by: Mike Christie --- drivers/nvme/target/configfs.c | 324 ++++++++++++++++++++++++++++++++- drivers/nvme/target/core.c | 6 +- drivers/nvme/target/nvmet.h | 1 + 3 files changed, 328 insertions(+), 3 deletions(-) diff --git a/drivers/nvme/target/configfs.c b/drivers/nvme/target/configfs.c index 896ae65e4918..65b6cbffe805 100644 --- a/drivers/nvme/target/configfs.c +++ b/drivers/nvme/target/configfs.c @@ -1666,7 +1666,8 @@ static ssize_t nvmet_subsys_attr_qid_max_store(struct config_item *item, /* Force reconnect */ list_for_each_entry(ctrl, &subsys->ctrls, subsys_entry) - ctrl->ops->delete_ctrl(ctrl); + if (!(ctrl->ops->flags & NVMF_STATIC_CTRL)) + ctrl->ops->delete_ctrl(ctrl); up_write(&nvmet_config_sem); return cnt; @@ -1976,6 +1977,323 @@ static const struct config_item_type nvmet_ana_groups_type = { .ct_owner = THIS_MODULE, }; +struct nvmet_ctrl_conf { + struct nvmet_alloc_ctrl_args args; + struct config_group group; + struct config_group subsys_group; + struct nvmet_ctrl *ctrl; + char hostnqn[NVMF_NQN_SIZE]; + char subsysnqn[NVMF_NQN_SIZE]; +}; + +static inline +struct nvmet_ctrl_conf *to_nvmet_ctrl_conf(struct config_item *item) +{ + return container_of(to_config_group(item), struct nvmet_ctrl_conf, + group); +} + +static bool nvmet_is_ctrl_enabled(struct nvmet_ctrl_conf *conf, + const char *caller) +{ + if (conf->ctrl) + pr_err("Disable ctrl '%u' before changing attribute in %s\n", + conf->args.cntlid, caller); + return conf->ctrl ? true : false; +} + +static ssize_t nvmet_ctrl_enable_show(struct config_item *item, char *page) +{ + struct nvmet_ctrl_conf *conf = to_nvmet_ctrl_conf(item); + + return snprintf(page, PAGE_SIZE, "%d\n", conf->ctrl ? true : false); +} + +static ssize_t nvmet_ctrl_enable_store(struct config_item *item, + const char *page, size_t count) +{ + struct nvmet_port *port = to_nvmet_port(item->ci_parent->ci_parent); + struct nvmet_ctrl_conf *conf = to_nvmet_ctrl_conf(item); + struct nvmet_ctrl *ctrl; + bool val; + int ret; + + if (kstrtobool(page, &val)) + return -EINVAL; + + if (!val) + return -EINVAL; + + down_read(&nvmet_config_sem); + if (conf->ctrl) { + up_read(&nvmet_config_sem); + return -EINVAL; + } + + if (!conf->args.ops) { + pr_err("trtype must be set before enabling controller.\n"); + up_read(&nvmet_config_sem); + return -EINVAL; + } + + if (!conf->args.subsysnqn) { + pr_err("subsystem must be set before enabling controller.\n"); + up_read(&nvmet_config_sem); + return -EINVAL; + } + + if (port->enabled) { + pr_err("Cannot create new controllers on enabled port.\n"); + up_read(&nvmet_config_sem); + return -EBUSY; + } + + if (port->disc_addr.trtype != conf->args.ops->type) { + pr_err("Port trtype and controller trtype must match.\n"); + up_read(&nvmet_config_sem); + return -EINVAL; + } + + conf->args.hostnqn = conf->hostnqn; + conf->args.port = port; + up_read(&nvmet_config_sem); + + ctrl = nvmet_alloc_ctrl(&conf->args); + if (!ctrl) + return count; + + down_read(&nvmet_config_sem); + /* Check if a user did this while nvmet_config_sem was dropped */ + if (port->enabled) { + pr_err("Controller and port were already setup.\n"); + ret = -EBUSY; + goto out_put_ctrl; + } + + ret = nvmet_enable_port(port); + if (ret) + goto out_put_ctrl; + + conf->ctrl = ctrl; + up_read(&nvmet_config_sem); + + return count; + +out_put_ctrl: + up_read(&nvmet_config_sem); + nvmet_ctrl_put(ctrl); + return ret; +} +CONFIGFS_ATTR(nvmet_ctrl_, enable); + +static ssize_t nvmet_ctrl_trtype_show(struct config_item *item, char *page) +{ + struct nvmet_ctrl_conf *conf = to_nvmet_ctrl_conf(item); + + if (!conf->args.ops) + return sprintf(page, "\n"); + + return nvmet_trtype_show(conf->args.ops->type, page); +} + +static ssize_t nvmet_ctrl_trtype_store(struct config_item *item, + const char *page, size_t count) +{ + struct nvmet_ctrl_conf *conf = to_nvmet_ctrl_conf(item); + const struct nvmet_fabrics_ops *ops = NULL; + int i; + + if (nvmet_is_ctrl_enabled(conf, __func__)) + return -EACCES; + + down_write(&nvmet_config_sem); + for (i = 0; i < ARRAY_SIZE(nvmet_transport); i++) { + if (sysfs_streq(page, nvmet_transport[i].name)) { + ops = nvmet_get_ops_by_transport( + nvmet_transport[i].type); + break; + } + } + + if (ops && (ops->flags & NVMF_STATIC_CTRL)) { + conf->args.ops = ops; + up_write(&nvmet_config_sem); + return count; + } + up_write(&nvmet_config_sem); + + pr_err("Invalid value '%s' for trtype\n", page); + return -EINVAL; +} +CONFIGFS_ATTR(nvmet_ctrl_, trtype); + +static struct configfs_attribute *nvmet_ctrl_attrs[] = { + &nvmet_ctrl_attr_trtype, + &nvmet_ctrl_attr_enable, + NULL, +}; + +static void nvmet_ctrl_release(struct config_item *item) +{ + struct nvmet_ctrl_conf *conf = to_nvmet_ctrl_conf(item); + struct nvmet_port *port = conf->args.port; + struct module *mod = NULL; + + if (conf->args.ops) + mod = conf->args.ops->owner; + + if (conf->ctrl) { + conf->args.ops->delete_ctrl(conf->ctrl); + nvmet_ctrl_put(conf->ctrl); + } + + kfree(conf); + + /* + * We wait for the last user of the port before disabling to make + * it easier on the driver. It knows the controllers will be freed + * and will not require extra locking. + */ + down_write(&nvmet_config_sem); + if (port && port->enabled && list_empty(&port->subsystems)) + nvmet_disable_port(port); + up_write(&nvmet_config_sem); + + if (mod) + module_put(mod); +} + +static struct configfs_item_operations nvmet_ctrl_item_ops = { + .release = nvmet_ctrl_release, +}; + +static const struct config_item_type nvmet_ctrl_type = { + .ct_attrs = nvmet_ctrl_attrs, + .ct_item_ops = &nvmet_ctrl_item_ops, + .ct_owner = THIS_MODULE, +}; + +static int nvmet_ctrl_subsys_allow_link(struct config_item *parent, + struct config_item *target) +{ + struct nvmet_ctrl_conf *conf = to_nvmet_ctrl_conf(parent->ci_parent); + struct nvmet_port *port = to_nvmet_port(parent->ci_parent->ci_parent->ci_parent); + struct nvmet_subsys_link *link, *p; + struct nvmet_subsys *subsys; + int ret; + + if (target->ci_type != &nvmet_subsys_type) { + pr_err("can only link subsystems into the subsystem directory.\n"); + return -EINVAL; + } + + down_write(&nvmet_config_sem); + if (conf->args.subsysnqn) { + pr_err("subsystem %s already set to controller %u\n", + conf->subsysnqn, conf->args.cntlid); + ret = -EBUSY; + goto out_unlock; + } + + subsys = to_subsys(target); + link = kmalloc(sizeof(*link), GFP_KERNEL); + if (!link) { + ret = -ENOMEM; + goto out_unlock; + } + link->subsys = subsys; + + ret = -EEXIST; + list_for_each_entry(p, &port->subsystems, entry) { + if (p->subsys == subsys) + goto out_free_link; + } + list_add_tail(&link->entry, &port->subsystems); + + memcpy(conf->subsysnqn, subsys->subsysnqn, NVMF_NQN_SIZE); + conf->args.subsysnqn = conf->subsysnqn; + conf->args.port = port; + up_write(&nvmet_config_sem); + return 0; + +out_free_link: + kfree(link); +out_unlock: + up_write(&nvmet_config_sem); + return ret; +} + +static void nvmet_ctrl_subsys_drop_link(struct config_item *parent, + struct config_item *target) +{ + struct nvmet_ctrl_conf *conf = to_nvmet_ctrl_conf(parent->ci_parent); + struct nvmet_subsys *subsys = to_subsys(target); + struct nvmet_port *port = conf->args.port; + struct nvmet_subsys_link *p; + + down_write(&nvmet_config_sem); + list_for_each_entry(p, &port->subsystems, entry) { + if (p->subsys == subsys) + goto found; + } + up_write(&nvmet_config_sem); + return; + +found: + list_del(&p->entry); + conf->args.subsysnqn = NULL; + up_write(&nvmet_config_sem); + kfree(p); +} + +static struct configfs_item_operations nvmet_ctrl_subsys_item_ops = { + .allow_link = nvmet_ctrl_subsys_allow_link, + .drop_link = nvmet_ctrl_subsys_drop_link, +}; + +static const struct config_item_type nvmet_ctrl_subsys_type = { + .ct_item_ops = &nvmet_ctrl_subsys_item_ops, + .ct_owner = THIS_MODULE, +}; + +static struct +config_group *nvmet_ctrl_make_group(struct config_group *group, + const char *name) +{ + struct nvmet_ctrl_conf *conf; + u16 cntlid; + + if (kstrtou16(name, 0, &cntlid)) + return ERR_PTR(-EINVAL); + + if (cntlid >= NVMET_MAX_CNTLID) + return ERR_PTR(-EINVAL); + + conf = kzalloc(sizeof(*conf), GFP_KERNEL); + if (!conf) + return ERR_PTR(-ENOMEM); + + conf->args.cntlid = cntlid; + + config_group_init_type_name(&conf->group, name, &nvmet_ctrl_type); + config_group_init_type_name(&conf->subsys_group, "subsystem", + &nvmet_ctrl_subsys_type); + configfs_add_default_group(&conf->subsys_group, &conf->group); + + return &conf->group; +} + +static struct configfs_group_operations nvmet_controllers_group_ops = { + .make_group = nvmet_ctrl_make_group, +}; + +static const struct config_item_type nvmet_controllers_type = { + .ct_group_ops = &nvmet_controllers_group_ops, + .ct_owner = THIS_MODULE, +}; + +static struct config_group nvmet_controllers_group; + /* * Ports definitions. */ @@ -2079,6 +2397,10 @@ static struct config_group *nvmet_ports_make(struct config_group *group, "ana_groups", &nvmet_ana_groups_type); configfs_add_default_group(&port->ana_groups_group, &port->group); + config_group_init_type_name(&nvmet_controllers_group, + "static_controllers", &nvmet_controllers_type); + configfs_add_default_group(&nvmet_controllers_group, &port->group); + port->ana_default_group.port = port; port->ana_default_group.grpid = NVMET_DEFAULT_ANA_GRPID; config_group_init_type_name(&port->ana_default_group.group, diff --git a/drivers/nvme/target/core.c b/drivers/nvme/target/core.c index f587ec410023..f8a157e1046b 100644 --- a/drivers/nvme/target/core.c +++ b/drivers/nvme/target/core.c @@ -336,7 +336,8 @@ void nvmet_port_del_ctrls(struct nvmet_port *port, struct nvmet_subsys *subsys) mutex_lock(&subsys->lock); list_for_each_entry(ctrl, &subsys->ctrls, subsys_entry) { - if (ctrl->port == port) + if (ctrl->port == port && + !(ctrl->ops->flags & NVMF_STATIC_CTRL)) ctrl->ops->delete_ctrl(ctrl); } mutex_unlock(&subsys->lock); @@ -1889,7 +1890,8 @@ void nvmet_subsys_del_ctrls(struct nvmet_subsys *subsys) mutex_lock(&subsys->lock); list_for_each_entry(ctrl, &subsys->ctrls, subsys_entry) - ctrl->ops->delete_ctrl(ctrl); + if (!(ctrl->ops->flags & NVMF_STATIC_CTRL)) + ctrl->ops->delete_ctrl(ctrl); mutex_unlock(&subsys->lock); } diff --git a/drivers/nvme/target/nvmet.h b/drivers/nvme/target/nvmet.h index 990dd43df5c9..f652c62ebdd2 100644 --- a/drivers/nvme/target/nvmet.h +++ b/drivers/nvme/target/nvmet.h @@ -404,6 +404,7 @@ struct nvmet_fabrics_ops { #define NVMF_KEYED_SGLS (1 << 0) #define NVMF_METADATA_SUPPORTED (1 << 1) #define NVMF_SGLS_NOT_SUPP (1 << 2) +#define NVMF_STATIC_CTRL (1 << 3) void (*queue_response)(struct nvmet_req *req); int (*add_port)(struct nvmet_port *port); void (*remove_port)(struct nvmet_port *port); From patchwork Thu Mar 13 05:18:09 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Mike Christie X-Patchwork-Id: 14014347 Received: from mx0b-00069f02.pphosted.com (mx0b-00069f02.pphosted.com [205.220.177.32]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 0C5171D5CDE for ; Thu, 13 Mar 2025 05:24:52 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=fail smtp.client-ip=205.220.177.32 ARC-Seal: i=2; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1741843494; cv=fail; b=PDbUPC5RZlNDo+TBPkwqmPubHyoT8OxbPi+/wPejupNwO8/MFeJ85/gkjkYEBdqYDenUQbywUxlKOQatjC55arIYPpGt8DYRqYhkDUALnjuUwM41/Ashv0SMuVIsgfNFN152a3BAHl582OZBHnGJ74DjRPBr71zQZc2uJk2tnfY= ARC-Message-Signature: i=2; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1741843494; c=relaxed/simple; bh=fXQuP+CYiFVoUf5gl0lWL2tWZvXpWv2SGakasCwhDW4=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: Content-Type:MIME-Version; b=pRCSSHDW85F9HOel1CIvYiYrYRZZGbx8jtnxpnO/c49QGVp1uOcq1rnvzst/PKvvGDgkHUBbS4kQe+FAVu/YVrv02DRKR6fRcI/TQ2GAPq1a4xKmF1mLAloEcrqwktHF4HQM1WDftXRplioC8iOcJ15vja93d5QG4/DOUEbFjtI= ARC-Authentication-Results: i=2; smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=oracle.com; spf=pass smtp.mailfrom=oracle.com; dkim=pass (2048-bit key) header.d=oracle.com header.i=@oracle.com header.b=JoRxiiga; dkim=pass (1024-bit key) header.d=oracle.onmicrosoft.com header.i=@oracle.onmicrosoft.com header.b=FcbZGwGy; arc=fail smtp.client-ip=205.220.177.32 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=oracle.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=oracle.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=oracle.com header.i=@oracle.com header.b="JoRxiiga"; dkim=pass (1024-bit key) header.d=oracle.onmicrosoft.com header.i=@oracle.onmicrosoft.com header.b="FcbZGwGy" Received: from pps.filterd (m0246631.ppops.net [127.0.0.1]) by mx0b-00069f02.pphosted.com (8.18.1.2/8.18.1.2) with ESMTP id 52D3tn8M011514; Thu, 13 Mar 2025 05:22:42 GMT DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=oracle.com; h=cc :content-transfer-encoding:content-type:date:from:in-reply-to :message-id:mime-version:references:subject:to; s= corp-2023-11-20; bh=k/xDWMgD1Lw+3Lyvz3067UPO3gGox7QR/u/h6AifK4A=; b= JoRxiigaaxciRoCsQonFgL5PWgacU1w5/y+cNPNNGYM1HJzKLsRHCScarA2jcZ6b efCozpXR4wAhTjokWm2O+8BBLKvbSCk5TM9H4QlWxnelsIAFlZ+a0HaMUitTt31f Q/KJdQQHTwASvBcj7rKwGqXiCSvWCtbdKoIH178h6HRAfSO7fDH0K6s5/mYyohXd +JVAvgS8OboUk9wZQKgDL/XEdmBseC7KBEYO2HyWurFPnxB0YbKK28UeZXsY0KCb 2DJtwyD8txJkj89Qj4xyLkGJq0JivjY7OaVMNCRLjxIb9OSVRsc8uhBunIUs1Pr0 OG4Pn5Q3x/ioPLn5WznL1w== Received: from phxpaimrmta02.imrmtpd1.prodappphxaev1.oraclevcn.com (phxpaimrmta02.appoci.oracle.com [147.154.114.232]) by mx0b-00069f02.pphosted.com (PPS) with ESMTPS id 45au4hbee2-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=OK); Thu, 13 Mar 2025 05:22:42 +0000 (GMT) Received: from pps.filterd (phxpaimrmta02.imrmtpd1.prodappphxaev1.oraclevcn.com [127.0.0.1]) by phxpaimrmta02.imrmtpd1.prodappphxaev1.oraclevcn.com (8.18.1.2/8.18.1.2) with ESMTP id 52D4Lh8n022282; Thu, 13 Mar 2025 05:22:41 GMT Received: from nam10-dm6-obe.outbound.protection.outlook.com (mail-dm6nam10lp2040.outbound.protection.outlook.com [104.47.58.40]) by phxpaimrmta02.imrmtpd1.prodappphxaev1.oraclevcn.com (PPS) with ESMTPS id 45atmw5mtj-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=OK); Thu, 13 Mar 2025 05:22:41 +0000 ARC-Seal: i=1; a=rsa-sha256; s=arcselector10001; d=microsoft.com; cv=none; b=Ut/Oq6DCGEX/qiRiDL2AULxPBByhc5UWGy3WDAzi28HR+GRYjDvuqRUPSH7uOHBJqHoUg6IQfKOk484PODtRSdof2kFcHqLo54yBAD557OSYNdFMo0miWVUI1/awuR1Rl1YV4Mwna2yfThiL91mBnK1aa1zpQQX9IWztMZ7UytJEYFfQO2cRhvPR5/OBwPc72+pD2xMRnAEQQpH+y6fAgH8zSihCQiaRrTL3ZheCq35VmrdZmAjmLwxalwj3mOhM7eeXlGm7WPeMuaQ8rinW9cTxpU230kqmfvtSdtV51Ug4K1pRXVTyeI8sQIfz9ls2V6VMYGaO7uj7jCL/2+79sQ== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=microsoft.com; s=arcselector10001; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-AntiSpam-MessageData-ChunkCount:X-MS-Exchange-AntiSpam-MessageData-0:X-MS-Exchange-AntiSpam-MessageData-1; bh=k/xDWMgD1Lw+3Lyvz3067UPO3gGox7QR/u/h6AifK4A=; b=wd+Hd+TyTaISC6AY5iBcnGo959hPRDd0rcfLYGIRRnwPCYANRi4PpehPNazU1ECLQnwauKcOYg1QAqOP91HStZizr6AHgiGBCF+85s+l3dINHhsoxLI/6j/VXeVbLw4VqGriJ0T46fB0Wo61qSwyjyYcZ2zw7I1nWUDoxrYizgftRCAfcchgf4FR1sj0KU5kinkd48PPiZtJOePLbjXt6L9FfS9tNvH+Gqp741gZWoIuqNDffKoYM6VTETZA8iBrPh8ByswGKSxlJzg4f2eNRhvoFR2hdJjRvxE6EMQkY+3smC66r+gI0CCgWTZj6eYc665OGokeW2kBq5vQ2ZzsTw== ARC-Authentication-Results: i=1; mx.microsoft.com 1; spf=pass smtp.mailfrom=oracle.com; dmarc=pass action=none header.from=oracle.com; dkim=pass header.d=oracle.com; arc=none DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=oracle.onmicrosoft.com; s=selector2-oracle-onmicrosoft-com; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck; bh=k/xDWMgD1Lw+3Lyvz3067UPO3gGox7QR/u/h6AifK4A=; b=FcbZGwGyobwZPbjv4VgqC3IvOh0NnZITr719Fzhs3QCYQnTmi7N/o0PzvOtct/KIr1zSRcwval4fPtv1Rej1wDqZCriVo9d77f7DTZasW+zuR6FGwkxkMV/tBn9MWfHr55mXXj488mw5t3Pwynm7c9w3EAslas0DvAMjOHUsXig= Received: from CY8PR10MB7243.namprd10.prod.outlook.com (2603:10b6:930:7c::10) by IA0PR10MB6724.namprd10.prod.outlook.com (2603:10b6:208:43e::5) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.8511.27; Thu, 13 Mar 2025 05:22:38 +0000 Received: from CY8PR10MB7243.namprd10.prod.outlook.com ([fe80::b779:d0be:9e3a:34f0]) by CY8PR10MB7243.namprd10.prod.outlook.com ([fe80::b779:d0be:9e3a:34f0%4]) with mapi id 15.20.8511.026; Thu, 13 Mar 2025 05:22:38 +0000 From: Mike Christie To: chaitanyak@nvidia.com, kbusch@kernel.org, hch@lst.de, sagi@grimberg.me, joao.m.martins@oracle.com, linux-nvme@lists.infradead.org, kvm@vger.kernel.org, kwankhede@nvidia.com, alex.williamson@redhat.com, mlevitsk@redhat.com Cc: Mike Christie Subject: [PATCH RFC 08/11] nvmet: Add shadow doorbell support Date: Thu, 13 Mar 2025 00:18:09 -0500 Message-ID: <20250313052222.178524-9-michael.christie@oracle.com> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20250313052222.178524-1-michael.christie@oracle.com> References: <20250313052222.178524-1-michael.christie@oracle.com> X-ClientProxiedBy: CH3P220CA0009.NAMP220.PROD.OUTLOOK.COM (2603:10b6:610:1e8::27) To CY8PR10MB7243.namprd10.prod.outlook.com (2603:10b6:930:7c::10) Precedence: bulk X-Mailing-List: kvm@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 X-MS-PublicTrafficType: Email X-MS-TrafficTypeDiagnostic: CY8PR10MB7243:EE_|IA0PR10MB6724:EE_ X-MS-Office365-Filtering-Correlation-Id: 1df68a35-fcfe-4248-4d4c-08dd61ef123a X-MS-Exchange-SenderADCheck: 1 X-MS-Exchange-AntiSpam-Relay: 0 X-Microsoft-Antispam: BCL:0;ARA:13230040|376014|366016|1800799024|921020; X-Microsoft-Antispam-Message-Info: x/UT5ATBGMWHIHvNUeyd8K2a+p/z9X79P0CobB1ksbIjJW//Tl2cMM6CWVIrgp0rPFl1XlJ8AMbPjDY8kaBYWycfa0z4RY6JxXw6mXWMKMZGOHFt12KKsIkrrTJ39gzufiiDSbpsQDmrdEutZVGzy7XY+D+L8qo2DmpGgyglSrPLJ/v15Ynbyoh0vdaZ6kKbJR4J4U3nUWwMLkcBqupL5c21qT/TH6j3sZJe7mdPmKQsN/nn/Ok4SYTlqdoNaIJKQVbTC1eMPfrSawlCNBkBBNR1yNz3sxvkoDvt02vGBJm5lBkc/davLxPcT8cew56thX5TrJSYVWQUBfZ5PjIOGlsPL647yyU8pzj1L99HzL268LHMxz50D6Qp39rmgZqFYYVLVuOdi7c8y/gkCrDaavkDMesBDBXI/Qt8QXX0xdEyfEEJcxcNFOSe7UwJkqfpqBRoQacW4Y6ibKDgx+Gb3pjNPQOICRQxZmldXPE8zLa7LrKxg1276GPXpMYl0OlVzAFtLjAPb5DW7k23a/BsCK1dCVe6I87LOElvK6QKgpDrecFu52WprXBKLHgqjV/NUWGqKlO1RnHMxYnggCrHWNTXgQQddWKRijiKFoM2xA9jrqxRwyS29sh9SDcRyVbe3gRaD3CA4zu0WrB4CbXDXzFiBZSwqLogBnLMH06M8g+gUJA0hb44qrwN0vytRGQ8K0u6KIzhiaB46KQtfZ+kEhEFUNOTOcpSUWSoNTCxOPqB8edBEbenww2EXNISQLWXnJ+pJ2MRyxPpX8TUmXA2xbqAqHiDHR3JjrHWf06aquRBygShL5bpKVLKS7njdbg2X9PrqAxC2hOoxSmpDgAhJ6DemMJyX/7rapRV0Sf1JS+6yFuZ2lQioZS5olNKw5S+sozGprACvPxinhgmc8fFZcSXBF8KEBYeETIfdcnK/XmRwTePpF598vkCQYWeO1keeAQ+6HK4D9tNKNzirgZba/6oOViuwk5hZJppaB/7R/HBie/8G3svXeDgGBVdyisb+f40DbF/6dRdB8Qmi/xBhj1bldd0ot52XC1FmcmZy187bJDz+bttgB+4O23ySjmvYdKzzFefYbMNBl9toKpFORiQhEIWmnHbtFqXLIqZiB+t3sHIP7HpXI4E39fcQYns/GveFCPR/AcwvaBkeg2N0E65l+Ji/WCO1MgvZfdE+QBsLQu65pVYoddSTIkKDw8ZnKxfLaVJi5XlZjnwq0gkFVyWND/7pXfSogPx5GD652IK6tT4klv5wiaCN7NAsEI5k/01KQ7Yiog+PSyYJsmDKXyx+jYvUMvhhtJFujX/TD6eBw/ygsh6F/OdM79DJ/ul8CuRWMGI6dv26qZLYlrLZ3aQPiY7H80jbxYjvGqiFq7rUMqU+TpWbV0iS7J6hT+pa4Stf4PzccnQsmzRq9/vFLJJGwhcY+CzS6jfhjTIKwE= X-Forefront-Antispam-Report: CIP:255.255.255.255;CTRY:;LANG:en;SCL:1;SRV:;IPV:NLI;SFV:NSPM;H:CY8PR10MB7243.namprd10.prod.outlook.com;PTR:;CAT:NONE;SFS:(13230040)(376014)(366016)(1800799024)(921020);DIR:OUT;SFP:1101; X-MS-Exchange-AntiSpam-MessageData-ChunkCount: 1 X-MS-Exchange-AntiSpam-MessageData-0: zIqZvqS7fH0e0nVOJopROtx6dlmuv215FsixzFBlEDRljbquqWk+pZo9dBgODl8W224FTUkXGDWhanNH3fuRKqz+GgoPJFfnVTkTm+BL3ACPQTvfI/691UH7SHGki4tIqWwj7EHb8RO+BcCV7wdCb1he2WnuKPT+ekKDA+y4HfExT9h06/C/k0h6s6wxrwYV78JjGdGFrKIZiU7CD4d1M83/Rz1AHekAmvqr6KPhvWcMd8NkmGWSf/rcGoSuB3zp6ze3zkB3/V8G45B/+yFXqXNFRxzUbhRImegPbUQXa5B+bFNxve2wyVIGOiFYmwwLqAVk8qzBYkhRNqmpND2wIKYAykZAet2CirJQAd8YkVXWYsQf7JjzrJWvPOnW203Eovaz4yU9ZE7enq074UTitMiB3+o+GJeGHE6Laa/gg3C1j7ATNdqGkGAmlLG6qbotyBtvyLDYYLOQN+60IL6fKlLy9M0gGFqSBwpP4USPV+j4nLhqMzuRjlP+6j6S3qRAFLJubiURDJWkhPL+5uA6rtAia/qHGe8EyBRqJ1XNhhFIQb0QpKR6/Zs3WPfmmTlnvVrOAaU/ykJ29G9hYomenEmndIRkK2jzQUr1y9JPQcZTI8Sqbm9DXaMwDnNTMx4jbuXwTfnkSvIEfbpZ6xcNHSpaX4RVExkrJQhlVuvgCf9ckikYxidYAe2QKCvmz0KGLF1jFGaZ9ZVtTgNWrA/fAZgcFVt0DoTPLCy6YuGK3k5qkPupG1H9IhyqwZ2jKHfpfwg/PMzZ0yPFxr4kXmIfM6CBAs1q7+N1nagCCZQb+88vyjdwanT9/gIGz06JoYVPfhFROI0V9Yc0Ni/mtxdIiYbAOSwCg3W2FolLIbQkSGjScLFVin8x8DqkvXN65pmdV1ytM4Az0A6VMERkl8xKyJ+wYuwSo4Pd2mqkSzAHM4RX7HXetAR3WNtnC7QRWkfVtJofqEeVcX5Y5c+6uHq2n6xuxfv+pnrFY5ry3MzkUXeIBstlvrd2wsMuiDvkethhOl8Oxj5itob4rF/kBPeic0+ogss8wTVKW4H/zbsnwi6U/kfrF3gUkxRB0qz4lF9q39FXjbIo4MQdkvkzBXW99BNjUMdQvJUUJhaqvdFqHt1UDv1mRMfODfcjmpZ7PA+EQg0j+Bh74Jqo80RQN+4/pJ3B1w+HYqG+FOQIFAeYIgB3Dv1bzijvJ/KrtX96pzB3jtt3Vnd/hBnVOZMy9lzJKgSMp5ywV0Xo3LbCCBZPVGqaghA/ZLeDNW43OanJvhi4CC8bQA9YGHLPqefvTGjuWBGsqR1buiE3t9J/FHgOITo0CXxe3Gmvwot3c+fe+BZt4Pp/r+dy27oCgmv2vzehKMJS8cUMRLwnnYadf+93CsnWcNPF9hZEtrayzp2g7V+d/4LCqD1aKlbjcG0w3W4Fw0RxT/7s4M47qgME5QudaudetXcG2HR+wiN35Qg+D84fpmvlVNBoKZzHW7VaE3kFar7OlhBTaAOFHoPxHZo2M6zAm2pmsThaKRB1RxmaS7zNzVAsWGmGvRuSoDotbNESPPTa8WQJakyi8UmCTFluenKCSr4avBCYNIagmZLZS9zXc5RevYf5pmZuXyUxuWBCZg== X-MS-Exchange-AntiSpam-ExternalHop-MessageData-ChunkCount: 1 X-MS-Exchange-AntiSpam-ExternalHop-MessageData-0: 4HDHe8TvAZOEmHmqd1//WRLZNIl9wXUeuJHIi9+TexGx6cmBDBngtMusqr2zHWcDGtKdIFEqZuKTmmPHYSeyhQG8YMrjFn8fsH3Oqga+6N23zvobV1vP2biJ+q1SUbSf/Zb3Qj8llt/CyZfc0CuduUlMDLm+aLAkAYjzagMYV2868ceqyEUn49Uemvh857T7/2u95yZt9lFOSWNmRIVriZqVKlGs4szcu3umV82durSNguPfvUryd7EJrDOJVuO/njG3rDKos5wdKM8lVrH++tabY8caHnlXnhQI1X6zdZL3d1VxZiNbh4KUhrcz37dzpM7/kgYUKjSBzP+phnBL9JQEpQeK26BGB3zN4s4FonJ85RVXdQzrd/JSkoRAyA5QoUKl+dcWtzkYrSK/yA3+74obM5ogjy+eBT0n6UyXQIhE02URrCTJbVmb3dAu8AWLOx5mn2HoD8EGIzGMshLj5Z4L8ifaLttNQQEZs5q/ajtu9NNsc/bq41ly7pmI36/3cWNvaL6xrR61Rv4AiNLB0yzsa9y8UCD3KCpWxcKH21KXRUeSdpEW65IQckweMi2eLTbgNDVXJlayKHW0zoMwIfWS7NwQ4dH667S6ZdjDy8w= X-OriginatorOrg: oracle.com X-MS-Exchange-CrossTenant-Network-Message-Id: 1df68a35-fcfe-4248-4d4c-08dd61ef123a X-MS-Exchange-CrossTenant-AuthSource: CY8PR10MB7243.namprd10.prod.outlook.com X-MS-Exchange-CrossTenant-AuthAs: Internal X-MS-Exchange-CrossTenant-OriginalArrivalTime: 13 Mar 2025 05:22:38.8210 (UTC) X-MS-Exchange-CrossTenant-FromEntityHeader: Hosted X-MS-Exchange-CrossTenant-Id: 4e2c6054-71cb-48f1-bd6c-3a9705aca71b X-MS-Exchange-CrossTenant-MailboxType: HOSTED X-MS-Exchange-CrossTenant-UserPrincipalName: 73GW9/SJ6cfD+nbOrqJoiemWf82SCNi+AQ01NQNV54zYdvabN4Bk+e+auQIdm8Lb+/o6CTdAqnIAyCp1DfEX1CurYwKlF/U3RfJfP/f7Ils= X-MS-Exchange-Transport-CrossTenantHeadersStamped: IA0PR10MB6724 X-Proofpoint-Virus-Version: vendor=baseguard engine=ICAP:2.0.293,Aquarius:18.0.1093,Hydra:6.0.680,FMLib:17.12.68.34 definitions=2025-03-13_02,2025-03-11_02,2024-11-22_01 X-Proofpoint-Spam-Details: rule=notspam policy=default score=0 malwarescore=0 phishscore=0 mlxscore=0 spamscore=0 mlxlogscore=999 bulkscore=0 adultscore=0 suspectscore=0 classifier=spam adjust=0 reason=mlx scancount=1 engine=8.12.0-2502280000 definitions=main-2503130040 X-Proofpoint-GUID: _BcA-a0u_NYi_2Ka8Z_wPfFkV3eFX5yQ X-Proofpoint-ORIG-GUID: _BcA-a0u_NYi_2Ka8Z_wPfFkV3eFX5yQ This patch allows a user to enable shadow doorbell support and to report that its supported if the driver also support it. Signed-off-by: Mike Christie --- drivers/nvme/target/admin-cmd.c | 25 ++++++++++++++++++++++++- drivers/nvme/target/configfs.c | 26 ++++++++++++++++++++++++++ drivers/nvme/target/core.c | 1 + drivers/nvme/target/nvmet.h | 4 ++++ 4 files changed, 55 insertions(+), 1 deletion(-) diff --git a/drivers/nvme/target/admin-cmd.c b/drivers/nvme/target/admin-cmd.c index 486ed6f7b717..e15cf25a4033 100644 --- a/drivers/nvme/target/admin-cmd.c +++ b/drivers/nvme/target/admin-cmd.c @@ -378,6 +378,8 @@ static void nvmet_get_cmd_effects_admin(struct nvmet_ctrl *ctrl, cpu_to_le32(NVME_CMD_EFFECTS_CSUPP); } + if (ctrl->ops->set_dbbuf && ctrl->shadow_db) + log->acs[nvme_admin_dbbuf] = cpu_to_le32(NVME_CMD_EFFECTS_CSUPP); log->acs[nvme_admin_get_log_page] = log->acs[nvme_admin_identify] = log->acs[nvme_admin_abort_cmd] = @@ -713,7 +715,8 @@ static void nvmet_execute_identify_ctrl(struct nvmet_req *req) ctratt |= NVME_CTRL_ATTR_RHII; id->ctratt = cpu_to_le32(ctratt); - id->oacs = 0; + if (ctrl->ops->set_dbbuf && ctrl->shadow_db) + id->oacs = cpu_to_le16(NVME_CTRL_OACS_DBBUF_SUPP); /* * We don't really have a practical limit on the number of abort @@ -1640,6 +1643,23 @@ u32 nvmet_admin_cmd_data_len(struct nvmet_req *req) } } +static void nvmet_execute_dbbuf(struct nvmet_req *req) +{ + struct nvmet_ctrl *ctrl = req->sq->ctrl; + struct nvme_command *cmd = req->cmd; + u16 status; + + if (!nvmet_is_pci_ctrl(ctrl)) { + status = nvmet_report_invalid_opcode(req); + goto complete; + } + + status = ctrl->ops->set_dbbuf(ctrl, le64_to_cpu(cmd->dbbuf.prp1), + le64_to_cpu(cmd->dbbuf.prp2)); +complete: + nvmet_req_complete(req, status); +} + u16 nvmet_parse_admin_cmd(struct nvmet_req *req) { struct nvme_command *cmd = req->cmd; @@ -1696,6 +1716,9 @@ u16 nvmet_parse_admin_cmd(struct nvmet_req *req) case nvme_admin_keep_alive: req->execute = nvmet_execute_keep_alive; return 0; + case nvme_admin_dbbuf: + req->execute = nvmet_execute_dbbuf; + return 0; default: return nvmet_report_invalid_opcode(req); } diff --git a/drivers/nvme/target/configfs.c b/drivers/nvme/target/configfs.c index 65b6cbffe805..a946a879b9d6 100644 --- a/drivers/nvme/target/configfs.c +++ b/drivers/nvme/target/configfs.c @@ -2086,6 +2086,31 @@ static ssize_t nvmet_ctrl_enable_store(struct config_item *item, } CONFIGFS_ATTR(nvmet_ctrl_, enable); +static ssize_t nvmet_ctrl_shadow_doorbell_show(struct config_item *item, + char *page) +{ + struct nvmet_ctrl_conf *conf = to_nvmet_ctrl_conf(item); + + return snprintf(page, PAGE_SIZE, "%d\n", conf->args.shadow_db); +} + +static ssize_t nvmet_ctrl_shadow_doorbell_store(struct config_item *item, + const char *page, size_t count) +{ + struct nvmet_ctrl_conf *conf = to_nvmet_ctrl_conf(item); + int ret; + + if (nvmet_is_ctrl_enabled(conf, __func__)) + return -EACCES; + + ret = kstrtobool(page, &conf->args.shadow_db); + if (ret) + return ret; + + return count; +} +CONFIGFS_ATTR(nvmet_ctrl_, shadow_doorbell); + static ssize_t nvmet_ctrl_trtype_show(struct config_item *item, char *page) { struct nvmet_ctrl_conf *conf = to_nvmet_ctrl_conf(item); @@ -2128,6 +2153,7 @@ static ssize_t nvmet_ctrl_trtype_store(struct config_item *item, CONFIGFS_ATTR(nvmet_ctrl_, trtype); static struct configfs_attribute *nvmet_ctrl_attrs[] = { + &nvmet_ctrl_attr_shadow_doorbell, &nvmet_ctrl_attr_trtype, &nvmet_ctrl_attr_enable, NULL, diff --git a/drivers/nvme/target/core.c b/drivers/nvme/target/core.c index f8a157e1046b..1385368270de 100644 --- a/drivers/nvme/target/core.c +++ b/drivers/nvme/target/core.c @@ -1587,6 +1587,7 @@ struct nvmet_ctrl *nvmet_alloc_ctrl(struct nvmet_alloc_ctrl_args *args) goto out_put_subsystem; mutex_init(&ctrl->lock); + ctrl->shadow_db = args->shadow_db; ctrl->port = args->port; ctrl->ops = args->ops; diff --git a/drivers/nvme/target/nvmet.h b/drivers/nvme/target/nvmet.h index f652c62ebdd2..2b0e624b80e1 100644 --- a/drivers/nvme/target/nvmet.h +++ b/drivers/nvme/target/nvmet.h @@ -253,6 +253,7 @@ struct nvmet_ctrl { u64 cap; u32 cc; u32 csts; + bool shadow_db; uuid_t hostid; u16 cntlid; @@ -418,6 +419,8 @@ struct nvmet_fabrics_ops { u8 (*get_mdts)(const struct nvmet_ctrl *ctrl); u16 (*get_max_queue_size)(const struct nvmet_ctrl *ctrl); + u16 (*set_dbbuf)(struct nvmet_ctrl *ctrl, u64 prp1, u64 prp2); + /* Operations mandatory for PCI target controllers */ u16 (*create_sq)(struct nvmet_ctrl *ctrl, u16 sqid, u16 flags, u16 qsize, u64 prp1); @@ -593,6 +596,7 @@ struct nvmet_alloc_ctrl_args { const struct nvmet_fabrics_ops *ops; struct device *p2p_client; u32 kato; + bool shadow_db; u16 cntlid; __le32 result; u16 error_loc; From patchwork Thu Mar 13 05:18:10 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Mike Christie X-Patchwork-Id: 14014342 Received: from mx0a-00069f02.pphosted.com (mx0a-00069f02.pphosted.com [205.220.165.32]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 1F6411D5CDE for ; Thu, 13 Mar 2025 05:22:56 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=fail smtp.client-ip=205.220.165.32 ARC-Seal: i=2; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1741843377; cv=fail; b=keneFb1k2F/xDAhngCsO5K6aFI+3MfG2hLag2Xp/1qoz7DHD/ExKuEtqNQMN3BzOvwxL4P4vC6nUOn88CjsLdGXQ3F0Dnf5rmZ8ELRXNTqOwlD1ZUpCqs0JZFP+DU3uUgDvcA4WGswAh6HhrFDN5oLA6amMCMtAsDa6RP543D+M= ARC-Message-Signature: i=2; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1741843377; c=relaxed/simple; bh=JTTtVJD9nyeuq6zFIGnb8UTGh/0iiyozSFnZeLqE+WU=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: Content-Type:MIME-Version; b=VV4YitCERrKhShBjYjGZbn4LUUPO/MRD2ZpF3Ee+RW5DlOilXPlWygoNb9VP8S8EMgKoaMiaClcVRY8xvCopQWnJgxILfsk45POaA9FdlHCa6YtuPswVutFlKEjdgdYiOXuftRkpKyM6c8NcdoYFUnrMXoMpl0XpDqjP9wT0uUY= ARC-Authentication-Results: i=2; smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=oracle.com; spf=pass smtp.mailfrom=oracle.com; dkim=pass (2048-bit key) header.d=oracle.com header.i=@oracle.com header.b=hWz1gw1t; dkim=pass (1024-bit key) header.d=oracle.onmicrosoft.com header.i=@oracle.onmicrosoft.com header.b=RHnIMx7j; arc=fail smtp.client-ip=205.220.165.32 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=oracle.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=oracle.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=oracle.com header.i=@oracle.com header.b="hWz1gw1t"; dkim=pass (1024-bit key) header.d=oracle.onmicrosoft.com header.i=@oracle.onmicrosoft.com header.b="RHnIMx7j" Received: from pps.filterd (m0246627.ppops.net [127.0.0.1]) by mx0b-00069f02.pphosted.com (8.18.1.2/8.18.1.2) with ESMTP id 52D3uLGS019112; Thu, 13 Mar 2025 05:22:44 GMT DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=oracle.com; h=cc :content-transfer-encoding:content-type:date:from:in-reply-to :message-id:mime-version:references:subject:to; s= corp-2023-11-20; bh=nPz/HhlRuxe4zmzACGzvAswpfFIr4Uj/3ncEqzpfcZA=; b= hWz1gw1twl3WgRz/yi5V0mu4Gz2Y3bFCtlKWKMIj7Sb59l7D3mxTI2lqa0Ve3Um4 S40brbKYnNBRkinC/QN3ptL0Vfq1pjV8Nxeb71bHkS5ejYqVaoVscCHwH+vZcutn NfZi/sAhVpYkJcQo6LEdsjF7UVEzH+R2YOiOrvgPzUjrCNWG82psh4WM70xXrjph Qg8cpj6qXKIBA0YNu6pKepHUuq6sChbzp2sa2BYO19323rN1w1580Dxl3hdyfKAe e9t5yPakmav8zr4E0qGFFO1eG4iyTB8bVc1YtVi89a6J8Vz5sg4iG1uCiwoM1ebl JT65Uqck7rR9E+nBozqryA== Received: from iadpaimrmta01.imrmtpd1.prodappiadaev1.oraclevcn.com (iadpaimrmta01.appoci.oracle.com [130.35.100.223]) by mx0b-00069f02.pphosted.com (PPS) with ESMTPS id 45au6vkes8-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=OK); Thu, 13 Mar 2025 05:22:43 +0000 (GMT) Received: from pps.filterd (iadpaimrmta01.imrmtpd1.prodappiadaev1.oraclevcn.com [127.0.0.1]) by iadpaimrmta01.imrmtpd1.prodappiadaev1.oraclevcn.com (8.18.1.2/8.18.1.2) with ESMTP id 52D3RH9X012272; Thu, 13 Mar 2025 05:22:42 GMT Received: from nam10-dm6-obe.outbound.protection.outlook.com (mail-dm6nam10lp2048.outbound.protection.outlook.com [104.47.58.48]) by iadpaimrmta01.imrmtpd1.prodappiadaev1.oraclevcn.com (PPS) with ESMTPS id 45atn272s0-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=OK); Thu, 13 Mar 2025 05:22:42 +0000 ARC-Seal: i=1; a=rsa-sha256; s=arcselector10001; d=microsoft.com; cv=none; b=h4pQNBH53LJYF0gmG/u++VCia4IL/k8XF8t+Px4m/ki1V7fmwgMZjwnuD01etdmxGRuN1WPDfRzC6U0/SsJhVyAv2YmMkVfJaakIy6BQ2abBszA8Bw9FfVwYT0HCuwocGoF66cTceN2FuXw5kDrlocDq14f4WXUtKZAvjicT/gY5MBYWVxbDgqu959bDgl843YkDh2QoA9b1JKRTS4NzzDmhWrorq1eH+5BLh0xTF31ohfxOUAxRdg2dUMTESOPvt2p6k31JQvH9SyJfB6OGmRQhz3RtMN//+zMLG+eLxTi1g2/cQ57PBMr5s45IPDDQGMed5sEyAWDzRo4pVQ9buQ== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=microsoft.com; s=arcselector10001; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-AntiSpam-MessageData-ChunkCount:X-MS-Exchange-AntiSpam-MessageData-0:X-MS-Exchange-AntiSpam-MessageData-1; bh=nPz/HhlRuxe4zmzACGzvAswpfFIr4Uj/3ncEqzpfcZA=; b=Gu/Y/pNOZ9DPp3rDyxRdimLE3gKX5qBor6yQXns11aoG4HRZ+izV7lZFVGesl9oGfw7ZzhkNYTBeiWnBVSWNwjhP2SAQA9imokhCnbkAGo++sKcN9MJRRN6daf81jW3W1u9+54tWzEDjy9UxIerMXSGt6BcsAlgnGKj7hY4uAc6DaPglBG5Zg8btw3Hbtk1t4322Ci8HIYhbGJJhvDV8Kj6rm3z3wPzhpp9aMiUGMxSWQvapDaco2pxzW+gEdF/hYSKLGstftCZ7Y1SVKbPszFNcMJu0oelefRElErqxDfg6FsFFfXOlngKMi3zl8Hoz/iLB04r7PaifZU/v0CJYHA== ARC-Authentication-Results: i=1; mx.microsoft.com 1; spf=pass smtp.mailfrom=oracle.com; dmarc=pass action=none header.from=oracle.com; dkim=pass header.d=oracle.com; arc=none DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=oracle.onmicrosoft.com; s=selector2-oracle-onmicrosoft-com; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck; bh=nPz/HhlRuxe4zmzACGzvAswpfFIr4Uj/3ncEqzpfcZA=; b=RHnIMx7ja9GnL1YqoIsoQ5BW7Ys9+7WOVkqXnAtya/AP/DvAimi4YVEej3dPCZZl07iBl6STV3RFBxrVL1FEaMuLJZxo3ZIInBeNqct0OE4+YoadZGSNEAaohXXUap3bhw51cKzqRi3PJQtzgLVnX8zNz9QV8ZUmMBrXho21l6k= Received: from CY8PR10MB7243.namprd10.prod.outlook.com (2603:10b6:930:7c::10) by IA0PR10MB6724.namprd10.prod.outlook.com (2603:10b6:208:43e::5) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.8511.27; Thu, 13 Mar 2025 05:22:40 +0000 Received: from CY8PR10MB7243.namprd10.prod.outlook.com ([fe80::b779:d0be:9e3a:34f0]) by CY8PR10MB7243.namprd10.prod.outlook.com ([fe80::b779:d0be:9e3a:34f0%4]) with mapi id 15.20.8511.026; Thu, 13 Mar 2025 05:22:40 +0000 From: Mike Christie To: chaitanyak@nvidia.com, kbusch@kernel.org, hch@lst.de, sagi@grimberg.me, joao.m.martins@oracle.com, linux-nvme@lists.infradead.org, kvm@vger.kernel.org, kwankhede@nvidia.com, alex.williamson@redhat.com, mlevitsk@redhat.com Cc: Mike Christie Subject: [PATCH RFC 09/11] nvmet: Add helpers to find and get static controllers Date: Thu, 13 Mar 2025 00:18:10 -0500 Message-ID: <20250313052222.178524-10-michael.christie@oracle.com> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20250313052222.178524-1-michael.christie@oracle.com> References: <20250313052222.178524-1-michael.christie@oracle.com> X-ClientProxiedBy: CH0PR08CA0002.namprd08.prod.outlook.com (2603:10b6:610:33::7) To CY8PR10MB7243.namprd10.prod.outlook.com (2603:10b6:930:7c::10) Precedence: bulk X-Mailing-List: kvm@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 X-MS-PublicTrafficType: Email X-MS-TrafficTypeDiagnostic: CY8PR10MB7243:EE_|IA0PR10MB6724:EE_ X-MS-Office365-Filtering-Correlation-Id: 15cad60d-b139-4fc9-fc53-08dd61ef1357 X-MS-Exchange-SenderADCheck: 1 X-MS-Exchange-AntiSpam-Relay: 0 X-Microsoft-Antispam: BCL:0;ARA:13230040|376014|366016|1800799024|921020; X-Microsoft-Antispam-Message-Info: 4n2f8TlX8H3O0SR0L1aoahOppp3qrRUA5+LjAJ4ZaPE6CRMLDswmmotHUpAKFsuPTq+pco9lb/T0RttukPGjmgHluX8Yo2CiWVraEeYyr53pqOa8jpSZJmLVJC+DZEDO6oT0NuMsuAbXvIvWCuQvxqWZ5Hr5PaRSY9N6F02hAkWcz3SWsqjLWVquwX7chfnipwlmBon+tbVZy19025yl+pa65SATc/QQCeW5edlxaWfyYQ/EswEmyYC3Z9dKVN/V0Vr8sCwXFqXkKgZfKleULgadTfpSyFVu1UyQ0SLJHMjxZR1hSM6arF5AHMGNBN8WYNqL21m2MQYV0gvTqfMia6K6wUrWpGWlAuafUurwbrpRH9EQY0b7nDvHpgvAVjmWSPzVCidYaHKNcB5qi7x8E++z9Tm6vEcUtwhl9gmksv7aM1piE6xQoqxi60SD7+qF78PR2yN9oeIBuiJup/6OKa+tZbBjzMqTmneRcJ0GmXKI+R+CVDlBg6SC4JzS2Rw459bH2I2uWtPSmsS6fcO4Nw1w7ERXAsDUZhUSeZQjBgzisU694IukmNve/RIe0rR0WHZg9YursVfARkgBIYeag0M2uWQQVmI2TM0APS0m9ht4hvqBIz9zku1a/oheZPo6+tO3YpdRWt2bjS8YiufV5YS7LdSvyQszu1lMAjR//Or4/Sq23wpnqszV/vCyQik6zBZYn2u+zrfWDw9PQtemJB3Zs41RkuZ/zXmNiLZP8HM6YQ/FDg2fSER85S2RAq8vCjMxJUTs+ge737h4zlatnCv9FH0AEF9N505fkY5XTlRGLW2N2sqdtp1kOP+llA3yOHWj8Jb5SkJVK/Uiy+H0j8SozTLrXniqplbLfNGyoJXYWy03tnObRGWUscle7YSKdzwttiqSb8msCY8isEmx6sJMtAFsRzvou68SuBYceu+2j7ENhgb+GYLcL19R6Mn1Z2JLGFXgSLZuoAZ6nOxYbu9vPXrOtG1yW1T+byikV2vxR6HjcOCZZ9CSvI/Puv43oXXnKXc9T/9tIFP/+HLNtctgiyyPJ0lx1v14aQgv0mJ9hub8hTMBtDrweIkiiQumrj4VyMDkpN7zyXzgbHRD+Q1ny2B7mepSwQzRCXskNZj7NJOqh9bjHOhkMVSYXPs6oucAdb+ClPKWjQum5ZtSSxJDMyQEHuYSqTiYHdfwbZsQXHlrehc7O1y5bwSQ4YoGIu8zWPpBwnMrlDHxh+bjkuJTXB5lY3fnjyRQ54sVMwmQ5SlzGfv1LSkrsG7McrR4+HDbj3C6ve1YELLZJ6ZxHTzJaGgcwSEB8J3nFH45BYDrnQauZpgbNBgy4u2QSc6rkJabLFzYCOD2zOWth+u9flRhBpfDznd7UKros4VDgruC5ndnJdJOcGAJ7B9koEFtfZR56rvlJR1dmYfRhd4kBsKUNSYU+40dJn/76mPjgFc= X-Forefront-Antispam-Report: CIP:255.255.255.255;CTRY:;LANG:en;SCL:1;SRV:;IPV:NLI;SFV:NSPM;H:CY8PR10MB7243.namprd10.prod.outlook.com;PTR:;CAT:NONE;SFS:(13230040)(376014)(366016)(1800799024)(921020);DIR:OUT;SFP:1101; X-MS-Exchange-AntiSpam-MessageData-ChunkCount: 1 X-MS-Exchange-AntiSpam-MessageData-0: ytNU+6tu7sAwSKseAVyCuQk+6MffIO776kcOIkzzmxQy1+CwHlTvUMimhQ4LVbTLjjcUQOFOnDdeOQQgPq+UBXiAUYbu4UmljnL0UWgJ/xyQTTHDJ35DsMgRLL+ZlxS6nm7PXPkPt5T0zzbaRWssQV0irGrjMU+zAKY8+1QeeSFO9flkkEKGT5JKfE5w8okCX1Rx44a1WbWzKs8ZQ5y7MN26d/SX1LOtNzBq4HmQ8sMMVE76dX4bwYL5E0dFLiUnza2RwB+/yhkkZYvLNCcdRDj/Z+UKne7UJQHtUCzhFkUvUv7cw5O3/ziTZtD/pZUq+AXFSIR/EV1aLgSd0d0ckobrOPk2klU5z8hiRUCVf6b71dYA4vWcigZNuE/1cvfTxwmB12U0jXb2F1unwMe0I+EoxfIMm8b9nBv9xtEMxAnM/emc1oB0klDgG9JXGJiG9WEj+o1lZtxYY9qcBpMu9zMSjg+051CW4nEAa6yzH9JEiStSgHlNKMj+i2oL/bFw27TO06u+b2Ay7nVZFsGhgpROf568jjDUBgVqC/j9w+nc03znWcJrqGXbwX0L6lmu6YIrEqZ5h7iZuiV3GDVRTvzJnq7/PRda+6IErP7aUQc6iO5BkHEYJ4KzgUxASR45yCOtJ73HYTll0SCTqULyUWoWl2QZnbFwE7wkRe33D0cyDaaDFgTJ6/qW307MJk5d4eSd4WbuTumYE3vq8GjJiJlhW7KTPweX8MrxOmNV9xej4N5gOvvBj09A5sDm8AFwveG+YmW7WjXreYZGo1OVoLsHPUtHF5EZkspenQlzlME9es5GbKiXPJNhlZQVvHg1ZkQJMno7JjZEas4qmMEyZDmcRm8xYZKuKrcykg8QPxM91PcNOue50WthCo0MsFLHInQzh0D/V40K0reUY92YV7S5o9Ll4PI3HoNusFvW06YBEztuM853Ie3KhKHgjMR2gklrSDYtnUNMZLippTjtg3mmChIanaOwB4lG8YfbeMBWTiBzU3Nk4LWt7D9prvicIQYwFfyJodQTmr0Gi00AkeAV8RmTYBZDidFDOLmRXZ+2twqmBDrrPo54wvwrqvJa5HRktSW130TgJ4sePLtYuVFyzDvryEdL4C+KZHx8AuDMB7CTYnLgYhNPpIHjngv162u61uNhaLIIRFdjP70REBN+BSygxZuD9JpbcJHt71FTVHT66Ehz7aBofioDeONn9aaid9f/XgBu0r00FfHnQYvurlkSg7Wrx8CFgV3gL39ubohoGyW02lx7vMn1bdu6bmzlY0ex8OdYE/iN33u8r5o2cmzUGWqzX2NxXh6cIhhql8okDyN3AwXcb7qo62Oc4Gt5Zm6NE4bdfKHnZzqOU3J3I0+0Ig0T4Q0XotLxxDubm9zxOM+QYsxEKoe/X3l2AXg80WufN3iB5yAhomPwZ+v1/2yedznWW7gLqwLqSrQ1UVdhR88ztjKVRgYxqn1rnxvqC6m9sf4zSZnYq+LkzzyDoenTt/qox9rBLlr1XZS2H44yAdLeNY93I/YEDu1GBRJ8KHIl4BpNtzdSmsFag+IjkUPf+nMQ6Qi4Z+gmSdoqxnL3kNH0JlA5FpJswGp4zV9fK2dwtuKz1IU8mpNt4w== X-MS-Exchange-AntiSpam-ExternalHop-MessageData-ChunkCount: 1 X-MS-Exchange-AntiSpam-ExternalHop-MessageData-0: 6BWLIyxSQztKK8ylBfkGvl0rFq8YeA6ycxZ3J49cr6zJTtyG6TXrb224hRvx2cfsMIddQrm7Ux4Vhnh1HvpdyhpCBgF1rttrhjyJoSU1rm70TBgXQWH6gTuhorV0DQFOfpF2ZJUqXQHVMZcKo34qnESyFV7k35vby2+V5ifar0rROdMKsoI0bHGKmcG5REQVaErtQQmGf1QOQTMSk/Ke5fAafEICGnhYQntUVr9PnSux/eEawVe6SD7MshfebZ0VD+6Q/+udHa5hEOBQA9FuXSbsDgSh40moP2mKJNBp0kUO6aJUmBd2jkSSH84zQcJOYpXjZPULdrcrnnh1BuKNacNKPtOwaWYLd8upVPI2sdU91Tp+IiKcL0aQnOdB+l2SbrXp+rEDO+D7BkeRfbI+y02toUHONXIxpzaRAgfgjD8t/FYyuAAhMQKQemn2dddpLiSA2egHEd4g2Voblee69wg+cLOS4vCKhL+Fvf7SBjkAgVKRnhwn8g3WWNX90eXZIs6VgF5yvKX4TvbSDQnpUaf/ja/VTwl+OghdttRyTbRMKkZx4D1Ws1ByCriTRTMVYhn8vMWc3i13f6/BnqEwP0yEvC4jj7AxF180rOS31kY= X-OriginatorOrg: oracle.com X-MS-Exchange-CrossTenant-Network-Message-Id: 15cad60d-b139-4fc9-fc53-08dd61ef1357 X-MS-Exchange-CrossTenant-AuthSource: CY8PR10MB7243.namprd10.prod.outlook.com X-MS-Exchange-CrossTenant-AuthAs: Internal X-MS-Exchange-CrossTenant-OriginalArrivalTime: 13 Mar 2025 05:22:40.7496 (UTC) X-MS-Exchange-CrossTenant-FromEntityHeader: Hosted X-MS-Exchange-CrossTenant-Id: 4e2c6054-71cb-48f1-bd6c-3a9705aca71b X-MS-Exchange-CrossTenant-MailboxType: HOSTED X-MS-Exchange-CrossTenant-UserPrincipalName: D6WYTikeNAjwU9OxjpQ6XNu+/8losvqsvAWth8CiOE6/v6N/K/Ct6s5BnQequPcWmsAr1VI1YC/k28gGPbyi9iHGZnzxkh8G1nbytIOIssI= X-MS-Exchange-Transport-CrossTenantHeadersStamped: IA0PR10MB6724 X-Proofpoint-Virus-Version: vendor=baseguard engine=ICAP:2.0.293,Aquarius:18.0.1093,Hydra:6.0.680,FMLib:17.12.68.34 definitions=2025-03-13_02,2025-03-11_02,2024-11-22_01 X-Proofpoint-Spam-Details: rule=notspam policy=default score=0 bulkscore=0 phishscore=0 spamscore=0 mlxscore=0 mlxlogscore=999 adultscore=0 malwarescore=0 suspectscore=0 classifier=spam adjust=0 reason=mlx scancount=1 engine=8.12.0-2502280000 definitions=main-2503130040 X-Proofpoint-GUID: xfwW0U03xmuXLiCx01yq1avU3jSKwvfN X-Proofpoint-ORIG-GUID: xfwW0U03xmuXLiCx01yq1avU3jSKwvfN The new nvmet_mdev_pci driver lives on the mdev bus and does not have direct access to the configfs interface. For the nvmet_fabrics_ops.add_port callout we will add a mdev port. However, the mdev bus driver design requires the device under that to be added in a separate step (from the driver->probe callout). For this callout we need a way to find the controllers under a port, so this patch adds some helpers to be able to loop over the static controllers created under a port. The nvmet-mdev-pci driver can then loop over the controllers under a port and create a mdev/vfio device for the nvmet controller. Signed-off-by: Mike Christie --- drivers/nvme/target/configfs.c | 10 ++++- drivers/nvme/target/core.c | 71 ++++++++++++++++++++++++++++++++++ drivers/nvme/target/nvmet.h | 8 ++++ 3 files changed, 88 insertions(+), 1 deletion(-) diff --git a/drivers/nvme/target/configfs.c b/drivers/nvme/target/configfs.c index a946a879b9d6..31c484d51a69 100644 --- a/drivers/nvme/target/configfs.c +++ b/drivers/nvme/target/configfs.c @@ -2069,16 +2069,19 @@ static ssize_t nvmet_ctrl_enable_store(struct config_item *item, ret = -EBUSY; goto out_put_ctrl; } + list_add_tail(&ctrl->port_entry, &port->static_ctrls); ret = nvmet_enable_port(port); if (ret) - goto out_put_ctrl; + goto out_del_entry; conf->ctrl = ctrl; up_read(&nvmet_config_sem); return count; +out_del_entry: + list_del(&ctrl->port_entry); out_put_ctrl: up_read(&nvmet_config_sem); nvmet_ctrl_put(ctrl); @@ -2169,6 +2172,10 @@ static void nvmet_ctrl_release(struct config_item *item) mod = conf->args.ops->owner; if (conf->ctrl) { + down_write(&nvmet_config_sem); + list_del(&conf->ctrl->port_entry); + up_write(&nvmet_config_sem); + conf->args.ops->delete_ctrl(conf->ctrl); nvmet_ctrl_put(conf->ctrl); } @@ -2401,6 +2408,7 @@ static struct config_group *nvmet_ports_make(struct config_group *group, INIT_LIST_HEAD(&port->entry); INIT_LIST_HEAD(&port->subsystems); + INIT_LIST_HEAD(&port->static_ctrls); INIT_LIST_HEAD(&port->referrals); port->inline_data_size = -1; /* < 0 == let the transport choose */ port->max_queue_size = -1; /* < 0 == let the transport choose */ diff --git a/drivers/nvme/target/core.c b/drivers/nvme/target/core.c index 1385368270de..6dab9d0f6b2f 100644 --- a/drivers/nvme/target/core.c +++ b/drivers/nvme/target/core.c @@ -1551,6 +1551,76 @@ static void nvmet_fatal_error_handler(struct work_struct *work) ctrl->ops->delete_ctrl(ctrl); } +/** + * nvmet_find_get_static_ctrl - find a static controller by port and cntlid + * @port: port to search under + * @trtype: transport type of the controller + * @cntlid: controller ID + * + * Returns: On success this returns a nvmet_ctrl with the refcount increased + * by one that the caller must drop. + */ +struct nvmet_ctrl *nvmet_find_get_static_ctrl(struct nvmet_port *port, + int trtype, u16 cntlid) +{ + struct nvmet_ctrl *ctrl; + + down_read(&nvmet_config_sem); + + list_for_each_entry(ctrl, &port->static_ctrls, port_entry) { + if (ctrl->ops->type != trtype) + continue; + + if (ctrl->cntlid == cntlid) { + if (!kref_get_unless_zero(&ctrl->ref)) + ctrl = NULL; + + up_read(&nvmet_config_sem); + return ctrl; + } + } + + up_read(&nvmet_config_sem); + return NULL; +} +EXPORT_SYMBOL_GPL(nvmet_find_get_static_ctrl); + +/** + * nvmet_for_each_static_ctrl - execute fn over matching static controllers + * @port: port that the controller is using. + * @trtype: transport type of the controller. + * @fn: function to execute on each matching controller. + * @priv: driver specific struct passed to fn. + * + * This must be called with the nvmet_config_sem. + * + * Returns: passes fn's return value to caller. + */ +int nvmet_for_each_static_ctrl(struct nvmet_port *port, int trtype, + nvmet_ctlr_iter_fn *fn, void *priv) +{ + struct nvmet_ctrl *ctrl; + int ret = 0; + + lockdep_assert_held(&nvmet_config_sem); + + list_for_each_entry(ctrl, &port->static_ctrls, port_entry) { + if (ctrl->ops->type != trtype) + continue; + + if (!kref_get_unless_zero(&ctrl->ref)) + continue; + + ret = fn(priv, port, ctrl); + nvmet_ctrl_put(ctrl); + if (ret) + break; + } + + return ret; +} +EXPORT_SYMBOL_GPL(nvmet_for_each_static_ctrl); + struct nvmet_ctrl *nvmet_alloc_ctrl(struct nvmet_alloc_ctrl_args *args) { struct nvmet_subsys *subsys; @@ -1599,6 +1669,7 @@ struct nvmet_ctrl *nvmet_alloc_ctrl(struct nvmet_alloc_ctrl_args *args) INIT_WORK(&ctrl->async_event_work, nvmet_async_event_work); INIT_LIST_HEAD(&ctrl->async_events); + INIT_LIST_HEAD(&ctrl->port_entry); INIT_RADIX_TREE(&ctrl->p2p_ns_map, GFP_KERNEL); INIT_WORK(&ctrl->fatal_err_work, nvmet_fatal_error_handler); INIT_DELAYED_WORK(&ctrl->ka_work, nvmet_keep_alive_timer); diff --git a/drivers/nvme/target/nvmet.h b/drivers/nvme/target/nvmet.h index 2b0e624b80e1..a16d1c74e3d9 100644 --- a/drivers/nvme/target/nvmet.h +++ b/drivers/nvme/target/nvmet.h @@ -196,6 +196,7 @@ struct nvmet_port { struct config_group group; struct config_group subsys_group; struct list_head subsystems; + struct list_head static_ctrls; struct config_group referrals_group; struct list_head referrals; struct list_head global_entry; @@ -268,6 +269,7 @@ struct nvmet_ctrl { struct list_head async_events; struct work_struct async_event_work; + struct list_head port_entry; struct list_head subsys_entry; struct kref ref; struct delayed_work ka_work; @@ -603,6 +605,12 @@ struct nvmet_alloc_ctrl_args { u16 status; }; +typedef int (nvmet_ctlr_iter_fn)(void *priv, struct nvmet_port *port, + struct nvmet_ctrl *ctrl); +int nvmet_for_each_static_ctrl(struct nvmet_port *port, int trtype, + nvmet_ctlr_iter_fn *fn, void *priv); +struct nvmet_ctrl *nvmet_find_get_static_ctrl(struct nvmet_port *port, + int trtype, u16 cntlid); struct nvmet_ctrl *nvmet_alloc_ctrl(struct nvmet_alloc_ctrl_args *args); struct nvmet_ctrl *nvmet_ctrl_find_get(const char *subsysnqn, const char *hostnqn, u16 cntlid, From patchwork Thu Mar 13 05:18:11 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Mike Christie X-Patchwork-Id: 14014343 Received: from mx0a-00069f02.pphosted.com (mx0a-00069f02.pphosted.com [205.220.165.32]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 1C6701D5CDE for ; Thu, 13 Mar 2025 05:23:01 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=fail smtp.client-ip=205.220.165.32 ARC-Seal: i=2; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1741843382; cv=fail; b=pIh2AOHf/KUEPM+Tbp9Ocfod1ilrvea5y0ERdLl1t0GVavH5S1aEBzBoqqpFEGpBh7XxWyJ/Ae7EDJ12Y5NC3iPQGQ2jq3fhNq5KEF/Xrq0gQz6GtAYqbCNSWPEQHCDTyw+y30xL33qL7eoabWaZboNs0ea7lSHJJ8RFTQ1V8es= ARC-Message-Signature: i=2; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1741843382; c=relaxed/simple; bh=k5ApVM4ZkA12L99n+lq78dmhdC477FzPX/07mt5O1PE=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: Content-Type:MIME-Version; b=c8gb5TPOwI+3BDkru1NoJaWouwd3kNcY9ZgkgaHv7KBkq0eM8SNigUiXTkq2baJH/jm+E1KarWV6WIpRY8zUcH64KDB4hOJ3sdFqAFM6cWXz5HU/APcU5GIaPaTfWKz+gJ4lbVSes6OA5v04Ytgg86tPF46Ndopt6fEyjqPoXFc= ARC-Authentication-Results: i=2; smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=oracle.com; spf=pass smtp.mailfrom=oracle.com; dkim=pass (2048-bit key) header.d=oracle.com header.i=@oracle.com header.b=Umv00b05; dkim=pass (1024-bit key) header.d=oracle.onmicrosoft.com header.i=@oracle.onmicrosoft.com header.b=P2QCm0A0; arc=fail smtp.client-ip=205.220.165.32 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=oracle.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=oracle.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=oracle.com header.i=@oracle.com header.b="Umv00b05"; dkim=pass (1024-bit key) header.d=oracle.onmicrosoft.com header.i=@oracle.onmicrosoft.com header.b="P2QCm0A0" Received: from pps.filterd (m0246617.ppops.net [127.0.0.1]) by mx0b-00069f02.pphosted.com (8.18.1.2/8.18.1.2) with ESMTP id 52D3tmwX024188; Thu, 13 Mar 2025 05:22:47 GMT DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=oracle.com; h=cc :content-transfer-encoding:content-type:date:from:in-reply-to :message-id:mime-version:references:subject:to; s= corp-2023-11-20; bh=osV83JdKhfLPCqrUijMecGqAfiS7Na/MQ3l2kxSqkxQ=; b= Umv00b054WXwUc9ZrTJqtnMek9ZwMKIpDtbZypojUFUHrVS22TSLtM9yr6OMObXr hqNdFxBdip44uA9ibi2V3IFYPzMJAKNHqN6JgFFrVp8xvktW2MtCFcC7JGo263eg +D9G+y4MzjSupAbRGgI0HZkPHSIlo5nbwgK0MEt/66sTVwwX9DM6hM2URqxb+Eqw RNKhrTPfJwQgDX5k3IcORnEemHI8CQOEnwQoTzkTthhbaF9bBORY5pHSrdJEb33u 3j7N7XYIyvoxyKdjr98lVsJQzmq3+acKqzNGEbiKc0THHuJddiJlhGvc+n37nlCZ XHfx02ky7gc5s48+9KiqgQ== Received: from iadpaimrmta03.imrmtpd1.prodappiadaev1.oraclevcn.com (iadpaimrmta03.appoci.oracle.com [130.35.103.27]) by mx0b-00069f02.pphosted.com (PPS) with ESMTPS id 45au4dkf1f-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=OK); Thu, 13 Mar 2025 05:22:46 +0000 (GMT) Received: from pps.filterd (iadpaimrmta03.imrmtpd1.prodappiadaev1.oraclevcn.com [127.0.0.1]) by iadpaimrmta03.imrmtpd1.prodappiadaev1.oraclevcn.com (8.18.1.2/8.18.1.2) with ESMTP id 52D3WRUs008738; Thu, 13 Mar 2025 05:22:45 GMT Received: from nam10-mw2-obe.outbound.protection.outlook.com (mail-mw2nam10lp2048.outbound.protection.outlook.com [104.47.55.48]) by iadpaimrmta03.imrmtpd1.prodappiadaev1.oraclevcn.com (PPS) with ESMTPS id 45atn47gj9-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=OK); Thu, 13 Mar 2025 05:22:45 +0000 ARC-Seal: i=1; a=rsa-sha256; s=arcselector10001; d=microsoft.com; cv=none; b=PfyLgqWne8+etoF15Y1PI42De3IkEDdJtUIJMzFRW2a8bhle4ABAulQMFGK6cHO7DdnQ1WeI5nu+0UpxewNvP+ERGL6VYWU9JKZxHXMFJcY7/NXe83XhjxRYugL3Ip9U3BtgdvPLL8FmQmgTOUd/RLa373I9pjECtrRFKGmhGamzdVfQxBqwrX031Mms0ZifcPEBsZUZ1ek0XaTwzi+SsF1MCcD3Mw49vp1Cja+xIjEXBzRAQPu/Q01guHQYqVtEZZWYOo1m9+9FnU5t6MxTB6yK6dYv27TpFrQinKGxHoSiIn2lxK/g7wrCPMdHnlBry4Nlz/gUEbhqsoIfjOuPHw== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=microsoft.com; s=arcselector10001; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-AntiSpam-MessageData-ChunkCount:X-MS-Exchange-AntiSpam-MessageData-0:X-MS-Exchange-AntiSpam-MessageData-1; bh=osV83JdKhfLPCqrUijMecGqAfiS7Na/MQ3l2kxSqkxQ=; b=XdhHbiyFH/vnpKhwrRhJPWnL/IL/IVjRpLzw8/iCSeHGgZUz2qVbT6XfWF+XuWwayi/Zg4vuFcxXeOLAK4Bt+9qX63ibMAz56tSwUPXkbZ+ZHF7Rt/97mFTiaCZ2jaa+QHiX/vNs8rsnbJY3THppiymzOEtlkJrvahCUfn075urBHguI4eE8blBhYThUrs+eyC9lheMgvYvaHYso6CyDLOlrhZV6laDbYxw85Twe45M96oHKxX3pMhEo2R9Rmq6qDa45BxC9MowHu40KSORFBPYjt6pOJHBZfbSPeKGIwXShF7nbp3eXolcLzSr0VBvsUtUUqFJQvH5/zetgYUTIIg== ARC-Authentication-Results: i=1; mx.microsoft.com 1; spf=pass smtp.mailfrom=oracle.com; dmarc=pass action=none header.from=oracle.com; dkim=pass header.d=oracle.com; arc=none DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=oracle.onmicrosoft.com; s=selector2-oracle-onmicrosoft-com; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck; bh=osV83JdKhfLPCqrUijMecGqAfiS7Na/MQ3l2kxSqkxQ=; b=P2QCm0A0OdLAsAGltMdVQqNnrjE5j1PS99T4ujf6+d2YsIbJizSx0KapEvg8ngJDCEU1fb6OE/+Tp9cNLsjCSd4XUEanyHI1x2qeIfWmMzpXyC/gpVuJLIlkPylVmuvuHreR7aN/lRzWWbLYfqNOQcFZHkvm7dJqb2TG4IHCGV0= Received: from CY8PR10MB7243.namprd10.prod.outlook.com (2603:10b6:930:7c::10) by IA0PR10MB6724.namprd10.prod.outlook.com (2603:10b6:208:43e::5) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.8511.27; Thu, 13 Mar 2025 05:22:42 +0000 Received: from CY8PR10MB7243.namprd10.prod.outlook.com ([fe80::b779:d0be:9e3a:34f0]) by CY8PR10MB7243.namprd10.prod.outlook.com ([fe80::b779:d0be:9e3a:34f0%4]) with mapi id 15.20.8511.026; Thu, 13 Mar 2025 05:22:42 +0000 From: Mike Christie To: chaitanyak@nvidia.com, kbusch@kernel.org, hch@lst.de, sagi@grimberg.me, joao.m.martins@oracle.com, linux-nvme@lists.infradead.org, kvm@vger.kernel.org, kwankhede@nvidia.com, alex.williamson@redhat.com, mlevitsk@redhat.com Cc: Mike Christie Subject: [PATCH RFC 10/11] nvmet: Add addr fam and trtype for mdev pci driver Date: Thu, 13 Mar 2025 00:18:11 -0500 Message-ID: <20250313052222.178524-11-michael.christie@oracle.com> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20250313052222.178524-1-michael.christie@oracle.com> References: <20250313052222.178524-1-michael.christie@oracle.com> X-ClientProxiedBy: CH0PR03CA0084.namprd03.prod.outlook.com (2603:10b6:610:cc::29) To CY8PR10MB7243.namprd10.prod.outlook.com (2603:10b6:930:7c::10) Precedence: bulk X-Mailing-List: kvm@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 X-MS-PublicTrafficType: Email X-MS-TrafficTypeDiagnostic: CY8PR10MB7243:EE_|IA0PR10MB6724:EE_ X-MS-Office365-Filtering-Correlation-Id: 69e776cf-90e3-485b-436e-08dd61ef1484 X-MS-Exchange-SenderADCheck: 1 X-MS-Exchange-AntiSpam-Relay: 0 X-Microsoft-Antispam: BCL:0;ARA:13230040|376014|366016|1800799024|921020; X-Microsoft-Antispam-Message-Info: 5bQfOJGUZiTM0L8vDtDIN+mhAQkVicuucTXVPmWpiMyKYNGTZLKQ16nAazD7WWtqll1eDcNWOqmsm21976QvQaCdzRevlsudR/8c7EklCzpP7WHCHgjp6+7rminACNXN3vhrwC5xswx09YX7lnmlvGVJvhm3eg9MmgsAjScpTUjdijno1rjPcBsA5LL1tW8SCfLuCZ2jCYGcxKP1vP/ObCl6HuKTQbFsBSjSWK0EntGLD5PfmLhydRvkbt2o040JiU0srsQ/jX9vZksV5KnJLXRm8LLwVoNlWKczmfZZlbWqxjjFgenoAK5Az+oIBUe6KU7yzH3CaTNw6YyJYVMbKxw3dXTdi4cRHl7RQyhzLk02UiuqL/CXfzJdZAOs8pJPxcpO9gag/yaE7Rp3jaaHwXQNBU69G+oLfxBd6JjIe1KzBYTi30gfxD0awFo0eHCRQGjlYMk3no0ht3Lak+VXPv/0vcyZJ6BFjXG0hviUGxyZyeOxgdo9/dG6OHvR6No/ccNK4SWkTWP1hzM5Lqfc4wkB/GBIdsUOoT1TnVtdWzs3ddr9Oia/JErSIPGYnWHyq00qaQOD1jWPkdKrArcDpdbZakW3VmyqRmUk/N3mbJ3Q0wIqUNfAdg7dd4XeU/ARQWjNJwShzMMDZbhKvesT7MbvtQsXRa+r6zGFgpJG9xB6//pohVpItA9QuhZMZlyg0MLTdv7QrISlYnhmH2nwnMq1nBEGeVBHKrW/dI0NcGlizATY0v4IfgKTqTO7rNxCXxN8ldD2haisY/FUf/Twu3PfFUMsXv3owVwqRs78bmQhNK/kuLue72O0AEiORv5FvSE8LUTN3MVKLghrhsarb4wNuXXb6PlJTlc7xLZmdQJy0tS0yZsWeM3maXrMoq/GzUil1UWA0nlo+FjuzLf6dQqccqoxzG76kiXaVYW6DVVDyl1OkCSCgEyCgBHm5nhe7NzZC0u36ga5SXH/HIcOkyRrTy/DOQB3JrRR7Ok1huDfqEQ7koI1juT+7IpriDz9CGHMj46EIOA6edjr17W5nEknRY64ILQwtx6xvc0AsQZAubT8Qo8VJO7T1pdwh26PJYm5uI8qt9beJ1ef0cQnZGmGjG08HDzRFby8sw40/hTQxvuGnFiPb1f8xfN6P81uHv4FzbPvd+ZNzTdw9I/DNY5YLZqh6xY/WqCIOHKzlFlQY2J3Gt7Z1MKbAdITDUX0W6eSlWq02DfaRkPA/JtwPxKFHiRb1xFDEHnzTFxW5Q4g+i2FXnK6Ph2S0YFaZATuEuPLpZInyQBRz3/g2rGuHh4VRqf1R2Of/HR2n/EjD0ok5IGfT90KcqGWc7FPuPX+hh5jFqvzi/xfqKeUiEKO+QKW1U+wvxoeL+BHPaV8rGoHu2E6CaawCqMb15Q3rAfBODwPeh9Wq/usCYO8B9ryvDLPHESOIA8f6ShTC0D9CJI= X-Forefront-Antispam-Report: CIP:255.255.255.255;CTRY:;LANG:en;SCL:1;SRV:;IPV:NLI;SFV:NSPM;H:CY8PR10MB7243.namprd10.prod.outlook.com;PTR:;CAT:NONE;SFS:(13230040)(376014)(366016)(1800799024)(921020);DIR:OUT;SFP:1101; X-MS-Exchange-AntiSpam-MessageData-ChunkCount: 1 X-MS-Exchange-AntiSpam-MessageData-0: O1vvtnJ6euwJuomCK4d3nEO/+v7D5cCmLxslbo9CYrDUToDMeD6vdbcL9acO8WXiMTBj3wgvmdSWMVpiHyay6odQKXjDWidYkwJmHw1t51zTknmFOvUaieyaXEg5Q8vPsMl/iSNCRiY0xtRSJ4wFO9WKOcXnmoyeRTp1Gz89o4/2QaIkBQGIL5NGtVL5lPW0ZChj6c1lmS/fQKdnlDsMXhwPrzhbvZHNDnHTIOvFno2Sd1WPjXG0IPiD8mBKx6/PqySC1nfszONPyPZpwFm6gLpi62TMyNvOK1IL1/d5rlPv3zLv+qEorZqJ9ZlCLBOfvfaP5SKbWdTwRNwX9tT7dfP/NWmxZjA3PwlG+xSnGV69gujWCD04qWuZQqMRlbChWH71Zfn/FJ4ay3Vp3ElRwvLwcZnBKj3k97uZno71hK0nhbS/CXHk4RZvpKIuN4auPGKB60yZy4lYeCiqkNO6H1I1bpFFNDXJkvSWSevgh6yAa5Yg5xzTE6zcqMDU2AEuMtu+V4VNIDRqNTJgx4xUUuwNf+M1V6S+VBEU3dubPq+ljG/SoaisSxg8x45VwVBYJ8D6FuKAWW7g5Oy5zOMIXIUp7sLgnmC6ZWRAtJMIkYkYNyV84tvCxOcIOZFiZm3i1heIDt+Jv+F+pATqfQLpA0j4eClsrl6rbpUCqwaP7SDy3tI5fzSjrQoNPvvguVdgZagGWOJH24q/kk6M3n88LdCJHrYCNRkThL0hLSgXaB6zQty30rtJDxgP8WE7D06tRMGiymfn7sqzYaqYCMeOfAPvIX0WNyNj6kQ0uiGvInSjpvRxsa7JFALzyc6yB5FT8ybrqH5S83Dyic8g6qblYDcs0RtV1871cxZBbRrIDH3dAvObIBmEAdXO+zCA8oKi4wFI69jl++wV4idPUYjqAn8oz6nHSusJGZtCvAikUFZWBTfaPaFhH3s5JZUHDxCc+gBhUjSZqrYbbTyPJMTt9eIaSy6CoIbeJ8+4tcC+N8pPUE2uKjT2q+ntfIwXLeuvZRezrH1wqSeCAxMxu3FR+eQqNEN67aRczdLBZCBZKOWb4mkZ4RLkErCuZqN+I7gjam70UlMRcWklgKDeUcFPFkwt11sRCUZUs8wTv3TL70myJMeFc/t1SQUkaNc3lLP8SMbnVMH36hnVIsJ+cKze+Ip3I/Y4a1SW6xlEFtmoqJ6aCL2YCR502z4dFnFtwf333VDkIkzN8cLkavkjzaGyWI9nw3RkWNW0UNq37f1qZdMo0o1XkebcvTms1vYYKrQ+OTlAyCuQEa9ULnUiz5uShLsO7+NEvxwNtKwSC9lgJXKC8wQvicSMePp9VAqIu6Djqbbq9DUX5kS02YBuF/GBd2HuvI8hAiWYxrfTZnl0icptI9ZHRlRqiqXaXv+Sk78PVe4We+WtRn4ES6Jr0Nao6ccnYvhV/RvB6/ibXtLSNZv9VMCjQ6o6iYtZbNzc3YBV53BORKxzKwGs78TpkAWWxHrjUavPABvrlVE7BI4dqQCpOtMEsWY7U9troXWVZs6uuw4fMJh2QU9S4VbN/zBl7mhNRM0PXdhSjTtk9AFV6CEQzANUNajjcSdmeuV3JazRBmjsHFRhzwgfTKgHxjDJww== X-MS-Exchange-AntiSpam-ExternalHop-MessageData-ChunkCount: 1 X-MS-Exchange-AntiSpam-ExternalHop-MessageData-0: Rv4kJFVnPwMP7lC3yxfCZEUfcXN9xj9d+k6jf0u/eWcaFBF4Vq7LQEDnn1YgSb9rT55tWz30Hw+FaXiOqhZmQcH7c6SXjUAx3K1y4kIkXA/1yHUKD3XKh8F9mblJ0fl1G+XapR720GONAh9LSx2wjgDBsSdp5CYb8NwRNPwdsBa07BTiu2xmxrvcr6+mqAiL1w6pTOg02BlOlq9aWEAh5eEMHKjB3+kCiDhF46xMQW2alkCbHb6s7QnS3/E30PdQCZzzUFibKediK2993Skk7U4u7CUbH8OJ69TTIoCk89IE5oHP9HS9JgvTrKrMX3jwr1cp1h90CPKTMkaiqw3z6P1o+9naJMRJK8An5GzIZMtkyEsKS6E2YTnsKsXwAcJQBRe35f/+0DRGXDOFufZpuI+s8Ogbp7+aPpCjVyxLieWiJ5KEgvKdL4lIEJFTE8phGfHLo/Llp+MnFiMw39ePQLcDHr+Qd2xkVZYSnqYaBpL8HWo1kBeglGkhGfaTCAWg5JhYUT8jCPuLC9YSFADYMbenZ5YJar5gUuzVZ6YZV6PvCCl3Bsj4zASDYjBAkSC9X/QMuM6YCS4sLLriOlN5Ngy2i5pkae3ol6D7UZOpRMA= X-OriginatorOrg: oracle.com X-MS-Exchange-CrossTenant-Network-Message-Id: 69e776cf-90e3-485b-436e-08dd61ef1484 X-MS-Exchange-CrossTenant-AuthSource: CY8PR10MB7243.namprd10.prod.outlook.com X-MS-Exchange-CrossTenant-AuthAs: Internal X-MS-Exchange-CrossTenant-OriginalArrivalTime: 13 Mar 2025 05:22:42.6704 (UTC) X-MS-Exchange-CrossTenant-FromEntityHeader: Hosted X-MS-Exchange-CrossTenant-Id: 4e2c6054-71cb-48f1-bd6c-3a9705aca71b X-MS-Exchange-CrossTenant-MailboxType: HOSTED X-MS-Exchange-CrossTenant-UserPrincipalName: 6+3Wt7UDIdSXDqVKn14uVh65NcSVda7Uuww/T9m8Xbwp7z5+9h2O142YrzLViw+8/Lzx6YpXB1FhLaMvL1GlyvkdLsA8k3HGKuZ6Hesh5Ys= X-MS-Exchange-Transport-CrossTenantHeadersStamped: IA0PR10MB6724 X-Proofpoint-Virus-Version: vendor=baseguard engine=ICAP:2.0.293,Aquarius:18.0.1093,Hydra:6.0.680,FMLib:17.12.68.34 definitions=2025-03-13_02,2025-03-11_02,2024-11-22_01 X-Proofpoint-Spam-Details: rule=notspam policy=default score=0 suspectscore=0 malwarescore=0 mlxlogscore=999 mlxscore=0 adultscore=0 phishscore=0 spamscore=0 bulkscore=0 classifier=spam adjust=0 reason=mlx scancount=1 engine=8.12.0-2502280000 definitions=main-2503130040 X-Proofpoint-GUID: oyxVwlLKwnDN_mBN9L9Qm2FZataF4K_R X-Proofpoint-ORIG-GUID: oyxVwlLKwnDN_mBN9L9Qm2FZataF4K_R This allocates 253 for mdev pci since it might not fit into any existing value (not sure how to co-exist with pci-epf). One of the reasons this patchset is a RFC is because I was not sure if allocating a new number for this was the best. Another approach is that I could break up pci-epf into a: 1. PCI component - Common PCI and NVMe PCI code. 2. Interface/bus component - Callouts so pci-epf can use the pci_epf_driver/pci_epf_ops and mdev-pci can use mdev and vfio callouts. 3. Memory management component - Callouts for using DMA for pci-epf vs vfio related memory for mdev-pci. On one hand, by creating a core nvmet pci driver then have subdrivers we could share NVMF_ADDR_FAMILY_PCI and NVMF_TRTYPE_PCI. However, it will get messy. There is some PCI code we could share for 1 but 2 and 3 will make sharing difficult becuse of how different the drivers work (mdev-vfio vs pci-epf layers). Signed-off-by: Mike Christie --- drivers/nvme/target/configfs.c | 1 + drivers/nvme/target/nvmet.h | 5 ++++- include/linux/nvme.h | 14 ++++++++------ 3 files changed, 13 insertions(+), 7 deletions(-) diff --git a/drivers/nvme/target/configfs.c b/drivers/nvme/target/configfs.c index 31c484d51a69..73bab15506c2 100644 --- a/drivers/nvme/target/configfs.c +++ b/drivers/nvme/target/configfs.c @@ -39,6 +39,7 @@ static struct nvmet_type_name_map nvmet_transport[] = { { NVMF_TRTYPE_TCP, "tcp" }, { NVMF_TRTYPE_PCI, "pci" }, { NVMF_TRTYPE_LOOP, "loop" }, + { NVMF_TRTYPE_MDEV_PCI, "mdev-pci" }, }; static const struct nvmet_type_name_map nvmet_addr_family[] = { diff --git a/drivers/nvme/target/nvmet.h b/drivers/nvme/target/nvmet.h index a16d1c74e3d9..6c825177ee87 100644 --- a/drivers/nvme/target/nvmet.h +++ b/drivers/nvme/target/nvmet.h @@ -755,7 +755,10 @@ static inline bool nvmet_is_disc_subsys(struct nvmet_subsys *subsys) static inline bool nvmet_is_pci_ctrl(struct nvmet_ctrl *ctrl) { - return ctrl->port->disc_addr.trtype == NVMF_TRTYPE_PCI; + struct nvmf_disc_rsp_page_entry *addr = &ctrl->port->disc_addr; + + return addr->trtype == NVMF_TRTYPE_PCI || + addr->trtype == NVMF_TRTYPE_MDEV_PCI; } #ifdef CONFIG_NVME_TARGET_PASSTHRU diff --git a/include/linux/nvme.h b/include/linux/nvme.h index a7b8bcef20fb..994f02158078 100644 --- a/include/linux/nvme.h +++ b/include/linux/nvme.h @@ -53,12 +53,13 @@ enum nvme_dctype { /* Address Family codes for Discovery Log Page entry ADRFAM field */ enum { - NVMF_ADDR_FAMILY_PCI = 0, /* PCIe */ - NVMF_ADDR_FAMILY_IP4 = 1, /* IP4 */ - NVMF_ADDR_FAMILY_IP6 = 2, /* IP6 */ - NVMF_ADDR_FAMILY_IB = 3, /* InfiniBand */ - NVMF_ADDR_FAMILY_FC = 4, /* Fibre Channel */ - NVMF_ADDR_FAMILY_LOOP = 254, /* Reserved for host usage */ + NVMF_ADDR_FAMILY_PCI = 0, /* PCIe */ + NVMF_ADDR_FAMILY_IP4 = 1, /* IP4 */ + NVMF_ADDR_FAMILY_IP6 = 2, /* IP6 */ + NVMF_ADDR_FAMILY_IB = 3, /* InfiniBand */ + NVMF_ADDR_FAMILY_FC = 4, /* Fibre Channel */ + NVMF_ADDR_FAMILY_MDEV_PCI = 253, /* MDEV PCI */ + NVMF_ADDR_FAMILY_LOOP = 254, /* Reserved for host usage */ NVMF_ADDR_FAMILY_MAX, }; @@ -68,6 +69,7 @@ enum { NVMF_TRTYPE_RDMA = 1, /* RDMA */ NVMF_TRTYPE_FC = 2, /* Fibre Channel */ NVMF_TRTYPE_TCP = 3, /* TCP/IP */ + NVMF_TRTYPE_MDEV_PCI = 253, /* MDEV PCI hack */ NVMF_TRTYPE_LOOP = 254, /* Reserved for host usage */ NVMF_TRTYPE_MAX, }; From patchwork Thu Mar 13 05:18:12 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Mike Christie X-Patchwork-Id: 14014345 Received: from mx0a-00069f02.pphosted.com (mx0a-00069f02.pphosted.com [205.220.165.32]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id DF2F41D5CDE for ; Thu, 13 Mar 2025 05:24:12 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=fail smtp.client-ip=205.220.165.32 ARC-Seal: i=2; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1741843458; cv=fail; b=Z1F0Iwx6/YWlAlQnnfr5w8vEju8MXWfMpQIUgGYt1TDi3zqheUgt44oWo4gUBk/7kRpzTQdms4PDpZpCzY14ba2ZdzA46PGnjjyVgXr6lbFWf6hfQana2Es/Jwh2zvqFb6D5zKnViFxL7hyKzozcYMIOmvIqiQux4pZDUOG2194= ARC-Message-Signature: i=2; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1741843458; c=relaxed/simple; bh=JedUTLVXNJGEmfBqhM01D9OAk1y6Zru7AbmUZ92TXLA=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: Content-Type:MIME-Version; b=VhmixeG/59irq+rTuSDm51XdHm4OmxCSwUsTJ2kdeV0x/wRDK499/rxOvPU2L6OL0x7cewDn34+bg4oIZP1CRKYmEEqDKedXU80iUlcWGHUoP+RV03r/mpeBMM7PWaSS0UoKvRjpK9R3qU9TBnZ8WhCU2ZWqDjtenr5ooUbTTAU= ARC-Authentication-Results: i=2; smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=oracle.com; spf=pass smtp.mailfrom=oracle.com; dkim=pass (2048-bit key) header.d=oracle.com header.i=@oracle.com header.b=Hs2hQBfj; dkim=pass (1024-bit key) header.d=oracle.onmicrosoft.com header.i=@oracle.onmicrosoft.com header.b=HiooXB+B; arc=fail smtp.client-ip=205.220.165.32 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=oracle.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=oracle.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=oracle.com header.i=@oracle.com header.b="Hs2hQBfj"; dkim=pass (1024-bit key) header.d=oracle.onmicrosoft.com header.i=@oracle.onmicrosoft.com header.b="HiooXB+B" Received: from pps.filterd (m0246617.ppops.net [127.0.0.1]) by mx0b-00069f02.pphosted.com (8.18.1.2/8.18.1.2) with ESMTP id 52D3uN2a025239; Thu, 13 Mar 2025 05:22:49 GMT DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=oracle.com; h=cc :content-transfer-encoding:content-type:date:from:in-reply-to :message-id:mime-version:references:subject:to; s= corp-2023-11-20; bh=KzgKmFrPi1qZHB74acbxxncfddC+W3GAj+sv6CZAaMU=; b= Hs2hQBfjBjD6eR1rVNMQ97Rt6OHx+7+M5Mvn9W4xl9lYQQaNcJmPno0AyXXijTXI dXlqsujo4DWJb7gMpr2gRzGLBwJp3RCGqTAUb1ft5A7/KTTcyK5/IirPUVi7FqHW Agnu7ESqR5NX0jhdW1nn7epvXeQS2sWBIHAH4RY5I+vinTVbxelTX0aVlEe5yPyM 3pwEVqzPLFGCTVuNQluRTR7q5asOfKtEqTZpH4rG1d4Oh/Mvmt9aEkAFNgK1dKBA +Nt2x9cLwfL7Thza3tzaFHS1xFV9CW0mpFd+/g634p4rqGibUsAJGT2ma5UbSljB mgnoolkOCuKSJoqicR95Hw== Received: from phxpaimrmta01.imrmtpd1.prodappphxaev1.oraclevcn.com (phxpaimrmta01.appoci.oracle.com [138.1.114.2]) by mx0b-00069f02.pphosted.com (PPS) with ESMTPS id 45au4dkf1g-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=OK); Thu, 13 Mar 2025 05:22:48 +0000 (GMT) Received: from pps.filterd (phxpaimrmta01.imrmtpd1.prodappphxaev1.oraclevcn.com [127.0.0.1]) by phxpaimrmta01.imrmtpd1.prodappphxaev1.oraclevcn.com (8.18.1.2/8.18.1.2) with ESMTP id 52D4ZQK8003845; Thu, 13 Mar 2025 05:22:47 GMT Received: from nam10-dm6-obe.outbound.protection.outlook.com (mail-dm6nam10lp2048.outbound.protection.outlook.com [104.47.58.48]) by phxpaimrmta01.imrmtpd1.prodappphxaev1.oraclevcn.com (PPS) with ESMTPS id 45atn1nwwb-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=OK); Thu, 13 Mar 2025 05:22:47 +0000 ARC-Seal: i=1; a=rsa-sha256; s=arcselector10001; d=microsoft.com; cv=none; b=wqvrAAFE0+KZaTffjUxQKmZVLqKCNlcZ1fEaKHeseZUz7PkEMMdefrMb4Zid21J04TjD1JetI9WOEtFsJ9MK3cLl6KhwuL2Q0YGYeX4MxyO80EhkSg5hpwz5t653l/h8RkvPp6pSEVgqVMxC6D/TlWJWRSzbni6cakblxHi6O3ScCsVbO7zK9o0qkAsAeYh67MaUnFEKpF1VnLVVXyfa37sWqboM1NNFUER+aCExWpZpdjfL6FsWX1B6KQGfizGe/wf5YGzr2S6f2pg3DkB2j7xgqOaIbseWKOVEfNBmm50o4375CII0eAOSOIjtIcp1/dpc9lZzhjAxUL+f5LM2pQ== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=microsoft.com; s=arcselector10001; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-AntiSpam-MessageData-ChunkCount:X-MS-Exchange-AntiSpam-MessageData-0:X-MS-Exchange-AntiSpam-MessageData-1; bh=KzgKmFrPi1qZHB74acbxxncfddC+W3GAj+sv6CZAaMU=; b=rOcq+013pBSwfzxOx71qhM9eC5BkxxOMyQTTNti8Z4rK6+RB8K5FMIlFLM5lhlfh6Xiq3JCQ5+GSV6JthcF8D6PIHmBJi+QA3XA0NF4/2pC73s7GGTBz+wwr0uLnQmSfplAHjHAtkwm3vvOARyhG4aWrAvxuvtMdYm6eCT1+h0iaantEnjotzQXZtQ2GshtZWTnEkxz/ZuoaKYAeJn61AprE4I5A/YZTZKVrt11NfeH9eflIZ7ojA10sQlWD9QozGyx0CGDdZnV5e/tPLwquqdqQw3GLpOoKeCN3BRZLMiK9NUta21ME/yaFQrseFjgrY+yWE34ngtcrq4Zct0UCcA== ARC-Authentication-Results: i=1; mx.microsoft.com 1; spf=pass smtp.mailfrom=oracle.com; dmarc=pass action=none header.from=oracle.com; dkim=pass header.d=oracle.com; arc=none DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=oracle.onmicrosoft.com; s=selector2-oracle-onmicrosoft-com; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck; bh=KzgKmFrPi1qZHB74acbxxncfddC+W3GAj+sv6CZAaMU=; b=HiooXB+BsSD6edlHVXSQ03psJyz30aaFATlOHcwVaC7nQtEsVvrAbzqXyFLUjvfXRW3LWoEWi60owfz1Z1y0EfLy2sBJChJI9GbcrH9h9jWd7Rqth6OtLurQ0vqkegjmn7mxo/r4YbV/2+ZVY0mELcs9cfr7Sl0J0WHbn6pncWM= Received: from CY8PR10MB7243.namprd10.prod.outlook.com (2603:10b6:930:7c::10) by IA0PR10MB6724.namprd10.prod.outlook.com (2603:10b6:208:43e::5) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.8511.27; Thu, 13 Mar 2025 05:22:44 +0000 Received: from CY8PR10MB7243.namprd10.prod.outlook.com ([fe80::b779:d0be:9e3a:34f0]) by CY8PR10MB7243.namprd10.prod.outlook.com ([fe80::b779:d0be:9e3a:34f0%4]) with mapi id 15.20.8511.026; Thu, 13 Mar 2025 05:22:44 +0000 From: Mike Christie To: chaitanyak@nvidia.com, kbusch@kernel.org, hch@lst.de, sagi@grimberg.me, joao.m.martins@oracle.com, linux-nvme@lists.infradead.org, kvm@vger.kernel.org, kwankhede@nvidia.com, alex.williamson@redhat.com, mlevitsk@redhat.com Cc: Mike Christie Subject: [PATCH RFC 11/11] nvmet: Add nvmet-mdev-pci driver Date: Thu, 13 Mar 2025 00:18:12 -0500 Message-ID: <20250313052222.178524-12-michael.christie@oracle.com> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20250313052222.178524-1-michael.christie@oracle.com> References: <20250313052222.178524-1-michael.christie@oracle.com> X-ClientProxiedBy: CH5PR05CA0019.namprd05.prod.outlook.com (2603:10b6:610:1f0::27) To CY8PR10MB7243.namprd10.prod.outlook.com (2603:10b6:930:7c::10) Precedence: bulk X-Mailing-List: kvm@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 X-MS-PublicTrafficType: Email X-MS-TrafficTypeDiagnostic: CY8PR10MB7243:EE_|IA0PR10MB6724:EE_ X-MS-Office365-Filtering-Correlation-Id: 8b8b6cfd-6244-4aa3-b335-08dd61ef1591 X-MS-Exchange-SenderADCheck: 1 X-MS-Exchange-AntiSpam-Relay: 0 X-Microsoft-Antispam: BCL:0;ARA:13230040|376014|366016|1800799024|921020; X-Microsoft-Antispam-Message-Info: zW4ePmiSsgdD17eNN4mL3yWVCM2Zkf/GqlpLOXA53qwKsJ7WoCGYrtDcXUrogQa8XEjmSvTiO4v+OBx4f+W89Zr84nZx4K/f++8SY5CmfmNysXUZBwhCjYp+ffO+xedG9l+5NHLKt9O7akRtgHUYk3gyyD1sK2mDazB7z8njCen3JEPSXVRn059XCnyp5M/2has2MNdU5/1Kdh6sg6kFADLLw2UiOeCyx3Db+Q1cYZqS7JNrPDsmQTakpNggxf4cfrO79jSv7AuzgE5A3yXw1cgnb65xY57rAbyLVM1Yy1OPXKfAl7J7zevj3FYhsimZOG3/MwXvuffkQtLUkyrt6fBUNSQie4iKhBL4dC2UTtM6rv4g8+nRLSiE4ZOcFSIY8uElKRT/UtqaphbSXtfNvsBo25PVV/eESz/ciqyyxbYDdpO5VT3stMsfYKENsITO+cMhMT2fsd57jz5R+hZLMCCtdskJk3bQwIxOCqk1z6aObTok5H2Kvbhdb1Yt0tKmwaQID7/boWXUVTsOk8qF/Q/qUM0od9MHhYx19J4+ur/kJbmiNb2znSzAXL9wFAL1zQqgsXd6aBuyHQprax8pECMlfD6kof1m7ge92WrcxgltETrPeECa9VqrhI+QK6d06ytFo2u9Rwr5vPUwJu5YlkF5Wk08fdukWaQotMMBVg9n0ZTAJwsgBA1u47UfcYmJ2xWHO88QBcA5oUIQYBi2Jcm+TfjPQ7jV8KsjI99pMUERjBh+0cLVFoE0WZ44qpNMgnPFFg5+R/La+hUNqCUY0tsCJjyIEE03ZTF3u6GLb4IsABlyJaF0HcKXh9qMsjlL3YjLSRXdDIj6/rDrpKmSbRQokpxJ1Cv4qupfmEDtWf1SIB2AEDtIcBp1yJQdhmcOdmjlaprrSV1MP18aXZKSSepCMjMfPC9RJOzjPT4+TzQXm2G13BINjWltpKs73sDoIs1xnJHgegNZ/4BdFCN4bSESTlTI2ZmkJH2dyUmArdVP+CUXMXFxil6vmJPPtrBMO1jyLp49/pN8ttqDPXJ3v8e7IxfVOThqvTE1oEkGR2UUdHmOSncnY7D9LG6xdfpEofO6g/CyWl/i+0HgzLAwINkawS+uOi44AaFdBCzErsw4G9OGrotEFCg3GUPNc/L1VsTlLMZdtQNhZwaIH+jQr8/G1E538k29K21CNvNuzp+Wl5r07/x5usIhKKwgisdI1pJIIcB9S3zzzSdzA4hIhaYLH4NOYg/4ieBDIWM+QooVjwpBrNtv6DqW/Tt/ZpMTCUOj2yFSL7p/em1E/FgfE/ZTcZkQrBRz6HHoftCmCle68psTSu9lIzcf3TAtuJeGaq47uzk95jG14KHgQens6XhvPVXvcfzbh7Cjo7SJrCHxg+MDmIvrem09UWU5T1d6EYpg+JtHGhomJPALLkJAiqUyxueUbP03dszCDg3ytus= X-Forefront-Antispam-Report: CIP:255.255.255.255;CTRY:;LANG:en;SCL:1;SRV:;IPV:NLI;SFV:NSPM;H:CY8PR10MB7243.namprd10.prod.outlook.com;PTR:;CAT:NONE;SFS:(13230040)(376014)(366016)(1800799024)(921020);DIR:OUT;SFP:1101; X-MS-Exchange-AntiSpam-MessageData-ChunkCount: 1 X-MS-Exchange-AntiSpam-MessageData-0: n/lYt8SKGh6R3wYfz10BERjWoJ/HU5jz3csQOXahXa81oemqjvbSHWtM2PCaxcUwc5Xr5LaB9YEPmc4gF9hslWW5tPzxEpXcDyOkcmzPk+svhkqAFi3Y/gTs2vy6RaZwbxyFYngYoQiQDti++RW58YbfPk0Oz/DAI5HZTyQl+e1qiFJPdxrPSxB+aWA4Jmsb9M/KTVtgEeaBEF1igeK7siUSMV7CQPH00Nx0FwwSE3NE6yW/rbZF42N2nFQV6vZ8xyU4p9Zle087kDayBO2NitOglWxi9tzqus1hrrMWy/JYBoAhnZ8Jb+weT5JcxcxtxdKfQAZvtQotJb6sPLghSDFmlLG5U3hWtodYF/pZqRyDRIIEMUf+ouxPLw5bM84RT64OO86zmO2fOMNa2XcyRbluMC8k/e0kxRIiEG3J0gNDo5ngfAwSu9fNsUHjhalI+lL9jdZkiGom+pNuOenhI0tqrdRM2t7I4xa08sdPKKu8ZJE4YPHB6qv4WNu6/aW2/8fpFLLyOO3ZvAmn+Ub7kWeyq3nvsr49AIUgFslNgXfwrPrJpNnSsx16Rnu6RTfpKiMRUBXaGTrOyc02akemcX8aqa7W+WV8kzMYh7Tk67JyyW11xv6rjIdTyO0MWyCsj6e3PA/v4IcTQ7ktk/RS4M/xgXQAFrLwe9uv5TfuxsGCcf90Mr6O1kwNBvdrvdsTWLx0RY8vEJC2ZxOsIjjayt3EhZGuuRhdN/EUx0nO8soPrqcavKV0ELFfXSr07Ah8d6YJjHyeEi6Y6hfFlP/+eiZ9TGS47UHBg8KQo5NCJ4Ax+ECVgxtoOtsf6X5gSnZbpXMeooBqmwRl9DCKYA3Ku5YWD+Q7fZMFjWA3aw/mqIHqJ4eWpzNnupo0j707+vG7k0/yfU7P2p8KdHDcrRltsrfTj0GjiwozOMlhoFlYAH5fgNisx4Mt6KtKyQgriZcRB817CmyEkSQXXXO4aMn7GxCqcBE+w90buB3h18sEmmH6FA2wHj8srUCJC84hHiKu+uRZtDc394sVdz8+anYlA5gaXDQPxijh8RFOtioI3wod2K+aJMNazas2YS4xYFZjJtPDE8VfXxH8+a63aaNSb4lyRTQyXEVb+wdOHeueG6jvXbqLUY/nmZgJml89MxQ9UviHskadLjLDyyfOikKuMAaML6G8pGA5xTTTWE+3n7tyxcSND5T7iBEg8j6YwwEWCXBMl+JlD7QAaeFlIlI/1u3yig2qWUZealY4HZrxWfE1CxtHNhUglFUx4fFIyTL5w2Er6dhuHdwJIdGs1blifBH/qHaGMTKhstJnvsGtZOoe6xFhZv9Q08LCD9oJDgkn1LHCPQk9uudm6nK3/4YLa+7g+BcGeZEjC0wFhhG/K0G+MV0mTdS6FYwQefSF1G9W4GKX3Y9C+nBt7cxC5NPV5rgET9VlNVYTgb/LZk61I/psL7Ja+j+M703RGv8KcNkLfpVNkz3tvJl4HltMASmqo9Tdt90nmaqvsINyTKtBBEwV7M6NX0GemNtTmLBO6l7EOJzlIOJohb8vdzZ48GJ2WahaUD0prDx8FthYl6vYwsMxVom+rbI2kB9RvKvIarquuOkz3w38W2YQjKCKLOD9jA== X-MS-Exchange-AntiSpam-ExternalHop-MessageData-ChunkCount: 1 X-MS-Exchange-AntiSpam-ExternalHop-MessageData-0: VzhQ9x+I5RYyr3jb/W8j98pUpfgGB6dDioypk/8/cX7mWQ/GgbPHIRDyHuC8jyCwAsDKL5g/iSdTFexQERbOVedjU04iNhXgoNzi+6Hfkc4ar+IECHRecxBpXV2MPDQI+CZNyiIK1wUu0We7gNK5Ak04tkKvHZoSdS9IEhKWGNkIpoVSlwHaA63PRkf9xenAchucykMY92pi6wuygn934zOE/Vitxggt8yBEsY7hokDwNlQw9RELu129NT6T5zjA6mKtay1RNPh0Er+mUhu1SVTfKJRL1MpQGuj5utOAdSgh/mKP+xGbKS0TIaqc2HmMwsKKP92iffUYpSrxnrUZPI/yEXMu6UV0sN47+Ze2P45o66LZGahIArzIMHUy2DxOoM1PnVwn2GQtv5uwbvc1q3aWxDWihGCunhHrcLSnDk+nLwZdhzOZLAzY2dvAsvuypZYEnS407tX93aKh97itB6IOCXwfwDqBXkQGg7flrsE+9V9fpW1zL8WNK0aQO5VrPoLFM0AS53AaD4ahaiovovDXcJdzw7EbnxelJHXkfp9XyooU/POfKLcfm8E+DAXnq7D6VRYijE9qndTqZqtluP3jEogIw08Td2/SKh9her0= X-OriginatorOrg: oracle.com X-MS-Exchange-CrossTenant-Network-Message-Id: 8b8b6cfd-6244-4aa3-b335-08dd61ef1591 X-MS-Exchange-CrossTenant-AuthSource: CY8PR10MB7243.namprd10.prod.outlook.com X-MS-Exchange-CrossTenant-AuthAs: Internal X-MS-Exchange-CrossTenant-OriginalArrivalTime: 13 Mar 2025 05:22:44.5912 (UTC) X-MS-Exchange-CrossTenant-FromEntityHeader: Hosted X-MS-Exchange-CrossTenant-Id: 4e2c6054-71cb-48f1-bd6c-3a9705aca71b X-MS-Exchange-CrossTenant-MailboxType: HOSTED X-MS-Exchange-CrossTenant-UserPrincipalName: ePC7RUY1KhTAyus87sMiR9iO353Ocz2Wn/e2TjG1224U0GtsXi+tqXpADhpLsdjommafevKkggmHfzKvZiyuUTOJrGBQ0uFrlCz3XS0wmrk= X-MS-Exchange-Transport-CrossTenantHeadersStamped: IA0PR10MB6724 X-Proofpoint-Virus-Version: vendor=baseguard engine=ICAP:2.0.293,Aquarius:18.0.1093,Hydra:6.0.680,FMLib:17.12.68.34 definitions=2025-03-13_02,2025-03-11_02,2024-11-22_01 X-Proofpoint-Spam-Details: rule=notspam policy=default score=0 spamscore=0 suspectscore=0 mlxlogscore=999 bulkscore=0 malwarescore=0 adultscore=0 mlxscore=0 phishscore=0 classifier=spam adjust=0 reason=mlx scancount=1 engine=8.12.0-2502280000 definitions=main-2503130040 X-Proofpoint-GUID: yaBVuKpWa07hzxrF9GiMCJgykQ9DqRWz X-Proofpoint-ORIG-GUID: yaBVuKpWa07hzxrF9GiMCJgykQ9DqRWz This adds new nvmet driver, nvmet-mdev-pci, that can be used as a virtual NVMe PCI driver. The performance of this version of the driver beats the kernel vhost-scsi and SPDK vhost drivers at low number of queues/CPUs. Here we do a fio job per queue and there's a queue per vCPU: fio bs=4K iodepth=128 and numjobs=$value_below: mdev vhost-scsi vhost-scsi-usr vhost-blk-usr numjobs 1 518K 198K 332K 301K 2 1037K 363K 609K 664K 4 974K 633K 1369K 1383K 8 813K 1788K 1358K 1363K note: shadow doorbell support has been enabled. but at higher number of queues vhost kernel and SPDK are better. However, with changes to the vfio iommu code like being able to pre-pin pages mdev performs better at higher queue use: mdev numjobs 1 505K 2 1037K 4 2375K 8 2162K note: shadow doorbell support has been enabled. To create a device create your subsytem, namespace, and port like usual. Then create a nvmet controller using the previous configfs patch: Here we create a controller with cntrlid 1 under port 1: mkdir .../nvmet/ports/1/static_controllers/1 You then set the type: echo mdev-pci > .../nvmet/ports/1/static_controllers/1/trtype Enable shadow doorbell support: echo 1 > .../nvmet/ports/1/static_controllers/1/shadow_doorbell and instead of linking the subsys to the old dir, you use the controller's dir: ln -s ...nvmet/subsystems/nqn.my.subsys \ ...nvmet/ports/1/static_controllers/1/subsystem/nqn.my.subsys" You then enable the controller: echo 1 > .../nvmet/ports/1/static_controllers/1/enable You can then create the mdev device via: UUID=$(uuidgen) echo $UUID > /sys/devices/nvmet_mdev_pci/port-1/dev_supported_types/ \ nvmet_mdev_pci-1/create and pass the mdev device to qemu like: qemu-system-x86_64 ..... \ -device vfio-pci,sysfsdev=/sys/bus/mdev/devices/$UUID Note: there is a bug with iommufd which I'm working on so the old style is used here. This version of the driver is very unstable. You can do IO, but there are several TODO items: 1. Decide the interface (driver specific sysfs like pci-epf vs configfs). 2. Fix interface initiated removal bugs. 3. Add support for DSM. 4. Fix polling support. 5. More integration with nvmet core (more cc and csts integration) and possibly pci-epf. 6. Pre-pin pages to improve perf or modify the iommu code. 7. volatile use cleanup. Signed-off-by: Mike Christie --- drivers/nvme/target/Kconfig | 11 + drivers/nvme/target/Makefile | 1 + drivers/nvme/target/mdev-pci/Makefile | 5 + drivers/nvme/target/mdev-pci/instance.c | 818 ++++++++++++++++++++++++ drivers/nvme/target/mdev-pci/io.c | 332 ++++++++++ drivers/nvme/target/mdev-pci/irq.c | 269 ++++++++ drivers/nvme/target/mdev-pci/mmio.c | 561 ++++++++++++++++ drivers/nvme/target/mdev-pci/pci.c | 241 +++++++ drivers/nvme/target/mdev-pci/priv.h | 487 ++++++++++++++ drivers/nvme/target/mdev-pci/target.c | 284 ++++++++ drivers/nvme/target/mdev-pci/udata.c | 304 +++++++++ drivers/nvme/target/mdev-pci/vcq.c | 160 +++++ drivers/nvme/target/mdev-pci/vctrl.c | 260 ++++++++ drivers/nvme/target/mdev-pci/viommu.c | 308 +++++++++ drivers/nvme/target/mdev-pci/vsq.c | 175 +++++ 15 files changed, 4216 insertions(+) create mode 100644 drivers/nvme/target/mdev-pci/Makefile create mode 100644 drivers/nvme/target/mdev-pci/instance.c create mode 100644 drivers/nvme/target/mdev-pci/io.c create mode 100644 drivers/nvme/target/mdev-pci/irq.c create mode 100644 drivers/nvme/target/mdev-pci/mmio.c create mode 100644 drivers/nvme/target/mdev-pci/pci.c create mode 100644 drivers/nvme/target/mdev-pci/priv.h create mode 100644 drivers/nvme/target/mdev-pci/target.c create mode 100644 drivers/nvme/target/mdev-pci/udata.c create mode 100644 drivers/nvme/target/mdev-pci/vcq.c create mode 100644 drivers/nvme/target/mdev-pci/vctrl.c create mode 100644 drivers/nvme/target/mdev-pci/viommu.c create mode 100644 drivers/nvme/target/mdev-pci/vsq.c diff --git a/drivers/nvme/target/Kconfig b/drivers/nvme/target/Kconfig index fb7446d6d682..7e8c64f61486 100644 --- a/drivers/nvme/target/Kconfig +++ b/drivers/nvme/target/Kconfig @@ -94,6 +94,17 @@ config NVME_TARGET_TCP If unsure, say N. +config NVME_TARGET_MDEV_PCI + tristate "NVMe MDEV VFIO PCI target support" + select VFIO + select VFIO_MDEV + depends on NVME_TARGET + help + This enables the NVMe MDEV VFIO PCI target support, which allows + exporting NVMe PCI devices using VFIO. + + If unsure, say N. + config NVME_TARGET_TCP_TLS bool "NVMe over Fabrics TCP target TLS encryption support" depends on NVME_TARGET_TCP diff --git a/drivers/nvme/target/Makefile b/drivers/nvme/target/Makefile index ed8522911d1f..369dab7a03f5 100644 --- a/drivers/nvme/target/Makefile +++ b/drivers/nvme/target/Makefile @@ -9,6 +9,7 @@ obj-$(CONFIG_NVME_TARGET_FC) += nvmet-fc.o obj-$(CONFIG_NVME_TARGET_FCLOOP) += nvme-fcloop.o obj-$(CONFIG_NVME_TARGET_TCP) += nvmet-tcp.o obj-$(CONFIG_NVME_TARGET_PCI_EPF) += nvmet-pci-epf.o +obj-$(CONFIG_NVME_TARGET_MDEV_PCI) += mdev-pci/ nvmet-y += core.o configfs.o admin-cmd.o fabrics-cmd.o \ discovery.o io-cmd-file.o io-cmd-bdev.o pr.o diff --git a/drivers/nvme/target/mdev-pci/Makefile b/drivers/nvme/target/mdev-pci/Makefile new file mode 100644 index 000000000000..03cc34b13e07 --- /dev/null +++ b/drivers/nvme/target/mdev-pci/Makefile @@ -0,0 +1,5 @@ + +obj-$(CONFIG_NVME_TARGET_MDEV_PCI) += nvmet-mdev-pci.o + +nvmet-mdev-pci-y += instance.o target.o io.o irq.o udata.o viommu.o vsq.o \ + vcq.o vctrl.o mmio.o pci.o diff --git a/drivers/nvme/target/mdev-pci/instance.c b/drivers/nvme/target/mdev-pci/instance.c new file mode 100644 index 000000000000..c14bcf47c409 --- /dev/null +++ b/drivers/nvme/target/mdev-pci/instance.c @@ -0,0 +1,818 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Mediated NVMe instance VFIO code + * Copyright (c) 2019 - Maxim Levitsky + * Copyright (C) 2025 Oracle Corporation + */ + +#include +#include +#include +#include +#include +#include +#include "../../../vfio/vfio.h" +#include "../nvmet.h" +#include "priv.h" + +#define OFFSET_TO_REGION(offset) ((offset) >> 20) +#define REGION_TO_OFFSET(nr) (((u64)nr) << 20) + +#define NVMET_MDEV_NAME "nvmet_mdev_pci" + +static struct device *nvmet_mdev_root_dev; + +struct mdev_nvme_vfio_region_info { + struct vfio_region_info base; + struct vfio_region_info_cap_sparse_mmap mmap_cap; +}; + +/* User memory removed */ +static void nvmet_mdev_dma_unmap(struct vfio_device *vfio_dev, u64 iova, + u64 length) +{ + struct nvmet_mdev_vctrl *vctrl = vfio_dev_to_nvmet_mdev_vctrl(vfio_dev); + + mutex_lock(&vctrl->lock); + /* + * TODO: This cannot be run while the device is in use. + */ + nvmet_mdev_vctrl_viommu_unmap(vctrl, iova, length); + mutex_unlock(&vctrl->lock); +} + +/* Helper function for bar/pci config read/write access */ +static ssize_t nvmet_mdev_access(struct nvmet_mdev_vctrl *vctrl, + char *buf, size_t count, + loff_t pos, bool is_write) +{ + int index = OFFSET_TO_REGION(pos); + int ret = -EINVAL; + unsigned int offset; + + if (index >= VFIO_PCI_NUM_REGIONS || !vctrl->regions[index].rw) + goto out; + + offset = pos - REGION_TO_OFFSET(index); + if (offset + count > vctrl->regions[index].size) + goto out; + + ret = vctrl->regions[index].rw(vctrl, offset, buf, count, is_write); +out: + return ret; +} + +/* Called when read() is done on the device */ +static ssize_t nvmet_mdev_read(struct vfio_device *vfio_dev, char __user *buf, + size_t count, loff_t *ppos) +{ + struct nvmet_mdev_vctrl *vctrl = vfio_dev_to_nvmet_mdev_vctrl(vfio_dev); + unsigned int done = 0; + int ret; + + while (count) { + size_t filled; + + if (count >= 4 && !(*ppos % 4)) { + u32 val; + + ret = nvmet_mdev_access(vctrl, (char *)&val, + sizeof(val), *ppos, false); + if (ret <= 0) + goto read_err; + + if (copy_to_user(buf, &val, sizeof(val))) + goto read_err; + filled = sizeof(val); + } else if (count >= 2 && !(*ppos % 2)) { + u16 val; + + ret = nvmet_mdev_access(vctrl, (char *)&val, + sizeof(val), *ppos, false); + if (ret <= 0) + goto read_err; + if (copy_to_user(buf, &val, sizeof(val))) + goto read_err; + filled = sizeof(val); + } else { + u8 val; + + ret = nvmet_mdev_access(vctrl, (char *)&val, + sizeof(val), *ppos, false); + if (ret <= 0) + goto read_err; + if (copy_to_user(buf, &val, sizeof(val))) + goto read_err; + filled = sizeof(val); + } + + count -= filled; + done += filled; + *ppos += filled; + buf += filled; + } + return done; +read_err: + return -EFAULT; +} + +/* Called when write() is done on the device */ +static ssize_t nvmet_mdev_write(struct vfio_device *vfio_dev, + const char __user *buf, size_t count, + loff_t *ppos) +{ + struct nvmet_mdev_vctrl *vctrl = vfio_dev_to_nvmet_mdev_vctrl(vfio_dev); + unsigned int done = 0; + int ret; + + while (count) { + size_t filled; + + if (count >= 4 && !(*ppos % 4)) { + u32 val; + + if (copy_from_user(&val, buf, sizeof(val))) + goto write_err; + ret = nvmet_mdev_access(vctrl, (char *)&val, + sizeof(val), *ppos, true); + if (ret <= 0) + goto write_err; + filled = sizeof(val); + } else if (count >= 2 && !(*ppos % 2)) { + u16 val; + + if (copy_from_user(&val, buf, sizeof(val))) + goto write_err; + + ret = nvmet_mdev_access(vctrl, (char *)&val, + sizeof(val), *ppos, true); + if (ret <= 0) + goto write_err; + filled = sizeof(val); + } else { + u8 val; + + if (copy_from_user(&val, buf, sizeof(val))) + goto write_err; + ret = nvmet_mdev_access(vctrl, (char *)&val, + sizeof(val), *ppos, true); + if (ret <= 0) + goto write_err; + filled = sizeof(val); + } + count -= filled; + done += filled; + *ppos += filled; + buf += filled; + } + return done; +write_err: + return -EFAULT; +} + +/* Helper for IRQ number VFIO query */ +static int nvmet_mdev_irq_counts(struct nvmet_mdev_vctrl *vctrl, + unsigned int irq_type) +{ + switch (irq_type) { + case VFIO_PCI_INTX_IRQ_INDEX: + return 1; + case VFIO_PCI_MSIX_IRQ_INDEX: + return MAX_VIRTUAL_IRQS; + case VFIO_PCI_REQ_IRQ_INDEX: + return 1; + default: + return 0; + } +} + +/* VFIO VFIO_IRQ_SET_ACTION_TRIGGER implementation */ +static int nvmet_mdev_ioctl_set_irqs_trigger(struct nvmet_mdev_vctrl *vctrl, + u32 flags, + unsigned int irq_type, + unsigned int start, + unsigned int count, + void *data) +{ + u32 data_type = flags & VFIO_IRQ_SET_DATA_TYPE_MASK; + u8 *bools = NULL; + unsigned int i; + int ret = -EINVAL; + + /* Asked to disable the current interrupt mode */ + if (data_type == VFIO_IRQ_SET_DATA_NONE && count == 0) { + switch (irq_type) { + case VFIO_PCI_REQ_IRQ_INDEX: + nvmet_mdev_irqs_set_unplug_trigger(vctrl, -1); + return 0; + case VFIO_PCI_INTX_IRQ_INDEX: + nvmet_mdev_irqs_disable(vctrl, NVME_MDEV_IMODE_INTX); + return 0; + case VFIO_PCI_MSIX_IRQ_INDEX: + nvmet_mdev_irqs_disable(vctrl, NVME_MDEV_IMODE_MSIX); + return 0; + default: + return -EINVAL; + } + } + + if (start + count > nvmet_mdev_irq_counts(vctrl, irq_type)) + return -EINVAL; + + switch (data_type) { + case VFIO_IRQ_SET_DATA_BOOL: + bools = (u8 *)data; + fallthrough; + case VFIO_IRQ_SET_DATA_NONE: + if (irq_type == VFIO_PCI_REQ_IRQ_INDEX) + return -EINVAL; + + for (i = 0 ; i < count ; i++) { + int index = start + i; + + if (!bools || bools[i]) + nvmet_mdev_irq_trigger(vctrl, index); + } + return 0; + + case VFIO_IRQ_SET_DATA_EVENTFD: + switch (irq_type) { + case VFIO_PCI_REQ_IRQ_INDEX: + return nvmet_mdev_irqs_set_unplug_trigger(vctrl, + *(int32_t *)data); + case VFIO_PCI_INTX_IRQ_INDEX: + ret = nvmet_mdev_irqs_enable(vctrl, + NVME_MDEV_IMODE_INTX); + break; + case VFIO_PCI_MSIX_IRQ_INDEX: + ret = nvmet_mdev_irqs_enable(vctrl, + NVME_MDEV_IMODE_MSIX); + break; + default: + return -EINVAL; + } + if (ret) + return ret; + + return nvmet_mdev_irqs_set_triggers(vctrl, start, count, + (int32_t *)data); + default: + return -EINVAL; + } +} + +/* VFIO_DEVICE_GET_INFO ioctl implementation */ +static int nvmet_mdev_ioctl_get_info(struct nvmet_mdev_vctrl *vctrl, + void __user *arg) +{ + struct vfio_device_info info; + unsigned int minsz = offsetofend(struct vfio_device_info, num_irqs); + + if (copy_from_user(&info, (void __user *)arg, minsz)) + return -EFAULT; + if (info.argsz < minsz) + return -EINVAL; + + info.flags = VFIO_DEVICE_FLAGS_PCI | VFIO_DEVICE_FLAGS_RESET; + info.num_regions = VFIO_PCI_NUM_REGIONS; + info.num_irqs = VFIO_PCI_NUM_IRQS; + + if (copy_to_user(arg, &info, minsz)) + return -EFAULT; + return 0; +} + +/* VFIO_DEVICE_GET_REGION_INFO ioctl implementation */ +static int nvmet_mdev_ioctl_get_reg_info(struct nvmet_mdev_vctrl *vctrl, + void __user *arg) +{ + struct nvmet_mdev_io_region *region; + struct mdev_nvme_vfio_region_info *info; + unsigned long minsz, outsz, maxsz; + int ret = 0; + + minsz = offsetofend(struct vfio_region_info, offset); + maxsz = sizeof(struct mdev_nvme_vfio_region_info) + + sizeof(struct vfio_region_sparse_mmap_area); + + info = kzalloc(maxsz, GFP_KERNEL); + if (!info) + return -ENOMEM; + + if (copy_from_user(info, arg, minsz)) { + ret = -EFAULT; + goto out; + } + + outsz = info->base.argsz; + if (outsz < minsz || outsz > maxsz) { + ret = -EINVAL; + goto out; + } + + if (info->base.index >= VFIO_PCI_NUM_REGIONS) { + ret = -EINVAL; + goto out; + } + + region = &vctrl->regions[info->base.index]; + info->base.offset = REGION_TO_OFFSET(info->base.index); + info->base.argsz = maxsz; + info->base.size = region->size; + + info->base.flags = VFIO_REGION_INFO_FLAG_READ | + VFIO_REGION_INFO_FLAG_WRITE; + + if (region->mmap_ops) { + info->base.flags |= (VFIO_REGION_INFO_FLAG_MMAP | + VFIO_REGION_INFO_FLAG_CAPS); + + info->base.cap_offset = + offsetof(struct mdev_nvme_vfio_region_info, mmap_cap); + + info->mmap_cap.header.id = VFIO_REGION_INFO_CAP_SPARSE_MMAP; + info->mmap_cap.header.version = 1; + info->mmap_cap.header.next = 0; + info->mmap_cap.nr_areas = 1; + info->mmap_cap.areas[0].offset = region->mmap_area_start; + info->mmap_cap.areas[0].size = region->mmap_area_size; + } + + if (copy_to_user(arg, info, outsz)) + ret = -EFAULT; +out: + kfree(info); + return ret; +} + +/* VFIO_DEVICE_GET_IRQ_INFO ioctl implementation */ +static int nvmet_mdev_ioctl_get_irq_info(struct nvmet_mdev_vctrl *vctrl, + void __user *arg) +{ + struct vfio_irq_info info; + unsigned int minsz = offsetofend(struct vfio_irq_info, count); + + if (copy_from_user(&info, arg, minsz)) + return -EFAULT; + if (info.argsz < minsz) + return -EINVAL; + + info.count = nvmet_mdev_irq_counts(vctrl, info.index); + info.flags = VFIO_IRQ_INFO_EVENTFD; + + if (info.index == VFIO_PCI_INTX_IRQ_INDEX) + info.flags |= VFIO_IRQ_INFO_MASKABLE | VFIO_IRQ_INFO_AUTOMASKED; + + if (copy_to_user(arg, &info, minsz)) + return -EFAULT; + return 0; +} + +/* VFIO VFIO_DEVICE_SET_IRQS ioctl implementation */ +static int nvmet_mdev_ioctl_set_irqs(struct nvmet_mdev_vctrl *vctrl, + void __user *arg) +{ + int ret, irqcount; + struct vfio_irq_set hdr; + u8 *data = NULL; + size_t data_size = 0; + unsigned long minsz = offsetofend(struct vfio_irq_set, count); + + if (copy_from_user(&hdr, arg, minsz)) + return -EFAULT; + + irqcount = nvmet_mdev_irq_counts(vctrl, hdr.index); + ret = vfio_set_irqs_validate_and_prepare(&hdr, + irqcount, + VFIO_PCI_NUM_IRQS, + &data_size); + if (ret) + return ret; + + if (data_size) { + data = memdup_user((arg + minsz), data_size); + if (IS_ERR(data)) + return PTR_ERR(data); + } + + ret = -ENOTTY; + switch (hdr.index) { + case VFIO_PCI_INTX_IRQ_INDEX: + case VFIO_PCI_MSIX_IRQ_INDEX: + case VFIO_PCI_REQ_IRQ_INDEX: + switch (hdr.flags & VFIO_IRQ_SET_ACTION_TYPE_MASK) { + case VFIO_IRQ_SET_ACTION_MASK: + case VFIO_IRQ_SET_ACTION_UNMASK: + /* pretend to support this (even with eventfd) */ + ret = hdr.index == VFIO_PCI_INTX_IRQ_INDEX ? + 0 : -EINVAL; + break; + case VFIO_IRQ_SET_ACTION_TRIGGER: + ret = nvmet_mdev_ioctl_set_irqs_trigger(vctrl, + hdr.flags, + hdr.index, + hdr.start, + hdr.count, + data); + break; + } + break; + } + + kfree(data); + return ret; +} + +static long nvmet_mdev_ioctl(struct vfio_device *vfio_dev, unsigned int cmd, + unsigned long arg) +{ + struct nvmet_mdev_vctrl *vctrl = vfio_dev_to_nvmet_mdev_vctrl(vfio_dev); + + switch (cmd) { + case VFIO_DEVICE_GET_INFO: + return nvmet_mdev_ioctl_get_info(vctrl, (void __user *)arg); + case VFIO_DEVICE_GET_REGION_INFO: + return nvmet_mdev_ioctl_get_reg_info(vctrl, (void __user *)arg); + case VFIO_DEVICE_GET_IRQ_INFO: + return nvmet_mdev_ioctl_get_irq_info(vctrl, (void __user *)arg); + case VFIO_DEVICE_SET_IRQS: + return nvmet_mdev_ioctl_set_irqs(vctrl, (void __user *)arg); + case VFIO_DEVICE_RESET: + nvmet_mdev_vctrl_reset(vctrl); + return 0; + default: + return -ENOTTY; + } +} + +/* mmap() implementation (doorbell area) */ +static int nvmet_mdev_mmap(struct vfio_device *vfio_dev, + struct vm_area_struct *vma) +{ + struct nvmet_mdev_vctrl *vctrl = vfio_dev_to_nvmet_mdev_vctrl(vfio_dev); + int index = OFFSET_TO_REGION((u64)vma->vm_pgoff << PAGE_SHIFT); + unsigned long size, start; + + if (index >= VFIO_PCI_NUM_REGIONS || !vctrl->regions[index].mmap_ops) + return -EINVAL; + + if (vma->vm_end < vma->vm_start) + return -EINVAL; + + size = vma->vm_end - vma->vm_start; + start = vma->vm_pgoff << PAGE_SHIFT; + + if (start < vctrl->regions[index].mmap_area_start) + return -EINVAL; + if (size > vctrl->regions[index].mmap_area_size) + return -EINVAL; + + if ((vma->vm_flags & VM_SHARED) == 0) + return -EINVAL; + + vma->vm_ops = vctrl->regions[index].mmap_ops; + vma->vm_private_data = vctrl; + return 0; +} + +static const struct vfio_device_ops nvme_vfio_dev_ops = { + .open_device = nvmet_mdev_vctrl_open, + .close_device = nvmet_mdev_vctrl_release, + .read = nvmet_mdev_read, + .write = nvmet_mdev_write, + .mmap = nvmet_mdev_mmap, + .ioctl = nvmet_mdev_ioctl, + .dma_unmap = nvmet_mdev_dma_unmap, + .bind_iommufd = vfio_iommufd_emulated_bind, + .unbind_iommufd = vfio_iommufd_emulated_unbind, + .attach_ioas = vfio_iommufd_emulated_attach_ioas, + .detach_ioas = vfio_iommufd_emulated_detach_ioas, +}; + +/* Called when new mediated device is created */ +static int nvmet_mdev_probe(struct mdev_device *mdev) +{ + struct nvmet_mdev_port *mport = container_of(mdev->type->parent, + struct nvmet_mdev_port, + parent); + struct nvmet_mdev_vctrl *vctrl; + struct nvmet_ctrl *ctrl; + u16 cntlid; + int ret; + + ret = kstrtou16(mdev->type->sysfs_name, 10, &cntlid); + if (ret) + return -EINVAL; + + mutex_lock(&mport->mutex); + /* Release the refcount taken on the ctrl at remove. */ + ctrl = nvmet_find_get_static_ctrl(mport->nvmet_port, + nvmet_mdev_ops.type, cntlid); + if (!ctrl) { + ret = -ENODEV; + goto unlock; + } + + vctrl = vfio_alloc_device(nvmet_mdev_vctrl, vfio_dev, &mdev->dev, + &nvme_vfio_dev_ops); + if (IS_ERR(vctrl)) { + ret = PTR_ERR(vctrl); + goto put_ctrl; + } + + vctrl->nvmet_ctrl = ctrl; + ctrl->drvdata = vctrl; + dev_set_drvdata(&mdev->dev, vctrl); + + ret = vfio_register_emulated_iommu_dev(&vctrl->vfio_dev); + if (ret) + goto put_vfio_dev; + + ret = nvmet_mdev_vctrl_create(vctrl, mdev); + if (ret) + goto unreg_vfio_dev; + + mutex_unlock(&mport->mutex); + return 0; + +unreg_vfio_dev: + vfio_unregister_group_dev(&vctrl->vfio_dev); +put_vfio_dev: + vfio_put_device(&vctrl->vfio_dev); +put_ctrl: + nvmet_ctrl_put(ctrl); +unlock: + mutex_unlock(&mport->mutex); + return ret; +} + +/* + * TODO handle if this is called while opened. + * + * Depending on if we go with configfs based setup we can get a refcount to + * the conifgfs objects to prevent them from being removed while in use. + * However, the mdev bus hotplug removal cannot be stopped right now + * but we may want to modify it to just not allow it. + */ +void nvmet_mdev_remove_ctrl(struct nvmet_mdev_vctrl *vctrl) +{ + struct nvmet_ctrl *ctrl; + + if (!vctrl) + return; + + ctrl = vctrl->nvmet_ctrl; + if (!ctrl) + return; + + nvmet_mdev_irq_raise_unplug_event(vctrl); + nvmet_mdev_vctrl_destroy(vctrl); + + dev_set_drvdata(vctrl->vfio_dev.dev, vctrl); + vctrl->nvmet_ctrl = NULL; + ctrl->drvdata = NULL; + + vfio_unregister_group_dev(&vctrl->vfio_dev); + vfio_put_device(&vctrl->vfio_dev); + + if (ctrl) + nvmet_ctrl_put(ctrl); +} + +/* Called when a mediated device is removed via sysfs or parent removal */ +static void nvmet_mdev_remove(struct mdev_device *mdev) +{ + struct nvmet_mdev_port *mport = container_of(mdev->type->parent, + struct nvmet_mdev_port, + parent); + + mutex_lock(&mport->mutex); + nvmet_mdev_remove_ctrl(dev_get_drvdata(&mdev->dev)); + mutex_unlock(&mport->mutex); +} + +static unsigned int nvmet_mdev_get_available(struct mdev_type *mtype) +{ + /* No limit since nvmet does not restrict it either */ + return UINT_MAX; +} + +static ssize_t poll_timeout_ms_store(struct device *dev, + struct device_attribute *attr, const char *buf, size_t count) +{ + struct nvmet_mdev_vctrl *vctrl = dev_get_drvdata(dev); + int ret; + + if (!vctrl) + return -ENODEV; + + ret = kstrtoint(buf, 10, &vctrl->poll_timeout_ms); + if (ret) + return ret; + + return count; +} + +static ssize_t poll_timeout_ms_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + struct nvmet_mdev_vctrl *vctrl = dev_get_drvdata(dev); + + if (!vctrl) + return -ENODEV; + + return sysfs_emit(buf, "%d\n", vctrl->poll_timeout_ms); +} +static DEVICE_ATTR_RW(poll_timeout_ms); + +static struct attribute *nvmet_mdev_dev_settings_atttributes[] = { + &dev_attr_poll_timeout_ms.attr, + NULL +}; + +static const struct attribute_group nvmet_mdev_setting_attr_group = { + .name = "settings", + .attrs = nvmet_mdev_dev_settings_atttributes, +}; + +static const struct attribute_group *nvmet_mdev_dev_attr_groups[] = { + &nvmet_mdev_setting_attr_group, + NULL, +}; + +static struct mdev_driver nvmet_mdev_driver = { + .device_api = VFIO_DEVICE_API_PCI_STRING, + .driver = { + .name = NVMET_MDEV_NAME, + .owner = THIS_MODULE, + .dev_groups = nvmet_mdev_dev_attr_groups, + }, + .probe = nvmet_mdev_probe, + .remove = nvmet_mdev_remove, + .get_available = nvmet_mdev_get_available, +}; + +static const struct bus_type nvmet_mdev_bus = { + .name = NVMET_MDEV_NAME, +}; + +static void nvmet_mdev_destroy_types(struct nvmet_mdev_port *mport) +{ + int i; + + for (i = 0; i < mport->type_count; i++) + kfree(mport->types[i].name); +} + +static int nvmet_mdev_setup_types(void *priv, struct nvmet_port *port, + struct nvmet_ctrl *ctrl) +{ + struct nvmet_mdev_port *mport = priv; + struct nvmet_mdev_type *type; + + if (mport->type_count == mport->ctrl_count) { + pr_err("Invalid number of controllers found %d\n", + mport->ctrl_count); + return -EINVAL; + } + + type = &mport->types[mport->type_count]; + type->name = kasprintf(GFP_KERNEL, "%hu", ctrl->cntlid); + if (!type->name) + return -ENOMEM; + + mport->mdev_types[mport->type_count] = &type->type; + mport->mdev_types[mport->type_count]->sysfs_name = type->name; + + mport->type_count++; + return 0; +} + +static void nvmet_mdev_dev_release(struct device *dev) +{ + struct nvmet_mdev_port *mport = container_of(dev, + struct nvmet_mdev_port, + device); + nvmet_mdev_destroy_types(mport); + kfree(mport->types); + kfree(mport->mdev_types); + kfree(mport); +} + +int nvmet_mdev_register_port(struct nvmet_mdev_port *mport) +{ + int ret; + + mport->types = kcalloc(mport->ctrl_count, sizeof(*mport->types), + GFP_KERNEL); + if (!mport->types) + return -ENOMEM; + + mport->mdev_types = kcalloc(mport->ctrl_count, + sizeof(*mport->mdev_types), GFP_KERNEL); + if (!mport->mdev_types) { + ret = -ENOMEM; + goto free_types; + } + + ret = nvmet_for_each_static_ctrl(mport->nvmet_port, nvmet_mdev_ops.type, + nvmet_mdev_setup_types, mport); + if (ret) + /* we might have partially setup the types arrays */ + goto destroy_types; + + mport->device.parent = nvmet_mdev_root_dev; + mport->device.bus = &nvmet_mdev_bus; + mport->device.release = nvmet_mdev_dev_release; + dev_set_name(&mport->device, "port-%s", + config_item_name(&mport->nvmet_port->group.cg_item)); + + ret = device_register(&mport->device); + if (ret) + goto free_mdev_types; + + ret = mdev_register_parent(&mport->parent, &mport->device, + &nvmet_mdev_driver, mport->mdev_types, + mport->type_count); + if (ret) + goto unreg_dev; + + return 0; + +unreg_dev: + device_unregister(&mport->device); +destroy_types: + nvmet_mdev_destroy_types(mport); +free_mdev_types: + kfree(mport->mdev_types); +free_types: + kfree(mport->types); + return ret; +} + +void nvmet_mdev_unregister_port(struct nvmet_mdev_port *mport) +{ + mdev_unregister_parent(&mport->parent); + device_unregister(&mport->device); +} + +static int nvmet_mdev_register_root_device(void) +{ + int ret; + + nvmet_mdev_root_dev = root_device_register(NVMET_MDEV_NAME); + if (IS_ERR(nvmet_mdev_root_dev)) + return PTR_ERR(nvmet_mdev_root_dev); + + ret = bus_register(&nvmet_mdev_bus); + if (ret) + goto unreg_root; + + nvmet_unregister_transport(&nvmet_mdev_ops); + return 0; + +unreg_root: + root_device_unregister(nvmet_mdev_root_dev); + return ret; +} + +static void nvmet_mdev_unregister_root_device(void) +{ + root_device_unregister(nvmet_mdev_root_dev); + bus_unregister(&nvmet_mdev_bus); +} + +static int __init nvmet_mdev_init(void) +{ + int ret; + + ret = nvmet_mdev_register_root_device(); + if (ret) + return ret; + + ret = mdev_register_driver(&nvmet_mdev_driver); + if (ret) + goto unreg_root; + + ret = nvmet_register_transport(&nvmet_mdev_ops); + if (ret) + goto unreg_driver; + + return 0; + +unreg_driver: + mdev_unregister_driver(&nvmet_mdev_driver); +unreg_root: + nvmet_mdev_unregister_root_device(); + return ret; +} + +static void __exit nvmet_mdev_exit(void) +{ + nvmet_unregister_transport(&nvmet_mdev_ops); + nvmet_mdev_unregister_root_device(); + mdev_unregister_driver(&nvmet_mdev_driver); +} + +module_init(nvmet_mdev_init); +module_exit(nvmet_mdev_exit); diff --git a/drivers/nvme/target/mdev-pci/io.c b/drivers/nvme/target/mdev-pci/io.c new file mode 100644 index 000000000000..ece3a01434ac --- /dev/null +++ b/drivers/nvme/target/mdev-pci/io.c @@ -0,0 +1,332 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * NVMe IO command translation and polling IO thread + * Copyright (c) 2019 - Maxim Levitsky + * Copyright (C) 2025 Oracle Corporation + */ +#include +#include +#include +#include +#include +#include +#include +#include "priv.h" + +static int nvmet_mdev_create_sgl(struct nvmet_mdev_req *mreq, u64 data_len, + const struct nvme_command *cmd) +{ + struct nvmet_ext_data_iter *iter = &mreq->data_iter; + struct nvmet_req *req = &mreq->req; + struct scatterlist *sg; + int i, ret; + + ret = nvmet_mdev_udata_iter_set_dptr(&mreq->data_iter, + &cmd->common.dptr, data_len); + if (ret) + return ret; + + ret = sg_alloc_table(&mreq->sgt, iter->count, GFP_KERNEL); + if (ret) + return ret; + + for_each_sgtable_sg(&mreq->sgt, sg, i) { + int seg_len = min(PAGE_SIZE, data_len); + struct page *page; + int offset; + + page = pfn_to_page(PHYS_PFN(iter->physical)); + offset = offset_in_page(iter->physical); + + sg_set_page(sg, page, seg_len, offset); + + ret = iter->next(iter); + if (WARN_ON(ret)) + goto release_iter; + data_len -= seg_len; + } + + req->sg = mreq->sgt.sgl; + req->sg_cnt = mreq->sgt.nents; + return 0; + +release_iter: + if (iter->release) + iter->release(iter); + + sg_free_table(&mreq->sgt); + return ret; +} + +static bool nvmet_mdev_submit_cmd(struct nvmet_mdev_vctrl *vctrl, + struct nvmet_mdev_vsq *vsq) +{ + struct nvmet_mdev_vcq *vcq = vsq->vcq; + struct nvme_completion cqe = {}; + struct nvmet_mdev_req *mreq; + struct nvme_command *cmd; + struct nvmet_req *req; + u16 ucid; + int ret; + + cmd = nvmet_mdev_vsq_get_cmd(vctrl, vsq, &ucid); + if (!cmd) + return false; + + if (ucid >= vsq->size) { + ret = DNR(NVME_SC_INVALID_FIELD); + goto complete; + } + + if (cmd->common.flags != 0) { + ret = DNR(NVME_SC_INVALID_FIELD); + goto complete; + } + + mreq = &vsq->reqs[ucid]; + memset(mreq, 0, sizeof(*mreq)); + + INIT_LIST_HEAD(&mreq->mem_map_list); + nvmet_mdev_udata_iter_setup(&vctrl->viommu, &mreq->data_iter, + &mreq->mem_map_list); + init_llist_node(&mreq->cq_node); + mreq->vcq = vcq; + + req = &mreq->req; + req->cmd = cmd; + req->cqe = &mreq->cqe; + req->port = vctrl->nvmet_ctrl->port; + + if (!nvmet_req_init(req, &vcq->nvmet_cq, &vsq->nvmet_sq, + &nvmet_mdev_ops)) { + vctrl->expected_responses++; + /* nvmet will complete via queue_response */ + return true; + } + + req->transfer_len = nvmet_req_transfer_len(req); + if (req->transfer_len) { + ret = nvmet_mdev_create_sgl(mreq, req->transfer_len, cmd); + if (ret) { + ret = nvmet_mdev_translate_error(ret); + goto uninit_req; + } + } + + vctrl->expected_responses++; + req->execute(req); + return true; + +uninit_req: + nvmet_req_uninit(req); +complete: + cqe.sq_head = cpu_to_le16(vsq->head); + cqe.sq_id = cpu_to_le16(vsq->qid); + cqe.command_id = cmd->common.command_id; + cqe.status = cpu_to_le16(ret << 1); + + nvmet_mdev_vcq_write_cqe(vctrl, vcq, &cqe); + return true; +} + +bool nvmet_mdev_process_responses(struct nvmet_mdev_vctrl *vctrl, + struct nvmet_mdev_vcq *vcq) +{ + struct nvmet_mdev_req *mreq, *mreq_next; + struct nvmet_ext_data_iter *iter; + struct llist_node *node; + bool processed = false; + + node = llist_del_all(&vcq->mreq_list); + if (!node) + return processed; + + llist_for_each_entry_safe(mreq, mreq_next, node, cq_node) { + iter = &mreq->data_iter; + + nvmet_mdev_vcq_write_cqe(vctrl, vcq, mreq->req.cqe); + + if (iter->release) + iter->release(iter); + + if (mreq->req.sg_cnt) + sg_free_table(&mreq->sgt); + + vctrl->expected_responses--; + processed = true; + } + + return processed; +} + +void nvmet_mdev_io_resume(struct nvmet_mdev_vctrl *vctrl) +{ + if (!vctrl->iothread || !vctrl->iothread_parked || vctrl->io_idle) + return; + + vctrl->iothread_parked = false; + /* has memory barrier */ + kthread_unpark(vctrl->iothread); +} + +bool nvmet_mdev_io_pause(struct nvmet_mdev_vctrl *vctrl) +{ + if (!vctrl->iothread || vctrl->iothread_parked) + return false; + + vctrl->iothread_parked = true; + kthread_park(vctrl->iothread); + return true; +} + +static int nvmet_mdev_get_poll_tmo(struct nvmet_mdev_vctrl *vctrl) +{ + /* can't stop polling when shadow db not enabled */ + return vctrl->mmio.shadow_db_en ? vctrl->poll_timeout_ms : 0; +} + +static void nvmet_mdev_process_io(struct nvmet_mdev_vctrl *vctrl) +{ + struct nvmet_mdev_vcq *vcq; + struct nvmet_mdev_vsq *vsq; + unsigned long last = jiffies; + bool idle = false; + int timeout; + u16 qid; + int i; + + vctrl->now = ktime_get(); + + /* main loop */ + while (!kthread_should_park()) { + vctrl->now = ktime_get(); + + for_each_set_bit(qid, vctrl->vsq_en, NVMET_MDEV_MAX_NR_QUEUES) { + vsq = &vctrl->vsqs[qid]; + + for (i = 0 ; i < (1 << vctrl->arb_burst_shift) ; i++) + if (nvmet_mdev_submit_cmd(vctrl, vsq)) + last = jiffies; + } + + for_each_set_bit(qid, vctrl->vcq_en, NVMET_MDEV_MAX_NR_QUEUES) { + vcq = &vctrl->vcqs[qid]; + + nvmet_mdev_vcq_process(vctrl, vcq, true, vctrl->now); + } + + for_each_set_bit(qid, vctrl->vcq_en, NVMET_MDEV_MAX_NR_QUEUES) { + vcq = &vctrl->vcqs[qid]; + + if (nvmet_mdev_process_responses(vctrl, vcq)) + last = jiffies; + } + + /* Check if we need to stop polling */ + timeout = nvmet_mdev_get_poll_tmo(vctrl); + if (timeout && + time_is_before_jiffies(last + msecs_to_jiffies(timeout))) { + idle = true; + break; + } + cond_resched(); + } + + for_each_set_bit(qid, vctrl->vcq_en, NVMET_MDEV_MAX_NR_QUEUES) { + vcq = &vctrl->vcqs[qid]; + + /* Drain all the pending completion interrupts to the guest */ + if (nvmet_mdev_vcq_flush(vctrl, vcq, vctrl->now)) + idle = false; + } + + /* + * Park IO thread if IO is truly idle. + * TODO - expected_responses will always be > 1 because of async + * events. + */ + if (!vctrl->expected_responses && idle) { + if (!mutex_trylock(&vctrl->lock)) + return; + + for_each_set_bit(qid, vctrl->vsq_en, NVMET_MDEV_MAX_NR_QUEUES) { + vsq = &vctrl->vsqs[qid]; + + if (!nvmet_mdev_vsq_suspend_io(vsq)) + idle = false; + } + + if (idle) { + _DBG(vctrl, "IO: self-parking\n"); + vctrl->io_idle = true; + nvmet_mdev_io_pause(vctrl); + } + mutex_unlock(&vctrl->lock); + } +} + +static int nvmet_mdev_poll(void *data) +{ + struct nvmet_mdev_vctrl *vctrl = data; + + if (kthread_should_stop()) + return 0; + + _DBG(vctrl, "IO: iothread started\n"); + + for (;;) { + if (kthread_should_park()) { + _DBG(vctrl, "IO: iothread parked\n"); + kthread_parkme(); + } + + if (kthread_should_stop()) + break; + + nvmet_mdev_process_io(vctrl); + } + + _DBG(vctrl, "IO: iothread stopped\n"); + return 0; +} + +int nvmet_mdev_io_create(struct nvmet_mdev_vctrl *vctrl) +{ + char name[TASK_COMM_LEN]; + + _DBG(vctrl, "IO: creating the polling iothread\n"); + + snprintf(name, sizeof(name), "nvmet_mdev%d", vctrl->nvmet_ctrl->cntlid); + + vctrl->iothread_parked = false; + vctrl->io_idle = true; + + vctrl->iothread = kthread_create(nvmet_mdev_poll, vctrl, name); + if (IS_ERR(vctrl->iothread)) { + vctrl->iothread = NULL; + return PTR_ERR(vctrl->iothread); + } + + if (vctrl->io_idle) { + vctrl->iothread_parked = true; + kthread_park(vctrl->iothread); + return 0; + } + + wake_up_process(vctrl->iothread); + return 0; +} + +void nvmet_mdev_io_free(struct nvmet_mdev_vctrl *vctrl) +{ + _DBG(vctrl, "IO: destroying the polling iothread\n"); + nvmet_mdev_io_pause(vctrl); + kthread_stop(vctrl->iothread); + vctrl->iothread = NULL; +} + +void nvmet_mdev_assert_io_not_running(struct nvmet_mdev_vctrl *vctrl) +{ + if (WARN_ON(vctrl->iothread && !vctrl->iothread_parked)) + nvmet_mdev_io_pause(vctrl); +} diff --git a/drivers/nvme/target/mdev-pci/irq.c b/drivers/nvme/target/mdev-pci/irq.c new file mode 100644 index 000000000000..38a096427dcb --- /dev/null +++ b/drivers/nvme/target/mdev-pci/irq.c @@ -0,0 +1,269 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * NVMe virtual controller IRQ implementation (MSIx and INTx) + * Copyright (c) 2019 - Maxim Levitsky + */ + +#include +#include +#include +#include +#include "priv.h" + +/* Setup the interrupt subsystem */ +void nvmet_mdev_irqs_setup(struct nvmet_mdev_vctrl *vctrl) +{ + vctrl->irqs.mode = NVME_MDEV_IMODE_NONE; + vctrl->irqs.irq_coalesc_max = 1; +} + +/* Enable INTx or MSIx interrupts */ +static int __nvmet_mdev_irqs_enable(struct nvmet_mdev_vctrl *vctrl, + enum nvmet_mdev_irq_mode mode) +{ + bool paused; + + if (vctrl->irqs.mode == mode) + return 0; + if (vctrl->irqs.mode != NVME_MDEV_IMODE_NONE) + return -EBUSY; + + if (mode == NVME_MDEV_IMODE_INTX) + _DBG(vctrl, "IRQ: enable INTx interrupts\n"); + else if (mode == NVME_MDEV_IMODE_MSIX) + _DBG(vctrl, "IRQ: enable MSIX interrupts\n"); + else + WARN_ON(1); + + paused = nvmet_mdev_io_pause(vctrl); + vctrl->irqs.mode = mode; + if (paused) + nvmet_mdev_io_resume(vctrl); + return 0; +} + +int nvmet_mdev_irqs_enable(struct nvmet_mdev_vctrl *vctrl, + enum nvmet_mdev_irq_mode mode) +{ + int retval; + + mutex_lock(&vctrl->lock); + retval = __nvmet_mdev_irqs_enable(vctrl, mode); + mutex_unlock(&vctrl->lock); + return retval; +} + +/* Disable INTx or MSIx interrupts */ +static void __nvmet_mdev_irqs_disable(struct nvmet_mdev_vctrl *vctrl, + enum nvmet_mdev_irq_mode mode) +{ + unsigned int i; + bool paused; + + if (vctrl->irqs.mode == NVME_MDEV_IMODE_NONE) + return; + if (vctrl->irqs.mode != mode) + return; + + if (vctrl->irqs.mode == NVME_MDEV_IMODE_INTX) + _DBG(vctrl, "IRQ: disable INTx interrupts\n"); + else if (vctrl->irqs.mode == NVME_MDEV_IMODE_MSIX) + _DBG(vctrl, "IRQ: disable MSIX interrupts\n"); + else + WARN_ON(1); + + paused = nvmet_mdev_io_pause(vctrl); + + for (i = 0; i < MAX_VIRTUAL_IRQS; i++) { + struct nvmet_mdev_user_irq *vec = &vctrl->irqs.vecs[i]; + + if (vec->trigger) { + eventfd_ctx_put(vec->trigger); + vec->trigger = NULL; + } + vec->irq_pending_cnt = 0; + vec->irq_time = 0; + } + vctrl->irqs.mode = NVME_MDEV_IMODE_NONE; + if (paused) + nvmet_mdev_io_resume(vctrl); +} + +void nvmet_mdev_irqs_disable(struct nvmet_mdev_vctrl *vctrl, + enum nvmet_mdev_irq_mode mode) +{ + mutex_lock(&vctrl->lock); + __nvmet_mdev_irqs_disable(vctrl, mode); + mutex_unlock(&vctrl->lock); +} + +/* Set eventfd triggers for INTx or MSIx interrupts */ +int nvmet_mdev_irqs_set_triggers(struct nvmet_mdev_vctrl *vctrl, int start, + int count, int32_t *fds) +{ + unsigned int i; + bool paused; + + mutex_lock(&vctrl->lock); + paused = nvmet_mdev_io_pause(vctrl); + + for (i = 0; i < count; i++) { + int irqindex = start + i; + struct eventfd_ctx *trigger; + struct nvmet_mdev_user_irq *irq = &vctrl->irqs.vecs[irqindex]; + + if (irq->trigger) { + eventfd_ctx_put(irq->trigger); + irq->trigger = NULL; + } + + if (fds[i] < 0) + continue; + + trigger = eventfd_ctx_fdget(fds[i]); + if (IS_ERR(trigger)) { + mutex_unlock(&vctrl->lock); + return PTR_ERR(trigger); + } + + irq->trigger = trigger; + } + if (paused) + nvmet_mdev_io_resume(vctrl); + mutex_unlock(&vctrl->lock); + return 0; +} + +/* Set eventfd trigger for unplug interrupt */ +static int __nvmet_mdev_irqs_set_unplug_trigger(struct nvmet_mdev_vctrl *vctrl, + int32_t fd) +{ + struct eventfd_ctx *trigger; + + if (vctrl->irqs.request_trigger) { + _DBG(vctrl, "IRQ: clear hotplug trigger\n"); + eventfd_ctx_put(vctrl->irqs.request_trigger); + vctrl->irqs.request_trigger = NULL; + } + + if (fd < 0) + return 0; + + _DBG(vctrl, "IRQ: set hotplug trigger\n"); + + trigger = eventfd_ctx_fdget(fd); + if (IS_ERR(trigger)) + return PTR_ERR(trigger); + + vctrl->irqs.request_trigger = trigger; + return 0; +} + +int nvmet_mdev_irqs_set_unplug_trigger(struct nvmet_mdev_vctrl *vctrl, + int32_t fd) +{ + int retval; + + mutex_lock(&vctrl->lock); + retval = __nvmet_mdev_irqs_set_unplug_trigger(vctrl, fd); + mutex_unlock(&vctrl->lock); + return retval; +} + +/* Reset the interrupts subsystem */ +void nvmet_mdev_irqs_reset(struct nvmet_mdev_vctrl *vctrl) +{ + int i; + + lockdep_assert_held(&vctrl->lock); + + if (vctrl->irqs.mode != NVME_MDEV_IMODE_NONE) + __nvmet_mdev_irqs_disable(vctrl, vctrl->irqs.mode); + + __nvmet_mdev_irqs_set_unplug_trigger(vctrl, -1); + + for (i = 0; i < MAX_VIRTUAL_IRQS; i++) { + struct nvmet_mdev_user_irq *vec = &vctrl->irqs.vecs[i]; + + vec->irq_coalesc_en = false; + vec->irq_pending_cnt = 0; + vec->irq_time = 0; + } + + vctrl->irqs.irq_coalesc_time_us = 0; +} + +/* Check if interrupt can be coalesced */ +static bool nvmet_mdev_irq_coalesce(struct nvmet_mdev_vctrl *vctrl, + struct nvmet_mdev_user_irq *irq, + ktime_t now) +{ + s64 delta; + + if (!irq->irq_coalesc_en) + return false; + + if (irq->irq_pending_cnt >= vctrl->irqs.irq_coalesc_max) + return false; + + delta = ktime_us_delta(now, irq->irq_time); + return (delta < vctrl->irqs.irq_coalesc_time_us); +} + +void nvmet_mdev_irq_raise_unplug_event(struct nvmet_mdev_vctrl *vctrl) +{ + mutex_lock(&vctrl->lock); + + if (vctrl->irqs.request_trigger) { + dev_notice_ratelimited(mdev_dev(vctrl->mdev), + "Relaying device request to user\n"); + eventfd_signal(vctrl->irqs.request_trigger); + + } else { + dev_notice(mdev_dev(vctrl->mdev), + "No device request channel registered, blocked until released by user\n"); + } + mutex_unlock(&vctrl->lock); +} + +/* Raise an interrupt */ +void nvmet_mdev_irq_raise(struct nvmet_mdev_vctrl *vctrl, unsigned int index) +{ + struct nvmet_mdev_user_irq *irq = &vctrl->irqs.vecs[index]; + + irq->irq_pending_cnt++; +} + +/* Unraise an interrupt */ +void nvmet_mdev_irq_clear(struct nvmet_mdev_vctrl *vctrl, unsigned int index, + ktime_t now) +{ + struct nvmet_mdev_user_irq *irq = &vctrl->irqs.vecs[index]; + + irq->irq_time = now; + irq->irq_pending_cnt = 0; +} + +/* Directly trigger an interrupt without affecting irq coalescing settings */ +void nvmet_mdev_irq_trigger(struct nvmet_mdev_vctrl *vctrl, unsigned int index) +{ + struct nvmet_mdev_user_irq *irq = &vctrl->irqs.vecs[index]; + + if (irq->trigger) + eventfd_signal(irq->trigger); +} + +/* Trigger previously raised interrupt */ +void nvmet_mdev_irq_cond_trigger(struct nvmet_mdev_vctrl *vctrl, + unsigned int index, ktime_t now) +{ + struct nvmet_mdev_user_irq *irq = &vctrl->irqs.vecs[index]; + + if (irq->irq_pending_cnt == 0) + return; + + if (!nvmet_mdev_irq_coalesce(vctrl, irq, now)) { + nvmet_mdev_irq_trigger(vctrl, index); + nvmet_mdev_irq_clear(vctrl, index, now); + } +} diff --git a/drivers/nvme/target/mdev-pci/mmio.c b/drivers/nvme/target/mdev-pci/mmio.c new file mode 100644 index 000000000000..f41246b73044 --- /dev/null +++ b/drivers/nvme/target/mdev-pci/mmio.c @@ -0,0 +1,561 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * NVMe virtual controller MMIO implementation + * Copyright (c) 2019 - Maxim Levitsky + */ +#include +#include +#include "priv.h" + +#define DB_AREA_SIZE (NVMET_MDEV_MAX_NR_QUEUES * 2 * (4 << DB_STRIDE_SHIFT)) +#define DB_MASK ((4 << DB_STRIDE_SHIFT) - 1) +#define MMIO_BAR_SIZE __roundup_pow_of_two(NVME_REG_DBS + DB_AREA_SIZE) + +/* Put the controller into fatal error state. Only way out is reset */ +static void nvmet_mdev_mmio_fatal_error(struct nvmet_mdev_vctrl *vctrl) +{ + if (vctrl->mmio.csts & NVME_CSTS_CFS) + return; + + vctrl->mmio.csts |= NVME_CSTS_CFS; + nvmet_mdev_io_pause(vctrl); + + if (vctrl->mmio.csts & NVME_CSTS_RDY) + nvmet_mdev_vctrl_disable(vctrl); +} + +/* This is memory fault handler for the mmap area of the doorbells */ +static vm_fault_t nvmet_mdev_mmio_dbs_mmap_fault(struct vm_fault *vmf) +{ + struct vm_area_struct *vma = vmf->vma; + struct nvmet_mdev_vctrl *vctrl = vma->vm_private_data; + + /* DB area is just one page, starting at offset 4096 of the mmio */ + if (WARN_ON(vmf->pgoff != 1)) + return VM_FAULT_SIGBUS; + + get_page(vctrl->mmio.dbs_page); + vmf->page = vctrl->mmio.dbs_page; + return 0; +} + +static const struct vm_operations_struct nvmet_mdev_mmio_dbs_vm_ops = { + .fault = nvmet_mdev_mmio_dbs_mmap_fault, +}; + +/* check that user db write is valid and send an error if not */ +bool nvmet_mdev_mmio_db_check(struct nvmet_mdev_vctrl *vctrl, u16 qid, u16 size, + u16 db) +{ + if (db < size) + return true; + if (qid == 0) { + _DBG(vctrl, "MMIO: invalid admin DB write - fatal error\n"); + nvmet_mdev_mmio_fatal_error(vctrl); + return false; + } + + _DBG(vctrl, "MMIO: invalid DB value write qid=%d, size=%d, value=%d\n", + qid, size, db); + + nvmet_add_async_event(vctrl->nvmet_ctrl, NVME_AER_ERROR, + NVME_AER_ERROR_INVALID_DB_VALUE, NVME_LOG_ERROR); + return false; +} + +/* handle submission queue doorbell write */ +static void nvmet_mdev_mmio_db_write_sq(struct nvmet_mdev_vctrl *vctrl, u32 qid, + u32 val) +{ + _DBG(vctrl, "MMIO: doorbell SQID %d, DB write %d\n", qid, val); + + /* check if the db belongs to a valid queue */ + if (qid >= NVMET_MDEV_MAX_NR_QUEUES || !test_bit(qid, vctrl->vsq_en)) + goto err_db; + + vctrl->io_idle = false; + + if (!vctrl->mmio.shadow_db_supported) + return; + + nvmet_mdev_io_resume(vctrl); + return; + +err_db: + _DBG(vctrl, "MMIO: inactive/invalid SQ DB write qid=%d, value=%d\n", + qid, val); + + nvmet_add_async_event(vctrl->nvmet_ctrl, NVME_AER_ERROR, + NVME_AER_ERROR_INVALID_DB_REG, NVME_LOG_ERROR); +} + +/* handle doorbell write */ +static void nvmet_mdev_mmio_db_write_cq(struct nvmet_mdev_vctrl *vctrl, u32 qid, + u32 val) +{ + _DBG(vctrl, "MMIO: doorbell CQID %d, DB write %d\n", qid, val); + + lockdep_assert_held(&vctrl->lock); + /* check if the db belongs to a valid queue */ + if (qid >= NVMET_MDEV_MAX_NR_QUEUES || !test_bit(qid, vctrl->vcq_en)) + goto err_db; + + if (!vctrl->mmio.shadow_db_supported) + return; + + nvmet_mdev_io_resume(vctrl); + return; + +err_db: + _DBG(vctrl, + "MMIO: inactive/invalid CQ DB write qid=%d, value=%d\n", + qid, val); + + nvmet_add_async_event(vctrl->nvmet_ctrl, NVME_AER_ERROR, + NVME_AER_ERROR_INVALID_DB_REG, NVME_LOG_ERROR); +} + +/* This is called when user enables the controller */ +static void nvmet_mdev_mmio_cntrl_enable(struct nvmet_mdev_vctrl *vctrl) +{ + u64 acq, asq; + + lockdep_assert_held(&vctrl->lock); + + /* Controller must be reset from the dead state */ + if (nvmet_mdev_vctrl_is_dead(vctrl)) + goto error; + + if (nvmet_cc_ams(vctrl->mmio.cc) != NVME_CC_AMS_RR) + goto error; + + /* Check the page size */ + if (nvmet_cc_mps(vctrl->mmio.cc) != (PAGE_SHIFT - 12)) + goto error; + + /* Start the admin completion queue */ + acq = vctrl->mmio.acql | ((u64)vctrl->mmio.acqh << 32); + asq = vctrl->mmio.asql | ((u64)vctrl->mmio.asqh << 32); + + if (!nvmet_mdev_vctrl_enable(vctrl, acq, asq, vctrl->mmio.aqa)) + goto error; + + /* Success! */ + vctrl->mmio.csts |= NVME_CSTS_RDY; + return; +error: + _WARN(vctrl, "MMIO: failure to enable the controller - fatal error\n"); + nvmet_mdev_mmio_fatal_error(vctrl); +} + +/* + * This is called when user sends a notification that controller is + * about to be disabled + */ +static void nvmet_mdev_mmio_cntrl_shutdown(struct nvmet_mdev_vctrl *vctrl) +{ + lockdep_assert_held(&vctrl->lock); + + nvmet_update_cc(vctrl->nvmet_ctrl, vctrl->mmio.cc); + /* + * Manually clear shutdown notification bits + * TODO: inherit csts/cc from nvmet core. + */ + vctrl->mmio.cc &= ~NVME_CC_SHN_MASK; + + if (nvmet_mdev_vctrl_is_dead(vctrl)) { + _DBG(vctrl, "MMIO: shutdown notification for dead ctrl\n"); + return; + } + + /* not enabled */ + if (!(vctrl->mmio.csts & NVME_CSTS_RDY)) { + _DBG(vctrl, "MMIO: shutdown notification with CSTS.RDY==0\n"); + nvmet_mdev_assert_io_not_running(vctrl); + return; + } + + nvmet_mdev_io_pause(vctrl); + nvmet_mdev_vctrl_disable(vctrl); + vctrl->mmio.csts |= NVME_CSTS_SHST_CMPLT; +} + +/* MMIO BAR read/write */ +static int nvmet_mdev_mmio_bar_access(struct nvmet_mdev_vctrl *vctrl, + u16 offset, char *buf, u32 count, + bool is_write) +{ + u32 val, oldval; + + mutex_lock(&vctrl->lock); + + /* + * Drop non DWORD sized and aligned reads/writes + * (QWORD read/writes are split by the caller) + */ + if (count != 4 || (offset & 0x3)) + goto drop; + + val = is_write ? le32_to_cpu(*(__le32 *)buf) : 0; + + switch (offset) { + case NVME_REG_CAP: + /* controller capabilities (low 32 bit) */ + if (is_write) + goto drop; + store_le32(buf, vctrl->mmio.cap & 0xFFFFFFFF); + break; + case NVME_REG_CAP + 4: + /* controller capabilities (upper 32 bit) */ + if (is_write) + goto drop; + store_le32(buf, vctrl->mmio.cap >> 32); + break; + case NVME_REG_VS: + if (is_write) + goto drop; + store_le32(buf, NVME_MDEV_NVME_VER); + break; + case NVME_REG_INTMS: + case NVME_REG_INTMC: + /* Interrupt Mask Set & Clear */ + goto drop; + case NVME_REG_CC: + /* Controller Configuration */ + if (!is_write) { + store_le32(buf, vctrl->mmio.cc); + break; + } + + oldval = vctrl->mmio.cc; + vctrl->mmio.cc = val; + + /* drop if reserved bits set */ + if (vctrl->mmio.cc & 0xFF00000E) { + _DBG(vctrl, + "MMIO: reserved bits of CC set - fatal error\n"); + nvmet_mdev_mmio_fatal_error(vctrl); + goto drop; + } + + /* + * CSS(command set),MPS(memory page size),AMS(queue arbitration) + * must not be changed while controller is running + */ + if (vctrl->mmio.csts & NVME_CSTS_RDY) { + if ((vctrl->mmio.cc & 0x3FF0) != (oldval & 0x3FF0)) { + _DBG(vctrl, + "MMIO: attempt to change setting bits of CC while CC.EN=1 - fatal error\n"); + + nvmet_mdev_mmio_fatal_error(vctrl); + goto drop; + } + } + + if (nvmet_cc_shn(vctrl->mmio.cc)) { + _DBG(vctrl, "MMIO: CC.SHN != 0 - shutdown\n"); + nvmet_mdev_mmio_cntrl_shutdown(vctrl); + } + + /* change in controller enabled state */ + if (nvmet_cc_en(val) == nvmet_cc_en(oldval)) + break; + + if (nvmet_cc_en(vctrl->mmio.cc)) { + _DBG(vctrl, "MMIO: CC.EN<=1 - enable the controller\n"); + nvmet_mdev_mmio_cntrl_enable(vctrl); + } else { + _DBG(vctrl, "MMIO: CC.EN<=0 - reset controller\n"); + __nvmet_mdev_vctrl_reset(vctrl, false); + } + + break; + case NVME_REG_CSTS: + /* Controller Status */ + if (is_write) + goto drop; + store_le32(buf, vctrl->mmio.csts); + break; + case NVME_REG_AQA: + /* admin queue submission and completion size */ + if (!is_write) + store_le32(buf, vctrl->mmio.aqa); + else if (!(vctrl->mmio.csts & NVME_CSTS_RDY)) + vctrl->mmio.aqa = val; + else + goto drop; + break; + case NVME_REG_ASQ: + /* admin submission queue address (low 32 bit) */ + if (!is_write) + store_le32(buf, vctrl->mmio.asql); + else if (!(vctrl->mmio.csts & NVME_CSTS_RDY)) + vctrl->mmio.asql = val; + else + goto drop; + break; + + case NVME_REG_ASQ + 4: + /* admin submission queue address (high 32 bit) */ + if (!is_write) + store_le32(buf, vctrl->mmio.asqh); + else if (!(vctrl->mmio.csts & NVME_CSTS_RDY)) + vctrl->mmio.asqh = val; + else + goto drop; + break; + case NVME_REG_ACQ: + /* admin completion queue address (low 32 bit) */ + if (!is_write) + store_le32(buf, vctrl->mmio.acql); + else if (!(vctrl->mmio.csts & NVME_CSTS_RDY)) + vctrl->mmio.acql = val; + else + goto drop; + break; + case NVME_REG_ACQ + 4: + /* admin completion queue address (high 32 bit) */ + if (!is_write) + store_le32(buf, vctrl->mmio.acqh); + else if (!(vctrl->mmio.csts & NVME_CSTS_RDY)) + vctrl->mmio.acqh = val; + else + goto drop; + break; + case NVME_REG_CMBLOC: + case NVME_REG_CMBSZ: + /* not supported - hardwired to 0 */ + if (is_write) + goto drop; + store_le32(buf, 0); + break; + case NVME_REG_DBS ... (NVME_REG_DBS + DB_AREA_SIZE - 1): { + /* completion and submission doorbells */ + u16 db_offset = offset - NVME_REG_DBS; + u16 index = db_offset >> (DB_STRIDE_SHIFT + 2); + u16 qid = index >> 1; + bool sq = (index & 0x1) == 0; + + if (!is_write || (db_offset & DB_MASK)) + goto drop; + + if (!(vctrl->mmio.csts & NVME_CSTS_RDY)) + goto drop; + + if (nvmet_mdev_vctrl_is_dead(vctrl)) + goto drop; + + sq ? nvmet_mdev_mmio_db_write_sq(vctrl, qid, val) : + nvmet_mdev_mmio_db_write_cq(vctrl, qid, val); + break; + } + default: + goto drop; + } + + mutex_unlock(&vctrl->lock); + return count; + +drop: + _WARN(vctrl, "MMIO: dropping write at 0x%x\n", offset); + mutex_unlock(&vctrl->lock); + return 0; +} + +/* Called when the virtual controller is created */ +int nvmet_mdev_mmio_create(struct nvmet_mdev_vctrl *vctrl) +{ + struct nvmet_ctrl *ctrl = vctrl->nvmet_ctrl; + int ret; + + /* BAR0 */ + nvmet_mdev_pci_setup_bar(vctrl, PCI_BASE_ADDRESS_0, MMIO_BAR_SIZE, + nvmet_mdev_mmio_bar_access); + + /* CAP has 4 bits for the doorbell stride shift */ + BUILD_BUG_ON(DB_STRIDE_SHIFT > 0xF); + + /* Shadow doorbell limits doorbells to 1 page */ + BUILD_BUG_ON(DB_AREA_SIZE > PAGE_SIZE); + + /* Just in case... */ + BUILD_BUG_ON((PAGE_SHIFT - 12) > 0xF); + + /* + * Inherit nvmet core's defaults and configfs values and then add + * specific settings. + */ + vctrl->mmio.cap = ctrl->cap; + + vctrl->mmio.cap |= + /* + * CQR: physically contiguous queues until we fine a OS + * that needs otherwise. + */ + (1ULL << 16) | + /* DSTRD: doorbell stride */ + ((u64)DB_STRIDE_SHIFT << 32) | + /* MPSMIN: Minimum page size supported is PAGE_SIZE */ + ((u64)(PAGE_SHIFT - 12) << 48) | + /* MPSMAX: Maximum page size is PAGE_SIZE as well */ + ((u64)(PAGE_SHIFT - 12) << 52); + + /* Create the (regular) doorbell buffers */ + vctrl->mmio.dbs_page = alloc_pages(__GFP_ZERO, 0); + + ret = -ENOMEM; + + if (!vctrl->mmio.dbs_page) + goto error0; + + vctrl->mmio.db_page_kmap = kmap_local_page(vctrl->mmio.dbs_page); + if (!vctrl->mmio.db_page_kmap) + goto error1; + + vctrl->mmio.fake_eidx_page = alloc_page(__GFP_ZERO); + if (!vctrl->mmio.fake_eidx_page) + goto error2; + + vctrl->mmio.fake_eidx_kmap = kmap_local_page(vctrl->mmio.fake_eidx_page); + if (!vctrl->mmio.fake_eidx_kmap) + goto error3; + return 0; +error3: + put_page(vctrl->mmio.fake_eidx_kmap); +error2: + kunmap_local(vctrl->mmio.db_page_kmap); +error1: + put_page(vctrl->mmio.dbs_page); +error0: + return ret; +} + +/* Called when the virtual controller is reset */ +void nvmet_mdev_mmio_reset(struct nvmet_mdev_vctrl *vctrl, bool pci_reset) +{ + vctrl->mmio.cc = 0; + vctrl->mmio.csts = 0; + + if (pci_reset) { + vctrl->mmio.aqa = 0; + vctrl->mmio.asql = 0; + vctrl->mmio.asqh = 0; + vctrl->mmio.acql = 0; + vctrl->mmio.acqh = 0; + } +} + +/* Called when the virtual controller is opened */ +void nvmet_mdev_mmio_open(struct nvmet_mdev_vctrl *vctrl) +{ + if (!vctrl->mmio.shadow_db_supported) + nvmet_mdev_vctrl_region_set_mmap(vctrl, + VFIO_PCI_BAR0_REGION_INDEX, + NVME_REG_DBS, PAGE_SIZE, + &nvmet_mdev_mmio_dbs_vm_ops); + else + nvmet_mdev_vctrl_region_disable_mmap(vctrl, + VFIO_PCI_BAR0_REGION_INDEX); +} + +/* Called when the virtual controller queues are enabled */ +int nvmet_mdev_mmio_enable_dbs(struct nvmet_mdev_vctrl *vctrl) +{ + if (WARN_ON(vctrl->mmio.shadow_db_en)) + return -EINVAL; + + nvmet_mdev_assert_io_not_running(vctrl); + + /* setup normal doorbells and reset them */ + vctrl->mmio.dbs = vctrl->mmio.db_page_kmap; + vctrl->mmio.eidxs = vctrl->mmio.fake_eidx_kmap; + memset((void *)vctrl->mmio.dbs, 0, DB_AREA_SIZE); + memset((void *)vctrl->mmio.eidxs, 0, DB_AREA_SIZE); + return 0; +} + +/* Called when the virtual controller shadow doorbell is enabled */ +int nvmet_mdev_mmio_enable_dbs_shadow(struct nvmet_mdev_vctrl *vctrl, + dma_addr_t sdb_iova, + dma_addr_t eidx_iova) +{ + int ret; + + ret = nvmet_mdev_viommu_add(&vctrl->viommu, + VFIO_DMA_MAP_FLAG_READ | + VFIO_DMA_MAP_FLAG_WRITE, + sdb_iova, PAGE_SIZE, + &vctrl->viommu.mem_map_list); + if (ret) + return ret; + + ret = nvmet_mdev_viommu_create_kmap(&vctrl->viommu, sdb_iova, + &vctrl->mmio.sdb_map); + if (ret) + goto unmap_sdb; + + ret = nvmet_mdev_viommu_add(&vctrl->viommu, + VFIO_DMA_MAP_FLAG_READ | + VFIO_DMA_MAP_FLAG_WRITE, + eidx_iova, PAGE_SIZE, + &vctrl->viommu.mem_map_list); + if (ret) + goto kunmap_sdb; + + ret = nvmet_mdev_viommu_create_kmap(&vctrl->viommu, eidx_iova, + &vctrl->mmio.seidx_map); + if (ret) + goto unmap_eidx; + + vctrl->mmio.sdb_iova = sdb_iova; + vctrl->mmio.dbs = vctrl->mmio.sdb_map.kmap; + + vctrl->mmio.eidx_iova = eidx_iova; + vctrl->mmio.eidxs = vctrl->mmio.seidx_map.kmap; + + memcpy((void *)vctrl->mmio.dbs, vctrl->mmio.db_page_kmap, + DB_AREA_SIZE); + memcpy((void *)vctrl->mmio.eidxs, vctrl->mmio.db_page_kmap, + DB_AREA_SIZE); + + vctrl->mmio.shadow_db_en = true; + return 0; + +unmap_eidx: + nvmet_mdev_vctrl_viommu_unmap(vctrl, eidx_iova, PAGE_SIZE); +kunmap_sdb: + nvmet_mdev_viommu_free_kmap(&vctrl->viommu, &vctrl->mmio.sdb_map); +unmap_sdb: + nvmet_mdev_vctrl_viommu_unmap(vctrl, sdb_iova, PAGE_SIZE); + return ret; +} + +/* Disable the doorbells */ +void nvmet_mdev_mmio_disable_dbs(struct nvmet_mdev_vctrl *vctrl) +{ + nvmet_mdev_assert_io_not_running(vctrl); + + /* Free the shadow doorbells */ + nvmet_mdev_viommu_free_kmap(&vctrl->viommu, &vctrl->mmio.sdb_map); + nvmet_mdev_viommu_free_kmap(&vctrl->viommu, &vctrl->mmio.seidx_map); + + nvmet_mdev_vctrl_viommu_unmap(vctrl, vctrl->mmio.sdb_iova, PAGE_SIZE); + nvmet_mdev_vctrl_viommu_unmap(vctrl, vctrl->mmio.eidx_iova, PAGE_SIZE); + + /* Clear the doorbells */ + vctrl->mmio.sdb_iova = 0; + vctrl->mmio.eidx_iova = 0; + vctrl->mmio.dbs = NULL; + vctrl->mmio.eidxs = NULL; + vctrl->mmio.shadow_db_en = false; +} + +/* Called when the virtual controller is about to be freed */ +void nvmet_mdev_mmio_free(struct nvmet_mdev_vctrl *vctrl) +{ + nvmet_mdev_assert_io_not_running(vctrl); + kunmap_local(vctrl->mmio.db_page_kmap); + put_page(vctrl->mmio.dbs_page); + kunmap_local(vctrl->mmio.fake_eidx_kmap); + put_page(vctrl->mmio.fake_eidx_page); +} diff --git a/drivers/nvme/target/mdev-pci/pci.c b/drivers/nvme/target/mdev-pci/pci.c new file mode 100644 index 000000000000..dda0eed00854 --- /dev/null +++ b/drivers/nvme/target/mdev-pci/pci.c @@ -0,0 +1,241 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * NVMe virtual controller minimal PCI/PCIe config space implementation + * Copyright (c) 2019 - Maxim Levitsky + */ +#include +#include +#include "priv.h" + +/* setup a 64 bit PCI bar */ +void nvmet_mdev_pci_setup_bar(struct nvmet_mdev_vctrl *vctrl, u8 bar, + unsigned int size, region_access_fn access_fn) +{ + nvmet_mdev_vctrl_add_region(vctrl, VFIO_PCI_BAR0_REGION_INDEX + + ((bar - PCI_BASE_ADDRESS_0) >> 2), + size, access_fn); + + store_le32(vctrl->pcicfg.wmask + bar, ~((u64)size - 1)); + store_le32(vctrl->pcicfg.values + bar, + PCI_BASE_ADDRESS_SPACE_MEMORY | + PCI_BASE_ADDRESS_MEM_TYPE_64); +} + +/* Allocate a pci capability */ +static u8 nvmet_mdev_pci_allocate_cap(struct nvmet_mdev_vctrl *vctrl, u8 id, + u8 size) +{ + u8 *cfg = vctrl->pcicfg.values; + u8 newcap = vctrl->pcicfg.end; + u8 cap = cfg[PCI_CAPABILITY_LIST]; + + size = round_up(size, 4); + /* only standard cfg space caps for now */ + WARN_ON(newcap + size > 256); + + if (!cfg[PCI_CAPABILITY_LIST]) { + /* special case for first capability */ + u16 status = load_le16(cfg + PCI_STATUS); + + status |= PCI_STATUS_CAP_LIST; + store_le16(cfg + PCI_STATUS, status); + + cfg[PCI_CAPABILITY_LIST] = newcap; + goto setupcap; + } + + while (cfg[cap + PCI_CAP_LIST_NEXT] != 0) + cap = cfg[cap + PCI_CAP_LIST_NEXT]; + + cfg[cap + PCI_CAP_LIST_NEXT] = newcap; + +setupcap: + cfg[newcap + PCI_CAP_LIST_ID] = id; + cfg[newcap + PCI_CAP_LIST_NEXT] = 0; + vctrl->pcicfg.end += size; + return newcap; +} + +static void nvmet_mdev_pci_setup_pm_cap(struct nvmet_mdev_vctrl *vctrl) +{ + u8 *cfg = vctrl->pcicfg.values; + u8 *cfgm = vctrl->pcicfg.wmask; + + u8 cap = nvmet_mdev_pci_allocate_cap(vctrl, PCI_CAP_ID_PM, + PCI_PM_SIZEOF); + + store_le16(cfg + cap + PCI_PM_PMC, 0x3); + store_le16(cfg + cap + PCI_PM_CTRL, PCI_PM_CTRL_NO_SOFT_RESET); + store_le16(cfgm + cap + PCI_PM_CTRL, 0x3); + vctrl->pcicfg.pmcap = cap; +} + +static void nvmet_mdev_pci_setup_msix_cap(struct nvmet_mdev_vctrl *vctrl) +{ + u8 *cfg = vctrl->pcicfg.values; + u8 *cfgm = vctrl->pcicfg.wmask; + u8 cap = nvmet_mdev_pci_allocate_cap(vctrl, PCI_CAP_ID_MSIX, + PCI_CAP_MSIX_SIZEOF); + + int MSIX_TBL_SIZE = roundup(MAX_VIRTUAL_IRQS * 16, PAGE_SIZE); + int MSIX_PBA_SIZE = roundup(DIV_ROUND_UP(MAX_VIRTUAL_IRQS, 8), + PAGE_SIZE); + + store_le16(cfg + cap + PCI_MSIX_FLAGS, MAX_VIRTUAL_IRQS - 1); + store_le16(cfgm + cap + PCI_MSIX_FLAGS, + PCI_MSIX_FLAGS_MASKALL | PCI_MSIX_FLAGS_ENABLE); + + store_le32(cfg + cap + PCI_MSIX_TABLE, 0x2); + store_le32(cfg + cap + PCI_MSIX_PBA, MSIX_TBL_SIZE | 0x2); + + nvmet_mdev_pci_setup_bar(vctrl, PCI_BASE_ADDRESS_2, + __roundup_pow_of_two(MSIX_TBL_SIZE + + MSIX_PBA_SIZE), NULL); + vctrl->pcicfg.msixcap = cap; +} + +static void nvmet_mdev_pci_setup_pcie_cap(struct nvmet_mdev_vctrl *vctrl) +{ + u8 *cfg = vctrl->pcicfg.values; + u8 cap = nvmet_mdev_pci_allocate_cap(vctrl, PCI_CAP_ID_EXP, + PCI_CAP_EXP_ENDPOINT_SIZEOF_V2); + + store_le16(cfg + cap + PCI_EXP_FLAGS, 0x02 | + (PCI_EXP_TYPE_ENDPOINT << 4)); + + store_le32(cfg + cap + PCI_EXP_DEVCAP, + PCI_EXP_DEVCAP_RBER | PCI_EXP_DEVCAP_FLR); + store_le32(cfg + cap + PCI_EXP_LNKCAP, + PCI_EXP_LNKCAP_SLS_8_0GB | (4 << 4) /*4x*/); + store_le16(cfg + cap + PCI_EXP_LNKSTA, + PCI_EXP_LNKSTA_CLS_8_0GB | (4 << 4) /*4x*/); + + store_le32(cfg + cap + PCI_EXP_LNKCAP2, PCI_EXP_LNKCAP2_SLS_8_0GB); + store_le16(cfg + cap + PCI_EXP_LNKCTL2, PCI_EXP_LNKCTL2_TLS_8_0GT); + vctrl->pcicfg.pciecap = cap; +} + +/* This is called on PCI config read/write */ +static int nvmet_mdev_pci_cfg_access(struct nvmet_mdev_vctrl *vctrl, u16 offset, + char *buf, u32 count, bool is_write) +{ + unsigned int i; + + mutex_lock(&vctrl->lock); + + if (!is_write) { + memcpy(buf, (vctrl->pcicfg.values + offset), count); + goto out; + } + + for (i = 0; i < count; i++) { + u8 address = offset + i; + u8 value = buf[i]; + u8 old_value = vctrl->pcicfg.values[address]; + u8 wmask = vctrl->pcicfg.wmask[address]; + u8 new_value = (value & wmask) | (old_value & ~wmask); + + /* D3/D0 power control */ + if (address == vctrl->pcicfg.pmcap + PCI_PM_CTRL) { + u8 state = new_value & 0x03; + + if (state != 0 && state != 3) + new_value = old_value; + + if (old_value != new_value) { + const char *s = state == 3 ? "D3" : "D0"; + + if (state == 3) + __nvmet_mdev_vctrl_reset(vctrl, true); + _DBG(vctrl, "PCI: going to %s\n", s); + } + } + + /* FLR reset */ + if (address == vctrl->pcicfg.pciecap + PCI_EXP_DEVCTL + 1) + if (value & 0x80) { + _DBG(vctrl, "PCI: FLR reset\n"); + __nvmet_mdev_vctrl_reset(vctrl, true); + } + vctrl->pcicfg.values[offset + i] = new_value; + } +out: + mutex_unlock(&vctrl->lock); + return count; +} + +/* setup pci configuration */ +int nvmet_mdev_pci_create(struct nvmet_mdev_vctrl *vctrl) +{ + u8 *cfg, *cfgm; + + vctrl->pcicfg.values = kzalloc(NVMET_MDEV_PCI_CFG_SIZE, GFP_KERNEL); + if (!vctrl->pcicfg.values) + return -ENOMEM; + + vctrl->pcicfg.wmask = kzalloc(NVMET_MDEV_PCI_CFG_SIZE, GFP_KERNEL); + if (!vctrl->pcicfg.wmask) { + kfree(vctrl->pcicfg.values); + return -ENOMEM; + } + + cfg = vctrl->pcicfg.values; + cfgm = vctrl->pcicfg.wmask; + + nvmet_mdev_vctrl_add_region(vctrl, VFIO_PCI_CONFIG_REGION_INDEX, + NVMET_MDEV_PCI_CFG_SIZE, + nvmet_mdev_pci_cfg_access); + + /* vendor information */ + store_le16(cfg + PCI_VENDOR_ID, NVME_MDEV_PCI_VENDOR_ID); + store_le16(cfg + PCI_DEVICE_ID, NVME_MDEV_PCI_DEVICE_ID); + + /* pci command register */ + store_le16(cfgm + PCI_COMMAND, + PCI_COMMAND_INTX_DISABLE | + PCI_COMMAND_MEMORY | + PCI_COMMAND_MASTER); + + /* pci status register */ + store_le16(cfg + PCI_STATUS, PCI_STATUS_CAP_LIST); + + /* subsystem information */ + store_le16(cfg + PCI_SUBSYSTEM_VENDOR_ID, NVME_MDEV_PCI_SUBVENDOR_ID); + store_le16(cfg + PCI_SUBSYSTEM_ID, NVME_MDEV_PCI_SUBDEVICE_ID); + store_le8(cfg + PCI_CLASS_REVISION, NVME_MDEV_PCI_REVISION); + + /* Programming Interface (NVM Express) */ + store_le8(cfg + PCI_CLASS_PROG, 0x02); + + /* + * Device class and subclass (Mass storage controller, Non-Volatile + * memory controller) + */ + store_le16(cfg + PCI_CLASS_DEVICE, 0x0108); + + /* dummy read/write */ + store_le8(cfgm + PCI_CACHE_LINE_SIZE, 0xFF); + + /* initial value */ + store_le8(cfg + PCI_CAPABILITY_LIST, 0); + vctrl->pcicfg.end = 0x40; + + nvmet_mdev_pci_setup_pm_cap(vctrl); + nvmet_mdev_pci_setup_msix_cap(vctrl); + nvmet_mdev_pci_setup_pcie_cap(vctrl); + + /* INTX IRQ number - info only for BIOS */ + store_le8(cfgm + PCI_INTERRUPT_LINE, 0xFF); + store_le8(cfg + PCI_INTERRUPT_PIN, 0x01); + + return 0; +} + +/* teardown pci configuration */ +void nvmet_mdev_pci_free(struct nvmet_mdev_vctrl *vctrl) +{ + kfree(vctrl->pcicfg.values); + kfree(vctrl->pcicfg.wmask); + vctrl->pcicfg.values = NULL; + vctrl->pcicfg.wmask = NULL; +} diff --git a/drivers/nvme/target/mdev-pci/priv.h b/drivers/nvme/target/mdev-pci/priv.h new file mode 100644 index 000000000000..9572a182ddc7 --- /dev/null +++ b/drivers/nvme/target/mdev-pci/priv.h @@ -0,0 +1,487 @@ +/* SPDX-License-Identifier: GPL-2.0+ */ +/* + * Driver private data structures and helper macros + * Copyright (c) 2019 - Maxim Levitsky + */ + +#ifndef _MDEV_NVME_PRIV_H +#define _MDEV_NVME_PRIV_H + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "../../host/nvme.h" +#include "../nvmet.h" + +#define NVME_MDEV_NVME_VER NVME_VS(0x01, 0x03, 0x00) + +#define NVME_MDEV_PCI_VENDOR_ID PCI_VENDOR_ID_REDHAT_QUMRANET +#define NVME_MDEV_PCI_DEVICE_ID 0x1234 +#define NVME_MDEV_PCI_SUBVENDOR_ID PCI_SUBVENDOR_ID_REDHAT_QUMRANET +#define NVME_MDEV_PCI_SUBDEVICE_ID 0 +#define NVME_MDEV_PCI_REVISION 0x0 + +#define DB_STRIDE_SHIFT 4 /*4 = 1 cacheline */ +#define NVMET_MDEV_MAX_NR_QUEUES 16 +#define MAX_VIRTUAL_IRQS 128 + +struct page_map { + void *kmap; + struct page *page; + dma_addr_t iova; +}; + +struct user_prplist { + /* used by user data iterator */ + struct page_map page; + /* index of current entry */ + unsigned int index; +}; + +struct nvmet_ext_data_iter { + /* private */ + struct nvmet_mdev_viommu *viommu; + union { + const union nvme_data_ptr *dptr; + struct user_prplist uprp; + }; + + /* user interface */ + /* number of data pages, yet to be covered */ + u64 count; + /* iterator physical address value */ + phys_addr_t physical; + + struct list_head *mem_map_list; + + /* moves iterator to the next item */ + int (*next)(struct nvmet_ext_data_iter *data_iter); + /* + * if != NULL, user should call this when it's done with data + * pointed by the iterator + */ + void (*release)(struct nvmet_ext_data_iter *data_iter); +}; + +/* virtual submission queue */ +struct nvmet_mdev_vsq { + struct nvmet_sq nvmet_sq; + u16 qid; + u16 size; + /* next item to read */ + u16 head; + + /* the queue */ + struct nvme_command *data; + unsigned int data_size; + dma_addr_t iova; + + struct nvmet_mdev_vcq *vcq; + struct nvmet_mdev_vctrl *vctrl; + + struct nvmet_mdev_req *reqs; +}; + +/* virtual completion queue */ +struct nvmet_mdev_vcq { + struct nvmet_cq nvmet_cq; + /* basic queue settings */ + u16 qid; + u16 size; + u16 head; + u16 tail; + u16 phase; + + volatile struct nvme_completion *data; + unsigned int data_size; + dma_addr_t iova; + + struct llist_head mreq_list; + struct nvmet_mdev_vctrl *vctrl; + + /* IRQ settings */ + int irq /* -1 if disabled */; +}; + +struct nvmet_mdev_req { + struct nvmet_req req; + struct nvme_completion cqe; + struct sg_table sgt; + struct nvmet_ext_data_iter data_iter; + struct list_head mem_map_list; + + struct nvmet_mdev_vcq *vcq; + struct llist_node cq_node; +}; + +/* Virtual IOMMU */ +struct nvmet_mdev_viommu { + struct vfio_device *vfio_dev; + + /* dma/prp bookkeeping */ + struct rb_root_cached maps_tree; + struct list_head mem_map_list; + struct nvmet_mdev_vctrl *vctrl; +}; + +struct doorbell { + volatile __le32 sqt; + u8 rsvd1[(4 << DB_STRIDE_SHIFT) - sizeof(__le32)]; + volatile __le32 cqh; + u8 rsvd2[(4 << DB_STRIDE_SHIFT) - sizeof(__le32)]; +}; + +/* MMIO state */ +struct nvmet_mdev_user_ctrl_mmio { + u32 cc; /* controller configuration */ + u32 csts; /* controller status */ + u64 cap /* controller capabilities */; + + /* admin queue location & size */ + u32 aqa; + u32 asql; + u32 asqh; + u32 acql; + u32 acqh; + + bool shadow_db_supported; + bool shadow_db_en; + + /* Regular doorbells */ + struct page *dbs_page; + struct page *fake_eidx_page; + void *db_page_kmap; + void *fake_eidx_kmap; + + /* Shadow doorbells */ + dma_addr_t sdb_iova; + struct page_map sdb_map; + dma_addr_t eidx_iova; + struct page_map seidx_map; + + /* Current doorbell mappings */ + volatile struct doorbell *dbs; + volatile struct doorbell *eidxs; +}; + +/* pci configuration space of the device */ +#define NVMET_MDEV_PCI_CFG_SIZE 4096 +struct nvmet_mdev_pci_cfg_space { + u8 *values; + u8 *wmask; + + u8 pmcap; + u8 pciecap; + u8 msixcap; + u8 end; +}; + +/* IRQ state of the controller */ +struct nvmet_mdev_user_irq { + struct eventfd_ctx *trigger; + /* IRQ coalescing */ + bool irq_coalesc_en; + ktime_t irq_time; + unsigned int irq_pending_cnt; +}; + +enum nvmet_mdev_irq_mode { + NVME_MDEV_IMODE_NONE, + NVME_MDEV_IMODE_INTX, + NVME_MDEV_IMODE_MSIX, +}; + +struct nvmet_mdev_user_irqs { + /* one of VFIO_PCI_{INTX|MSI|MSIX}_IRQ_INDEX */ + enum nvmet_mdev_irq_mode mode; + + struct nvmet_mdev_user_irq vecs[MAX_VIRTUAL_IRQS]; + /* user interrupt coalescing settings */ + u8 irq_coalesc_max; + unsigned int irq_coalesc_time_us; + /* device removal trigger */ + struct eventfd_ctx *request_trigger; +}; + +/* IO region abstraction (BARs, the PCI config space */ +struct nvmet_mdev_vctrl; +typedef int (*region_access_fn)(struct nvmet_mdev_vctrl *vctrl, u16 offset, + char *buf, u32 size, bool is_write); + +struct nvmet_mdev_io_region { + unsigned int size; + region_access_fn rw; + + /* + * IF != NULL, the mmap_area_start/size specify the mmaped window + * of this region + */ + const struct vm_operations_struct *mmap_ops; + unsigned int mmap_area_start; + unsigned int mmap_area_size; +}; + +struct nvmet_mdev_type { + struct mdev_type type; + char *name; +}; + +struct nvmet_mdev_port { + struct mdev_parent parent; + struct device device; + struct nvmet_port *nvmet_port; + struct mutex mutex; + + int ctrl_count; + int type_count; + struct nvmet_mdev_type *types; + struct mdev_type **mdev_types; +}; + +#define vfio_dev_to_nvmet_mdev_vctrl(vfio_dev) \ + container_of(vfio_dev, struct nvmet_mdev_vctrl, vfio_dev) + +/* Virtual NVME controller state */ +struct nvmet_mdev_vctrl { + struct vfio_device vfio_dev; + struct kref ref; + struct mutex lock; + + struct mdev_device *mdev; + struct nvmet_ctrl *nvmet_ctrl; + + /* the IO thread */ + struct task_struct *iothread; + bool iothread_parked; + bool io_idle; + ktime_t now; + int expected_responses; + int poll_timeout_ms; + + struct nvmet_mdev_io_region regions[VFIO_PCI_NUM_REGIONS]; + + /* virtual controller state */ + struct nvmet_mdev_user_ctrl_mmio mmio; + struct nvmet_mdev_pci_cfg_space pcicfg; + struct nvmet_mdev_user_irqs irqs; + + /* emulated submission queues */ + struct nvmet_mdev_vsq vsqs[NVMET_MDEV_MAX_NR_QUEUES]; + unsigned long vsq_en[BITS_TO_LONGS(NVMET_MDEV_MAX_NR_QUEUES)]; + + /* emulated completion queues */ + unsigned long vcq_en[BITS_TO_LONGS(NVMET_MDEV_MAX_NR_QUEUES)]; + struct nvmet_mdev_vcq vcqs[NVMET_MDEV_MAX_NR_QUEUES]; + + /* Interface to access user memory */ + struct notifier_block vfio_map_notifier; + struct notifier_block vfio_unmap_notifier; + struct nvmet_mdev_viommu viommu; + + /* Settings */ + unsigned int arb_burst_shift; + u8 worload_hint; + unsigned int iothread_cpu; +}; + +/* vctrl.c */ +int nvmet_mdev_vctrl_create(struct nvmet_mdev_vctrl *vctrl, + struct mdev_device *mdev); +void nvmet_mdev_vctrl_destroy(struct nvmet_mdev_vctrl *vctrl); +int nvmet_mdev_vctrl_open(struct vfio_device *vfio_dev); +void nvmet_mdev_vctrl_release(struct vfio_device *vfio_dev); +bool nvmet_mdev_vctrl_enable(struct nvmet_mdev_vctrl *vctrl, dma_addr_t cqiova, + dma_addr_t sqiova, u32 sizes); +void nvmet_mdev_vctrl_disable(struct nvmet_mdev_vctrl *vctrl); +void nvmet_mdev_vctrl_reset(struct nvmet_mdev_vctrl *vctrl); +void __nvmet_mdev_vctrl_reset(struct nvmet_mdev_vctrl *vctrl, bool pci_reset); +void nvmet_mdev_vctrl_add_region(struct nvmet_mdev_vctrl *vctrl, + unsigned int index, unsigned int size, + region_access_fn access_fn); +void nvmet_mdev_vctrl_region_set_mmap(struct nvmet_mdev_vctrl *vctrl, + unsigned int index, unsigned int offset, + unsigned int size, + const struct vm_operations_struct *ops); +void nvmet_mdev_vctrl_region_disable_mmap(struct nvmet_mdev_vctrl *vctrl, + unsigned int index); +bool nvmet_mdev_vctrl_is_dead(struct nvmet_mdev_vctrl *vctrl); +int nvmet_mdev_vctrl_viommu_map(struct nvmet_mdev_vctrl *vctrl, u32 flags, + dma_addr_t iova, u64 size); +int nvmet_mdev_vctrl_viommu_unmap(struct nvmet_mdev_vctrl *vctrl, + dma_addr_t iova, u64 size); + +/* io.c */ +int nvmet_mdev_io_create(struct nvmet_mdev_vctrl *vctrl); +void nvmet_mdev_io_free(struct nvmet_mdev_vctrl *vctrl); +void nvmet_mdev_io_resume(struct nvmet_mdev_vctrl *vctrl); +bool nvmet_mdev_io_pause(struct nvmet_mdev_vctrl *vctrl); +void nvmet_mdev_assert_io_not_running(struct nvmet_mdev_vctrl *vctrl); +bool nvmet_mdev_process_responses(struct nvmet_mdev_vctrl *vctrl, + struct nvmet_mdev_vcq *vcq); + +/* mmio.c */ +int nvmet_mdev_mmio_create(struct nvmet_mdev_vctrl *vctrl); +void nvmet_mdev_mmio_open(struct nvmet_mdev_vctrl *vctrl); +void nvmet_mdev_mmio_reset(struct nvmet_mdev_vctrl *vctrl, bool pci_reset); +void nvmet_mdev_mmio_free(struct nvmet_mdev_vctrl *vctrl); + +int nvmet_mdev_mmio_enable_dbs(struct nvmet_mdev_vctrl *vctrl); +int nvmet_mdev_mmio_enable_dbs_shadow(struct nvmet_mdev_vctrl *vctrl, + dma_addr_t sdb_iova, + dma_addr_t eidx_iova); + +void nvmet_mdev_mmio_viommu_update(struct nvmet_mdev_vctrl *vctrl); +void nvmet_mdev_mmio_disable_dbs(struct nvmet_mdev_vctrl *vctrl); +bool nvmet_mdev_mmio_db_check(struct nvmet_mdev_vctrl *vctrl, u16 qid, u16 size, + u16 db); + +/* pci.c */ +int nvmet_mdev_pci_create(struct nvmet_mdev_vctrl *vctrl); +void nvmet_mdev_pci_free(struct nvmet_mdev_vctrl *vctrl); +void nvmet_mdev_pci_setup_bar(struct nvmet_mdev_vctrl *vctrl, u8 bar, + unsigned int size, region_access_fn access_fn); + +/* irq.c */ +void nvmet_mdev_irqs_setup(struct nvmet_mdev_vctrl *vctrl); +void nvmet_mdev_irqs_reset(struct nvmet_mdev_vctrl *vctrl); +int nvmet_mdev_irqs_enable(struct nvmet_mdev_vctrl *vctrl, + enum nvmet_mdev_irq_mode mode); +void nvmet_mdev_irqs_disable(struct nvmet_mdev_vctrl *vctrl, + enum nvmet_mdev_irq_mode mode); +int nvmet_mdev_irqs_set_triggers(struct nvmet_mdev_vctrl *vctrl, + int start, int count, int32_t *fds); +int nvmet_mdev_irqs_set_unplug_trigger(struct nvmet_mdev_vctrl *vctrl, + int32_t fd); +void nvmet_mdev_irq_raise_unplug_event(struct nvmet_mdev_vctrl *vctrl); +void nvmet_mdev_irq_raise(struct nvmet_mdev_vctrl *vctrl, unsigned int index); +void nvmet_mdev_irq_trigger(struct nvmet_mdev_vctrl *vctrl, unsigned int index); +void nvmet_mdev_irq_cond_trigger(struct nvmet_mdev_vctrl *vctrl, + unsigned int index, ktime_t now); +void nvmet_mdev_irq_clear(struct nvmet_mdev_vctrl *vctrl, unsigned int index, + ktime_t now); + +/* vcq.c */ +int nvmet_mdev_vcq_init(struct nvmet_mdev_vctrl *vctrl, u16 qid, + dma_addr_t iova, u16 size, int irq); +int nvmet_mdev_vcq_viommu_update(struct nvmet_mdev_viommu *viommu, + struct nvmet_mdev_vcq *q); +void nvmet_mdev_vcq_delete(struct nvmet_mdev_vctrl *vctrl, u16 qid); +void nvmet_mdev_vcq_process(struct nvmet_mdev_vctrl *vctrl, + struct nvmet_mdev_vcq *q, bool trigger_irqs, + ktime_t now); +bool nvmet_mdev_vcq_flush(struct nvmet_mdev_vctrl *vctrl, + struct nvmet_mdev_vcq *q, ktime_t now); +void nvmet_mdev_vcq_write_cqe(struct nvmet_mdev_vctrl *vctrl, + struct nvmet_mdev_vcq *q, + struct nvme_completion *cqe); + +/* vsq.c */ +int nvmet_mdev_vsq_init(struct nvmet_mdev_vctrl *vctrl, u16 qid, + dma_addr_t iova, u16 size, u16 cqid); +int nvmet_mdev_vsq_viommu_update(struct nvmet_mdev_viommu *viommu, + struct nvmet_mdev_vsq *q); +void nvmet_mdev_vsq_delete(struct nvmet_mdev_vctrl *vctrl, u16 qid); +struct nvme_command *nvmet_mdev_vsq_get_cmd(struct nvmet_mdev_vctrl *vctrl, + struct nvmet_mdev_vsq *q, + u16 *index); +bool nvmet_mdev_vsq_suspend_io(struct nvmet_mdev_vsq *q); + +/* udata.c */ +void nvmet_mdev_udata_iter_setup(struct nvmet_mdev_viommu *viommu, + struct nvmet_ext_data_iter *iter, + struct list_head *maps_list); +int nvmet_mdev_udata_iter_set_dptr(struct nvmet_ext_data_iter *it, + const union nvme_data_ptr *dptr, u64 size); +void *nvmet_mdev_udata_update_queue_vmap(struct nvmet_mdev_viommu *viommu, + dma_addr_t iova, void *data, + unsigned int data_size); +void nvmet_mdev_udata_queue_vunmap(struct nvmet_mdev_viommu *viommu, + dma_addr_t iova, void *data, + unsigned int data_size); + +/* viommu.c */ +void nvmet_mdev_viommu_init(struct nvmet_mdev_viommu *viommu, + struct vfio_device *vfio_dev); +int nvmet_mdev_viommu_add(struct nvmet_mdev_viommu *viommu, u32 flags, + dma_addr_t iova, u64 size, + struct list_head *maps_list); +int nvmet_mdev_viommu_remove(struct nvmet_mdev_viommu *viommu, + dma_addr_t iova, u64 size); +int nvmet_mdev_viommu_remove_list(struct nvmet_mdev_viommu *viommu, + struct list_head *remove_list); +int nvmet_mdev_viommu_translate(struct nvmet_mdev_viommu *viommu, + dma_addr_t iova, dma_addr_t *physical); +int nvmet_mdev_viommu_create_kmap(struct nvmet_mdev_viommu *viommu, + dma_addr_t iova, struct page_map *page); +void nvmet_mdev_viommu_free_kmap(struct nvmet_mdev_viommu *viommu, + struct page_map *page); +void nvmet_mdev_viommu_update_kmap(struct nvmet_mdev_viommu *viommu, + struct page_map *page); +void nvmet_mdev_viommu_reset(struct nvmet_mdev_viommu *viommu); + +/* instance.c */ +int nvmet_mdev_register_port(struct nvmet_mdev_port *mport); +void nvmet_mdev_unregister_port(struct nvmet_mdev_port *mport); +void nvmet_mdev_remove_ctrl(struct nvmet_mdev_vctrl *vctrl); + +/* some utilities*/ + +#define store_le32(address, value) (*((__le32 *)(address)) = cpu_to_le32(value)) +#define store_le16(address, value) (*((__le16 *)(address)) = cpu_to_le16(value)) +#define store_le8(address, value) (*((u8 *)(address)) = (value)) + +#define load_le16(address) le16_to_cpu(*(__le16 *)(address)) + +#define DNR(e) ((e) | NVME_STATUS_DNR) + +#define PAGE_ADDRESS(address) ((address) & PAGE_MASK) + +#define _DBG(vctrl, fmt, ...) \ + dev_dbg(vctrl->vfio_dev.dev, fmt, ##__VA_ARGS__) + +#define _INFO(vctrl, fmt, ...) \ + dev_info(vctrl->vfio_dev.dev, fmt, ##__VA_ARGS__) + +#define _WARN(vctrl, fmt, ...) \ + dev_warn(vctrl->vfio_dev.dev, fmt, ##__VA_ARGS__) + +/* Rough translation of internal errors to the NVME errors */ +static inline int nvmet_mdev_translate_error(int error) +{ + /* nvme status, including no error (NVME_SC_SUCCESS) */ + if (error >= 0) + return error; + + switch (error) { + case -ENOMEM: + /* no memory - truly an internal error */ + return NVME_SC_INTERNAL; + case -ENOSPC: + /* + * Happens when user sends to large PRP list User shoudn't do + * this since the maximum transfer size is specified in the + * controller caps + */ + return DNR(NVME_SC_DATA_XFER_ERROR); + case -EFAULT: + /* Bad memory pointers in the prp lists */ + return DNR(NVME_SC_DATA_XFER_ERROR); + case -EINVAL: + /* Bad prp offsets in the prp lists/command */ + return DNR(NVME_SC_PRP_INVALID_OFFSET); + default: + /* Shouldn't happen */ + WARN_ON_ONCE(true); + return NVME_SC_INTERNAL; + } +} + +extern const struct nvmet_fabrics_ops nvmet_mdev_ops; + +#endif // _MDEV_NVME_H diff --git a/drivers/nvme/target/mdev-pci/target.c b/drivers/nvme/target/mdev-pci/target.c new file mode 100644 index 000000000000..1b688544db1e --- /dev/null +++ b/drivers/nvme/target/mdev-pci/target.c @@ -0,0 +1,284 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * NVMe target callouts + * Copyright (c) 2019 - Maxim Levitsky + * Copyright (C) 2025 Oracle Corporation + */ +#include +#include +#include +#include +#include +#include "../nvmet.h" +#include "../../host/nvme.h" +#include "../../host/fabrics.h" +#include "priv.h" + +static void nvmet_mdev_delete_ctrl(struct nvmet_ctrl *ctrl) +{ + struct nvmet_mdev_port *mport = ctrl->port->priv; + + mutex_lock(&mport->mutex); + nvmet_mdev_remove_ctrl(ctrl->drvdata); + mutex_unlock(&mport->mutex); +} + +static void nvmet_mdev_remove_port(struct nvmet_port *port) +{ + nvmet_mdev_unregister_port(port->priv); +} + +static int nvmet_mdev_count_ctrls(void *priv, struct nvmet_port *port, + struct nvmet_ctrl *ctrl) +{ + int *count = priv; + + (*count)++; + return 0; +} + +static int nvmet_mdev_add_port(struct nvmet_port *port) +{ + struct nvmet_mdev_port *mport; + int count = 0; + int ret; + + ret = nvmet_for_each_static_ctrl(port, nvmet_mdev_ops.type, + nvmet_mdev_count_ctrls, &count); + if (ret) + return ret; + + if (!count) { + pr_err("Controllers must be added and enabled before enabling port.\n"); + return -ENODEV; + } + + mport = kzalloc(sizeof(*mport), GFP_KERNEL); + if (!mport) + return -ENOMEM; + + mutex_init(&mport->mutex); + port->priv = mport; + mport->nvmet_port = port; + mport->ctrl_count = count; + + return nvmet_mdev_register_port(mport); +} + +static u16 nvmet_mdev_adm_create_cq(struct nvmet_ctrl *ctrl, u16 cqid, + u16 cq_flags, u16 qsize, u64 prp1, u16 irq) +{ + struct nvmet_mdev_vctrl *vctrl = ctrl->drvdata; + u16 ret; + + mutex_lock(&vctrl->lock); + if (cqid >= NVMET_MDEV_MAX_NR_QUEUES || test_bit(cqid, vctrl->vcq_en)) { + ret = DNR(NVME_SC_QID_INVALID); + goto unlock; + } + + if (!(cq_flags & NVME_QUEUE_PHYS_CONTIG)) { + ret = DNR(NVME_SC_INVALID_QUEUE); + goto unlock; + } + + if (cq_flags & NVME_CQ_IRQ_ENABLED) { + if (irq >= MAX_VIRTUAL_IRQS) { + ret = DNR(NVME_SC_INVALID_VECTOR); + goto unlock; + } + } + + ret = nvmet_mdev_vcq_init(vctrl, cqid, prp1, qsize + 1, irq); +unlock: + mutex_unlock(&vctrl->lock); + return ret; +} + +static u16 nvmet_mdev_adm_delete_cq(struct nvmet_ctrl *ctrl, u16 cqid) +{ + struct nvmet_mdev_vctrl *vctrl = ctrl->drvdata; + u16 ret = NVME_SC_SUCCESS; + + mutex_lock(&vctrl->lock); + if (cqid >= NVMET_MDEV_MAX_NR_QUEUES || + !test_bit(cqid, vctrl->vcq_en)) { + ret = DNR(NVME_SC_QID_INVALID); + goto unlock; + } + + nvmet_mdev_vcq_delete(vctrl, cqid); +unlock: + mutex_unlock(&vctrl->lock); + return ret; +} + +static u16 nvmet_mdev_adm_create_sq(struct nvmet_ctrl *ctrl, u16 sqid, + u16 sq_flags, u16 qsize, u64 prp1) +{ + struct nvmet_mdev_vctrl *vctrl = ctrl->drvdata; + u16 ret; + + mutex_lock(&vctrl->lock); + if (sqid >= NVMET_MDEV_MAX_NR_QUEUES || test_bit(sqid, vctrl->vsq_en)) { + ret = DNR(NVME_SC_QID_INVALID); + goto unlock; + } + + /* + * sqid and cqid are checked they are equal by nvmet before calling + * this + */ + if (!test_bit(sqid, vctrl->vcq_en)) { + ret = DNR(NVME_SC_CQ_INVALID); + goto unlock; + } + + if (!(sq_flags & NVME_QUEUE_PHYS_CONTIG)) { + ret = DNR(NVME_SC_INVALID_QUEUE); + goto unlock; + } + + ret = nvmet_mdev_vsq_init(vctrl, sqid, prp1, qsize + 1, sqid); +unlock: + mutex_unlock(&vctrl->lock); + return ret; +} + +static u16 nvmet_mdev_adm_delete_sq(struct nvmet_ctrl *ctrl, u16 sqid) +{ + struct nvmet_mdev_vctrl *vctrl = ctrl->drvdata; + u16 ret = NVME_SC_SUCCESS; + + mutex_lock(&vctrl->lock); + if (sqid >= NVMET_MDEV_MAX_NR_QUEUES || + !test_bit(sqid, vctrl->vsq_en)) { + ret = DNR(NVME_SC_QID_INVALID); + goto unlock; + } + + nvmet_mdev_vsq_delete(vctrl, sqid); +unlock: + mutex_unlock(&vctrl->lock); + return ret; +} + +static u16 nvmet_mdev_adm_get_features(const struct nvmet_ctrl *ctrl, u8 feat, + void *feat_data) +{ + struct nvmet_mdev_vctrl *vctrl = ctrl->drvdata; + struct nvmet_feat_arbitration *arb; + struct nvmet_feat_irq_coalesce *irqc; + struct nvmet_feat_irq_config *irqcfg; + + switch (feat) { + case NVME_FEAT_ARBITRATION: + arb = feat_data; + + arb->ab = vctrl->arb_burst_shift; + break; + case NVME_FEAT_IRQ_COALESCE: + irqc = feat_data; + + irqc->thr = vctrl->irqs.irq_coalesc_max - 1; + + irqc->time = vctrl->irqs.irq_coalesc_time_us; + do_div(irqc->time, 100); + break; + case NVME_FEAT_IRQ_CONFIG: + irqcfg = feat_data; + + if (irqcfg->iv >= MAX_VIRTUAL_IRQS) + return DNR(NVME_SC_INVALID_FIELD); + + irqcfg->cd = vctrl->irqs.vecs[irqcfg->iv].irq_coalesc_en; + break; + default: + return DNR(NVME_SC_INVALID_FIELD); + } + + return NVME_SC_SUCCESS; +} + +static u16 nvmet_mdev_adm_set_features(const struct nvmet_ctrl *ctrl, u8 feat, + void *feat_data) +{ + struct nvmet_mdev_vctrl *vctrl = ctrl->drvdata; + struct nvmet_feat_arbitration *arb; + struct nvmet_feat_irq_coalesce *irqc; + struct nvmet_feat_irq_config *irqcfg; + + switch (feat) { + case NVME_FEAT_ARBITRATION: + arb = feat_data; + + vctrl->arb_burst_shift = arb->ab; + break; + case NVME_FEAT_IRQ_COALESCE: + irqc = feat_data; + + vctrl->irqs.irq_coalesc_max = irqc->thr + 1; + vctrl->irqs.irq_coalesc_time_us = irqc->time * 100; + break; + case NVME_FEAT_IRQ_CONFIG: + irqcfg = feat_data; + + if (irqcfg->iv >= MAX_VIRTUAL_IRQS) + return DNR(NVME_SC_INVALID_FIELD); + + vctrl->irqs.vecs[irqcfg->iv].irq_coalesc_en = irqcfg->cd != 0; + break; + default: + return DNR(NVME_SC_INVALID_FIELD); + } + + return NVME_SC_SUCCESS; +} + +static u16 nvmet_mdev_adm_set_dbbuf(struct nvmet_ctrl *ctrl, u64 prp1, u64 prp2) +{ + struct nvmet_mdev_vctrl *vctrl = ctrl->drvdata; + int ret; + + if (!vctrl->mmio.shadow_db_supported) + return DNR(NVME_SC_INVALID_OPCODE); + + if (vctrl->mmio.shadow_db_en) + return DNR(NVME_SC_INVALID_FIELD); + + if ((offset_in_page(prp1) != 0) || (offset_in_page(prp2) != 0)) + return DNR(NVME_SC_INVALID_FIELD); + + ret = nvmet_mdev_mmio_enable_dbs_shadow(vctrl, prp1, prp2); + return nvmet_mdev_translate_error(ret); +} + +static void nvmet_mdev_queue_response(struct nvmet_req *req) +{ + struct nvmet_mdev_req *mreq = container_of(req, struct nvmet_mdev_req, + req); + + llist_add(&mreq->cq_node, &mreq->vcq->mreq_list); +} + +const struct nvmet_fabrics_ops nvmet_mdev_ops = { + .owner = THIS_MODULE, + .flags = NVMF_SGLS_NOT_SUPP | NVMF_STATIC_CTRL, + .type = NVMF_TRTYPE_MDEV_PCI, + .delete_ctrl = nvmet_mdev_delete_ctrl, + .add_port = nvmet_mdev_add_port, + .remove_port = nvmet_mdev_remove_port, + .create_cq = nvmet_mdev_adm_create_cq, + .delete_cq = nvmet_mdev_adm_delete_cq, + .create_sq = nvmet_mdev_adm_create_sq, + .delete_sq = nvmet_mdev_adm_delete_sq, + .set_feature = nvmet_mdev_adm_set_features, + .get_feature = nvmet_mdev_adm_get_features, + .set_dbbuf = nvmet_mdev_adm_set_dbbuf, + .queue_response = nvmet_mdev_queue_response, +}; + +MODULE_AUTHOR("Maxim Levitsky , " + "Mike Christie "); +MODULE_LICENSE("GPL"); +MODULE_ALIAS("nvmet-transport-253"); /* 253 == NVMF_TRTYPE_MDEV_PCI */ diff --git a/drivers/nvme/target/mdev-pci/udata.c b/drivers/nvme/target/mdev-pci/udata.c new file mode 100644 index 000000000000..9fa9f63e9d23 --- /dev/null +++ b/drivers/nvme/target/mdev-pci/udata.c @@ -0,0 +1,304 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * User (guest) data access routines + * Implementation of PRP iterator in user memory + * Copyright (c) 2019 - Maxim Levitsky + */ +#include +#include +#include +#include +#include +#include +#include +#include "priv.h" + +#define MAX_PRP ((PAGE_SIZE / sizeof(__le64)) - 1) + +/* Setup up a new PRP iterator */ +void nvmet_mdev_udata_iter_setup(struct nvmet_mdev_viommu *viommu, + struct nvmet_ext_data_iter *iter, + struct list_head *mem_map_list) +{ + memset(iter, 0, sizeof(*iter)); + iter->viommu = viommu; + iter->mem_map_list = mem_map_list; +} + +/* Load a new prp list into the iterator. Internal */ +static int nvmet_mdev_udata_iter_load_prplist(struct nvmet_ext_data_iter *iter, + dma_addr_t iova) +{ + dma_addr_t data_iova; + int ret; + __le64 *map; + + ret = nvmet_mdev_viommu_add(iter->viommu, + VFIO_DMA_MAP_FLAG_READ | + VFIO_DMA_MAP_FLAG_WRITE, iova, PAGE_SIZE, + iter->mem_map_list); + if (ret) + return ret; + + /* map the prp list */ + ret = nvmet_mdev_viommu_create_kmap(iter->viommu, PAGE_ADDRESS(iova), + &iter->uprp.page); + if (ret) + return ret; + + iter->uprp.index = offset_in_page(iova) / (sizeof(__le64)); + + /* read its first entry and check its alignment */ + map = iter->uprp.page.kmap; + data_iova = le64_to_cpu(map[iter->uprp.index]); + + if (offset_in_page(data_iova) != 0) { + nvmet_mdev_viommu_free_kmap(iter->viommu, &iter->uprp.page); + return -EINVAL; + } + + ret = nvmet_mdev_viommu_add(iter->viommu, + VFIO_DMA_MAP_FLAG_READ | + VFIO_DMA_MAP_FLAG_WRITE, data_iova, + PAGE_SIZE, iter->mem_map_list); + if (ret) + return ret; + + /* translate the entry to complete the setup */ + ret = nvmet_mdev_viommu_translate(iter->viommu, data_iova, + &iter->physical); + if (ret) + nvmet_mdev_viommu_free_kmap(iter->viommu, &iter->uprp.page); + + return ret; +} + +/* ->next function when iterator points to prp list */ +static int nvmet_mdev_udata_iter_next_prplist(struct nvmet_ext_data_iter *iter) +{ + dma_addr_t iova; + int ret; + __le64 *map = iter->uprp.page.kmap; + + if (WARN_ON(iter->count <= 0)) + return 0; + + if (--iter->count == 0) { + nvmet_mdev_viommu_free_kmap(iter->viommu, &iter->uprp.page); + return 0; + } + + iter->uprp.index++; + + if (iter->uprp.index < MAX_PRP || iter->count == 1) { + /* + * advance over next pointer in current prp list these + * pointers must be page aligned + */ + iova = le64_to_cpu(map[iter->uprp.index]); + if (offset_in_page(iova) != 0) + return -EINVAL; + + ret = nvmet_mdev_viommu_add(iter->viommu, + VFIO_DMA_MAP_FLAG_READ | + VFIO_DMA_MAP_FLAG_WRITE, iova, + PAGE_SIZE, iter->mem_map_list); + if (ret) + return ret; + + ret = nvmet_mdev_viommu_translate(iter->viommu, iova, + &iter->physical); + if (ret) + nvmet_mdev_viommu_free_kmap(iter->viommu, + &iter->uprp.page); + return ret; + } + + /* switch to next prp list. it must be page aligned as well */ + iova = le64_to_cpu(map[MAX_PRP]); + + if (offset_in_page(iova) != 0) + return -EINVAL; + + nvmet_mdev_viommu_free_kmap(iter->viommu, &iter->uprp.page); + return nvmet_mdev_udata_iter_load_prplist(iter, iova); +} + +/* ->next function when iterator points to user data pointer */ +static int nvmet_mdev_udata_iter_next_dptr(struct nvmet_ext_data_iter *iter) +{ + dma_addr_t iova; + int ret; + + if (WARN_ON(iter->count <= 0)) + return 0; + + if (--iter->count == 0) + return 0; + + /* + * we will be called only once to deal with the second + * pointer in the data pointer + */ + iova = le64_to_cpu(iter->dptr->prp2); + + if (iter->count == 1) { + /* + * only need to read one more entry, meaning the 2nd entry of + * the dptr. It must be page aligned + */ + if (offset_in_page(iova) != 0) + return -EINVAL; + + /* + * Size may be less than a page but it doesn't matter to + * the viommu as we have to get the entire page either way. + */ + ret = nvmet_mdev_viommu_add(iter->viommu, + VFIO_DMA_MAP_FLAG_READ | + VFIO_DMA_MAP_FLAG_WRITE, iova, + PAGE_SIZE, iter->mem_map_list); + if (ret) + return ret; + + return nvmet_mdev_viommu_translate(iter->viommu, iova, + &iter->physical); + } else { + /* + * Second dptr entry is prp pointer, and it might not + * be page aligned (but QWORD aligned at least) + */ + if (iova & 0x7ULL) + return -EINVAL; + iter->next = nvmet_mdev_udata_iter_next_prplist; + return nvmet_mdev_udata_iter_load_prplist(iter, iova); + } +} + +static void nvmet_mdev_udata_iter_release(struct nvmet_ext_data_iter *iter) +{ + nvmet_mdev_viommu_free_kmap(iter->viommu, &iter->uprp.page); + nvmet_mdev_viommu_remove_list(iter->viommu, iter->mem_map_list); +} + +/* Set prp list iterator to point to data pointer found in NVME command */ +int nvmet_mdev_udata_iter_set_dptr(struct nvmet_ext_data_iter *iter, + const union nvme_data_ptr *dptr, u64 size) +{ + int ret; + u64 prp1 = le64_to_cpu(dptr->prp1); + dma_addr_t iova = PAGE_ADDRESS(prp1); + unsigned int page_offset = offset_in_page(prp1); + + /* first dptr pointer must be at least DWORD aligned */ + if (page_offset & 0x3) + return -EINVAL; + + ret = nvmet_mdev_viommu_add(iter->viommu, + VFIO_DMA_MAP_FLAG_READ | + VFIO_DMA_MAP_FLAG_WRITE, iova, size, + iter->mem_map_list); + if (ret) + return ret; + + iter->dptr = dptr; + iter->next = nvmet_mdev_udata_iter_next_dptr; + iter->release = nvmet_mdev_udata_iter_release; + iter->count = DIV_ROUND_UP_ULL(size + page_offset, PAGE_SIZE); + + ret = nvmet_mdev_viommu_translate(iter->viommu, iova, &iter->physical); + if (ret) + goto release; + + iter->physical += page_offset; + return 0; + +release: + nvmet_mdev_udata_iter_release(iter); + return ret; +} + +/* Map an SQ/CQ queue (contiguous in guest physical memory) */ +static int +nvmet_mdev_queue_getpages_contiguous(struct nvmet_mdev_viommu *viommu, + dma_addr_t iova, struct page **pages, + unsigned int npages) +{ + dma_addr_t curr_iova = iova; + phys_addr_t physical; + unsigned int i; + int ret; + + for (i = 0 ; i < npages; i++) { + ret = nvmet_mdev_viommu_add(viommu, + VFIO_DMA_MAP_FLAG_READ | + VFIO_DMA_MAP_FLAG_WRITE, + curr_iova, PAGE_SIZE, + &viommu->mem_map_list); + if (ret) + goto remove; + + ret = nvmet_mdev_viommu_translate(viommu, curr_iova, &physical); + if (ret) + goto remove; + + pages[i] = pfn_to_page(PHYS_PFN(physical)); + curr_iova += PAGE_SIZE; + } + return 0; + +remove: + nvmet_mdev_viommu_remove(viommu, iova, npages * PAGE_SIZE); + return ret; +} + +/* map a SQ/CQ queue to host physical memory */ +static void *nvmet_mdev_udata_queue_vmap(struct nvmet_mdev_viommu *viommu, + dma_addr_t iova, unsigned int size) +{ + unsigned int npages; + struct page **pages; + void *map = NULL; + + /* queue must be page aligned */ + if (offset_in_page(iova) != 0) + return NULL; + + npages = DIV_ROUND_UP(size, PAGE_SIZE); + pages = kcalloc(npages, sizeof(struct page *), GFP_KERNEL); + if (!pages) + return NULL; + + if (nvmet_mdev_queue_getpages_contiguous(viommu, iova, pages, npages)) + goto out; + + map = vmap(pages, npages, VM_MAP, PAGE_KERNEL); +out: + kfree(pages); + return map; +} + +void nvmet_mdev_udata_queue_vunmap(struct nvmet_mdev_viommu *viommu, + dma_addr_t iova, void *data, + unsigned int data_size) +{ + if (!data) + return; + + vunmap(data); + nvmet_mdev_viommu_remove(viommu, iova, + DIV_ROUND_UP(data_size, PAGE_SIZE)); +} + +void *nvmet_mdev_udata_update_queue_vmap(struct nvmet_mdev_viommu *viommu, + dma_addr_t iova, void *data, + unsigned int data_size) +{ + if (!iova) + return NULL; + + if (data) + vunmap(data); + + return nvmet_mdev_udata_queue_vmap(viommu, iova, data_size); +} diff --git a/drivers/nvme/target/mdev-pci/vcq.c b/drivers/nvme/target/mdev-pci/vcq.c new file mode 100644 index 000000000000..22ac71a67a4c --- /dev/null +++ b/drivers/nvme/target/mdev-pci/vcq.c @@ -0,0 +1,160 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Virtual NVMe completion queue implementation + * Copyright (c) 2019 - Maxim Levitsky + * Copyright (C) 2025 Oracle Corporation + */ +#include +#include +#include +#include +#include "priv.h" + +static int nvmet_mdev_calc_vcq_size(struct nvmet_mdev_vcq *vcq) +{ + return round_up(vcq->size * sizeof(struct nvme_completion), PAGE_SIZE); +} + +/* Create new virtual completion queue */ +int nvmet_mdev_vcq_init(struct nvmet_mdev_vctrl *vctrl, u16 qid, + dma_addr_t iova, u16 size, int irq) +{ + struct nvmet_ctrl *ctrl = vctrl->nvmet_ctrl; + struct nvmet_mdev_vcq *q = &vctrl->vcqs[qid]; + + lockdep_assert_held(&vctrl->lock); + + q->vctrl = vctrl; + q->qid = qid; + q->size = size; + q->tail = 0; + q->phase = 1; + q->irq = irq; + q->head = 0; + q->iova = iova; + q->data = NULL; + q->data_size = nvmet_mdev_calc_vcq_size(q); + init_llist_head(&q->mreq_list); + + q->data = nvmet_mdev_udata_update_queue_vmap(&vctrl->viommu, q->iova, + (void *)q->data, + q->data_size); + if (!q->data) + goto delete; + + _DBG(vctrl, "VCQ: create qid=%d depth=%d irq=%d\n", qid, size, irq); + + vctrl->mmio.dbs[q->qid].cqh = 0; + vctrl->mmio.eidxs[q->qid].cqh = 0; + + if (nvmet_cq_create(ctrl, &q->nvmet_cq, qid, size)) + goto delete; + + set_bit(qid, vctrl->vcq_en); + return NVME_SC_SUCCESS; + +delete: + nvmet_mdev_vcq_delete(vctrl, qid); + return NVME_SC_INTERNAL; +} + +/* Delete a virtual completion queue */ +void nvmet_mdev_vcq_delete(struct nvmet_mdev_vctrl *vctrl, u16 qid) +{ + struct nvmet_mdev_vcq *q = &vctrl->vcqs[qid]; + + lockdep_assert_held(&vctrl->lock); + + nvmet_mdev_udata_queue_vunmap(&vctrl->viommu, q->iova, (void *)q->data, + q->data_size); + q->data = NULL; + q->iova = 0; + clear_bit(qid, vctrl->vcq_en); + + _DBG(vctrl, "VCQ: delete qid=%d\n", q->qid); +} + +/* Move queue tail one item forward */ +static void nvmet_mdev_vcq_advance_tail(struct nvmet_mdev_vcq *q) +{ + if (++q->tail == q->size) { + q->tail = 0; + q->phase ^= 1; + } +} + +/* Move queue head one item forward */ +static void nvmet_mdev_vcq_advance_head(struct nvmet_mdev_vcq *q) +{ + q->head++; + if (q->head == q->size) + q->head = 0; +} + +/* Process a virtual completion queue */ +void nvmet_mdev_vcq_process(struct nvmet_mdev_vctrl *vctrl, + struct nvmet_mdev_vcq *q, bool trigger_irqs, + ktime_t now) +{ + u16 new_head; + u32 eidx; + + if (!vctrl->mmio.dbs || !vctrl->mmio.eidxs) + return; + + new_head = le32_to_cpu(READ_ONCE(vctrl->mmio.dbs[q->qid].cqh)); + + if (new_head != q->head) { + /* bad tail - can't process */ + if (!nvmet_mdev_mmio_db_check(vctrl, q->qid, q->size, new_head)) + return; + + while (q->head != new_head) + nvmet_mdev_vcq_advance_head(q); + + eidx = q->head + (q->size >> 1); + if (eidx >= q->size) + eidx -= q->size; + WRITE_ONCE(vctrl->mmio.eidxs[q->qid].cqh, cpu_to_le32(eidx)); + } + + if (q->irq != -1 && trigger_irqs) { + if (q->tail != new_head) + nvmet_mdev_irq_cond_trigger(vctrl, q->irq, now); + else + nvmet_mdev_irq_clear(vctrl, q->irq, now); + } +} + +/* flush interrupts on a completion queue */ +bool nvmet_mdev_vcq_flush(struct nvmet_mdev_vctrl *vctrl, + struct nvmet_mdev_vcq *q, ktime_t now) +{ + u16 new_head = le32_to_cpu(READ_ONCE(vctrl->mmio.dbs[q->qid].cqh)); + + if (new_head == q->tail || q->irq == -1) + return false; + + nvmet_mdev_irq_trigger(vctrl, q->irq); + nvmet_mdev_irq_clear(vctrl, q->irq, now); + return true; +} + +void nvmet_mdev_vcq_write_cqe(struct nvmet_mdev_vctrl *vctrl, + struct nvmet_mdev_vcq *q, + struct nvme_completion *cqe) +{ + volatile u64 *qw = (u64 *)&q->data[q->tail]; + u64 *data = (u64 *)cqe; + + cqe->status = cqe->status | cpu_to_le16(q->phase); + + WRITE_ONCE(qw[0], data[0]); + /* ensure that hardware sees the phase bit flip last */ + wmb(); + WRITE_ONCE(qw[1], data[1]); + + nvmet_mdev_vcq_advance_tail(q); + if (q->irq != -1) + nvmet_mdev_irq_raise(vctrl, q->irq); +} diff --git a/drivers/nvme/target/mdev-pci/vctrl.c b/drivers/nvme/target/mdev-pci/vctrl.c new file mode 100644 index 000000000000..0568bec52f56 --- /dev/null +++ b/drivers/nvme/target/mdev-pci/vctrl.c @@ -0,0 +1,260 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Virtual NVMe controller implementation + * Copyright (c) 2019 - Maxim Levitsky + */ +#include +#include +#include +#include +#include +#include "priv.h" + +bool nvmet_mdev_vctrl_is_dead(struct nvmet_mdev_vctrl *vctrl) +{ + return (vctrl->mmio.csts & (NVME_CSTS_CFS | NVME_CSTS_SHST_MASK)) != 0; +} + +/* Create a new virtual controller */ +int nvmet_mdev_vctrl_create(struct nvmet_mdev_vctrl *vctrl, + struct mdev_device *mdev) +{ + int ret; + + /* Basic init */ + vctrl->mdev = mdev; + vctrl->viommu.vctrl = vctrl; + + kref_init(&vctrl->ref); + mutex_init(&vctrl->lock); + + /* default feature values */ + vctrl->arb_burst_shift = 3; + vctrl->mmio.shadow_db_supported = vctrl->nvmet_ctrl->shadow_db; + + ret = nvmet_mdev_pci_create(vctrl); + if (ret) + return ret; + + ret = nvmet_mdev_mmio_create(vctrl); + if (ret) + goto free_pci; + + nvmet_mdev_irqs_setup(vctrl); + + ret = nvmet_mdev_io_create(vctrl); + if (ret) + goto free_mmio; + + _INFO(vctrl, "device created\n"); + return 0; + +free_mmio: + nvmet_mdev_mmio_free(vctrl); +free_pci: + nvmet_mdev_pci_free(vctrl); + return ret; +} + +/* Try to destroy an vctrl */ +void nvmet_mdev_vctrl_destroy(struct nvmet_mdev_vctrl *vctrl) +{ + mutex_unlock(&vctrl->lock); + + mutex_lock(&vctrl->lock); /* only for lockdep checks */ + nvmet_mdev_io_free(vctrl); + __nvmet_mdev_vctrl_reset(vctrl, true); + + nvmet_mdev_pci_free(vctrl); + nvmet_mdev_mmio_free(vctrl); + + mutex_unlock(&vctrl->lock); + + _INFO(vctrl, "device is destroyed\n"); +} + +/* Called when new mediated device is first opened by a user */ +int nvmet_mdev_vctrl_open(struct vfio_device *vfio_dev) +{ + struct nvmet_mdev_vctrl *vctrl = vfio_dev_to_nvmet_mdev_vctrl(vfio_dev); + + _INFO(vctrl, "device is opened\n"); + + mutex_lock(&vctrl->lock); + nvmet_mdev_viommu_init(&vctrl->viommu, vfio_dev); + nvmet_mdev_mmio_open(vctrl); + mutex_unlock(&vctrl->lock); + return 0; +} + +/* Called when new mediated device is closed (last close of the user) */ +void nvmet_mdev_vctrl_release(struct vfio_device *vfio_dev) +{ + struct nvmet_mdev_vctrl *vctrl = vfio_dev_to_nvmet_mdev_vctrl(vfio_dev); + + mutex_lock(&vctrl->lock); + nvmet_mdev_io_pause(vctrl); + /* + * Remove the guest DMA mappings - new user that will open the + * device might be a different guest + */ + nvmet_mdev_viommu_reset(&vctrl->viommu); + + /* Reset the controller to a clean state for a new user */ + __nvmet_mdev_vctrl_reset(vctrl, false); + nvmet_mdev_irqs_reset(vctrl); + mutex_unlock(&vctrl->lock); + + _INFO(vctrl, "device is released\n"); +} + +/* Called each time the controller is reset (CC.EN <= 0 or VM level reset) */ +void __nvmet_mdev_vctrl_reset(struct nvmet_mdev_vctrl *vctrl, bool pci_reset) +{ + lockdep_assert_held(&vctrl->lock); + + if ((vctrl->mmio.csts & NVME_CSTS_RDY) && + !(vctrl->mmio.csts & NVME_CSTS_SHST_MASK)) { + _DBG(vctrl, "unsafe reset (CSTS.RDY==1)\n"); + nvmet_mdev_io_pause(vctrl); + nvmet_mdev_vctrl_disable(vctrl); + } + nvmet_mdev_mmio_reset(vctrl, pci_reset); +} + +/* setups initial admin queues and doorbells */ +bool nvmet_mdev_vctrl_enable(struct nvmet_mdev_vctrl *vctrl, dma_addr_t cqiova, + dma_addr_t sqiova, u32 sizes) +{ + struct nvmet_ctrl *ctrl = vctrl->nvmet_ctrl; + u16 cqentries, sqentries; + int ret; + + nvmet_mdev_assert_io_not_running(vctrl); + + lockdep_assert_held(&vctrl->lock); + + sqentries = (sizes & 0xFFFF) + 1; + cqentries = (sizes >> 16) + 1; + + if (cqentries > 4096 || cqentries < 2) + return false; + if (sqentries > 4096 || sqentries < 2) + return false; + + ret = nvmet_mdev_mmio_enable_dbs(vctrl); + if (ret) + return false; + + ret = nvmet_mdev_vcq_init(vctrl, 0, cqiova, cqentries, 0); + if (ret) + goto disable_dbs; + + ret = nvmet_mdev_vsq_init(vctrl, 0, sqiova, sqentries, 0); + if (ret) + goto delete_vcq; + + nvmet_update_cc(ctrl, vctrl->mmio.cc); + if (ctrl->csts != NVME_CSTS_RDY) + goto delete_vsq; + + if (!vctrl->mmio.shadow_db_supported) { + /* start polling right away to support admin queue */ + vctrl->io_idle = false; + nvmet_mdev_io_resume(vctrl); + } + + return true; + +delete_vsq: + nvmet_mdev_vsq_delete(vctrl, 0); +delete_vcq: + nvmet_mdev_vcq_delete(vctrl, 0); +disable_dbs: + nvmet_mdev_mmio_disable_dbs(vctrl); + return false; +} + +/* destroy all io/admin queues on the controller */ +void nvmet_mdev_vctrl_disable(struct nvmet_mdev_vctrl *vctrl) +{ + u16 sqid, cqid; + + nvmet_mdev_assert_io_not_running(vctrl); + + lockdep_assert_held(&vctrl->lock); + + sqid = 1; + for_each_set_bit_from(sqid, vctrl->vsq_en, NVMET_MDEV_MAX_NR_QUEUES) + nvmet_mdev_vsq_delete(vctrl, sqid); + + cqid = 1; + for_each_set_bit_from(cqid, vctrl->vcq_en, NVMET_MDEV_MAX_NR_QUEUES) + nvmet_mdev_vcq_delete(vctrl, cqid); + + nvmet_mdev_vsq_delete(vctrl, 0); + nvmet_mdev_vcq_delete(vctrl, 0); + + nvmet_mdev_mmio_disable_dbs(vctrl); + vctrl->io_idle = true; +} + +/* External reset */ +void nvmet_mdev_vctrl_reset(struct nvmet_mdev_vctrl *vctrl) +{ + mutex_lock(&vctrl->lock); + _INFO(vctrl, "reset\n"); + __nvmet_mdev_vctrl_reset(vctrl, true); + mutex_unlock(&vctrl->lock); +} + +/* Add IO region */ +void nvmet_mdev_vctrl_add_region(struct nvmet_mdev_vctrl *vctrl, + unsigned int index, unsigned int size, + region_access_fn access_fn) +{ + struct nvmet_mdev_io_region *region = &vctrl->regions[index]; + + region->size = size; + region->rw = access_fn; + region->mmap_ops = NULL; +} + +/* Enable mmap window on an IO region */ +void nvmet_mdev_vctrl_region_set_mmap(struct nvmet_mdev_vctrl *vctrl, + unsigned int index, + unsigned int offset, + unsigned int size, + const struct vm_operations_struct *ops) +{ + struct nvmet_mdev_io_region *region = &vctrl->regions[index]; + + region->mmap_area_start = offset; + region->mmap_area_size = size; + region->mmap_ops = ops; +} + +/* Disable mmap window on an IO region */ +void nvmet_mdev_vctrl_region_disable_mmap(struct nvmet_mdev_vctrl *vctrl, + unsigned int index) +{ + struct nvmet_mdev_io_region *region = &vctrl->regions[index]; + + region->mmap_area_start = 0; + region->mmap_area_size = 0; + region->mmap_ops = NULL; +} + +/* remove a user memory mapping */ +int nvmet_mdev_vctrl_viommu_unmap(struct nvmet_mdev_vctrl *vctrl, + dma_addr_t iova, u64 size) +{ + bool paused; + int ret; + + paused = nvmet_mdev_io_pause(vctrl); + ret = nvmet_mdev_viommu_remove(&vctrl->viommu, iova, size); + if (paused) + nvmet_mdev_io_resume(vctrl); + return ret; +} diff --git a/drivers/nvme/target/mdev-pci/viommu.c b/drivers/nvme/target/mdev-pci/viommu.c new file mode 100644 index 000000000000..9ef4281a87da --- /dev/null +++ b/drivers/nvme/target/mdev-pci/viommu.c @@ -0,0 +1,308 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Virtual IOMMU - mapping user memory to the real device + * Copyright (c) 2019 - Maxim Levitsky + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "priv.h" + +struct mem_mapping { + struct rb_node rb; + struct list_head link; + + dma_addr_t __subtree_last; + dma_addr_t iova_start; /* first iova in this mapping */ + dma_addr_t iova_last; /* last iova in this mapping */ + + unsigned long pfn; /* physical address of this mapping */ + int refcount; +}; + +#define map_len(m) (((m)->iova_last - (m)->iova_start) + 1ULL) +#define map_pages(m) (map_len(m) >> PAGE_SHIFT) +#define START(node) ((node)->iova_start) +#define LAST(node) ((node)->iova_last) + +INTERVAL_TREE_DEFINE(struct mem_mapping, rb, dma_addr_t, __subtree_last, + START, LAST, static inline, viommu_int_tree); + +static void nvmet_mdev_viommu_dbg_dma_range(struct nvmet_mdev_viommu *viommu, + struct mem_mapping *map, + const char *action) +{ + dma_addr_t iova_start = map->iova_start; + dma_addr_t iova_end = map->iova_start + map_len(map) - 1; + + _DBG(viommu->vctrl, "vIOMMU: %s RW IOVA %pad-%pad", + action, &iova_start, &iova_end); +} + +/* unpin N pages starting at given IOVA */ +static void nvmet_mdev_viommu_unpin_pages(struct nvmet_mdev_viommu *viommu, + dma_addr_t iova, int n) +{ + int i, npages; + + for (i = 0; i < n; i += npages) { + npages = min_t(int, VFIO_PIN_PAGES_MAX_ENTRIES, n); + + vfio_unpin_pages(viommu->vfio_dev, iova + (i * PAGE_SIZE), + npages); + } +} + +/* User memory init code */ +void nvmet_mdev_viommu_init(struct nvmet_mdev_viommu *viommu, + struct vfio_device *vfio_dev) +{ + viommu->vfio_dev = vfio_dev; + viommu->maps_tree = RB_ROOT_CACHED; + INIT_LIST_HEAD(&viommu->mem_map_list); +} + +int nvmet_mdev_viommu_remove_list(struct nvmet_mdev_viommu *viommu, + struct list_head *remove_list) +{ + struct mem_mapping *map, *tmp; + int count = 0; + + list_for_each_entry_safe(map, tmp, remove_list, link) { + list_del(&map->link); + + nvmet_mdev_viommu_unpin_pages(viommu, map->iova_start, + map_pages(map)); + viommu_int_tree_remove(map, &viommu->maps_tree); + kfree(map); + count++; + } + return count; +} + +/* User memory end code */ +void nvmet_mdev_viommu_reset(struct nvmet_mdev_viommu *viommu) +{ + nvmet_mdev_viommu_remove_list(viommu, &viommu->mem_map_list); + WARN_ON(!list_empty(&viommu->mem_map_list)); +} + +/* Adds a new range of user memory */ +int nvmet_mdev_viommu_add(struct nvmet_mdev_viommu *viommu, u32 flags, + dma_addr_t iova, u64 size, + struct list_head *mem_map_list) +{ + struct vfio_device *vfio_dev = viommu->vfio_dev; + struct nvmet_mdev_vctrl *vctrl = vfio_dev_to_nvmet_mdev_vctrl(vfio_dev); + dma_addr_t iova_curr, iova_end, iova_start; + struct mem_mapping *map = NULL, *tmp; + LIST_HEAD(new_mappings_list); + int ret, count = 0; + + /* + * iova/size may not be page aligned if this is for IO. We align + * them here because the viommu requires it. + */ + iova_start = iova; + if (!PAGE_ALIGNED(iova_start)) { + iova_start = PAGE_ALIGN_DOWN(iova_start); + _DBG(vctrl, "vIOMMU: realign iova %pad -> %pad\n", + &iova, &iova_start); + } + + iova_end = iova + size; + if (!PAGE_ALIGNED(iova_end)) { + iova_end = PAGE_ALIGN(iova_end); + _DBG(vctrl, + "vIOMMU: realign size %llu -> %llu\n", + size, PAGE_ALIGN(size)); + } + + if (!(flags & VFIO_DMA_MAP_FLAG_READ) || + !(flags & VFIO_DMA_MAP_FLAG_WRITE)) { + const char *type = "none"; + + if (flags & VFIO_DMA_MAP_FLAG_READ) + type = "RO"; + else if (flags & VFIO_DMA_MAP_FLAG_WRITE) + type = "WO"; + + _DBG(viommu->vctrl, "vIOMMU: IGN %s IOVA %pad-%pad\n", + type, &iova_start, &iova_end); + return 0; + } + + /* VFIO pinning all the pages */ + for (iova_curr = iova_start; iova_curr < iova_end; + iova_curr += PAGE_SIZE) { + struct page *page; + + ret = vfio_pin_pages(viommu->vfio_dev, iova_curr, 1, + VFIO_DMA_MAP_FLAG_READ | + VFIO_DMA_MAP_FLAG_WRITE, + &page); + if (ret != 1) { + _DBG(viommu->vctrl, + "vIOMMU: ADD RW IOVA %pad len: %llu - pin failed %d\n", + &iova, size, ret); + goto unwind; + } + + /* new mapping needed */ + if (!map || map->pfn + map_pages(map) != page_to_pfn(page)) { + map = kzalloc(sizeof(*map), GFP_KERNEL); + if (!map) { + vfio_unpin_pages(viommu->vfio_dev, iova_curr, + 1); + ret = -ENOMEM; + goto unwind; + } + map->iova_start = iova_curr; + map->iova_last = iova_curr + PAGE_SIZE - 1ULL; + map->pfn = page_to_pfn(page); + map->refcount = 1; + INIT_LIST_HEAD(&map->link); + list_add_tail(&map->link, &new_mappings_list); + } else { + /* current map can be extended */ + map->iova_last += PAGE_SIZE; + } + } + + /* DMA mapping the pages */ + list_for_each_entry_safe(map, tmp, &new_mappings_list, link) { + nvmet_mdev_viommu_dbg_dma_range(viommu, map, "ADD"); + list_move_tail(&map->link, mem_map_list); + viommu_int_tree_insert(map, &viommu->maps_tree); + count++; + } + + _DBG(viommu->vctrl, "vIOMMU: ADD RW IOVA %pad-%pad len %llu count %d\n", + &iova_start, &iova_end, size, count); + + return 0; +unwind: + list_for_each_entry_safe(map, tmp, &new_mappings_list, link) { + nvmet_mdev_viommu_unpin_pages(viommu, map->iova_start, + map_pages(map)); + + list_del(&map->link); + kfree(map); + } + return ret; +} + +/* Removes a range of user memory */ +int nvmet_mdev_viommu_remove(struct nvmet_mdev_viommu *viommu, dma_addr_t iova, + u64 size) +{ + dma_addr_t last_iova = iova + (size) - 1ULL; + struct mem_mapping *map; + LIST_HEAD(remove_list); + int count = 0; + + /* find out all the relevant ranges */ + map = viommu_int_tree_iter_first(&viommu->maps_tree, iova, last_iova); + while (map) { + list_move_tail(&map->link, &remove_list); + map = viommu_int_tree_iter_next(map, iova, last_iova); + } + + /* remove them */ + count = nvmet_mdev_viommu_remove_list(viommu, &remove_list); + return count; +} + +/* Translate an IOVA to a physical address and read device bus address */ +int nvmet_mdev_viommu_translate(struct nvmet_mdev_viommu *viommu, + dma_addr_t iova, dma_addr_t *physical) +{ + struct mem_mapping *mapping; + u64 offset; + + if (WARN_ON_ONCE(offset_in_page(iova) != 0)) + return -EINVAL; + + mapping = viommu_int_tree_iter_first(&viommu->maps_tree, + iova, iova + PAGE_SIZE - 1); + if (!mapping) { + _DBG(viommu->vctrl, + "vIOMMU: translation of IOVA %pad failed\n", &iova); + return -EFAULT; + } + + WARN_ON(iova > mapping->iova_last); + WARN_ON(offset_in_page(mapping->iova_start) != 0); + + offset = iova - mapping->iova_start; + *physical = PFN_PHYS(mapping->pfn) + offset; + return 0; +} + +/* map an IOVA to kernel address space */ +int nvmet_mdev_viommu_create_kmap(struct nvmet_mdev_viommu *viommu, + dma_addr_t iova, struct page_map *page) +{ + phys_addr_t physical; + struct page *new_page; + int ret; + + page->iova = iova; + + ret = nvmet_mdev_viommu_translate(viommu, iova, &physical); + if (ret) + return ret; + + new_page = pfn_to_page(PHYS_PFN(physical)); + + page->kmap = kmap_local_page(new_page); + if (!page->kmap) + return -ENOMEM; + + page->page = new_page; + return 0; +} + +/* update IOVA <-> kernel mapping. If fails, removes the previous mapping */ +void nvmet_mdev_viommu_update_kmap(struct nvmet_mdev_viommu *viommu, + struct page_map *page) +{ + phys_addr_t physical; + struct page *new_page; + int ret; + + ret = nvmet_mdev_viommu_translate(viommu, page->iova, &physical); + if (ret) { + nvmet_mdev_viommu_free_kmap(viommu, page); + return; + } + + new_page = pfn_to_page(PHYS_PFN(physical)); + if (new_page == page->page) + return; + + nvmet_mdev_viommu_free_kmap(viommu, page); + + page->kmap = kmap_local_page(new_page); + if (!page->kmap) + return; + page->page = new_page; +} + +/* unmap an IOVA to kernel address space */ +void nvmet_mdev_viommu_free_kmap(struct nvmet_mdev_viommu *viommu, + struct page_map *page) +{ + if (page->page) { + kunmap_local(page->kmap); + page->page = NULL; + page->kmap = NULL; + } +} diff --git a/drivers/nvme/target/mdev-pci/vsq.c b/drivers/nvme/target/mdev-pci/vsq.c new file mode 100644 index 000000000000..69e82b29cc4a --- /dev/null +++ b/drivers/nvme/target/mdev-pci/vsq.c @@ -0,0 +1,175 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Virtual NVMe submission queue implementation + * Copyright (c) 2019 - Maxim Levitsky + * Copyright (C) 2025 Oracle Corporation + */ +#include +#include +#include +#include +#include +#include "priv.h" + +static int nvmet_mdev_calc_vsq_size(struct nvmet_mdev_vsq *vsq) +{ + return round_up(vsq->size * sizeof(struct nvme_command), PAGE_SIZE); +} + +/* Delete an virtual completion queue */ +void nvmet_mdev_vsq_delete(struct nvmet_mdev_vctrl *vctrl, u16 qid) +{ + struct nvmet_mdev_vsq *q = &vctrl->vsqs[qid]; + bool paused; + + lockdep_assert_held(&vctrl->lock); + _DBG(vctrl, "VSQ: delete qid=%d\n", q->qid); + + /* + * If this is an unclean shutdown make sure we don't try to start + * new IOs after we free the queue. + */ + paused = nvmet_mdev_io_pause(vctrl); + clear_bit(qid, vctrl->vsq_en); + if (paused) + nvmet_mdev_io_resume(vctrl); + + if (q->nvmet_sq.ctrl) + nvmet_sq_destroy(&q->nvmet_sq); + + /* + * The nvmet sq destruction just waits for the queue_response callout + * to return, so we could still have completions queued. Flush + * them now since we are freeing the queue below. + */ + if (test_and_clear_bit(qid, vctrl->vcq_en)) { + paused = nvmet_mdev_io_pause(vctrl); + nvmet_mdev_process_responses(vctrl, q->vcq); + if (paused) + nvmet_mdev_io_resume(vctrl); + } + + kfree(q->reqs); + + nvmet_mdev_udata_queue_vunmap(&vctrl->viommu, q->iova, q->data, + q->data_size); + q->data = NULL; + q->iova = 0; +} + +/* Create new virtual completion queue */ +int nvmet_mdev_vsq_init(struct nvmet_mdev_vctrl *vctrl, u16 qid, + dma_addr_t iova, u16 size, u16 cqid) +{ + struct nvmet_ctrl *ctrl = vctrl->nvmet_ctrl; + struct nvmet_mdev_vsq *q = &vctrl->vsqs[qid]; + + lockdep_assert_held(&vctrl->lock); + + q->vctrl = vctrl; + q->qid = qid; + q->size = size; + q->head = 0; + q->vcq = &vctrl->vcqs[cqid]; + q->data = NULL; + q->iova = iova; + q->data_size = nvmet_mdev_calc_vsq_size(q); + + _DBG(vctrl, "VSQ: create qid=%d depth=%d cqid=%d\n", qid, size, cqid); + + q->data = nvmet_mdev_udata_update_queue_vmap(&vctrl->viommu, q->iova, + q->data, q->data_size); + if (!q->data) + goto delete; + + q->reqs = kcalloc(size, sizeof(*q->reqs), GFP_KERNEL); + if (!q->reqs) + goto delete; + + vctrl->mmio.dbs[q->qid].sqt = 0; + vctrl->mmio.eidxs[q->qid].sqt = 0; + + if (nvmet_sq_create(ctrl, &q->nvmet_sq, qid, size)) + goto delete; + + set_bit(qid, vctrl->vsq_en); + return NVME_SC_SUCCESS; + +delete: + nvmet_mdev_vsq_delete(vctrl, qid); + return NVME_SC_INTERNAL; +} + +/* Move queue head one item forward */ +static void nvmet_mdev_vsq_advance_head(struct nvmet_mdev_vsq *q) +{ + q->head++; + if (q->head == q->size) + q->head = 0; +} + +static bool nvmet_mdev_vsq_has_data(struct nvmet_mdev_vctrl *vctrl, + struct nvmet_mdev_vsq *q) +{ + u16 tail = le32_to_cpu(READ_ONCE(vctrl->mmio.dbs[q->qid].sqt)); + + if (!vctrl->mmio.dbs || !vctrl->mmio.eidxs || !q->data) + return false; + + if (tail == q->head) + return false; + + if (!nvmet_mdev_mmio_db_check(vctrl, q->qid, q->size, tail)) + return false; + return true; +} + +/* get one command from a virtual submission queue */ +struct nvme_command *nvmet_mdev_vsq_get_cmd(struct nvmet_mdev_vctrl *vctrl, + struct nvmet_mdev_vsq *q, + u16 *index) +{ + u16 oldhead = q->head; + u32 eidx; + + if (!nvmet_mdev_vsq_has_data(vctrl, q)) + return NULL; + + nvmet_mdev_vsq_advance_head(q); + + eidx = q->head + (q->size >> 1); + if (eidx >= q->size) + eidx -= q->size; + + WRITE_ONCE(vctrl->mmio.eidxs[q->qid].sqt, cpu_to_le32(eidx)); + + *index = oldhead; + return &q->data[oldhead]; +} + +bool nvmet_mdev_vsq_suspend_io(struct nvmet_mdev_vsq *q) +{ + struct nvmet_mdev_vctrl *vctrl = q->vctrl; + u16 tail = le32_to_cpu(vctrl->mmio.dbs[q->qid].sqt); + + /* + * If the queue is not in working state don't allow the idle code + * to kick in + */ + if (!vctrl->mmio.dbs || !vctrl->mmio.eidxs || !q->data) + return false; + + /* queue has data - refuse idle */ + if (tail != q->head) + return false; + + /* Write eventid to tell the user to ring normal doorbell */ + vctrl->mmio.eidxs[q->qid].sqt = cpu_to_le32(q->head); + + /* memory barrier to ensure that the user have seen the eidx */ + mb(); + + /* Check that doorbell diddn't move meanwhile */ + tail = le32_to_cpu(vctrl->mmio.dbs[q->qid].sqt); + return (tail == q->head); +}