From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from NAM01-BY2-obe.outbound.protection.outlook.com (mail-by2nam01on0079.outbound.protection.outlook.com [104.47.34.79]) by dpdk.org (Postfix) with ESMTP id 23DC42C18 for ; Fri, 5 May 2017 15:34:22 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=CAVIUMNETWORKS.onmicrosoft.com; s=selector1-cavium-com; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version; bh=9RKbABWteubRJY1bh14ERI+w6fJWK7thMCap3+GZkLA=; b=SvhTTuiYD5W1p9rifRdlVxS7JmR6YAaKMhA7jNHfHLNO6HTOMCLSKziVMlsyD4RgAQkzITOwtFXOEbkZRzL39eOQKF9PwEmXxO7ptQBcPtPIaC+6uf2UpYNT6uBbicLdic0L8VD7Uq+cbUu6pvMxpkJh6xhDidyP4WQzyZkT8o4= Authentication-Results: dpdk.org; dkim=none (message not signed) header.d=none;dpdk.org; dmarc=none action=none header.from=caviumnetworks.com; Received: from jerin.domain.name (122.167.66.17) by BLUPR0701MB1714.namprd07.prod.outlook.com (10.163.85.140) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256_P256) id 15.1.1075.11; Fri, 5 May 2017 13:34:12 +0000 From: Jerin Jacob To: dev@dpdk.org Cc: thomas@monjalon.net, bruce.richardson@intel.com, harry.van.haaren@intel.com, hemant.agrawal@nxp.com, gage.eads@intel.com, nipun.gupta@nxp.com, narender.vangati@intel.com, Jerin Jacob Date: Fri, 5 May 2017 19:03:41 +0530 Message-Id: <20170505133341.31138-1-jerin.jacob@caviumnetworks.com> X-Mailer: git-send-email 2.12.2 MIME-Version: 1.0 Content-Type: text/plain X-Originating-IP: [122.167.66.17] X-ClientProxiedBy: MA1PR01CA0090.INDPRD01.PROD.OUTLOOK.COM (10.174.56.30) To BLUPR0701MB1714.namprd07.prod.outlook.com (10.163.85.140) X-MS-PublicTrafficType: Email X-MS-Office365-Filtering-Correlation-Id: 725cd10d-ceb8-42e2-e155-08d493bb6e84 X-Microsoft-Antispam: UriScan:; BCL:0; PCL:0; RULEID:(22001)(201703131423075)(201703031133081); SRVR:BLUPR0701MB1714; X-Microsoft-Exchange-Diagnostics: 1; BLUPR0701MB1714; 3:pQyQpGQeV5bAAfmThA/KHLuHTUqegtFRfc0QkZ2ZC0zPmo2WCwn1pmdYB2/xkhtrFi/tPY7c6GTKRmIETsi0IG8NL2W5YiRI1lcr7oDTZPBDomTMTnHjPRrp1PrQ6bkCxAs9wkaVvvHujG0aNwxCgbPwV3qYh6cig0e1TNr+6hwnIm5+B73uwOcejwtRrZoZBT+fcQnAOoHJQXb0LCktbhvV5STL90lU3EJVV61ajY9aC5OETqgK8z98FnQcF+aDZ+Mp9dM+yyK2IafHOF6dA+i5Ma/2Ad1SOMeD/QL6tQf34nmN6L4BvzmundH6IYEGQH7CQDGxj2cAkHu4yQ86Qg==; 25:58NLF3Yx+iTYPs0LYhCUaB9BPOuSEim+dLFdF5N53vWtipCAWNjWwaGGAyH4iuaakwKyG3nm/JY/TteZ8Y+VA1r6iGwRfhDTB43JwdcaWpzVa+WzFLS4+OdrAKB2VxfiP4jmJzUcQHVfKe5+mDNT5LepYVoY2l2fl6vaX2wq7ORmcj2kpZf2xpGLFQQTeXB4pOKCpxWPXX1R3K07AXLZebtJkQ7D5WYFAHXbhz0A8Lc/QwzzlSd2lWoTaXX0uYzgoj0AxaYfuFUpJaFz0EglDrCLfG+wOH4chsnrf4NNcwzTCiqS78uyaPHNftMBGtoc+1SEff/E96bG0x10elUFyZp798hdylVopmSRrK5nRprf3s4BpnmEq7xJ0GeIDGvjT1LnBBM+5R2SPQlcaYyeD96MkhUTJtyACmwGk124LafUx3rVOHnWTomx+ZgfEGG2K5P0G+kus5Q3QQ7BeTZsXMuEWBZhbE9PAMkqWJ7XZjY= X-Microsoft-Exchange-Diagnostics: 1; BLUPR0701MB1714; 31:rvPMHNvehfzbwdUfvDlitReQXxLVSflLu57dQ3npTEK6K+BxFhZx0tpP2ZOOdS0hw+mwXGfOWUxGUiRqabrz0gnyaUPFLtuhpSJjra5Jbc50ixzZjSsrEtwySJQQtIeJgaAv04RDPrq5YdDt41vrd2U/X6/R8k8AdaOf6b23zsLiWLzsyINhYyue+Pfi2El4lVKbbhYt7WW6t9LMY9re5fknTmIGMn9dPpkZjN86JxkVZvgT/TvK3eaMSfdr1aBI; 20:onPGRj7X0czMVBWkFaCWq9nJrt7m5BMhbbPMl2z5EqZGcORIYzwcC2+APQiCTNDQumXKHKw7ZJZlmHx+8zTGwaTCuwQNR2AGsM7yUItci3ydCDBZQxubhu8kUP9DVXEipryzsnoFtFPd9rHKbKxeFOovlQedHl5/jVnFq8dLEfFXBBka7Sjjf7v1ZiGBoujOOT7SgljED/KvnxNf7MRfd4wvA+WyPuLtTw4vzn0e8xOj+a6J4EnII/1asQCX8P+vN0zqas8p8ZjeM/V64C96FYhxLITwiEjZfwate1vcCYNBf38Y3bY4WIEybhfw1CmeYAOPEqiFZeDFcrDNTQwiIjZagRbi0iIRBDL6SK79V9vAefu6ri3My3uMtkUEtVLgnTZdgo4833/EWDf8qp+MZEMPZH2IMc8whCvGlrG5a1i+0LzkYHL0TzLtAAcujovqNP9HpAzszDZi8ITOpdznQuHbrGyYmaTcnceBEOxllduZBEtKpwkTz8BQ43afRVbCLSK4UWscYzMMC6vs2VNkhP/mMs/G3PGTXZ4iA0cMoiQln+YD4dW7oxdze60jx1e14sVkexz1gjW99fQa2d+FoVyqIFZqPTZoF+/Xz+Ef0YA= X-Microsoft-Antispam-PRVS: X-Exchange-Antispam-Report-Test: UriScan:; X-Exchange-Antispam-Report-CFA-Test: BCL:0; PCL:0; RULEID:(6040450)(601004)(2401047)(5005006)(8121501046)(10201501046)(93006095)(3002001)(6041248)(201703131423075)(201702281528075)(201703061421075)(201703061406153)(20161123555025)(20161123562025)(20161123560025)(20161123564025)(20161123558100)(6072148); SRVR:BLUPR0701MB1714; BCL:0; PCL:0; RULEID:; SRVR:BLUPR0701MB1714; X-Microsoft-Exchange-Diagnostics: 1; BLUPR0701MB1714; 4:G0XhYvI9GaL5ZydVAtQ1GnHlbQwNpkMoWnppoo35YHig83SWu8fe/NfvhyNQZQ5HEa86jZ0wCS3Vdjg+rR0/hvtBoBVFbXIVtQNO7Z65lpnF83EX7mWy+eYmYhSUQEm+GVr12a4rnzSQlaCt0D5CCbsjG+MoCltpbltH1yMfYftR9O72oRMQkWAUJIvZvyxAFDMO+IVf2XRuJiuzmvw5LgngalwXbDEgCoekL0qVXZQL6SxvdpagySCgak1J5mGtDHe214zsZcyTxtHo7u/eoWcHyn2xTgvt1gPBGoo2twlLE1yyyfz9lhYwy1Ayq/00r/Gq0PDZMWPjC7/mSjcGPP/OUaUsxYqpBaKD+Qqnd7d7TguHZfeaXCjUFEnxmKoYH4m9T1iDyeV9F3JrT6jfDlXjgmQxgjK+1u/95+g1oxwBxE/JRBX7SkdIDEkXNx4gidQKUQHwi4kqeF/t2Khm8hceF3wIchxhc4b/5yMRVOOq8pAE+VO3+iLuKch0pNo6HpSrcQE5Cj11GBSgsBhliBDirf5lAEgVvmhTLb7NMIvsEbnoxYDg7CAkk9p+/+PnknaTn02Qt+ZIA/WuPCjxU7E79nIJtDOKhzGsi9WHJ4ciAChLs1BSOUyXuWrnaJTsDQUWmywLOJTn9Ghn/1udkVc9bnQLZLRsf6iRX2GBld18UzrBaq3+7TcWxkZjjMEsOsS3nA+Fp+Kk1p8S+ekSbUSLKs9zKS+YOPXPcxiNyqcSKKtAqsy81OP5rvCH9bvXuRpFIInkDDhi52KlrZb1Hg== X-Forefront-PRVS: 02981BE340 X-Forefront-Antispam-Report: SFV:NSPM; SFS:(10009020)(4630300001)(6009001)(39450400003)(39400400002)(39410400002)(39840400002)(39850400002)(8656002)(478600001)(189998001)(6512007)(47776003)(2351001)(966004)(2361001)(6116002)(33646002)(53376002)(2906002)(6486002)(53936002)(25786009)(6306002)(107886003)(110136004)(38730400002)(6506006)(5660300001)(50986999)(5003940100001)(6666003)(42882006)(6916009)(36756003)(50226002)(8676002)(4326008)(81166006)(53416004)(42186005)(1076002)(48376002)(66066001)(3846002)(7736002)(50466002)(305945005); DIR:OUT; SFP:1101; SCL:1; SRVR:BLUPR0701MB1714; H:jerin.domain.name; FPR:; SPF:None; MLV:sfv; LANG:en; X-Microsoft-Exchange-Diagnostics: =?us-ascii?Q?1; BLUPR0701MB1714; 23:3G6t4V5eontFQiAMMcQp550ULAQHvepMAzSoG8N?= =?us-ascii?Q?YP+UK0G/ZpncWLdQ1je8p3HhQ4LUVuwHPWyZh2umz6dICuoSwifg9Wk+QmmZ?= =?us-ascii?Q?y4cIZ1O78UVcllD2M5B23Ra9TeJiSsY3coDYxUujPU7Io1EOvbiR+Wn0RIIh?= =?us-ascii?Q?E/NGwHusKHwBlGZSIWlelmILiTkH39j43vF/vAnCb+gzUrUtPpgvB8Dvyzlp?= =?us-ascii?Q?jcJ0MWQ7/sGghObYrd5xlnfej0oseik3adL+n7N0zB3uulpFrJshJZN4qzw6?= =?us-ascii?Q?+eRLBsYprZYrrCU5KehvJaXPj+eIGZ6Z3B6sBSqx4N1X8tWaFwnXSMDAw59a?= =?us-ascii?Q?wshwszytVbH3616/3wJPPFkk5wz/5Ku33lOqYvChVRCPtj4S8zxO1YTyi8ou?= =?us-ascii?Q?b9ghRQpr0dbYKuuNAyVdPcfFf1c32RbAeze6uuSFb05r/Mjiga57G30PITHn?= =?us-ascii?Q?kSF3n+BsR3qsW0zsscY7+gBOxQ+OHOhB/DKMpNb7fg61Am41I+UTVM0JN3Rc?= =?us-ascii?Q?jbWfit2x4brpmEcPNAD65i62pppJ99F7HRzu9uDTUCmDBoNQ/hOaLSkSKw3p?= =?us-ascii?Q?xt5epbNnUiY15/TNb9ZPtMF2mjQi+M1T8OSsPjYu9cJV1BanSOmcFLc11AJ5?= =?us-ascii?Q?7vHTbybIKgvVpKfeUjM7fIVvnd1cCRGEPC8ptW3wCPMasKii2w0fcIBdZjIO?= =?us-ascii?Q?bFizjm6nD5a2gpfDC+coD5r7USdsAKW9FG/78sh7jqtFrsI56upEvQOItheC?= =?us-ascii?Q?+xCl/Iqdcb0AhAx72dNkXBsZrZrYxfb6IFX7i0mJ6uECLY59XWWlfqalxKW0?= =?us-ascii?Q?5cZ4dZ7lN4CgKvFRsJvVoYO5w4BnS4cwLn6+GyNxHTOz+prJzocBLIBipPCo?= =?us-ascii?Q?grLbJOxmVBhIMjyCO4cNqdGSxyf1BhCCj3lfAQGKRvbJvtX5k+XJMIMnZ7YK?= =?us-ascii?Q?JuW+DeLCF3Jl393Yq+VjWB6bistHifmvTXh0BLbJVWhKcVU7qW/p8Q5A0EMj?= =?us-ascii?Q?2ykU21gY8tBWHGxepp2MZhDib+uA7ZOY98Y/RjVyFUA7a2JistNX8wSqnEfC?= =?us-ascii?Q?5EFSTT05oGGnnUcfR9+/MY7tGjwMI0lxEfRGBKkpMKlTds9EDGiiuZ0x89pM?= =?us-ascii?Q?Bakf/NlRVpjR+Ewzt0Y7Pt87QZPTkIXp/+ZFSvzM5GRyhzgH+XM5Eug=3D?= =?us-ascii?Q?=3D?= X-Microsoft-Exchange-Diagnostics: 1; BLUPR0701MB1714; 6:6AX4cLeTf7HRLBCE1ucDXNPqLWQ7qQOaKQtyVDnIrlOiwtstBrG6O5FN89x2EaFR/azucIaXLDJdVReQmWj8smt+CPotsDijtlxLl9JC86DKbV9x7Wc3yGOvpWuZLhUD9PCO7q/nHN9pA3fOdhtpkSu11tcEtkFyerwitmklJZIvfV81F+l4of7OVRBwI+RLIEwxJIXEVkmWim+ZEd7dOlPQ5ti9lsHI0Z2lYFkJCIiTg7Jr2M0wfZP4xuR3jK1UBEcm7/H2/PLJ/Rfbz6vYhlGJhFCAdF6IPETh8ainutoE1Hi6ZXp9YbQA83puDb7i4jqZFIRY+CEE5fYO7SHqIEE88XUcSKMpfgfIHdFY7fjOKUwwvg/008qHDqREGKv/2vzjqNvBXcfWZLSBhiDEX7sNyZVIowBcWnxA6Ti3c7+g7ri60cZYy+L7VfLzRHNA0B8gM31zzjaSVM2GX05f+QCXqK/kIUkRFDO2XZFKWdZVSHqR7siPDbtu6UCzN3syYXGCZBVoTlxa18Heee7J8Q==; 5:7NMGOTqtj9ED+zwckfMycxtYq1f4w373MztpqZlGwF4OZM1pvqNA3WiYpffmff1dR+JGR8Kb//QR1OEiXlVV3oZHKkemDDegw2J0GPhJKJ7MUAfS7UUnmYqJIXjg0ETbTVCK/0Eqak+IK5jqeosU5A==; 24:jsJim2F69wsDG2/ZmmRCRtm1fkMhiZC8tD66M10vJHGBT1JPP0Db6XwdoI0FyKvN0RGya+Iusw1h2tDeD53LwD2jtOOWBOZ1juYUyAvJxsw= SpamDiagnosticOutput: 1:99 SpamDiagnosticMetadata: NSPM X-Microsoft-Exchange-Diagnostics: 1; BLUPR0701MB1714; 7:job9nFVacAHumwv6m9YzqwYdxRnx6tKVZhBPjoDR8RC5MX/vgEqkMSNo/gcxcYcnip7NVtV2EUw/Co0ryaMNPeRZzIcu/V64vwIXvN3ln/4bLbr5JVzZk70k838FFxWKfW+g7P+yJqNvxrrkpom8qQ67qRXcPQnjUcqAIo8fyMn3604bQfElSL6/29LvDOeDUEWEarrZ6KFrjyJEoahzCjx1YFmJLy7M+Y+quY3rsmiGByjk/YWPhKFnipg3DrcxZReiuCy0G7pUkAI7zwD4aWQMJQ4mgiXpkjzhlocu95XkQQLb2Yn4mMKL3YLeCmvq3VwA96wwij1kVXuMG817fg== X-OriginatorOrg: caviumnetworks.com X-MS-Exchange-CrossTenant-OriginalArrivalTime: 05 May 2017 13:34:12.6091 (UTC) X-MS-Exchange-CrossTenant-FromEntityHeader: Hosted X-MS-Exchange-Transport-CrossTenantHeadersStamped: BLUPR0701MB1714 Subject: [dpdk-dev] [PATCH] eventdev: abstract ethdev HW capability to inject packets X-BeenThere: dev@dpdk.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: DPDK patches and discussions List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Fri, 05 May 2017 13:34:22 -0000 Some Ethdev Hardware is capable of injecting the events(Ethernet packets) to eventdev without the need for dedicated service cores on Rx path. Since eventdev API is device capability agnostic, we need to address three combinations of ethdev and eventdev PMD drivers. 1) Ethdev HW is not capable of injecting the packets and SW eventdev driver(All existing ethdev PMD + drivers/event/sw PMD combination) 2) Ethdev HW is not capable of injecting the packets and not compatible HW eventdev driver(All existing ethdev PMD + driver/event/octeontx PMD combination) 3) Ethdev HW is capable of injecting the packet to compatible HW eventdev driver. This patch abstract such capability disparity and have unified way to get the functionality in the application. NOTE: The same infrastructure can be used _if_ an SW PMD wish to create the default producer as service function with the service core scheme in EAL to make it completely transparent to the application for the default case. The selection of service core enablement can be a vdev argument to SW PMD. Detailed comments are added in the header file. Example API usage: - rte_eth_dev_configure(port,..); - rte_eth_rx_queue_setup(port,..); - rte_eth_dev_start(port,..); struct rte_event_queue_producer_conf ethdev_conf = { .event_type = RTE_EVENT_TYPE_ETHDEV; .sched_type = RTE_SCHED_TYPE_ATOMIC; .priority = RTE_EVENT_DEV_PRIORITY_LOWEST; .ethdev.ethdev_port = port; .ethdev.rx_queue_id = -1; }; - rte_event_dev_has_producer(dev_id, ðdev_conf); # configure additional producer ports based on eventdev producer capability. - rte_event_dev_configure(dev_id,..); struct rte_event_queue_conf = conf { nb_producers = 1; producers = ðdev_conf; }; # configure event queue based on eventdev producer capability - rte_event_queue_setup(dev_id, &conf,..); - rte_event_port_setup(dev_id,..); - rte_event_dev_start(dev_id); Signed-off-by: Jerin Jacob --- This patch is based on the review commets from following RFC http://dpdk.org/ml/archives/dev/2017-May/065176.html --- lib/librte_eventdev/rte_eventdev.h | 110 +++++++++++++++++++++++++++++++++++++ 1 file changed, 110 insertions(+) diff --git a/lib/librte_eventdev/rte_eventdev.h b/lib/librte_eventdev/rte_eventdev.h index 20e7293e0..202d03f61 100644 --- a/lib/librte_eventdev/rte_eventdev.h +++ b/lib/librte_eventdev/rte_eventdev.h @@ -396,6 +396,100 @@ struct rte_event_dev_info { int rte_event_dev_info_get(uint8_t dev_id, struct rte_event_dev_info *dev_info); +/** Eventdev producer configuration structure. + * The events are injected to event device through *enqueue* operation with + * op == RTE_EVENT_OP_NEW by event producers in the system. If the event + * producer is an Ethernet device then eventdev PMD may operate in conjunction + * with ethdev PMD to injects the events(Ethernet packets) to eventdev. + * The event injection can happen in HW or SW or the combination of these two + * based on the HW capabilities of target eventdev and ethdev PMDs. + * + * @see rte_event_dev_has_producer() rte_event_queue_setup() + * + */ +struct rte_event_dev_producer_conf { + uint32_t event_type:4; + /**< Event type to classify the event source. + * @see RTE_EVENT_TYPE_ETHDEV, (RTE_EVENT_TYPE_*) + */ + uint8_t sched_type:2; + /**< Scheduler synchronization type (RTE_SCHED_TYPE_*) + * associated with flow id on a given event queue for the enqueue + * operation. + */ + uint8_t priority; + /**< Event priority relative to other events in the + * event queue. The requested priority should in the + * range of [RTE_EVENT_DEV_PRIORITY_HIGHEST, + * RTE_EVENT_DEV_PRIORITY_LOWEST]. + * The implementation shall normalize the requested + * priority to supported priority value. + * Valid when the device has + * RTE_EVENT_DEV_CAP_EVENT_QOS capability. + */ + union { + struct rte_event_ethdev_producer { + uint16_t ethdev_port; + /**< The port identifier of the Ethernet device */ + int32_t rx_queue_id; + /**< The index of the receive queue from which to + * retrieve the input packets and inject to eventdev. + * The value -1 denotes all the Rx queues configured + * for the given ethdev_port are selected for retrieving + * the input packets and then injecting the + * events/packets to eventdev. + * The rte_eth_rx_burst() result is undefined + * if application invokes on bounded ethdev_port and + * rx_queue_id. + */ + } ethdev; /* RTE_EVENT_TYPE_ETHDEV */ + /**< Valid when event_type == RTE_EVENT_TYPE_ETHDEV. + * Implementation may use mbuff's rss->hash value as + * flow_id for the enqueue operation. + */ + }; +}; + +/** + * Check for eventdev producer capability for the given eventdev producer *conf* + * on an event device. + * + * When application needs to setup an event producer to inject the events to + * eventdev, application must check the event device producer capability by + * invoking this function, On success, application can configure to inject the + * events to eventdev by setting up the event queue using + * rte_event_queue_setup() with checked *conf*. + * On failure due to lack of adequate capability in PMD or an application that + * wish to inject the event through application, it must create additional + * event port by configuring the eventdev with rte_event_dev_config() and use + * rte_event_enqueue_burst() to inject the event through + * op == RTE_EVENT_OP_NEW operation. + * + * @param dev_id + * The identifier of the device. + * @param conf + * The eventdev producer configuration structure. + * + * @see rte_event_queue_setup() rte_event_dev_config() + * + * @return + * - TRUE (value different than 0) if the eventdev is capable of producing the + * events for the given *conf* + * - FALSE (value zero) if the eventdev is not capable of producing the events + * for the given *conf* + * + * PMD may have partial support for the requested capability. + * On return FALSE, PMD sets rte_errno to reflect the partial support. + * Possible rte_errno values include: + * - -EOPNOTSUPP: The eventdev is not capable of pulling the events from + * the specific producer queue. On this errno, The caller may try to + * check the capability with rx_queue_id as -1 in *conf*. + * + */ +int +rte_event_dev_has_producer(uint8_t dev_id, + struct rte_event_dev_producer_conf *conf); + /* Event device configuration bitmap flags */ #define RTE_EVENT_DEV_CFG_PER_DEQUEUE_TIMEOUT (1ULL << 0) /**< Override the global *dequeue_timeout_ns* and use per dequeue timeout in ns. @@ -545,6 +639,19 @@ struct rte_event_queue_conf { * event device supported priority value. * Valid when the device has RTE_EVENT_DEV_CAP_QUEUE_QOS capability */ + uint16_t nb_producers; + /**< The number of producers to inject the events with operation as + * RTE_EVENT_OP_NEW to this event queue. + * + * @see rte_event_dev_producer_conf rte_event_dev_has_producer() + */ + struct rte_event_dev_producer_conf *producers; + /**< Points to an array of *nb_producers* objects of type + * *rte_event_dev_producer_conf* structure which contain + * event queue producers configuration information. + * + * @see rte_event_dev_has_producer() + */ }; /** @@ -590,6 +697,9 @@ rte_event_queue_default_conf_get(uint8_t dev_id, uint8_t queue_id, * @return * - 0: Success, event queue correctly set up. * - <0: event queue configuration failed + * - -EDQUOT: Quota exceeded(Application tried to configure the same producer + * on more than one event queue) + * - EOPNOTSUPP: Unsupported producer(s) in *producers* array. */ int rte_event_queue_setup(uint8_t dev_id, uint8_t queue_id, -- 2.12.2