日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

VPP TCP定时器

發布時間:2023/12/14 编程问答 35 豆豆
生活随笔 收集整理的這篇文章主要介紹了 VPP TCP定时器 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

對于多線程VPP,為主線程和worker線程分別分配timer_wheel,處理函數為tcp_expired_timers_dispatch。

static clib_error_t * tcp_main_enable (vlib_main_t * vm) {vlib_thread_main_t *vtm = vlib_get_thread_main ();num_threads = 1 /* main thread */ + vtm->n_threads;vec_validate (tm->wrk_ctx, num_threads - 1);n_workers = num_threads == 1 ? 1 : vtm->n_threads;for (thread = 0; thread < num_threads; thread++){ wrk = &tm->wrk_ctx[thread];tcp_timer_initialize_wheel (&wrk->timer_wheel,tcp_expired_timers_dispatch,vlib_time_now (vm));}

超時處理函數中,首先根據線程號獲得對應的tcp_worker_ctx_t上下文結構,并且獲取當前待處理的定時器數量。

static void tcp_expired_timers_dispatch (u32 * expired_timers) {u32 thread_index = vlib_get_thread_index (), n_left, max_per_loop;u32 connection_index, timer_id, n_expired, max_loops;tcp_worker_ctx_t *wrk;tcp_connection_t *tc;int i;wrk = tcp_get_worker (thread_index);n_expired = vec_len (expired_timers);tcp_worker_stats_inc (wrk, timer_expirations, n_expired);n_left = clib_fifo_elts (wrk->pending_timers);

遍歷超時的定時器,參數expired_timers的每個元素,最高的4位保存了定時器的ID,后28位保存了TCP連接的索引值。如果定時器ID為重傳的SYN報文定時器,由函數tcp_half_open_connection_get獲取TCP連接結構(實際上是根據連接索引,在線程號為0的TCP worker結構中獲取TCP連接);否則,由函數tcp_connection_get根據當前的線程號和連接索引獲取TCP連接結構。

此處將TCP連接的定時器處理句柄設置為無效,設置掛起定時器ID。

/** Invalidate all timer handles before dispatching. This avoids dangling* index references to timer wheel pool entries that have been freed.*/for (i = 0; i < n_expired; i++){connection_index = expired_timers[i] & 0x0FFFFFFF;timer_id = expired_timers[i] >> 28;if (timer_id != TCP_TIMER_RETRANSMIT_SYN)tc = tcp_connection_get (connection_index, thread_index);elsetc = tcp_half_open_connection_get (connection_index);TCP_EVT (TCP_EVT_TIMER_POP, connection_index, timer_id);tc->timers[timer_id] = TCP_TIMER_HANDLE_INVALID;tc->pending_timers |= (1 << timer_id);}

將到期的定時器添加到worker結構中的掛起定時器。之后,計算每次循環最多處理的定時器數量。首先確定最大的循環次數max_loops,即最大時長0.5 * TCP_TIMER_TICK,乘以每一秒的循環數量,即最大的循環次數。其次,所有待處理的定時器(n_left+n_expired)除以max_loops即為每次循環的最大數量。最后,最大值不能大于每次最多可處理的最大向量長度VLIB_FRAME_SIZE(256),

clib_fifo_add (wrk->pending_timers, expired_timers, n_expired);max_loops =clib_max ((u32) 0.5 * TCP_TIMER_TICK * wrk->vm->loops_per_second, 1);max_per_loop = clib_max ((n_left + n_expired) / max_loops, 10);max_per_loop = clib_min (max_per_loop, VLIB_FRAME_SIZE);wrk->max_timers_per_loop = clib_max (n_left ? wrk->max_timers_per_loop : 0,max_per_loop);if (thread_index == 0)session_queue_run_on_main_thread (wrk->vm);

掛起定時器處理函數tcp_dispatch_pending_timers如下,如果TCP線程結構中沒有掛起的定時器,結束處理。

static void tcp_dispatch_pending_timers (tcp_worker_ctx_t * wrk) {u32 n_timers, connection_index, timer_id, thread_index, timer_handle;tcp_connection_t *tc;int i;if (!(n_timers = clib_fifo_elts (wrk->pending_timers)))return;

每次遍歷處理的定時器數量不能超過以上計算得到到max_timers_per_loop的值,如果掛起定時器已經被重置,即TCP連接的pending_timers已經不再置位,不進行處理。

thread_index = wrk->vm->thread_index;for (i = 0; i < clib_min (n_timers, wrk->max_timers_per_loop); i++){clib_fifo_sub1 (wrk->pending_timers, timer_handle);connection_index = timer_handle & 0x0FFFFFFF;timer_id = timer_handle >> 28;if (PREDICT_TRUE (timer_id != TCP_TIMER_RETRANSMIT_SYN))tc = tcp_connection_get (connection_index, thread_index);elsetc = tcp_half_open_connection_get (connection_index);if (PREDICT_FALSE (!tc))continue;/* Skip if the timer is not pending. Probably it was reset while* waiting for dispatch */if (PREDICT_FALSE (!(tc->pending_timers & (1 << timer_id))))continue;tc->pending_timers &= ~(1 << timer_id);/* Skip timer if it was rearmed while pending dispatch */if (PREDICT_FALSE (tc->timers[timer_id] != TCP_TIMER_HANDLE_INVALID))continue;

否則,調用定時器ID注冊的超時處理函數,處理超時的TCP連接。

(*timer_expiration_handlers[timer_id]) (tc);}if (thread_index == 0 && clib_fifo_elts (wrk->pending_timers))session_queue_run_on_main_thread (wrk->vm); }

TCP連接定義了如下的四種定時器。

#define foreach_tcp_timer \_(RETRANSMIT, "RETRANSMIT") \_(PERSIST, "PERSIST") \_(WAITCLOSE, "WAIT CLOSE") \_(RETRANSMIT_SYN, "RETRANSMIT SYN") \typedef enum _tcp_timers { #define _(sym, str) TCP_TIMER_##sym,foreach_tcp_timer #undef _TCP_N_TIMERS } __clib_packed tcp_timers_e;

以上四種定時器對應如下四個超時處理函數。

static timer_expiration_handler *timer_expiration_handlers[TCP_N_TIMERS] = {tcp_timer_retransmit_handler,tcp_timer_persist_handler,tcp_timer_waitclose_handler,tcp_timer_retransmit_syn_handler, };

總結

以上是生活随笔為你收集整理的VPP TCP定时器的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。