From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from NAM01-BY2-obe.outbound.protection.outlook.com (mail-by2nam01on0050.outbound.protection.outlook.com [104.47.34.50]) by dpdk.org (Postfix) with ESMTP id 40F831C00 for ; Tue, 12 Dec 2017 08:07:31 +0100 (CET) Received: from CY1PR03CA0014.namprd03.prod.outlook.com (10.174.128.24) by MWHPR03MB2701.namprd03.prod.outlook.com (10.168.207.135) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384_P256) id 15.20.302.9; Tue, 12 Dec 2017 07:07:29 +0000 Received: from BY2FFO11FD010.protection.gbl (2a01:111:f400:7c0c::197) by CY1PR03CA0014.outlook.office365.com (2603:10b6:600::24) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384) id 15.20.302.9 via Frontend Transport; Tue, 12 Dec 2017 07:07:29 +0000 Authentication-Results: spf=fail (sender IP is 192.88.168.50) smtp.mailfrom=nxp.com; 6wind.com; dkim=none (message not signed) header.d=none;6wind.com; dmarc=fail action=none header.from=nxp.com; Received-SPF: Fail (protection.outlook.com: domain of nxp.com does not designate 192.88.168.50 as permitted sender) receiver=protection.outlook.com; client-ip=192.88.168.50; helo=tx30smr01.am.freescale.net; Received: from tx30smr01.am.freescale.net (192.88.168.50) by BY2FFO11FD010.mail.protection.outlook.com (10.1.14.74) with Microsoft SMTP Server (version=TLS1_0, cipher=TLS_RSA_WITH_AES_256_CBC_SHA) id 15.20.282.5 via Frontend Transport; Tue, 12 Dec 2017 07:07:23 +0000 Received: from [10.232.14.39] ([10.232.14.39]) by tx30smr01.am.freescale.net (8.14.3/8.14.0) with ESMTP id vBC77Q2D010935; Tue, 12 Dec 2017 00:07:27 -0700 To: =?UTF-8?Q?Ga=c3=abtan_Rivet?= CC: References: <91106540c460d22dd23a30dc2903d7e238ff9a3b.1507796085.git.gaetan.rivet@6wind.com> <088de7d2-9bd4-4a49-44ba-9df9c52b72d1@nxp.com> <20171211124359.zhyeaveywobmobef@bidouze.vm.6wind.com> <665f56dc-3cd5-e199-59b5-2021facd0bba@nxp.com> <20171211143819.hxgyhnxiiwlegjbw@bidouze.vm.6wind.com> From: Shreyansh Jain Message-ID: Date: Tue, 12 Dec 2017 12:51:02 +0530 User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:52.0) Gecko/20100101 Thunderbird/52.5.0 MIME-Version: 1.0 In-Reply-To: <20171211143819.hxgyhnxiiwlegjbw@bidouze.vm.6wind.com> Content-Type: text/plain; charset="utf-8"; format=flowed Content-Language: en-US Content-Transfer-Encoding: 8bit X-EOPAttributedMessage: 0 X-Matching-Connectors: 131575360436817655; (91ab9b29-cfa4-454e-5278-08d120cd25b8); () X-Forefront-Antispam-Report: CIP:192.88.168.50; IPV:NLI; CTRY:US; EFV:NLI; SFV:NSPM; SFS:(10009020)(336005)(376002)(346002)(39860400002)(39380400002)(2980300002)(1109001)(1110001)(339900001)(51444003)(24454002)(199004)(189003)(59450400001)(65956001)(65806001)(81166006)(81156014)(6666003)(8676002)(316002)(6916009)(77096006)(58126008)(5660300001)(86362001)(229853002)(31696002)(65826007)(4326008)(64126003)(305945005)(50466002)(2950100002)(47776003)(53936002)(93886005)(6246003)(2486003)(23676004)(2906002)(8936002)(97736004)(76176011)(356003)(67846002)(85426001)(83506002)(31686004)(2870700001)(68736007)(36756003)(498600001)(105606002)(106466001)(104016004)(21314002); DIR:OUT; SFP:1101; SCL:1; SRVR:MWHPR03MB2701; H:tx30smr01.am.freescale.net; FPR:; SPF:Fail; PTR:InfoDomainNonexistent; A:1; MX:1; LANG:en; X-Microsoft-Exchange-Diagnostics: 1; BY2FFO11FD010; 1:3gjdQtei2mJ37zeuiwynPmQqj0YsB24wPsShNmhKRSHaAf3dUfLBl0KOtYw5bRlKvK7zJm09cCnTRJLGHrDyohR/qIyi/qTCXkpauCIGW5od/a5WdnKwsOpxJNuV6K66 X-MS-PublicTrafficType: Email X-MS-Office365-Filtering-Correlation-Id: ecdf8b94-2eea-4773-cef7-08d5412efe7e X-Microsoft-Antispam: UriScan:; BCL:0; PCL:0; RULEID:(4534020)(4628075)(201703131517081)(5600026)(4604075)(2017052603307); SRVR:MWHPR03MB2701; X-Microsoft-Exchange-Diagnostics: 1; MWHPR03MB2701; 3:V3h8Zof7ob2JGGkg0rj2+Xnv4dADi96Uj9oMPf6X66E3MS58WAue6CzjCBEqpww0naLiB6YBTYWDi5sbMmbDEtBLTLgNqUT34r6LMT9j1jglgfvdmvoq1q5woWHjh+dXCSBAc0WTg/pAdAfjkfDx4Vihb7+nhk53mQ0N7XFfwWaoDa+TLjoTVpX0F01MLR5J61yHbkdEXo3NKzoj3QScNuUbThyUgHFC90YkvmXOeQYlaXs6lhVWUmgzNFF2qx5Lt4sbIBaGBOy07cypEFR5sj00I2UYokEDWDbdN5qejYF13z2ZhA0xgG6GbK2oa1DgKxbDtvM4wbxgZt54yOHBLioh5V/3E0bHdwQZLQZr4cQ=; 25:uQTYQyjpZxre9RRPTwsK6Q7QSR2/f2Gi6RGCW5VJ/JnzFvWtAZGvaH2pXTIDu8yA7Fnt3jrmSyZomSe9F4uPWNR/H0IJ10whsd+Igcf5zZAo9d34IFKasLiIHa2OLK2zcYQV5TnmaF9c5nyZFiT9TqAUhZsHgI25Pj60Z/ZJrKgujrF7QF5VRWitRZ51/NHsbVs3x1gOXmEB0926GHxrGawusWCQrvPR1uIvsMCAeDwahDl5gSYLngbEJhJPxwlSjefWczIkMeJXfd/0+XUAU4aYmswW9LpubEDELEJ4L+WMq97Xae/0fWz+6D6viDsoAQPGNiuAR8zyp52mjJtWlw== X-MS-TrafficTypeDiagnostic: MWHPR03MB2701: X-Microsoft-Exchange-Diagnostics: 1; MWHPR03MB2701; 31:iLr6r0RSoQXRNm663TCeAA66QQdxs62B5XyJKaadiuz9prFrmMGiYLohyVCNGeBAA34QD8s/bGa4U+T2j2yTjiMT8jJtTVUN6IETaw5N/eJah+zSO6lkGD3AcjmpYWPRZp36XGZ8a2Uze2fEsl6Q/2RsWZbuOZjrmQZ2QEDKUhsrtZjjrZZdc8elg9bACnKonGcnNVH5uR3/L1O8YdG5W/aFwER3oa0ziFwFNgF74fQ=; 4:MrKRGs/ynoM1pktdzxe6Y4Pmb0h8sF5/2McIw1S4IJIUGRZKuX8NtPM6/x196EPY6VCEAuWypBtzRuCqet+L0rAtPnFXzzcJM1Uf0W0uTeI6sUaClzCSliVXFrZTvOruqqRKH86gyuzvd5rd7qJdIDRZH061v9KAMiwUQZ0bE4G90yjloN10oq/bECKSGd03LO3sGsjmr6oM/S10j9sNdEeiH2gtljQfRrL+e2wwTipgNziL6QmK8hjTL1ZaCEwWcA5/PgfUpGaHiPKA1FRSYue4DLIPIEFRTyDqUozzpg75h2quZ2hrUdVvCbTja+95 X-Microsoft-Antispam-PRVS: X-Exchange-Antispam-Report-Test: UriScan:(278428928389397); X-Exchange-Antispam-Report-CFA-Test: BCL:0; PCL:0; RULEID:(6095135)(2401047)(5005006)(8121501046)(3002001)(3231023)(93006095)(93001095)(10201501046)(6055026)(6096035)(20161123565025)(20161123556025)(20161123559100)(20161123561025)(201703131430075)(201703131433075)(201703131448075)(201703161259150)(201703151042153)(20161123563025)(201708071742011); SRVR:MWHPR03MB2701; BCL:0; PCL:0; RULEID:(100000803101)(100110400095)(400006); SRVR:MWHPR03MB2701; X-Forefront-PRVS: 051900244E X-Microsoft-Exchange-Diagnostics: =?utf-8?B?MTtNV0hQUjAzTUIyNzAxOzIzOmZnSFRacEJTVGJOdGM4UFd5eEVVY2V3bzFY?= =?utf-8?B?cWE5Vk80QzR6RUV5MjNaZVhvVlV5OHBvaHFnNlE2dERFVzIrLzRONUVzUCtV?= =?utf-8?B?Z2RKUnhicnZkMng4MjVxVGo2dXdsbS94Z21FVzlNOUQ1czBwODZCREszR2tj?= =?utf-8?B?VmJibm1uZnpiSGR6QVlNNHU3ZDBkTjQ2cXJBaUN5TGhVWmJPQmg4bnMzYjJ6?= =?utf-8?B?WTZic1BsK2NESlNxNkU4RUNjNjJJL2RUdVEzakNZdDRwRExNeHZSOHpEMXlh?= =?utf-8?B?c0dHencxQnJDOEVyWW1pZ2hsRmttRGV1dXV0Nk9IdmF4TjJxZUpyRThSc0Zp?= =?utf-8?B?MHhUUElmZlVrZmFrY3N0UFE3ZzZUcjd6bzFVVmN2c21hSm5YVGdSMUttSEdx?= =?utf-8?B?clpqQXp4SGRtMCsvZ0ZkbnZwYkdBb0tFakxSTldPeCt6eG5JQ01FSE1MdkRT?= =?utf-8?B?RUwvN3hWUFZOMnNyOXZzdUw1akQxaWdsYkttR3c4ZkNrRGpLV1hVWkVsVGN5?= =?utf-8?B?NnY3OG9Wc0R4d3J5VEcycjF2WkNacTMrc3BVNk1wYWJNTU9odkZiSk03b2cv?= =?utf-8?B?b2FuQm93Q0NnWjNHL2dvSXlsaTlGaGNTcDZhaUNmWDBwN0ZWUUNRWUxpRXZW?= =?utf-8?B?VHR6dVI3VDkwM2dZZHdORzA1cVU5T09OWUdzZnNVUUpCUG5vMHhCTnNUaFJT?= =?utf-8?B?QW5WYVBBUGoycnhMckJEa1MwVXVpc0x4anpYTXRpbjVYMzByUEo3bEFoZ2xM?= =?utf-8?B?Z0MrczhuTDJZcTY0OWxvdlRTa2VUaWRiak02UE4wTVRKSk1Uak4yZmpFTGRM?= =?utf-8?B?ZGFCYlRZaTZHSzR0ajRodnRNa1BhYVJXcFBUZXNJRmNORE4xTi9FUEF1ck56?= =?utf-8?B?Y3RJNERBVmswMWtwVzQrQ0R5c2ZQOHU2eVcwei9KK1AyZk0vMWNsVktNaFh5?= =?utf-8?B?alBNeExORklzRGFVTGxvKzFxMW9yeHNZM3ZtVjdGVEhPZmRNY2hQNWNnMURy?= =?utf-8?B?a0c0N0kvdkg1TmNaR0MxaDkwdnNLZW9WMStvR3lybktGZmNhU0ZzZGNuMDY1?= =?utf-8?B?dWYzYXErVXZ3ZmJXZUYrYnd2TXJ2MHRzRmhBNWVEMWFFcGVIbllCTnFLQzBh?= =?utf-8?B?R0RTZWpoV2gvYTBkanpBNDdYZDAxcy9QRXBINGNKN3lia3NOS0J2d2NUcFFo?= =?utf-8?B?eVZkUHFCdk15Z1gvZmNRbFNtTTVYSUFmdHVJZzNwUmJyNkFsWmZlaC9jeVBF?= =?utf-8?B?bUxIRitOeXIrVXJsTjkrZzBuMWI4Vmh0VkJMUTRNcXRIa1hHelhwWVMxeHlE?= =?utf-8?B?ZzYrQXl4cHlSMkFtcTY4RXA3MHdOKzVjT05LenlwTGpaN3ROZ2NtYjFNVlRt?= =?utf-8?B?RVkwWmRBYWQ0aWRuL0szT29JeWc2TkRPU1RobTRFS3VlSlNydktFM1doaDgw?= =?utf-8?B?RVZJallMdTJSUTRXTnZwWFJ1cm5GcXhHZllueHE1THJ4TU14M3NhanVCditi?= =?utf-8?B?eEhpK0ZlT2dBdFc1OFcvUE5KOVcxaFgyL2NHbG5UWVJDSWxlblZTTU1zYWRm?= =?utf-8?B?SmI0cGREU1ZHWTVVTlFYaU9aNHo3Qjl2c3VsSlhHY2hHN2NlaXRta3gwZmw4?= =?utf-8?B?RHRFMk80S3FnMDk3TWpZUzhQWUZIMU9OMkQwbnNlVk5pQVR6OENMTitpNjdx?= =?utf-8?B?Ky9FTWpHb0pwMjZlZ1EyU3BKTHdITFlDclJ6SUxQTFJnSVlrL1ZQdm5RVlBW?= =?utf-8?B?TXFmSkdjaFlrWlg2dGFvS1FMem5WTFl2NWFXd2FxWWIzUG1JTVd3ZDBwc2pG?= =?utf-8?Q?QXLFBhmGhl1LF?= X-Microsoft-Exchange-Diagnostics: 1; MWHPR03MB2701; 6:ptC+QyLM7GLEtaHmjo0i5rekbveu8RkqD+gDMcasumaqw54VlQdUZig+S8ZB8LWtKpG99KN1f6Uvz50t3LoOXF799bcI+/G43yimqNSliqeoz/66uBBdK/Xfg3x6ZI0aROSKT14anSSd8EwJ/XRUuZqqni3ILTHNHTBLEEMBgt27zrYyMpz0lmMrAfSzbkMnQkubqUXbudkFjnCgCIcmV+byWpin0eMuKfYgRwsYhdRx3qdQe765x/zhNWsGtuOeEkNPUrRROi+sv0PeFgdQQ6896mn9XR1IJBjdg3Uutx0w/lVh09bDPY8K1ixTNOoYeEVtefei3JTNLXtZ14WRRBs/jyuyxwZUtXBAWL8EVhc=; 5:xrnhOr/O5IUMF52K1DJOS4akPSkrqk7X1+QLtKMMae6F/R7kuDrx97nU+QjaV/VQ6ORLuRM2Pwc8tv2BJgkRQ+FnhAxmEu3Y9j1nypNgEnjRKfUyY6n/hKe9NRXBCzYCmSimwNTMMdjJ3JVTJVgAgDmqTdVmLNQVObHP8jmtz6c=; 24:0SlD9OalY24Ob1Jkbe7nhRrr79Gjea4SO6fjuTrXChEkugSHp0fVm6sU66vfvePttJCRB6YRNgPuPvHmcJtUmYTbuQHviRwVnBtjyfGnWE8=; 7:FA2X49doHD7Le/il72oOiY7Lc/fHnQbLpmGN1iM8XKWJRY6gRofAepCgNE9K1rbxdlTa9+5G9xuWGOrqZ3IHNjzg4Ly22v3SL2e/i9TDC5kIDUfCiLexM78yZTvERrc79q+V6FbS0wvezB4O/vrROON63k6YgA4sAqjY6cyipLJ/w+V0nz5AV1aI8dguRsg+DQhdR8vWRkazJfIuMwVT6l2Kb/cGnW7nE9xnq/edLqtHuVDKhjjksKLwK2Bimn/r SpamDiagnosticOutput: 1:99 SpamDiagnosticMetadata: NSPM X-MS-Exchange-CrossTenant-OriginalArrivalTime: 12 Dec 2017 07:07:23.4789 (UTC) X-MS-Exchange-CrossTenant-Network-Message-Id: ecdf8b94-2eea-4773-cef7-08d5412efe7e X-MS-Exchange-CrossTenant-Id: 5afe0b00-7697-4969-b663-5eab37d5f47e X-MS-Exchange-CrossTenant-OriginalAttributedTenantConnectingIp: TenantId=5afe0b00-7697-4969-b663-5eab37d5f47e; Ip=[192.88.168.50]; Helo=[tx30smr01.am.freescale.net] X-MS-Exchange-CrossTenant-FromEntityHeader: HybridOnPrem X-MS-Exchange-Transport-CrossTenantHeadersStamped: MWHPR03MB2701 Subject: Re: [dpdk-dev] [PATCH v1 2/8] bus: introduce opaque control framework 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: Tue, 12 Dec 2017 07:07:31 -0000 On Monday 11 December 2017 08:08 PM, Gaëtan Rivet wrote: > On Mon, Dec 11, 2017 at 07:06:55PM +0530, Shreyansh Jain wrote: >> On Monday 11 December 2017 06:13 PM, Gaëtan Rivet wrote: >>> On Mon, Dec 11, 2017 at 05:30:16PM +0530, Shreyansh Jain wrote: >>>> On Thursday 12 October 2017 01:48 PM, Gaetan Rivet wrote: >> >> [...] >> >>>>> diff --git a/lib/librte_eal/common/include/rte_bus.h b/lib/librte_eal/common/include/rte_bus.h >>>>> index 331d954..bd3c28e 100644 >>>>> --- a/lib/librte_eal/common/include/rte_bus.h >>>>> +++ b/lib/librte_eal/common/include/rte_bus.h >>>>> @@ -183,6 +183,51 @@ struct rte_bus_conf { >>>>> enum rte_bus_probe_mode probe_mode; /**< Probe policy. */ >>>>> }; >>>>> +/** >>>>> + * Bus configuration items. >>>>> + */ >>>>> +enum rte_bus_ctrl_item { >>>>> + RTE_BUS_CTRL_PROBE_MODE = 0, >>>>> + RTE_BUS_CTRL_ITEM_MAX, >>>>> +}; >>>> >>>> I am assuming that a driver implementation can take more than ITEM_MAX >>>> control knobs. It is opaque to the library. Are we on same page? >>>> >>>> For example, a bus driver can implement: >>>> >>>> rte_bus_XXX_ctrl_item { >>>> >>>> RTE_BUS_XYZ_KNOB_1 = 100, >>>> RTE_BUS_XYZ_KNOB_2, >>>> RTE_BUS_XYZ_KNOB_3, >>>> }; >>>> >>>> without the library knowing or restricting the API to RTE_BUS_CTRL_ITEM_MAX. >>>> >>>> I see that in your code for PCI (Patch 5/8: pci_ctrl) you have restricted >>>> the control knob to RTE_BUS_CTRL_ITEM_MAX. >>>> I hope that such restrictions would not float to library layer. >>>> >>>> If we are on same page, should this be documented as a code comment >>>> somewhere? >>>> if not, do you think what I am stating makes sense? >>>> >>> >>> I see what you mean, but I'm not sure it would be a good thing. >>> Actually, I think proposing this ITEM_MAX was a mistake. >>> >>> Regarding the specific bus knobs: >>> >>> - If a single bus needs this knob, then it would be better for the dev >>> to add it as part of the bus' public API, following the correct >>> library versioning processes. This would not break this bus control >>> structure ABI. >> >> Sorry, but can you elaborate on "...add it as part of bus' public API"? >> >> This is what I had in mind: >> >> ctrl_fn = rte_bus_control_get(busname, RTE_BUS_XYZ_KNOB_1); >> >> (unlike specific functions like probe_mode_get/set and iova_mode_get/set) >> >> Where ctrl_fn would then point to a method specific to bus for KNOB_1 >> configuration parameter. >> Thereafter, ctrl_fn(KNOB_1, void *arg). >> >> What other public API method are you hinting at? >> >> > > I was thinking that buses would simply expose a function > > rte_busname_xyz_knob1(void *arg); Yes, that is possible but only for cases where some very specific functionality needs to be exposed which is not expected to be generalized ever. > > as part of their public API. This would not require an ABI break for > this bus, as it would only be an API extension and would not use > callbacks within the bus structure. Yes, agree with your point. As such APIs are outside control of DPDK framework, they are something which will never impact the library layer. > > Thus, I think that for buses tempted to propose a specific API, this would be > the cleanest way. > > The bus proposing it as part of a custom control section would only be > interesting when the operation is expected to become a standard API for > other buses but was not yet accepted. Applications would be able to use > the interface and the ITEM could be added later. But I doubt this is > encouraging best practices as far as API evolution go. So, technically both are feasible: 1) having a bus specific API like rte_busname_xyz_knob1 and 2) expanding OPS with bus specific values and allowing application to use them. But, in either case, if the APIs can be generalized and/or can be used by multiple buses, they can definitely be moved into the library API (e.g. rte_bus_probe_mode_set) and/or can be added to rte_bus_ctrl_item. To summarize, I am OK with your approach. > >>> >>> - If more than one bus implement this knob, then it should be proposed >>> as part of the library API. Buses adding this new knob would break >>> their ABI, other buses would be left untouched. >> >> Agree, if more than one bus implements same operation. >> >>> >>> This makes me realize that proposing this ITEM_MAX value is not good to >>> the intended purpose of this patchset: >>> >>> - If a bus implementation use a reference to ITEM_MAX, then the control >>> structure ABI would be broken by any new control knob added, even if the >>> bus does not implement it. Granted, it would not break the driver >>> structure itself, but still. My PCI implementation is thus incorrect. >> >> Changes to enum wouldn't break ABI as far as I understand. Adding a new >> entry only expands it to a new declaration without impacting its size or >> signature. >> >>> >>> Therefore I think that it would be best to remove this ITEM_MAX altogether, >>> forcing bus developpers to use other ways that would not break their >>> ABIs every other release. >>> >> >> Removing ITEM_MAX is OK from my side. It doesn't serve much purpose. But, >> not for the "ABI break" reason. > > Adding the enum would not break ABI indeed, but I was thinking about the > way the bus control structure would be declared. > > However, upon second inspection on the my PCI implementation, I did not > actually use ITEM_MAX: > >> static rte_bus_ctrl_t pci_ctrl_ops[][RTE_BUS_CTRL_OP_MAX] = { >> » [RTE_BUS_CTRL_PROBE_MODE] = { >> » » [RTE_BUS_CTRL_GET] = pci_probe_mode_get, >> » » [RTE_BUS_CTRL_SET] = pci_probe_mode_set, >> » }, >> }; > > I just thought I had used RTE_BUS_CTRL_ITEM_MAX instead of RTE_BUS_CTRL_OP_MAX. > So my line of thought was simply that if any new item was declared, the control > structure would then change size. > > But I was mistaken, so that's actually not a problem :) > > Having ITEM_MAX available would still make those kind of mistakes > possible however. It might be better to prevent it completely by > removing it. This would however also prevent a custom control section. It might be a naive question, but, why do you think it would prevent a custom control section? Assuming that only RTE_BUS_CTRL_ITEM_MAX is not available (RTE_BUS_CTRL_OPS_MAX is available), Bus driver can still define: static rte_bus_ctrl_t pci_ctrl_ops[][RTE_BUS_CTRL_OP_MAX] = { [ITEM_1] = { {...}, {...}, }, [ITEM_2] = { {...}, {...}, }, [ITEM_NOT_IN_RTE_BUS.H] = { {...}, {...}, }, } (I know you disagree with third element of above definition - but somehow I feel it is a good addition for defining a knob which doesn't require an additional API call. Just assume as an example for now, please!) > > Do you think this would be useful enough to justify the slightly more > complex maintenance and review of bus implementations? > Having RTE_BUS_CTRL_ITEM_MAX is helpful if one has to iterate over all ctrl_items - but, that might never be required in my perception. Other than that, I don't have a strong reason to say that ITEM_MAX is required. Though, same is not true for OP_MAX - which is required for definitions like above.