Merge pull request #15543 from grpc/revert-15524-revert_arena_fix

Revert "Revert arena size fix"
diff --git a/src/core/lib/surface/call.cc b/src/core/lib/surface/call.cc
index 8946a7b..86e0afa 100644
--- a/src/core/lib/surface/call.cc
+++ b/src/core/lib/surface/call.cc
@@ -67,6 +67,9 @@
 
 #define MAX_SEND_EXTRA_METADATA_COUNT 3
 
+// Used to create arena for the first call.
+#define ESTIMATED_MDELEM_COUNT 16
+
 /* Status data for a request can come from several sources; this
    enumerates them all, and acts as a priority sorting for which
    status to return to the application - earlier entries override
@@ -323,6 +326,11 @@
   return (parent_call*)gpr_atm_acq_load(&call->parent_call_atm);
 }
 
+size_t grpc_call_get_initial_size_estimate() {
+  return sizeof(grpc_call) + sizeof(batch_control) * MAX_CONCURRENT_BATCHES +
+         sizeof(grpc_linked_mdelem) * ESTIMATED_MDELEM_COUNT;
+}
+
 grpc_error* grpc_call_create(const grpc_call_create_args* args,
                              grpc_call** out_call) {
   GPR_TIMER_SCOPE("grpc_call_create", 0);
diff --git a/src/core/lib/surface/call.h b/src/core/lib/surface/call.h
index 793cce4..e000f13 100644
--- a/src/core/lib/surface/call.h
+++ b/src/core/lib/surface/call.h
@@ -98,6 +98,11 @@
 
 uint8_t grpc_call_is_client(grpc_call* call);
 
+/* Get the estimated memory size for a call BESIDES the call stack. Combined
+ * with the size of the call stack, it helps estimate the arena size for the
+ * initial call. */
+size_t grpc_call_get_initial_size_estimate();
+
 /* Return an appropriate compression algorithm for the requested compression \a
  * level in the context of \a call. */
 grpc_compression_algorithm grpc_call_compression_for_level(
diff --git a/src/core/lib/surface/channel.cc b/src/core/lib/surface/channel.cc
index 0062d0d..a466b32 100644
--- a/src/core/lib/surface/channel.cc
+++ b/src/core/lib/surface/channel.cc
@@ -108,7 +108,8 @@
 
   gpr_atm_no_barrier_store(
       &channel->call_size_estimate,
-      (gpr_atm)CHANNEL_STACK_FROM_CHANNEL(channel)->call_stack_size);
+      (gpr_atm)CHANNEL_STACK_FROM_CHANNEL(channel)->call_stack_size +
+          grpc_call_get_initial_size_estimate());
 
   grpc_compression_options_init(&channel->compression_options);
   for (size_t i = 0; i < args->num_args; i++) {