From patchwork Fri Apr 18 21:55:42 2014 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Hefty, Sean" X-Patchwork-Id: 4018741 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.19.201]) by patchwork1.web.kernel.org (Postfix) with ESMTP id 9CCA29F38C for ; Fri, 18 Apr 2014 21:56:10 +0000 (UTC) Received: from mail.kernel.org (localhost [127.0.0.1]) by mail.kernel.org (Postfix) with ESMTP id A6B0B203A9 for ; Fri, 18 Apr 2014 21:56:09 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id 8DEAC2025B for ; Fri, 18 Apr 2014 21:56:08 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1753935AbaDRV4G (ORCPT ); Fri, 18 Apr 2014 17:56:06 -0400 Received: from mga03.intel.com ([143.182.124.21]:9361 "EHLO mga03.intel.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1754564AbaDRV4E (ORCPT ); Fri, 18 Apr 2014 17:56:04 -0400 Received: from azsmga001.ch.intel.com ([10.2.17.19]) by azsmga101.ch.intel.com with ESMTP; 18 Apr 2014 14:55:57 -0700 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="4.97,886,1389772800"; d="scan'208";a="420918650" Received: from cst-linux.jf.intel.com ([10.23.221.72]) by azsmga001.ch.intel.com with ESMTP; 18 Apr 2014 14:55:56 -0700 From: sean.hefty@intel.com To: linux-rdma@vger.kernel.org Cc: Sean Hefty Subject: [PATCH librdmacm 3/4] rsocket: Modify when control messages are available Date: Fri, 18 Apr 2014 14:55:42 -0700 Message-Id: <1397858143-22402-3-git-send-email-sean.hefty@intel.com> X-Mailer: git-send-email 1.7.3 In-Reply-To: <1397858143-22402-1-git-send-email-sean.hefty@intel.com> References: <1397858143-22402-1-git-send-email-sean.hefty@intel.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=-7.5 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 From: Sean Hefty Rsockets currently tracks how many control messages (i.e. entries in the send queue) that are available using a single ctrl_avail counter. Seems simple enough. However, control messages currently require the use of inline data. In order to support control messages that do not use inline data, we need to associate each control message with a specific data buffer. This will become easier to manage if we modify how we track when control messages are available. We replace the single ctrl_avail counter with two new counters. The new counters conceptually treat control messages as if each message had its own sequence number. The sequence number will then be able to correspond to a specific data buffer in a follow up patch. ctrl_seqno will be used to indicate the current control message being sent. ctrl_max_seqno will track the highest control message that may be sent. A side effect of this change is that we will be able to see how many control messages have been sent. This also separates the updating of the control count on the sending side, versus the receiving side. Signed-off-by: Sean Hefty --- src/rsocket.c | 46 ++++++++++++++++++++++++++++++---------------- 1 files changed, 30 insertions(+), 16 deletions(-) diff --git a/src/rsocket.c b/src/rsocket.c index ea18ba7..77b3979 100644 --- a/src/rsocket.c +++ b/src/rsocket.c @@ -308,7 +308,8 @@ struct rsocket { uint64_t tcp_opts; unsigned int keepalive_time; - int ctrl_avail; + unsigned int ctrl_seqno; + unsigned int ctrl_max_seqno; uint16_t sseq_no; uint16_t sseq_comp; uint16_t rseq_no; @@ -563,6 +564,7 @@ static void rs_remove(struct rsocket *rs) pthread_mutex_unlock(&mut); } +/* We only inherit from listening sockets */ static struct rsocket *rs_alloc(struct rsocket *inherited_rs, int type) { struct rsocket *rs; @@ -585,7 +587,7 @@ static struct rsocket *rs_alloc(struct rsocket *inherited_rs, int type) rs->sq_size = inherited_rs->sq_size; rs->rq_size = inherited_rs->rq_size; if (type == SOCK_STREAM) { - rs->ctrl_avail = inherited_rs->ctrl_avail; + rs->ctrl_max_seqno = inherited_rs->ctrl_max_seqno; rs->target_iomap_size = inherited_rs->target_iomap_size; } } else { @@ -595,7 +597,7 @@ static struct rsocket *rs_alloc(struct rsocket *inherited_rs, int type) rs->sq_size = def_sqsize; rs->rq_size = def_rqsize; if (type == SOCK_STREAM) { - rs->ctrl_avail = RS_QP_CTRL_SIZE; + rs->ctrl_max_seqno = RS_QP_CTRL_SIZE; rs->target_iomap_size = def_iomap_size; } } @@ -723,7 +725,7 @@ static int rs_init_bufs(struct rsocket *rs) rs->rbuf_free_offset = rs->rbuf_size >> 1; rs->rbuf_bytes_avail = rs->rbuf_size >> 1; - rs->sqe_avail = rs->sq_size - rs->ctrl_avail; + rs->sqe_avail = rs->sq_size - rs->ctrl_max_seqno; rs->rseq_comp = rs->rq_size >> 1; return 0; } @@ -1786,11 +1788,11 @@ static void rs_send_credits(struct rsocket *rs) struct ibv_sge ibsge; struct rs_sge sge; - rs->ctrl_avail--; + rs->ctrl_seqno++; rs->rseq_comp = rs->rseq_no + (rs->rq_size >> 1); if (rs->rbuf_bytes_avail >= (rs->rbuf_size >> 1)) { if (rs->opts & RS_OPT_MSG_SEND) - rs->ctrl_avail--; + rs->ctrl_seqno++; if (!(rs->opts & RS_OPT_SWAP_SGL)) { sge.addr = (uintptr_t) &rs->rbuf[rs->rbuf_free_offset]; @@ -1824,16 +1826,27 @@ static void rs_send_credits(struct rsocket *rs) } } +static inline int rs_ctrl_avail(struct rsocket *rs) +{ + return rs->ctrl_seqno != rs->ctrl_max_seqno; +} + +/* Protocols that do not support RDMA write with immediate may require 2 msgs */ +static inline int rs_2ctrl_avail(struct rsocket *rs) +{ + return (int)((rs->ctrl_seqno + 1) - rs->ctrl_max_seqno) < 0; +} + static int rs_give_credits(struct rsocket *rs) { if (!(rs->opts & RS_OPT_MSG_SEND)) { return ((rs->rbuf_bytes_avail >= (rs->rbuf_size >> 1)) || ((short) ((short) rs->rseq_no - (short) rs->rseq_comp) >= 0)) && - rs->ctrl_avail && (rs->state & rs_connected); + rs_ctrl_avail(rs) && (rs->state & rs_connected); } else { return ((rs->rbuf_bytes_avail >= (rs->rbuf_size >> 1)) || ((short) ((short) rs->rseq_no - (short) rs->rseq_comp) >= 0)) && - (rs->ctrl_avail > 1) && (rs->state & rs_connected); + rs_2ctrl_avail(rs) && (rs->state & rs_connected); } } @@ -1895,10 +1908,10 @@ static int rs_poll_cq(struct rsocket *rs) } else { switch (rs_msg_op(rs_wr_data(wc.wr_id))) { case RS_OP_SGL: - rs->ctrl_avail++; + rs->ctrl_max_seqno++; break; case RS_OP_CTRL: - rs->ctrl_avail++; + rs->ctrl_max_seqno++; if (rs_msg_data(rs_wr_data(wc.wr_id)) == RS_CTRL_DISCONNECT) rs->state = rs_disconnected; break; @@ -2237,7 +2250,7 @@ static int rs_conn_can_send(struct rsocket *rs) static int rs_conn_can_send_ctrl(struct rsocket *rs) { - return rs->ctrl_avail || !(rs->state & rs_connected); + return rs_ctrl_avail(rs) || !(rs->state & rs_connected); } static int rs_have_rdata(struct rsocket *rs) @@ -2252,7 +2265,8 @@ static int rs_conn_have_rdata(struct rsocket *rs) static int rs_conn_all_sends_done(struct rsocket *rs) { - return ((rs->sqe_avail + rs->ctrl_avail) == rs->sq_size) || + return ((((int) rs->ctrl_max_seqno) - ((int) rs->ctrl_seqno)) + + rs->sqe_avail == rs->sq_size) || !(rs->state & rs_connected); } @@ -3189,14 +3203,14 @@ int rshutdown(int socket, int how) goto out; ctrl = RS_CTRL_DISCONNECT; } - if (!rs->ctrl_avail) { + if (!rs_ctrl_avail(rs)) { ret = rs_process_cq(rs, 0, rs_conn_can_send_ctrl); if (ret) goto out; } - if ((rs->state & rs_connected) && rs->ctrl_avail) { - rs->ctrl_avail--; + if ((rs->state & rs_connected) && rs_ctrl_avail(rs)) { + rs->ctrl_seqno++; ret = rs_post_msg(rs, rs_msg_set(RS_OP_CTRL, ctrl)); } } @@ -4158,7 +4172,7 @@ static void tcp_svc_process_sock(struct rs_svc *svc) static void tcp_svc_send_keepalive(struct rsocket *rs) { fastlock_acquire(&rs->cq_lock); - if ((rs->ctrl_avail > 1) && (rs->state & rs_connected)) + if (rs_2ctrl_avail(rs) && (rs->state & rs_connected)) rs_send_credits(rs); fastlock_release(&rs->cq_lock); }