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

Linux內存管理--slab及其代碼解析

系統 Linux
Linux內核使用了源自于 Solaris 的一種方法,但是這種方法在嵌入式系統中已經使用了很長時間了,它是將內存作為對象按照大小進行分配,被稱為slab高速緩存。內存管理的目標是提供一種方法,為實現各種目的而在各個用戶之間實現內存共享。

Linux內核使用了源自于 Solaris 的一種方法,但是這種方法在嵌入式系統中已經使用了很長時間了,它是將內存作為對象按照大小進行分配,被稱為slab高速緩存。

內存管理的目標是提供一種方法,為實現各種目的而在各個用戶之間實現內存共享。內存管理方法應該實現以下兩個功能:

  • 最小化管理內存所需的時間
  • ***化用于一般應用的可用內存(最小化管理開銷)

內存管理實際上是一種關于權衡的零和游戲。您可以開發一種使用少量內存進行管理的算法,但是要花費更多時間來管理可用內存。也可以開發一個算法來有效地管理內存,但卻要使用更多的內存。最終,特定應用程序的需求將促使對這種權衡作出選擇。

每個內存管理器都使用了一種基于堆的分配策略。在這種方法中,大塊內存(稱為 堆)用來為用戶定義的目的提供內存。當用戶需要一塊內存時,就請求給自己分配一定大小的內存。堆管理器會查看可用內存的情況(使用特定算法)并返回一塊內存。搜索過程中使用的一些算法有 first-fit(在堆中搜索到的***個滿足請求的內存塊)和 best-fit(使用堆中滿足請求的最合適的內存塊)。當用戶使用完內存后,就將內存返回給堆。

這種基于堆的分配策略的根本問題是碎片(fragmentation)。當內存塊被分配后,它們會以不同的順序在不同的時間返回。這樣會在堆中留下一些洞,需要花一些時間才能有效地管理空閑內存。這種算法通常具有較高的內存使用效率(分配需要的內存),但是卻需要花費更多時間來對堆進行管理。

另外一種方法稱為 buddy memory allocation,是一種更快的內存分配技術,它將內存劃分為 2 的冪次方個分區,并使用 best-fit 方法來分配內存請求。當用戶釋放內存時,就會檢查 buddy 塊,查看其相鄰的內存塊是否也已經被釋放。如果是的話,將合并內存塊以最小化內存碎片。這個算法的時間效率更高,但是由于使用 best-fit 方法的緣故,會產生內存浪費。

slab 緩存

Linux 所使用的 slab 分配器的基礎是 Jeff Bonwick 為 SunOS 操作系統***引入的一種算法。Jeff 的分配器是圍繞對象緩存進行的。在內核中,會為有限的對象集(例如文件描述符和其他常見結構)分配大量內存。Jeff 發現對內核中普通對象進行初始化所需的時間超過了對其進行分配和釋放所需的時間。因此他的結論是不應該將內存釋放回一個全局的內存池,而是將內存保持為針對特定目而初始化的狀態。例如,如果內存被分配給了一個互斥鎖,那么只需在為互斥鎖***分配內存時執行一次互斥鎖初始化函數(mutex_init)即可。后續的內存分配不需要執行這個初始化函數,因為從上次釋放和調用析構之后,它已經處于所需的狀態中了。

Linux slab 分配器使用了這種思想和其他一些思想來構建一個在空間和時間上都具有高效性的內存分配器。

圖 1 給出了 slab 結構的高層組織結構。在***層是 cache_chain,這是一個 slab 緩存的鏈接列表。這對于 best-fit 算法非常有用,可以用來查找最適合所需要的分配大小的緩存(遍歷列表)。cache_chain 的每個元素都是一個 kmem_cache 結構的引用(稱為一個 cache)。它定義了一個要管理的給定大小的對象池。

圖 1. slab 分配器的主要結構

每個緩存都包含了一個 slabs 列表,這是一段連續的內存塊(通常都是頁面)。存在 3 種 slab:

slabs_full

完全分配的 slab

slabs_partial

部分分配的 slab

slabs_empty

空 slab,或者沒有對象被分配

注意:slabs_empty 列表中的 slab 是進行回收(reaping)的主要備選對象。正是通過此過程,slab 所使用的內存被返回給操作系統供其他用戶使用。

slab 列表中的每個 slab 都是一個連續的內存塊(一個或多個連續頁),它們被劃分成一個個對象。這些對象是從特定緩存中進行分配和釋放的基本元素。注意 slab 是 slab 分配器進行操作的最小分配單位,因此如果需要對 slab 進行擴展,這也就是所擴展的最小值。通常來說,每個 slab 被分配為多個對象。

由于對象是從 slab 中進行分配和釋放的,因此單個 slab 可以在 slab 列表之間進行移動。例如,當一個 slab 中的所有對象都被使用完時,就從 slabs_partial 列表中移動到 slabs_full 列表中。當一個 slab 完全被分配并且有對象被釋放后,就從 slabs_full 列表中移動到 slabs_partial 列表中。當所有對象都被釋放之后,就從 slabs_partial 列表移動到 slabs_empty 列表中。

#p#

一、slab相關數據結構


1)slab高速緩存描述符

  1. struct kmem_cache {   
  2.     struct array_cache   *array[NR_CPUS];//為了提高效率,每個cpu都有一個slab空閑對象緩存   
  3. /* 2) Cache tunables. Protected by cache_chain_mutex */   
  4.     unsigned int batchcount;//從本地高速緩存批量移入或移出對象的數目   
  5.     unsigned int limit;//本地高速緩存空閑對象的***數目   
  6.     unsigned int shared;   
  7.     unsigned int buffer_size;   
  8.     struct kmem_list3 *nodelists[MAX_NUMNODES];//slab高速緩存空閑,部分空閑,無空閑slab的三個鏈表   
  9.    
  10.     unsigned int flags;     /* constant flags */   
  11.     unsigned int num;//每個slab obj的個數   
  12.     unsigned int gfporder;//每個slab中連續頁框的數目   
  13.     gfp_t gfpflags;//分配頁框時,傳遞給伙伴系統的標志   
  14.     size_t colour;//slab使用的顏色個數   
  15.     unsigned int colour_off; //slab的顏色偏移   
  16.     struct kmem_cache *slabp_cache;  //指向存放slab描述符的chache,內部slab此字段為null   
  17.     unsigned int slab_size;//單個slab的大小   
  18.     unsigned int dflags;        /* dynamic flags */   
  19.     //對象創建的構建函數   
  20.     void (*ctor) (void *, struct kmem_cache *, unsigned long);   
  21.     //對象的析構函數   
  22.     void (*dtor) (void *, struct kmem_cache *, unsigned long);   
  23.     const char *name;//slab高速緩存的名稱   
  24.     struct list_head next;//通過該字段,將該cachep鏈接到cachep鏈表上   
  25. }   

2)slab描述符

  1. struct slab {   
  2.     struct list_head list;  //將slab鏈接到各個slab鏈表上面,slabs_full, slabs_paril, slabs_free   
  3.     unsigned long colouroff;//slab中***個對象的偏移   
  4.     void *s_mem; //slab中***個對象的地址           
  5.     unsigned int inuse; //有多少對象正在被使用   
  6.     kmem_bufctl_t free; //表明接下來使用哪個空閑對象   
  7.     unsigned short nodeid;//該slab屬于哪個內存節點   

slab描述符可能會被存放在兩個地方:

外部slab描述符:存放在slab外部,位于cache_size指向的一個普通高速緩存中。

內部slab描述符:存放在slab的內部,位于分配給slab的內存的***個頁框的起始位置。

3)slab隊列描述符

  1. struct kmem_list3 {   
  2.     struct list_head slabs_partial; //對象被使用了一部分的slab描述符的鏈表   
  3.     struct list_head slabs_full;//對象都被占用了的slab描述符的鏈表   
  4.     struct list_head slabs_free;//只包含空閑對象的slab描述符的鏈表   
  5.     unsigned long free_objects;//高速緩存中空閑對象的個數   
  6.     unsigned int free_limit;   
  7.     unsigned int colour_next;   /* Per-node cache coloring */   
  8.     spinlock_t list_lock;   
  9.     struct array_cache *shared; //指向所有cpu所共享的一個本地高速緩存 
  10.     struct array_cache **alien; /* on other nodes */   
  11.     unsigned long next_reap;    //由slab的頁回收算法使用   
  12.     int free_touched;       //由slab的頁回收算法使用   

4)slab對象描述符

  1. typedef unsigned int kmem_bufctl_t; 

每個對象都有一個類型為kmem_bufctl_t的對象描述符,每個slab描述符都有一個kmem_bufctl_t類型的數組來描述slab中的各個對象。其實該描述符記錄的是下一個可用的空閑對象,使用了數組的索引來形成一個對象鏈表而已。對象描述符也分為內部對象描述符和外部對象描述符兩種:

  1. 內部對象描述符:存放在slab的內部,位于描述符所描述的對象的前面。
  2. 外部對象描述符:存放在slab的外部,位于高速緩存描述符slabp_cache字段指向的一個普通高速緩存中,

slab描述符和slab對象之間的組織圖如下圖所示:

二、slab的本地對象緩存


Linux2.6為了更好的支持多處理器,減少自旋鎖的競爭并更好的利用硬件高速緩存,slab分配器的每個高速緩存都包含一個被稱為slab本地高速緩存的每cpu數據結構,該結構由一個指向被釋放對象的指針數組組成。這樣的話,slab對象的釋放和分配就只影響到本地的指針數組,減少了并發性。只有本地數組上溢或者下溢時才會去涉及slab結構。相關數據結構如下:

  1. struct array_cache {   
  2.     unsigned int avail;//本地高速緩存中可用對象的個數,也是空閑數組位置的索引   
  3.     unsigned int limit;//本地高速緩存的大小   
  4.     unsigned int batchcount;//本地高速緩存填充或者清空時使用到的對象個數   
  5.     unsigned int touched;//如果本地高速緩存最近被使用過,置成1   
  6.     spinlock_t lock;   
  7.     void *entry[0];    

同時在多cpu的環境下,還存在著一個共享高速緩存,它的地址被存放在高速緩存描述符的lists.shared字段中,本地共享高速緩存被所有cpu所共享,使得對象從一個本地高速緩存移至另一個高速緩存變的簡單。

三、slab內存著色


比如cache line 32 字節,字節0-31一次從內存寫入/讀取,字節32-63一次從內存寫入/讀取…..

另外cache對應到內存位置不是任意的

Cache 地址0 對應到 內存地址0 , 32 ,64 ….

Cache 地址1 對應到 內存地址1 , 33 ,65 ….

一個slab大小肯定是整數頁,所以起始地址末12位為零, 即都于cache0 對應。然后2個slab的每一個obj大小一樣, 所以2個slab每個obj都對應相同的cache line.這樣2個位置相同的obj都要頻繁訪問,比較容易使cache來回刷新,效率降低。

著色就是在第二個slab的起始位置空一個cache line出來,這樣2個slab每個obj對應的cache錯開一個,這樣2個位置相同的obj即使頻繁訪問,也不會用一個相同cache line。

但是這種方法也是有限的,2個slab里面的obj對象的訪問比較隨即,不能保證哪兩個在一個cache line 里。

#p#

四、slab內存的申請


內核代碼中通過slab分配對象的函數時kmem_cachep_alloc(),實質上***調用的函數是____cache_alloc(),其相應源碼解析如下:

  1. static inline void *____cache_alloc(struct kmem_cache *cachep, gfp_t flags)   
  2. {   
  3.     void *objp;   
  4.     struct array_cache *ac;   
  5.    
  6.     check_irq_off();   
  7.     //通過進程所在的cpu的id獲取slab的本地高速緩存   
  8.     ac = cpu_cache_get(cachep);   
  9.     //本地高速緩存中是否有空閑的slab對象   
  10.     if (likely(ac->avail)) {   
  11.         //有空閑對象的話,從本地高速緩存數組上取一個空閑的對象來使用   
  12.         STATS_INC_ALLOCHIT(cachep);   
  13.         //標記一下該本地高速緩存最近被使用過   
  14.         ac->touched = 1;   
  15.         //從數組的***面先取一個未使用的對象,HOHO   
  16.         objp = ac->entry[--ac->avail];   
  17.     } else {   
  18.         STATS_INC_ALLOCMISS(cachep);   
  19.         //本地高速緩存中已經沒有空閑對象,需要填充本地高速緩存   
  20.         objp = cache_alloc_refill(cachep, flags);   
  21.     }   
  22.     return objp;   
  23. }   
  24.    
  25.     cache_alloc_refill()用來填充本地高速緩存,也是slab分配精華的地方,代碼解析如下:   
  26. static void *cache_alloc_refill(struct kmem_cache *cachep, gfp_t flags)   
  27. {   
  28.     int batchcount;   
  29.     struct kmem_list3 *l3;   
  30.     struct array_cache *ac;   
  31.    
  32.     check_irq_off();   
  33.     //根據cpu id得到slab本地高速緩存的數據結構   
  34.     ac = cpu_cache_get(cachep);   
  35. retry:   
  36.     //batchcount記錄了此次需要填充多少個空閑對象   
  37.     batchcount = ac->batchcount;   
  38.     if (!ac->touched && batchcount > BATCHREFILL_LIMIT) {   
  39.         batchcount = BATCHREFILL_LIMIT;   
  40.     }   
  41.     //獲取到相對應的內存節點上的slab鏈表kmem_list3,每個內存節點都有自己的一套空閑,部分空閑,非空閑slab鏈表   
  42.     //因為相應cpu訪問自己所屬的內存節點的速度是最快的   
  43.     l3 = cachep->nodelists[numa_node_id()];   
  44.    
  45.     BUG_ON(ac->avail > 0 || !l3);   
  46.     spin_lock(&l3->list_lock);   
  47.    
  48.     //從本地共享高速緩存中往本地高速緩存中填充空閑對象,要注意對于numa   
  49.     //系統來說,往本地高速緩存上填充的空閑對象也都是該內存節點上的空閑對象   
  50.     if (l3->shared && transfer_objects(ac, l3->shared, batchcount))   
  51.         goto alloc_done;   
  52.    
  53.     while (batchcount > 0) {   
  54.         struct list_head *entry;   
  55.         struct slab *slabp;   
  56.         //先從部分空閑的slab里面分配空閑對象,保留完全空閑的slab,因為空閑的   
  57.         //slab在內存不足時是可以回收的   
  58.         entry = l3->slabs_partial.next;   
  59.         //如果沒有了部分空閑的slab,就只能去完全空閑的slab中分配了   
  60.         if (entry == &l3->slabs_partial) {   
  61.             l3->free_touched = 1;   
  62.             entry = l3->slabs_free.next;   
  63.             //如果完全空閑的slab也沒有了,就必須要為slab高速緩存分配新的slab了   
  64.             if (entry == &l3->slabs_free)   
  65.                 goto must_grow;   
  66.         }   
  67.    
  68.         slabp = list_entry(entry, struct slab, list);   
  69.         check_slabp(cachep, slabp);   
  70.         check_spinlock_acquired(cachep);   
  71.         //從slab中分配空閑對象,直到slab中空閑對象不存在了,或者已經分配   
  72.         //了足夠的空閑對象了   
  73.         while (slabp->inuse < cachep->num && batchcount--) {   
  74.             STATS_INC_ALLOCED(cachep);   
  75.             STATS_INC_ACTIVE(cachep);   
  76.             STATS_SET_HIGH(cachep);   
  77.             //此處獲取空閑對象   
  78.             ac->entry[ac->avail++] = slab_get_obj(cachep, slabp,   
  79.                                 numa_node_id());   
  80.         }   
  81.         check_slabp(cachep, slabp);   
  82.    
  83.         /* move slabp to correct slabp list: */   
  84.         list_del(&slabp->list);   
  85.         //若相應slab的空閑內存分配完畢,將其掛入slabs_full的slab鏈表中   
  86.         if (slabp->free == BUFCTL_END)   
  87.             list_add(&slabp->list, &l3->slabs_full);   
  88.         else   
  89.             list_add(&slabp->list, &l3->slabs_partial);   
  90.     }   
  91.    
  92. must_grow:   
  93.     l3->free_objects -ac->avail;   
  94. alloc_done:   
  95.     spin_unlock(&l3->list_lock);   
  96.     //沒有分配到任何的對象   
  97.     if (unlikely(!ac->avail)) {   
  98.         int x;   
  99.         //為高速緩存申請新的slab   
  100.         x = cache_grow(cachep, flags, numa_node_id());   
  101.    
  102.         /* cache_grow can reenable interrupts, then ac could change. */   
  103.         ac = cpu_cache_get(cachep);   
  104.         if (!x && ac->avail == 0)    /* no objects in sight? abort */   
  105.             return NULL;   
  106.         //重新從頭填充本地高速緩存   
  107.         if (!ac->avail)      /* objects refilled by interrupt? */   
  108.             goto retry;   
  109.     }   
  110.     ac->touched = 1;   
  111.     //返回本地高速緩存***一個空閑對象的地址   
  112.     return ac->entry[--ac->avail];   
  113. }   

#p#

五、slab內存的釋放


slab內存的釋放在函數kmem_cache_free()中,主要處理部分在__cache_free()函數中,其代碼解析如下:

  1. static inline void __cache_free(struct kmem_cache *cachep, void *objp)   
  2. {   
  3.     struct array_cache *ac = cpu_cache_get(cachep);   
  4.     check_irq_off();   
  5.     objp = cache_free_debugcheck(cachep, objp, __builtin_return_address(0));   
  6.     if (cache_free_alien(cachep, objp))   
  7.         return;   
  8.     //本地高速緩存可用的空閑對象尚未達到限制,將空閑對象放入本地高速緩存   
  9.     if (likely(ac->avail < ac->limit)) {   
  10.         STATS_INC_FREEHIT(cachep);   
  11.         ac->entry[ac->avail++] = objp;   
  12.         return;   
  13.     } else {   
  14.         //cache_flusharray()會將本地高速緩存的一些空閑對象放入到slab中   
  15.         cache_flusharray(cachep, ac);   
  16.         ac->entry[ac->avail++] = objp;   
  17.     }   
  18. }   
  19.    
  20. static void cache_flusharray(struct kmem_cache *cachep, struct array_cache *ac)   
  21. {   
  22.     int batchcount;   
  23.     struct kmem_list3 *l3;   
  24.     int node = numa_node_id();   
  25.     //一次應該將batchcount個空閑對象歸還到slab中   
  26.     batchcount = ac->batchcount;   
  27.     check_irq_off();   
  28.     //得到對應內存節點的slab list3,上面記錄著該節點的slab鏈表   
  29.     l3 = cachep->nodelists[node];   
  30.     spin_lock(&l3->list_lock);   
  31.     //優先先歸還到本地共享高速緩存中,注意本地共享高速緩存中的   
  32.     //空閑對象是僅供該內存節點上的各個cpu分配使用的,這樣可以使內存訪問的效率***。   
  33.     if (l3->shared) {   
  34.         struct array_cache *shared_array = l3->shared;   
  35.         int max = shared_array->limit - shared_array->avail;   
  36.         if (max) {   
  37.             if (batchcount > max)   
  38.                 batchcount = max;   
  39.             //將batchcount個數組元素copy到本地高速緩存中   
  40.             memcpy(&(shared_array->entry[shared_array->avail]),   
  41.                    ac->entry, sizeof(void *) * batchcount);   
  42.             shared_array->avail += batchcount;   
  43.             goto free_done;   
  44.         }   
  45.     }   
  46.     //在沒有本地高速緩存的情況下,釋放回slab中   
  47.     free_block(cachep, ac->entry, batchcount, node);   
  48. free_done:   
  49.     spin_unlock(&l3->list_lock);   
  50.     ac->avail -batchcount;   
  51.     //將刪除后剩下的空閑對象往前移動一下,hoho,可能還剩下些空閑對象   
  52.     memmove(ac->entry, &(ac->entry[batchcount]), sizeof(void *)*ac->avail);   
  53. }   
  54.    
  55. static void free_block(struct kmem_cache *cachep, void **objpp, int nr_objects,   
  56.                int node)   
  57. {   
  58.     int i;   
  59.     struct kmem_list3 *l3;   
  60.    
  61.     for (i = 0; i < nr_objects; i++) {   
  62.         void *objp = objpp[i];   
  63.         struct slab *slabp;   
  64.         //先從對象獲取到其所在的page,再從page得到其所屬的slab   
  65.         //page->lru.prev中記錄了page所屬的slab   
  66.         slabp = virt_to_slab(objp);   
  67.         l3 = cachep->nodelists[node];   
  68.         list_del(&slabp->list);   
  69.         check_spinlock_acquired_node(cachep, node);   
  70.         check_slabp(cachep, slabp);   
  71.         //放入對應的slab   
  72.         slab_put_obj(cachep, slabp, objp, node);   
  73.         STATS_DEC_ACTIVE(cachep);   
  74.         l3->free_objects++;   
  75.         check_slabp(cachep, slabp);   
  76.    
  77.         /* fixup slab chains */   
  78.         //slab所有的對象都已經被歸還   
  79.         if (slabp->inuse == 0) {   
  80.             //slab高速緩存的空閑對象數超過了限制,可以釋放掉該slab,以   
  81.             //釋放其所占有的內存   
  82.             if (l3->free_objects > l3->free_limit) {   
  83.                 l3->free_objects -cachep->num;   
  84.                 slab_destroy(cachep, slabp);   
  85.             } else {   
  86.                 //加入到完全空閑slab鏈表中   
  87.                 list_add(&slabp->list, &l3->slabs_free);   
  88.             }   
  89.         } else {   
  90.             //加入到部分空閑的slab鏈表中   
  91.             list_add_tail(&slabp->list, &l3->slabs_partial);   
  92.         }   
  93.     }   
  94. }  
責任編輯:奔跑的冰淇淋 來源: CSDN博客
相關推薦

2018-12-06 10:22:54

Linux內核內存

2024-12-11 08:18:11

2021-08-10 16:50:37

內核內存管理

2013-10-11 17:32:18

Linux運維內存管理

2021-08-03 09:02:58

LinuxSlab算法

2011-06-27 17:52:57

Voting DiskOCR

2009-12-25 15:34:54

slab分配器

2025-09-28 01:00:00

2012-02-13 17:26:35

2025-01-13 00:30:17

2023-10-18 13:31:00

Linux內存

2022-08-08 08:31:00

Linux內存管理

2017-05-18 16:30:29

Linux內存管理

2016-10-09 14:41:40

Swift開發ARC

2010-05-27 15:25:14

Linux查看內存

2021-03-30 10:50:18

Linux內存命令

2021-10-15 08:51:09

Linux內存 Kmalloc

2020-12-23 13:14:00

LinuxLinux內存Swap

2021-05-27 05:28:18

Linux 內存管理

2013-09-29 15:11:46

Linux運維內存管理
點贊
收藏

51CTO技術棧公眾號

日本一区二区精品| 91av在线网站| 免费在线观看日韩av| 国产丝袜在线观看视频| 成人高清免费观看| 国产精品久久久久久久久男| 成人免费毛片xxx| 给我免费播放日韩视频| 日本高清免费不卡视频| 青青视频免费在线观看| 头脑特工队2在线播放| 美女在线视频一区| 高清欧美电影在线| 久久精品国产亚洲AV成人婷婷| 国产亚洲高清一区| 欧美日韩亚洲成人| 中文字幕欧美日韩一区二区| 天天干天天摸天天操| 免播放器亚洲一区| 91精品国产乱码久久久久久蜜臀 | 99精品欧美一区| 国产免费久久av| 美日韩一二三区| 中文字幕乱码亚洲无线精品一区| 日韩精品亚洲元码| 久久综合桃花网| 91精品国产66| 红桃av永久久久| 香蕉视频免费版| 1769在线观看| 久久综合色8888| 成人自拍爱视频| 国产一区二区网站| 日韩综合小视频| 欧美另类极品videosbest最新版本| 国产免费看av| 日韩电影不卡一区| 亚洲成**性毛茸茸| 肉色超薄丝袜脚交| 久久亚洲精品人成综合网| 欧美日韩中文字幕| 欧美日韩福利在线| jizz性欧美10| 亚洲国产成人午夜在线一区 | www.久久久久久久久久久| 波多野结衣亚洲| 亚洲一区二区综合| 潘金莲一级淫片aaaaa免费看| 国产视频网站在线| av资源网一区| 国产精品一区二区欧美黑人喷潮水 | 国产精彩精品视频| 国产高清中文字幕| 先锋亚洲精品| 欧美一级淫片videoshd| 国产无码精品久久久| 国产综合婷婷| 欧美极品美女电影一区| 久视频在线观看| 国产精品mv在线观看| 日韩一区av在线| 又色又爽的视频| 久久精品播放| 日韩专区在线播放| 很污很黄的网站| 婷婷亚洲五月色综合| zzijzzij亚洲日本成熟少妇| 黑人狂躁日本娇小| 忘忧草精品久久久久久久高清| 色系列之999| 任我爽在线视频| 亚洲影视一区二区三区| 久久999免费视频| 国产午夜福利一区二区| 国产精品久久久久久模特 | 大地资源网在线观看免费官网| 国产激情在线视频| 亚洲最新视频在线播放| 国产精品无码av在线播放| 中文字幕色婷婷在线视频| 日本韩国一区二区| 夜夜夜夜夜夜操| 91精品短视频| 亚洲摸下面视频| 成人精品一二三区| 欧美激情在线| 欧洲日韩成人av| 中文字幕观看视频| 国产精品资源在线观看| 国产精品手机在线| 国产在线观看精品一区| 亚洲同性同志一二三专区| 蜜臀av色欲a片无码精品一区| 美女在线视频免费| 欧美日韩高清一区二区三区| 久久久久国产免费| 精品国产乱码久久久久久果冻传媒 | 91国偷自产一区二区三区成为亚洲经典| 艹b视频在线观看| 亚洲国产视频二区| 亚洲桃花岛网站| 久久久精品视频免费观看| 亚洲综合国产| 5566中文字幕一区二区| 亚洲av成人精品毛片| 国产精品初高中害羞小美女文| 日本手机在线视频| 亚洲欧美专区| 亚洲色无码播放| 久一区二区三区| 日韩不卡免费视频| 国产精品免费一区二区三区在线观看 | 综合操久久久| 中文字幕资源网在线观看免费| 欧美丰满一区二区免费视频| 双性尿奴穿贞c带憋尿| 伊人成综合网| 国产精品视频精品| 婷婷丁香花五月天| 亚洲精品第一国产综合野| 成人黄色一区二区| 欧美做受69| 欧美国产日韩一区二区在线观看| 337p粉嫩色噜噜噜大肥臀| 成人美女在线视频| 欧美少妇一区二区三区| 福利一区在线| 亚洲夜晚福利在线观看| 可以在线观看av的网站| 国产成人在线视频网站| 制服诱惑一区| 欧美天堂一区二区| 亚洲新中文字幕| 国产精品国产三级国产专区52| 国产精品一品二品| 中文字幕一区二区三区乱码| julia一区二区三区中文字幕| 日韩av一区二区在线观看| 国产亚洲精品av| 国产精品亚洲а∨天堂免在线| 一区二区三区av在线| 日本国产欧美| 亚洲天堂男人天堂| 二区视频在线观看| 不卡av电影在线播放| 欧美无砖专区免费| **爰片久久毛片| 欧美精品videossex性护士| 国产美女裸体无遮挡免费视频| 国产女人18水真多18精品一级做| 亚洲乱码中文字幕久久孕妇黑人| 久久悠悠精品综合网| 午夜精品福利视频| 蜜桃视频久久一区免费观看入口| 一区二区三区免费在线观看| www.亚洲自拍| 欧美精选一区| 成人免费91在线看| 国产在线拍揄自揄拍视频| 日韩欧美精品三级| 久久精品国产亚洲AV无码麻豆| 国产成人在线观看免费网站| 欧美中文字幕在线观看视频| 亚洲国产高清在线观看| 久久人人爽人人爽人人片av高请| 手机在线观看免费av| 狠狠躁天天躁日日躁欧美| 3d动漫精品啪啪一区二区下载| 翔田千里一区二区| 日韩欧美精品一区二区三区经典| 日韩精品99| 色999日韩欧美国产| 97人妻精品一区二区三区软件 | 久久精品视频9| www.色精品| 亚洲色欲综合一区二区三区| 日韩免费看片| av噜噜色噜噜久久| 精品丝袜在线| 国产亚洲人成网站在线观看| 国产精品女人久久久| 亚洲福利视频一区二区| 全黄一级裸体片| 久久99精品久久久久婷婷| 欧美另类videosbestsex日本| 精品三级av| 国产精品久久久久久久久粉嫩av| 国产三区视频在线观看| 亚洲精品一区二区三区99| 福利网址在线观看| 综合欧美一区二区三区| a级一a一级在线观看| 免费在线观看视频一区| 成人国产一区二区三区| 亚洲妇女av| 亚洲伊人第一页| 免费亚洲电影| 欧美美女操人视频| 成人免费在线观看| 欧美变态tickling挠脚心| 亚洲 欧美 中文字幕| 亚洲精品v日韩精品| 成人片黄网站色大片免费毛片| 久久91精品国产91久久小草| 热99这里只有精品| 999国产精品视频| 久精品国产欧美| 亚洲视频自拍| 国产精品成人久久久久| 91桃色在线| 另类色图亚洲色图| 岛国最新视频免费在线观看| 精品国精品国产尤物美女| 99re热视频| 五月天国产精品| 懂色av懂色av粉嫩av| 久久久久9999亚洲精品| 中文字幕一区二区三区人妻在线视频 | 中文av一区二区| 国产精品成人无码专区| 国产在线视视频有精品| 熟女人妇 成熟妇女系列视频| 国产综合自拍| 在线不卡日本| 精品香蕉视频| 久久久久久九九| 97色成人综合网站| 成人伊人精品色xxxx视频| 日产精品一区| 欧美亚洲国产视频| ririsao久久精品一区| 久久人人爽人人爽人人片亚洲| 精品视频一二三| 精品亚洲va在线va天堂资源站| www.久久久久久| 欧美一区二区三区小说| 国产又黄又猛又爽| 欧美日产国产精品| 在线免费一级片| 欧美午夜精品免费| 最近中文字幕在线免费观看| 日韩欧美一区二区在线| 国产 日韩 欧美 在线| 亚洲成人免费av| 国产无码精品久久久| 亚洲高清视频中文字幕| 久久久久成人精品无码| 亚洲一区二区三区在线看 | 五月开心婷婷久久| 国产无人区码熟妇毛片多| 偷窥少妇高潮呻吟av久久免费| 久久成人国产精品入口| 亚洲第一精品在线| 日韩特黄一级片| 天天做天天摸天天爽国产一区| 91香蕉在线视频| 日韩欧美在线中文字幕| 久久高清免费视频| 欧美日韩国产在线播放| 天堂а√在线中文在线新版| 疯狂做受xxxx欧美肥白少妇 | 色偷偷一区二区三区| 蜜臀精品一区二区三区| 91成人在线观看喷潮| 少妇无套内谢久久久久| 欧美美女一区二区| 精品国产18久久久久久| 欧美精品一区二区三区在线播放 | 国产一区二区片| 99精品久久| 久草综合在线观看| 久久福利视频一区二区| 丰满少妇一区二区三区专区| 成人免费毛片aaaaa**| 一级特级黄色片| 国产清纯白嫩初高生在线观看91 | 精品人妻一区二区三区香蕉 | 欧美精品一区二区三区蜜桃 | 久久精品免费播放| 免费看电影在线| 人妖精品videosex性欧美| 九七影院97影院理论片久久 | 97在线观看免费| 性高爱久久久久久久久| 91久久夜色精品国产网站| 高清精品xnxxcom| 日本成人黄色| 一区二区日韩欧美| 动漫av网站免费观看| 精品一区免费av| 日韩精品一区二区三区高清免费| 日本一区二区三区四区在线视频| 我要看黄色一级片| 五月天亚洲婷婷| 亚洲天堂男人网| 欧美精品一区二区精品网| 成年人在线观看网站| 欧美黄网免费在线观看| 影视一区二区三区| 91中文字幕一区| 亚洲影院天堂中文av色| 久久久无码中文字幕久...| 久久精品毛片| 性色av浪潮av| 欧美国产激情一区二区三区蜜月| 久久激情免费视频| 欧美午夜片在线观看| 日韩在线观看视频一区| xvideos国产精品| 中文字幕在线高清| 国产欧美日韩综合精品二区| 精品国产91| 免费无码不卡视频在线观看| 国内精品久久久久影院薰衣草| 无码国产69精品久久久久同性| 亚洲日本韩国一区| 亚洲 小说区 图片区| 亚洲国产天堂久久国产91| av免费在线观| 国产精品久久久久免费a∨大胸| 欧美久久精品| 欧美黑人在线观看| 国产最新精品精品你懂的| 国产精品国产三级国产专业不 | 日韩一区二区精品视频| free欧美| 欧美一区2区三区4区公司二百| 亚洲第一精品影视| 韩国av中国字幕| 亚洲欧美一区二区三区久本道91 | 欧洲一区精品| 国产精品美女黄网| 欧美视频网站| 午夜影院免费观看视频| 国产精品久久久久久久裸模| 无码人妻精品一区二区蜜桃色欲| 亚洲国产第一页| 在线观看三级视频| 91视频在线免费观看| 中文字幕一区二区av| 九九久久久久久| 亚洲免费在线视频一区 二区| 在线观看免费视频a| 丝袜一区二区三区| 精品三级在线| 欧美性受黑人性爽| 国产综合久久久久久鬼色| 91高清免费看| 91精品国产综合久久福利| 麻豆tv在线| 91久久爱成人| 国产精品videosex极品| 91精品又粗又猛又爽| 亚洲综合视频在线观看| 人妻一区二区三区| 91国产美女在线观看| 亚洲成人一品| 美女黄色片视频| 国产精品国产三级国产aⅴ中文| 91在线公开视频| 欧美日产国产成人免费图片| 亚洲三区欧美一区国产二区| 免费看欧美一级片| 99精品国产热久久91蜜凸| 无码人妻久久一区二区三区| 亚洲无亚洲人成网站77777| 日韩国产大片| 欧美交换配乱吟粗大25p| 成人午夜私人影院| 三级视频在线观看| 色青青草原桃花久久综合| 国产色99精品9i| 黄页网站大全在线观看| 久久久久久久久久久久久夜| 亚洲天堂手机版| 欧美超级免费视 在线| 奇米777国产一区国产二区| 免费日韩中文字幕| 亚洲日穴在线视频| 欧美 日韩 综合| 国产成人在线视频| 一区二区三区在线电影| 国产传媒第一页| 欧美日韩一区久久| 国产亚av手机在线观看| 日韩成人av网站| 国产精品综合久久| 国产精品视频免费播放| 日韩在线观看网站| 美女主播精品视频一二三四| 九九九在线观看视频| 亚洲国产精品天堂| 大地资源中文在线观看免费版| 亚洲直播在线一区| 久久五月激情| 成人免费看片98| 日韩专区中文字幕| 羞羞色国产精品网站| 亚洲免费黄色录像| 色中色一区二区|