From patchwork Thu Jan 9 22:48:16 2014 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Upinder Malhi (umalhi)" X-Patchwork-Id: 3463541 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.19.201]) by patchwork2.web.kernel.org (Postfix) with ESMTP id 5F2C5C02DC for ; Thu, 9 Jan 2014 22:48:32 +0000 (UTC) Received: from mail.kernel.org (localhost [127.0.0.1]) by mail.kernel.org (Postfix) with ESMTP id 62FC1200F3 for ; Thu, 9 Jan 2014 22:48:31 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id 6657C20103 for ; Thu, 9 Jan 2014 22:48:30 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1756638AbaAIWs2 (ORCPT ); Thu, 9 Jan 2014 17:48:28 -0500 Received: from mtv-iport-1.cisco.com ([173.36.130.12]:25028 "EHLO mtv-iport-1.cisco.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1756602AbaAIWsW (ORCPT ); Thu, 9 Jan 2014 17:48:22 -0500 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=cisco.com; i=@cisco.com; l=6441; q=dns/txt; s=iport; t=1389307702; x=1390517302; h=from:to:cc:subject:date:message-id:in-reply-to: references; bh=bxHJNjDSHhTUs+6Jgf2ezRe/x1OTMRHLMjcDqOcYkOU=; b=YGfvnr7DPGTecPxqVJAOuyIcvOCadJ2fGIoALimlTASBJ+499+T+ww3c yiu7nBT/PZ/Q5B85Mry2CJQTTNI/RG8ich3kIsm+cwNzjiDQvOSLS18DK /XvC/tfiPvVWOc2MK6ONwblCPkuYY1MbLwu4H7MPKDb7av8sMHRbrn16V s=; X-IronPort-AV: E=Sophos;i="4.95,634,1384300800"; d="scan'208";a="99229753" Received: from mtv-core-4.cisco.com ([171.68.58.9]) by mtv-iport-1.cisco.com with ESMTP; 09 Jan 2014 22:48:21 +0000 Received: from sjc-savbu-bld03.cisco.com (sjc-savbu-bld03.cisco.com [171.71.188.58]) by mtv-core-4.cisco.com (8.14.5/8.14.5) with ESMTP id s09MmKYV011958; Thu, 9 Jan 2014 22:48:20 GMT Received: by sjc-savbu-bld03.cisco.com (Postfix, from userid 246720) id 632E43F7CD; Thu, 9 Jan 2014 14:48:20 -0800 (PST) From: Upinder Malhi To: linux-rdma@vger.kernel.org, roland@kernel.org Cc: Upinder Malhi Subject: [PATCH v1 for-next 3/6] IB:usnic: Add UDP support to usnic_transport.[hc] Date: Thu, 9 Jan 2014 14:48:16 -0800 Message-Id: <1389307699-11545-4-git-send-email-umalhi@cisco.com> X-Mailer: git-send-email 1.8.0-rc0 In-Reply-To: <1389307699-11545-1-git-send-email-umalhi@cisco.com> References: <1389307699-11545-1-git-send-email-umalhi@cisco.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=-14.5 required=5.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, RCVD_IN_DNSWL_HI, RP_MATCHES_RCVD, UNPARSEABLE_RELAY, USER_IN_DEF_DKIM_WL 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 This patch provides API for rest of usNIC code to increment or decrement socket's reference count. Auxiliary socket APIs are also provided. Signed-off-by: Upinder Malhi --- drivers/infiniband/hw/usnic/usnic_transport.c | 93 +++++++++++++++++++++++++-- drivers/infiniband/hw/usnic/usnic_transport.h | 19 ++++++ 2 files changed, 105 insertions(+), 7 deletions(-) diff --git a/drivers/infiniband/hw/usnic/usnic_transport.c b/drivers/infiniband/hw/usnic/usnic_transport.c index 723bd6c..73dffc9 100644 --- a/drivers/infiniband/hw/usnic/usnic_transport.c +++ b/drivers/infiniband/hw/usnic/usnic_transport.c @@ -16,8 +16,10 @@ * */ #include +#include #include #include +#include #include "usnic_transport.h" #include "usnic_log.h" @@ -28,13 +30,15 @@ static u16 roce_next_port = 1; #define ROCE_BITMAP_SZ ((1 << (8 /*CHAR_BIT*/ * sizeof(u16)))/8 /*CHAR BIT*/) static DEFINE_SPINLOCK(roce_bitmap_lock); -static const char *transport_to_str(enum usnic_transport_type type) +const char *usnic_transport_to_str(enum usnic_transport_type type) { switch (type) { case USNIC_TRANSPORT_UNKNOWN: return "Unknown"; case USNIC_TRANSPORT_ROCE_CUSTOM: return "roce custom"; + case USNIC_TRANSPORT_IPV4_UDP: + return "IPv4 UDP"; case USNIC_TRANSPORT_MAX: return "Max?"; default: @@ -42,6 +46,24 @@ static const char *transport_to_str(enum usnic_transport_type type) } } +int usnic_transport_sock_to_str(char *buf, int buf_sz, + struct socket *sock) +{ + int err; + uint32_t addr; + uint16_t port; + int proto; + + memset(buf, 0, buf_sz); + err = usnic_transport_sock_get_addr(sock, &proto, &addr, &port); + if (err) + return 0; + + addr = htonl(addr); + return scnprintf(buf, buf_sz, "Proto:%u Addr:%pI4 Port:%hu", + proto, &addr, port); +} + /* * reserve a port number. if "0" specified, we will try to pick one * starting at roce_next_port. roce_next_port will take on the values @@ -60,7 +82,7 @@ u16 usnic_transport_rsrv_port(enum usnic_transport_type type, u16 port_num) roce_next_port = (port_num & 4095) + 1; } else if (test_bit(port_num, roce_bitmap)) { usnic_err("Failed to allocate port for %s\n", - transport_to_str(type)); + usnic_transport_to_str(type)); spin_unlock(&roce_bitmap_lock); goto out_fail; } @@ -68,12 +90,12 @@ u16 usnic_transport_rsrv_port(enum usnic_transport_type type, u16 port_num) spin_unlock(&roce_bitmap_lock); } else { usnic_err("Failed to allocate port - transport %s unsupported\n", - transport_to_str(type)); + usnic_transport_to_str(type)); goto out_fail; } usnic_dbg("Allocating port %hu for %s\n", port_num, - transport_to_str(type)); + usnic_transport_to_str(type)); return port_num; out_fail: @@ -86,19 +108,19 @@ void usnic_transport_unrsrv_port(enum usnic_transport_type type, u16 port_num) spin_lock(&roce_bitmap_lock); if (!port_num) { usnic_err("Unreserved unvalid port num 0 for %s\n", - transport_to_str(type)); + usnic_transport_to_str(type)); goto out_roce_custom; } if (!test_bit(port_num, roce_bitmap)) { usnic_err("Unreserving invalid %hu for %s\n", port_num, - transport_to_str(type)); + usnic_transport_to_str(type)); goto out_roce_custom; } bitmap_clear(roce_bitmap, port_num, 1); usnic_dbg("Freeing port %hu for %s\n", port_num, - transport_to_str(type)); + usnic_transport_to_str(type)); out_roce_custom: spin_unlock(&roce_bitmap_lock); } else { @@ -106,6 +128,63 @@ out_roce_custom: } } +struct socket *usnic_transport_get_socket(int sock_fd) +{ + struct socket *sock; + int err; + char buf[25]; + + /* sockfd_lookup will internally do a fget */ + sock = sockfd_lookup(sock_fd, &err); + if (!sock) { + usnic_err("Unable to lookup socket for fd %d with err %d\n", + sock_fd, err); + return ERR_PTR(-ENOENT); + } + + usnic_transport_sock_to_str(buf, sizeof(buf), sock); + usnic_dbg("Get sock %s\n", buf); + + return sock; +} + +void usnic_transport_put_socket(struct socket *sock) +{ + char buf[100]; + + usnic_transport_sock_to_str(buf, sizeof(buf), sock); + usnic_dbg("Put sock %s\n", buf); + sockfd_put(sock); +} + +int usnic_transport_sock_get_addr(struct socket *sock, int *proto, + uint32_t *addr, uint16_t *port) +{ + int len; + int err; + struct sockaddr_in sock_addr; + + err = sock->ops->getname(sock, + (struct sockaddr *)&sock_addr, + &len, 0); + if (err) + return err; + + if (sock_addr.sin_family != AF_INET) + return -EINVAL; + + if (proto) + *proto = sock->sk->sk_protocol; + if (port) + *port = ntohs(((struct sockaddr_in *)&sock_addr)->sin_port); + if (addr) + *addr = ntohl(((struct sockaddr_in *) + &sock_addr)->sin_addr.s_addr); + + return 0; +} + + int usnic_transport_init(void) { roce_bitmap = kzalloc(ROCE_BITMAP_SZ, GFP_KERNEL); diff --git a/drivers/infiniband/hw/usnic/usnic_transport.h b/drivers/infiniband/hw/usnic/usnic_transport.h index 091fdaf..21371bb 100644 --- a/drivers/infiniband/hw/usnic/usnic_transport.h +++ b/drivers/infiniband/hw/usnic/usnic_transport.h @@ -21,8 +21,27 @@ #include "usnic_abi.h" +const char *usnic_transport_to_str(enum usnic_transport_type trans_type); +/* + * Returns number of bytes written, excluding null terminator. If + * nothing was written, the function returns 0. + */ +int usnic_transport_sock_to_str(char *buf, int buf_sz, + struct socket *sock); u16 usnic_transport_rsrv_port(enum usnic_transport_type type, u16 port_num); void usnic_transport_unrsrv_port(enum usnic_transport_type type, u16 port_num); +/* + * Do a fget on the socket refered to by sock_fd and returns the socket. + * Socket will not be destroyed before usnic_transport_put_socket has + * been called. + */ +struct socket *usnic_transport_get_socket(int sock_fd); +void usnic_transport_put_socket(struct socket *sock); +/* + * Call usnic_transport_get_socket before calling *_sock_get_addr + */ +int usnic_transport_sock_get_addr(struct socket *sock, int *proto, + uint32_t *addr, uint16_t *port); int usnic_transport_init(void); void usnic_transport_fini(void); #endif /* !USNIC_TRANSPORT_H */