Skip to content

Commit fe6efbd

Browse files
committed
[LIBAUTOCORK]: Allow setting the max number of packets that can be queued
Using the env var AUTOCORK_MAX_QLEN, that will push the pending frames when this the maximum number of packets is reached. This can be useful if the server can make progress with portions of the logical packet being assembled in the kernel. Signed-off-by: Arnaldo Carvalho de Melo <[email protected]>
1 parent da78346 commit fe6efbd

File tree

1 file changed

+39
-7
lines changed

1 file changed

+39
-7
lines changed

libautocork.c

+39-7
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,9 @@
2626

2727
static int autocork_debug = -1;
2828

29+
/* If non-zero says how many app buffers can be autocorked */
30+
static int autocork_max_qlen;
31+
2932
static unsigned int dump_interval = 300; /* 5 minutes */
3033

3134
#define NSEC_PER_SEC 1000000000L
@@ -89,6 +92,7 @@ enum uncorkers {
8992
UNCORKER_recvfrom = 1 << 6,
9093
UNCORKER_recvmsg = 1 << 7,
9194
UNCORKER_select = 1 << 8,
95+
UNCORKER_check_qlen = 1 << 9,
9296
};
9397

9498
static const char *uncorkers_str[] = {
@@ -101,6 +105,7 @@ static const char *uncorkers_str[] = {
101105
"recvfrom",
102106
"recvmsg",
103107
"select",
108+
"check_qlen",
104109
};
105110

106111
static void fprintf_uncorkers(FILE *fp, int mask)
@@ -189,7 +194,7 @@ static void libautocork__fprintf_stats(FILE *fp)
189194
fd_autocork_table[fd].pktsize_stats.min,
190195
fd_autocork_table[fd].pktsize_stats.max);
191196
fprintf_uncorkers(fp, fd_autocork_table[fd].uncorkers);
192-
fputc('\n', fp);
197+
fprintf(fp, " %d\n", autocork_max_qlen);
193198
}
194199
}
195200
fflush(fp);
@@ -217,14 +222,18 @@ static void libautocork__init(void)
217222
if (s != NULL)
218223
dump_interval = atoi(s);
219224

225+
s = getenv("AUTOCORK_MAX_QLEN");
226+
if (s != NULL)
227+
autocork_max_qlen = atoi(s);
228+
220229
if (dump_interval != 0) {
221230
char filename[PATH_MAX];
222231

223232
snprintf(filename, sizeof(filename), "%s/libautocork.%d.debug",
224233
getenv("HOME"), getpid());
225234
dump_fp = fopen(filename, "w");
226235
if (dump_fp != NULL)
227-
fputs("# fd: corklat:samples avg min max qlen:avg min max pktsz:samples avg min max uncorkers\n", dump_fp);
236+
fputs("# fd: corklat:samples avg min max qlen:avg min max pktsz:samples avg min max uncorkers envmaxqlen\n", dump_fp);
228237
}
229238

230239
atexit(libautocork__exit);
@@ -482,16 +491,27 @@ static void set_pending_frames(int fd, size_t len)
482491
stats__add_sample(&fd_autocork_table[fd].pktsize_stats, len);
483492
}
484493

494+
static void check_qlen(int fd)
495+
{
496+
if (autocork_max_qlen != 0 &&
497+
autocork_needed(fd) &&
498+
fd_autocork_table[fd].pending_frames >= autocork_max_qlen)
499+
push_pending_frames(fd, check_qlen);
500+
}
501+
485502
ssize_t write(int fd, const void *buf, size_t count)
486503
{
487504
static ssize_t (*libc_write)(int fd, const void *buf, size_t count);
505+
ssize_t rc;
488506

489507
hook(write);
490508

491509
if (autocork_needed(fd))
492510
set_pending_frames(fd, count);
493511

494-
return libc_write(fd, buf, count);
512+
rc = libc_write(fd, buf, count);
513+
check_qlen(fd);
514+
return rc;
495515
}
496516

497517
static size_t iov_totlen(const struct iovec *iov, int iovcnt)
@@ -507,49 +527,61 @@ static size_t iov_totlen(const struct iovec *iov, int iovcnt)
507527
ssize_t writev(int fd, const struct iovec *iov, int iovcnt)
508528
{
509529
static ssize_t (*libc_writev)(int fd, const struct iovec *iov, int iovcnt);
530+
ssize_t rc;
510531

511532
hook(writev);
512533

513534
if (autocork_needed(fd))
514535
set_pending_frames(fd, iov_totlen(iov, iovcnt));
515536

516-
return libc_writev(fd, iov, iovcnt);
537+
rc = libc_writev(fd, iov, iovcnt);
538+
check_qlen(fd);
539+
return rc;
517540
}
518541

519542
ssize_t send(int s, const void *buf, size_t len, int flags)
520543
{
521544
static ssize_t (*libc_send)(int s, const void *buf, size_t len, int flags);
545+
ssize_t rc;
522546

523547
hook(send);
524548

525549
if (autocork_needed(s))
526550
set_pending_frames(s, len);
527551

528-
return libc_send(s, buf, len, flags);
552+
rc = libc_send(s, buf, len, flags);
553+
check_qlen(s);
554+
return rc;
529555
}
530556

531557
ssize_t sendto(int s, const void *buf, size_t len, int flags,
532558
const struct sockaddr *to, socklen_t tolen)
533559
{
534560
static ssize_t (*libc_sendto)(int s, const void *buf, size_t len, int flags,
535561
const struct sockaddr *to, socklen_t tolen);
562+
ssize_t rc;
536563

537564
hook(sendto);
538565

539566
if (autocork_needed(s))
540567
set_pending_frames(s, len);
541568

542-
return libc_sendto(s, buf, len, flags, to, tolen);
569+
rc = libc_sendto(s, buf, len, flags, to, tolen);
570+
check_qlen(s);
571+
return rc;
543572
}
544573

545574
ssize_t sendmsg(int s, const struct msghdr *msg, int flags)
546575
{
547576
static ssize_t (*libc_sendmsg)(int s, const struct msghdr *msg, int flags);
577+
ssize_t rc;
548578

549579
hook(sendmsg);
550580

551581
if (autocork_needed(s))
552582
set_pending_frames(s, iov_totlen(msg->msg_iov, msg->msg_iovlen));
553583

554-
return libc_sendmsg(s, msg, flags);
584+
rc = libc_sendmsg(s, msg, flags);
585+
check_qlen(s);
586+
return rc;
555587
}

0 commit comments

Comments
 (0)