From patchwork Tue Feb 22 10:58:09 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Shay Drori X-Patchwork-Id: 12754908 X-Patchwork-Delegate: kuba@kernel.org Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id A52B9C433F5 for ; Tue, 22 Feb 2022 11:07:46 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S231592AbiBVLIJ (ORCPT ); Tue, 22 Feb 2022 06:08:09 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:33958 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S229485AbiBVLIE (ORCPT ); Tue, 22 Feb 2022 06:08:04 -0500 Received: from NAM11-DM6-obe.outbound.protection.outlook.com (mail-dm6nam11on2068.outbound.protection.outlook.com [40.107.223.68]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id EE565B54EC; Tue, 22 Feb 2022 03:07:38 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; s=arcselector9901; d=microsoft.com; cv=none; b=LSxq21kr56ymOTjD3OZrspOc8Tu5eUsnN+dC3yfym2t7sAifTORpnfD8xdnaPfJvMIV5/EjSgWN+AeROnRI1wdXZaJnkAU+7lX1iahTkA+Ngv33Mec32WmqVbw9xkc/gYxH6Pc17NQy0zb3BlkCMFAZVlWDnQXKTtgQH/cF2QTuzGbOHP9ezd1vwMOJS4vn2gfOHdF4J7aGfL0CWMtCQV7V2Qs4qNv6ISYd4IARaEJWJ1PocWjIYjT6u11Uj1cNHNl66DtMAAsOkKxEZbwr+40bf3/yJ03NPubi6KmJvI+Zp4x5+CFp7033b5V1Zgg1+0P22/fTR4gcKi+w+2sdbnw== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=microsoft.com; s=arcselector9901; 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=sOMFDq4QE6VORqebDv2FV/10xjOx8JvCW+nDUBQjRz4=; b=lQ3zoPNh0nTTE3W9lVV2uKH5wqUBljCVV8O7phnDC2fjpSx6gOlHIYNhBvy3jZWhe5EiwqVs09b3DUrq8RYJr1dkAdAxz0rYZJ2Bg778WnXRKv1hI1zaUL6onD9xyVaOVz3Mx55Uv9cTzRoHAAHopsSAhsK4j8zl80/s7CaTOqgsHvOd4QQLBUNndwigEM/ejoEbtPz4eQrofyE2fc0hLi0+Js1EqfkqjXwc7oxt+WsGbrMJDIU1qgNH/9pA9RQLBZ7B+3KsIypcqJg3QDhK9VNXErj3ry/8L1KizdL25xAqaYDFwZyqJnhpYRt8ISH5qb9tEXiiDgr+ed1djbz8mA== ARC-Authentication-Results: i=1; mx.microsoft.com 1; spf=pass smtp.mailfrom=nvidia.com; dmarc=pass action=none header.from=nvidia.com; dkim=pass header.d=nvidia.com; arc=none DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=Nvidia.com; s=selector2; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck; bh=sOMFDq4QE6VORqebDv2FV/10xjOx8JvCW+nDUBQjRz4=; b=uSF332aLGdvPHKxM5/VATROGm1bdy9DxHHoqvAGwGUyUEt0Tng9AeC7yNGkMSYxGmk+Kg6NxfH2yRQHZp/YftRi5vhPER/R311e9s/vsQJ4wctvEzZgSc3ZPUehm0OO/L/U85+vNKcSFRxL15h3RA+wcqawipY7QRqY/lr49xqV/LfQJ6faH3yJPSlNY+WlmffSlsj98ev5nhem/JBPbkCQ56+JkRdXXCf5xLmuM9+62En10jgZpW0MlVZ5EC+pTjmJFCghzr5uBVfpJxQMUJTtEU4QSQQ04V2E48EjXXoviEJ/B1GXYqH8qqNA6DIIsq3iLJv8oldYiDGYFz7VXrQ== Authentication-Results: dkim=none (message not signed) header.d=none;dmarc=none action=none header.from=nvidia.com; Received: from MWHPR12MB1310.namprd12.prod.outlook.com (2603:10b6:300:a::21) by MW5PR12MB5683.namprd12.prod.outlook.com (2603:10b6:303:1a0::10) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.4995.26; Tue, 22 Feb 2022 11:07:37 +0000 Received: from MWHPR12MB1310.namprd12.prod.outlook.com ([fe80::5165:db44:70d5:1c2a]) by MWHPR12MB1310.namprd12.prod.outlook.com ([fe80::5165:db44:70d5:1c2a%11]) with mapi id 15.20.4995.027; Tue, 22 Feb 2022 11:07:37 +0000 From: Shay Drory To: "David S . Miller" , Jakub Kicinski Cc: jiri@nvidia.com, saeedm@nvidia.com, parav@nvidia.com, netdev@vger.kernel.org, linux-kernel@vger.kernel.org, Shay Drory , Moshe Shemesh Subject: [PATCH net-next 1/4] net netlink: Introduce NLA_BITFIELD type Date: Tue, 22 Feb 2022 12:58:09 +0200 Message-Id: <20220222105812.18668-2-shayd@nvidia.com> X-Mailer: git-send-email 2.21.3 In-Reply-To: <20220222105812.18668-1-shayd@nvidia.com> References: <20220222105812.18668-1-shayd@nvidia.com> X-ClientProxiedBy: AM5PR0201CA0002.eurprd02.prod.outlook.com (2603:10a6:203:3d::12) To MWHPR12MB1310.namprd12.prod.outlook.com (2603:10b6:300:a::21) MIME-Version: 1.0 X-MS-PublicTrafficType: Email X-MS-Office365-Filtering-Correlation-Id: ffb0d4c1-9d0c-46fb-c2ee-08d9f5f388cb X-MS-TrafficTypeDiagnostic: MW5PR12MB5683:EE_ X-Microsoft-Antispam-PRVS: X-MS-Exchange-SenderADCheck: 1 X-MS-Exchange-AntiSpam-Relay: 0 X-Microsoft-Antispam: BCL:0; X-Microsoft-Antispam-Message-Info: Ct7omhR6+XdoQZTmBJCRj96sP34W5DdU3tMDVwr5D+ACx6+xoU5BziEh9pRf9EJTNczxlKctKawkRgyHFYCG9BFdE+u4tNi/J0GORynB7ewOxrN6ovzvbi06KLT0qqoH0djsRrpp6jOLaPFZhGj6VF4WZfWerYq984mcw/wNXYVS2uPz2nKsaKPnbsAPEv4MxoXAM2HX1mQSHU4jvAbeax0pCrxxY5Lj8wjuMSRFL+rjTLmW16swHNyK75QP+b3m0jOxurPyFAES6OqgC8v+JqgKGPel5brf6KteEcmuDp1F/sAti/kvmuvVpYmSnqpx8wG6dVt/OJJ6tyy43J5i+5klwMLK6RNpmL+fq1V+9AHAaFTlL/FDRFGvYWy2R27863eCNEcMnnFhmLEUdgIAmGp8Lfo1+9SMMjiYLdf3WJU1O//eEWxkxaEVbWEKo06QYgVztn1JbOy7d1ULa5MHg398JiwjCiLvyhZUa2RLYLrl0gXyjWOgLAuhVRtXK6r/OThIIW9DotercDrUrBvQldDyamVsNaPJ4cH/ef3YUbBqlSoDqN14NmdV/7OeMrFG3dHnM4nGCMuSOwKI+b2AgAq6yzWdWyWfudQDFyZDvh6lYTvWW1UnLqy3fqARWu7IyAUaDVZGEH80RlLBR2u4b9dXNAMMIAppBP4uaOCQjvp111ftrBj8bs7C7FfttPskGuxNF1cuqvQOy6ppw1tEwQ== X-Forefront-Antispam-Report: CIP:255.255.255.255;CTRY:;LANG:en;SCL:1;SRV:;IPV:NLI;SFV:NSPM;H:MWHPR12MB1310.namprd12.prod.outlook.com;PTR:;CAT:NONE;SFS:(13230001)(4636009)(366004)(83380400001)(186003)(2616005)(1076003)(26005)(38350700002)(508600001)(8936002)(38100700002)(2906002)(36756003)(107886003)(86362001)(52116002)(4326008)(6486002)(66556008)(66476007)(5660300002)(30864003)(6666004)(54906003)(8676002)(316002)(66946007)(110136005)(6506007)(6512007);DIR:OUT;SFP:1101; X-MS-Exchange-AntiSpam-MessageData-ChunkCount: 1 X-MS-Exchange-AntiSpam-MessageData-0: GtPE+L8jAqA5hHygU01CaJNFlWCVvXYTCQfwTIz1moGwtXE/h1eW/pGqTSUt8/rdL0mZjjBiofcrHxd+upnB3RJeW4cJ0XjYVZ3Y6IBU8WFW23KncZm5Yrqb+zXqMuAaWiLDwAxRIZD3l5r/H9NGmLrABnpRNu+x+GKQo/Im1Tu4lqFQyRtTnYGR1BXj36hRSDrzGbDSU3k2BwBD7mzEBwEH1LEme/0dUBDgmaEkTd1WSQqDYJuD++iEOJvtvByOEaF0BnBMkMK6Tq4CZSIyaNDrbtSr0tcUhZnV6vjonbe0r+QC/Uu44tuTO45B+evcJCE/VOH7O+DhrZPWqOsqy4FSwj3L1MBUHYceo+s8x4WlFN5gP0Qml2f8BPFMHpHYFKYVxF7X+Y6K3pSl+b0UhhkPU1j/noZEmzU3I/svSAC4waqnokusY/0XuVCRAtd2u8W6dHAcYeybWwqvCHw0uaduVA6tR8WVwTJsnvmc6D49XMf9neRA4vw9WGpmhfLfxTkE8k+FgQz94FYc+ZaymzwglERfaGGlVkmn0OcTSOB/2EWV7gr5Wj4hI1kLcke2kRZFB8YKuDwLeIOdyw8SBZBayKYXPiTHpTywuJXfZ6n9dUH3EbN2UMxIyx07CkNzsR1fQFref7jXDnamwiaGGj4YS55oPIXf5gNhq5kv3a4eYZvaJpsm5YjP4dCrB8ogL626RZ9BKqFpyyS5hzwNwXwAwT6hBl6C5rY+F1m7SrkxI2RVMba896soccKthIxMLMJwsguSZu83AXPIYfwVPcKtEPTWgSaJ1SA7lzuSOLe646XV23Keu1pLZapxQmN6h4khijQ0RqYKuXVxKLlcDq2IDmQ4wTAuSixJsRQOrwVWJ+JRINAA5VZdwCFMFg/ZxB1mxIFTvn6S4kuEyQOkZ8NGjquem/FtDkmawOxdijpjDbecnDVQz/OjfGzZuHoyJZiPThDEKB5bCNph/wbhJjZC0G9ybrSBN1zI1SKkfbOziXnxzNvb40gXSXzmhMZ3aVnayEDXCBGoTPgTkdgXNsR+/5qnjCBUyMWKwYdTXjRSvm38FmszTdPzL02Sye2+JjYemhy4+XKpg3OCNJx04hcDRyvoAr2Ban8P2QXR7kE8avB+87Iw5QVI8qNhz4aNu1UEwOksn+z/iH0LaBttxRT+gJprAcLBTpjts5JkS6siQZyn7TYg96M8r33cPby8NteXmrhbrzMwbjFNejCam5KXyfPA7fxGg8k9TyYUuSHv/E5W8PBhscXyaymr7VV2MDZrRnCMQswnZgsUBnOZhNvov56HwWNVzUoL+R6B46cBV67mQghEvq/CQqvFHezX8q6CA3cfnL7+iFH4SV9XgMdVHAyiWm55sKvSOPYRN9x9gKene9jNMZTl1IMW1036z9TZsSk1dT/9yhpF1MAhUYRWU8HE6KDGcHtFVD13GQ8gqoozWome2YRek7wcbVwYKZDNTR+DX8b9hNZhJ4AamtguP/aF+QIhyJKnHevoAjxn2SCU6Y09DWtrr3PsEgQxa65BZGPQu1oe1y7kcL+ETslVSIpSGsnHPXP60vIN4lTU/01Y9uaRfe8seh5nbhQ8bn3Wxwz67Tm9MwbSNfHd4uohr4nYDWp2H5rC1KONfJs= X-OriginatorOrg: Nvidia.com X-MS-Exchange-CrossTenant-Network-Message-Id: ffb0d4c1-9d0c-46fb-c2ee-08d9f5f388cb X-MS-Exchange-CrossTenant-AuthSource: MWHPR12MB1310.namprd12.prod.outlook.com X-MS-Exchange-CrossTenant-AuthAs: Internal X-MS-Exchange-CrossTenant-OriginalArrivalTime: 22 Feb 2022 11:07:37.4298 (UTC) X-MS-Exchange-CrossTenant-FromEntityHeader: Hosted X-MS-Exchange-CrossTenant-Id: 43083d15-7273-40c1-b7db-39efd9ccc17a X-MS-Exchange-CrossTenant-MailboxType: HOSTED X-MS-Exchange-CrossTenant-UserPrincipalName: SnTD+cyFjugRa777PP/aAKX98xGzZJTn6dRwzZROrO6oKFsJkyK3P/yjolL6J+c0+HhOkiFBskWchDR9yts/zg== X-MS-Exchange-Transport-CrossTenantHeadersStamped: MW5PR12MB5683 Precedence: bulk List-ID: X-Mailing-List: netdev@vger.kernel.org X-Patchwork-Delegate: kuba@kernel.org Generic bitfield attribute content sent to the kernel by user. With this netlink attr type the user can either set or unset a bitmap in the kernel. This attribute is an extension (dynamic array) of NLA_BITFIELD32, and have similar checks and policies. Signed-off-by: Shay Drory Reviewed-by: Moshe Shemesh --- include/net/netlink.h | 30 ++++++++ include/uapi/linux/netlink.h | 10 +++ lib/nlattr.c | 145 ++++++++++++++++++++++++++++++++++- net/netlink/policy.c | 4 + 4 files changed, 185 insertions(+), 4 deletions(-) diff --git a/include/net/netlink.h b/include/net/netlink.h index 7a2a9d3144ba..52a0bcccae36 100644 --- a/include/net/netlink.h +++ b/include/net/netlink.h @@ -180,6 +180,7 @@ enum { NLA_S32, NLA_S64, NLA_BITFIELD32, + NLA_BITFIELD, NLA_REJECT, __NLA_TYPE_MAX, }; @@ -235,12 +236,16 @@ enum nla_policy_validation { * given type fits, using it verifies minimum length * just like "All other" * NLA_BITFIELD32 Unused + * NLA_BITFIELD Maximum length of attribute payload * NLA_REJECT Unused * All other Minimum length of attribute payload * * Meaning of validation union: * NLA_BITFIELD32 This is a 32-bit bitmap/bitselector attribute and * `bitfield32_valid' is the u32 value of valid flags + * NLA_BITFIELD This is a dynamic array of 32-bit bitmap/bitselector + * attribute and `arr_bitfield32_valid' is the u32 + * values array of valid flags. * NLA_REJECT This attribute is always rejected and `reject_message' * may point to a string to report as the error instead * of the generic one in extended ACK. @@ -318,6 +323,7 @@ struct nla_policy { u16 len; union { const u32 bitfield32_valid; + const u32 *arr_bitfield32_valid; const u32 mask; const char *reject_message; const struct nla_policy *nested_policy; @@ -363,6 +369,8 @@ struct nla_policy { _NLA_POLICY_NESTED_ARRAY(ARRAY_SIZE(policy) - 1, policy) #define NLA_POLICY_BITFIELD32(valid) \ { .type = NLA_BITFIELD32, .bitfield32_valid = valid } +#define NLA_POLICY_BITFIELD(valid, size) \ + { .type = NLA_BITFIELD, .arr_bitfield32_valid = valid, .len = size } #define __NLA_IS_UINT_TYPE(tp) \ (tp == NLA_U8 || tp == NLA_U16 || tp == NLA_U32 || tp == NLA_U64) @@ -1545,6 +1553,19 @@ static inline int nla_put_bitfield32(struct sk_buff *skb, int attrtype, return nla_put(skb, attrtype, sizeof(tmp), &tmp); } +/** + * nla_put_bitfield - Add a bitfield netlink attribute to a socket buffer + * @skb: socket buffer to add attribute to + * @attrtype: attribute type + * @bitfield: bitfield + */ +static inline int nla_put_bitfield(struct sk_buff *skb, int attrtype, + const struct nla_bitfield *bitfield) +{ + return nla_put(skb, attrtype, bitfield->size * sizeof(struct nla_bitfield32) + + sizeof(*bitfield), bitfield); +} + /** * nla_get_u32 - return payload of u32 attribute * @nla: u32 netlink attribute @@ -1738,6 +1759,15 @@ static inline struct nla_bitfield32 nla_get_bitfield32(const struct nlattr *nla) return tmp; } +struct nla_bitfield *nla_bitfield_alloc(__u64 nbits); +void nla_bitfield_free(struct nla_bitfield *bitfield); +void nla_bitfield_to_bitmap(unsigned long *bitmap, + struct nla_bitfield *bitfield); +void nla_bitfield_from_bitmap(struct nla_bitfield *bitfield, + unsigned long *bitmap, __u64 bitmap_nbits); +bool nla_bitfield_len_is_valid(struct nla_bitfield *bitfield, size_t user_len); +bool nla_bitfield_nbits_valid(struct nla_bitfield *bitfield, size_t nbits); + /** * nla_memdup - duplicate attribute memory (kmemdup) * @src: netlink attribute to duplicate from diff --git a/include/uapi/linux/netlink.h b/include/uapi/linux/netlink.h index 4c0cde075c27..a11bb91e3386 100644 --- a/include/uapi/linux/netlink.h +++ b/include/uapi/linux/netlink.h @@ -252,6 +252,14 @@ struct nla_bitfield32 { __u32 selector; }; +/* Generic bitmap attribute content sent to the kernel. + * The size is the number of elements in the array. + */ +struct nla_bitfield { + __u64 size; + struct nla_bitfield32 data[0]; +}; + /* * policy descriptions - it's specific to each family how this is used * Normally, it should be retrieved via a dump inside another attribute @@ -283,6 +291,7 @@ struct nla_bitfield32 { * entry has attributes again, the policy for those inner ones * and the corresponding maxtype may be specified. * @NL_ATTR_TYPE_BITFIELD32: &struct nla_bitfield32 attribute + * @NL_ATTR_TYPE_BITFIELD: &struct nla_bitfield attribute */ enum netlink_attribute_type { NL_ATTR_TYPE_INVALID, @@ -307,6 +316,7 @@ enum netlink_attribute_type { NL_ATTR_TYPE_NESTED_ARRAY, NL_ATTR_TYPE_BITFIELD32, + NL_ATTR_TYPE_BITFIELD, }; /** diff --git a/lib/nlattr.c b/lib/nlattr.c index 86029ad5ead4..6d20bf38850b 100644 --- a/lib/nlattr.c +++ b/lib/nlattr.c @@ -58,11 +58,9 @@ static int __nla_validate_parse(const struct nlattr *head, int len, int maxtype, struct netlink_ext_ack *extack, struct nlattr **tb, unsigned int depth); -static int validate_nla_bitfield32(const struct nlattr *nla, - const u32 valid_flags_mask) +static int validate_bitfield32(const struct nla_bitfield32 *bf, + const u32 valid_flags_mask) { - const struct nla_bitfield32 *bf = nla_data(nla); - if (!valid_flags_mask) return -EINVAL; @@ -81,6 +79,33 @@ static int validate_nla_bitfield32(const struct nlattr *nla, return 0; } +static int validate_nla_bitfield32(const struct nlattr *nla, + const u32 valid_flags_mask) +{ + const struct nla_bitfield32 *bf = nla_data(nla); + + return validate_bitfield32(bf, valid_flags_mask); +} + +static int validate_nla_bitfield(const struct nlattr *nla, + const u32 *valid_flags_masks, + const u16 nbits) +{ + struct nla_bitfield *bf = nla_data(nla); + int err; + int i; + + if (!nla_bitfield_len_is_valid(bf, nla_len(nla)) || + !nla_bitfield_nbits_valid(bf, nbits)) + return -EINVAL; + for (i = 0; i < bf->size; i++) { + err = validate_bitfield32(&bf->data[i], valid_flags_masks[i]); + if (err) + return err; + } + return 0; +} + static int nla_validate_array(const struct nlattr *head, int len, int maxtype, const struct nla_policy *policy, struct netlink_ext_ack *extack, @@ -422,6 +447,12 @@ static int validate_nla(const struct nlattr *nla, int maxtype, goto out_err; break; + case NLA_BITFIELD: + err = validate_nla_bitfield(nla, pt->arr_bitfield32_valid, pt->len); + if (err) + goto out_err; + break; + case NLA_NUL_STRING: if (pt->len) minlen = min_t(int, attrlen, pt->len + 1); @@ -839,6 +870,112 @@ int nla_strcmp(const struct nlattr *nla, const char *str) } EXPORT_SYMBOL(nla_strcmp); +/** + * nla_bitfield_alloc - Alloc struct nla_bitfield + * @nbits: number of bits to accommodate + */ +struct nla_bitfield *nla_bitfield_alloc(__u64 nbits) +{ + struct nla_bitfield *bitfield; + size_t bitfield_size; + size_t bitfield_len; + + bitfield_len = DIV_ROUND_UP(nbits, BITS_PER_TYPE(u32)); + bitfield_size = bitfield_len * sizeof(struct nla_bitfield32) + + sizeof(*bitfield); + bitfield = kzalloc(bitfield_size, GFP_KERNEL); + if (bitfield) + bitfield->size = bitfield_len; + return bitfield; +} +EXPORT_SYMBOL(nla_bitfield_alloc); + +/** + * nla_bitfield_free - Free struct nla_bitfield + * @bitfield: the bitfield to free + */ +void nla_bitfield_free(struct nla_bitfield *bitfield) +{ + kfree(bitfield); +} +EXPORT_SYMBOL(nla_bitfield_free); + +/** + * nla_bitfield_to_bitmap - Convert bitfield to bitmap + * @bitmap: bitmap to copy to (dst) + * @bitfield: bitfield to be copied (src) + */ +void nla_bitfield_to_bitmap(unsigned long *bitmap, + struct nla_bitfield *bitfield) +{ + int i, j; + u32 tmp; + + for (i = 0; i < bitfield->size; i++) { + tmp = bitfield->data[i].value & bitfield->data[i].selector; + for (j = 0; j < BITS_PER_TYPE(u32); j++) + if (tmp & (1 << j)) + set_bit(j + i * BITS_PER_TYPE(u32), bitmap); + } +} +EXPORT_SYMBOL(nla_bitfield_to_bitmap); + +/** + * nla_bitfield_from_bitmap - Convert bitmap to bitfield + * @bitfield: bitfield to copy to (dst) + * @bitmap: bitmap to be copied (src) + * @bitmap_nbits: len of bitmap + */ +void nla_bitfield_from_bitmap(struct nla_bitfield *bitfield, + unsigned long *bitmap, __u64 bitmap_nbits) +{ + long size; + int i, j; + + size = DIV_ROUND_UP(bitmap_nbits, BITS_PER_TYPE(u32)); + for (i = 0; i < size; i++) { + for (j = 0; j < min_t(__u64, bitmap_nbits, BITS_PER_TYPE(u32)); j++) + if (test_bit(j + i * BITS_PER_TYPE(u32), bitmap)) + bitfield->data[i].value |= 1 << j; + bitfield->data[i].selector = bitmap_nbits >= BITS_PER_TYPE(u32) ? + UINT_MAX : (1 << bitmap_nbits) - 1; + bitmap_nbits -= BITS_PER_TYPE(u32); + } +} +EXPORT_SYMBOL(nla_bitfield_from_bitmap); + +/** + * nla_bitfield_len_is_valid - validate the len of the bitfield + * @bitfield: bitfield to validate + * @user_len: len of the nla. + */ +bool nla_bitfield_len_is_valid(struct nla_bitfield *bitfield, size_t user_len) +{ + return !(user_len % sizeof(bitfield->data[0]) || + sizeof(bitfield->data[0]) * bitfield->size + + sizeof(*bitfield) != user_len); +} +EXPORT_SYMBOL(nla_bitfield_len_is_valid); + +/** + * nla_bitfield_nbits_valid - validate the len of the bitfield vs a given nbits + * @bitfield: bitfield to validate + * @nbits: number of bits the user wants to use. + */ +bool nla_bitfield_nbits_valid(struct nla_bitfield *bitfield, size_t nbits) +{ + u32 *last_value = &bitfield->data[bitfield->size - 1].value; + u32 last_bit; + + if (BITS_PER_TYPE(u32) * (bitfield->size - 1) > nbits) + return false; + + nbits -= BITS_PER_TYPE(u32) * (bitfield->size - 1); + last_bit = find_last_bit((unsigned long *)last_value, BITS_PER_TYPE(u32)); + return last_bit == BITS_PER_TYPE(u32) ? true : last_bit <= nbits - 1; +} +EXPORT_SYMBOL(nla_bitfield_nbits_valid); + #ifdef CONFIG_NET /** * __nla_reserve - reserve room for attribute on the skb diff --git a/net/netlink/policy.c b/net/netlink/policy.c index 8d7c900e27f4..c9fffb3b8045 100644 --- a/net/netlink/policy.c +++ b/net/netlink/policy.c @@ -227,6 +227,7 @@ int netlink_policy_dump_attr_size_estimate(const struct nla_policy *pt) case NLA_STRING: case NLA_NUL_STRING: case NLA_BINARY: + case NLA_BITFIELD: /* maximum is common, u32 min-length/max-length */ return common + 2 * nla_attr_size(sizeof(u32)); case NLA_FLAG: @@ -338,11 +339,14 @@ __netlink_policy_dump_write_attr(struct netlink_policy_dump_state *state, break; case NLA_STRING: case NLA_NUL_STRING: + case NLA_BITFIELD: case NLA_BINARY: if (pt->type == NLA_STRING) type = NL_ATTR_TYPE_STRING; else if (pt->type == NLA_NUL_STRING) type = NL_ATTR_TYPE_NUL_STRING; + else if (pt->type == NLA_BITFIELD) + type = NL_ATTR_TYPE_BITFIELD; else type = NL_ATTR_TYPE_BINARY; From patchwork Tue Feb 22 10:58:10 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Shay Drori X-Patchwork-Id: 12754907 X-Patchwork-Delegate: kuba@kernel.org Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id B3A6CC433EF for ; Tue, 22 Feb 2022 11:07:49 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S231573AbiBVLIL (ORCPT ); Tue, 22 Feb 2022 06:08:11 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:34112 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S231587AbiBVLIJ (ORCPT ); Tue, 22 Feb 2022 06:08:09 -0500 Received: from NAM10-BN7-obe.outbound.protection.outlook.com (mail-bn7nam10on2078.outbound.protection.outlook.com [40.107.92.78]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 1902CB6D01; Tue, 22 Feb 2022 03:07:43 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; s=arcselector9901; d=microsoft.com; cv=none; b=D3J9GIta6yMIXZQ3Vcq+9Vxdg2/tOxBFrfFHj9kfXparDtTItCSCrlqHdAfvRaCyBcTBMKXgeKkdVsSdMh0FQXzfrUU1VIQswPDAr9m14wujjtzyt6X618kgGNSu2PxmPC1dBoK3CLuHLZeFTlFdc2P0PWqmn2UNrJtYEjn3LuP9tkZM482yUnE4xrXuXaJqCH/ys/2isInl8JlXyzcyJgPfUm3wO9br8F384r24yGto+UKEHCX2T7ky/v6uyGm9Too8+OHq1k5VJTcJAAe1j5WO08JAlpwsuW046RqWD7zSiTfqtRL/e93jY+axX0F9h8+fC/SHJDm7X0EEzU4CKA== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=microsoft.com; s=arcselector9901; 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=rMJd7HpZsjDU4WSJBWmdc3agHDtbQz7Z3yngAULUUg8=; b=fYvsM6lG8aAsKiHrLBmaqRq12Wbq5XL87/IaWiR5FqJ3pUT8W+na8cV4zp//EOmKir84sR5kNpIV3EnGlXWczfH/0Pgl2oDiLJRHEfhcuymKnazc8flRGPLnqAZdPLx3ZwJ+OhR4BdWVg4auoWHSZ6qQr4Zh3ZGt6zzv1J8x/7QD9sCK8+3r6K+PbpWsAAj8ghcWT2bBsUwFw0oe3ok5OWPMzsk1vMVQ220UnJgclaUDvir8VSR8IobqO852cqfaEsLlhx2Qjt1RuqO/xqBcyk/lpYsRXtOWcAmaqaCUORja4IfWkMzRY3xRSM7UeKG0ClRZVGjAMmQ3AkbuT8adNg== ARC-Authentication-Results: i=1; mx.microsoft.com 1; spf=pass smtp.mailfrom=nvidia.com; dmarc=pass action=none header.from=nvidia.com; dkim=pass header.d=nvidia.com; arc=none DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=Nvidia.com; s=selector2; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck; bh=rMJd7HpZsjDU4WSJBWmdc3agHDtbQz7Z3yngAULUUg8=; b=AKQYM8AaMQAfSDhkA+6fGzJ8IsxPluB7egk3+o+jTDK4Hdoj9GJc0rc35maY8EXfYLWrjpsofN9d2UHJ08HvuCDQFUD7V2Cv9hy1dlTui7lFw1PjTzgOWGEUQSEsQghoKq8Ea03zS0VQ23esH/DAmZC6QxzdWgkZEGytVxyD5VRcgbJciPUAYI0U8TXSIkNweSEOHkAre5aJwVm6L/e4L3jCI5RxQqv2v58tsHY+R6XHOQngL4ytOl43bU5PEReUITnbc4u380LI2cvh8r245nx5Qjw0Xo7s5oUtQXVwg5o4blDei5iaqt4ST1N815bk0DTk1r0ZNFzyJVg+uMq6bw== Authentication-Results: dkim=none (message not signed) header.d=none;dmarc=none action=none header.from=nvidia.com; Received: from MWHPR12MB1310.namprd12.prod.outlook.com (2603:10b6:300:a::21) by DM6PR12MB5552.namprd12.prod.outlook.com (2603:10b6:5:1bd::20) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.5017.21; Tue, 22 Feb 2022 11:07:40 +0000 Received: from MWHPR12MB1310.namprd12.prod.outlook.com ([fe80::5165:db44:70d5:1c2a]) by MWHPR12MB1310.namprd12.prod.outlook.com ([fe80::5165:db44:70d5:1c2a%11]) with mapi id 15.20.4995.027; Tue, 22 Feb 2022 11:07:40 +0000 From: Shay Drory To: "David S . Miller" , Jakub Kicinski Cc: jiri@nvidia.com, saeedm@nvidia.com, parav@nvidia.com, netdev@vger.kernel.org, linux-kernel@vger.kernel.org, Shay Drory , Moshe Shemesh Subject: [PATCH net-next 2/4] devlink: Add support for NLA_BITFIELD for devlink param Date: Tue, 22 Feb 2022 12:58:10 +0200 Message-Id: <20220222105812.18668-3-shayd@nvidia.com> X-Mailer: git-send-email 2.21.3 In-Reply-To: <20220222105812.18668-1-shayd@nvidia.com> References: <20220222105812.18668-1-shayd@nvidia.com> X-ClientProxiedBy: AM5PR0201CA0002.eurprd02.prod.outlook.com (2603:10a6:203:3d::12) To MWHPR12MB1310.namprd12.prod.outlook.com (2603:10b6:300:a::21) MIME-Version: 1.0 X-MS-PublicTrafficType: Email X-MS-Office365-Filtering-Correlation-Id: e8669a79-eb9e-492e-e0cf-08d9f5f38a97 X-MS-TrafficTypeDiagnostic: DM6PR12MB5552:EE_ X-Microsoft-Antispam-PRVS: X-MS-Exchange-SenderADCheck: 1 X-MS-Exchange-AntiSpam-Relay: 0 X-Microsoft-Antispam: BCL:0; X-Microsoft-Antispam-Message-Info: 73CiVa3a4wSUv1+uxmCTd4rZw0U+v4OfVYU62x0yxUpPU9Djv9obwKEfUdvDlKYS8ljgRlw7TtQlkTBcdc5g1APSoU6w7tQy0a62vtZniJRU3qCzXKK69WHpLkUHIKzTaqDclsOJ3lam8JOHpHZh1K5/C4W4nmzmhOUEB7ZM2TRRSst9r5ose78WSrLcITRqklVUNQVRkOM44NMiO9BkYTvN5Go4HWCKSKCIJLcR6abvlYzp1pavIf92i5+bu80xbPsmxHfip9dANMKjsf1ZOIpJzcPzUGyMQSFUKBWl7cR31BStJv/tOcGY8WN8Reec00lLkBt8aYAp87wte4OpuUf2XLfzOgdrZPqlkGRXh8S3vzW0Zt1d8R58/jeisKZX/DJxbd4lCTBIZZ5jiFUIz/napBP7LQZ/aGR4e0lUAJEJtjCMVQO6X3XJ327Zc5qpJcUjDWCd7JEKtJtVVKbgXXXwb7abJ1PabAlt/GvP3VfeWds4WsDHivEeOFvAUufEbnKF0qw8sV681v1Rp7oC0p7xnZEXssgqirfmrQglAhLF9HFqa26AThRdKxuuBVI/H5mrR3aTyYoELdZ7LMo7Xc1UTNehYdZDAAjUTktcpFK1XZLATkt/y2YIX9VzpkoWby5atblNTE3H3Jt+hLRAHvuEU8LcuSJ4aYR2LioiGUfYoRI6MxH6RF3o4DLdO5X+myy5HqkROavle4WR/dirYQ== X-Forefront-Antispam-Report: CIP:255.255.255.255;CTRY:;LANG:en;SCL:1;SRV:;IPV:NLI;SFV:NSPM;H:MWHPR12MB1310.namprd12.prod.outlook.com;PTR:;CAT:NONE;SFS:(13230001)(4636009)(366004)(38350700002)(38100700002)(36756003)(508600001)(30864003)(5660300002)(6486002)(86362001)(8936002)(316002)(54906003)(8676002)(66476007)(66556008)(4326008)(66946007)(1076003)(2616005)(107886003)(83380400001)(186003)(6666004)(6512007)(6506007)(52116002)(2906002)(110136005)(26005);DIR:OUT;SFP:1101; X-MS-Exchange-AntiSpam-MessageData-ChunkCount: 1 X-MS-Exchange-AntiSpam-MessageData-0: VMJqxik/7Ilv1AEY5J1gkrBYs/yYk4To54MqU7XErphb1I9P5hwup4G4IO2s4sU89ycA09ZYL0/x7cla7a47ZThs61f8DtCMm4KOpWn7ws4tPQuciu8yBMhjO7DO9EWwtTuWvocAF5rPuKIKIiVn6B43qbdknK08QBGjs+rfk5YGKPDYRH7WvcxiDW9p9YKEsVCY4JrM1n0iSCPBaLS8aiwWrEIqlhzsyBcXTIR2+5uNPgaQ2XK7/N8ci3AepfCDAmTyR1E4bpnirhr49cJzQAzHGCyWrcBsbZL02bygdBu9p9VOCJPxxpE+/nGmiAdu2HehyxncIupQEjal/hAS5QU9sDapOImvgTeK1pSQZHfVmrHG0lFA8ldrgQ0bWToKiXJrHGwZKzCxFNTE1C3/WLsPPY5jQR2u33dLpV8y7EMacHX70Ejfdca66Q3lxSae3HGDTblYRNYlGjEFzUfmRc6lT7xzMOZEvuNtNQs1WbQrqUHhIlzsWLJ6hL0hG0dvsceo6EO+qJqarWN+2Ppeoy4nFxUAFk+DepoERrSFgIBAG7FDVuUmVmf5jejaGzmA8j1af357fIq39bdi5mjIKmxfkT1pR+VsvsZoM0AF+47vgZ8kOuxXZ00M0HZYfOh2dL9LX4G70yCDpn3V3PXrhj185TjHa4Fof/w09iECkzy+u3A6ZdbcK5ViJQZMX0Eq3VOZhC/olTLkxd2eWxBam0ndp8GRLumtMPMUZ0do3SZPovBZtyxoPHtH6NrBZDQQcMjRFHYpWADkXAOAfalvZq/+qo9MK0VqFdqgncz5UaeXuE0xOPu5XRtMwwvBTLo9QxQC5w7WgZfKZf4PImC2AcqiKDas69Y6HbCCZdyeb8SMXh7dP0R5gdyYPYib6z5doHyMwB9IbSY3EZfaBlPEzcvbf1C0YcTso9kieV2uW5/2Id7LvC4ckaeDYJiWM7TzRO1CAh8KD0C0FdhGJ7g/J2YwRD4d7MEk4KD/lnrOtZPgPDDKx+oeXhRwi2KXXq8I18TnAh4pLDiB2RV8SvNqBz4sHZbo3p8k76lln9ShIXk1H0FmW2Rdbj17SxlDo6hr8o3GcgBQZn01dz7ifKZ0G3i2meOAiwtFMsKz/P1UYveJXjK1RGBUU8F0BeiYa4PBteMnyZJO86In8MRegNIsn3XSgybgVtSaN1JGW3MC4ylqqkDpGVIQus6qa2P3QUtWecgSPXmW8Iy+jGawvY3XZZnJDEyr100gLMoco/KBTDftgVm049o1JdLRMcUOVnRN4pDgq0DJwatnak72EA384ucWUbsESfUFv9n9E2AcwYQA5XpSgAprj1rutwT4dPjrO6k/iYc0RSNsfzmOIawm++g34HmVyH0pbDnVOFUTix08uaHRw9afYyLcodDyn1AnmoZUFdn9ql2qcGBOiFUppNhVeURdT6w+Mzt/93Yv3ArnHt/c4BzIhbUGODRhFkqqD/gCiITMkRrqFGT/aTrePLQDEhnJRm8M97KsoWWaWG1cB1Fxw8S+jQNpFWFffC7IEq0PE92s1WPqhjMmfokungBEuxPcgNEEvI9XlbDF5GkWK7BDSrb0mHi3+0AwZCUyZpyvSVDNsrcuSz5t3qsYmxnoybIigGXnY8YKFwUGMy0= X-OriginatorOrg: Nvidia.com X-MS-Exchange-CrossTenant-Network-Message-Id: e8669a79-eb9e-492e-e0cf-08d9f5f38a97 X-MS-Exchange-CrossTenant-AuthSource: MWHPR12MB1310.namprd12.prod.outlook.com X-MS-Exchange-CrossTenant-AuthAs: Internal X-MS-Exchange-CrossTenant-OriginalArrivalTime: 22 Feb 2022 11:07:40.3046 (UTC) X-MS-Exchange-CrossTenant-FromEntityHeader: Hosted X-MS-Exchange-CrossTenant-Id: 43083d15-7273-40c1-b7db-39efd9ccc17a X-MS-Exchange-CrossTenant-MailboxType: HOSTED X-MS-Exchange-CrossTenant-UserPrincipalName: 1L12tXIPvdAEjJFTk+Iq0Bd+EJbadbawEvunHeKBvUw4r7WmpYb5F1uDOBdgzfc8rmiKdJY62AycECPAPLmyyw== X-MS-Exchange-Transport-CrossTenantHeadersStamped: DM6PR12MB5552 Precedence: bulk List-ID: X-Mailing-List: netdev@vger.kernel.org X-Patchwork-Delegate: kuba@kernel.org Add devlink support for param of type NLA_BITFIELD. kernel user need to provide a bitmap to devlink. Signed-off-by: Shay Drory Reviewed-by: Moshe Shemesh --- include/net/devlink.h | 18 ++++++ net/core/devlink.c | 138 ++++++++++++++++++++++++++++++++++++------ 2 files changed, 139 insertions(+), 17 deletions(-) diff --git a/include/net/devlink.h b/include/net/devlink.h index 8d5349d2fb68..f411482f716d 100644 --- a/include/net/devlink.h +++ b/include/net/devlink.h @@ -372,6 +372,7 @@ enum devlink_param_type { DEVLINK_PARAM_TYPE_U32, DEVLINK_PARAM_TYPE_STRING, DEVLINK_PARAM_TYPE_BOOL, + DEVLINK_PARAM_TYPE_BITFIELD, }; union devlink_param_value { @@ -380,6 +381,7 @@ union devlink_param_value { u32 vu32; char vstr[__DEVLINK_PARAM_MAX_STRING_VALUE]; bool vbool; + unsigned long *vbitmap; }; struct devlink_param_gset_ctx { @@ -412,6 +414,8 @@ struct devlink_flash_notify { * @generic: indicates if the parameter is generic or driver specific * @type: parameter type * @supported_cmodes: bitmap of supported configuration modes + * @nbits: number of bits this param need to use, if this param is + * of dynamic len. * @get: get parameter value, used for runtime and permanent * configuration modes * @set: set parameter value, used for runtime and permanent @@ -427,6 +431,7 @@ struct devlink_param { bool generic; enum devlink_param_type type; unsigned long supported_cmodes; + u64 nbits; int (*get)(struct devlink *devlink, u32 id, struct devlink_param_gset_ctx *ctx); int (*set)(struct devlink *devlink, u32 id, @@ -542,6 +547,19 @@ enum devlink_param_generic_id { .validate = _validate, \ } +#define DEVLINK_PARAM_DYNAMIC_GENERIC(_id, _cmodes, _get, _set, _validate, _nbits)\ +{ \ + .id = DEVLINK_PARAM_GENERIC_ID_##_id, \ + .name = DEVLINK_PARAM_GENERIC_##_id##_NAME, \ + .type = DEVLINK_PARAM_GENERIC_##_id##_TYPE, \ + .generic = true, \ + .supported_cmodes = _cmodes, \ + .nbits = _nbits, \ + .get = _get, \ + .set = _set, \ + .validate = _validate, \ +} + /* Part number, identifier of board design */ #define DEVLINK_INFO_VERSION_GENERIC_BOARD_ID "board.id" /* Revision of board design */ diff --git a/net/core/devlink.c b/net/core/devlink.c index fcd9f6d85cf1..3d7e27abc487 100644 --- a/net/core/devlink.c +++ b/net/core/devlink.c @@ -4568,6 +4568,8 @@ devlink_param_type_to_nla_type(enum devlink_param_type param_type) return NLA_STRING; case DEVLINK_PARAM_TYPE_BOOL: return NLA_FLAG; + case DEVLINK_PARAM_TYPE_BITFIELD: + return NLA_BITFIELD; default: return -EINVAL; } @@ -4575,11 +4577,13 @@ devlink_param_type_to_nla_type(enum devlink_param_type param_type) static int devlink_nl_param_value_fill_one(struct sk_buff *msg, - enum devlink_param_type type, + const struct devlink_param *param, enum devlink_param_cmode cmode, union devlink_param_value val) { struct nlattr *param_value_attr; + struct nla_bitfield *bitfield; + int err; param_value_attr = nla_nest_start_noflag(msg, DEVLINK_ATTR_PARAM_VALUE); @@ -4589,7 +4593,7 @@ devlink_nl_param_value_fill_one(struct sk_buff *msg, if (nla_put_u8(msg, DEVLINK_ATTR_PARAM_VALUE_CMODE, cmode)) goto value_nest_cancel; - switch (type) { + switch (param->type) { case DEVLINK_PARAM_TYPE_U8: if (nla_put_u8(msg, DEVLINK_ATTR_PARAM_VALUE_DATA, val.vu8)) goto value_nest_cancel; @@ -4612,6 +4616,17 @@ devlink_nl_param_value_fill_one(struct sk_buff *msg, nla_put_flag(msg, DEVLINK_ATTR_PARAM_VALUE_DATA)) goto value_nest_cancel; break; + case DEVLINK_PARAM_TYPE_BITFIELD: + bitfield = nla_bitfield_alloc(param->nbits); + if (!bitfield) + return -ENOMEM; + nla_bitfield_from_bitmap(bitfield, val.vbitmap, param->nbits); + err = nla_put_bitfield(msg, DEVLINK_ATTR_PARAM_VALUE_DATA, + bitfield); + nla_bitfield_free(bitfield); + if (err) + goto value_nest_cancel; + break; } nla_nest_end(msg, param_value_attr); @@ -4623,6 +4638,24 @@ devlink_nl_param_value_fill_one(struct sk_buff *msg, return -EMSGSIZE; } +static int devlink_param_value_get(const struct devlink_param *param, + union devlink_param_value *value) +{ + if (param->type == DEVLINK_PARAM_TYPE_BITFIELD) { + value->vbitmap = bitmap_zalloc(param->nbits, GFP_KERNEL); + if (!value->vbitmap) + return -ENOMEM; + } + return 0; +} + +static void devlink_param_value_put(const struct devlink_param *param, + union devlink_param_value *value) +{ + if (param->type == DEVLINK_PARAM_TYPE_BITFIELD) + bitmap_free(value->vbitmap); +} + static int devlink_nl_param_fill(struct sk_buff *msg, struct devlink *devlink, unsigned int port_index, struct devlink_param_item *param_item, @@ -4645,14 +4678,22 @@ static int devlink_nl_param_fill(struct sk_buff *msg, struct devlink *devlink, if (!devlink_param_cmode_is_supported(param, i)) continue; if (i == DEVLINK_PARAM_CMODE_DRIVERINIT) { - if (!param_item->driverinit_value_valid) - return -EOPNOTSUPP; + if (!param_item->driverinit_value_valid) { + err = -EOPNOTSUPP; + goto param_value_put; + } param_value[i] = param_item->driverinit_value; } else { ctx.cmode = i; - err = devlink_param_get(devlink, param, &ctx); + err = devlink_param_value_get(param, ¶m_value[i]); if (err) - return err; + goto param_value_put; + ctx.val = param_value[i]; + err = devlink_param_get(devlink, param, &ctx); + if (err) { + devlink_param_value_put(param, ¶m_value[i]); + goto param_value_put; + } param_value[i] = ctx.val; } param_value_set[i] = true; @@ -4660,7 +4701,7 @@ static int devlink_nl_param_fill(struct sk_buff *msg, struct devlink *devlink, hdr = genlmsg_put(msg, portid, seq, &devlink_nl_family, flags, cmd); if (!hdr) - return -EMSGSIZE; + goto genlmsg_put_err; if (devlink_nl_put_handle(msg, devlink)) goto genlmsg_cancel; @@ -4693,10 +4734,13 @@ static int devlink_nl_param_fill(struct sk_buff *msg, struct devlink *devlink, for (i = 0; i <= DEVLINK_PARAM_CMODE_MAX; i++) { if (!param_value_set[i]) continue; - err = devlink_nl_param_value_fill_one(msg, param->type, + err = devlink_nl_param_value_fill_one(msg, param, i, param_value[i]); if (err) goto values_list_nest_cancel; + if (i != DEVLINK_PARAM_CMODE_DRIVERINIT) + devlink_param_value_put(param, ¶m_value[i]); + param_value_set[i] = false; } nla_nest_end(msg, param_values_list); @@ -4710,7 +4754,13 @@ static int devlink_nl_param_fill(struct sk_buff *msg, struct devlink *devlink, nla_nest_cancel(msg, param_attr); genlmsg_cancel: genlmsg_cancel(msg, hdr); - return -EMSGSIZE; +genlmsg_put_err: + err = -EMSGSIZE; +param_value_put: + for (i = 0; i <= DEVLINK_PARAM_CMODE_MAX; i++) + if (i != DEVLINK_PARAM_CMODE_DRIVERINIT && param_value_set[i]) + devlink_param_value_put(param, ¶m_value[i]); + return err; } static void devlink_param_notify(struct devlink *devlink, @@ -4815,6 +4865,9 @@ devlink_param_type_get_from_info(struct genl_info *info, case NLA_FLAG: *param_type = DEVLINK_PARAM_TYPE_BOOL; break; + case NLA_BITFIELD: + *param_type = DEVLINK_PARAM_TYPE_BITFIELD; + break; default: return -EINVAL; } @@ -4827,6 +4880,7 @@ devlink_param_value_get_from_info(const struct devlink_param *param, struct genl_info *info, union devlink_param_value *value) { + struct nla_bitfield *bitfield; struct nlattr *param_data; int len; @@ -4863,6 +4917,18 @@ devlink_param_value_get_from_info(const struct devlink_param *param, return -EINVAL; value->vbool = nla_get_flag(param_data); break; + case DEVLINK_PARAM_TYPE_BITFIELD: + bitfield = nla_data(param_data); + + if (!nla_bitfield_len_is_valid(bitfield, nla_len(param_data)) || + !nla_bitfield_nbits_valid(bitfield, param->nbits)) + return -EINVAL; + value->vbitmap = bitmap_zalloc(param->nbits, GFP_KERNEL); + if (!value->vbitmap) + return -ENOMEM; + + nla_bitfield_to_bitmap(value->vbitmap, bitfield); + break; } return 0; } @@ -4936,33 +5002,48 @@ static int __devlink_nl_cmd_param_set_doit(struct devlink *devlink, if (param->validate) { err = param->validate(devlink, param->id, value, info->extack); if (err) - return err; + goto out; } - if (!info->attrs[DEVLINK_ATTR_PARAM_VALUE_CMODE]) - return -EINVAL; + if (!info->attrs[DEVLINK_ATTR_PARAM_VALUE_CMODE]) { + err = -EINVAL; + goto out; + } cmode = nla_get_u8(info->attrs[DEVLINK_ATTR_PARAM_VALUE_CMODE]); - if (!devlink_param_cmode_is_supported(param, cmode)) - return -EOPNOTSUPP; + if (!devlink_param_cmode_is_supported(param, cmode)) { + err = -EOPNOTSUPP; + goto out; + } if (cmode == DEVLINK_PARAM_CMODE_DRIVERINIT) { if (param->type == DEVLINK_PARAM_TYPE_STRING) strcpy(param_item->driverinit_value.vstr, value.vstr); + else if (param->type == DEVLINK_PARAM_TYPE_BITFIELD) + bitmap_copy(param_item->driverinit_value.vbitmap, + value.vbitmap, + param_item->param->nbits); else param_item->driverinit_value = value; param_item->driverinit_value_valid = true; } else { - if (!param->set) - return -EOPNOTSUPP; + if (!param->set) { + err = -EOPNOTSUPP; + goto out; + } ctx.val = value; ctx.cmode = cmode; err = devlink_param_set(devlink, param, &ctx); if (err) - return err; + goto out; } + devlink_param_value_put(param, &value); devlink_param_notify(devlink, port_index, param_item, cmd); return 0; + +out: + devlink_param_value_put(param, &value); + return err; } static int devlink_nl_cmd_param_set_doit(struct sk_buff *skb, @@ -10098,6 +10179,8 @@ static int devlink_param_verify(const struct devlink_param *param) { if (!param || !param->name || !param->supported_cmodes) return -EINVAL; + if (param->type == DEVLINK_PARAM_TYPE_BITFIELD && !param->nbits) + return -EINVAL; if (param->generic) return devlink_param_generic_verify(param); else @@ -10188,6 +10271,16 @@ int devlink_param_register(struct devlink *devlink, return -ENOMEM; param_item->param = param; + if (param_item->param->type == DEVLINK_PARAM_TYPE_BITFIELD && + devlink_param_cmode_is_supported(param_item->param, + DEVLINK_PARAM_CMODE_DRIVERINIT)) { + param_item->driverinit_value.vbitmap = + bitmap_zalloc(param_item->param->nbits, GFP_KERNEL); + if (!param_item->driverinit_value.vbitmap) { + kfree(param_item); + return -ENOMEM; + } + } list_add_tail(¶m_item->list, &devlink->param_list); return 0; @@ -10210,6 +10303,10 @@ void devlink_param_unregister(struct devlink *devlink, devlink_param_find_by_name(&devlink->param_list, param->name); WARN_ON(!param_item); list_del(¶m_item->list); + if (param_item->param->type == DEVLINK_PARAM_TYPE_BITFIELD && + devlink_param_cmode_is_supported(param_item->param, + DEVLINK_PARAM_CMODE_DRIVERINIT)) + bitmap_free(param_item->driverinit_value.vbitmap); kfree(param_item); } EXPORT_SYMBOL_GPL(devlink_param_unregister); @@ -10244,6 +10341,10 @@ int devlink_param_driverinit_value_get(struct devlink *devlink, u32 param_id, if (param_item->param->type == DEVLINK_PARAM_TYPE_STRING) strcpy(init_val->vstr, param_item->driverinit_value.vstr); + else if (param_item->param->type == DEVLINK_PARAM_TYPE_BITFIELD) + bitmap_copy(init_val->vbitmap, + param_item->driverinit_value.vbitmap, + param_item->param->nbits); else *init_val = param_item->driverinit_value; @@ -10280,6 +10381,9 @@ int devlink_param_driverinit_value_set(struct devlink *devlink, u32 param_id, if (param_item->param->type == DEVLINK_PARAM_TYPE_STRING) strcpy(param_item->driverinit_value.vstr, init_val.vstr); + else if (param_item->param->type == DEVLINK_PARAM_TYPE_BITFIELD) + bitmap_copy(param_item->driverinit_value.vbitmap, + init_val.vbitmap, param_item->param->nbits); else param_item->driverinit_value = init_val; param_item->driverinit_value_valid = true; From patchwork Tue Feb 22 10:58:11 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Shay Drori X-Patchwork-Id: 12754909 X-Patchwork-Delegate: kuba@kernel.org Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 33566C433F5 for ; Tue, 22 Feb 2022 11:08:05 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S231628AbiBVLI1 (ORCPT ); Tue, 22 Feb 2022 06:08:27 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:34142 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S231593AbiBVLIK (ORCPT ); Tue, 22 Feb 2022 06:08:10 -0500 Received: from NAM10-BN7-obe.outbound.protection.outlook.com (mail-bn7nam10on2078.outbound.protection.outlook.com [40.107.92.78]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 3B608B563A; Tue, 22 Feb 2022 03:07:45 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; s=arcselector9901; d=microsoft.com; cv=none; b=ffg+QqDACmsRqHrZHuuIHUaND76G1leIOIK/a877tDM7HD6ERuwNDy7eR1a2p0mXz502S2EjdHswinW6Pw35Z0Hdpu96FT+2RQMnA1VN/YfaKeI1UBRQ5Zoy+yyisTVTsROE0Pn/AJK5DsKGzGiR4pJWbN6OmGSlhL8WGnF+beJX5UqKQXJH48txHYBP2LNFF0HOzbc1WaB2Vva5b8xijvoPVfesDa9VmhREyllDckkHcW88ekjbAUUvhShU55fWuJHhuqwBT73F4Yy8kmhI36QiHfwg9QEU7coucZl5XgWDHV8VJ+w7zZ5w03jphN9u4tRIBdljPRpVMOOwZgzoNg== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=microsoft.com; s=arcselector9901; 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=t83gCaByttGbPJlkwwou89R9Parmk3kUqbAzxiWBtHE=; b=iDuh6Bodl2xbExeDHJGRVv97cmwoZ0P3cGrZfP/cNwPV8uDEt7/RtlMJJ2MbZvogIjpJWOEpwldp6czrWsHnTx6FkUgfkef6Nt7r2F91UDjsKeh3usy31HJ5HOWQSXJ5LrCI8IZERJ5msRE6ZOnA5e9Di/OdO1LzvEQEUDqSXC5fYGuH0vHAGkmMlrzWW5IJgbEhXDvOLfehsoM09xYY3ii3PHY26LMYf8triMpBvdb0yUAKvdHpmqXxjec83puEUK4kSt56vUKmPt9xIvXQgomibAyNCflR6mznakJteA0VtLywaUGrCZnqkLuK49OZxqzMaQ8kFAdWPCP2FyyHCQ== ARC-Authentication-Results: i=1; mx.microsoft.com 1; spf=pass smtp.mailfrom=nvidia.com; dmarc=pass action=none header.from=nvidia.com; dkim=pass header.d=nvidia.com; arc=none DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=Nvidia.com; s=selector2; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck; bh=t83gCaByttGbPJlkwwou89R9Parmk3kUqbAzxiWBtHE=; b=sPA4MReDAdzMqbN6XNbYB31xmxvrFyctZdd7SPw5jahZ5hnqDB27GakWmTiw26qFSsuJQ6Tj/e/b36owK3iOmL783Q1KtlDUBkrrD6rljw+/svXSOOs8V7AdBr1JzsLTU9oLTAHbRU8s/Qa1ABZqeT9LCsPY0UX+Lxsi0/j6HrW9unbrFaqQ1seZfWrH9YPbxiR5qn4lEPU+59VLuE8q2IlbSos1F31AW0D6f9Z+FCLvfJeEB/lqcjtQD/u7eDzudCSFNM6BqHbtUpgWh0cximefUs10kdGD+ynhTwx0zs/ZubOtadFOv8f+Nk4LV6xul4hOX1tf6aLcyTWlgpHxjA== Authentication-Results: dkim=none (message not signed) header.d=none;dmarc=none action=none header.from=nvidia.com; Received: from MWHPR12MB1310.namprd12.prod.outlook.com (2603:10b6:300:a::21) by DM6PR12MB5552.namprd12.prod.outlook.com (2603:10b6:5:1bd::20) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.5017.21; Tue, 22 Feb 2022 11:07:43 +0000 Received: from MWHPR12MB1310.namprd12.prod.outlook.com ([fe80::5165:db44:70d5:1c2a]) by MWHPR12MB1310.namprd12.prod.outlook.com ([fe80::5165:db44:70d5:1c2a%11]) with mapi id 15.20.4995.027; Tue, 22 Feb 2022 11:07:43 +0000 From: Shay Drory To: "David S . Miller" , Jakub Kicinski Cc: jiri@nvidia.com, saeedm@nvidia.com, parav@nvidia.com, netdev@vger.kernel.org, linux-kernel@vger.kernel.org, Shay Drory Subject: [PATCH net-next 3/4] devlink: Add new cpu_affinity generic device param Date: Tue, 22 Feb 2022 12:58:11 +0200 Message-Id: <20220222105812.18668-4-shayd@nvidia.com> X-Mailer: git-send-email 2.21.3 In-Reply-To: <20220222105812.18668-1-shayd@nvidia.com> References: <20220222105812.18668-1-shayd@nvidia.com> X-ClientProxiedBy: AM5PR0201CA0002.eurprd02.prod.outlook.com (2603:10a6:203:3d::12) To MWHPR12MB1310.namprd12.prod.outlook.com (2603:10b6:300:a::21) MIME-Version: 1.0 X-MS-PublicTrafficType: Email X-MS-Office365-Filtering-Correlation-Id: e1db2b02-12c7-49f4-c72b-08d9f5f38c2a X-MS-TrafficTypeDiagnostic: DM6PR12MB5552:EE_ X-Microsoft-Antispam-PRVS: X-MS-Exchange-SenderADCheck: 1 X-MS-Exchange-AntiSpam-Relay: 0 X-Microsoft-Antispam: BCL:0; X-Microsoft-Antispam-Message-Info: tYyEIh2Fu5rskCG8YY4Jwrw2hexkqPtCzvoJvd0Bu8WYuZMjyvXmrb/cD1+CemHJt1O+CRk4oE/f5jJv1z4iBshppZ8C8XL2LNU6XbkYvng9JpcXqui6+jB1uJLGUvXyORcO0Vhsf4HwbHUs6eAu9YiZw2kbNvzvvtvdnV643FCXLOmzm8trGHzOIrpHFevrjME5YKKc8ngO+IzxWWk+vhFcTvZ82u66bfGHzXc9x4BQCf/cnmtj+vTob6WqFBnzeglM7eKgcl2ki9j56aHC8XT/+cFpeIDvRSExr0ld8vXcf8b0P7yox8S/lgNO7o0nSjQtz1hvXMT+QQT7+5b6qf1OnlN0aAC1cn4efY/+X1so0QEEZLAGyM5ZOOy0b6MTKJFc8Ud03s8/nfGy1TBlCY9sONTj0rPm3uQEbPkIX3H1Lrw6ZQLPynENTRzcmJKE71TUAlAZBiUm/wG5/MjHMMZVzz4RlGmL3Go3U/jRPFSkoIWHhth4E9XW09mx+siuXFK2oo9JKLq9A+eJSdCcF+SJZOPYIRxdIr2dAcbOJ2ySudyRsEy5H7sQhF2EHleW8m1vuOvymrl5UyfyHw0rmTFc126RHVt6JwSacEUDIUENuL3ColhcpWDQo53cIt+Vdeaxc+1F5esH1dPeYjf9VQjiWOBijRjexm/Pp5Kmj7OzXLFc5H7u0kMVSO7cPvlCB/Cws+kXokxFBOOyj4IL90aqdMmSGHCxSZE21GVv9VI= X-Forefront-Antispam-Report: CIP:255.255.255.255;CTRY:;LANG:en;SCL:1;SRV:;IPV:NLI;SFV:NSPM;H:MWHPR12MB1310.namprd12.prod.outlook.com;PTR:;CAT:NONE;SFS:(13230001)(4636009)(366004)(38350700002)(38100700002)(36756003)(508600001)(5660300002)(6486002)(86362001)(8936002)(316002)(8676002)(66476007)(66556008)(4326008)(66946007)(1076003)(2616005)(107886003)(83380400001)(186003)(6666004)(6512007)(6506007)(52116002)(2906002)(110136005)(26005)(41533002);DIR:OUT;SFP:1101; X-MS-Exchange-AntiSpam-MessageData-ChunkCount: 1 X-MS-Exchange-AntiSpam-MessageData-0: yveZrskN/+0RUoMk5xuCYWXnd+au2inFixjW9muoGYZQ3qKycB+VQ8mnnWGVtw9neWD3l7JcRSbng/efAlxY7g/ud440CX2iiYV0+0ZsyFvq4JWyln+x8cwzFqFBAykph996hmPzg7Kfqje5sAhCayLPg/NJJIXQknr1gH3s+UsFWYAqRI5+/OHpctyZueQn91JnoCTBmi3GNhWDzgPFTkhz5C8+9IQME7s02SimpwfJ4zhppo+t1leglzTRfxuyWJTkns8QKFzcIelW11T5GxGqhhSjHJvxHWgTXOHlNq1VNmC4E4ORvECCewOhNx6WzNqSYBrxiciZG0GgzTN2oLVYbqKN5DcEbBl4J0fajzE+wCuvfn9YgaiG9170ZQfNQJJFCWNfywZ1BnGklVhPTrMC4HHSyNulTvaYEKsScHP2cOZkao2yoQU4Ey/aJoAflfBEfc3mgxI8IDs/onSAdoTCnSDPx7dMLPo1k2RSAoTF31XBSVhigelhRdmo9CnHGd7rkRFMPZlBUdn5oP50t77NUC8PNokmV1QjdvQRMHtP8I5/rB/eSne5AzwiKZCspe1kum/7KPOURJYlecW31j1qywBTJWn5pNCY8ulL/v4CKgYUf3IJP+0nE21P9NssPVfbgv8Tz9QrJH0+ekZxlRSjYe/SiL8jcXDFy19zZu4nZLjQgy4YneS2awi2zxKY5odoGmkXHZdcdnJXHJHQN7YMkAybuNhZpoS0Tns+h+BFDCK/I89Vl1qgAcADgPCftrG1MFJebkaO1TVU3sEBLGjQaQDW9cgIFJ3W3pEqGkEee8F78vZ2d4dgIbKxAnf5croLeI7QT7msxOlzgWsP3LWf733L1cKAJ5RGoQ5tSfMBGrIPHw3W07Jb6rW9ErHNMFvnVk+d+yQflQZeNAiLxjJALAnDcj6rf34XOUy2UtYxH14WW+1yVpR6UYN5xPl3Wsq8C2K/jZMjbPPw147rPMk4c0LVxfPlexjxdEyeEodFLYsuAW+8/j/BcZNlMGWYqvpX+o4PaF6+gAJ/1EZCV7S7rZ6Ds+EBPRhMenxDB2oHdtIHoSUKC5b/bXkz8OGjfD2Ykgawe/ZZeMiUK7jUwexLvykuUivUUQAudejRK2ktzxaf/xTWs+Zw3LUow2R3W+yfFMcGzRkdBL8Ng8csHsLmmx3whkEXKtVet4I4W5jo+6sIvQwE5t+DPOACZDEOo3W+TEStvRXEtpcV5mDVJcT7XVeHdS6RtNCQhu9csoGVIrFkLZ+5n8d7Pl5Ux1ha7+qcwZ5IPuuS0wQXT+gwL8U0WJwLYyQjlntKv9suUb6Aw8zNQQ4Gz0WWGlqCvLpeqSciRVTf2O5XWkqCiVKSJGfFkJ6v2U0apvi2G+BWYc8LL7Tvo69liGHH7y3dLmvzBwB2SdcAcJe9xccPlG5+ychMjWq9yYkjJNDEtzgSillmthTfTFTAO5mEcpyEwC/IhjdmYvuZoQFAvdLsZOxVDBATAuBmEtVhWfp3SUR/WryVxFjPfPxiF3oCQrDPdlKtptiuJJ/oSnHxHgDSBf7HoUB3b/cGMdQ6zsWajwHTk9WPn0R2/rNbL4jmCQqkvwxsN1YIP7MfKR0ChDuSEGlnKp3etB32nQAolLTWcNiz2DA= X-OriginatorOrg: Nvidia.com X-MS-Exchange-CrossTenant-Network-Message-Id: e1db2b02-12c7-49f4-c72b-08d9f5f38c2a X-MS-Exchange-CrossTenant-AuthSource: MWHPR12MB1310.namprd12.prod.outlook.com X-MS-Exchange-CrossTenant-AuthAs: Internal X-MS-Exchange-CrossTenant-OriginalArrivalTime: 22 Feb 2022 11:07:42.9138 (UTC) X-MS-Exchange-CrossTenant-FromEntityHeader: Hosted X-MS-Exchange-CrossTenant-Id: 43083d15-7273-40c1-b7db-39efd9ccc17a X-MS-Exchange-CrossTenant-MailboxType: HOSTED X-MS-Exchange-CrossTenant-UserPrincipalName: WQnutLVm59t42NhKh4s0c9So2UUJIoNU37BxKuO9dCaiBmr8fUKX3DQ1IkIYzxSxQ25Y8xBvjiME+uqpQhQFcw== X-MS-Exchange-Transport-CrossTenantHeadersStamped: DM6PR12MB5552 Precedence: bulk List-ID: X-Mailing-List: netdev@vger.kernel.org X-Patchwork-Delegate: kuba@kernel.org Add new device generic parameter to configure device affinity. A user who wishes to customize the affinity of the device can do it using below example. $ devlink dev param set auxiliary/mlx5_core.sf.4 name cpu_affinity \ value [cpu_bitmask] cmode driverinit $ devlink dev reload pci/0000:06:00.0 At this point devlink instance will use the customize affinity. Signed-off-by: Shay Drory --- Documentation/networking/devlink/devlink-params.rst | 5 +++++ include/net/devlink.h | 4 ++++ net/core/devlink.c | 5 +++++ 3 files changed, 14 insertions(+) diff --git a/Documentation/networking/devlink/devlink-params.rst b/Documentation/networking/devlink/devlink-params.rst index 4e01dc32bc08..2f9f5baf4373 100644 --- a/Documentation/networking/devlink/devlink-params.rst +++ b/Documentation/networking/devlink/devlink-params.rst @@ -137,3 +137,8 @@ own name. * - ``event_eq_size`` - u32 - Control the size of asynchronous control events EQ. + * - ``cpu_affinity`` + - Bitfield + - control the cpu affinity of the device. user is able to change cpu + affinity also via procfs interface (/proc/irq/\*/smp_affinity). This will + overwrite the devlink setting. diff --git a/include/net/devlink.h b/include/net/devlink.h index f411482f716d..595a4d54a2bd 100644 --- a/include/net/devlink.h +++ b/include/net/devlink.h @@ -466,6 +466,7 @@ enum devlink_param_generic_id { DEVLINK_PARAM_GENERIC_ID_ENABLE_IWARP, DEVLINK_PARAM_GENERIC_ID_IO_EQ_SIZE, DEVLINK_PARAM_GENERIC_ID_EVENT_EQ_SIZE, + DEVLINK_PARAM_GENERIC_ID_CPU_AFFINITY, /* add new param generic ids above here*/ __DEVLINK_PARAM_GENERIC_ID_MAX, @@ -524,6 +525,9 @@ enum devlink_param_generic_id { #define DEVLINK_PARAM_GENERIC_EVENT_EQ_SIZE_NAME "event_eq_size" #define DEVLINK_PARAM_GENERIC_EVENT_EQ_SIZE_TYPE DEVLINK_PARAM_TYPE_U32 +#define DEVLINK_PARAM_GENERIC_CPU_AFFINITY_NAME "cpu_affinity" +#define DEVLINK_PARAM_GENERIC_CPU_AFFINITY_TYPE DEVLINK_PARAM_TYPE_BITFIELD + #define DEVLINK_PARAM_GENERIC(_id, _cmodes, _get, _set, _validate) \ { \ .id = DEVLINK_PARAM_GENERIC_ID_##_id, \ diff --git a/net/core/devlink.c b/net/core/devlink.c index 3d7e27abc487..d2dfd9a88eb1 100644 --- a/net/core/devlink.c +++ b/net/core/devlink.c @@ -4477,6 +4477,11 @@ static const struct devlink_param devlink_param_generic[] = { .name = DEVLINK_PARAM_GENERIC_EVENT_EQ_SIZE_NAME, .type = DEVLINK_PARAM_GENERIC_EVENT_EQ_SIZE_TYPE, }, + { + .id = DEVLINK_PARAM_GENERIC_ID_CPU_AFFINITY, + .name = DEVLINK_PARAM_GENERIC_CPU_AFFINITY_NAME, + .type = DEVLINK_PARAM_GENERIC_CPU_AFFINITY_TYPE, + }, }; static int devlink_param_generic_verify(const struct devlink_param *param) From patchwork Tue Feb 22 10:58:12 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Shay Drori X-Patchwork-Id: 12754910 X-Patchwork-Delegate: kuba@kernel.org Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 70A8BC433F5 for ; Tue, 22 Feb 2022 11:08:15 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S231618AbiBVLIi (ORCPT ); Tue, 22 Feb 2022 06:08:38 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:34696 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S231587AbiBVLI0 (ORCPT ); Tue, 22 Feb 2022 06:08:26 -0500 Received: from NAM12-DM6-obe.outbound.protection.outlook.com (mail-dm6nam12on2083.outbound.protection.outlook.com [40.107.243.83]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 6B282B65D5; Tue, 22 Feb 2022 03:07:47 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; s=arcselector9901; d=microsoft.com; cv=none; b=JMu0pnK54CIcNqzkmawTqfqoT8mvCqixI+R7rVpGd0stywXXX4q+f/hZaaNb9CswzQSGfBAi3q6mNdJthqpEYaJElO6ASVBPs3GsCLTLDBumK72uRQdONujWeKBnCtRXgjBONtM6+Da1D6qc3m5g+FtSYC6dR0SbWTYqh3oLFS+CHz6bjie3OGJ1MVwr9o5gnKJUlKCgHGc3hAljR29r7axyXT9bpgpb4KoPpWhycHNzxGoEDrI60uvYV3NCdvNmmu628a8J40rpAIQoHm51L5XcjnEz6PFm52kSz4eK3x5iELqLrA6rujZ7wIcSlYJgTF+3o7jI8307zUXb/Cedbg== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=microsoft.com; s=arcselector9901; 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=khi9uD4NmylJHeLz7sizAo+rR7j8g1Zgjuih7WzIKqc=; b=oXC/doBBXAnlwSBOseaukd91hyL1j5ZIW0fzSie1fiwvFIEp5I07c754DXNd9YrCiZDPA9jrUjTd54dW0PFMZ79m7nhadURs79dejANlWDnIVXJs3QQ1a7txJG5X8kEQEu174icejZ2+FwsZ6y1sphkhGZTUdWVmv8oiSadTNlwx7NHIgyeBK0Qay1AOJ2n+wPhajY2rFYqoAituP1fXOQm6e7w2sgAQm+wPGiALOYx5XC2ko3hKeIWHLaPXgx56c0YHm4jOGFuRwOaZLnMiyTd+ckV7uIqlaCs3RI9WgWMn01HbccUlPusCKWeo/GGcNvQiN1MEPBEC+N/P28hIrw== ARC-Authentication-Results: i=1; mx.microsoft.com 1; spf=pass smtp.mailfrom=nvidia.com; dmarc=pass action=none header.from=nvidia.com; dkim=pass header.d=nvidia.com; arc=none DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=Nvidia.com; s=selector2; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck; bh=khi9uD4NmylJHeLz7sizAo+rR7j8g1Zgjuih7WzIKqc=; b=SZujbqBC9PP+UQMKEo6Z6239UX8cEmYN69Ac+NO94mMTvVqazjuI5FlEGxYCtzLfZ+9gUwGXU/j6F27u6UzSsLGy/If1cmW84H8AUc4OfK41uLe7b6drHqdD3JmtafEs5wMG8Ia2HSdweuNE73YMp0DkeNlAv61Sr3WD/ugvjnWkaiburW4y8/keparJChhrt/CJQb/Jj55qSvQVBZ52F66voJzBpMBpiyxlM52pmHcGcIEz5IZKFlUVx15BySlRLuAF2g0bI/JFH6DRR4pO3y52UeoSSz++9o8M5FWZyhUNl3VJfP/kVHuiMdeIrHHXzCcOwHEJHO18mFXnREdgKg== Authentication-Results: dkim=none (message not signed) header.d=none;dmarc=none action=none header.from=nvidia.com; Received: from MWHPR12MB1310.namprd12.prod.outlook.com (2603:10b6:300:a::21) by DM6PR12MB5552.namprd12.prod.outlook.com (2603:10b6:5:1bd::20) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.5017.21; Tue, 22 Feb 2022 11:07:45 +0000 Received: from MWHPR12MB1310.namprd12.prod.outlook.com ([fe80::5165:db44:70d5:1c2a]) by MWHPR12MB1310.namprd12.prod.outlook.com ([fe80::5165:db44:70d5:1c2a%11]) with mapi id 15.20.4995.027; Tue, 22 Feb 2022 11:07:45 +0000 From: Shay Drory To: "David S . Miller" , Jakub Kicinski Cc: jiri@nvidia.com, saeedm@nvidia.com, parav@nvidia.com, netdev@vger.kernel.org, linux-kernel@vger.kernel.org, Shay Drory , Moshe Shemesh Subject: [PATCH net-next 4/4] net/mlx5: Support cpu_affinity devlink dev param Date: Tue, 22 Feb 2022 12:58:12 +0200 Message-Id: <20220222105812.18668-5-shayd@nvidia.com> X-Mailer: git-send-email 2.21.3 In-Reply-To: <20220222105812.18668-1-shayd@nvidia.com> References: <20220222105812.18668-1-shayd@nvidia.com> X-ClientProxiedBy: AM5PR0201CA0002.eurprd02.prod.outlook.com (2603:10a6:203:3d::12) To MWHPR12MB1310.namprd12.prod.outlook.com (2603:10b6:300:a::21) MIME-Version: 1.0 X-MS-PublicTrafficType: Email X-MS-Office365-Filtering-Correlation-Id: 406bf253-cafc-4536-e701-08d9f5f38dd7 X-MS-TrafficTypeDiagnostic: DM6PR12MB5552:EE_ X-Microsoft-Antispam-PRVS: X-MS-Exchange-SenderADCheck: 1 X-MS-Exchange-AntiSpam-Relay: 0 X-Microsoft-Antispam: BCL:0; X-Microsoft-Antispam-Message-Info: nGPVw8tKpN4VLjSYQR5U47LCiKZ/YAEUaLg/0od+fji+k/RBR5Wa8RXpQYlfZoVZE2tOUcfuHJHZ/dmOSoRKKoTtk7tdHlqRJkvn/4PevpMveTLjAOc/+Yi/zkwBJuhTb7/SLZg7fCvtW0BAtJRy+UeSTKtfiB/OlMotjul1GxezTG4NcSfII9l3B2EFqJMjAClGs4qWIcUki/jQgb9hE12eU9NGuOCrW55jJiHXOd9FkVVqQEL4tEopYvQPWdb9WVxAKXxX4iGr3nbjVKjQIgBJRY4BTry/WGKX2L4qNDoSKkciRqqQaEodtyB7a5opGccgfS1M8lojz3vxV/UbP5Q+JxK1F26zSegotkzrD/XnWU/6yaLmztCoKUFv7E+tDldOTGAMtFsa+GW3AYT/AEnn5CFcZuAdf+HqFwps35u68kUR+lvJN5VF3ShQiQSACZEaEfktwvyuHx2IdmVaxzfb5YaK5VckiFJpTbaCJfmI7Q3E8Gs60d21G5/bySsjyGU/ZFQv9jSxAVNyBcoCRLaetwRDMe+A5kZX5xRF+Dq3EnhMSbBStrE5BfJJuESxx2mUTIEj72m6yNhhkZEuvtGFT5YIQPSxE81LXhXQHAJYXb488cq9lCXscTd2L1Zkqvss0m0eZZ3TfSs1RzC3g6MEnmzFKiGEH8l7/UoIRQKzJuenZUUSIsuLFa/WkqiqOva9MEX9vwPJRoS3OlxhKQ== X-Forefront-Antispam-Report: CIP:255.255.255.255;CTRY:;LANG:en;SCL:1;SRV:;IPV:NLI;SFV:NSPM;H:MWHPR12MB1310.namprd12.prod.outlook.com;PTR:;CAT:NONE;SFS:(13230001)(4636009)(366004)(38350700002)(38100700002)(36756003)(508600001)(30864003)(5660300002)(6486002)(86362001)(8936002)(316002)(54906003)(8676002)(66476007)(66556008)(4326008)(66946007)(1076003)(2616005)(107886003)(83380400001)(186003)(6666004)(6512007)(6506007)(52116002)(2906002)(110136005)(26005);DIR:OUT;SFP:1101; X-MS-Exchange-AntiSpam-MessageData-ChunkCount: 1 X-MS-Exchange-AntiSpam-MessageData-0: =?utf-8?q?FpY6s9xbdJOUruBIpFnH//10X1rH?= =?utf-8?q?X6bWeh6ZhRz653141QVtowqnss0MJyx2//5+QwKFk6XREqTNEdAxZgIf6pa04H4gv?= =?utf-8?q?RPlMfh1rweDc06ha1UI0rcsxgyboSmuiqbqkZRRcSYx4ys+0ZG3I43QapcW8tw31i?= =?utf-8?q?p/sHtYZW8qNxj3kb3YidguOzZPb1UCHGMPbYngAWq48euR9uYK+sOz6/sa154VOz1?= =?utf-8?q?lFM8kLFPvmvBioPcrHvu3ku3c1tbmH786cgIQCGUME9EK7+xBcsro1HLcLCQZBIy8?= =?utf-8?q?hParIi9fRsT4XiQzz6Q5B9aPVTWHP9rZwcFwHYmzjtf5jJUPStN+D8XXOFbQMuvJ8?= =?utf-8?q?Ad6CLHkIorZ4YcsNaNYRn9KwPTCs2KqpWTNr0ZTJFHU+7OUVK7b/Jvhw49Kv4iL5j?= =?utf-8?q?TzmYNCaF8jgf3IhLHPzRbhbYLqUoZ+Fw9MRYA+QUCHPJ8ajyXBGx1CeXdzX3E+doR?= =?utf-8?q?fzxRWYLu7GEsBCoUkDW5mcN2O1idDoQQ7BiYdhv0qAQB+UexdYDMNBNFgyk3M51Za?= =?utf-8?q?EsbvkueeECyX41n+zfYirj3+8xYgh66rzifbVHoeEt+c+mwTC/ZQgVYHi0/5xDwvs?= =?utf-8?q?cTilsgsoN6M3aPfOJD3W0f7lH4VGIL8lTbfLNreBloysLqG0yqT2h8dz0uDXytD05?= =?utf-8?q?ydadV9r4tIz05FDF7ZBMWHvyHMyHRs4TZDGG1pKhWpE2Q+cm+kLf4WaEpmDS48ZA4?= =?utf-8?q?qWjW37Fki4G5JPMSE7oR5bppopplHfzfBEZo5CbjNm2WXTfkeec2T897YY94d2gsz?= =?utf-8?q?7sbZSuXcfnBBKPNypsuOIunLFin+SgI8f9rXVFHfQZwofqEjvEbZnoX4BZEXKsOyt?= =?utf-8?q?/WujMRczhS0BLfZGxJ1tnlgnsE6okPY83jpz8yzvguyeLeseiAGT/99AhHV4DQzax?= =?utf-8?q?LcmdZo7erJN1YUG3SD1NjLtk0I1eoD/IoCok8sMsvzTelq6YnMwCy/BJ4bRrWhwob?= =?utf-8?q?TlMRlQAesUKHZ/Mxkp4OUmLsej0nr7k4ORJQ4eQRHupqrWESRbY8uTa35cUJlZVNQ?= =?utf-8?q?Sc4TJD3oNPTrJr7Oqmj/0jh24AIoBLocy/Rp/SE8lm9coxqhrQ1iekks57t9j+J08?= =?utf-8?q?fWHxyzxs1hnB95dZuQHC1NjoOdEYv/z5EhCUPC3gwDxquw6acrE2LGXd4pYCNo9/L?= =?utf-8?q?oBAKJs46Cm6zj5oS8qfx/jxnFCBjpXwGR1FDZT4Y4mDxPRhVAAb7+w29mYcqdhes9?= =?utf-8?q?FTLFaHqUm9d4+F0jORZ/d856TTGeqtOZ45lUMIp2mM5Lf+nslatxhMoNCPOzuljfw?= =?utf-8?q?0sOm6AxN1rtbKOA4XsjMA8NNpk30RwZgv9noKJqxkGveM35eukJ5BzmU9T/IScwl/?= =?utf-8?q?iKNYg0tzJ3p7UciPGjBwWP9ztpDPVIPXZjmmiW5/pN6O69ekIvoTLWbPjZU4/kR28?= =?utf-8?q?2K/fDujQpog+9NLYH6Iy4qmAKlyZmQcHsWZiVYM8JRO0AXFiKv94NrF+UzPVexgN3?= =?utf-8?q?2pnDvm4WVs2bNRHRvjFkEntqxnHc5xj9eN9LdQTZKwmnWEt60V6x4baHXby9qPrSV?= =?utf-8?q?8O68GjxZbcs0kea59gwqyuuGrHRgBLoByAopYMGDw2aM3SIXznJXi+k=3D?= X-OriginatorOrg: Nvidia.com X-MS-Exchange-CrossTenant-Network-Message-Id: 406bf253-cafc-4536-e701-08d9f5f38dd7 X-MS-Exchange-CrossTenant-AuthSource: MWHPR12MB1310.namprd12.prod.outlook.com X-MS-Exchange-CrossTenant-AuthAs: Internal X-MS-Exchange-CrossTenant-OriginalArrivalTime: 22 Feb 2022 11:07:45.7574 (UTC) X-MS-Exchange-CrossTenant-FromEntityHeader: Hosted X-MS-Exchange-CrossTenant-Id: 43083d15-7273-40c1-b7db-39efd9ccc17a X-MS-Exchange-CrossTenant-MailboxType: HOSTED X-MS-Exchange-CrossTenant-UserPrincipalName: S+FzQt2I8VHN0WBkI2Qb4vFFGfczKxSSQyPx/IKM3q4G6KtHdokmPNk+Lg9i052YkOw4zgD21H1vwUgVe4c4fg== X-MS-Exchange-Transport-CrossTenantHeadersStamped: DM6PR12MB5552 Precedence: bulk List-ID: X-Mailing-List: netdev@vger.kernel.org X-Patchwork-Delegate: kuba@kernel.org Enable users to control the affinity of PCI Function. The default value is the affinity assigned by kernel for the PCI Function. The runtime value shows the current affinity, the driverinit value is used in order to set a new affinity on the next driver reload. Setting empty affinity means kernel default policy. Example: - Show the current affinity. $ devlink dev param show auxiliary/mlx5_core.sf.4 name cpu_affinity name cpu_affinity type driver-specific values: cmode runtime value ff cmode driverinit value 0 - Set affinity to 3 (cpu 0 and cpu 1). $ devlink dev param set auxiliary/mlx5_core.sf.4 name cpu_affinity \ value 3 cmode driverinit Then run devlink reload command to apply the new value. $ devlink dev reload auxiliary/mlx5_core.sf.4 Signed-off-by: Shay Drory Reviewed-by: Moshe Shemesh --- Documentation/networking/devlink/mlx5.rst | 3 + .../net/ethernet/mellanox/mlx5/core/devlink.c | 123 ++++++++++++++++++ .../net/ethernet/mellanox/mlx5/core/devlink.h | 2 + drivers/net/ethernet/mellanox/mlx5/core/eq.c | 39 ++++++ .../ethernet/mellanox/mlx5/core/mlx5_core.h | 2 + .../ethernet/mellanox/mlx5/core/mlx5_irq.h | 5 +- .../net/ethernet/mellanox/mlx5/core/pci_irq.c | 85 +++++++++++- 7 files changed, 256 insertions(+), 3 deletions(-) diff --git a/Documentation/networking/devlink/mlx5.rst b/Documentation/networking/devlink/mlx5.rst index 29ad304e6fba..a213e93e495b 100644 --- a/Documentation/networking/devlink/mlx5.rst +++ b/Documentation/networking/devlink/mlx5.rst @@ -27,6 +27,9 @@ Parameters * - ``max_macs`` - driverinit - The range is between 1 and 2^31. Only power of 2 values are supported. + * - ``cpu_affinity`` + - driverinit | runtime + - empty affinity (0) means kernel assign the affinity The ``mlx5`` driver also implements the following driver-specific parameters. diff --git a/drivers/net/ethernet/mellanox/mlx5/core/devlink.c b/drivers/net/ethernet/mellanox/mlx5/core/devlink.c index d1093bb2d436..9e33e8f7fed0 100644 --- a/drivers/net/ethernet/mellanox/mlx5/core/devlink.c +++ b/drivers/net/ethernet/mellanox/mlx5/core/devlink.c @@ -10,6 +10,7 @@ #include "esw/qos.h" #include "sf/dev/dev.h" #include "sf/sf.h" +#include "mlx5_irq.h" static int mlx5_devlink_flash_update(struct devlink *devlink, struct devlink_flash_update_params *params, @@ -833,6 +834,121 @@ mlx5_devlink_max_uc_list_param_unregister(struct devlink *devlink) devlink_param_unregister(devlink, &max_uc_list_param); } +static int mlx5_devlink_cpu_affinity_validate(struct devlink *devlink, u32 id, + union devlink_param_value val, + struct netlink_ext_ack *extack) +{ + struct mlx5_core_dev *dev = devlink_priv(devlink); + cpumask_var_t tmp; + int max_eqs; + int ret = 0; + int last; + + /* Check whether the mask is valid cpu mask */ + last = find_last_bit(val.vbitmap, MLX5_CPU_AFFINITY_MAX_LEN); + if (last == MLX5_CPU_AFFINITY_MAX_LEN) + /* Affinity is empty, will use default policy*/ + return 0; + if (last >= num_present_cpus()) { + NL_SET_ERR_MSG_MOD(extack, "Some CPUs aren't present"); + return -ERANGE; + } + + if (!zalloc_cpumask_var(&tmp, GFP_KERNEL)) + return -ENOMEM; + + bitmap_copy(cpumask_bits(tmp), val.vbitmap, nr_cpu_ids); + if (!cpumask_subset(tmp, cpu_online_mask)) { + NL_SET_ERR_MSG_MOD(extack, "Some CPUs aren't online"); + ret = -EINVAL; + goto out; + } + + /* Check whether the PF/VF/SFs have enough IRQs. SF will + * perform IRQ->CPU check during load time. + */ + if (mlx5_core_is_sf(dev)) + max_eqs = min_t(int, MLX5_COMP_EQS_PER_SF, + mlx5_irq_table_get_sfs_vec(mlx5_irq_table_get(dev))); + else + max_eqs = mlx5_irq_table_get_num_comp(mlx5_irq_table_get(dev)); + if (cpumask_weight(tmp) > max_eqs) { + NL_SET_ERR_MSG_MOD(extack, "PCI Function doesn’t have enough IRQs"); + ret = -EINVAL; + } + +out: + free_cpumask_var(tmp); + return ret; +} + +static int mlx5_devlink_cpu_affinity_set(struct devlink *devlink, u32 id, + struct devlink_param_gset_ctx *ctx) +{ + /* Runtime set of cpu_affinity is not supported */ + return -EOPNOTSUPP; +} + +static int mlx5_devlink_cpu_affinity_get(struct devlink *devlink, u32 id, + struct devlink_param_gset_ctx *ctx) +{ + struct mlx5_core_dev *dev = devlink_priv(devlink); + cpumask_var_t dev_mask; + + if (!zalloc_cpumask_var(&dev_mask, GFP_KERNEL)) + return -ENOMEM; + mlx5_core_affinity_get(dev, dev_mask); + bitmap_copy(ctx->val.vbitmap, cpumask_bits(dev_mask), nr_cpu_ids); + free_cpumask_var(dev_mask); + return 0; +} + +static const struct devlink_param cpu_affinity_param = + DEVLINK_PARAM_DYNAMIC_GENERIC(CPU_AFFINITY, BIT(DEVLINK_PARAM_CMODE_RUNTIME) | + BIT(DEVLINK_PARAM_CMODE_DRIVERINIT), + mlx5_devlink_cpu_affinity_get, + mlx5_devlink_cpu_affinity_set, + mlx5_devlink_cpu_affinity_validate, + MLX5_CPU_AFFINITY_MAX_LEN); + +static int mlx5_devlink_cpu_affinity_param_register(struct devlink *devlink) +{ + struct mlx5_core_dev *dev = devlink_priv(devlink); + union devlink_param_value value; + cpumask_var_t dev_mask; + int ret = 0; + + if (mlx5_core_is_sf(dev) && + !mlx5_irq_table_have_dedicated_sfs_irqs(mlx5_irq_table_get(dev))) + return 0; + + if (!zalloc_cpumask_var(&dev_mask, GFP_KERNEL)) + return -ENOMEM; + + ret = devlink_param_register(devlink, &cpu_affinity_param); + if (ret) + goto out; + + value.vbitmap = cpumask_bits(dev_mask); + devlink_param_driverinit_value_set(devlink, + DEVLINK_PARAM_GENERIC_ID_CPU_AFFINITY, + value); +out: + free_cpumask_var(dev_mask); + return ret; +} + +static void mlx5_devlink_cpu_affinity_param_unregister(struct devlink *devlink) +{ + struct mlx5_core_dev *dev = devlink_priv(devlink); + + if (mlx5_core_is_sf(dev) && + !mlx5_irq_table_have_dedicated_sfs_irqs(mlx5_irq_table_get(dev))) + return; + + devlink_param_unregister(devlink, &cpu_affinity_param); +} + #define MLX5_TRAP_DROP(_id, _group_id) \ DEVLINK_TRAP_GENERIC(DROP, DROP, _id, \ DEVLINK_TRAP_GROUP_GENERIC_ID_##_group_id, \ @@ -896,6 +1012,10 @@ int mlx5_devlink_register(struct devlink *devlink) if (err) goto max_uc_list_err; + err = mlx5_devlink_cpu_affinity_param_register(devlink); + if (err) + goto cpu_affinity_err; + err = mlx5_devlink_traps_register(devlink); if (err) goto traps_reg_err; @@ -906,6 +1026,8 @@ int mlx5_devlink_register(struct devlink *devlink) return 0; traps_reg_err: + mlx5_devlink_cpu_affinity_param_unregister(devlink); +cpu_affinity_err: mlx5_devlink_max_uc_list_param_unregister(devlink); max_uc_list_err: mlx5_devlink_auxdev_params_unregister(devlink); @@ -918,6 +1040,7 @@ int mlx5_devlink_register(struct devlink *devlink) void mlx5_devlink_unregister(struct devlink *devlink) { mlx5_devlink_traps_unregister(devlink); + mlx5_devlink_cpu_affinity_param_unregister(devlink); mlx5_devlink_max_uc_list_param_unregister(devlink); mlx5_devlink_auxdev_params_unregister(devlink); devlink_params_unregister(devlink, mlx5_devlink_params, diff --git a/drivers/net/ethernet/mellanox/mlx5/core/devlink.h b/drivers/net/ethernet/mellanox/mlx5/core/devlink.h index 30bf4882779b..891d4df419fe 100644 --- a/drivers/net/ethernet/mellanox/mlx5/core/devlink.h +++ b/drivers/net/ethernet/mellanox/mlx5/core/devlink.h @@ -6,6 +6,8 @@ #include +#define MLX5_CPU_AFFINITY_MAX_LEN (NR_CPUS) + enum mlx5_devlink_param_id { MLX5_DEVLINK_PARAM_ID_BASE = DEVLINK_PARAM_GENERIC_ID_MAX, MLX5_DEVLINK_PARAM_ID_FLOW_STEERING_MODE, diff --git a/drivers/net/ethernet/mellanox/mlx5/core/eq.c b/drivers/net/ethernet/mellanox/mlx5/core/eq.c index 48a45aa54a3c..9572c9f85f70 100644 --- a/drivers/net/ethernet/mellanox/mlx5/core/eq.c +++ b/drivers/net/ethernet/mellanox/mlx5/core/eq.c @@ -794,6 +794,30 @@ void mlx5_eq_update_ci(struct mlx5_eq *eq, u32 cc, bool arm) } EXPORT_SYMBOL(mlx5_eq_update_ci); +static int comp_irqs_request_by_cpu_affinity(struct mlx5_core_dev *dev) +{ + struct mlx5_eq_table *table = dev->priv.eq_table; + struct devlink *devlink = priv_to_devlink(dev); + union devlink_param_value val; + cpumask_var_t user_mask; + int ret; + + if (!zalloc_cpumask_var(&user_mask, GFP_KERNEL)) + return -ENOMEM; + + val.vbitmap = cpumask_bits(user_mask); + ret = devlink_param_driverinit_value_get(devlink, + DEVLINK_PARAM_GENERIC_ID_CPU_AFFINITY, + &val); + if (ret) + goto out; + + ret = mlx5_irqs_request_mask(dev, table->comp_irqs, user_mask); +out: + free_cpumask_var(user_mask); + return ret; +} + static void comp_irqs_release(struct mlx5_core_dev *dev) { struct mlx5_eq_table *table = dev->priv.eq_table; @@ -817,6 +841,11 @@ static int comp_irqs_request(struct mlx5_core_dev *dev) table->comp_irqs = kcalloc(ncomp_eqs, sizeof(*table->comp_irqs), GFP_KERNEL); if (!table->comp_irqs) return -ENOMEM; + + ret = comp_irqs_request_by_cpu_affinity(dev); + if (ret > 0) + return ret; + mlx5_core_dbg(dev, "failed to get param cpu_affinity. use default policy\n"); if (mlx5_core_is_sf(dev)) { ret = mlx5_irq_affinity_irqs_request_auto(dev, ncomp_eqs, table->comp_irqs); if (ret < 0) @@ -987,6 +1016,16 @@ mlx5_comp_irq_get_affinity_mask(struct mlx5_core_dev *dev, int vector) } EXPORT_SYMBOL(mlx5_comp_irq_get_affinity_mask); +void mlx5_core_affinity_get(struct mlx5_core_dev *dev, struct cpumask *dev_mask) +{ + struct mlx5_eq_table *table = dev->priv.eq_table; + struct mlx5_eq_comp *eq, *n; + + list_for_each_entry_safe(eq, n, &table->comp_eqs_list, list) + cpumask_or(dev_mask, dev_mask, + mlx5_irq_get_affinity_mask(eq->core.irq)); +} + #ifdef CONFIG_RFS_ACCEL struct cpu_rmap *mlx5_eq_table_get_rmap(struct mlx5_core_dev *dev) { diff --git a/drivers/net/ethernet/mellanox/mlx5/core/mlx5_core.h b/drivers/net/ethernet/mellanox/mlx5/core/mlx5_core.h index 6f8baa0f2a73..95d133aa3fcd 100644 --- a/drivers/net/ethernet/mellanox/mlx5/core/mlx5_core.h +++ b/drivers/net/ethernet/mellanox/mlx5/core/mlx5_core.h @@ -307,4 +307,6 @@ bool mlx5_rdma_supported(struct mlx5_core_dev *dev); bool mlx5_vnet_supported(struct mlx5_core_dev *dev); bool mlx5_same_hw_devs(struct mlx5_core_dev *dev, struct mlx5_core_dev *peer_dev); +void mlx5_core_affinity_get(struct mlx5_core_dev *dev, struct cpumask *dev_mask); + #endif /* __MLX5_CORE_H__ */ diff --git a/drivers/net/ethernet/mellanox/mlx5/core/mlx5_irq.h b/drivers/net/ethernet/mellanox/mlx5/core/mlx5_irq.h index 23cb63fa4588..a31dc3d900af 100644 --- a/drivers/net/ethernet/mellanox/mlx5/core/mlx5_irq.h +++ b/drivers/net/ethernet/mellanox/mlx5/core/mlx5_irq.h @@ -16,6 +16,7 @@ int mlx5_irq_table_create(struct mlx5_core_dev *dev); void mlx5_irq_table_destroy(struct mlx5_core_dev *dev); int mlx5_irq_table_get_num_comp(struct mlx5_irq_table *table); int mlx5_irq_table_get_sfs_vec(struct mlx5_irq_table *table); +bool mlx5_irq_table_have_dedicated_sfs_irqs(struct mlx5_irq_table *table); struct mlx5_irq_table *mlx5_irq_table_get(struct mlx5_core_dev *dev); int mlx5_set_msix_vec_count(struct mlx5_core_dev *dev, int devfn, @@ -25,10 +26,12 @@ int mlx5_get_default_msix_vec_count(struct mlx5_core_dev *dev, int num_vfs); struct mlx5_irq *mlx5_ctrl_irq_request(struct mlx5_core_dev *dev); void mlx5_ctrl_irq_release(struct mlx5_irq *ctrl_irq); struct mlx5_irq *mlx5_irq_request(struct mlx5_core_dev *dev, u16 vecidx, - struct cpumask *affinity); + const struct cpumask *affinity); int mlx5_irqs_request_vectors(struct mlx5_core_dev *dev, u16 *cpus, int nirqs, struct mlx5_irq **irqs); void mlx5_irqs_release_vectors(struct mlx5_irq **irqs, int nirqs); +int mlx5_irqs_request_mask(struct mlx5_core_dev *dev, struct mlx5_irq **irqs, + struct cpumask *irqs_req_mask); int mlx5_irq_attach_nb(struct mlx5_irq *irq, struct notifier_block *nb); int mlx5_irq_detach_nb(struct mlx5_irq *irq, struct notifier_block *nb); struct cpumask *mlx5_irq_get_affinity_mask(struct mlx5_irq *irq); diff --git a/drivers/net/ethernet/mellanox/mlx5/core/pci_irq.c b/drivers/net/ethernet/mellanox/mlx5/core/pci_irq.c index 41807ef55201..ed4e491ec9c0 100644 --- a/drivers/net/ethernet/mellanox/mlx5/core/pci_irq.c +++ b/drivers/net/ethernet/mellanox/mlx5/core/pci_irq.c @@ -300,7 +300,7 @@ int mlx5_irq_get_index(struct mlx5_irq *irq) /* requesting an irq from a given pool according to given index */ static struct mlx5_irq * irq_pool_request_vector(struct mlx5_irq_pool *pool, int vecidx, - struct cpumask *affinity) + const struct cpumask *affinity) { struct mlx5_irq *irq; @@ -420,7 +420,7 @@ struct mlx5_irq *mlx5_ctrl_irq_request(struct mlx5_core_dev *dev) * This function returns a pointer to IRQ, or ERR_PTR in case of error. */ struct mlx5_irq *mlx5_irq_request(struct mlx5_core_dev *dev, u16 vecidx, - struct cpumask *affinity) + const struct cpumask *affinity) { struct mlx5_irq_table *irq_table = mlx5_irq_table_get(dev); struct mlx5_irq_pool *pool; @@ -481,6 +481,82 @@ int mlx5_irqs_request_vectors(struct mlx5_core_dev *dev, u16 *cpus, int nirqs, return i ? i : PTR_ERR(irq); } +static int req_mask_local_spread(unsigned int i, int node, + const struct cpumask *irqs_req_mask) +{ + int cpu; + + if (node == NUMA_NO_NODE) { + for_each_cpu_and(cpu, cpu_online_mask, irqs_req_mask) + if (i-- == 0) + return cpu; + } else { + /* NUMA first. */ + for_each_cpu_and(cpu, cpumask_of_node(node), irqs_req_mask) + if (cpu_online(cpu)) + if (i-- == 0) + return cpu; + + for_each_online_cpu(cpu) { + /* Skip NUMA nodes, done above. */ + if (cpumask_test_cpu(cpu, cpumask_of_node(node))) + continue; + + if (i-- == 0) + return cpu; + } + } + WARN_ON(true); + return cpumask_first(cpu_online_mask); +} + +/** + * mlx5_irqs_request_mask - request one or more IRQs for mlx5 device. + * @dev: mlx5 device that is requesting the IRQs. + * @irqs: an output array of IRQs pointers. + * @irqs_req_mask: cpumask requested for these IRQs. + * + * Each IRQ is bounded to at most 1 CPU. + * This function returns the number of IRQs requested, (which might be smaller than + * cpumask_weight(@irqs_req_mask)), if successful, or a negative error code in + * case of an error. + */ +int mlx5_irqs_request_mask(struct mlx5_core_dev *dev, struct mlx5_irq **irqs, + struct cpumask *irqs_req_mask) +{ + struct mlx5_irq_pool *pool = mlx5_irq_pool_get(dev); + struct mlx5_irq *irq; + int nirqs; + int cpu; + int i; + + /* Request an IRQ for each online CPU in the given mask */ + cpumask_and(irqs_req_mask, irqs_req_mask, cpu_online_mask); + nirqs = cpumask_weight(irqs_req_mask); + for (i = 0; i < nirqs; i++) { + /* Iterate over the mask the caller provided in numa aware fashion. + * Local CPUs are requested first, followed by non-local ones. + */ + cpu = req_mask_local_spread(i, dev->priv.numa_node, irqs_req_mask); + + if (mlx5_irq_pool_is_sf_pool(pool)) + irq = mlx5_irq_affinity_request(pool, cpumask_of(cpu)); + else + irq = mlx5_irq_request(dev, i, cpumask_of(cpu)); + if (IS_ERR(irq)) { + if (!i) + return PTR_ERR(irq); + return i; + } + irqs[i] = irq; + mlx5_core_dbg(pool->dev, "IRQ %u mapped to cpu %*pbl, %u EQs on this irq\n", + pci_irq_vector(dev->pdev, mlx5_irq_get_index(irq)), + cpumask_pr_args(mlx5_irq_get_affinity_mask(irq)), + mlx5_irq_read_locked(irq) / MLX5_EQ_REFS_PER_IRQ); + } + return i; +} + static struct mlx5_irq_pool * irq_pool_alloc(struct mlx5_core_dev *dev, int start, int size, char *name, u32 min_threshold, u32 max_threshold) @@ -670,6 +746,11 @@ void mlx5_irq_table_destroy(struct mlx5_core_dev *dev) pci_free_irq_vectors(dev->pdev); } +bool mlx5_irq_table_have_dedicated_sfs_irqs(struct mlx5_irq_table *table) +{ + return table->sf_comp_pool; +} + int mlx5_irq_table_get_sfs_vec(struct mlx5_irq_table *table) { if (table->sf_comp_pool)