Use a smaller array for write IOVs. (#27224)

Instead of 1000, use 260 IOVs to make stack overflows less likely.

Also pull the `iov` array to the bottom of the stack, to improve
locality.
pull/27229/head
Soheil Hassas Yeganeh 4 years ago committed by GitHub
parent 9e4c657fa3
commit 7911beacdb
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 14
      src/core/lib/iomgr/tcp_posix.cc

@ -1257,10 +1257,10 @@ void tcp_shutdown_buffer_list(grpc_tcp* tcp) {
}
}
#if defined(IOV_MAX) && IOV_MAX < 1000
#if defined(IOV_MAX) && IOV_MAX < 260
#define MAX_WRITE_IOVEC IOV_MAX
#else
#define MAX_WRITE_IOVEC 1000
#define MAX_WRITE_IOVEC 260
#endif
msg_iovlen_type TcpZerocopySendRecord::PopulateIovs(size_t* unwind_slice_idx,
size_t* unwind_byte_idx,
@ -1305,13 +1305,17 @@ void TcpZerocopySendRecord::UpdateOffsetForBytesSent(size_t sending_length,
// returns true if done, false if pending; if returning true, *error is set
static bool do_tcp_flush_zerocopy(grpc_tcp* tcp, TcpZerocopySendRecord* record,
grpc_error_handle* error) {
struct msghdr msg;
struct iovec iov[MAX_WRITE_IOVEC];
msg_iovlen_type iov_size;
ssize_t sent_length = 0;
size_t sending_length;
size_t unwind_slice_idx;
size_t unwind_byte_idx;
bool tried_sending_message;
msghdr msg;
// iov consumes a large space. Keep it as the last item on the stack to
// improve locality. After all, we expect only the first elements of it being
// populated in most cases.
iovec iov[MAX_WRITE_IOVEC];
while (true) {
sending_length = 0;
iov_size = record->PopulateIovs(&unwind_slice_idx, &unwind_byte_idx,
@ -1321,7 +1325,7 @@ static bool do_tcp_flush_zerocopy(grpc_tcp* tcp, TcpZerocopySendRecord* record,
msg.msg_iov = iov;
msg.msg_iovlen = iov_size;
msg.msg_flags = 0;
bool tried_sending_message = false;
tried_sending_message = false;
// Before calling sendmsg (with or without timestamps): we
// take a single ref on the zerocopy send record.
tcp->tcp_zerocopy_send_ctx.NoteSend(record);

Loading…
Cancel
Save