Index: sbin/ggate/ggatec/ggatec.8 =================================================================== --- sbin/ggate/ggatec/ggatec.8 +++ sbin/ggate/ggatec/ggatec.8 @@ -127,11 +127,9 @@ start to be canceled. Default is 1024. .It Fl R Ar rcvbuf -Size of receive buffer to use. -Default is 131072 (128kB). +Set the size of receive buffer to use instead of the system default. .It Fl S Ar sndbuf -Size of send buffer to use. -Default is 131072 (128kB). +Set the size of send buffer to use instead of the system default. .It Fl s Ar sectorsize Sector size for .Nm ggate Index: sbin/ggate/ggated/ggated.8 =================================================================== --- sbin/ggate/ggated/ggated.8 +++ sbin/ggate/ggated/ggated.8 @@ -37,6 +37,7 @@ .Op Fl v .Op Fl a Ar address .Op Fl p Ar port +.Op Fl q Ar queue_size .Op Fl R Ar rcvbuf .Op Fl S Ar sndbuf .Op Ar "exports file" @@ -67,12 +68,15 @@ .Nm listens for connections. Default is 3080. +.It Fl q Ar queue_size +The number of IOs to queue to the disks at once. +The default is 20. +If you have a large number of disks and/or you are not seeing the expected +number of IOPS, increase this parameter. .It Fl R Ar rcvbuf -Size of receive buffer to use. -Default is 131072 (128kB). +Set the size of receive buffer to use instead of the system default. .It Fl S Ar sndbuf -Size of send buffer to use. -Default is 131072 (128kB). +Set the size of send buffer to use instead of the system default. .It Fl v Do not fork, run in foreground and print debug information on standard output. Index: sbin/ggate/ggated/ggated.c =================================================================== --- sbin/ggate/ggated/ggated.c +++ sbin/ggate/ggated/ggated.c @@ -526,6 +526,7 @@ { pthread_t td; int error, pid; + int i; pid = fork(); if (pid > 0) @@ -577,6 +578,14 @@ g_gate_xlog("pthread_create(recv_thread): %s.", strerror(error)); } + for (i = 0; niothreads && i < niothreads - 1; i++) { + error = pthread_create(&td, NULL, disk_thread, conn); + if (error != 0) { + g_gate_xlog("pthread_create(disk_thread): %s.", + strerror(error)); + } + } + disk_thread(conn); } @@ -957,7 +966,7 @@ for (;;) { int ch; - ch = getopt(argc, argv, "a:hnp:R:S:v"); + ch = getopt(argc, argv, "a:hnp:q:R:S:v"); if (ch == -1) break; switch (ch) { @@ -977,6 +986,11 @@ if (port == 0 && errno != 0) errx(EXIT_FAILURE, "Invalid port."); break; + case 'q': + niothreads = strtol(optarg, NULL, 10); + if (niothreads < 0) + errx(EXIT_FAILURE, "Invalid queue size."); + break; case 'R': errno = 0; rcvbuf = strtoul(optarg, NULL, 10); Index: sbin/ggate/shared/ggate.h =================================================================== --- sbin/ggate/shared/ggate.h +++ sbin/ggate/shared/ggate.h @@ -34,8 +34,6 @@ #define G_GATE_PORT 3080 -#define G_GATE_RCVBUF 131072 -#define G_GATE_SNDBUF 131072 #define G_GATE_QUEUE_SIZE 1024 #define G_GATE_TIMEOUT 0 @@ -59,6 +57,7 @@ extern int g_gate_devfd; extern int g_gate_verbose; +extern int niothreads; extern int nagle; extern unsigned rcvbuf, sndbuf; Index: sbin/ggate/shared/ggate.c =================================================================== --- sbin/ggate/shared/ggate.c +++ sbin/ggate/shared/ggate.c @@ -268,9 +268,10 @@ return (done); } +int niothreads = 20; int nagle = 1; -unsigned rcvbuf = G_GATE_RCVBUF; -unsigned sndbuf = G_GATE_SNDBUF; +unsigned rcvbuf; +unsigned sndbuf; void g_gate_socket_settings(int sfd) @@ -288,12 +289,20 @@ } if (setsockopt(sfd, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on)) == -1) g_gate_xlog("setsockopt(SO_REUSEADDR): %s.", strerror(errno)); - bsize = rcvbuf; - if (setsockopt(sfd, SOL_SOCKET, SO_RCVBUF, &bsize, sizeof(bsize)) == -1) - g_gate_xlog("setsockopt(SO_RCVBUF): %s.", strerror(errno)); - bsize = sndbuf; - if (setsockopt(sfd, SOL_SOCKET, SO_SNDBUF, &bsize, sizeof(bsize)) == -1) - g_gate_xlog("setsockopt(SO_SNDBUF): %s.", strerror(errno)); + if (rcvbuf) { + bsize = rcvbuf; + if (setsockopt(sfd, SOL_SOCKET, SO_RCVBUF, &bsize, + sizeof(bsize)) == -1) + g_gate_xlog("setsockopt(SO_RCVBUF): %s.", + strerror(errno)); + } + if (sndbuf) { + bsize = sndbuf; + if (setsockopt(sfd, SOL_SOCKET, SO_SNDBUF, &bsize, + sizeof(bsize)) == -1) + g_gate_xlog("setsockopt(SO_SNDBUF): %s.", + strerror(errno)); + } tv.tv_sec = 8; tv.tv_usec = 0; if (setsockopt(sfd, SOL_SOCKET, SO_SNDTIMEO, &tv, sizeof(tv)) == -1) {