Line data Source code
1 : #include "fd_tpu.h" 2 : 3 : #include <assert.h> 4 : 5 : /* fd_tpu_reasm_private.h contains reusable logic of fd_tpu_reasm such 6 : that it can be included in test cases. */ 7 : 8 3 : #define FD_TPU_REASM_MAGIC (0xb4ef0d5ea766713cUL) /* random */ 9 : 10 : /* fd_tpu_reasm_reset initializes all reassembly slots to their initial 11 : state. Corrupts messages currently visible in mcache ring. */ 12 : 13 : void 14 : fd_tpu_reasm_reset( fd_tpu_reasm_t * reasm ); 15 : 16 : /* Accessors **********************************************************/ 17 : 18 : static inline FD_FN_PURE fd_tpu_reasm_slot_t * 19 519912 : fd_tpu_reasm_slots_laddr( fd_tpu_reasm_t * reasm ) { 20 519912 : return (fd_tpu_reasm_slot_t *)( (ulong)reasm + reasm->slots_off ); 21 519912 : } 22 : 23 : static inline FD_FN_PURE fd_tpu_reasm_slot_t const * 24 358869 : fd_tpu_reasm_slots_laddr_const( fd_tpu_reasm_t const * reasm ) { 25 358869 : return (fd_tpu_reasm_slot_t const *)( (ulong)reasm + reasm->slots_off ); 26 358869 : } 27 : 28 : static inline FD_FN_PURE uint * 29 216972 : fd_tpu_reasm_pub_slots_laddr( fd_tpu_reasm_t * reasm ) { 30 216972 : return (uint *)( (ulong)reasm + reasm->pub_slots_off ); 31 216972 : } 32 : 33 : static inline FD_FN_PURE uchar * 34 132135 : fd_tpu_reasm_chunks_laddr( fd_tpu_reasm_t * reasm ) { 35 132135 : return (uchar *)( (ulong)reasm + reasm->chunks_off ); 36 132135 : } 37 : 38 : static inline FD_FN_PURE uchar const * 39 6 : fd_tpu_reasm_chunks_laddr_const( fd_tpu_reasm_t const * reasm ) { 40 6 : return (uchar const *)( (ulong)reasm + reasm->chunks_off ); 41 6 : } 42 : 43 : /* Slot class methods *************************************************/ 44 : 45 : static inline uint 46 : slot_get_idx( fd_tpu_reasm_t const * reasm, 47 358869 : fd_tpu_reasm_slot_t const * slot ) { 48 358869 : ulong slot_idx = (ulong)( slot - fd_tpu_reasm_slots_laddr_const( reasm ) ); 49 358869 : if( FD_UNLIKELY( slot_idx >= (reasm->depth + reasm->burst) ) ) { 50 0 : FD_LOG_CRIT(( "invalid slot pointer! slot_idx=%lu, depth+burst=%u\n", 51 0 : slot_idx, reasm->depth + reasm->burst )); 52 0 : } 53 358869 : return (uint)slot_idx; 54 358869 : } 55 : 56 : FD_FN_PURE static inline uchar * 57 : slot_get_data( fd_tpu_reasm_t * reasm, 58 132132 : ulong slot_idx ) { 59 132132 : return fd_tpu_reasm_chunks_laddr( reasm ) + (slot_idx * FD_TPU_REASM_MTU); 60 132132 : } 61 : 62 : FD_FN_PURE static inline uchar const * 63 : slot_get_data_const( fd_tpu_reasm_t const * reasm, 64 6 : ulong slot_idx ) { 65 6 : return fd_tpu_reasm_chunks_laddr_const( reasm ) + (slot_idx * FD_TPU_REASM_MTU); 66 6 : } 67 : 68 : static FD_FN_UNUSED void 69 76203 : slot_begin( fd_tpu_reasm_slot_t * slot ) { 70 76203 : memset( slot, 0, sizeof(fd_tpu_reasm_slot_t) ); 71 76203 : slot->state = FD_TPU_REASM_STATE_BUSY; 72 76203 : } 73 : 74 : /* Slot queue methods *************************************************/ 75 : 76 : /* slotq_push_head adds the given slot to the reassembly queue head. 77 : Assumes queue element count > 2. */ 78 : 79 : static FD_FN_UNUSED void 80 : slotq_push_head( fd_tpu_reasm_t * reasm, 81 76203 : fd_tpu_reasm_slot_t * slot ) { 82 : 83 76203 : uint slot_idx = slot_get_idx( reasm, slot ); 84 76203 : uint head_idx = reasm->head; 85 : 86 76203 : fd_tpu_reasm_slot_t * head = fd_tpu_reasm_slots_laddr( reasm ) + head_idx; 87 : 88 76203 : head->prev_idx = slot_idx; 89 76203 : slot->prev_idx = UINT_MAX; 90 76203 : slot->next_idx = head_idx; 91 76203 : reasm->head = slot_idx; 92 76203 : } 93 : 94 : /* slotq_push_tail adds the given slot to the reassembly queue tail. 95 : Assumes queue element count > 2. */ 96 : 97 : static FD_FN_UNUSED void 98 : slotq_push_tail( fd_tpu_reasm_t * reasm, 99 75267 : fd_tpu_reasm_slot_t * slot ) { 100 : 101 75267 : uint slot_idx = slot_get_idx( reasm, slot ); 102 75267 : uint tail_idx = reasm->tail; 103 75267 : FD_TEST( tail_idx < reasm->slot_cnt ); 104 : 105 75267 : fd_tpu_reasm_slot_t * tail = fd_tpu_reasm_slots_laddr( reasm ) + tail_idx; 106 : 107 75267 : tail->next_idx = slot_idx; 108 75267 : slot->prev_idx = tail_idx; 109 75267 : slot->next_idx = UINT_MAX; 110 75267 : reasm->tail = slot_idx; 111 75267 : } 112 : 113 : /* slotq_pop_tail removes a slot from the reassembly queue tail. 114 : Assumes queue element count > 2. */ 115 : 116 : static FD_FN_UNUSED fd_tpu_reasm_slot_t * 117 76203 : slotq_pop_tail( fd_tpu_reasm_t * reasm ) { 118 : 119 76203 : uint tail_idx = reasm->tail; 120 76203 : fd_tpu_reasm_slot_t * tail = fd_tpu_reasm_slots_laddr( reasm ) + tail_idx; 121 76203 : uint slot_idx = tail->prev_idx; 122 76203 : fd_tpu_reasm_slot_t * slot = fd_tpu_reasm_slots_laddr( reasm ) + slot_idx; 123 : 124 76203 : slot->next_idx = UINT_MAX; 125 76203 : reasm->tail = slot_idx; 126 76203 : return tail; 127 76203 : } 128 : 129 : /* slotq_remove removes a slot at an arbitrary position in the 130 : reassembly queue. Aborts the process if the slot is not part of the 131 : queue. Assumes queue element count > 2. */ 132 : 133 : static FD_FN_UNUSED void 134 : slotq_remove( fd_tpu_reasm_t * reasm, 135 75267 : fd_tpu_reasm_slot_t * slot ) { 136 : 137 75267 : uint slot_idx = slot_get_idx( reasm, slot ); 138 75267 : uint prev_idx = slot->prev_idx; 139 75267 : uint next_idx = slot->next_idx; 140 : 141 75267 : slot->prev_idx = UINT_MAX; 142 75267 : slot->next_idx = UINT_MAX; 143 : 144 75267 : fd_tpu_reasm_slot_t * prev = fd_tpu_reasm_slots_laddr( reasm ) + prev_idx; 145 75267 : fd_tpu_reasm_slot_t * next = fd_tpu_reasm_slots_laddr( reasm ) + next_idx; 146 : 147 75267 : if( slot_idx==reasm->head ) { 148 1164 : if( FD_UNLIKELY( next_idx >= reasm->slot_cnt ) ) { 149 0 : FD_LOG_ERR(( "OOB next_idx (next_idx=%u, slot_cnt=%u)", next_idx, reasm->slot_cnt )); 150 0 : } 151 1164 : reasm->head = next_idx; 152 1164 : next->prev_idx = UINT_MAX; 153 1164 : return; 154 1164 : } 155 74103 : if( slot_idx==reasm->tail ) { 156 0 : if( FD_UNLIKELY( prev_idx >= reasm->slot_cnt ) ) { 157 0 : FD_LOG_ERR(( "OOB prev_idx (prev_idx=%u, slot_cnt=%u)", prev_idx, reasm->slot_cnt )); 158 0 : } 159 0 : reasm->tail = prev_idx; 160 0 : prev->next_idx = UINT_MAX; 161 0 : return; 162 0 : } 163 : 164 74103 : assert( prev_idx < reasm->slot_cnt ); 165 74103 : assert( next_idx < reasm->slot_cnt ); 166 74103 : if( FD_UNLIKELY( prev_idx >= reasm->slot_cnt ) ) { 167 0 : FD_LOG_ERR(( "OOB prev_idx (prev_idx=%u, slot_cnt=%u)", prev_idx, reasm->slot_cnt )); 168 0 : } 169 74103 : if( FD_UNLIKELY( next_idx >= reasm->slot_cnt ) ) { 170 0 : FD_LOG_ERR(( "OOB next_idx (next_idx=%u, slot_cnt=%u)", next_idx, reasm->slot_cnt )); 171 0 : } 172 74103 : prev->next_idx = next_idx; 173 74103 : next->prev_idx = prev_idx; 174 74103 : }