<output id="qn6qe"></output>

    1. <output id="qn6qe"><tt id="qn6qe"></tt></output>
    2. <strike id="qn6qe"></strike>

      亚洲 日本 欧洲 欧美 视频,日韩中文字幕有码av,一本一道av中文字幕无码,国产线播放免费人成视频播放,人妻少妇偷人无码视频,日夜啪啪一区二区三区,国产尤物精品自在拍视频首页,久热这里只有精品12

      Perf / Ring Buffer對比

      Perf Buffer常規用法:

      struct addrinfo  //需要上傳給應用層的數據結構
      {
        int ai_flags;         /* Input flags.  */
        int ai_family;        /* Protocol family for socket.  */
        int ai_socktype;      /* Socket type.  */
        int ai_protocol;      /* Protocol for socket.  */
        u32 ai_addrlen;       /* Length of socket address.  */ // CHANGED from socklen_t
        struct sockaddr *ai_addr; /* Socket address for socket.  */
        char *ai_canonname;       /* Canonical name for service location.  */
        struct addrinfo *ai_next; /* Pointer to next in list.  */
      };
      
      
      struct  //Perf Map聲明
      {
          __uint(type, BPF_MAP_TYPE_PERF_EVENT_ARRAY);
         	__uint(key_size, sizeof(int));
      	  __uint(value_size, sizeof(int)); //這里不是 struct addrinfo大小,這里指的是key對應的fd的大小 *****
          __uint(max_entries, 1024);       //最大 fd 數量,這里可以不設置,在應用層設置,會覆蓋這里的值,盡量保證一個cpu對應一個buffer
      		// https://github.com/cilium/ebpf/pull/300
          // https://github.com/cilium/ebpf/issues/209
          // https://github.com/cilium/ebpf/blob/02ebf28c2b0cd7c2c6aaf56031bc54f4684c5850/map.go 的函數 clampPerfEventArraySize() 里面
      } events SEC(".maps");
      
      
      
      SEC("uretprobe/getaddrinfo")
      int getaddrinfo_return(struct pt_regs *ctx) {
      		...
          struct data_t data = {}; //創建棧上結構體,第一次內存拷貝
      		data.xxx = xxx;  //獲取需要的數據
          bpf_perf_event_output(ctx, &events, BPF_F_CURRENT_CPU, &data, sizeof(data)); //將棧上結構體復制到Perf Map中,第二次內存拷貝
      		...
          return 0;
      }
      

      總結: 在棧中申請的結構體,此時ebpf verify驗證器會限制結構體不能超過512字節,影響功能開發。

      發生了2次內存拷貝,消耗性能。

            在對結構體成員賦值完成后,調用bpf_perf_event_output時,如果Perf Map已經滿了。則會發生上傳數據失敗。
      

      Perf Buffer高階用法:

      struct addrinfo  //需要上傳給應用層的數據結構
      {
        int ai_flags;         /* Input flags.  */
        int ai_family;        /* Protocol family for socket.  */
        int ai_socktype;      /* Socket type.  */
        int ai_protocol;      /* Protocol for socket.  */
        u32 ai_addrlen;       /* Length of socket address.  */ // CHANGED from socklen_t
        struct sockaddr *ai_addr; /* Socket address for socket.  */
        char *ai_canonname;       /* Canonical name for service location.  */
        struct addrinfo *ai_next; /* Pointer to next in list.  */
      };
      
      struct {       //Perf Map聲明
      	__uint(type, BPF_MAP_TYPE_PERF_EVENT_ARRAY);
      	__uint(key_size, sizeof(int));
      	__uint(value_size, sizeof(int));
        __uint(max_entries, 1024);
      } events SEC(".maps");
      
      struct {      //高階用法,改為Map堆中創建數據結構
      	__uint(type, BPF_MAP_TYPE_PERCPU_ARRAY);
      	__uint(max_entries, 1);
      	__type(key, int);
      	__type(value, struct event);
      } heap SEC(".maps");
      
      
      SEC("uretprobe/getaddrinfo")
      int getaddrinfo_return(struct pt_regs *ctx) {
      		...
      		struct data_t *data;  //差異點,不創建棧上數據結構
      		int zero = 0;
      	  data = bpf_map_lookup_elem(&heap, &zero); //改為創建在Map堆中
      		data.xxx = xxx;  //獲取需要的數據
          bpf_perf_event_output(ctx, &events, BPF_F_CURRENT_CPU, data, sizeof(*data)); //上傳數據
      		...
          return 0;
      }
      

      總結:內存申請發生在Map提供的堆中,規避棧上申請512字節的限制

           還是存在調用bpf_perf_event_output時,如果Perf Map已經滿了。則會發生上傳數據失敗。
      

      Ring Buffer用法

      struct addrinfo  //需要上傳給應用層的數據結構
      {
        int ai_flags;         /* Input flags.  */
        int ai_family;        /* Protocol family for socket.  */
        int ai_socktype;      /* Socket type.  */
        int ai_protocol;      /* Protocol for socket.  */
        u32 ai_addrlen;       /* Length of socket address.  */ // CHANGED from socklen_t
        struct sockaddr *ai_addr; /* Socket address for socket.  */
        char *ai_canonname;       /* Canonical name for service location.  */
        struct addrinfo *ai_next; /* Pointer to next in list.  */
      };
      
      
      struct {    //Ring buffer聲明,注意此時max_entries代表的是buffer的大小,和Perf buffer中該字段的含義有所不同
      	__uint(type, BPF_MAP_TYPE_RINGBUF);
      	__uint(max_entries, 256 * 1024 /* 256 KB */);
      } events SEC(".maps");
      
      SEC("uretprobe/getaddrinfo")
      int getaddrinfo_return(struct pt_regs *ctx) {
      	...
        
      	struct data_t *data;  //差異點,不創建棧上數據結構
      	data = bpf_ringbuf_reserve(&events, sizeof(*data), 0); //直接在ring buffer中申請空間
      	if (!data)
      		return 0;
      
      	data.xxx = xxx;  //獲取需要的數據
      	bpf_ringbuf_submit(data, 0); //上傳數據
      	return 0;
      }
      

      總結:函數一開始直接在ring buffer中申請空間,申請失敗的話直接就返回了,不會執行后續操作,節省時間,一旦申請成功,即可保證bpf_ringbuf_submit一定不會因為沒有空間失敗,且省去Perf buffer中拷貝結構體的操作。

      差異性

      總結:

      共同點:

      1. Perf/Ring Buffer相對于其他種類map(被動輪詢)來說,提供專用api,通知應用層事件就緒,減少cpu消耗,提高性能。

      2. 采用共享內存,節省復制數據開銷。

      3. Perf/Ring Buffer支持傳入可變長結構。

      差異:

      1. Perf Buffer每個CPU核心一個緩存區,不保證數據順序(fork exec exit),會對我們應用層消費數據造成影響。Ring Buffer多CPU共用一個緩存區且內部實現了自旋鎖,保證數據順序。

      2. Perf Buffer有著兩次數據拷貝動作,當空間不足時,效率低下。 Ring Buffer采用先申請內存,再操作形式,提高效率。

      3. Ring Buffer性能強于Perf Buffer。參考patch 【ringbuf perfbuf 性能對比】

      本文由博客一文多發平臺 OpenWrite 發布!

      posted @ 2021-12-27 17:30  SenberHu  閱讀(506)  評論(0)    收藏  舉報
      主站蜘蛛池模板: 亚洲男人的天堂久久香蕉| 国产乱子伦视频在线播放| 午夜福利一区二区三区在线观看| 久久国产精品老人性| 美女一区二区三区亚洲麻豆| 久久综合免费一区二区三区| 久久精品人人做人人爽97| 福利一区二区不卡国产| 一区二区三区四区黄色网| 亚洲精品自拍在线视频| 国产乱码精品一区二三区| 国产精品亚洲二区在线播放| 久9re热视频这里只有精品免费| 国产午夜精品一区理论片| 正蓝旗| 这里只有精品在线播放| 日韩精品 在线一区二区| 热久在线免费观看视频| 一区二区中文字幕av| 国产视频 视频一区二区| 潘金莲高清dvd碟片| 亚洲综合av男人的天堂| 久久月本道色综合久久| 淮阳县| 2020精品自拍视频曝光| 国产成人综合网在线观看| 亚洲精品人妻中文字幕| 日韩精品中文女同在线播放| 韩国午夜福利片在线观看| 亚洲av成人网在线观看| 国产欧美综合在线观看第十页| 麻豆国产成人AV在线播放| 好先生在线观看免费播放| 久久亚洲av成人无码软件| 毛多水多高潮高清视频| 亚洲精品日韩久久精品| 少妇高潮喷水正在播放| 日韩人妻无码精品久久| 18禁亚洲一区二区三区| 免费黄色大全一区二区三区| 久久精品A一国产成人免费网站|