1 /* 2 * 3 * Copyright 2018 gRPC authors. 4 * 5 * Licensed under the Apache License, Version 2.0 (the "License"); 6 * you may not use this file except in compliance with the License. 7 * You may obtain a copy of the License at 8 * 9 * http://www.apache.org/licenses/LICENSE-2.0 10 * 11 * Unless required by applicable law or agreed to in writing, software 12 * distributed under the License is distributed on an "AS IS" BASIS, 13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 * See the License for the specific language governing permissions and 15 * limitations under the License. 16 * 17 */ 18 19 #ifndef GRPC_CORE_LIB_IOMGR_BUFFER_LIST_H 20 #define GRPC_CORE_LIB_IOMGR_BUFFER_LIST_H 21 22 #include <grpc/support/port_platform.h> 23 24 #include "absl/types/optional.h" 25 26 #include "src/core/lib/iomgr/port.h" 27 28 #include <grpc/support/time.h> 29 30 #include "src/core/lib/gprpp/memory.h" 31 #include "src/core/lib/iomgr/error.h" 32 #include "src/core/lib/iomgr/internal_errqueue.h" 33 34 namespace grpc_core { 35 36 struct ConnectionMetrics { 37 /* Delivery rate in Bytes/s. */ 38 absl::optional<uint64_t> delivery_rate; 39 /* If the delivery rate is limited by the application, this is set to true. */ 40 absl::optional<bool> is_delivery_rate_app_limited; 41 /* Total packets retransmitted. */ 42 absl::optional<uint32_t> packet_retx; 43 /* Total packets retransmitted spuriously. This metric is smaller than or 44 equal to packet_retx. */ 45 absl::optional<uint32_t> packet_spurious_retx; 46 /* Total packets sent. */ 47 absl::optional<uint32_t> packet_sent; 48 /* Total packets delivered. */ 49 absl::optional<uint32_t> packet_delivered; 50 /* Total packets delivered with ECE marked. This metric is smaller than or 51 equal to packet_delivered. */ 52 absl::optional<uint32_t> packet_delivered_ce; 53 /* Total bytes lost so far. */ 54 absl::optional<uint64_t> data_retx; 55 /* Total bytes sent so far. */ 56 absl::optional<uint64_t> data_sent; 57 /* Total bytes in write queue but not sent. */ 58 absl::optional<uint64_t> data_notsent; 59 /* Pacing rate of the connection in Bps */ 60 absl::optional<uint64_t> pacing_rate; 61 /* Minimum RTT observed in usec. */ 62 absl::optional<uint32_t> min_rtt; 63 /* Smoothed RTT in usec */ 64 absl::optional<uint32_t> srtt; 65 /* Send congestion window. */ 66 absl::optional<uint32_t> congestion_window; 67 /* Slow start threshold in packets. */ 68 absl::optional<uint32_t> snd_ssthresh; 69 /* Maximum degree of reordering (i.e., maximum number of packets reodered) 70 on the connection. */ 71 absl::optional<uint32_t> reordering; 72 /* Represents the number of recurring retransmissions of the first sequence 73 that is not acknowledged yet. */ 74 absl::optional<uint8_t> recurring_retrans; 75 /* The cumulative time (in usec) that the transport protocol was busy 76 sending data. */ 77 absl::optional<uint64_t> busy_usec; 78 /* The cumulative time (in usec) that the transport protocol was limited by 79 the receive window size. */ 80 absl::optional<uint64_t> rwnd_limited_usec; 81 /* The cumulative time (in usec) that the transport protocol was limited by 82 the send buffer size. */ 83 absl::optional<uint64_t> sndbuf_limited_usec; 84 }; 85 86 struct Timestamp { 87 gpr_timespec time; 88 ConnectionMetrics metrics; /* Metrics collected with this timestamp */ 89 }; 90 91 struct Timestamps { 92 Timestamp sendmsg_time; 93 Timestamp scheduled_time; 94 Timestamp sent_time; 95 Timestamp acked_time; 96 97 uint32_t byte_offset; /* byte offset relative to the start of the RPC */ 98 99 #ifdef GRPC_LINUX_ERRQUEUE 100 grpc_core::tcp_info info; /* tcp_info collected on sendmsg */ 101 #endif /* GRPC_LINUX_ERRQUEUE */ 102 }; 103 104 /** TracedBuffer is a class to keep track of timestamps for a specific buffer in 105 * the TCP layer. We are only tracking timestamps for Linux kernels and hence 106 * this class would only be used by Linux platforms. For all other platforms, 107 * TracedBuffer would be an empty class. 108 * 109 * The timestamps collected are according to grpc_core::Timestamps declared 110 * above. 111 * 112 * A TracedBuffer list is kept track of using the head element of the list. If 113 * the head element of the list is nullptr, then the list is empty. 114 */ 115 #ifdef GRPC_LINUX_ERRQUEUE 116 class TracedBuffer { 117 public: 118 /** Use AddNewEntry function instead of using this directly. */ TracedBuffer(uint32_t seq_no,void * arg)119 TracedBuffer(uint32_t seq_no, void* arg) 120 : seq_no_(seq_no), arg_(arg), next_(nullptr) {} 121 122 /** Add a new entry in the TracedBuffer list pointed to by head. Also saves 123 * sendmsg_time with the current timestamp. */ 124 static void AddNewEntry(grpc_core::TracedBuffer** head, uint32_t seq_no, 125 int fd, void* arg); 126 127 /** Processes a received timestamp based on sock_extended_err and 128 * scm_timestamping structures. It will invoke the timestamps callback if the 129 * timestamp type is SCM_TSTAMP_ACK. */ 130 static void ProcessTimestamp(grpc_core::TracedBuffer** head, 131 struct sock_extended_err* serr, 132 struct cmsghdr* opt_stats, 133 struct scm_timestamping* tss); 134 135 /** Cleans the list by calling the callback for each traced buffer in the list 136 * with timestamps that it has. */ 137 static void Shutdown(grpc_core::TracedBuffer** head, void* remaining, 138 grpc_error* shutdown_err); 139 140 private: 141 uint32_t seq_no_; /* The sequence number for the last byte in the buffer */ 142 void* arg_; /* The arg to pass to timestamps_callback */ 143 grpc_core::Timestamps ts_; /* The timestamps corresponding to this buffer */ 144 grpc_core::TracedBuffer* next_; /* The next TracedBuffer in the list */ 145 }; 146 #else /* GRPC_LINUX_ERRQUEUE */ 147 class TracedBuffer { 148 public: 149 /* Dummy shutdown function */ Shutdown(grpc_core::TracedBuffer **,void *,grpc_error * shutdown_err)150 static void Shutdown(grpc_core::TracedBuffer** /*head*/, void* /*remaining*/, 151 grpc_error* shutdown_err) { 152 GRPC_ERROR_UNREF(shutdown_err); 153 } 154 }; 155 #endif /* GRPC_LINUX_ERRQUEUE */ 156 157 /** Sets the callback function to call when timestamps for a write are 158 * collected. The callback does not own a reference to error. */ 159 void grpc_tcp_set_write_timestamps_callback(void (*fn)(void*, 160 grpc_core::Timestamps*, 161 grpc_error* error)); 162 163 } /* namespace grpc_core */ 164 165 #endif /* GRPC_CORE_LIB_IOMGR_BUFFER_LIST_H */ 166