《電子技術應用》
您所在的位置:首頁 > 嵌入式技術 > 設計應用 > 透過Linux內核看無鎖編程
透過Linux內核看無鎖編程
摘要: 多核多線程已經成為當下一個時髦的話題,而無鎖編程更是這個時髦話題中的熱點話題。Linux內核可能是當今最大最復雜的并行程序之一,為我們分析多核多線程提供了絕佳的范例。內核設計者已經將最新的無鎖編程技術帶進了2。6系統內核中,本文以2。6。10版本為藍本,帶領您領略多核多線程編程的真諦,窺探無鎖編程的奧秘,體味大師們的高雅設計!
Abstract:
Key words :

多核多線程已經成為當下一個時髦的話題,而無鎖編程更是這個時髦話題中的熱點話題。Linux內核可能是當今最大最復雜的并行程序之一,為我們分析多核多線程提供了絕佳的范例。內核設計者已經將最新的無鎖編程技術帶進了2。6系統內核中,本文以2。6。10版本為藍本,帶領您領略多核多線程編程的真諦,窺探無鎖編程的奧秘,體味大師們的高雅設計!

非阻塞型同步(Non-blockingSynchronization)簡介

如何正確有效的保護共享數據是編寫并行程序必須面臨的一個難題,通常的手段就是同步。同步可分為阻塞型同步(BlockingSynchronization)和非阻塞型同步(Non-blockingSynchronization)。

阻塞型同步是指當一個線程到達臨界區時,因另外一個線程已經持有訪問該共享數據的鎖,從而不能獲取鎖資源而阻塞,直到另外一個線程釋放鎖。常見的同步原語有mutex、semaphore等。如果同步方案采用不當,就會造成死鎖(deadlock),活鎖(livelock)和優先級反轉(priorityinversion),以及效率低下等現象。

為了降低風險程度和提高程序運行效率,業界提出了不采用鎖的同步方案,依照這種設計思路設計的算法稱為非阻塞型算法,其本質特征就是停止一個線程的執行不會阻礙系統中其他執行實體的運行。

當今比較流行的Non-blockingSynchronization實現方案有三種:

Wait-free

Wait-free是指任意線程的任何操作都可以在有限步之內結束,而不用關心其它線程的執行速度。Wait-free是基于per-thread的,可以認為是starvation-free的。非常遺憾的是實際情況并非如此,采用Wait-free的程序并不能保證starvation-free,同時內存消耗也隨線程數量而線性增長。目前只有極少數的非阻塞算法實現了這一點。

Lock-free

Lock-Free是指能夠確保執行它的所有線程中至少有一個能夠繼續往下執行。由于每個線程不是starvation-free的,即有些線程可能會被任意地延遲,然而在每一步都至少有一個線程能夠往下執行,因此系統作為一個整體是在持續執行的,可以認為是system-wide的。所有Wait-free的算法都是Lock-Free的。

Obstruction-free

Obstruction-free是指在任何時間點,一個孤立運行線程的每一個操作可以在有限步之內結束。只要沒有競爭,線程就可以持續運行。一旦共享數據被修改,Obstruction-free要求中止已經完成的部分操作,并進行回滾。所有Lock-Free的算法都是Obstruction-free的。

綜上所述,不難得出Obstruction-free是Non-blockingsynchronization中性能最差的,而Wait-free性能是最好的,但實現難度也是最大的,因此Lock-free算法開始被重視,并廣泛運用于當今正在運行的程序中,比如linux內核。

一般采用原子級的read-modify-write原語來實現Lock-Free算法,其中LL和SC是Lock-Free理論研究領域的理想原語,但實現這些原語需要CPU指令的支持,非常遺憾的是目前沒有任何CPU直接實現了SC原語。根據此理論,業界在原子操作的基礎上提出了著名的CAS(Compare-And-Swap)操作來實現Lock-Free算法,Intel實現了一條類似該操作的指令:cmpxchg8。

CAS原語負責將某處內存地址的值(1個字節)與一個期望值進行比較,如果相等,則將該內存地址處的值替換為新值,CAS操作偽碼描述如下:

清單1。CAS偽碼

BoolCAS(T*addr,Texpected,TnewValue)

{

if(*addr==expected)

{

*addr=newValue;

returntrue;

}

else

returnfalse;

}

在實際開發過程中,利用CAS進行同步,代碼如下所示:

清單2。CAS實際操作

do{

備份舊數據;

基于舊數據構造新數據;

}while(!CAS(內存地址,備份的舊數據,新數據))

就是指當兩者進行比較時,如果相等,則證明共享數據沒有被修改,替換成新值,然后繼續往下運行;如果不相等,說明共享數據已經被修改,放棄已經所做的操作,然后重新執行剛才的操作。容易看出CAS操作是基于共享數據不會被修改的假設,采用了類似于數據庫的commit-retry的模式。當同步沖突出現的機會很少時,這種假設能帶來較大的性能提升。

加鎖的層級

根據復雜程度、加鎖粒度及運行速度,可以得出如下圖所示的鎖層級:

圖 1. 加鎖層級

圖1。加鎖層級

其中標注為紅色字體的方案為Blockingsynchronization,黑色字體為Non-blockingsynchronization。Lock-based和Lockless-based兩者之間的區別僅僅是加鎖粒度的不同。圖中最底層的方案就是大家經常使用的mutex和semaphore等方案,代碼復雜度低,但運行效率也最低。

Linux內核中的無鎖分析

Linux內核可能是當今最大最復雜的并行程序之一,它的并行主要來至于中斷、內核搶占及SMP等。內核設計者們為了不斷提高Linux內核的效率,從全局著眼,逐步廢棄了大內核鎖來降低鎖的粒度;從細處下手,不斷對局部代碼進行優化,用無鎖編程替代基于鎖的方案,如seqlock及RCU等;不斷減少鎖沖突程度、降低等待時間,如Double-checkedlocking和原子鎖等。

無論什么時候當臨界區中的代碼僅僅需要加鎖一次,同時當其獲取鎖的時候必須是線程安全的,此時就可以利用Double-checkedLocking模式來減少鎖競爭和加鎖載荷。目前Double-checkedLocking已經廣泛應用于單例(Singleton)模式中。內核設計者基于此思想,巧妙的將Double-checkedLocking方法運用于內核代碼中。

當一個進程已經僵死,即進程處于TASK_ZOMBIE狀態,如果父進程調用waitpid()系統調用時,父進程需要為子進程做一些清理性的工作,代碼如下所示:

清單3。少鎖操作

984staticintwait_task_zombie(task_t*p,intnoreap,

985structsiginfo__user*infop,

986int__user*stat_addr,structrusage__user*ru)

987{

……

1103if(p->real_parent!=p->parent){

1104write_lock_irq(&tasklist_lock);

1105/*Double-checkwithlockheld。*/

1106if(p->real_parent!=p->parent){

1107__ptrace_unlink(p);

1108//TODO:isthissafe?

1109p->exit_state=EXIT_ZOMBIE;

……

1120}

1121write_unlock_irq(&tasklist_lock);

1122}

……

1127}

如果將write_lock_irq放置于1103行之前,鎖的范圍過大,鎖的負載也會加重,影響效率;如果將加鎖的代碼放到判斷里面,且沒有1106行的代碼,程序會正確嗎?在單核情況下是正確的,但在雙核情況下問題就出現了。一個非主進程在一個CPU上運行,正準備調用exit退出,此時主進程在另外一個CPU上運行,在子進程調用release_task函數之前調用上述代碼。子進程在exit_notify函數中,先持有讀寫鎖tasklist_lock,調用forget_original_parent。主進程運行到1104處,由于此時子進程先持有該鎖,所以父進程只好等待。在forget_original_parent函數中,如果該子進程還有子進程,則會調用reparent_thread(),將執行p->parent=p->real_parent;語句,導致兩者相等,等非主進程釋放讀寫鎖tasklist_lock時,另外一個CPU上的主進程被喚醒,一旦開始執行,繼續運行將會導致bug。

嚴格的說,Double-checkedlocking不屬于無鎖編程的范疇,但由原來的每次加鎖訪問到大多數情況下無須加鎖,就是一個巨大的進步。同時從這里也可以看出一點端倪,內核開發者為了降低鎖沖突率,減少等待時間,提高運行效率,一直在持續不斷的進行改進。

原子操作可以保證指令以原子的方式執行——執行過程不被打斷。內核提供了兩組原子操作接口:一組針對于整數進行操作,另外一組針對于單獨的位進行操作。內核中的原子操作通常是內聯函數,一般是通過內嵌匯編指令來完成。對于一些簡單的需求,例如全局統計、引用計數等等,可以歸結為是對整數的原子計算。

1。Lock-free應用場景一——SpinLock

SpinLock是一種輕量級的同步方法,一種非阻塞鎖。當lock操作被阻塞時,并不是把自己掛到一個等待隊列,而是死循環CPU空轉等待其他線程釋放鎖。Spinlock鎖實現代碼如下:

清單4。spinlock實現代碼

staticinlinevoid__preempt_spin_lock(spinlock_t*lock)

{

……

do{

preempt_enable();

while(spin_is_locked(lock))

cpu_relax();

preempt_disable();

}while(!_raw_spin_trylock(lock));

}

staticinlineint_raw_spin_trylock(spinlock_t*lock)

{

charoldval;

__asm____volatile__(

"xchgb%b0,%1"

:"=q"(oldval),"=m"(lock->lock)

:"0"(0):"memory");

returnoldval>0;

}

匯編語言指令xchgb原子性的交換8位oldval(存0)和lock->lock的值,如果oldval為1(lock初始值為1),則獲取鎖成功,反之,則繼續循環,接著relax休息一會兒,然后繼續周而復始,直到成功。

對于應用程序來說,希望任何時候都能獲取到鎖,也就是期望lock->lock為1,那么用CAS原語來描述_raw_spin_trylock(lock)就是CAS(lock->lock,1,0);

如果同步操作總是能在數條指令內完成,那么使用SpinLock會比傳統的mutexlock快一個數量級。SpinLock多用于多核系統中,適合于鎖持有時間小于將一個線程阻塞和喚醒所需時間的場合。

pthread庫已經提供了對spinlock的支持,所以用戶態程序也能很方便的使用spinlock了,需要包含pthread。h。在某些場景下,pthread_spin_lock效率是pthread_mutex_lock效率的一倍多。美中不足的是,內核實現了讀寫spinlock鎖,但pthread未能實現。

2。Lock-free應用場景二——Seqlock

手表最主要最常用的功能是讀時間,而不是校正時間,一旦后者成了最常用的功能,消費者肯定不會買賬。計算機的時鐘也是這個功能,修改時間是小概率事件,而讀時間是經常發生的行為。以下代碼摘自2。4。34內核:

清單5。2。4。34seqlock實現代碼

443voiddo_gettimeofday(structtimeval*tv)

444{

……

448read_lock_irqsave(&xtime_lock,flags);

……

455sec=xtime。tv_sec;

456usec+=xtime。tv_usec;

457read_unlock_irqrestore(&xtime_lock,flags);

……

466}

468voiddo_settimeofday(structtimeval*tv)

469{

470write_lock_irq(&xtime_lock);

……

490write_unlock_irq(&xtime_lock);

491}

不難發現獲取時間和修改時間采用的是spinlock讀寫鎖,讀鎖和寫鎖具有相同的優先級,只要讀持有鎖,寫鎖就必須等待,反之亦然。

Linux2。6內核中引入一種新型鎖——順序鎖(seqlock),它與spinlock讀寫鎖非常相似,只是它為寫者賦予了較高的優先級。也就是說,即使讀者正在讀的時候也允許寫者繼續運行。當存在多個讀者和少數寫者共享一把鎖時,seqlock便有了用武之地,因為seqlock對寫者更有利,只要沒有其他寫者,寫鎖總能獲取成功。根據lock-free和時鐘功能的思想,內核開發者在2。6內核中,將上述讀寫鎖修改成了順序鎖seqlock,代碼如下:

清單6。2。6。10seqlock實現代碼

staticinlineunsignedread_seqbegin(constseqlock_t*sl)

{

unsignedret=sl->sequence;

smp_rmb();

returnret;

}

staticinlineintread_seqretry(constseqlock_t*sl,unsignediv)

{

smp_rmb();

return(iv&1)|(sl->sequence^iv);

}

staticinlinevoidwrite_seqlock(seqlock_t*sl)

{

spin_lock(&sl->lock);

++sl->sequence;

smp_wmb();

}

voiddo_gettimeofday(structtimeval*tv)

{

unsignedlongseq;

unsignedlongusec,sec;

unsignedlongmax_ntp_tick;

……

do{

unsignedlonglost;

seq=read_seqbegin(&xtime_lock);

……

sec=xtime。tv_sec;

usec+=(xtime。tv_nsec/1000);

}while(read_seqretry(&xtime_lock,seq));

……

tv->tv_sec=sec;

tv->tv_usec=usec;

}

intdo_settimeofday(structtimespec*tv)

{

……

write_seqlock_irq(&xtime_lock);

……

write_sequnlock_irq(&xtime_lock);

clock_was_set();

return0;

}

Seqlock實現原理是依賴一個序列計數器,當寫者寫入數據時,會得到一把鎖,并且將序列值加1。當讀者讀取數據之前和之后,該序列號都會被讀取,如果讀取的序列號值都相同,則表明寫沒有發生。反之,表明發生過寫事件,則放棄已進行的操作,重新循環一次,直至成功。不難看出,do_gettimeofday函數里面的while循環和接下來的兩行賦值操作就是CAS操作。

采用順序鎖seqlock好處就是寫者永遠不會等待,缺點就是有些時候讀者不得不反復多次讀相同的數據直到它獲得有效的副本。當要保護的臨界區很小,很簡單,頻繁讀取而寫入很少發生(WRRM---WriteRarelyReadMostly)且必須快速時,就可以使用seqlock。但seqlock不能保護包含有指針的數據結構,因為當寫者修改數據結構時,讀者可能會訪問一個無效的指針。

3。Lock-free應用場景三——RCU

在2。6內核中,開發者還引入了一種新的無鎖機制-RCU(Read-Copy-Update),允許多個讀者和寫者并發執行。RCU技術的核心是寫操作分為寫和更新兩步,允許讀操作在任何時候無阻礙的運行,換句話說,就是通過延遲寫來提高同步性能。RCU主要應用于WRRM場景,但它對可保護的數據結構做了一些限定:RCU只保護被動態分配并通過指針引用的數據結構,同時讀寫控制路徑不能有睡眠。以下數組動態增長代碼摘自2。4。34內核:

清單7。2。4。34RCU實現代碼

其中ipc_lock是讀者,grow_ary是寫者,不論是讀或者寫,都需要加spinlock對被保護的數據結構進行訪問。改變數組大小是小概率事件,而讀取是大概率事件,同時被保護的數據結構是指針,滿足RCU運用場景。以下代碼摘自2。6。10內核:

清單8。2。6。10RCU實現代碼

#definercu_read_lock()preempt_disable()

#definercu_read_unlock()preempt_enable()

#definercu_assign_pointer(p,v)({

smp_wmb();

(p)=(v);

})

structkern_ipc_perm*ipc_lock(structipc_ids*ids,intid)

{

……

rcu_read_lock();

entries=rcu_dereference(ids->entries);

if(lid>=entries->size){

rcu_read_unlock();

returnNULL;

}

out=entries->p[lid];

if(out==NULL){

rcu_read_unlock();

returnNULL;

}

……

returnout;

}

staticintgrow_ary(structipc_ids*ids,intnewsize)

{

structipc_id_ary*new;

structipc_id_ary*old;

……

new=ipc_rcu_alloc(sizeof(structkern_ipc_perm*)*newsize+

sizeof(structipc_id_ary));

if(new==NULL)

returnsize;

new->size=newsize;

memcpy(new->p,ids->entries->p,sizeof(structkern_ipc_perm*)*size

+sizeof(structipc_id_ary));

for(i=size;inew->p[i]=NULL;

}

old=ids->entries;

/*

*Usercu_assign_pointer()tomakesurethememcpyedcontents

*ofthenewarrayarevisiblebeforethenewarraybecomesvisible。

*/

rcu_assign_pointer(ids->entries,new);

ipc_rcu_putref(old);

returnnewsize;

}

縱觀整個流程,寫者除內核屏障外,幾乎沒有一把鎖。當寫者需要更新數據結構時,首先復制該數據結構,申請new內存,然后對副本進行修改,調用memcpy將原數組的內容拷貝到new中,同時對擴大的那部分賦新值,修改完畢后,寫者調用rcu_assign_pointer修改相關數據結構的指針,使之指向被修改后的新副本,整個寫操作一氣呵成,其中修改指針值的操作屬于原子操作。在數據結構被寫者修改后,需要調用內存屏障smp_wmb,讓其他CPU知曉已更新的指針值,否則會導致SMP環境下的bug。當所有潛在的讀者都執行完成后,調用call_rcu釋放舊副本。同Spinlock一樣,RCU同步技術主要適用于SMP環境。

環形緩沖區是生產者和消費者模型中常用的數據結構。生產者將數據放入數組的尾端,而消費者從數組的另一端移走數據,當達到數組的尾部時,生產者繞回到數組的頭部。

如果只有一個生產者和一個消費者,那么就可以做到免鎖訪問環形緩沖區(RingBuffer)。寫入索引只允許生產者訪問并修改,只要寫入者在更新索引之前將新的值保存到緩沖區中,則讀者將始終看到一致的數據結構。同理,讀取索引也只允許消費者訪問并修改。

圖 2. 環形緩沖區實現原理圖

圖2。環形緩沖區實現原理圖

如圖所示,當讀者和寫者指針相等時,表明緩沖區是空的,而只要寫入指針在讀取指針后面時,表明緩沖區已滿。

清單9。2。6。10環形緩沖區實現代碼

/*

*__kfifo_put-putssomedataintotheFIFO,nolockingversion

*Notethatwithonlyoneconcurrentreaderandoneconcurrent

*writer,youdon'tneedextralockingtousethesefunctions。

*/

unsignedint__kfifo_put(structkfifo*fifo,

unsignedchar*buffer,unsignedintlen)

{

unsignedintl;

len=min(len,fifo->size-fifo->in+fifo->out);

/*firstputthedatastartingfromfifo->intobufferend*/

l=min(len,fifo->size-(fifo->in&(fifo->size-1)));

memcpy(fifo->buffer+(fifo->in&(fifo->size-1)),buffer,l);

/*thenputtherest(ifany)atthebeginningofthebuffer*/

memcpy(fifo->buffer,buffer+l,len-l);

fifo->in+=len;

returnlen;

}

/*

*__kfifo_get-getssomedatafromtheFIFO,nolockingversion

*Notethatwithonlyoneconcurrentreaderandoneconcurrent

*writer,youdon'tneedextralockingtousethesefunctions。

*/

unsignedint__kfifo_get(structkfifo*fifo,

unsignedchar*buffer,unsignedintlen)

{

unsignedintl;

len=min(len,fifo->in-fifo->out);

/*firstgetthedatafromfifo->outuntiltheendofthebuffer*/

l=min(len,fifo->size-(fifo->out&(fifo->size-1)));

memcpy(buffer,fifo->buffer+(fifo->out&(fifo->size-1)),l);

/*thengettherest(ifany)fromthebeginningofthebuffer*/

memcpy(buffer+l,fifo->buffer,len-l);

fifo->out+=len;

returnlen;

}

以上代碼摘自2。6。10內核,通過代碼的注釋(斜體部分)可以看出,當只有一個消費者和一個生產者時,可以不用添加任何額外的鎖,就能達到對共享數據的訪問。

總結

通過對比2。4和2。6內核代碼,不得不佩服內核開發者的智慧,為了提高內核性能,一直不斷的進行各種優化,并將業界最新的lock-free理念運用到內核中。

在實際開發過程中,進行無鎖設計時,首先進行場景分析,因為每種無鎖方案都有特定的應用場景,接著根據場景分析進行數據結構的初步設計,然后根據先前的分析結果進行并發模型建模,最后在調整數據結構的設計,以便達到最優。

此內容為AET網站原創,未經授權禁止轉載。
主站蜘蛛池模板: 欧美日韩国产成人一区 | 色综合五月婷婷 | 九九视频在线 | 中文字幕亚洲国产 | 东京热无码av男人的天堂 | 亚洲mv高清砖码区2022伊甸园 | 99精品视频免费在线观看 | 国产精品久久久久久亚洲影视 | 成人精品一区日本无码网站 | 老外和中国女人毛片免费视频 | 亚洲免费高清视频 | 欧美成人家庭影院 | 污视频网站免费在线观看 | 日韩精品91亚洲二区在线观看 | 国产亚洲成av人在线观看导航 | 亚洲精品www久久久久久 | 人妖和人妖互交性xxxx视频 | 国产色精品久久人妻 | 都市激情中文字幕 | 天堂中文在线观看视频 | 我要看免费的毛片 | 欧美xxxxx自由摘花 | 好吊妞视频在线观看 | 国内精品人妻无码久久久影院蜜桃 | 四虎影视库www111we | 色av中文字幕 | 最新黄色网址在线观看 | 午夜看看| 亚洲成色www久久网站夜月 | 又粗又黑又大的吊av | 日本少妇ⅹxxxxx视频 | 亚洲高清在线视频 | 国产精品女同磨豆腐磨出水了 | 香蕉视频官网在线观看 | 免费国产在线麻豆网站 | 超碰人人超碰人人 | 成年性生交大片免费看 | 中文字幕人妻熟女人妻a片 国产精品人妻系列21p | 少妇天天干 | 久久黄色片网站 | 一区二区三区久久久 | 影音先锋成人资源网 | 日韩在线中文字幕 | 成人免费在线视频观看 | 和朋友换娶妻一区二区 | 91爱在线观看 | 久久久精品视频一区二区三区 | 91av视频在线播放 | 97人人射| 免费在线观看黄色av | 国产精品极品白嫩 | 日韩欧美xxxx | 色狠狠一区二区三区香蕉 | 黄色一毛片 | 91精品国产乱码久久 | 天天看天天射 | 日本三级香港三级人妇99 | 欧美交换配乱吟粗大25p | 免费观看不卡av | 日本特级毛片 | 少妇高潮久久久久久潘金莲 | 九一午夜精品av | 日韩人妻无码精品-专区 | 女人被狂躁c到高潮喷水电影 | 81国产精品久久久久久久久久 | 少妇搡bbbb搡bbb搡打电话 | 亚洲色图日韩 | 99久久99久久精品免费看蜜桃 | 国产精品二区一区二区aⅴ污介绍 | 免费av一区二区三区 | 国产精品无码av在线播放 | 欧美少妇网 | 欧美亚洲视频 | 成人深夜在线 | 污污视频网站在线免费观看 | 日韩字幕 | 国产女同疯狂互摸系列3 | 欧美性猛交xxxx黑人猛交 | 日韩在线视频免费观看 | 国产精选一区二区 | 婷婷久久综合九色综合 | 五月婷六月丁香狠狠躁狠狠爱 | 九色91蝌蚪 | 在线看无码的免费网站 | 2022国产成人精品视频人 | 国产又粗又黄又爽 | 欧美精品一区二区蜜臀亚洲 | 97超碰人人模人人人爽人人爱 | 一边吃奶一边摸下边激情说说 | 第一色影院| 日韩国产精品一区二区三区 | 精品久久久久久一区二区里番 | 91高清在线视频 | 97人人视频| 欧美国产日韩在线观看成人 | 91国偷自产一区二区三区 | 中文字幕日韩一区二区三区 | 开心激情久久 | 日韩欧美偷拍 | 黄色aaa视频 | 中文字幕精品久久久久人妻红杏1 | 欧美性受视频 | 亚洲一区二区三区播放 | 欧洲精品视频在线 | 人人妻人人澡人人爽超污 | 无套在线观看 | 美女网站免费黄 | 成人做爰69片免费看网站 | 风流少妇又紧又爽又丰满 | 好吊妞视频988gao免费软件 | 国产黑丝91 | 亚洲日韩中文字幕一区 | 日本黄色免费网站 | 97超碰色| 久久精品国产亚洲一区二区 | 国产亚洲精品成人 | 国产精品19乱码一区二区三区 | 国产一级免费片 | jizzjizz在线播放 | 国产午夜亚洲精品午夜鲁丝片 | 99久久综合狠狠综合久久 | 欧美韩日精品 | 日本人xxxxxxxxx19| 国产精品99久 | 国产做受高潮69 | 日本精品高清一区二区 | 国产91传媒 | 亚洲香蕉成人av网站在线观看 | 国产精品精品久久久 | 久久成人国产精品 | 国产精品xxxx喷水欧美 | 无套内谢丰满少妇中文字幕 | 日本免费在线观看 | 爱情岛亚洲论坛福利站 | 一区二区片 | 五月婷婷丁香 | 不卡黄色 | tube极品少妇videos | 99热这里只有精品18 | av中文天堂 | 精品视频在线一区二区 | jzzijzzij亚洲成熟少妇 | 天天天av | 香蕉婷婷| 亚洲 自拍 另类小说综合图区 | 亚洲国产区 | 看看黄色片 | 一级全黄少妇免费录像片 | 特大黑人娇小亚洲女 | 黄网站在线播放 | 91精品久久久久久综合乱菊 | 在线观看国产精品日韩av | 天堂а在线中文在线新版 | 国产高清在线观看 | 国产69精品久久久 | 黄免费在线 | 国产一区二区视频在线播放 | 国产黄在线观看免费观看不卡 | 国产-第1页-浮力影院 | 看三级毛片 | 日本久久黄色 | 日本一区二区三区在线观看 | 波多野结衣不打码视频 | 女性向av免费网站 | 国产91精品久久久久久久 | 天天cao在线 | 日本激情久久 | 又紧又大又爽精品一区二区 | 99久久免费精品国产男女高不卡 | 一级国产国产一级 | 国产人成精品 | √天堂资源在线 | 极品尤物magnet | 强壮公侵犯使我夜夜高潮 | 深夜福利亚洲 | 精品一区二区三区免费观看 | 欧美在线看片a免费观看 | 国产福利短视频 | 国产成人亚洲综合色婷婷 | 日韩女优在线视频 | 1024欧美| 综合国产第二页 | 国产精品人人人人 | 男人和女人黄 色大片 | 成人亚洲欧美成αⅴ人在线观看 | 国产对白叫床清晰在线播放图片 | 国产高清精品软件 | 亚洲免费不卡视频 | xxxxx在线观看 | 国产情侣激情 | 中文字幕日韩一级 | 欧美激情一区二区在线观看 | 不卡一区二区三区四区 | 久热这里只有精品视频6 | 日韩精品三区 | 四虎永久免费 | 国产精品乱码高清在线观看 | 国产熟妇乱xxxxx大屁股网 | 秋霞影院午夜老牛影院 | 亚洲精品一区二区三区蜜臀 | 成人av自拍 | 亚洲成人77777 | 国产东北农村女人av | 日本一区二区三区免费视频 | 久久精品国产亚洲夜色av网站 | 黑人巨大精品欧美一区二区, | 色wwwwww| 国产精品久久99综合免费观看尤物 | 日产特黄极日产 | 色婷婷一区二区三区四区成人网 | 色妞ww精品视频7777nga | 久久精品黄色片 | 日本三级日产三级国产三级 | 极品尤物在线观看 | 国产v亚洲v天堂a无码 | 日日夜夜操操 | 欧美精品一级二级三级 | 成人a v视频 | 欧美综合日韩 | 欧美经典一区 | 成年女人毛片免费视频 | 麻花豆传媒mv在线观看 | 熟妇高潮精品一区二区三区 | 风韵多水的老熟妇 | 免费观看的av毛片的网站 | 国内精品久久久久影院中文字幕 | 97人人模人人爽人人少妇 | 日日噜噜噜噜夜夜爽亚洲精品 | 成人av动漫| 岛国午夜视频 | 久久久久久久一区 | 国产精品毛片无遮挡高清 | 久久久妇女 | av免费网站观看 | 国产精品亚洲成在人线 | a级片日本| 久久综合精品国产二区无码 | 欧美在线性视频 | 无码h片在线观看网站 | 日本久久久影视 | 又粗又硬大战丰满少妇 | 伊人综合影院 | 高潮毛片又色又爽免费 | 国产激情一区二区三区成人免费 | 成人免费视频一区二区 | www.久久久久久久 | 欧美三级在线播放 | 黑人蹂躏少妇在线播放 | 亚洲国产精品成人天堂 | 中文字幕一区二区三区久久 | 免费观看久久久 | 老妇肥熟凸凹丰满刺激小说 | 亚洲欧美日韩一区二区 | 天天综合网91 | 周冬雨三级视频 | 亚洲一区 国产精品 | 国产精品成人久久 | 岛国大片在线免费观看 | 国产淫视频| 色综合激情网 | 日韩精品久久久久久久电影蜜臀 | 天海翼av在线播放 | 爱插美女网| 欧美日韩在线视频播放 | 免费看一级黄色大全 | 国产精品国产三级国产aⅴ浪潮 | 九九热精品在线视频 | 日韩视频精品在线 | 少妇呻吟白浆高潮啪啪69 | 久久精品亚洲中文字幕无码网站 | 痞帅大猛xnxx精品打桩 | 久久精品国产丝袜人妻 | 丰满孕妇性春猛交xx大陆 | av网站入口| 色视频网站在线观看一=区 色视频网址 | 91福利一区二区 | 欧美交换配乱吟粗大25p | 亚洲成在人线在线播放无码 | 久久精品视频网 | 无码里番纯肉h在线网站 | 青青草在线免费观看 | 三级网站在线播放 | 国产成人无码av在线播放dvd | 天天爽夜夜爽精品视频婷婷 | 椎名空在线播放 | 国产精品爽爽久久久久久 | 在线天堂中文www视软件 | 亚洲一区二区激情 | 亚洲日韩av在线观看 | 一区二区精品在线 | 国产精品www伦之荡艳岳 | 久久婷婷五月综合97色一本一本 | 91最新在线视频 | 成人黄色动漫在线观看 | 亚洲一区精品视频 | 国产91精品看黄网站在线观看 | 爽爽窝窝午夜精品一区二区 | 久久精品国产69国产精品亚洲 | 黄色免费网站观看 | 无码人妻丰满熟妇区毛片18 | 性猛交xxxx乱大交3 | 毛片毛片免费看 | 国产午夜精品一区理论片飘花 | 午夜大尺度做爰激吻视频 | 免费看片免费播放国产 | 色欲国产麻豆一精品一av一免费 | 国产69精品久久久久久野外 | 免费网站看v片在线18禁无码 | 尤物国产视频 | 五月天激情小说 | 啪啪国产精品 | 日韩在线视频免费观看 | 欧美日本韩国亚洲 | 亚洲成人经典 | 在线国产中文字幕 | 天天爱天天做天天爽 | 亚洲第一激情 | 日韩精品无码一区二区三区 | 国产一区二区三区四区五区vm | 天海翼一区二区三区高清在线观看 | 成人婷婷网色偷偷亚洲男人的天堂 | a在线亚洲男人的天堂 | 一本到视频 | 人妻有码中文字幕在线 | 可以免费看的av网站 | 黄色一级网址 | 在线观看成人动漫 | 综合在线一区 | 业余 自由 性别 成熟偷窥 | 久久一区二区三区精华液使用 | 日韩欧美在线观看一区二区三区 | 非洲黑人三级全黄 | 欧美一二区视频 | 综合五月激情二区视频 | 天天噜噜噜噜噜噜 | 狠狠色狠狠色88综合日日91 | 欧美情侣性视频 | 欧美综合久久久 | 久久91精品国产91久久小草 | 欧美一区二区三区啪啪 | 亚洲成a人v欧美综合天堂下载 | 91久久国产最好的精华液 | 永久免费观看片在线现看 | 久久99精品久久久秒播软件优势 | 日本理论视频 | 亚洲精品午夜久久久 | 一级特黄少妇高清毛片 | 美女网站黄频 | 娇小性xxxxx极品娇小小说 | 国产精品极品白嫩在线 | 关秀媚三级露全乳 | 三级视频网站在线观看 | www.国产一区| 久久精品国产亚卅av嘿嘿 | 国产精品一区二区av | 少妇被躁爽到高潮无码文 | av在线收看| 神马久久香蕉 | 久久精品久久久久 | 91theporn国产在线观看 | 性做久久久久久 | 国产日产欧产精品精乱了派 | 91精品国产高清一区二区三密臀 | 黄色三级小视频 | 久草在线视频新时代视频 | 中文字幕a∨在线乱码免费看 | 久久久久久久久亚洲 | jizz黄色片| 日本不卡一区在线观看 | 欧美肥妇毛多水多bbxx | 欧美日韩成人在线观看 | 44382亚洲最大成人网 | 在线日本看片免费人成视久网 | 国产女主播在线一区二区 | 国产精品视频入口麻豆 | 亚洲人成无码网站18禁10 | 久久亚洲少妇 | 国产精久久久久久妇女av | 91免费 看片 | 国产网站免费观看 | 中国精品毛片 | 都市激情久久 | 另类专区欧美 | 日本一区午夜艳熟免费 | 日韩怡红院 | 在线操 | 国产微拍精品一区 | 男人的亚洲天堂 | 青青草国产成人av片免费 | 日本一级片在线观看 | 爱情岛论坛成人永久网站在线观看 | 国产精品久久久久久亚瑟影院 | 国产成人精品在线 | 亚洲激情图 | 天天碰天天碰 | 欧美猛男性猛交视频 | a在线观看视频 | 色琪琪丁香婷婷综合久久 | 中文字幕+乱码+中文字幕一区 | 日本公妇乱淫xxxⅹ 日本公妇乱淫免费 | 中文字幕一区二区三区第十负 | 亚洲日韩精品a∨片无码加勒比 | 中年两口子高潮呻吟 | 日本欧美一区二区免费视频 | aaa一级黄色片| 九色在线视频 | 国产热热 | 国产精品久久夂夂精品香蕉爆 | 国产成人精品三上悠亚 | 四川少妇性色xxxxhd | 48沈阳熟女高潮嗷嗷叫 | 操欧美女| 精品午夜福利在线观看 | 亚洲天堂av免费在线观看 | 牲交欧美兽交欧美 | 成人免费一级片 | 日韩一卡二卡 | 黑人av| 三级黄在线观看 | 一本一道dvd在线观看免费视频 | 无码h黄肉动漫在线观看 | 免费xxxx大片国产在线 | 在线xxxx| 五月天婷婷色 | 亚洲天堂男人影院 | 日韩精品视频在线观看一区二区 | 色偷偷888欧美精品久久久 | 色狠狠操 | 成人丝袜激情一区二区 | 久久精品99北条麻妃 | 刚添一下她就呻吟起来的视频 | 亚欧av在线| 精品福利在线观看 | 大香伊人 | 欧美综合自拍 | 国产97色在线 | 中国 | 久久久久久久久久久网站 | 国产xxxx成人精品免费视频频 | 4438xx亚洲最大五色丁香一 | 理论片午午伦夜理片影院 | 成人午夜激情网 | 中文字幕一区二区三区精华液 | 国偷自产视频一区二区久 | 欧美裸体精品 | 国产农村妇女精品一二区 | 久久久国产精品 | 国产精品久久婷婷六月丁香 | 中文字幕资源在线 | 337p人体粉嫩胞高清视频 | 精品无人乱码一区二区三区 | 在线网站av | 亚洲色图偷拍 | 亚欧在线免费观看 | 久久一二三区 | 美女张开腿黄网站免费下载 | 国产一区两区 | 人妻av综合天堂一区 | 色36cccwww在线播放 | 日韩美女做爰高潮免费 | 久久综合综合 | 欧美在线一 | 亚色视频在线观看 | 丰满少妇大bbbbb超 | 久久久久久久久嫩草精品乱码 | 日韩在线第三页 | 欧美日韩亚洲成人 | 国产日韩欧美在线观看视频 | 97精品视频在线播放 | 91蝌蚪在线观看 | 99精品视频一区二区三区 | 无码av免费一区二区三区试看 | 欧美久久久久久久久中文字幕 | 久久黄色片网站 | 久久爽久久爽久久av东京爽 | 综合网日日天干夜夜久久 | 美女网站在线永久免费观看 | 哪里可以看毛片 | 国产在线无码视频一区二区三区 | 国偷自产av一区二区三区麻豆 | 免费午夜av | 人妻人人澡人人添人人爽人人玩 | 精品无码人妻一区二区三区不卡 | 久久91精品国产91久久久 | 国产精品久久久久久av | 免费a在线观看 | 视频福利一区 | 欧美一区二区三区爽爽爽 | 免费观看成人毛片a片 | 婷婷夜夜躁天天躁人人躁 | 超碰91在线观看 | 九九久久国产 | 成人性做爰av片免费看 | 免费视频福利 | 偷拍激情视频一区二区三区 | 欧美xxxx黑人xyx性爽 | 天天干天天操天天爱 | 国产成人精品无码免费看 | jlzzjizz亚洲学生好多水 | 日韩精品视频网 | hdhdhd69xxxxх| 中文字幕在线亚洲精品 | 国产精品久久久久久免费播放 | 亚洲一区二区黄色 | 国产三级视频 | 四虎最新网址在线观看 | 岛国精品一区 | 中文字幕日韩一区二区三区不卡 | 8×8x拔擦拔擦在线视频网站 | 久久福利网站 | 亚洲天堂av免费在线观看 | 成人做爰视频www网站小优视频 | 精品夜夜嗨av一区二区三区 | 国产欧美日韩在线 | 成人看片在线观看 | 国产精品久久久久免费观看 | 好了av四色综合网站 | 欧洲a级片| 激情影音 | 中文字幕久久精品 | 欧美日韩免费在线 | 男女洗澡视频网站 | 免费视频欧美无人区码 | 裸体美女无遮挡免费网站 | 日本一区二区三区四区在线观看 | 蜜桃视频一区二区三区 | 末发育娇小性色xxxxx视频 | 日本一区二区网站 | 久久人人爽人人爽人人片亞洲 | 女人做爰全过程免费观看美女 | 国产精品免费看久久久 | 边啃奶头边躁狠狠躁 | 日美女网站 | 欧美精品国产一区二区 | 北岛玲日韩一区二区三区 | 久久久久久国产精品视频 | 色女仆影院 | 奇米影视7777久久精品人人爽 | 人人爽久久涩噜噜噜蜜桃 | 女同 另类 激情 重口 | 邻居少妇张开腿让我爽了一夜 | 自拍偷在线精品自拍偷无码专区 | 黄视频网站在线 | 一道本视频在线 | 欧美综合精品 | 热久久亚洲 | 黄色免费视频网站 | a级片一级片 | 精品一二三四 | 西方av在线 | 美女的隐私免费看 | 成人中文视频 | 丝袜 亚洲 另类 欧美 重口 | 亚洲熟伦熟女新五十路熟妇 | 丰满人妻精品国产99aⅴ | 亚洲视频在线免费观看 | 97av.com| 精品久久久久久无码专区不卡 | 国内精品久久久久影视老司机 | 777精品出轨人妻国产 | 91在线视频导航 | 五月天中文字幕在线 | 丁香六月av | 精品二区视频 | wwwxxx在线播放 | 琪琪电影午夜理论片八戒八戒 | 日本大奶少妇 | 亚洲视频自拍 | 免费av影片| 天堂网av在线 | 99精品无码一区二区 | 国产精品高清网站 | 欧美情侣性视频 | 天天干天天摸 | 中文天堂最新版在线www | 免费人成视频在线观看不卡 | 久久久婷婷五月亚洲97号色 | 日韩激情在线视频 | 国产精品一区二区手机在线观看 | 老头把我添高潮了a片 | 久久av无码精品人妻糸列 | 中文字幕羽月希黑人侵犯 | 成人在线播放视频 | 在线观看免费www | 真多人做人爱视频高清免费 | 午夜草逼| av大片免费看 | 日本三级韩国三级欧美三级 | 欧美久久成人 | 亚洲第一成年免费网站 | 人人91 | 国产成人无码av在线播放dvd | 韩国黄色网 | 日本一区二区三区四区在线观看 | 宅男666在线永久免费观看 | 在线黄色av网站 | 日日躁夜夜摸月月添添添的视频 | 日日躁夜夜躁狠狠久久av | 黄在线免费 | 日本一区视频在线观看 | 极品尤物一区二区三区 | 国产日韩av免费无码一区二区三区 | 青青草久久伊人 | av丁香 | 国产偷人爽久久久久久老妇app | 国产精品蜜臀av免费观看四虎 | 亚洲欧美精品久久 | 九草影院 | 久久久五月天 | 久久不卡区| 日韩精品在线一区 | 一线二线三线天堂 | 亚洲视频在线视频 | 西西人体444www大胆无码视频 | 在线中文字幕网站 | 超污网站在线观看 |