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

Linux內核的進程負載均衡機制

系統 Linux
在多核系統中,為了更好的利用多CPU并行能力,進程調度器可以將進程負載盡可能的平均到各個CPU上。再具體實現中,如何選擇將進程遷移到的目標CPU,除了考慮各個CPU的負載平衡,還需要將Cache利用納入權衡因素。同時,對于進程A喚醒進程B這個模型,還做了特殊的處理。

概述

在多核系統中,為了更好的利用多CPU并行能力,進程調度器可以將進程負載盡可能的平均到各個CPU上。再具體實現中,如何選擇將進程遷移到的目標CPU,除了考慮各個CPU的負載平衡,還需要將Cache利用納入權衡因素。同時,對于進程A喚醒進程B這個模型,還做了特殊的處理。本文分析以Centos kernel 3.10.0-975源碼為藍本。

SMP負載均衡模型

問題

如果只是將CPU負載平均的分布在各個CPU上,那么就無所謂需要調度域。但是由于Cache以及內存Numa的存在,使得進程最好能遷移到與之前運行所在CPU更'近'的CPU上。

以我們常用的Intel X86為例。Cache基本視圖如下圖:

[[261979]]

從Cache和內存訪問的視角,如果進程負載均衡需要把進程A遷移到另一個CPU上,

  • 如果目標CPU和進程A之前所在CPU正好是同一個物理CPU同一個核心上(超線程),那么Cache利用率最好,畢竟L1,L2和L3中還是'熱'的。
  • 如果目標CPU和進程A之前所在CPU正好是同一個物理CPU但不同核心上(多核),那么Cache利用率次之,L3中還有'熱'數據。
  • 如果目標CPU和進程A之前所在CPU正好是同一個NUMA但是不同物理CPU上(多NUMA結構),雖然Cache已經是'冷'了,但至少內存訪問還是在本NUMA中。
  • 如果目標CPU和進程A之前所在CPU在不同NUMA中,不但Cache是'冷'的,跨NUMA內存還有懲罰,此時內存訪問速度最差。

SMP組織

為了更好地利用Cache,內核將CPU(如果開啟了超線程,那么以邏輯CPU為單位,否則以物理CPU核心為單位)組織成了調度域。

邏輯視角

假設某機器為2路4核8核心CPU,它的CPU調度域邏輯上如下圖:

 

2路NUMA最為簡單,如果是4路NUMA,那么這個視圖在NUMA層級將會復雜很多,因為跨NUMA訪問根據訪問距離導致訪問延時還不相同,這部分最后討論。

分層視角

所有CPU一共分為三個層次:SMT,MC,NUMA,每層都包含了所有CPU,但是劃分粒度不同。根據Cache和內存的相關性劃分調度域,調度域內的CPU又劃分一次調度組。越往下層調度域越小,越往上層調度域越大。進程負載均衡會盡可能的在底層調度域內部解決,這樣Cache利用率最優。

從分層的視角分析,下圖是調度域實際組織方式,每層都有per-cpu數組保存每個CPU對應的調度域和調度組,它們是在初始化時已經提前分配的內存。值得注意的是

  • 每個CPU對應的調度域數據結構都包含了有效的內容,比如說SMT層中,CPU0和CPU1對應的不同調度域數據結構,內容是一模一樣的。
  • 每個CPU對應的調度組數據結構不一定包含了有效內容,比如說MC層中,CPU0和CPU1指向不同的struct sched_domain,但是sched_domain->groups指向的調度組確是同樣的數據結構,這些調度組組成了環。
 

單CPU視角

從單個CPU的視角分析,下圖是調度域實際組織方式。

 

[[261980]]

 

每個CPU的進程運行隊列有一個成員指向其所在調度域。從最低層到最高層。

我們可以在/proc/sys/kernel/sched_domain/cpuX/ 中看到CPU實際使用的調度域個數以及每個調度域的名字和配置參數。

負載均衡時機

  • 周期性調用進程調度程序scheduler_tick()->trigger_load_balance()中,通過軟中斷觸發負載均衡。
  • 某個CPU上無可運行進程,__schedule()準備調度idle進程前,會嘗試從其它CPU上pull一批進程過來。

周期性負載均衡

CPU對應的運行隊列數據結構中記錄了下一次周期性負載均衡的時間,當超過這個時間點后,將觸發SCHED_SOFTIRQ軟中斷來進行負載均衡。

  1. void trigger_load_balance(struct rq *rq, int cpu) 
  2.         /* Don't need to rebalance while attached to NULL domain */ 
  3.         if (time_after_eq(jiffies, rq->next_balance) && 
  4.             likely(!on_null_domain(cpu))) 
  5.                 raise_softirq(SCHED_SOFTIRQ); 
  6. #ifdef CONFIG_NO_HZ_COMMON 
  7.         if (nohz_kick_needed(rq) && likely(!on_null_domain(cpu))) 
  8.                 nohz_balancer_kick(cpu); 
  9. #endif 

以下是rebalance_domains()函數核心流程,值得注意的是,每個層級的調度間隔不是固定的,而是臨時計算出來,他在一個可通過proc接口配置的最小值和最大值之間。

 

[[261981]]

 

以下是對CPU的每個層級調度域調用load_balance()函數核心流程,目的是把一些進程遷移到指定的CPU(該場景就是當前CPU)。

 

[[261982]]

 

以我的服務器為例,觀察不同層級調度域的調度間隔范圍,時間單位為jiffies。

Level

min_interval

max_interval

SMT

2

4

MC

40

80

NUMA

80

160

可見,SMT負載均衡頻率最高,越往上層越低。這也符合體系結構特點,在越低層次遷移進程代價越小(Cache利用率高),所以可以更加頻繁一點。

CPU進入idle前負載均衡

當進程調度函數__schedule()把即將切換到idle進程前,會發生一次負載均衡來避免當前CPU空閑。

  1. static void __sched __schedule(void) 
  2.         ... 
  3.         if (unlikely(!rq->nr_running)) 
  4.                 idle_balance(cpu, rq); 
  5.  
  6.         ... 

核心函數idle_balance()。基本上也是盡可能在低層調度域中負載均衡。

  1. /*  * idle_balance is called by schedule() if this_cpu is about to become  * idle. Attempts to pull tasks from other CPUs.  */ 
  2. void idle_balance(int this_cpu, struct rq *this_rq) 
  3.     unsigned long next_balance = jiffies + HZ; 
  4.     struct sched_domain *sd; 
  5.     int pulled_task = 0; 
  6.     u64 curr_cost = 0; 
  7.  
  8.     this_rq->idle_stamp = rq_clock(this_rq); 
  9.  
  10.     /* 如果該CPU平均空閑時間小于/proc中的配置值或者該cpu調度域中所有cpu都是idle狀態,那么不需要負載均衡了*/ 
  11.     if (this_rq->avg_idle < sysctl_sched_migration_cost || 
  12.         !this_rq->rd->overload) { 
  13.         rcu_read_lock(); 
  14.         sd = rcu_dereference_check_sched_domain(this_rq->sd); 
  15.         if (sd) 
  16.             update_next_balance(sd, 0, &next_balance); 
  17.         rcu_read_unlock(); 
  18.  
  19.         goto out
  20.     } 
  21.  
  22.     /*   * Drop the rq->lock, but keep IRQ/preempt disabled.     */ 
  23.     raw_spin_unlock(&this_rq->lock); 
  24.  
  25.     update_blocked_averages(this_cpu); 
  26.     rcu_read_lock(); 
  27.     /* 從底向上遍歷調度域,只要遷移成功一個進程就跳出循環*/ 
  28.     for_each_domain(this_cpu, sd) { 
  29.         int should_balance; 
  30.         u64 t0, domain_cost; 
  31.  
  32.         if (!(sd->flags & SD_LOAD_BALANCE)) 
  33.             continue
  34.  
  35.         /*           * 如果(當前累積的負載均衡開銷時間 + 歷史上該層級負載均衡開銷最大值)已經大于CPU平均空閑時間了,          * 那么就沒有必要負載均衡了。注意,sd->max_newidle_lb_cost會在load_balance()函數中緩慢減少。          */ 
  36.         if (this_rq->avg_idle < curr_cost + sd->max_newidle_lb_cost) { 
  37.             update_next_balance(sd, 0, &next_balance); 
  38.             break; 
  39.         } 
  40.  
  41.         /* 我的機器上該標記總是設置了SD_BALANCE_NEWIDLE */ 
  42.         if (sd->flags & SD_BALANCE_NEWIDLE) { 
  43.             t0 = sched_clock_cpu(this_cpu); 
  44.  
  45.             pulled_task = load_balance(this_cpu, this_rq, 
  46.                            sd, CPU_NEWLY_IDLE, 
  47.                            &should_balance); 
  48.             
  49.             domain_cost = sched_clock_cpu(this_cpu) - t0; 
  50.             if (domain_cost > sd->max_newidle_lb_cost) 
  51.                 sd->max_newidle_lb_cost = domain_cost; 
  52.  
  53.            /* 記錄了當前負載均衡開銷累計值 */ 
  54.             curr_cost += domain_cost; 
  55.         } 
  56.  
  57.         update_next_balance(sd, 0, &next_balance); 
  58.  
  59.         /*       * Stop searching for tasks to pull if there are         * now runnable tasks on this rq.        */         
  60.         if (pulled_task || this_rq->nr_running > 0) { 
  61.             this_rq->idle_stamp = 0; 
  62.             break; 
  63.         } 
  64.     } 
  65.     rcu_read_unlock(); 
  66.  
  67.     raw_spin_lock(&this_rq->lock); 
  68.  
  69. out
  70.     /* Move the next balance forward */ 
  71.     if (time_after(this_rq->next_balance, next_balance)) 
  72.         this_rq->next_balance = next_balance; 
  73.  
  74.     if (curr_cost > this_rq->max_idle_balance_cost) 
  75.         this_rq->max_idle_balance_cost = curr_cost; 

其它需要用到SMP負載均衡模型的時機

內核運行中,還有部分情況中需要用掉SMP負載均衡模型來確定最佳運行CPU:

  • 進程A喚醒進程B時,try_to_wake_up()中會考慮進程B將在哪個CPU上運行。
  • 進程調用execve()系統調用時。
  • fork出子進程,子進程第一次被調度運

喚醒進程時

當A進程喚醒B進程時,假設都是普通進程,那么將會調用try_to_wake_up()->select_task_rq()->select_task_rq_fair()

  1. /*  * sched_balance_self: balance the current task (running on cpu) in domains  * that have the 'flag' flag setIn practice, this is SD_BALANCE_FORK and  * SD_BALANCE_EXEC.  *  * Balance, ie. select the least loaded group.  *  * Returns the target CPU number, or the same CPU if no balancing is needed.  *  * preempt must be disabled.  */ 
  2. /* A進程給自己或者B進程選擇一個CPU運行,  * 1: A喚醒B  * 2: A fork()出B后讓B運行  * 3: A execute()后重新選擇自己將要運行的CPU  */  
  3. static int 
  4. select_task_rq_fair(struct task_struct *p, int prev_cpu, int sd_flag, int wake_flags) 
  5.     struct sched_domain *tmp, *affine_sd = NULL, *sd = NULL
  6.     int cpu = smp_processor_id(); 
  7.     int new_cpu = cpu; 
  8.     int want_affine = 0; 
  9.     int sync = wake_flags & WF_SYNC; 
  10.  
  11.     /* 當A進程喚醒B進程時,從try_to_wake_up()進入本函數,這里會置位SD_BALANCE_WAKE。 */ 
  12.     if (sd_flag & SD_BALANCE_WAKE) { 
  13.         /* B進程被喚醒時希望運行的CPU盡可能離A進程所在CPU近一點 */ 
  14.         if (cpumask_test_cpu(cpu, tsk_cpus_allowed(p))) 
  15.             want_affine = 1; 
  16.         new_cpu = prev_cpu; 
  17.         record_wakee(p); 
  18.     } 
  19.  
  20.     rcu_read_lock(); 
  21.     /*       * 如果是A喚醒B模式,則查找同時包含A所在cpu和B睡眠前所在prev_cpu的最低級別的調度域。因為A進程      * 和B進程大概率會有某種數據交換關系,喚醒B時讓它們所在的CPU離的近一點會性能最優。      * 否則,查找包含了sd_flag的最高調度域。      */ 
  22.     for_each_domain(cpu, tmp) { 
  23.         if (!(tmp->flags & SD_LOAD_BALANCE)) 
  24.             continue
  25.  
  26.         /*       * If both cpu and prev_cpu are part of this domain,         * cpu is a valid SD_WAKE_AFFINE target.         */         
  27.         if (want_affine && (tmp->flags & SD_WAKE_AFFINE) && 
  28.             cpumask_test_cpu(prev_cpu, sched_domain_span(tmp))) { 
  29.             affine_sd = tmp; 
  30.             break; 
  31.         } 
  32.  
  33.         if (tmp->flags & sd_flag) 
  34.             sd = tmp; 
  35.     } 
  36.  
  37.     /* 如果是A喚醒B模式,則在同時包含A所在cpu和B睡眠前所在prev_cpu的最低級別的調度域中尋找合適的CPU */ 
  38.     if (affine_sd) { 
  39.        /*          * wake_affine()計算A所在CPU和B睡眠前所在CPU的負載值,判斷出B進程喚醒時是否         * 需要離A近一點。         */ 
  40.         if (cpu != prev_cpu && wake_affine(affine_sd, p, sync)) 
  41.             prev_cpu = cpu; 
  42.  
  43.        /* 在與prev_cpu共享LLC的CPU中尋找空閑CPU,如果沒有找到,則返回prev_cpu。這里將確定         * B進程喚醒后在哪個CPU運行。         */ 
  44.         new_cpu = select_idle_sibling(p, prev_cpu); 
  45.         goto unlock; 
  46.     } 
  47.  
  48.     /* 到這里,A進程和B進程基本是沒有啥親緣關系的。不用考慮兩個進程的Cache親緣性 */ 
  49.     while (sd) { 
  50.         int load_idx = sd->forkexec_idx; 
  51.         struct sched_group *group
  52.         int weight; 
  53.  
  54.         if (!(sd->flags & sd_flag)) { 
  55.             sd = sd->child; 
  56.             continue
  57.         } 
  58.  
  59.         if (sd_flag & SD_BALANCE_WAKE) 
  60.             load_idx = sd->wake_idx; 
  61.  
  62.         group = find_idlest_group(sd, p, cpu, load_idx); 
  63.         if (!group) { 
  64.             sd = sd->child; 
  65.             continue
  66.         } 
  67.  
  68.         new_cpu = find_idlest_cpu(group, p, cpu); 
  69.         if (new_cpu == -1 || new_cpu == cpu) { 
  70.             /* Now try balancing at a lower domain level of cpu */ 
  71.             sd = sd->child; 
  72.             continue
  73.         } 
  74.  
  75.         /* Now try balancing at a lower domain level of new_cpu */ 
  76.         cpu = new_cpu; 
  77.         weight = sd->span_weight; 
  78.         sd = NULL
  79.         for_each_domain(cpu, tmp) { 
  80.             if (weight <= tmp->span_weight) 
  81.                 break; 
  82.             if (tmp->flags & sd_flag) 
  83.                 sd = tmp; 
  84.         } 
  85.         /* while loop will break here if sd == NULL */ 
  86.     } 
  87. unlock: 
  88.     rcu_read_unlock(); 
  89.  
  90.     return new_cpu; 
  91. }  
  1. /*  * Try and locate an idle CPU in the sched_domain.  */ 
  2.  /* 尋找離target CPU最近的空閑CPU(Cache或者內存距離最近)*/ 
  3. static int select_idle_sibling(struct task_struct *p, int target) 
  4.     struct sched_domain *sd; 
  5.     struct sched_group *sg; 
  6.     int i = task_cpu(p); 
  7.      
  8.     /* target CPU正好空閑,自己跟自己當然最近*/ 
  9.     if (idle_cpu(target)) 
  10.         return target; 
  11.  
  12.     /*   * If the prevous cpu is cache affine and idle, don't be stupid.     */ 
  13.     /*       * p進程所在的CPU跟target CPU有Cache共享關系(SMT,或者MC層才有這個關系),并且是空閑的,那就用它了。      * Cache共享說明距離很近了       */ 
  14.     if (i != target && cpus_share_cache(i, target) && idle_cpu(i)) 
  15.         return i; 
  16.  
  17.     /*   * Otherwise, iterate the domains and find an elegible idle cpu.     */ 
  18.     /*      * 在與target CPU有LLC Cache共享關系的調度域中尋找空閑CPU。注意,在X86體系中只有SMT和MC層的調度域才有Cache共享。      */ 
  19.     sd = rcu_dereference(per_cpu(sd_llc, target));     
  20.     /* 在我的機器上是按MC,SMT調度域順序遍歷 */ 
  21.     for_each_lower_domain(sd) { 
  22.         sg = sd->groups; 
  23.         do { 
  24.             if (!cpumask_intersects(sched_group_cpus(sg), 
  25.                         tsk_cpus_allowed(p))) 
  26.                 goto next
  27.  
  28.            /* 調度組內所有CPU都是空閑狀態,才能選定 */ 
  29.             for_each_cpu(i, sched_group_cpus(sg)) { 
  30.                 if (i == target || !idle_cpu(i)) 
  31.                     goto next
  32.             } 
  33.  
  34.            /* 選擇全部CPU都空閑的調度組中第一個CPU*/ 
  35.             target = cpumask_first_and(sched_group_cpus(sg), 
  36.                     tsk_cpus_allowed(p)); 
  37.             goto done; 
  38. next
  39.             sg = sg->next
  40.         } while (sg != sd->groups); 
  41.     } 
  42. done: 
  43.     return target; 

調用execve()系統調用時

  1. /*  * sched_exec - execve() is a valuable balancing opportunity, because at  * this point the task has the smallest effective memory and cache footprint.  */ 
  2. void sched_exec(void) 
  3.     struct task_struct *p = current
  4.     unsigned long flags; 
  5.     int dest_cpu; 
  6.  
  7.     raw_spin_lock_irqsave(&p->pi_lock, flags); 
  8.     /* 選擇最合適的CPU,這里由于進程execve()后,之前的Cache就無意義了,因此選擇目標CPU不用考慮Cache距離 */ 
  9.     dest_cpu = p->sched_class->select_task_rq(p, task_cpu(p), SD_BALANCE_EXEC, 0); 
  10.     if (dest_cpu == smp_processor_id()) 
  11.         goto unlock; 
  12.  
  13.     if (likely(cpu_active(dest_cpu))) { 
  14.         struct migration_arg arg = { p, dest_cpu }; 
  15.  
  16.         raw_spin_unlock_irqrestore(&p->pi_lock, flags); 
  17.         stop_one_cpu(task_cpu(p), migration_cpu_stop, &arg); 
  18.         return
  19.     } 
  20. unlock: 
  21.     raw_spin_unlock_irqrestore(&p->pi_lock, flags); 

fork的子進程第一次被調度運行時

  1. do_fork()->wake_up_new_task() 
  2.  
  3. /*  * wake_up_new_task - wake up a newly created task for the first time.  *  * This function will do some initial scheduler statistics housekeeping  * that must be done for every newly created context, then puts the task  * on the runqueue and wakes it.  */ 
  4. void wake_up_new_task(struct task_struct *p) 
  5.     unsigned long flags; 
  6.     struct rq *rq; 
  7.  
  8.     raw_spin_lock_irqsave(&p->pi_lock, flags); 
  9. #ifdef CONFIG_SMP 
  10.     /*   * Fork balancing, do it here and not earlier because:   *  - cpus_allowed can change in the fork path   *  - any previously selected cpu might disappear through hotplug    */ 
  11.     /* 選擇最合適的CPU,這里由于進程execve()后,之前的Cache就無意義了,因此選擇目標CPU不用考慮Cache距離 */ 
  12.     set_task_cpu(p, select_task_rq(p, task_cpu(p), SD_BALANCE_FORK, 0)); 
  13. #endif 
  14.  
  15.     /* Initialize new task's runnable average */ 
  16.     init_task_runnable_average(p); 
  17.     rq = __task_rq_lock(p); 
  18.     activate_task(rq, p, 0); 
  19.     p->on_rq = TASK_ON_RQ_QUEUED; 
  20.     trace_sched_wakeup_new(p, true); 
  21.     check_preempt_curr(rq, p, WF_FORK); 
  22. #ifdef CONFIG_SMP 
  23.     if (p->sched_class->task_woken) 
  24.         p->sched_class->task_woken(rq, p); 
  25. #endif 
  26.     task_rq_unlock(rq, p, &flags); 
  27. }  

SMP負載均衡模型的配置

可以在/proc/sys/kernel/sched_domain/cpuX/中可以對指定CPU所在不同層的調度域進行設置

主要分兩類:

  • 調度層名字:name
  • 調度域支持的特性:設置flags文件值,比如SD_LOAD_BALANCE,SD_BALANCE_NEWIDLE,SD_BALANCE_EXEC等,它將決定上文函數遍歷調度域時是否忽略本域。
  • 調度域計算參數:其它所有文件。 

 

責任編輯:龐桂玉 來源: 騰訊云-云+社區
相關推薦

2025-06-16 04:00:00

2021-04-22 07:47:46

Linux進程管理

2021-08-30 07:49:31

Linux內核負載均衡

2021-05-17 18:28:36

Linux CFS負載均衡

2024-11-14 09:10:13

消費者RocketMQ負載均衡

2009-10-29 09:41:01

Linux內核DeviceMappe

2010-05-05 21:39:29

linux負載均衡

2017-07-03 08:08:25

負載均衡分類

2010-04-27 12:56:35

lvs負載均衡

2009-10-23 19:11:32

linux集群

2010-04-27 12:29:08

Linux負載均衡

2010-05-06 12:18:34

IP負載均衡

2010-04-27 12:42:45

LVS負載均衡

2017-08-16 16:20:01

Linux內核態搶占用戶態搶占

2021-04-15 05:51:25

Linux

2018-11-07 10:12:37

2011-12-02 22:51:46

Nginx負載均衡

2012-05-14 14:09:53

Linux內核調度系統

2021-04-21 14:56:28

負載均衡高并發優化技術架構

2010-04-20 12:07:17

DNS負載均衡
點贊
收藏

51CTO技術棧公眾號

一区二区三区在线高清| 国产尤物一区二区在线| 亚洲毛片在线免费观看| 亚洲黄色小视频在线观看| 日韩伦理在线电影| 福利电影一区二区三区| 538国产精品视频一区二区| 蜜桃无码一区二区三区| 国产精品亚洲综合在线观看| 天天色综合天天| 亚洲午夜高清视频| 亚洲欧美另类一区| 日韩在线卡一卡二| 欧美精品videosex牲欧美| 最新中文字幕视频| 久久国产精品美女| 91国在线观看| 久久99久久99精品| 午夜免费视频在线国产| 94色蜜桃网一区二区三区| 国产日韩一区在线| 日韩在线 中文字幕| 午夜国产精品视频免费体验区| 亚洲国产日韩欧美在线图片| 91小视频在线播放| 欧美黑人巨大xxxxx| 一级做a爱片久久| 亚洲精品自在在线观看| 日韩欧美亚洲系列| 成人精品在线视频观看| 91免费国产视频| 无码人妻精品一区二| 亚洲电影成人| 久久99国产精品自在自在app| 粉嫩精品久久99综合一区| 久久综合另类图片小说| 欧美一卡在线观看| 少妇一级淫免费播放| 三上悠亚一区二区| 亚洲国产一区二区在线播放| 日韩不卡一二区| 大片免费播放在线视频| 91在线视频免费91| 国产不卡一区二区在线观看 | 亚洲一区二区综合| 制服丝袜综合日韩欧美| av在线免费观看网| 国产亚洲一区二区在线观看| 精品欧美一区二区久久久伦| 亚洲国产欧美另类| 国产精品亚洲一区二区三区妖精| 国产欧美精品日韩精品| 依依成人在线视频| 免费在线欧美视频| 国产精品第1页| 最新中文字幕在线观看视频| 久热精品在线| 日本中文字幕不卡免费| 五月天婷婷导航| 久久精品综合| 国产精彩精品视频| 国产又粗又猛又爽又| 日本中文一区二区三区| 国产精品久久久久久超碰 | 无码少妇精品一区二区免费动态| 天天做夜夜做人人爱精品 | 亚洲永久免费观看| 国产av无码专区亚洲av| 国产一区二区久久| av一区观看| 深夜福利视频网站| 91看片淫黄大片一级| 你懂的网址一区二区三区| 日本国产在线| 中文在线资源观看网站视频免费不卡| 亚洲v日韩v欧美v综合| 9191在线| 亚洲精品视频自拍| 日本福利视频一区| 亚洲十八**毛片| 欧美午夜精品电影| www.成年人| 国内精品国产成人国产三级粉色| 日韩高清人体午夜| 国产真人做爰视频免费| 国产精品二区不卡| 欧美—级高清免费播放| 中文字幕一区在线播放| 精品亚洲aⅴ乱码一区二区三区| 91精品中文在线| 日本毛片在线观看| 国产欧美精品一区aⅴ影院| 伊人色综合久久天天五月婷| 后进极品白嫩翘臀在线播放| 日韩欧美精品网站| 色啦啦av综合| 精品国产乱子伦一区二区| 亚洲视频欧洲视频| 永久久久久久久| 久久国产精品亚洲77777| 91精品国产自产在线| 国精产品一品二品国精品69xx| 久久久99久久精品欧美| 国产内射老熟女aaaa| 亚洲一区站长工具| 91精品国产综合久久精品图片| 国产又粗又长又爽| 91亚洲国产高清| 91国产中文字幕| 91片黄在线观看喷潮| 91丨porny丨在线| 中国成人亚色综合网站| 成人免费影院| 日韩免费电影一区| 伊人影院综合网| 亚洲三级毛片| 亚洲va欧美va国产综合剧情| 欧美高清电影在线| 亚洲国产精品麻豆| 在线观看中文av| 成人国产精品一级毛片视频| 午夜精品视频网站| 精品人妻一区二区三区浪潮在线| 国产女人18毛片水真多成人如厕 | 中文字幕免费高清电视剧网站在线观看 | 日本伊人精品一区二区三区观看方式| 成人自拍偷拍| 免费黄网在线观看| 欧美午夜电影网| 亚洲av综合一区二区| 亚洲国产一区二区三区高清| 92福利视频午夜1000合集在线观看| 蜜桃视频在线观看网站| 午夜精品久久久久久不卡8050| 亚洲精品成人在线播放| 成人羞羞视频播放网站| 欧美亚洲激情视频| 男人天堂手机在线观看| 亚洲激情av在线| 亚洲色图欧美自拍| 天天射—综合中文网| 国产精品女主播视频| 黄色在线观看网| 日韩欧美国产网站| 久久久无码人妻精品一区| 一区二区日韩免费看| 国产日韩三区| 国产夫妻在线播放| 亚洲成人精品av| 91蜜桃视频在线观看| 成人免费视频国产在线观看| 久久这里只有精品8| 亚洲日本va| 欧美精品videosex极品1| 午夜美女福利视频| 亚洲综合图片区| 亚洲精品久久一区二区三区777| 在线中文一区| 成人精品一二区| 黑人玩欧美人三根一起进| 精品乱码亚洲一区二区不卡| 国产一级二级三级视频| 国产mv日韩mv欧美| 九色自拍视频在线观看| 小嫩嫩12欧美| 国产精品久久激情| 黄在线免费观看| 日韩精品专区在线影院重磅| 国产系列精品av| 91丝袜国产在线播放| 成人性做爰aaa片免费看不忠| 日韩电影免费网址| 亚洲aⅴ男人的天堂在线观看| 天堂8中文在线| 日韩av在线一区二区| 色老头在线视频| 亚洲婷婷综合色高清在线| wwwxxx色| 午夜影院日韩| 一本一本久久a久久精品综合妖精| vam成人资源在线观看| 欧美激情videoshd| 四虎影院在线域名免费观看| 欧美无人高清视频在线观看| 国产探花在线免费观看| 9色porny自拍视频一区二区| 欧美精品成人网| 午夜欧美理论片| 欧美二区在线看| 91精品影视| 欧美激情在线观看视频| 男同在线观看| 在线播放亚洲一区| 国产午夜在线播放| 日韩一区欧美小说| www.17c.com喷水少妇| 日本va欧美va欧美va精品| 97在线免费视频观看| 九九久久电影| av蓝导航精品导航| 视频精品导航| 国外成人性视频| 在线免费av网站| 亚洲精品福利在线| 97av免费视频| 一本久道中文字幕精品亚洲嫩| 中日韩一级黄色片| 久久中文娱乐网| 中文字幕无码毛片免费看| 久久一综合视频| 69sex久久精品国产麻豆| 久久国产成人精品| 美女精品国产| 亚洲乱码一区| 91青草视频久久| av免费在线一区| 55夜色66夜色国产精品视频| 中文字幕中文字幕在线中高清免费版| 亚洲欧洲日产国产网站| 亚洲精品综合网| 宅男在线国产精品| 国产天堂第一区| 色综合网站在线| 奇米影视第四色777| 一区二区三区在线视频免费观看| 四虎国产成人精品免费一女五男| 91视频免费播放| 国产a级片视频| 国产精品99久久久久| 欧美成年人视频在线观看| 天堂av在线一区| 国产精品-区区久久久狼| 亚洲美女色禁图| 日本一区午夜艳熟免费| 欧美有码视频| 樱空桃在线播放| 久久日文中文字幕乱码| 久久久7777| 天堂av一区二区三区在线播放| 国产日韩欧美二区| 欧美国产不卡| 久久综合九色综合网站| 久久国产精品色av免费看| 国产精品一区二区三区精品| 99re8这里有精品热视频8在线| 91色琪琪电影亚洲精品久久| 伊人亚洲精品| 91亚洲精品一区二区| 91麻豆精品国产综合久久久 | 精品国产拍在线观看| 日本视频在线免费观看| 中文字幕久热精品在线视频| 国产免费av在线| 中文字幕日韩综合av| 69视频在线观看| 日韩中文字幕第一页| 免费av网站在线观看| 久久综合伊人77777尤物| 久久黄色美女电影| 欧美国产中文字幕| 678在线观看视频| 97视频在线免费观看| 在线一区av| 国产精品欧美日韩久久| 国产美女视频一区二区| 99在线国产| 日韩a级大片| 日本一区不卡| 婷婷亚洲五月| 国产va亚洲va在线va| 国产精品亚洲综合久久| 日韩一级理论片| 精品一区二区三区久久久| 91亚洲一线产区二线产区| 91网上在线视频| 中文乱码字幕高清一区二区| 亚洲激情av在线| 在线观看日韩中文字幕| 欧美色网站导航| 成人免费观看在线视频| 亚洲男人av在线| 免费av不卡| 6080yy精品一区二区三区| 91国内外精品自在线播放| 91中文字幕在线| 亚洲人成网亚洲欧洲无码| 亚洲一卡二卡三卡四卡无卡网站在线看 | 久久久国产精品黄毛片| 粉嫩老牛aⅴ一区二区三区| 欧美 亚洲 另类 激情 另类| 精品欧美一区二区久久| 国产小视频在线| 欧美成人全部免费| 欧美大片免费| caoporn国产精品免费公开| 亚洲欧洲免费| 97久久国产亚洲精品超碰热| 日韩成人一级片| 亚洲精品激情视频| 欧美国产精品劲爆| 日本少妇xxxx动漫| 欧美日韩电影在线| 桃花色综合影院| 九九精品视频在线观看| 777午夜精品电影免费看| 国产经品一区二区| 日韩久久精品网| ww国产内射精品后入国产| 久久精品免费看| 亚洲av无码一区二区三区观看| 1区2区3区精品视频| 四虎精品永久在线| 日韩精品中文字幕一区二区三区| 国产三级视频在线| 91av国产在线| **爰片久久毛片| 欧美 另类 交| 免费成人在线观看视频| 特级西西人体wwwww| 亚洲精品久久久蜜桃| 中文字幕观看在线| 日韩久久精品电影| 成年人国产在线观看| 91久久精品美女| 成人在线视频免费观看| 欧美成人免费高清视频| 99久久精品国产精品久久 | 色欧美片视频在线观看| 免费观看a视频| 欧美另类高清videos| 伊人久久大香| 亚洲精品一区二| 久久aⅴ国产紧身牛仔裤| 艳妇乳肉亭妇荡乳av| 亚洲成人免费视| 亚洲精品成人电影| 欧美成人精品在线播放| 999精品嫩草久久久久久99| 亚州欧美一区三区三区在线| 日韩在线一区二区| 懂色av蜜桃av| 欧美自拍偷拍午夜视频| 国产女主播在线写真| 国产精品极品美女粉嫩高清在线| 免费短视频成人日韩| 欧美 国产 小说 另类| 久久久天堂av| 人妻丰满熟妇av无码区| 亚洲精品小视频| 成人日韩在线观看| 日本一区二区在线视频观看| 水野朝阳av一区二区三区| 久久成人激情视频| 欧美性生活久久| 蜜桃视频在线观看免费视频网站www| 国产精品极品在线| 欧美电影三区| xxx中文字幕| 亚洲在线视频网站| 日韩中文字幕免费在线观看| 韩剧1988免费观看全集| 亚洲美女15p| 天堂中文视频在线| 中文字幕亚洲精品在线观看| jlzzjlzz亚洲女人18| 久久久久久久色| 岳的好大精品一区二区三区| 污污视频网站免费观看| 国产精品久久久久一区| 国产sm主人调教女m视频| 欧美激情综合亚洲一二区| 亚洲系列另类av| 青青草久久伊人| 亚洲成人资源网| 能在线看的av| 亚洲a一级视频| 亚洲一区二区三区高清| 国产91丝袜美女在线播放| 欧美一级生活片| 狼人综合视频| 一本一生久久a久久精品综合蜜 | 亚洲国产专区校园欧美| 在线免费观看麻豆| 制服丝袜国产精品| 高清毛片在线观看| 四虎永久国产精品| 国产河南妇女毛片精品久久久| 日韩和一区二区| 中文字幕在线看视频国产欧美| 涩爱av色老久久精品偷偷鲁 | 久久精品国产成人一区二区三区| 久久久久久久中文字幕| 亚洲色图18p| jizz国产精品| 亚洲视频一二三四| 亚洲成人精品在线观看| 男人资源在线播放| 久久大香伊蕉在人线观看热2| 九九久久精品视频| 天天操夜夜操视频|