精品欧美一区二区三区在线观看 _久久久久国色av免费观看性色_国产精品久久在线观看_亚洲第一综合网站_91精品又粗又猛又爽_小泽玛利亚一区二区免费_91亚洲精品国偷拍自产在线观看 _久久精品视频在线播放_美女精品久久久_欧美日韩国产成人在线

Linux對象分配器 Slab 算法

系統 Linux 算法
為了解決小塊內存申請的問題, Linux內核引入了 SLAB 分配算法. Linux 所使用的 SLAB 分配算法 的基礎是 Jeff Bonwick 為SunOS 操作系統首次引入的一種算法。

[[414991]]

本文轉載自微信公眾號「Linux內核那些事」,作者songsong001。轉載本文請聯系Linux內核那些事公眾號。

由于這篇文章寫得比較早, 當時使用的是Linux-2.4.16版本內核, 但不影響整體的源碼分析.

SLAB分配算法

上一節說過Linux內核使用伙伴系統算法來管理內存頁, 但伙伴系統算法分配的單位是內存頁, 就是至少要分配一個或以上的內存塊. 但很多時候我們并不需要分配一個內存頁, 例如我們要申請一個大小為200字節的結構體時, 如果使用伙伴系統分配算法至少申請一個內存頁, 但只使用了200字節的內存, 那么剩余的3896字節就被浪費掉了.

為了解決小塊內存申請的問題, Linux內核引入了 SLAB 分配算法. Linux 所使用的 SLAB 分配算法 的基礎是 Jeff Bonwick 為SunOS 操作系統首次引入的一種算法。在內核中,會為有限的對象集(例如文件描述符和其他常見結構)分配大量內存。Jeff發現對內核中普通對象進行初始化所需的時間超過了對其進行分配和釋放所需的時間。因此他的結論是不應該將內存釋放回一個全局的內存池,而是將內存保持為針對特定目而初始化的狀態。

為了更好的理解 SLAB分配算法, 我們先來介紹一下算法使用到的數據結構.

相關數據結構

SLAB分配算法 有兩個重要的數據結構, 一個是 kmem_cache_t,另外一個是 slab_t . 下面我們先來看看 kmem_cache_t 結構:

  1. struct kmem_cache_s { 
  2. /* 1) each alloc & free */ 
  3.     /* fullpartial firstthen free */ 
  4.     struct list_head    slabs_full; 
  5.     struct list_head    slabs_partial; 
  6.     struct list_head    slabs_free; 
  7.     unsigned int        objsize; 
  8.     unsigned int        flags;  /* constant flags */ 
  9.     unsigned int        num;    /* # of objs per slab */ 
  10.     spinlock_t      spinlock; 
  11. #ifdef CONFIG_SMP 
  12.     unsigned int        batchcount; 
  13. #endif 
  14.  
  15. /* 2) slab additions /removals */ 
  16.     /* order of pgs per slab (2^n) */ 
  17.     unsigned int        gfporder; 
  18.  
  19.     /* force GFP flags, e.g. GFP_DMA */ 
  20.     unsigned int        gfpflags; 
  21.  
  22.     size_t          colour;     /* cache colouring range */ 
  23.     unsigned int        colour_off; /* colour offset */ 
  24.     unsigned int        colour_next;    /* cache colouring */ 
  25.     kmem_cache_t        *slabp_cache; 
  26.     unsigned int        growing; 
  27.     unsigned int        dflags;     /* dynamic flags */ 
  28.  
  29.     /* constructor func */ 
  30.     void (*ctor)(void *, kmem_cache_t *, unsigned long); 
  31.  
  32.     /* de-constructor func */ 
  33.     void (*dtor)(void *, kmem_cache_t *, unsigned long); 
  34.  
  35.     unsigned long       failures; 
  36.  
  37. /* 3) cache creation/removal */ 
  38.     char            name[CACHE_NAMELEN]; 
  39.     struct list_head    next
  40.     ... 
  41. }; 

下面介紹一下kmem_cache_t結構中比較重要的字段:

  • slab_full:完全分配的slab
  • slab_partial:部分分配的slab
  • slab_free:沒有被分配過的slab
  • objsize:存儲的對象大小
  • num:一個slab能夠存儲的對象個數
  • gfporder:一個slab由2gfporder個內存頁組成
  • colour/colour_off/colour_next:著色區大小(后面會講到)

slab_t結構定義如下:

  1. typedef struct slab_s { 
  2.     struct list_head    list; 
  3.     unsigned long       colouroff; 
  4.     void                *s_mem;     /* including colour offset */ 
  5.     unsigned int        inuse;      /* num of objs active in slab */ 
  6.     kmem_bufctl_t       free
  7. } slab_t; 

slab_t結構各個字段的用途如下:

  • list:連接(全滿/部分/全空)鏈
  • colouroff:著色補償
  • s_mem:存儲對象的起始內存地址
  • inuse:已經分配多少個對象
  • free:用于連接空閑的對象

用圖來表示它們之間的關系,如下:

SLAB分配算法初始化

SLAB分配算法的初始化由 kmem_cache_init() 函數完成,如下:

  1. void __init kmem_cache_init(void) 
  2.     size_t left_over; 
  3.  
  4.     init_MUTEX(&cache_chain_sem); 
  5.     INIT_LIST_HEAD(&cache_chain); 
  6.  
  7.     kmem_cache_estimate(0, cache_cache.objsize, 0, 
  8.             &left_over, &cache_cache.num); 
  9.     if (!cache_cache.num) 
  10.         BUG(); 
  11.  
  12.     cache_cache.colour = left_over/cache_cache.colour_off; 
  13.     cache_cache.colour_next = 0; 

這個函數主要用來初始化 cache_cache 這個變量,cache_cache 是一個類型為 kmem_cache_t 的結構體變量,定義如下:

  1. static kmem_cache_t cache_cache = { 
  2.     slabs_full: LIST_HEAD_INIT(cache_cache.slabs_full), 
  3.     slabs_partial:  LIST_HEAD_INIT(cache_cache.slabs_partial), 
  4.     slabs_free: LIST_HEAD_INIT(cache_cache.slabs_free), 
  5.     objsize:    sizeof(kmem_cache_t), 
  6.     flags:      SLAB_NO_REAP, 
  7.     spinlock:   SPIN_LOCK_UNLOCKED, 
  8.     colour_off: L1_CACHE_BYTES, 
  9.     name:       "kmem_cache"
  10. }; 

為什么需要一個這樣的對象呢?因為本身 kmem_cache_t 結構體也是小內存對象,所以也應該有slab分配器來分配的,但這樣就出現“雞蛋和雞誰先出現”的問題。在系統初始化的時候,slab分配器還沒有初始化,所以并不能使用slab分配器來分配一個 kmem_cache_t 對象,這時候只能通過定義一個 kmem_cache_t 類型的靜態變量來來管理slab分配器了,所以 cache_cache 靜態變量就是用來管理slab分配器的。

從上面的代碼可知,cache_cache 的 objsize字段 被設置為 sizeof(kmem_cache_t) 的大小,所以這個對象主要是用來分配不同類型的 kmem_cache_t 對象的。

kmem_cache_init() 函數調用了 kmem_cache_estimate() 函數來計算一個slab能夠保存多少個大小為 cache_cache.objsize 的對象,并保存到 cache_cache.num 字段中。一個slab中不可能全部都用來分配對象的,舉個例子:一個4096字節大小的slab用來分配大小為22字節的對象,可以劃分為186個,但還剩余4字節不能使用的,所以這部分內存用來作為著色區。著色區的作用是為了錯開不同的slab,讓CPU更有效的緩存slab。當然這屬于優化部分,對slab分配算法沒有多大的影響。就是說就算不對slab進行著色操作,slab分配算法還是可以工作起來的。

kmem_cache_t對象申請

kmem_cache_t 是用來管理和分配對象的,所以要使用slab分配器時,必須先申請一個 kmem_cache_t 對象,申請 kmem_cache_t 對象由 kmem_cache_create() 函數進行:

  1. kmem_cache_t * 
  2. kmem_cache_create (const char *name, size_t size, size_t offset, 
  3.     unsigned long flags, void (*ctor)(void*, kmem_cache_t *, unsigned long), 
  4.     void (*dtor)(void*, kmem_cache_t *, unsigned long)) 
  5.     const char *func_nm = KERN_ERR "kmem_create: "
  6.     size_t left_over, align, slab_size; 
  7.     kmem_cache_t *cachep = NULL
  8.  
  9.     ... 
  10.  
  11.     cachep = (kmem_cache_t *) kmem_cache_alloc(&cache_cache, SLAB_KERNEL); 
  12.     if (!cachep) 
  13.         goto opps; 
  14.     memset(cachep, 0, sizeof(kmem_cache_t)); 
  15.  
  16.     ... 
  17.  
  18.     do { 
  19.         unsigned int break_flag = 0; 
  20. cal_wastage: 
  21.         kmem_cache_estimate(cachep->gfporder, size, flags, 
  22.                         &left_over, &cachep->num); 
  23.         if (break_flag) 
  24.             break; 
  25.         if (cachep->gfporder >= MAX_GFP_ORDER) 
  26.             break; 
  27.         if (!cachep->num) 
  28.             goto next
  29.         if (flags & CFLGS_OFF_SLAB && cachep->num > offslab_limit) { 
  30.             cachep->gfporder--; 
  31.             break_flag++; 
  32.             goto cal_wastage; 
  33.         } 
  34.  
  35.         if (cachep->gfporder >= slab_break_gfp_order) 
  36.             break; 
  37.  
  38.         if ((left_over*8) <= (PAGE_SIZE<<cachep->gfporder)) 
  39.             break;  /* Acceptable internal fragmentation. */ 
  40. next
  41.         cachep->gfporder++; 
  42.     } while (1); 
  43.  
  44.     if (!cachep->num) { 
  45.         printk("kmem_cache_create: couldn't create cache %s.\n"name); 
  46.         kmem_cache_free(&cache_cache, cachep); 
  47.         cachep = NULL
  48.         goto opps; 
  49.     } 
  50.     slab_size = L1_CACHE_ALIGN(cachep->num*sizeof(kmem_bufctl_t)+sizeof(slab_t)); 
  51.  
  52.     if (flags & CFLGS_OFF_SLAB && left_over >= slab_size) { 
  53.         flags &= ~CFLGS_OFF_SLAB; 
  54.         left_over -= slab_size; 
  55.     } 
  56.  
  57.     offset += (align-1); 
  58.     offset &= ~(align-1); 
  59.     if (!offset) 
  60.         offset = L1_CACHE_BYTES; 
  61.     cachep->colour_off = offset; 
  62.     cachep->colour = left_over/offset; 
  63.  
  64.     if (!cachep->gfporder && !(flags & CFLGS_OFF_SLAB)) 
  65.         flags |= CFLGS_OPTIMIZE; 
  66.  
  67.     cachep->flags = flags; 
  68.     cachep->gfpflags = 0; 
  69.     if (flags & SLAB_CACHE_DMA) 
  70.         cachep->gfpflags |= GFP_DMA; 
  71.     spin_lock_init(&cachep->spinlock); 
  72.     cachep->objsize = size
  73.     INIT_LIST_HEAD(&cachep->slabs_full); 
  74.     INIT_LIST_HEAD(&cachep->slabs_partial); 
  75.     INIT_LIST_HEAD(&cachep->slabs_free); 
  76.  
  77.     if (flags & CFLGS_OFF_SLAB) 
  78.         cachep->slabp_cache = kmem_find_general_cachep(slab_size,0); 
  79.     cachep->ctor = ctor; 
  80.     cachep->dtor = dtor; 
  81.     strcpy(cachep->namename); 
  82.  
  83. #ifdef CONFIG_SMP 
  84.     if (g_cpucache_up) 
  85.         enable_cpucache(cachep); 
  86. #endif 
  87.  
  88.     down(&cache_chain_sem); 
  89.     { 
  90.         struct list_head *p; 
  91.  
  92.         list_for_each(p, &cache_chain) { 
  93.             kmem_cache_t *pc = list_entry(p, kmem_cache_t, next); 
  94.  
  95.             if (!strcmp(pc->namename)) 
  96.                 BUG(); 
  97.         } 
  98.     } 
  99.  
  100.     list_add(&cachep->next, &cache_chain); 
  101.     up(&cache_chain_sem); 
  102. opps: 
  103.     return cachep; 

kmem_cache_create() 函數比較長,所以上面代碼去掉了一些不那么重要的地方,使代碼更清晰的體現其原理。

在 kmem_cache_create() 函數中,首先調用 kmem_cache_alloc() 函數申請一個 kmem_cache_t 對象,我們看到調用 kmem_cache_alloc() 時,傳入的就是 cache_cache 變量。申請完 kmem_cache_t對象 后需要對其進行初始化操作,主要是對 kmem_cache_t對象 的所有字段進行初始化:

  • 計算需要多少個頁面來作為slab的大小。
  • 計算一個slab能夠分配多少個對象。
  • 計算著色區信息。
  • 初始化 slab_full / slab_partial / slab_free 鏈表。
  • 把申請的 kmem_cache_t對象 保存到 cache_chain 鏈表中。

對象分配

申請完 kmem_cache_t對象 后,就使用通過調用 kmem_cache_alloc() 函數來申請指定的對象。kmem_cache_alloc() 函數代碼如下:

  1. static inline void * kmem_cache_alloc_one_tail (kmem_cache_t *cachep, slab_t *slabp) 
  2.     void *objp; 
  3.  
  4.     ... 
  5.  
  6.     slabp->inuse++; 
  7.     objp = slabp->s_mem + slabp->free*cachep->objsize; 
  8.     slabp->free=slab_bufctl(slabp)[slabp->free]; 
  9.  
  10.     if (unlikely(slabp->free == BUFCTL_END)) { 
  11.         list_del(&slabp->list); 
  12.         list_add(&slabp->list, &cachep->slabs_full); 
  13.     } 
  14.  
  15.     return objp; 
  16.  
  17. #define kmem_cache_alloc_one(cachep)                \ 
  18. ({                                                  \ 
  19.     struct list_head * slabs_partial, * entry;      \ 
  20.     slab_t *slabp;                                  \ 
  21.                                                     \ 
  22.     slabs_partial = &(cachep)->slabs_partial;       \ 
  23.     entry = slabs_partial->next;                    \ 
  24.     if (unlikely(entry == slabs_partial)) {         \ 
  25.         struct list_head * slabs_free;              \ 
  26.         slabs_free = &(cachep)->slabs_free;         \ 
  27.         entry = slabs_free->next;                   \ 
  28.         if (unlikely(entry == slabs_free))          \ 
  29.             goto alloc_new_slab;                    \ 
  30.         list_del(entry);                            \ 
  31.         list_add(entry, slabs_partial);             \ 
  32.     }                                               \ 
  33.     slabp = list_entry(entry, slab_t, list);        \ 
  34.     kmem_cache_alloc_one_tail(cachep, slabp);       \ 
  35. }) 
  36.  
  37. static inline void * __kmem_cache_alloc (kmem_cache_t *cachep, int flags) 
  38.     unsigned long save_flags; 
  39.     void* objp; 
  40.  
  41.     kmem_cache_alloc_head(cachep, flags); 
  42. try_again: 
  43.     local_irq_save(save_flags); 
  44.     ... 
  45.     objp = kmem_cache_alloc_one(cachep); 
  46.  
  47.     local_irq_restore(save_flags); 
  48.     return objp; 
  49. alloc_new_slab: 
  50.     ... 
  51.     local_irq_restore(save_flags); 
  52.     if (kmem_cache_grow(cachep, flags)) 
  53.         goto try_again; 
  54.     return NULL
  55.  
  56. void * kmem_cache_alloc (kmem_cache_t *cachep, int flags) 
  57.     return __kmem_cache_alloc(cachep, flags); 

kmem_cache_alloc() 函數被我展開之后如上代碼,kmem_cache_alloc() 函數的主要步驟是:

從kmem_cache_t對象 的 slab_partial 列表中查找是否有slab可用,如果有就直接從slab中分配一個對象。

如果 slab_partial 列表中沒有可用的slab,那么就從 slab_free 列表中查找可用的slab,如果有可用slab,就從slab分配一個對象,并且把此slab放置到 slab_partial 列表中。

如果 slab_free 列表中沒有可用的slab,那么就調用 kmem_cache_grow() 函數申請新的slab來進行對象的分配。kmem_cache_grow() 函數會調用 __get_free_pages() 函數來申請內存頁并且初始化slab.

一個slab的結構如下圖:

灰色部分是著色區,綠色部分是slab管理結構,黃色部分是空閑對象鏈表的索引,紅色部分是對象的實體。我們可以看到slab結構的s_mem字段指向了對象實體列表的起始地址。

分配對象的時候就是先通過slab結構的free字段查看是否有空閑的對象可用,free字段保存了空閑對象鏈表的首節點索引。

對象釋放

對象的釋放比較簡單,主要通過調用 kmem_cache_free() 函數完成,而 kmem_cache_free() 函數最終會調用 kmem_cache_free_one() 函數,代碼如下:

  1. static inline void kmem_cache_free_one(kmem_cache_t *cachep, void *objp) 
  2.     slab_t* slabp; 
  3.  
  4.     CHECK_PAGE(virt_to_page(objp)); 
  5.  
  6.     slabp = GET_PAGE_SLAB(virt_to_page(objp)); 
  7.  
  8.     { 
  9.         unsigned int objnr = (objp-slabp->s_mem)/cachep->objsize; 
  10.  
  11.         slab_bufctl(slabp)[objnr] = slabp->free
  12.         slabp->free = objnr; 
  13.     } 
  14.     STATS_DEC_ACTIVE(cachep); 
  15.      
  16.     { 
  17.         int inuse = slabp->inuse; 
  18.         if (unlikely(!--slabp->inuse)) { 
  19.             list_del(&slabp->list); 
  20.             list_add(&slabp->list, &cachep->slabs_free); 
  21.         } else if (unlikely(inuse == cachep->num)) { 
  22.             list_del(&slabp->list); 
  23.             list_add(&slabp->list, &cachep->slabs_partial); 
  24.         } 
  25.     } 

對象釋放的時候首先會把對象的索引添加到slab的空閑對象鏈表中,然后根據slab的使用情況移動slab到合適的列表中。

如果slab所有對象都被釋放完時,把slab放置到 slab_free 列表中。

 

如果對象所在的slab原來在 slab_full 中,那么就把slab移動到 slab_partial 中。

 

責任編輯:武曉燕 來源: Linux內核那些事
相關推薦

2009-12-25 15:34:54

slab分配器

2024-12-11 08:18:11

2023-04-03 08:25:02

Linux內存slub

2013-10-12 11:15:09

Linux運維內存管理

2020-12-15 08:54:06

Linux內存碎片化

2024-10-11 10:00:20

2025-07-30 01:27:00

2025-04-11 00:44:00

2025-05-27 02:45:45

2014-09-01 10:09:44

Linux

2013-10-14 10:41:41

分配器buddy syste

2017-01-20 14:21:35

內存分配器存儲

2017-02-08 08:40:21

C++固定內存塊

2017-01-17 16:17:48

C++固定分配器

2020-03-11 13:44:20

編程語言PythonJava

2023-12-22 07:55:38

Go語言分配策略

2018-12-06 10:22:54

Linux內核內存

2023-04-13 14:42:26

PoE供電器PoE交換機

2025-02-10 07:30:00

malloc內存分配器內存

2021-05-27 05:28:18

Linux 內存管理
點贊
收藏

51CTO技術棧公眾號

在哪里可以看毛片| 波多野结衣与黑人| 日韩欧美一级大片| 国产精品久久天天影视| 欧美日韩小视频| 日韩国产精品毛片| 五月婷婷在线播放| 蜜桃视频在线观看一区| 欧美区二区三区| 日韩 中文字幕| 欧美黄页免费| 婷婷综合另类小说色区| 亚洲一区bb| 欧美一级免费片| 久久精品国产网站| 26uuu亚洲伊人春色| 午夜激情福利电影| 色婷婷综合久久久久久| 欧美精品亚洲一区二区在线播放| 久久综合久久网| 在线免费看a| 成人三级在线视频| 国产人妖伪娘一区91| 免费在线视频一区二区| 欧美精品一区二区久久| 亚洲成人a级网| 污污网站免费看| 密臀av在线播放| 亚洲精品va在线观看| 欧美成人一区二区在线| 成人黄色免费视频| 看国产成人h片视频| 91av在线免费观看| 久久久综合久久| 国产精品久久久久久| 亚洲人成网站999久久久综合| 两女双腿交缠激烈磨豆腐| 欧美性xxx| 五月激情丁香一区二区三区| 熟妇熟女乱妇乱女网站| 国产高清视频在线| 91一区二区在线| 国产精品白丝jk白祙| 国产有码在线观看| 奇米888四色在线精品| 91av在线播放视频| 日韩精品视频免费播放| 欧美日韩精品一本二本三本| 久久精品成人动漫| a级黄色免费视频| 国产一区网站| 亚洲欧美国产精品va在线观看| 无码国产69精品久久久久网站| 精品91福利视频| 8x8x8国产精品| 色一情一区二区三区| jvid一区二区三区| 欧美在线一二三| 亚洲精品视频导航| 欧美日韩在线精品一区二区三区激情综合 | 你懂的一区二区三区| 亚洲护士老师的毛茸茸最新章节| 人妻 丝袜美腿 中文字幕| 亚洲网一区二区三区| 日韩精品一区二区三区中文不卡 | 日韩在线观看你懂的| 怡红院一区二区三区| 日韩伦理视频| xxx一区二区| 欧美卡一卡二卡三| 激情久久久久| 欧美洲成人男女午夜视频| 亚洲欧美综合自拍| 日本视频免费一区| 亚洲aaa激情| 好吊色一区二区| 99re视频精品| 亚洲国产日韩美| 国内精品久久久久久野外| 亚洲欧美日韩国产手机在线 | 午夜一级在线看亚洲| 欧美中文字幕第一页| 国产99久久久久久免费看| 麻豆久久一区二区| 91偷拍精品一区二区三区| 好吊视频一区二区三区| 久久综合久久久久88| 亚洲图片小说在线| 青青草原国产在线| 91久久精品一区二区三| 午夜视频在线网站| 国产suv精品一区二区四区视频| 亚洲国产天堂网精品网站| 性高潮久久久久久久| 五月天久久777| 久久久亚洲福利精品午夜| 无码免费一区二区三区| 激情深爱一区二区| 久久影院理伦片| 欧美成人高清在线| 精品magnet| 91欧美一区二区三区| 日韩在线影视| 久久久91精品国产一区不卡| 日韩女优在线观看| 精品在线观看视频| 裸体丰满少妇做受久久99精品| 香蕉视频免费在线播放| 午夜精品视频在线观看| 一级黄色录像在线观看| 欧美韩一区二区| 久久手机免费视频| 日韩三级一区二区| 成人免费视频国产在线观看| 亚洲三级一区| 电影天堂国产精品| 亚洲精品一区二区三区福利| 国产综合精品久久久久成人av| 欧美视频在线观看| 国产精品一区二区三区在线播放| 黄色av小说在线观看| 中文字幕日本乱码精品影院| 丰满人妻中伦妇伦精品app| 精品视频一二| 中文字幕在线观看日韩| 69国产精品视频免费观看| 国产成人精品免费| 中文字幕黄色大片| 国精产品一区二区三区有限公司| 精品国产露脸精彩对白| 美国一级片在线观看| 老司机午夜免费精品视频| 高清国语自产拍免费一区二区三区| 超碰国产在线| 色婷婷狠狠综合| 欧美深性狂猛ⅹxxx深喉 | 国产在线播放观看| 日韩精品中文字幕一区二区| 日韩在线中文视频| 在线视频1卡二卡三卡| 久久久国产午夜精品| 日本中文字幕网址| 精品自拍偷拍| 国模极品一区二区三区| 亚洲美女综合网| 亚洲永久免费视频| www.555国产精品免费| 欧美成人久久| 97超级碰碰| 午夜影院免费在线| 欧美一区二区三区免费观看视频| 日本美女黄色一级片| 精品一区二区三区免费视频| 一区二区三区的久久的视频| 国产亚洲人成a在线v网站| 国产亚洲成av人片在线观看桃| 欧美精品韩国精品| 亚洲国产精品激情在线观看| 国产天堂在线播放| 日韩欧美一区二区三区免费看| 国产精品主播视频| 国产cdts系列另类在线观看| 欧美一区二区三区免费大片| 免费视频网站www| 9l国产精品久久久久麻豆| av免费播放网址| 国产精品欧美三级在线观看| 国产精品电影久久久久电影网| www.黄在线观看| 制服丝袜亚洲精品中文字幕| 欧美三级 欧美一级| 一区二区三区四区激情| 欧美tickling挠脚心丨vk| 国产喷水在线观看| 国产精品18久久久久久久久久久久 | 国产精品私人影院| 成年人网站av| 伊人久久久大香线蕉综合直播| 国内精品国语自产拍在线观看| 天堂√中文最新版在线| 中文字幕欧美亚洲| av手机免费看| 福利精品视频在线| 极品尤物一区二区| 国产美女一区二区| 欧美 日韩 国产 高清| 国产一区毛片| 91免费在线观看网站| 僵尸再翻生在线观看| 这里精品视频免费| 超碰福利在线观看| 在线亚洲一区二区| 欧美成人三级视频| 国产午夜亚洲精品不卡| 99中文字幕在线| 亚洲综合丁香| 丰满人妻一区二区三区53号 | 国产一区二区三区在线观看免费 | 6080午夜不卡| 日韩乱码一区二区| 国产精品免费丝袜| 国产一级二级视频| 久久99精品国产.久久久久| 成人性免费视频| 久久一区二区中文字幕| 国产在线一区二区三区欧美| 男女啪啪999亚洲精品| 国内成人精品一区| 黄色免费在线看| 亚洲午夜精品久久久久久久久久久久| 国产成人免费看一级大黄| 亚洲最大网站| 亚洲第一精品自拍| 国产精品无码白浆高潮| 色老综合老女人久久久| 欧美精品99久久久| 国产精品久久国产精麻豆99网站| 北京富婆泄欲对白| 国产自产高清不卡| 午夜免费精品视频| 亚洲日韩视频| 精品无码av无码免费专区| 日本女优一区| 欧美日韩亚洲免费| 国产精伦一区二区三区| 国产主播精品在线| 51一区二区三区| 欧美在线欧美在线| h片在线观看视频免费| 久久亚洲一区二区三区四区五区高| 国模精品一区二区| 精品亚洲一区二区三区在线播放| www.日日夜夜| 日韩视频一区在线观看| 91肉色超薄丝袜脚交一区二区| 91精品福利视频| 国产成人无码一区二区在线播放| 亚洲高清视频的网址| 永久免费看黄网站| 爆操欧美美女| 欧美日本精品一区二区三区| av大全在线观看| 精品色蜜蜜精品视频在线观看| 国产真实夫妇交换视频| 亚洲综合久久av| 91aaa在线观看| 一区二区三区日韩| 九九热只有精品| 一区二区三区四区亚洲| 欧美成人免费看| 亚洲成人你懂的| 日本一级淫片免费放| 亚洲va国产va欧美va观看| 精品无码一区二区三区电影桃花| 夜夜操天天操亚洲| 国产无遮挡aaa片爽爽| 午夜精品一区二区三区免费视频| 日韩欧美不卡视频| 色婷婷av一区二区三区之一色屋| 日韩精品一区不卡| 欧美日韩欧美一区二区| 97成人在线观看| 欧美一区二区三区在线视频| 成人av一区二区三区在线观看| 精品国产电影一区二区| 色视频在线看| 中文字幕不卡在线视频极品| 一级日本在线| 欧美理论电影在线观看| 久草免费在线色站| 欧美一级在线播放| 日韩网站中文字幕| 成人亲热视频网站| 伊色综合久久之综合久久| 久久久久久久久一区二区| 激情综合网站| 99视频精品全部免费看| 雨宫琴音一区二区在线| 50路60路老熟妇啪啪| 久久99精品一区二区三区| 精品人妻在线视频| 国产午夜精品久久久久久免费视| 亚洲一二三四五六区| 一区二区三区**美女毛片| 在线观看日本视频| 欧美挠脚心视频网站| 日韩一级中文字幕| 中文字幕视频在线免费欧美日韩综合在线看 | 日韩专区在线观看| 免费在线看污片| 国产成人久久久精品一区| 久久gogo国模啪啪裸体| 久久久久久久久久久久久久久久av| 成人在线一区| 成人一区二区免费视频| 日韩成人精品在线| 国产精品高潮粉嫩av| www亚洲人| 国内精品国产三级国产在线专| 国模一区二区| 国产日韩在线一区二区三区| 成人激情免费视频| 国产美女在线一区| 日韩精品乱码免费| 国内精品国产三级国产aⅴ久| 91在线你懂得| 色老板免费视频| 一本色道久久综合亚洲aⅴ蜜桃 | 日韩人妻无码一区二区三区99| 欧美三级午夜理伦三级中视频| 理论片中文字幕| 日韩一区二区三区xxxx| 亚洲精品88| 国产精品免费在线播放| 色琪琪久久se色| 少妇高清精品毛片在线视频| 国产高清精品在线| 国产麻豆a毛片| 色诱视频网站一区| 熟妇高潮一区二区高潮| 久久99热精品| 精品久久久久久久久久岛国gif| 台湾成人av| 视频在线在亚洲| 熟妇高潮一区二区| 一区二区三区视频在线观看| 中文字幕一二三四| 亚洲午夜色婷婷在线| 桃色av一区二区| 国内精品二区| 99精品视频网| 在线免费看黄色片| 亚洲午夜免费电影| www久久久久久| 欧美成人精品在线视频| 一级黄色在线观看| 日韩美一区二区三区| 午夜视频成人| 国产精品免费视频xxxx| 亚洲人成精品久久久| 可以在线看的av网站| 不卡视频在线观看| 日产欧产va高清| 亚洲福利视频网| h片在线观看| 国产一区二区三区黄| 亚洲激情国产| 久久福利小视频| 天天影视网天天综合色在线播放| 亚洲精品中文字幕成人片 | 人与动物性xxxx| 欧美日韩高清在线| 欧美被日视频| 亚洲va欧美va国产综合久久| 亚洲精品二区三区| 黄页网站在线看| 亚洲成精国产精品女| 手机看片福利永久| 热久久免费视频精品| 精品国产网站| www.色欧美| 一区二区三区在线免费播放| www.久久久久久| 性亚洲最疯狂xxxx高清| 蜜桃成人av| 午夜激情av在线| 亚洲六月丁香色婷婷综合久久 | 国产精品资源在线看| 特一级黄色录像| 日韩女同互慰一区二区| 国产夫妻在线播放| 欧美另类高清视频在线| 美女视频黄a大片欧美| 少妇被躁爽到高潮无码文| 精品国产乱码久久久久久蜜臀 | 黄色av免费在线观看| 国产精品青草久久久久福利99| 天天久久综合| 性猛交╳xxx乱大交| 欧美视频在线观看免费| 91caoporn在线| 91精品婷婷国产综合久久蝌蚪| 亚洲精品123区| 老司机福利在线观看| 欧美一二三区在线观看| 欧美办公室脚交xxxx| 亚洲第一导航| 成人美女在线观看| 伊人网av在线| 97超碰蝌蚪网人人做人人爽| 成人在线免费视频观看| 欧美xxxx×黑人性爽| 欧美日韩中文精品| 欧美少妇精品| 国产成人精品免费看在线播放| 99久久精品国产精品久久| 中文字幕在线观看视频一区| 欧美激情一二区| 四季av一区二区三区免费观看| 亚洲精品激情视频|