From patchwork Sun Dec 23 17:14:54 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Yishai Hadas X-Patchwork-Id: 10741773 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 606691880 for ; Sun, 23 Dec 2018 17:15:25 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 405A528736 for ; Sun, 23 Dec 2018 17:15:25 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 3541F2873E; Sun, 23 Dec 2018 17:15:25 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-7.9 required=2.0 tests=BAYES_00,MAILING_LIST_MULTI, RCVD_IN_DNSWL_HI,UNPARSEABLE_RELAY autolearn=ham version=3.3.1 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id A24D428739 for ; Sun, 23 Dec 2018 17:15:24 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1725817AbeLWRPW (ORCPT ); Sun, 23 Dec 2018 12:15:22 -0500 Received: from mail-il-dmz.mellanox.com ([193.47.165.129]:41680 "EHLO mellanox.co.il" rhost-flags-OK-OK-OK-FAIL) by vger.kernel.org with ESMTP id S1725796AbeLWRPW (ORCPT ); Sun, 23 Dec 2018 12:15:22 -0500 Received: from Internal Mail-Server by MTLPINE1 (envelope-from yishaih@mellanox.com) with ESMTPS (AES256-SHA encrypted); 23 Dec 2018 19:21:37 +0200 Received: from vnc17.mtl.labs.mlnx (vnc17.mtl.labs.mlnx [10.7.2.17]) by labmailer.mlnx (8.13.8/8.13.8) with ESMTP id wBNHFDAS030327; Sun, 23 Dec 2018 19:15:13 +0200 Received: from vnc17.mtl.labs.mlnx (vnc17.mtl.labs.mlnx [127.0.0.1]) by vnc17.mtl.labs.mlnx (8.13.8/8.13.8) with ESMTP id wBNHFDOE007168; Sun, 23 Dec 2018 19:15:13 +0200 Received: (from yishaih@localhost) by vnc17.mtl.labs.mlnx (8.13.8/8.13.8/Submit) id wBNHFDmd007167; Sun, 23 Dec 2018 19:15:13 +0200 From: Yishai Hadas To: linux-rdma@vger.kernel.org Cc: yishaih@mellanox.com, michaelgur@mellanox.com, jgg@mellanox.com, majd@mellanox.com Subject: [PATCH rdma-core 3/6] verbs: Make ibv_query_port extendable Date: Sun, 23 Dec 2018 19:14:54 +0200 Message-Id: <1545585297-6677-4-git-send-email-yishaih@mellanox.com> X-Mailer: git-send-email 1.8.2.3 In-Reply-To: <1545585297-6677-1-git-send-email-yishaih@mellanox.com> References: <1545585297-6677-1-git-send-email-yishaih@mellanox.com> 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: Jason Gunthorpe To be able to add new fields to the end of the struct without breaking the ABI introduce a new query function that takes the length of the struct as an argument and have the inline wrapper preserve the user API. Signed-off-by: Jason Gunthorpe Signed-off-by: Yishai Hadas --- libibverbs/device.c | 8 +++++++ libibverbs/dummy_ops.c | 2 +- libibverbs/ibverbs.h | 2 ++ libibverbs/verbs.c | 53 +++++++++++++++++++++++++++++++++++++++++++++-- libibverbs/verbs.h | 27 ++++++++++++++++++------ providers/bnxt_re/verbs.c | 1 - 6 files changed, 83 insertions(+), 10 deletions(-) diff --git a/libibverbs/device.c b/libibverbs/device.c index 1fed29b..d710513 100644 --- a/libibverbs/device.c +++ b/libibverbs/device.c @@ -306,6 +306,14 @@ err_free: static void set_lib_ops(struct verbs_context *vctx) { vctx->create_cq_ex = __lib_ibv_create_cq_ex; + + /* + * The compat symver entry point behaves identically to what used to + * be pointed to by _compat_query_port. + */ +#undef ibv_query_port + vctx->context.ops._compat_query_port = ibv_query_port; + vctx->query_port = __lib_query_port; } struct ibv_context *verbs_open_device(struct ibv_device *device, void *private_data) diff --git a/libibverbs/dummy_ops.c b/libibverbs/dummy_ops.c index a5e9380..c861c3a 100644 --- a/libibverbs/dummy_ops.c +++ b/libibverbs/dummy_ops.c @@ -616,7 +616,7 @@ void verbs_set_ops(struct verbs_context *vctx, SET_OP(ctx, post_srq_recv); SET_PRIV_OP(ctx, query_device); SET_OP(vctx, query_device_ex); - SET_PRIV_OP(ctx, query_port); + SET_PRIV_OP_IC(ctx, query_port); SET_PRIV_OP(ctx, query_qp); SET_OP(vctx, query_rt_values); SET_OP(vctx, read_counters); diff --git a/libibverbs/ibverbs.h b/libibverbs/ibverbs.h index 36e29a6..6e4cff4 100644 --- a/libibverbs/ibverbs.h +++ b/libibverbs/ibverbs.h @@ -58,6 +58,8 @@ int ibverbs_get_device_list(struct list_head *list); int ibverbs_init(void); void ibverbs_device_put(struct ibv_device *dev); void ibverbs_device_hold(struct ibv_device *dev); +int __lib_query_port(struct ibv_context *context, uint8_t port_num, + struct ibv_port_attr *port_attr, size_t port_attr_len); #ifdef _STATIC_LIBRARY_BUILD_ static inline void load_drivers(void) diff --git a/libibverbs/verbs.c b/libibverbs/verbs.c index 5edd1bb..3540ef2 100644 --- a/libibverbs/verbs.c +++ b/libibverbs/verbs.c @@ -145,12 +145,61 @@ LATEST_SYMVER_FUNC(ibv_query_device, 1_1, "IBVERBS_1.1", return get_ops(context)->query_device(context, device_attr); } +int __lib_query_port(struct ibv_context *context, uint8_t port_num, + struct ibv_port_attr *port_attr, size_t port_attr_len) +{ + /* Don't expose this mess to the provider, provide a large enough + * temporary buffer if the user buffer is too small. + */ + if (port_attr_len < sizeof(struct ibv_port_attr)) { + struct ibv_port_attr tmp_attr = {}; + int rc; + + rc = get_ops(context)->query_port(context, port_num, + &tmp_attr); + if (rc) + return rc; + + memcpy(port_attr, &tmp_attr, port_attr_len); + return 0; + } + + memset(port_attr, 0, port_attr_len); + return get_ops(context)->query_port(context, port_num, port_attr); +} + +struct _compat_ibv_port_attr { + enum ibv_port_state state; + enum ibv_mtu max_mtu; + enum ibv_mtu active_mtu; + int gid_tbl_len; + uint32_t port_cap_flags; + uint32_t max_msg_sz; + uint32_t bad_pkey_cntr; + uint32_t qkey_viol_cntr; + uint16_t pkey_tbl_len; + uint16_t lid; + uint16_t sm_lid; + uint8_t lmc; + uint8_t max_vl_num; + uint8_t sm_sl; + uint8_t subnet_timeout; + uint8_t init_type_reply; + uint8_t active_width; + uint8_t active_speed; + uint8_t phys_state; + uint8_t link_layer; + uint8_t flags; +}; + LATEST_SYMVER_FUNC(ibv_query_port, 1_1, "IBVERBS_1.1", int, struct ibv_context *context, uint8_t port_num, - struct ibv_port_attr *port_attr) + struct _compat_ibv_port_attr *port_attr) { - return get_ops(context)->query_port(context, port_num, port_attr); + return __lib_query_port(context, port_num, + (struct ibv_port_attr *)port_attr, + sizeof(*port_attr)); } LATEST_SYMVER_FUNC(ibv_query_gid, 1_1, "IBVERBS_1.1", diff --git a/libibverbs/verbs.h b/libibverbs/verbs.h index caf78f4..4851c72 100644 --- a/libibverbs/verbs.h +++ b/libibverbs/verbs.h @@ -1661,9 +1661,12 @@ struct ibv_device { char ibdev_path[IBV_SYSFS_PATH_MAX]; }; +struct _compat_ibv_port_attr; struct ibv_context_ops { void *(*_compat_query_device)(void); - void *(*_compat_query_port)(void); + int (*_compat_query_port)(struct ibv_context *context, + uint8_t port_num, + struct _compat_ibv_port_attr *port_attr); void *(*_compat_alloc_pd)(void); void *(*_compat_dealloc_pd)(void); void *(*_compat_reg_mr)(void); @@ -1786,6 +1789,9 @@ struct ibv_values_ex { struct verbs_context { /* "grows up" - new fields go here */ + int (*query_port)(struct ibv_context *context, uint8_t port_num, + struct ibv_port_attr *port_attr, + size_t port_attr_len); int (*advise_mr)(struct ibv_pd *pd, enum ibv_advise_mr_advice advice, uint32_t flags, @@ -1997,17 +2003,26 @@ int ibv_query_device(struct ibv_context *context, * ibv_query_port - Get port properties */ int ibv_query_port(struct ibv_context *context, uint8_t port_num, - struct ibv_port_attr *port_attr); + struct _compat_ibv_port_attr *port_attr); static inline int ___ibv_query_port(struct ibv_context *context, uint8_t port_num, struct ibv_port_attr *port_attr) { - /* For compatibility when running with old libibverbs */ - port_attr->link_layer = IBV_LINK_LAYER_UNSPECIFIED; - port_attr->flags = 0; + struct verbs_context *vctx = verbs_get_ctx_op(context, query_port); - return ibv_query_port(context, port_num, port_attr); + if (!vctx) { + int rc; + + memset(port_attr, 0, sizeof(*port_attr)); + + rc = ibv_query_port(context, port_num, + (struct _compat_ibv_port_attr *)port_attr); + return rc; + } + + return vctx->query_port(context, port_num, port_attr, + sizeof(*port_attr)); } #define ibv_query_port(context, port_num, port_attr) \ diff --git a/providers/bnxt_re/verbs.c b/providers/bnxt_re/verbs.c index 39b29b0..7786d24 100644 --- a/providers/bnxt_re/verbs.c +++ b/providers/bnxt_re/verbs.c @@ -74,7 +74,6 @@ int bnxt_re_query_port(struct ibv_context *ibvctx, uint8_t port, { struct ibv_query_port cmd; - memset(port_attr, 0, sizeof(struct ibv_port_attr)); return ibv_cmd_query_port(ibvctx, port, port_attr, &cmd, sizeof(cmd)); }