libceph: tcp_nodelay support
authorChaitanya Huilgol <chaitanya.huilgol@gmail.com>
Fri, 23 Jan 2015 11:11:25 +0000 (16:41 +0530)
committerIlya Dryomov <idryomov@gmail.com>
Thu, 19 Feb 2015 10:31:40 +0000 (13:31 +0300)
TCP_NODELAY socket option set on connection sockets,
disables Nagle’s algorithm and improves latency characteristics.
tcp_nodelay(default)/notcp_nodelay option flags provided to
enable/disable setting the socket option.

Signed-off-by: Chaitanya Huilgol <chaitanya.huilgol@sandisk.com>
[idryomov@redhat.com: NO_TCP_NODELAY -> TCP_NODELAY, minor adjustments]
Signed-off-by: Ilya Dryomov <idryomov@redhat.com>
include/linux/ceph/libceph.h
include/linux/ceph/messenger.h
net/ceph/ceph_common.c
net/ceph/messenger.c

index 8b11a79ca1cbf53630d0546b8a6d50446236d3a9..16fff9608848db88dd2c9bca903bc57ca971f527 100644 (file)
@@ -30,8 +30,9 @@
 #define CEPH_OPT_MYIP             (1<<2) /* specified my ip */
 #define CEPH_OPT_NOCRC            (1<<3) /* no data crc on writes */
 #define CEPH_OPT_NOMSGAUTH       (1<<4) /* not require cephx message signature */
+#define CEPH_OPT_TCP_NODELAY     (1<<5) /* TCP_NODELAY on TCP sockets */
 
-#define CEPH_OPT_DEFAULT   (0)
+#define CEPH_OPT_DEFAULT   (CEPH_OPT_TCP_NODELAY)
 
 #define ceph_set_opt(client, opt) \
        (client)->options->flags |= CEPH_OPT_##opt;
index d9d396c165037a7d6f661a41ec0dccec12f7dd1a..e15499422fdcc7686942ce88389d686d9078cd79 100644 (file)
@@ -57,6 +57,7 @@ struct ceph_messenger {
 
        atomic_t stopping;
        bool nocrc;
+       bool tcp_nodelay;
 
        /*
         * the global_seq counts connections i (attempt to) initiate
@@ -264,7 +265,8 @@ extern void ceph_messenger_init(struct ceph_messenger *msgr,
                        struct ceph_entity_addr *myaddr,
                        u64 supported_features,
                        u64 required_features,
-                       bool nocrc);
+                       bool nocrc,
+                       bool tcp_nodelay);
 
 extern void ceph_con_init(struct ceph_connection *con, void *private,
                        const struct ceph_connection_operations *ops,
index 5d5ab67f516dfa16ee5d86d6c312cf0a201bc3a4..ec565508e904113e65329b89dec5952bf5d41075 100644 (file)
@@ -239,6 +239,8 @@ enum {
        Opt_nocrc,
        Opt_cephx_require_signatures,
        Opt_nocephx_require_signatures,
+       Opt_tcp_nodelay,
+       Opt_notcp_nodelay,
 };
 
 static match_table_t opt_tokens = {
@@ -259,6 +261,8 @@ static match_table_t opt_tokens = {
        {Opt_nocrc, "nocrc"},
        {Opt_cephx_require_signatures, "cephx_require_signatures"},
        {Opt_nocephx_require_signatures, "nocephx_require_signatures"},
+       {Opt_tcp_nodelay, "tcp_nodelay"},
+       {Opt_notcp_nodelay, "notcp_nodelay"},
        {-1, NULL}
 };
 
@@ -457,6 +461,7 @@ ceph_parse_options(char *options, const char *dev_name,
                case Opt_nocrc:
                        opt->flags |= CEPH_OPT_NOCRC;
                        break;
+
                case Opt_cephx_require_signatures:
                        opt->flags &= ~CEPH_OPT_NOMSGAUTH;
                        break;
@@ -464,6 +469,13 @@ ceph_parse_options(char *options, const char *dev_name,
                        opt->flags |= CEPH_OPT_NOMSGAUTH;
                        break;
 
+               case Opt_tcp_nodelay:
+                       opt->flags |= CEPH_OPT_TCP_NODELAY;
+                       break;
+               case Opt_notcp_nodelay:
+                       opt->flags &= ~CEPH_OPT_TCP_NODELAY;
+                       break;
+
                default:
                        BUG_ON(token);
                }
@@ -518,10 +530,12 @@ struct ceph_client *ceph_create_client(struct ceph_options *opt, void *private,
        /* msgr */
        if (ceph_test_opt(client, MYIP))
                myaddr = &client->options->my_addr;
+
        ceph_messenger_init(&client->msgr, myaddr,
                client->supported_features,
                client->required_features,
-               ceph_test_opt(client, NOCRC));
+               ceph_test_opt(client, NOCRC),
+               ceph_test_opt(client, TCP_NODELAY));
 
        /* subsystems */
        err = ceph_monc_init(&client->monc, client);
index 33a2f201e460e1585f82db94c8f3f90f01bbacdf..6b3f54ed65ba6fc4ff392877f662ef5dddeb8939 100644 (file)
@@ -510,6 +510,16 @@ static int ceph_tcp_connect(struct ceph_connection *con)
                return ret;
        }
 
+       if (con->msgr->tcp_nodelay) {
+               int optval = 1;
+
+               ret = kernel_setsockopt(sock, SOL_TCP, TCP_NODELAY,
+                                       (char *)&optval, sizeof(optval));
+               if (ret)
+                       pr_err("kernel_setsockopt(TCP_NODELAY) failed: %d",
+                              ret);
+       }
+
        sk_set_memalloc(sock->sk);
 
        con->sock = sock;
@@ -2922,7 +2932,8 @@ void ceph_messenger_init(struct ceph_messenger *msgr,
                        struct ceph_entity_addr *myaddr,
                        u64 supported_features,
                        u64 required_features,
-                       bool nocrc)
+                       bool nocrc,
+                       bool tcp_nodelay)
 {
        msgr->supported_features = supported_features;
        msgr->required_features = required_features;
@@ -2937,6 +2948,7 @@ void ceph_messenger_init(struct ceph_messenger *msgr,
        get_random_bytes(&msgr->inst.addr.nonce, sizeof(msgr->inst.addr.nonce));
        encode_my_addr(msgr);
        msgr->nocrc = nocrc;
+       msgr->tcp_nodelay = tcp_nodelay;
 
        atomic_set(&msgr->stopping, 0);