日韩av黄I国产麻豆传媒I国产91av视频在线观看I日韩一区二区三区在线看I美女国产在线I麻豆视频国产在线观看I成人黄色短片

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 综合教程 >内容正文

综合教程

linux内核之时间子系统

發布時間:2023/12/3 综合教程 59 生活家
生活随笔 收集整理的這篇文章主要介紹了 linux内核之时间子系统 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

一、概要

???????? 時間管理在內核中占有非常重要的地位,內核中有大量的函數都是基于時間驅動的。有些函數需要周期執行,而有些需要等待一個相對時間后才運行,此外內核還必須管理系統的運行時間以及當前日期和時間。內核必須在硬件的幫助下才能計算和管理時間。

???????? 硬件為內核提供了一個系統定時器用以計算流逝的時間,該時鐘在內核中可看成是一個電子時間資源。系統定時器以某種頻率自行觸發或射中時鐘中斷,當時鐘中斷發生時內核就通過一種特殊的中斷處理程序對其進行處理。該頻率可以通過編程預定(即節拍率),連續兩次時鐘中斷的間隔時間稱為節拍(tick)。利用時間中斷周期執行的主要工作:

A.更新系統運行時間

B.更新墻上時間

C.在smp系統上,均衡調度程序中各處理器上的運行隊里

D.檢查當前進程是否用盡了自己的時間片

E.運行超時的動態定時器

F.更新資源消耗和處理器時間的統計值

?

1、節拍率:HZ

???????? 系統定時器頻率是通過靜態預處理定義的,就是HZ,在系統啟動時按照HZ值對硬件進行設置。不同體系結構,HZ不同,但大部分都是100即一個tick是10ms。

???????? 一個合適的HZ是相當重要的,下面分析了高HZ的優勢和劣勢:

優勢:

A.內核定時器能夠以更高的頻度和更高的準確度運行

B.依賴定時值的系統調用(poll和select)能夠以更高的精度運行

C.對諸如資源消耗和系統運行時間等的測量會有更精細的解析度

D.提高進程搶占的準確度

劣勢:

A.中斷頻率越高,切換頻繁,系統負擔越重

B.中斷處理程序占用的CPU時間越多

C.更頻繁的打亂處理器高速緩存并增加耗電

2、jiffies

???????? 全局變量jiffies用來記錄自系統啟動以來產生的節拍的總數。內核給jiffies賦了一個特殊的初值,引起盡早溢出捕捉bug,每次時鐘中斷處理程序就會增加該變量的值。

???????? 在include/linux/jiffies.h文件中定義了該變量:

extern unsigned long volatile __jiffy_datajiffies;

jiffies為無符號長整形,在32位體系結構上是32位,在64位體系結構上是64位。

???????? 當jiffies變量的值超過它的最大存放范圍后就會發生溢出,回繞到0。因此,內核提供了四個宏來幫助比較節拍計數,能正確地處理節拍計數回繞情況:

time_after(a, b) time_before(a, b)time_after_eq(a, b) time_before_eq(a, b)

3、硬件時鐘和定時器

???????? 體系結構提供了兩種設備進行計時:實時時鐘和系統定時器。

實時時鐘:

???????? 用來持久存放系統時間的設備,即便系統關閉后也可以靠主板上的微型電池提供的電力保持系統的計時。當系統啟動時,內核通過讀取RTC來初始化墻上時間,該時間存放在xtime變量中,然后定期同步兩者時間保持一致,重啟時可以得到一個相對準確的時間。

系統定時器:

???????? 內核定時機制中最為重要的角色,提供一種周期性觸發中斷機制。相應的中斷處理程序主要完成以下工作:

A.更新jiffies

B.更新墻上時間

C.更新資源消耗的統計值,比如當前進程所消耗的系統時間和用戶時間

D.執行到期的動態定時器

E.執行scheduler_tick()函數

F.計算平均負載值

4、實際時間

???????? 當前實際時間定義在文件kernel/time/timekeeping.c中:

static struct timekeeper timekeeper

struct timekeeper {

u64????????xtime_sec;

u64????????xtime_nsec;

}

xtime_sec以秒為單位,存放著自1970年1月1日(UTC)以來經過的時間,該時間點被稱為紀元,多數Unix系統的墻上時間都是基于該紀元而言的。xtime_nsec上一秒開始經過的ns數。

???????? 通過gettimeofday和settimeofday來獲取和設置當前時間,設置時間需要具有CAP_SYS_TIME權能。

5、動態定時器

???????? 它是管理內核流逝的時間的基礎,使用簡單。只需要執行一些初始化工作,設置一個超時時間,指定超時發生后執行的函數,然后激活定時器就可以了。

???????? 定時器由結構timer_list表示,定義在文件<include/linux/timer.h >

struct timer_list {??????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????

???/*???????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????

????* All fields that change during normal runtime grouped to the???????????????????????????????????????????????????????????????????????????????

????* same cacheline????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????

????*/??????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????

???struct list_head entry;? ?//定時器鏈表入口????????????????????????????????????????????????????????????????????????????????????????????????????????????????????

???unsigned long expires;? ?//以jiffies為單位的定時值?????????????????????????????????????????????????????????????????????????????????????????????????????????????????????

???struct tvec_base *base;? //定時器內部值,用戶不使用? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ??

???void (*function)(unsigned long); //定時器處理函數????????????????????????????????????????????????????????????????????????????????????????????????????????????

???unsigned long data;????????? //傳遞給處理函數的長整型參數? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ??

intslack;????????

???????? …

}

???????? 使用方法如下:

創建定時器:structtimer_list my_timer

初始化定時器:init_timer(&my_timer)

定時值初始化:

??????????????????????????? my_timer.expires= jiffies + delay

??????????????????????????? my_timer.data= 0

??????????????????????????? my_timer.function= my_function( void my_function(unsigned long data))

激活定時器:add_timer(&my_timer)

修改已經激活的定時器超時時間:mod_timer(&my_timer,jiffies+new_delay)

在定時器超市前停止定時器:del_timer(&my_timer)或 del_timer_sync(&my_timer)

? ?????? 定時器作為軟中斷在下半部上下文中執行,時鐘中斷處理程序會通過raise_softirq(TIMER_SOFTIRQ)喚醒定時器軟中斷,從而在當前處理器上運行所有的超時定時器。雖然所有定時器都以鏈表形式存放在一起,但是為了提高搜索效率,內核將定時器按照他們的超時時間劃分成五組,當定時器超時時間接近時,定時器將隨組一起下移。

6、延遲執行

???????? 內核代碼(尤其是驅動程序)除了使用定時器或下半部機制以外,還需要其他方法來推遲執行任務。內核提供了許多延遲方法處理各種延遲要求:

A.忙等待

???????? 該方法想要延遲的時間是節拍的整數倍,或者精確率要求不高時使用

unsinged long timeout = jiffies + 10

while (time_before(jiffies, timeout))

???????? ;

或者

while(time_before(jiffies, delay))

???????? cond_resched();

B.短延遲:

???????? voidudelay(unsigned long usecs)

???????? voidndelay(unsigned long nsecs)

???????? voidmdelay(unsigned long msecs)

/proc/cpuinfo的BogoMIPS主要被udelay()和mdelay()函數使用,記錄處理器在給定時間內忙循環執行的次數。

C.schedule_timeout()

???????? 該方法會讓需要延遲執行的任務睡眠到指定的延遲時間耗盡后再重新運行。唯一的參數是延遲的相對時間,單位是jiffies。需要注意一點:

該函數需要調用調度程序,所以調用它的代碼必須保證能夠睡眠。換句話說,調用代碼必須處于進程上下文中,并且不能持有鎖。

二、linux時間框架

1、框架

隨著技術發展,出現了下面兩種新的需求:

(1)嵌入式設備需要較好的電源管理策略。傳統的linux會有一個周期性的時鐘,即便是系統無事可做的時候也要醒來,這樣導致系統不斷的從低功耗(idle)狀態進入高功耗的狀態。這樣的設計不符合電源管理的需求。

(2)多媒體的應用程序需要非常精確的timer,例如為了避免視頻的跳幀、音頻回放中的跳動,這些需要系統提供足夠精度的timer。

???????? 因此,內核時間子系統也進行了框架調整,引進了高精度timer。和低精度timer不同,高精度timer使用了人類的最直觀的時間單位ns(低精度timer使用的tick是和內核配置相關,不夠直接)。本質上linuxkernel提供了高精度timer之后,其實不必提供低精度timer了,不過由于低精度timer存在了很長的歷史,并且滲入到內核各個部分,如果去掉容易引起linuxkernel穩定性和健壯性的問題,因此kernel保持兩種并存。其示意圖如下:

???????? 在smp情況下,driver硬件定時器劃分成了兩部分:一個提供給clocksource模塊使用,一個提供給clockevent事件使用。而clockevent又簡單化為兩個小部分:一個是每個CPU自己的定時器,一個是全局定時器;每個CPU定時器管理本CPU的任務運行情況、資源統計等,第一個啟動CPU(一般是CPU0)還會更新tick和墻上時鐘,而globaltimer則主要用于低功耗模式下CPU進入睡眠時喚醒所有CPU。

???????? Kernel抽象了底層驅動,劃分為clockevent和clocksource連個模塊,驅動加載時會調用兩個模塊接口進行注冊。clocksource的精度就是定時器時鐘頻率的精度(ns級別),可以認為是一個timeline,而clockevent則是這個timeline上的特定時間點,產生中斷后調用相應的callback函數進行事件處理。

???????? tickdevice layer 基于clockevent設備進行工作:每個CPU都有自己唯一的tickdevice,管理自己的調度,進程統計等。Tickdevice可以工作在兩種模式:periodic 和 one shot mode。有多少CPU就有多少個tickdevice稱之為local tickdevice,在所有的local tickdevice中會有一個被選為globaltick device(一般是CPU0的tick device),該device負責維護整個系統的jiffies,更新wall clock,計算全局負荷什么的。

???????? 高精度hrtimer需要高精度的clockevent,工作在one shotmode的tick device提供高精度的clockevent。雖然有了高精度hrtimer的出現,內核并沒有拋棄老的低精度timer機制。當系統處于高精度timer的時候,系統會setup一個特別的高精度hrtimer(sched_timer),該高精度timer會周期性的觸發,從而模擬傳統的periodictick,推動傳統低精度timer的運轉(代碼沒有弄明白sched_timer?)。

2、內核配置

(1)GENERIC_CLOCKEVENTS和GENERIC_CLOCKEVENTS_BUILD:代表使用新的時間子系統架構,默認就是配置好的

(2)新時間子系統框架下,Timerssubsystem配置選項主要和tick已經是否支持高精度hrtimer有關。Tick有2種配置(二選一):

CONFIG_HZ_PERIODIC:無論何時都啟用周期性的tick,即便是在系統idle的時候。

CONFIG_NO_HZ_IDLE:該選項默認會打開 CONFIG_TICK_ONESHOT 和CONFIG_NO_HZ_COMMON,在系統idle的時候,停掉周期性tick。

CONFIG_HIGH_RES_TIMERS:支持高精度hrtimer

配置了高精度hrtimer或NO_HZ_COMMOM就一定配置CONFIG_TICK_ONESHOT,表示系統支持one-shot類型的tick_device。

???????? 因此,在新時間子系統下有4種配置:

A.低精度timer和周期tick

B.低精度timer和dynamic tick(tickless idle)(當前系統使用情況)

C.高精度hrtimer和周期tick

D.高精度hrtimer和dynamic tick(tickless idle)

3、四種配置(轉載自附錄網站)

(1)低精度timer + 周期tick

我們首先看周期性tick的實現。起始點一定是底層的clocksource chip driver,該driver會調用接口clockevents_register_device向clock event注冊。一旦增加了一個clockevent device,需要通知上層的tickdevice layer,有可能新注冊的這個device更好、更適合某個tick device。要是這個clock eventdevice被某個tickdevice收留了(要么該tickdevice之前沒有匹配的clockevent device,要么新的clockevent device更適合該tickdevice),那么就啟動對該tickdevice的配置(參考tick_setup_device)。根據當前系統的配置情況(周期性tick),會調用tick_setup_periodic函數,這時候,該tick device對應的clock event device的clock event handler被設置為tick_handle_periodic。底層硬件會周期性的產生中斷,從而會周期性的調用tick_handle_periodic從而驅動整個系統的運轉。需要注意的是:即便是配置了CONFIG_NO_HZ和CONFIG_TICK_ONESHOT,系統中沒有提供one shot的clock event device,這種情況下,整個系統仍然是運行在周期tick的模式下。

下面來到低精度timer模塊了,其實即便沒有使能高精度timer,內核也會把高精度timer模塊的代碼編譯進kernel的image中,這一點可以從Makefile文件中看出。在這種構架下,各個內核模塊也可以調用linuxkernel中的高精度timer模塊的接口函數來實現高精度timer,但是,這時候高精度timer模塊是運行在低精度的模式,也就是說這些hrtimer雖然是按照高精度timer的紅黑樹進行組織,但是系統只是在每一周期性tick到來的時候調用hrtimer_run_queues函數,來檢查是否有expire的hrtimer。毫無疑問,這里的高精度timer也就是沒有意義了。

由于存在周期性tick,低精度timer的運作毫無壓力,和過去一樣。

(2)低精度timer + Dynamic Tick

系統開始的時候并不是直接進入Dynamictick mode的,而是經歷一個切換過程。開始的時候,系統運行在周期tick的模式下,各個cpu對應的tick device的(clock event device的)event handler是tick_handle_periodic。在timer的軟中斷上下文中,會調用tick_check_oneshot_change進行是否切換到one shot模式的檢查,如果系統中有支持one-shot的clock event device,并且沒有配置高精度timer的話,那么就會發生tick mode的切換(調用tick_nohz_switch_to_nohz),這時候,tick device會切換到one shot模式,而event handler被設置為tick_nohz_handler。由于這時候的clock eventdevice工作在oneshot模式,因此當系統正常運行的時候,在eventhandler中每次都要reprogramclock event,以便正常產生tick。當cpu運行idle進程的時候,clock eventdevice不再reprogram產生下次的tick信號,這樣,整個系統的周期性的tick就停下來。

(3)高精度timer + Dynamic Tick

同樣的,系統開始的時候并不是直接進入Dynamictick mode的,而是經歷一個切換過程。系統開始的時候是運行在周期tick的模式下,event handler是tick_handle_periodic。在周期tick的軟中斷上下文中(參考run_timer_softirq),如果滿足條件,會調用hrtimer_switch_to_hres將hrtimer從低精度模式切換到高精度模式上。這時候,系統會有下面的動作:

A.Tickdevice的clockevent設備切換到oneshotmode(參考tick_init_highres函數)

B.Tickdevice的clockevent設備的eventhandler會更新為hrtimer_interrupt(參考tick_init_highres函數)

C.設定schedtimer(也就是模擬周期tick那個高精度timer,參考tick_setup_sched_timer函數)

這樣,當下一次tick到來的時候,系統會調用hrtimer_interrupt來處理這個tick(該tick是通過sched timer產生的)。

在Dynamictick的模式下,各個cpu的tick device工作在one shot模式,該tick device對應的clock event設備也工作在one shot的模式,這時候,硬件Timer的中斷不會周期性的產生,但是linuxkernel中很多的模塊是依賴于周期性的tick的,因此,在這種情況下,系統使用hrtime模擬了一個周期性的tick。在切換到dynamic tick模式的時候會初始化這個高精度timer,該高精度timer的回調函數是tick_sched_timer。這個函數執行的函數類似周期性tick中event handler執行的內容。不過在最后會reprogram該高精度timer,以便可以周期性的產生clockevent。當系統進入idle的時候,就會stop這個高精度timer,這樣,當沒有用戶事件的時候,CPU可以持續在idle狀態,從而減少功耗。

(4)高精度timer + 周期性Tick

這種配置不多見,多半是由于硬件無法支持oneshot的clockevent device,這種情況下,整個系統仍然是運行在周期tick的模式下。

三、用戶接口

1、系統時間相關服務

(1)秒級函數:time和stime

#include <time.h>

time_t time(time_t *t); //獲取時間秒

int stime(time_t *t); ?//設置時間秒

對應的系統調用為:sys_time和sys_stime。time函數返回當前點到linuxepoch的秒數,stime設定當前時間點到linuxepoch的秒數。

???????? 與上面函數配套的還有一系列時間點與linuxepoch轉換函數:mktime,localtime_r。

(2)微秒級函數:gettimeofday和settimeofday

#include <sys/time.h>

int gettimeofday(struct timeval *tv, structtimezone *tz);

int settimeofday(const struct timeval *tv,const struct timezone *tz);

struct timeval {

time_t????? tv_sec;???? /* seconds */

suseconds_ttv_usec;??? /* microseconds */

};

struct timezone {

inttz_minuteswest;???? /* minutes west ofGreenwich */

inttz_dsttime;????? ???/* type of DST correction */

};

對應的系統調用:sys_gettimeofday和sys_settimeday。Gettimeofday獲取linux epoch到當前時間點的秒數以及微秒數;settimeofday則設定從linuxepoch到當前時間點的秒數以及微秒數。

值得一提的是:這些系統調用在新的POSIX標準中接口被clock_gettime和clock_settime取代。

(3)納秒級別的時間函數:clock_gettime和clock_settime

#include <time.h>

int clock_getres(clockid_t clk_id, structtimespec *res); //獲取clock_id的系統時鐘精度

int clock_gettime(clockid_t clk_id, structtimespec *tp);

int clock_settime(clockid_t clk_id, conststruct timespec *tp);

struct timespec {

time_t?? tv_sec;??????? /* seconds */

long???? tv_nsec;?????? /* nanoseconds */

};

clk_id識別systemclock的ID,定義如下:

CLOCK_REALTIME:真實的墻上時鐘,前面函數就是從獲取該ID的值

CLOCK_MONOTONIC:該時鐘是單調遞增的,也是真實的墻上時鐘只是起始點不一定是linuxepoch,一般會把系統啟動的時間點設定為基準點。除了NTP和adjtime對該時鐘進行調整外,其他任何接口不允許設定該時鐘,保證該時鐘的單調性。可以了解系統啟動時間。

CLOCK_MONOTONIC_RAW:具備CLOCK_MONOTONIC的特性,但它不受NTP和adjtime影響,是完全基于本地晶振的時鐘。一般程序員不大用。

CLOCK_BOOTTIME:類似CLOCK_MONOTONIC,但是系統suspend時依然增加。

CLOCK_PROCESS_CPUTIME_ID:每個CPU的高精度進程定時器,clock_getcpuclockid獲取進程的clock_id

CLOCK_THREAD_CPUTIME_ID:線程的CPU時間,pthread_getcpuclockid獲取線程的clock_id。

(4)系統時鐘調整

???????? 上面設定系統時間是一個比較粗暴的做法,一旦修改了系統時間,系統中很多以來絕對時間的進程會有各種奇怪的行為。所以系統提供了時間同步的接口函數,可以讓外部的精準計時服務器不斷的修正系統時鐘。

A.adjtime

int adjtime(const struct timeval *delta,struct timeval *olddelta);

struct timeval {

time_t????? tv_sec;???? /* seconds */

suseconds_ttv_usec;?? ?/* microseconds */

};

???????? 該函數可以根據delta參數緩慢的修正系統時鐘(CLOCK_REALTIME那個)。olddelta返回上一次調整中尚未完成的delta。

B.adjtimex

#include <sys/timex.h>

int adjtimex(struct timex *buf);

struct timex {

intmodes;?????????? /* mode selector */

longoffset;???????? /* time offset (usec) */

longfreq;?????????? /* frequency offset(scaled ppm) */

longmaxerror;?????? /* maximum error (usec)*/

longesterror;?????? /* estimated error (usec)*/

intstatus;????????? /* clock command/status*/

longconstant;?????? /* pll time constant */

longprecision;????? /* clock precision (usec)(read-only) */

longtolerance;????? /* clock frequencytolerance (ppm)

??????????????????????????????????????(read-only) */

structtimeval time; /* current time (read-only) */

longtick;?????????? /* usecs between clockticks */

};

???????? 該函數用來顯示或這修改linux內核的時間變量的工具,提供了對與內核時間變量直接訪問功能,可以實現對于系統時間的飄逸進行修正。任何用戶都可以使用它查看,但是只有root用戶才可以更改這些參數。

2、進程睡眠

(1)秒級函數:sleep

#include <unistd.h>

unsigned int sleep(unsigned int seconds);

???????? 該函數會導致當前進程sleepseconds之后(基于CLOCK_REALTIME)返回繼續執行程序。返回值說明了進程沒有進入睡眠的時間。

(2)微秒級別函數:usleep

#include <unistd.h>

int usleep(useconds_t usec);

???????? 該函數功能和上面一樣,不過返回值定義不同。0:表示執行成功,-1:執行失敗,錯誤碼在errno中。

(3)納秒級別函數:nanosleep

#include <time.h>

int nanosleep(const struct timespec *req,struct timespec *rem);

struct timespec {

time_ttv_sec;??????? /* seconds */

long?? tv_nsec;?????? /* nanoseconds */

};

該函數取代了usleep函數,req中設定你要sleep的秒以及納秒值,rem表示還有多少時間沒睡完。返回0表示成功,返回-1說明失敗。

sleep/usleep/nanosleep的系統都是通過kernel的sys_nanosleep系統調用實現(底層基于hrtimer)。

(4)更高級的sleep函數:clock_nanosleep

#include <time.h>

int clock_nanosleep(clockid_t clock_id, intflags,

?????????????????????????? const structtimespec *request,

?????????????????????????? struct timespec*remain);

clock_id說明該函數不僅能基于real_timeclock睡眠,還可以基于其他的系統時鐘睡眠。flag等0或1,分別指明request參數設定的時間值是相對時間還是絕對時間。

3、timer相關的服務

(1)alarm函數

#include <unistd.h>

unsigned int alarm(unsigned int seconds);

???????? 該函數在指定秒數(基于CLOCK_REALTIME)的時間過去后,向該進程發送SIGALRM信號。調用該接口的程序需要設定signalhandler。

四、代碼解析

第二章節講述內核配置有兩種主要模式:periodic和 one-shot,下面代碼分析主要根據實際使用的低精度tick和dynamic tick (tickles tick)即使用one-shot配置進行講解(Linux-3.10.y)。

1、數據結構

(1)clocksource

內核使用structclocksource數據結構記錄時鐘源所有信息,主要作為系統時間的基準,當有多個時鐘源時選擇最優那個,沒有時鐘源時默認使用基于jiffies的時鐘clocksource_jiffies。內核通過一個鏈表clocksource_list管理所有注冊的時鐘源,每個時鐘源定義了一個單調增加的計數器并以ns為單位。

???????? structclocksource結構體詳細如下(include/linux/clocksource.h):

struct clocksource {

???cycle_t (*read)(struct clocksource *cs);?//讀取指定CS的cycle值(定時器當前計數值)

???cycle_t cycle_last;?? //保存最近一次read的cycle值(其中一個重要作用翻轉)

cycle_tmask; //counter是32位還是64位

//公式:ns =(cycles/F) * NSEC_PER_SEC = (cycle* mult) >> shift

???u32 mult; //cycle轉化為ns的乘數

???u32 shift; //cycle轉化為ns的除數,采用移位的方式

???u64 max_idle_ns; //該時鐘允許的最大空閑時間(沒搞明白如何用)

???u32 maxadj;???? //最大調整值與mult相關

#ifdef CONFIG_ARCH_CLOCKSOURCE_DATA //未用

???struct arch_clocksource_data archdata;

#endif

???const char *name; //時鐘源名字

???struct list_head list; //注冊時鐘源鏈表頭

intrating; //時鐘源精度值,

1--99: 不適合于用作實際的時鐘源,只用于啟動過程或用于測試;

100--199:基本可用,可用作真實的時鐘源,但不推薦;

200--299:精度較好,可用作真實的時鐘源;

300--399:很好,精確的時鐘源;

400--499:理想的時鐘源,如有可能就必須選擇它作為時鐘源;

??? int(*enable)(struct clocksource *cs); //使能時鐘源

???void (*disable)(struct clocksource *cs); //禁止時鐘源

???unsigned long flags; //時鐘源屬性,CLOCK_SOURCE_IS_CONTINUOUS連續時鐘

???void (*suspend)(struct clocksource *cs); //掛起時鐘源

???void (*resume)(struct clocksource *cs); //恢復時鐘源

#ifdef CONFIG_CLOCKSOURCE_WATCHDOG?? //未用

???/* Watchdog related data, used by the framework */

???struct list_head wd_list;

???cycle_t cs_last;

???cycle_t wd_last;

#endif

}____cacheline_aligned;

(2)clockevent

內核使用struct clock_event_device數據結構記錄時鐘的事件信息,包括硬件時鐘中斷發生時要執行的那些操作。提供了對周期性事件和單觸發事件的支持。還提供了高精度定時器和動態定時器的支持。內核通過一個clockevent_devices管理所有注冊的clock event設備。

???????? 該結構體在頭文件include/linux/clockchips.h中定義,詳細定義如下:

struct clock_event_device {

???void ???????? (*event_handler)(structclock_event_device *); //事件處理函數,主要有三種:peridioc\one-shot\broadcast

???int??? (*set_next_event)(unsignedlong evt, struct clock_event_device *); //設置下次觸發事件基于clocksource的cycles

???int??? (*set_next_ktime)(ktime_texpires, struct clock_event_device *); //設置下次觸發事件基于ktime(用得比較少)

???ktime_t??? next_event;

???u64? max_delta_ns; //可設置的最大時間差

???u64? min_delta_ns; //可設置的最小時間差

???u32? mult; //和clocksource一樣

???u32? shift; //和clocksource一樣

???enum clock_event_mode?? mode; //clockevent工作模式,見下面

???unsigned int??????? features; //clockevent設備特征,見下面

?? ?unsigned long?????? retries;

???void? (*broadcast)(const structcpumask *mask); //廣播所有CPU函數

???void? (*set_mode)(enumclock_event_mode mode, struct clock_event_device *); //設置模式

???void? (*suspend)(structclock_event_device *);

???void? (*resume)(struct clock_event_device*);

???unsigned long? min_delta_ticks;

???unsigned long? max_delta_ticks;

???const char??????? *name;

???int??? rating;

???int??? irq;

???const struct cpumask????? *cpumask;//CPU掩碼,判斷是否屬于某一個CPU,或廣播支持的CPU

???struct list_head??????? list;

} ____cacheline_aligned;

???????? clockevent設備工作模式:

enum clock_event_mode {

???CLOCK_EVT_MODE_UNUSED = 0,??????????

???CLOCK_EVT_MODE_SHUTDOWN,?????????? //關閉模式

???CLOCK_EVT_MODE_PERIODIC,?????????????? //周期性模式

???CLOCK_EVT_MODE_ONESHOT,????? //單次模式

???CLOCK_EVT_MODE_RESUME,??????? //恢復模式

};

???????? clockevent設備特征:

#define CLOCK_EVT_FEAT_PERIODIC???? 0x000001 ???????? //可以產生周期觸發事件特征

#define CLOCK_EVT_FEAT_ONESHOT???? 0x000002????????? //可以產生單觸發事件特征

#define CLOCK_EVT_FEAT_KTIME?????????? 0x000004 ?????? //產生事件的事件基準ktime

//X86下使用,進入省電情況

#define CLOCK_EVT_FEAT_C3STOP???????? 0x000008 ?????? //clocksource停止,需要廣播事件支持,本ARM平臺也使用了該選項

#define CLOCK_EVT_FEAT_DUMMY?????? 0x000010????????? // Local APIC timer使用該選項

(3)tick_device

???????? struct tick_device只是對struct clock_event_device的一個封裝,加入了運行模式變量,支持PERIODIC和ONESHOT兩種模式。

struct tick_device {

???struct clock_event_device *evtdev;

???enum tick_device_mode mode;

};

enum tick_device_mode {

???TICKDEV_MODE_PERIODIC,

???TICKDEV_MODE_ONESHOT,

};

2、內核初始化

???????? 在內核啟動函數start_kernel里對時間系統進行了初始化

(1)tick_init

???????? 該函數初始化tick控制。向clockevents_chain通知鏈中添加一個tick通知分發器tick_notifier(分發回調函數:tick_notify)。在底層驅動注冊設備時,CLOCK_EVT_NOTIFY_ADD消息就是添加了一個新的clockevent設備。

初始化tick broadcast掩碼,如果配置了CONFIG_TICK_ONESHOT相關掩碼也要初始化。

(2)init_timers

初始化本CPU上的低精度定時器相關的數據結構,將通知分發器timers_nb添加到cpu_chain通知鏈;初始化定時器軟中斷open_softirq(TIMER_SOFTIRQ, run_timer_softirq);

(3)hrtimers_init

初始化本CPU上的高精度精度定時器相關的數據結構,將通知分發器hrtimers_nb添加到cpu_chain通知鏈;如果開啟高精度定時器宏,則初始化高精度定時器軟中斷open_softirq(HRTIMER_SOFTIRQ, run_hrtimer_softirq)(本平臺為使用)。

(4)timekeeping_init

初始化時鐘源clocksource及timekeeping模塊時間初始值,如果平臺沒有更好的時鐘源,系統使用jiffies作為時鐘源。

clock = clocksource_default_clock();

struct clocksource * __init __weakclocksource_default_clock(void)

{

???return &clocksource_jiffies;

}

struct clocksource clocksource_jiffies = {

???.name?????? = "jiffies",

???.rating???? = 1, /* lowest validrating*/

???.read?????? = jiffies_read,

???.mask?????? = 0xffffffff,/*32bits*/

???.mult?????? = NSEC_PER_JIFFY<< JIFFIES_SHIFT, /* details above */

???.shift????? = JIFFIES_SHIFT,

};

(5)time_init

前面函數時內核通用架構,該函數為硬件時鐘初始化平臺相關,一般由各個平臺自己實現,細節見下節。

void __init time_init(void)

{??

???if (machine_desc->init_time)

? ??????machine_desc->init_time(); (=hi3536_timer_init)

???else

???????clocksource_of_init();

???sched_clock_postinit();

}

?

3、硬件時鐘初始化

(1)平臺注冊

MACHINE_START(HI3536, "hi3536")

.atag_offset? = 0x100,

???.map_io?????? = hi3536_map_io,

???.init_early?? = hi3536_init_early,

???.init_irq???? =hi3536_gic_init_irq,

#ifdef CONFIG_HI3536_SYSCNT

???.init_time??? = arch_timer_init,

#else

??? .init_time??? =hi3536_timer_init,

#endif?

???.init_machine = hi3536_init,

???.smp????????? =smp_ops(hi3536_smp_ops),

???.reserve????? = hi3536_reserve,

???.restart????? = hi3536_restart,

???MACHINE_END

???????? 上一節machine_desc的具體實現即為該宏定義,init_time就是hi3536_timer_init,其具體內容見下面。

?

(2)平臺定時器初始化

void __init hi3536_timer_init(void)

{

/* 設置所有定時器的工作時鐘(未初始化,默認3MHZ)

???????? Hi3536有time0~910個時鐘

???????? 根據配置,所有定時器都配置成了總線時鐘125Mhz(8ns)

*/

???writel(readl((const volatile void *)IO_ADDRESS(REG_BASE_SCTL)) |

???????(1 << 16) | (1 << 18),

???????(volatile void *)IO_ADDRESS(REG_BASE_SCTL));???

#ifdef CONFIG_SP804_LOCAL_TIMER

???hi3536_local_timer_init(); //每個CPU使用一個定時器作為local timer,該平臺有4核CPU0~CPU3分別對應:timer4~timer7,注冊為clockevent設備

#endif

???hi3536_clocksource_init((void *)TIMER(0)->addr,

???????TIMER(0)->name); //timer0作為clocksource設備

???sp804_clockevents_init((void *)TIMER(1)->addr,

???????TIMER(1)->irq.irq, TIMER(1)->name); //timer1作為clockevent設備的globaltimer

}

???????? 從上面看,hi3536總共支持10個timer,實際使用了6個,timer0/timer1,timer4~timer7,其他保留。其注冊的順序如下:timer0(clocksource)—> timer1(clockevent global timer) —> timer4(clockevent cpu0 local timer)—> time5~7(clockevent cpu1~3 local timer)。每類定時器的初始化,見下面細節分析。

(3)clocksource初始化

???????? 初始化函數源碼如下:

static void __inithi3536_clocksource_init(void __iomem *base, const char *name)?????????????????????????????????????????????????????????????????

{????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????

???long rate = sp804_get_clock_rate(name); ?//獲取定時器時鐘62.5MHz? ????

???struct clocksource *clksrc = &hi3536_clocksource.clksrc;???

???

???if (rate < 0)????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????

???????return;??????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????

???? ???

???clksrc->name?? = name;? //name=timer0 ???????

???clksrc->rating = 200; //時鐘源精度值????????????

???clksrc->read?? =hi3536_clocksource_read;? ?//獲取計數值,系統主要調用該接口轉化為系統時間? ???????

???clksrc->mask?? =CLOCKSOURCE_MASK(32),? //計數值32位

???clksrc->flags? = CLOCK_SOURCE_IS_CONTINUOUS,?//持續的時鐘源

???clksrc->resume = hi3536_clocksource_resume,? ????

???hi3536_clocksource.base = base;? ?????

???hi3536_clocksource_start(base);? //初始化寄存器

??? clocksource_register_hz(clksrc, rate); ?//計算出mult和shift,為系統選擇更好的時鐘源??

???setup_sched_clock(hi3536_sched_clock_read, 32, rate); //通用sched_clock模塊,這個模塊主要是提供一個sched_clock的接口函數,獲取當前時間點和系統啟動之間的納秒值。

}

(4)per CPU定時器初始化

???????? 每CPU定時器初始化函數:

static void __inithi3536_local_timer_init(void)

{??

? ??unsigned int cpu = 0;

???unsigned int ncores = num_possible_cpus(); //獲取CPU個數

? ? local_timer_rate = sp804_get_clock_rate("sp804"); //獲取定時器時鐘

? ? for (cpu = 0; cpu < ncores; cpu++) { //為每個CPU分配各自的定時器

???????struct hi_timer_t *cpu_timer = GET_SMP_TIMER(cpu);

? ? ? ? cpu_timer->irq.handler = sp804_timer_isr; //中斷處理函數

???????cpu_timer->irq.dev_id = (void *)cpu_timer; //定時器分別是timer0~3

???????setup_irq(cpu_timer->irq.irq, &cpu_timer->irq); //注冊中斷號

???????disable_irq(cpu_timer->irq.irq); //關閉中斷

?? ?}

local_timer_register(&hi3536_timer_tick_ops);//注冊定時器操作函數

?/* 以上只是為每個CPU分配了定時器,并沒有注冊每個cpu的clockevent,啟動CPU(CPU0)在稍后注冊,而其他次CPU則直到kernel_init啟動它們后才會注冊 */

}

//定時器注冊clockevent操作函數

static struct local_timer_opshi3536_timer_tick_ops __cpuinitdata = {

???.setup? =hi3536_local_timer_setup,

???.stop?? = hi3536_local_timer_stop,

};

static int __cpuinithi3536_local_timer_setup(struct clock_event_device *evt)

{

???unsigned int cpu = smp_processor_id();

???struct hi_timer_t *timer = GET_SMP_TIMER(cpu);

???struct irqaction *irq = &timer->irq;

? ? evt->name = timer->name;

???evt->irq? = irq->irq;

???evt->features = CLOCK_EVT_FEAT_PERIODIC | CLOCK_EVT_FEAT_ONESHOT

????????????????????????? |CLOCK_EVT_FEAT_C3STOP;

? ? evt->set_mode = sp804_set_mode;

???evt->set_next_event = sp804_set_next_event;

???evt->rating = 350;

? ? timer->priv = (void *)evt;

? ? clockevents_config_and_register(evt, local_timer_rate, 0xf, 0xffffffff);//注冊clockevent

???irq_set_affinity(evt->irq, evt->cpumask);

???enable_irq(evt->irq);

? ? return 0;

}

//中斷處理函數

static irqreturn_t sp804_timer_isr(int irq,void *dev_id)

{

???struct hi_timer_t *timer = (struct hi_timer_t *)dev_id;

???unsigned int clkevt_base = timer->addr;

???struct clock_event_device *evt

???????= (struct clock_event_device *)timer->priv;

? ? /* clear the interrupt */

???writel(1, IOMEM(clkevt_base + TIMER_INTCLR));

? ? evt->event_handler(evt);? //periodic 和 one-shot模式處理函數不一樣,見4小節細節。

? ? return IRQ_HANDLED;

}

(5)per CPU注冊clockevent

???????? 上面只是初始化為每個CPU分配一個定時器,并沒有將定時器注冊到clockevent。而注冊則是在各個CPU啟動后,主CPU和次CPU注冊是分開的,具體如下:

A.主CPU(cpu0)

???????? 注冊過程:kernel_init—> kernel_init_freeable —> smp_prepare_cpus —> percpu_timer_setup :

static void __cpuinitpercpu_timer_setup(void)

{

???unsigned int cpu = smp_processor_id();

???struct clock_event_device *evt = &per_cpu(percpu_clockevent, cpu);

? ?evt->cpumask = cpumask_of(cpu);

? ?if (!lt_ops || lt_ops->setup(evt)) //這里的setup就是前面初始化的:hi3536_local_timer_setup,將CPU0的timer注冊到clockevent設備。

???????broadcast_timer_setup(evt);

}

B.次CPU(cpu1~cpu3)

???????? 注冊過程:kernel_init—> kernel_init_freeable —> smp_init:

void __init smp_init(void)

{??

?? …

???/* FIXME: This should be done in userspace --RR */

???for_each_present_cpu(cpu) {

???????if (num_online_cpus() >= setup_max_cpus)

???????????break;

???? ???if (!cpu_online(cpu)) //啟動所有未啟動的CPU

???????????cpu_up(cpu);

??? }

}

???????? cpu_up—> _cpu_up —> __cpu_up —> boot_secondary —> smp_ops.smp_boot_secondary—> hi3536_boot_secondary —> hi3536_secondary_startup(匯編) —> secondary_startup(匯編) —> __secondary_switched(匯編) —> secondary_start_kernel —>percpu_timer_setup該函數就是上面主CPU注冊本地定時器的函數。

(6)clockevent初始化

???????? 這里主要是注冊clockevent的global timer,在periodic模式下不起作用,在one-shot模式下才會作用。注冊過程過程如下:

???????? sp804_clockevents_init—> __sp804_clockevents_init —> clockevents_config_and_register —> clockevents_register_device—> clockevents_do_notify —> tick_notify(tick_init初始化的通知分發器) —>tick_check_new_device

?

4、periodic和one-shot模式

???????? 針對clockevent有periodic和one-shot兩種模式,主要的不同點:event_handler事件處理函數不同,細節見下列分析。

(1)periodic模式

???????? 根據上一節的注冊初始化,其先后順序如下:timer1(clockeventglobal timer) —> timer4(clockevent cpu0 local timer) —> time5~7(clockeventcpu1~3 local timer)。

???????? 注冊timer1時運行在CPU0上,次CPU1~3還沒有啟動,這時tick_check_new_device接口會把timer1注冊為CPU0的local timer,此刻timer1的event_handler= tick_handle_periodic。當CPU0調用smp_prepare_cpus注冊自己的local timer時會用timer4替換timer1,此刻timer4的event_handler= tick_handle_periodic,而timer1的event_handler在tick_setup_device中被修改為clockevents_handle_noop(空實現),并在接口tick_check_broadcast_device中被注冊為globaltimer設備(在周期模式下不起任何作用)。

???????? CPU1~3啟動時調用secondary_start_kernel注冊local timer時只有一個定時器分別是timer5~7,它們的event_handler= tick_handle_periodic。

???????? clockevents_handle_noop:空實現

???????? tick_handle_periodic主要完成如下工作:

A.如果是CPU0,則調用do_timer完成tick更新和墻上時鐘更新

B.update_process_times完成:啟動本地軟中斷;更新本CPU的運行隊列;調度任務;SMP下觸發運行隊列均衡。

?

(2)one-shot模式

???????? 設備啟動時一開始是periodic模式,過程和上面一模一樣。各個CPU觸發本地軟中斷后發生切換,run_timer_softirq—> hrtimer_run_pending —> tick_check_oneshot_change —> tick_nohz_switch_to_nohz—> tick_switch_to_oneshot:

將CPU0~3的event_handler切換為:tick_nohz_handler

將timer1的event_handler切換為:tick_handle_oneshot_broadcast

切換只會發生一次,切換好后hrtimer_run_pending接口就會直接返回。

tick_nohz_handler:

???????? 和tick_handle_periodic做的事情大致一樣。

tick_handle_oneshot_broadcast主要完成:喚醒各個CPU,補償tick的偏差。

???????? one-shot模式下event_handler處理函數每次都要重新設置next_event。該模式的好處就是可以節省CPU功耗。

5、系統調用例子講解

(1)gettimeofday

???????? 該函數主要用于獲取微妙級別的時間。其對應的系統調用為sys_gettimeofday,實際起作用的是do_gettimeofday:

void do_gettimeofday(struct timeval*tv)?????????????????????????????????????????????????????????????????????????????????????????????????????????

{????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????

???struct timespec now;?????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????

? ?getnstimeofday(&now); ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ??

???tv->tv_sec = now.tv_sec;?????????????????????????????????????????????????????????????????????????????????????????????????????????????????????

???tv->tv_usec = now.tv_nsec/1000;??????????????????????????????????????????????????????????????????????????????????????????????????????????????

}

int __getnstimeofday(structtimespec *ts) ????????????????????????????????????????????????????????????????????????????????????????????????????????

{??

???struct timekeeper *tk = &timekeeper;

???unsigned long seq;???????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????

???s64 nsecs = 0;? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ??

???do {

???????seq = read_seqcount_begin(&timekeeper_seq);? //使用順序鎖進行數據同步訪問

? ts->tv_sec = tk->xtime_sec;??? //獲取秒數,xtime_sec更新由update_all_time進行??????????????????????????????????????????????????????????????????????????????????????????????????????????????

???????nsecs = timekeeping_get_ns(tk); //調用clocksource的read函數(即上面的hi3536_clocksource_read),將計數轉化為相應的ns數

??? }while (read_seqcount_retry(&timekeeper_seq, seq));

?

???ts->tv_nsec = 0;

???timespec_add_ns(ts, nsecs); //調整ns數,傳遞給用戶

??????…..

}

?

(2)nanosleep

???????? 這是一個ns級別的睡眠函數,對應的系統調用sys_nanosleep(kernel/hrtimer.c),實際起作用的是hrtimer_nanosleep—> do_nanosleep:

static int __sched do_nanosleep(structhrtimer_sleeper *t, enum hrtimer_mode mode)

{??

???????? //初始化一個新的hrtimer

???hrtimer_init_sleeper(t, current);

???????

???do {

???????set_current_state(TASK_INTERRUPTIBLE); //設置當前任務睡眠

???????hrtimer_start_expires(&t->timer, mode);//將新的hrtimer加入到timer_list

???????if (!hrtimer_active(&t->timer)) //如果沒有激活hrtimer則直接退出

???????????t->task = NULL;

???????????

???????if (likely(t->task)) //如果激活了,就開始調度

???????????freezable_schedule();

???

???????hrtimer_cancel(&t->timer); //運行到這里,說明定時器到期,那么取消定時器。

???????mode = HRTIMER_MODE_ABS;

???

??? }while (t->task && !signal_pending(current));

?

???__set_current_state(TASK_RUNNING); //設置進程狀態可執行

?

???return t->task == NULL;

}

???????? 不管內核有沒有配置HIGH_RES_TIMERS,內核都編譯httimer.c接口。如果沒有配置hrtimer則使用低精度的tick方案,這時定時器是相當不準確;如果進行了配置,則使用高精度方案。兩種方案下,定時器中斷處理方法不同:

低精度下的hrtimer:

???????? update_process_times—> run_local_timers —> hrtimer_run_queues

高精度下的hrtimer:

run_hrtimer_softirq—>hrtimer_peek_ahead_timers —> __hrtimer_peek_ahead_timers —> hrtimer_interrupt

?

?

附錄A

參考資料

http://www.wowotech.net/timer_subsystem/time-subsyste-architecture.html

http://www.wowotech.net/timer_subsystem/timer_subsystem_userspace.html

?

?

?

總結

以上是生活随笔為你收集整理的linux内核之时间子系统的全部內容,希望文章能夠幫你解決所遇到的問題。

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

一区二区 不卡 | 美女视频免费一区二区 | 中文字幕视频在线播放 | 久久你懂的| 国产精品久久久久久久免费 | 亚洲视频在线观看网站 | 国产高清日韩欧美 | 欧美aa在线 | 麻豆视频在线播放 | 亚州精品视频 | 欧美激情综合色 | 一区二区三区免费在线播放 | 欧美污网站| 久久玖 | 欧美a级成人淫片免费看 | 波多野结衣小视频 | 一区二区三区观看 | 亚洲乱码精品久久久久 | 欧美a级一区二区 | 免费www视频| 免费精品| 草莓视频在线观看免费观看 | 成人羞羞视频在线观看免费 | 国产成人精品日本亚洲999 | 国产理论一区二区三区 | 亚洲欧美一区二区三区孕妇写真 | 美女免费网视频 | 怡红院av久久久久久久 | 在线免费观看麻豆视频 | 三级黄色网址 | 182午夜在线观看 | 亚洲清纯国产 | 免费在线中文字幕 | 久久久久久久久久免费 | 欧美亚洲精品在线观看 | 中文字幕亚洲欧美 | 99久久99久久精品国产片果冰 | 久久婷婷视频 | av黄色免费网站 | 五月婷婷操 | 最新99热 | 麻豆免费看片 | 日韩av在线免费看 | 精品一区二区三区久久久 | 亚洲 欧洲 国产 精品 | 国产裸体视频bbbbb | 九九九视频精品 | 久久精品123| 狠狠色噜噜狠狠 | 日韩网站在线播放 | 91探花国产综合在线精品 | 国产一级精品绿帽视频 | 99九九99九九九视频精品 | 亚洲国产色一区 | 人人干人人超 | 成人在线免费视频 | 国产黄色精品网站 | 国产精品成人自产拍在线观看 | 亚洲一区视频免费观看 | 国产日韩精品一区二区三区 | 久久人人爽人人爽人人 | 日本性视频| 久久香蕉国产精品麻豆粉嫩av | 色中色亚洲| 国产高清一 | 国产精品一区在线播放 | 久久久久久久久久久影视 | 日韩高清网站 | 在线亚洲高清视频 | 中文字幕 二区 | 国产精品大片 | 日韩中文字幕视频在线观看 | 一级黄毛片 | 91自拍91 | 一级成人网 | 91在线视频精品 | 日韩精品久久久久久久电影竹菊 | 日韩在线观看第一页 | 日韩免费观看一区二区 | 综合视频在线 | 国产成人亚洲在线观看 | 欧美日韩中文字幕综合视频 | 成全在线视频免费观看 | 欧美特一级片 | 免费黄在线观看 | 91片黄在线观 | 免费看黄网站在线 | 日本三级久久久 | www.一区二区三区 | 欧美激情精品久久久 | 免费在线观看一级片 | 色中射 | 在线观看www. | 中国精品少妇 | 亚洲精品乱码久久久久 | 亚洲伦理电影在线 | 中文字幕在线观看免费 | 国产一区二区三区午夜 | 热久久99这里有精品 | 中国一级片在线 | 亚洲黑丝少妇 | 一区二区三区电影在线播 | 天天干天天爽 | 最新日韩视频 | 亚洲天天| 亚洲精品在线视频网站 | 九九免费视频 | 黄色午夜网站 | 精品久久久久久久久久久院品网 | 日韩三级在线观看 | 国产日韩一区在线 | 日韩精品第一区 | 免费看色视频 | 午夜视频在线观看网站 | 久久久久女人精品毛片九一 | 欧美91片| 97碰视频| av在线直接看| www.av中文字幕.com | av在线看片 | 国产一区在线免费观看视频 | 91重口视频| 国产精品视频最多的网站 | 国产成人三级在线 | 91精品一区二区在线观看 | 日韩久久精品一区二区 | 91污视频在线| 500部大龄熟乱视频 欧美日本三级 | 日批视频在线观看免费 | free. 性欧美.com | 国产一区二区视频在线播放 | 国产精成人品免费观看 | 日韩精品播放 | 99成人精品 | 99久久er热在这里只有精品66 | 国产高清久久久久 | 成人在线免费看视频 | 99热这里只有精品免费 | 一级精品视频在线观看宜春院 | 国产字幕在线看 | 国产91粉嫩白浆在线观看 | 中文字幕一区二区三区乱码不卡 | 在线免费观看成人 | 国产无遮挡又黄又爽在线观看 | 人人爽久久涩噜噜噜网站 | 久久99精品久久久久久久久久久久 | 色综合天天综合 | 亚洲午夜精品在线观看 | 人人爽人人爽人人片av免 | 波多野结衣电影一区二区 | 国产精品黄色 | 日韩亚洲欧美中文字幕 | 久久伊人精品一区二区三区 | 怡红院av久久久久久久 | 成人av中文字幕 | 91精品国| 国产成人久久久久 | 欧美专区亚洲专区 | 欧美精品被 | 久久国产热视频 | 91视视频在线直接观看在线看网页在线看 | 久久午夜剧场 | 国产一级片免费观看 | 久久精品一区二区三区国产主播 | 日韩电影一区二区在线 | 亚洲一区久久久 | 91在线免费播放视频 | 91少妇精拍在线播放 | 亚洲成人在线免费 | 黄色小网站在线 | 在线观看中文字幕视频 | 亚洲精品玖玖玖av在线看 | 国产精品久久久久久久久久新婚 | 在线激情电影 | 日韩爱爱网站 | 日韩免费观看一区二区三区 | 国产剧情在线一区 | 91大神精品视频在线观看 | 欧洲一区二区三区精品 | 久久91久久久久麻豆精品 | 国产理论在线 | 欧美成人影音 | 久久高清国产 | 在线观看一级视频 | 国产小视频在线看 | 亚洲午夜精 | 97色在线观看 | 嫩草91影院 | 欧美日韩国产在线 | 97电影手机| 国产成人免费 | 麻豆视频免费观看 | 午夜av片| 天天操天天操天天操天天 | 福利片免费看 | 久久99在线 | 欧美伦理电影一区二区 | 狠狠色噜噜狠狠 | 四虎在线观看精品视频 | 日韩久久激情 | 天天射天天 | 中文字幕 欧美性 | 中文字幕日韩av | 人人爽人人香蕉 | 国产在线视频资源 | 91av在线播放| 国产精品区一区 | 天天拍天天操 | 五月天视频网站 | 免费观看全黄做爰大片国产 | 91视频最新网址 | 精品亚洲成a人在线观看 | 蜜臀av免费一区二区三区 | 婷婷丁香七月 | 日韩免费一二三区 | av黄色在线播放 | 五月婷婷另类国产 | 久在线观看视频 | 国产精品九九久久久久久久 | 我要看黄色一级片 | 午夜久久久久久久久久影院 | 日韩欧美xxxx| 久久免费国产 | 九九视频免费在线观看 | 国产精品一区在线观看 | 99精品国产99久久久久久97 | 福利视频一区二区 | 激情综合久久 | 园产精品久久久久久久7电影 | 国产a免费 | 97成人免费| 日韩av一区在线观看 | 九色91福利 | 亚洲传媒在线 | 97在线观看免费观看 | 婷婷久久五月天 | 日日干美女 | 久久精品国产免费看久久精品 | 精品国产免费一区二区三区五区 | 亚洲精品视频在线观看网站 | 91重口视频| 中文av字幕在线观看 | 成人资源站 | av电影在线观看 | 国产成人一区二区三区影院在线 | 又黄又爽又湿又无遮挡的在线视频 | a级国产乱理论片在线观看 特级毛片在线观看 | 久久精品看 | 天天操天天色天天射 | av线上免费看 | 中文字幕色在线视频 | 永久免费毛片 | 欧美日韩在线视频一区二区 | 中文国产字幕在线观看 | 久草在线免费新视频 | 久久国产视频网站 | 一区二区三区日韩在线 | www.狠狠干| 欧美亚洲国产精品久久高清浪潮 | 天天操天天操天天操天天 | 久草在线视频看看 | 天天爽夜夜操 | 99精品视频中文字幕 | 在线免费视 | 国产 中文 日韩 欧美 | 337p西西人体大胆瓣开下部 | 精品免费久久久久 | 久久国产手机看片 | 中文字幕日本在线 | av电影一区二区三区 | 亚洲影院一区 | 99在线免费观看视频 | 操操操综合 | 欧美a视频在线观看 | 亚洲精品无 | 国产午夜一级毛片 | 日韩欧美高清在线观看 | 97视频免费在线看 | 高潮久久久久久 | 欧美专区国产专区 | 99久久99视频只有精品 | 国产精品久久99综合免费观看尤物 | 欧美一级淫片videoshd | 天天操夜夜爱 | 91超级碰碰| 最新av免费在线 | 又黄又爽又无遮挡的视频 | 久草久热| 中文字幕精 | 综合国产视频 | 国产成人免费网站 | 久久久网 | 亚洲精品自拍视频在线观看 | 久草在线视频免赞 | 激情欧美丁香 | 国产成人一区二区三区在线观看 | 午夜私人影院久久久久 | 国产色女人 | 久久情网| 婷婷激情站| 天天草视频 | 免费在线观看成人av | 色夜影院 | 亚洲第一伊人 | 久久精品国产成人 | 国产成人精品亚洲精品 | 久久综合婷婷国产二区高清 | 国产精品久久久久久久99 | 激情综合五月 | 国产成人精品一区二三区 | 人九九精品 | 97超碰在线资源 | 久久久久久久久精 | 正在播放国产精品 | 黄色视屏在线免费观看 | 成人免费在线观看电影 | 久久99久久99精品免费看小说 | 天天操偷偷干 | 国产精品九九久久久久久久 | 中文字幕日韩av | 亚洲自拍偷拍色图 | 久久久国产精品久久久 | 国产在线观看一 | 一级黄色片在线观看 | 国产乱老熟视频网88av | 一区二区伦理 | 欧美黑人xxxx猛性大交 | 亚洲欧洲精品一区二区 | 91人人在线 | 99爱在线观看 | 青青草国产精品 | 99久久精品国产一区二区三区 | 国产男女无遮挡猛进猛出在线观看 | 丁香婷婷激情五月 | 国产真实精品久久二三区 | 狠狠色丁香婷婷综合久小说久 | 婷婷六月色 | 久久久久久高潮国产精品视 | 久久久久久久综合色一本 | 日韩精品视频在线观看免费 | 97视频免费观看2区 亚洲视屏 | 精品久久久久久久久久久久久 | 五月综合网站 | 国内久久精品视频 | 日韩极品视频在线观看 | 91精品天码美女少妇 | 97视频一区| 91天堂素人约啪 | 亚洲一级黄色av | 国产精品18久久久久久首页狼 | 国产无套精品久久久久久 | 欧美一级免费 | 六月婷色 | 色综合激情久久 | 婷婷六月丁 | 伊人夜夜| 99视频在线精品国自产拍免费观看 | 久草免费在线观看视频 | 欧美色噜噜 | 国产第一页在线播放 | 在线看污网站 | 精品麻豆入口免费 | 国产精品乱码久久 | 国产黄色片在线 | 成人av资源在线 | 婷婷综合亚洲 | 欧美一进一出抽搐大尺度视频 | 在线不卡中文字幕播放 | 美女视频久久久 | 91视频免费看片 | 在线中文字幕视频 | 久久99国产精品久久99 | 欧美91成人网 | 久久草在线精品 | 在线看国产精品 | 日韩高清免费无专码区 | 欧美日韩高清免费 | 国产一区二区不卡在线 | 久草在线久草在线2 | 人人干网站| 2022中文字幕在线观看 | 国产精品1000 | 国产麻豆精品一区 | 国产中文欧美日韩在线 | 国产在线国偷精品产拍 | 青青草国产精品视频 | 97免费视频在线 | 国产伦精品一区二区三区四区视频 | 麻豆久久一区二区 | 99精品国产免费久久 | 西西4444www大胆视频 | 国产无遮挡又黄又爽在线观看 | 视频99爱 | 国产精品久久久久久久久久久免费看 | 久久99精品久久久久蜜臀 | 成人av电影免费观看 | 成年人黄色免费网站 | 人人澡人人爱 | 国产分类视频 | 日韩一区二区三区观看 | 国产麻豆电影 | 韩国三级av在线 | 亚洲专区 国产精品 | 日韩av影视在线 | 国产高清中文字幕 | 成人免费视频网站 | 欧美日韩国产亚洲乱码字幕 | 久久精品国产美女 | 久章草在线| 天天综合天天做 | 青草视频免费观看 | 欧美日韩国产精品一区 | 久久综合九色综合网站 | 久久国产精品一区二区三区四区 | 国产精品岛国久久久久久久久红粉 | 91少妇精拍在线播放 | 999电影免费在线观看 | 一区二区三区电影 | 天天色天天射天天综合网 | 亚洲免费不卡 | 亚洲播播| 91亚洲综合 | 在线av资源 | 日韩国产精品久久久久久亚洲 | 在线观看视频一区二区三区 | 91精品国产一区二区三区 | 在线午夜电影神马影院 | 色就是色综合 | 国产剧情一区在线 | 在线观看国产一区 | 免费在线成人av电影 | 888av| www.超碰97.com | 亚洲国产免费网站 | 新版资源中文在线观看 | 久草在线费播放视频 | 日韩高清一区在线 | 色婷婷久久久综合中文字幕 | avove黑丝 | 精品国产色 | 久久综合狠狠综合久久综合88 | 久久99精品久久久久久清纯直播 | 日韩免费成人 | 九九热免费在线观看 | 免费男女羞羞的视频网站中文字幕 | 2023亚洲精品国偷拍自产在线 | 久久午夜视频 | 精品不卡视频 | 一区三区视频在线观看 | 精品91在线 | 欧美久久久久久久久 | 国产一级大片免费看 | 久草在线视频网站 | 日本精品久久久一区二区三区 | 超碰在线网 | 久久视频网址 | 天天搞天天干 | 国产一级大片免费看 | 国产精品高清av | 99热在线这里只有精品 | 久久久久久久久毛片 | 99精品国产免费久久久久久下载 | 五月婷婷激情五月 | 久久久18 | 成人中心免费视频 | 不卡视频在线看 | 国产精品黑丝在线观看 | 99国产精品久久久久老师 | 成人在线观看你懂的 | 色.com| av黄色免费在线观看 | 亚洲成免费 | 午夜婷婷网 | 国产精品久久久久久超碰 | 水蜜桃亚洲一二三四在线 | 黄色网中文字幕 | 国产精品女同一区二区三区久久夜 | 少妇搡bbb| 国产高清成人 | 东方av免费在线观看 | 黄色av网站在线免费观看 | 中文理论片| 丁香花在线视频观看免费 | 一区二区三区在线免费播放 | 欧美一区二区三区不卡 | 五月天婷婷丁香花 | 西西人体4444www高清视频 | aav在线| 九九亚洲精品 | 人人澡人人爱 | 人人爽人人爽人人爽人人爽 | 国产精品字幕 | 在线观看网站你懂的 | 久久五月婷婷丁香 | 精品国产一二区 | av免费在线网 | 国产精品成人aaaaa网站 | 免费看特级毛片 | 高清日韩一区二区 | 天天射天天 | 九九视频这里只有精品 | 欧美最新大片在线看 | 97天天综合网 | 久久精品www人人爽人人 | 国产一级二级视频 | 亚洲国产一二三 | 成人av免费播放 | 高清在线观看av | 亚州欧美视频 | 97超碰超碰| 国产一区二区在线视频观看 | 五月天激情视频 | 免费看黄在线 | 日韩av中文在线观看 | 黄色大片中国 | 久久久久久久久久久久影院 | 婷婷www| 久久久久久久综合色一本 | 久久女同性恋中文字幕 | 久久影院一区 | 日韩免费在线观看视频 | 久久av在线播放 | 日韩av影视在线观看 | 最新中文字幕视频 | 在线观看国产高清视频 | 亚洲黄色在线播放 | 麻豆影视在线播放 | 亚洲精品视频一二三 | 日本三级香港三级人妇99 | 99视频久久 | 成年人电影免费看 | 欧美一区三区四区 | 亚洲精品网页 | 五月天婷婷免费视频 | 天天鲁一鲁摸一摸爽一爽 | 国产色a在线观看 | 日韩理论 | 国产精品永久免费 | 天天干,天天射,天天操,天天摸 | 日韩视频1区 | 国产成人高清 | 九九免费在线观看视频 | 中文字幕av最新 | 午夜精品视频福利 | 国产精品日韩久久久久 | 日韩欧美在线不卡 | 亚洲a资源 | 欧美成人亚洲 | av中文在线 | 国产在线精品播放 | 中文字幕一区二区三区在线观看 | 国产91丝袜在线播放动漫 | 成人久久18免费网站图片 | 97免费公开视频 | 国产精品久久久久久久免费观看 | 久久久久99精品国产片 | 日韩中文在线观看 | 狠狠狠色丁香婷婷综合久久五月 | www.日韩免费 | 美女av在线免费 | www国产亚洲精品久久网站 | 国内少妇自拍视频一区 | 97精品久久 | 日韩美在线 | 黄色资源在线 | 狠狠色丁香婷婷 | 国内揄拍国内精品 | 综合天堂av久久久久久久 | 精品网站999www | 日韩中文字幕视频在线观看 | 亚洲国产激情 | 免费视频成人 | 亚洲综合成人婷婷小说 | 国产精品综合在线观看 | 天天操天天操天天操天天操天天操天天操 | 精品久久一区二区三区 | 91在线免费播放视频 | 亚洲美女精品视频 | 国产 日韩 中文字幕 | 国产精品一区二区三区视频免费 | www.久久色 | 国产精品久久久久久吹潮天美传媒 | 九九免费精品 | 久久久精品成人 | 色综合天天狠狠 | 可以免费看av | 久久精品中文字幕免费mv | 中文字幕在线国产 | 久久免费精品国产 | 99色人| 色综合五月天 | 天天躁日日 | 天天操综合网 | 久久精彩免费视频 | 欧美日韩视频一区二区 | 日韩精品免费一区二区 | 国产精品 中文字幕 亚洲 欧美 | 岛国片在线 | 国产精品视频一二三 | 午夜 免费| 黄色大全在线观看 | 亚洲高清免费在线 | 黄色成人在线 | 亚洲一区二区精品视频 | 美女黄频在线观看 | 久久伊人91 | 成人一级影视 | 香蕉国产91 | 手机av在线网站 | 久久综合操 | 日韩一级黄色片 | 国产在线免费 | 国产中文字幕一区 | 日韩免费观看视频 | 国产在线精品福利 | 最近日本中文字幕a | 久久综合九色综合97_ 久久久 | 国产一二区视频 | 国产伦精品一区二区三区在线 | 成人a视频片观看免费 | 韩日电影在线观看 | 黄色三级在线看 | 亚洲成免费 | 一级黄色大片在线观看 | avsex| 国产精品久久久99 | 成人黄色大片在线观看 | av888.com| 午夜精品一区二区三区视频免费看 | 欧美精品黑人性xxxx | 一二区精品 | 一区二区亚洲精品 | 久久成人国产 | 91激情小视频 | 亚洲免费精品一区二区 | 激情婷婷综合网 | 亚洲免费小视频 | 免费视频久久久 | 久久黄色网址 | 最新成人av| 麻豆影视网站 | 99精品免费视频 | 国产高清不卡av | 99久久这里只有精品 | 中文字幕在线影视资源 | 成人免费在线视频观看 | 久草视频在线免费播放 | 日日操天天爽 | 亚洲黄色片在线 | 国产精品久久在线 | 成人黄视频 | 91精品在线视频观看 | 一区二精品 | 在线观看你懂的网站 | 91免费视频网站在线观看 | 日韩在线视频国产 | 午夜婷婷在线播放 | 久久精品中文字幕免费mv | 久久刺激视频 | 久久久久久国产精品免费 | 在线国产高清 | 在线观看91精品国产网站 | 五月婷婷一区 | 久久综合国产伦精品免费 | 国产剧情在线一区 | 久草视频网 | 国产精品久久久久久久久久三级 | 国产传媒一区在线 | 久久午夜鲁丝片 | 在线免费黄色 | 91精品一区在线观看 | 91最新视频 | 色婷婷骚婷婷 | 日本精品久久久一区二区三区 | 天天操夜夜操夜夜操 | 91福利免费 | 日韩欧美高清视频在线观看 | 日本久久高清视频 | 五月天激情综合 | 九九热在线观看视频 | 欧美专区国产专区 | 天天激情综合 | 黄色影院在线免费观看 | 深夜视频久久 | 天天做天天干 | 久草网在线视频 | 久久免费国产精品 | 又黄又爽又湿又无遮挡的在线视频 | 国产精品激情在线观看 | 亚洲男男gaygay无套 | 久青草国产在线 | 日韩美一区二区三区 | 日韩欧美视频一区二区三区 | 国产精品成人在线观看 | 天天视频亚洲 | 亚洲精品视频在线观看视频 | 一区二区视频播放 | 手机看片| 国产亚洲在线视频 | www.香蕉视频在线观看 | 久久99在线观看 | 深夜男人影院 | 伊人宗合网 | 日日干影院| 中文字幕在线资源 | 97精品国产91久久久久久久 | 中文字幕一区二区在线播放 | 波多野结衣亚洲一区二区 | 亚洲精品在线观看视频 | 99久久999久久久精玫瑰 | 九九久久视频 | 99se视频在线观看 | 婷婷日 | 中文av影院| 免费的黄色av | 色婷婷五 | 91精品在线免费观看视频 | 国内精品久久久久影院日本资源 | 韩国av免费| 日韩成人看片 | 一区二区三区精品在线视频 | 免费亚洲一区二区 | 久久线视频 | 成人av电影免费在线观看 | 亚洲一区二区精品 | 成人免费视频网址 | 精品视频在线免费 | 国产小视频在线观看免费 | 99精品国产在热久久下载 | 欧美成人999| 99久久久久国产精品免费 | 国产在线永久 | 成人理论在线观看 | 日韩电影中文,亚洲精品乱码 | 成人资源网 | 亚洲无人区小视频 | 欧美日韩在线精品一区二区 | 欧美人交a欧美精品 | 欧美激情视频一区二区三区 | 免费一级毛毛片 | 日韩在线资源 | 亚洲男男gaygay无套同网址 | 欧美福利精品 | 中文字幕在线观看的网站 | 久久在线观看视频 | 网站在线观看日韩 | 97高清视频 | 国产精品mv | 国产一区二区精 | 精品女同一区二区三区在线观看 | 亚洲人毛片 | 伊人天堂久久 | 国产午夜av | 色播五月激情五月 | 精品国产三级 | 久久1区 | 亚洲免费高清视频 | 亚洲成a人片综合在线 | a视频在线观看 | 99热最新 | 成人免费毛片aaaaaa片 | 亚州精品在线视频 | 99精品视频网 | 亚洲五月花 | 黄色小网站在线观看 | 久久草精品 | www.天天射.com | 久久蜜臀一区二区三区av | 最新亚洲视频 | 久久综合色天天久久综合图片 | 美女网站视频免费都是黄 | 在线黄色国产电影 | 日韩av男人的天堂 | 精品日韩中文字幕 | 成人a免费视频 | 久久综合精品一区 | 亚洲精选视频在线 | 国产精品久久久久三级 | 国产精品一区在线 | 天天躁日日躁狠狠 | 国产精品久久久久久久午夜片 | 国产精品小视频网站 | 亚洲电影成人 | 久久网页 | 六月丁香婷婷网 | 九九九九九九精品任你躁 | 在线看黄网站 | 91在线永久 | 91视频传媒 | 久久久国产精品一区二区三区 | 日韩视 | 亚洲国产高清视频 | 激情欧美在线观看 | 婷婷色狠狠| 国产精品视频大全 | 蜜臀av免费一区二区三区 | 国产精品久久毛片 | 高清不卡免费视频 | 久久一久久 | 成人精品一区二区三区电影免费 | 久久综合色影院 | 天天天干天天射天天天操 | 亚洲激情电影在线 | 成人国产精品 | 久免费 | 日韩免费在线看 | 免费在线观看污 | 麻豆视频国产在线观看 | 婷婷激情综合五月天 | 国产成人一区二区三区免费看 | 久久精品视频18 | 中文字幕在线观看网址 | 日日夜夜免费精品视频 | 欧美人人爱 | 97超在线视频 | 国产精品免费在线视频 | 国产精品露脸在线 | www亚洲一区 | 国产中文字幕网 | 973理论片235影院9 | 亚洲精品午夜aaa久久久 | 久久艹欧美| 五月婷婷六月丁香激情 | 亚洲 欧美 日韩 综合 | 色之综合网 | 国产色a在线观看 | 久久国产视频网站 | 91人人射 | 国产污视频在线观看 | 天堂va在线高清一区 | 亚洲色图 校园春色 | 精品在线亚洲视频 | 免费瑟瑟网站 | 欧美人人爱 | 久久久久免费精品国产小说色大师 | 久久永久视频 | 99精品视频免费 | 超碰97人人在线 | 在线成人短视频 | 伊人五月天综合 | 91九色蝌蚪在线 | 日韩欧美高清免费 | 狠狠色丁香婷婷综合久小说久 | 九七人人干 | 色偷偷男人的天堂av | 色视频在线 | 亚洲日韩中文字幕 | 欧美小视频在线观看 | 亚洲黄色在线播放 | 91精品国产乱码久久桃 | 日本中文字幕在线一区 | 911av视频| 国产黄色大片免费看 | 天天干天天搞天天射 | 成人国产精品免费观看 | 911精品美国片911久久久 | 久久婷婷国产 | 亚洲天堂激情 | av网站地址 | 国内一级片在线观看 | 夜夜夜夜爽| 一级黄色片网站 | 午夜在线国产 | 久久久在线视频 | 久久精品电影网 | 中文字幕一区二区三区在线观看 | 天天操人人要 | 五月天激情在线 | 国产亚洲人成网站在线观看 | 69视频永久免费观看 | 狠狠色丁香婷综合久久 | 日本女人b| 1000部18岁以下禁看视频 | 美女视频永久黄网站免费观看国产 | 天天爱天天爽 | 国产精品福利在线播放 | 性色av免费看 | 免费a级毛片在线看 | 亚洲天天综合网 | 伊人影院av| 久久精品日产第一区二区三区乱码 | 国产精久久久久久妇女av | 亚洲精品 在线视频 | 九九久久国产 | 日韩资源在线播放 | 狠狠干五月天 | 黄色一级影院 | 欧美日韩国产一二三区 | 最新av网址在线 | 91大神电影 | 国产婷婷精品av在线 | 91在线免费公开视频 | 激情av网| 国产精品 9999 | 国产色道 | 中文在线字幕观看电影 | 人人玩人人添人人澡97 | 日本一区二区不卡高清 | 色播五月激情五月 | 欧美日韩精品在线播放 | 色综合天天综合在线视频 | 日本中文字幕一二区观 | av天天干| 欧美a在线看 | 99视频网址| 日韩欧美视频在线播放 | 国产高清无av久久 | 中文字幕在线观看网站 | 免费三级av | 国产中文字幕久久 | 日日夜色| 亚洲精品美女久久 | 超碰在线97国产 | 国产午夜影院 | 国产色中涩| 一区二区观看 | 久久国产精品久久w女人spa | 四虎成人精品在永久免费 | 在线观看一区二区精品 | 在线观看国产日韩 | 丁香狠狠 | 天天狠狠干 | 亚洲视频,欧洲视频 | 亚洲va韩国va欧美va精四季 | 中文字幕人成乱码在线观看 | 激情五月色播五月 | 91视频com | 黄污网站在线 | 国产 日韩 在线 亚洲 字幕 中文 | 91福利视频免费观看 | 国产精品久久久免费看 | 日韩在线 一区二区 | 国产韩国精品一区二区三区 | japanesexxx乱女另类 | 最近中文字幕国语免费高清6 | 国产精品美女免费看 | 午夜久久久久 | 国产色久| 日韩免费高清在线 | 国产99久久久欧美黑人 | 丁香九月激情 | av黄色在线 | 国产精品青青 | 麻豆传媒在线免费看 | 日本精品小视频 | 久久亚洲综合国产精品99麻豆的功能介绍 | 亚洲精品黄色片 | 国产精彩在线视频 | 国产精品嫩草69影院 | 91精选| 国产欧美最新羞羞视频在线观看 | 国产精品 亚洲精品 | 国产在线视频一区二区 | 美女网站免费福利视频 | 国产91精品看黄网站在线观看动漫 | 久草视频视频在线播放 | 美女久久99 | 黄色亚洲大片免费在线观看 | 天天色天天操天天爽 | av大全在线 | 天天色天天骑天天射 | 中文字幕在 | 天天久久夜夜 | 一本一本久久a久久精品综合妖精 | 天堂av高清| 91av免费观看 | 欧美 国产 视频 | 91亚洲精品在线 | 成人性生交大片免费观看网站 | 亚洲精品免费在线观看视频 | 国产精品久久久久久久久婷婷 | 国模吧一区| 天天色影院 | 久久精品国产一区二区三区 | 精品国产一区二区三区四区在线观看 | 中文字幕免费高清av | 亚洲国产中文字幕在线观看 | 美女福利视频一区二区 | 国产精品久久久久免费观看 | 亚洲综合在线五月 | 亚洲国产中文字幕在线观看 | 中文字幕欧美激情 | 91禁看片 | 日韩午夜一级片 | 免费高清无人区完整版 | 日韩在线电影一区二区 | 91手机电影| 日本精品中文字幕在线观看 | 亚州成人av在线 | 日韩欧美成 | 中文字幕第一页在线播放 | 在线观看完整版免费 | 中日韩免费视频 | 片网站| 国产精品第二页 | 久久av伊人 | 国产99区| 国产精品久久久99 |