From patchwork Wed May 4 15:41:56 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Leon Romanovsky X-Patchwork-Id: 9016251 Return-Path: X-Original-To: patchwork-linux-rdma@patchwork.kernel.org Delivered-To: patchwork-parsemail@patchwork1.web.kernel.org Received: from mail.kernel.org (mail.kernel.org [198.145.29.136]) by patchwork1.web.kernel.org (Postfix) with ESMTP id C838C9F30C for ; Wed, 4 May 2016 15:42:55 +0000 (UTC) Received: from mail.kernel.org (localhost [127.0.0.1]) by mail.kernel.org (Postfix) with ESMTP id 2B1F720382 for ; Wed, 4 May 2016 15:42:53 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id 236B82025B for ; Wed, 4 May 2016 15:42:52 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1752499AbcEDPmv (ORCPT ); Wed, 4 May 2016 11:42:51 -0400 Received: from mail.kernel.org ([198.145.29.136]:59857 "EHLO mail.kernel.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1752032AbcEDPmv (ORCPT ); Wed, 4 May 2016 11:42:51 -0400 Received: from mail.kernel.org (localhost [127.0.0.1]) by mail.kernel.org (Postfix) with ESMTP id 428E620382; Wed, 4 May 2016 15:42:49 +0000 (UTC) Received: from localhost (unknown [193.47.165.251]) (using TLSv1.2 with cipher AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPSA id C543B2025B; Wed, 4 May 2016 15:42:47 +0000 (UTC) From: Leon Romanovsky To: dledford@redhat.com Cc: linux-rdma@vger.kernel.org, markb@mellanox.com, majd@mellanox.com, matanb@mellanox.com, Leon Romanovsky Subject: [PATCH rdma-next 2/4] IB/netlink: Allow multiple clients to register under the same family Date: Wed, 4 May 2016 18:41:56 +0300 Message-Id: <1462376518-6725-3-git-send-email-leon@kernel.org> X-Mailer: git-send-email 2.1.4 In-Reply-To: <1462376518-6725-1-git-send-email-leon@kernel.org> References: <1462376518-6725-1-git-send-email-leon@kernel.org> X-Spam-Status: No, score=-9.0 required=5.0 tests=BAYES_00, RCVD_IN_DNSWL_HI, RP_MATCHES_RCVD, UNPARSEABLE_RELAY autolearn=unavailable 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 Sender: linux-rdma-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-rdma@vger.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP From: Mark Bloch 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 Signed-off-by: Leon Romanovsky --- 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 09a0243..8d93ab1 100644 --- a/drivers/infiniband/core/cma.c +++ b/drivers/infiniband/core/cma.c @@ -4312,7 +4312,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 5011ecf..0efa1e7 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 ff2dcbb..06e9de0 100644 --- a/drivers/infiniband/core/netlink.c +++ b/drivers/infiniband/core/netlink.c @@ -66,6 +66,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) @@ -79,10 +80,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; + } + } } } @@ -94,17 +100,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); @@ -159,9 +172,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 5050c61..62dc8dd 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.