From da3a2320a2912d0f91fb23938c59f5036ea639b3 Mon Sep 17 00:00:00 2001 From: Soheil Hassas Yeganeh Date: Tue, 26 Mar 2019 17:10:41 -0400 Subject: [PATCH] Ref transport and stream before init of chttp2_stream structure. The stream structure is really big and by the time we get to ref the stream and the transport, the fields are out of cache. We need to ref them immediately, before starting to initialize the stream. This commit introduces a 0-byte Reffer so that we can ref the streams on time before the field initializers. --- .../chttp2/transport/chttp2_transport.cc | 19 ++++++++++++------- .../ext/transport/chttp2/transport/internal.h | 6 ++++++ 2 files changed, 18 insertions(+), 7 deletions(-) diff --git a/src/core/ext/transport/chttp2/transport/chttp2_transport.cc b/src/core/ext/transport/chttp2/transport/chttp2_transport.cc index 404539c9e13..cb6596f9d1f 100644 --- a/src/core/ext/transport/chttp2/transport/chttp2_transport.cc +++ b/src/core/ext/transport/chttp2/transport/chttp2_transport.cc @@ -645,17 +645,22 @@ void grpc_chttp2_stream_unref(grpc_chttp2_stream* s) { } #endif -grpc_chttp2_stream::grpc_chttp2_stream(grpc_chttp2_transport* t, - grpc_stream_refcount* refcount, - const void* server_data, - gpr_arena* arena) - : t(t), refcount(refcount), metadata_buffer{{arena}, {arena}} { +grpc_chttp2_stream::Reffer::Reffer(grpc_chttp2_stream* s) { /* We reserve one 'active stream' that's dropped when the stream is read-closed. The others are for Chttp2IncomingByteStreams that are actively reading */ - GRPC_CHTTP2_STREAM_REF(this, "chttp2"); - GRPC_CHTTP2_REF_TRANSPORT(t, "stream"); + GRPC_CHTTP2_STREAM_REF(s, "chttp2"); + GRPC_CHTTP2_REF_TRANSPORT(s->t, "stream"); +} +grpc_chttp2_stream::grpc_chttp2_stream(grpc_chttp2_transport* t, + grpc_stream_refcount* refcount, + const void* server_data, + gpr_arena* arena) + : t(t), + refcount(refcount), + reffer(this), + metadata_buffer{{arena}, {arena}} { if (server_data) { id = static_cast((uintptr_t)server_data); *t->accepting_stream = this; diff --git a/src/core/ext/transport/chttp2/transport/internal.h b/src/core/ext/transport/chttp2/transport/internal.h index 760324c0c95..e4fd5928f2c 100644 --- a/src/core/ext/transport/chttp2/transport/internal.h +++ b/src/core/ext/transport/chttp2/transport/internal.h @@ -510,6 +510,12 @@ struct grpc_chttp2_stream { void* context; grpc_chttp2_transport* t; grpc_stream_refcount* refcount; + // Reffer is a 0-len structure, simply reffing `t` and `refcount` in its ctor + // before initializing the rest of the stream, to avoid cache misses. This + // field MUST be right after `t` and `refcount`. + struct Reffer { + explicit Reffer(grpc_chttp2_stream* s); + } reffer; grpc_closure destroy_stream; grpc_closure* destroy_stream_arg;