From patchwork Wed May 18 14:57:24 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Mark Bloch X-Patchwork-Id: 9119981 Return-Path: X-Original-To: patchwork-linux-rdma@patchwork.kernel.org Delivered-To: patchwork-parsemail@patchwork2.web.kernel.org Received: from mail.kernel.org (mail.kernel.org [198.145.29.136]) by patchwork2.web.kernel.org (Postfix) with ESMTP id 61E79BF29F for ; Wed, 18 May 2016 14:58:27 +0000 (UTC) Received: from mail.kernel.org (localhost [127.0.0.1]) by mail.kernel.org (Postfix) with ESMTP id 60D562034F for ; Wed, 18 May 2016 14:58:26 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id 8A1842034E for ; Wed, 18 May 2016 14:58:21 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1752006AbcERO6U (ORCPT ); Wed, 18 May 2016 10:58:20 -0400 Received: from [193.47.165.129] ([193.47.165.129]:58006 "EHLO mellanox.co.il" rhost-flags-FAIL-FAIL-OK-FAIL) by vger.kernel.org with ESMTP id S1751736AbcERO6U (ORCPT ); Wed, 18 May 2016 10:58:20 -0400 Received: from Internal Mail-Server by MTLPINE1 (envelope-from markb@mellanox.com) with ESMTPS (AES256-SHA encrypted); 18 May 2016 17:57:28 +0300 Received: from r-vnc06.mtr.labs.mlnx (r-vnc06.mtr.labs.mlnx [10.208.0.117]) by labmailer.mlnx (8.13.8/8.13.8) with ESMTP id u4IEvScG026509; Wed, 18 May 2016 17:57:28 +0300 Received: from r-vnc06.mtr.labs.mlnx (localhost.localdomain [127.0.0.1]) by r-vnc06.mtr.labs.mlnx (8.13.8/8.13.8) with ESMTP id u4IEvSau030070; Wed, 18 May 2016 17:57:28 +0300 Received: (from markb@localhost) by r-vnc06.mtr.labs.mlnx (8.13.8/8.13.8/Submit) id u4IEvSct030069; Wed, 18 May 2016 17:57:28 +0300 From: Mark Bloch To: dledford@redhat.com Cc: linux-rdma@vger.kernel.org Subject: [rdma-next, V1 2/4] IB/netlink: Allow multiple clients to register under the same family Date: Wed, 18 May 2016 17:57:24 +0300 Message-Id: <1463583446-30027-3-git-send-email-markb@mellanox.com> X-Mailer: git-send-email 1.8.4.3 In-Reply-To: <1463583446-30027-1-git-send-email-markb@mellanox.com> References: <1463583446-30027-1-git-send-email-markb@mellanox.com> Sender: linux-rdma-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-rdma@vger.kernel.org X-Spam-Status: No, score=-8.3 required=5.0 tests=BAYES_00, RCVD_IN_DNSWL_HI, RP_MATCHES_RCVD, UNPARSEABLE_RELAY autolearn=ham version=3.3.1 X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on mail.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP This commit adds the ability for multiple clients to register to the same family. We will allow this only if there isn't an overlap between them. If there is an overlap, we will fail the latest client registration. Signed-off-by: Mark Bloch --- drivers/infiniband/core/cma.c | 3 ++- drivers/infiniband/core/iwcm.c | 3 ++- drivers/infiniband/core/netlink.c | 37 ++++++++++++++++++++++++++----------- drivers/infiniband/core/sa_query.c | 2 +- include/rdma/rdma_netlink.h | 7 +++++-- 5 files changed, 36 insertions(+), 16 deletions(-) diff --git a/drivers/infiniband/core/cma.c b/drivers/infiniband/core/cma.c index f0c91ba..b1cbf73 100644 --- a/drivers/infiniband/core/cma.c +++ b/drivers/infiniband/core/cma.c @@ -4314,7 +4314,8 @@ err_wq: static void __exit cma_cleanup(void) { cma_configfs_exit(); - ibnl_remove_client(RDMA_NL_RDMA_CM); + ibnl_remove_client(RDMA_NL_RDMA_CM, + RDMA_NL_RDMA_CM_NUM_OPS, cma_cb_table); ib_unregister_client(&cma_client); unregister_netdevice_notifier(&cma_nb); rdma_addr_unregister_client(&addr_client); diff --git a/drivers/infiniband/core/iwcm.c b/drivers/infiniband/core/iwcm.c index f057204..680a1c3 100644 --- a/drivers/infiniband/core/iwcm.c +++ b/drivers/infiniband/core/iwcm.c @@ -1199,7 +1199,8 @@ static void __exit iw_cm_cleanup(void) { unregister_net_sysctl_table(iwcm_ctl_table_hdr); destroy_workqueue(iwcm_wq); - ibnl_remove_client(RDMA_NL_IWCM); + ibnl_remove_client(RDMA_NL_IWCM, RDMA_NL_IWPM_NUM_OPS, + iwcm_nl_cb_table); iwpm_exit(RDMA_NL_IWCM); } diff --git a/drivers/infiniband/core/netlink.c b/drivers/infiniband/core/netlink.c index 9b8c20c..f97cae5 100644 --- a/drivers/infiniband/core/netlink.c +++ b/drivers/infiniband/core/netlink.c @@ -62,6 +62,7 @@ int ibnl_add_client(int index, int nops, { struct ibnl_client *cur; struct ibnl_client *nl_client; + int i; nl_client = kmalloc(sizeof *nl_client, GFP_KERNEL); if (!nl_client) @@ -75,10 +76,15 @@ int ibnl_add_client(int index, int nops, list_for_each_entry(cur, &client_list, list) { if (cur->index == index) { - pr_warn("Client for %d already exists\n", index); - mutex_unlock(&ibnl_mutex); - kfree(nl_client); - return -EINVAL; + for (i = 0; i < min(nops, cur->nops); i++) { + if (cur->cb_table[i].dump && + cb_table[i].dump) { + pr_warn("Client for %d already exists\n", index); + mutex_unlock(&ibnl_mutex); + kfree(nl_client); + return -EINVAL; + } + } } } @@ -90,17 +96,24 @@ int ibnl_add_client(int index, int nops, } EXPORT_SYMBOL(ibnl_add_client); -int ibnl_remove_client(int index) +int ibnl_remove_client(int index, int nops, + const struct ibnl_client_cbs cb_table[]) { struct ibnl_client *cur, *next; + int i; mutex_lock(&ibnl_mutex); list_for_each_entry_safe(cur, next, &client_list, list) { - if (cur->index == index) { - list_del(&(cur->list)); - mutex_unlock(&ibnl_mutex); - kfree(cur); - return 0; + if (cur->index == index && cur->nops == nops) { + for (i = 0; i < nops; i++) { + if (cb_table[i].dump && + cur->cb_table[i].dump) { + list_del(&cur->list); + mutex_unlock(&ibnl_mutex); + kfree(cur); + return 0; + } + } } } pr_warn("Can't remove callback for client idx %d. Not found\n", index); @@ -155,9 +168,11 @@ static int ibnl_rcv_msg(struct sk_buff *skb, struct nlmsghdr *nlh) list_for_each_entry(client, &client_list, list) { if (client->index == index) { - if (op >= client->nops || !client->cb_table[op].dump) + if (op >= client->nops) return -EINVAL; + if (!client->cb_table[op].dump) + continue; /* * For response or local service set_timeout request, * there is no need to use netlink_dump_start. diff --git a/drivers/infiniband/core/sa_query.c b/drivers/infiniband/core/sa_query.c index 3ebd108..83ffa56 100644 --- a/drivers/infiniband/core/sa_query.c +++ b/drivers/infiniband/core/sa_query.c @@ -1841,7 +1841,7 @@ err1: static void __exit ib_sa_cleanup(void) { - ibnl_remove_client(RDMA_NL_LS); + ibnl_remove_client(RDMA_NL_LS, RDMA_NL_LS_NUM_OPS, ib_sa_cb_table); cancel_delayed_work(&ib_nl_timed_work); flush_workqueue(ib_nl_wq); destroy_workqueue(ib_nl_wq); diff --git a/include/rdma/rdma_netlink.h b/include/rdma/rdma_netlink.h index 5852661..c8aef66 100644 --- a/include/rdma/rdma_netlink.h +++ b/include/rdma/rdma_netlink.h @@ -16,7 +16,7 @@ void ibnl_cleanup(void); /** * Add a a client to the list of IB netlink exporters. * @index: Index of the added client - * @nops: Number of supported ops by the added client. + * @nops: Number of max supported ops by the added client. * @cb_table: A table for op->callback * * Returns 0 on success or a negative error code. @@ -27,10 +27,13 @@ int ibnl_add_client(int index, int nops, /** * Remove a client from IB netlink. * @index: Index of the removed IB client. + * @nops: Number of max supported ops by the added client. + * @cb_table: A table for op->callback * * Returns 0 on success or a negative error code. */ -int ibnl_remove_client(int index); +int ibnl_remove_client(int index, int nops, + const struct ibnl_client_cbs cb_table[]); /** * Put a new message in a supplied skb.