missing rwsem bits
Subsystems (2)
PATCH 1/1 missing rwsem bits
Hi Linus,
when David send you the last rwsem patch he included the bits done by Brian and me (1) in the description, but not in the patch. This BK patch adds the missing bits (already reviewed by David).
(1) that is: down_read_trylock/down_write_trylock and the generic spinlock implementation of write_downgrade.
--
You can import this changeset into BK by piping this whole message to:
'| bk receive [path to repository]' or apply the patch as usual.
===================================================================
[email protected], 2002-07-28 21:18:19+02:00, [email protected]
Implement down_read_trylock() and down_write_trylock() and add a generic spinlock implementation for downgrade_write().
include/asm-i386/rwsem.h | 36 ++++++++++++++++ include/linux/rwsem-spinlock.h | 3 + include/linux/rwsem.h | 25 +++++++++++ lib/rwsem-spinlock.c | 89 ++++++++++++++++++++++++++++++++++++++--- 4 files changed, 146 insertions, 7 deletions
include/asm-i386/rwsem.h +36 -0
@@ -118,6 +118,29 @@ }/* +* trylock for reading -- returns 1 if successful, 0 if contention +*/ +static inline int __down_read_trylock (struct rw_semaphore *sem) +{ +__s32 result, tmp; + __asm__ __volatile__( +"# beginning __down_read_trylock\n\t" +" movl %0,%1\n\t" +"1:\n\t" +" movl %1,%2\n\t" +" addl %3,%2\n\t" +" jle 2f\n\t" +LOCK_PREFIX " cmpxchgl %2,%0\n\t" +" jnz 1b\n\t" +"2:\n\t" +"# ending __down_read_trylock\n\t" + :"+m" (sem->count),"=&a" (result),"=&r" (tmp) + :"i" (RWSEM_ACTIVE_READ_BIAS ) + :"memory" ,"cc" ); +return result>=0 ?1 :0 ; +} + +/* * lock for writing */ static inline void __down_write (struct rw_semaphore *sem)
@@ -142,6 +165,19 @@ : "=m"(sem->count), "=d"(tmp) : "a"(sem), "1"(tmp), "m"(sem->count) : "memory", "cc"); +} + +/* +* trylock for writing -- returns 1 if successful, 0 if contention +*/ +static inline int __down_write_trylock (struct rw_semaphore *sem) +{ +signed long ret =cmpxchg (&sem->count, +RWSEM_UNLOCKED_VALUE , +RWSEM_ACTIVE_WRITE_BIAS ); +if (ret ==RWSEM_UNLOCKED_VALUE ) +return 1 ; +return 0 ; }/*
include/linux/rwsem-spinlock.h +3 -0
@@ -54,9 +54,12 @@extern void FASTCALL (init_rwsem (struct rw_semaphore *sem));extern void FASTCALL (__down_read (struct rw_semaphore *sem)); +extern int FASTCALL (__down_read_trylock (struct rw_semaphore *sem));extern void FASTCALL (__down_write (struct rw_semaphore *sem)); +extern int FASTCALL (__down_write_trylock (struct rw_semaphore *sem));extern void FASTCALL (__up_read (struct rw_semaphore *sem));extern void FASTCALL (__up_write (struct rw_semaphore *sem)); +extern void FASTCALL (__downgrade_write (struct rw_semaphore *sem));#endif /* __KERNEL__ */ #endif /* _LINUX_RWSEM_SPINLOCK_H */
include/linux/rwsem.h +24 -1
@@ -46,6 +46,18 @@ }/* +* trylock for reading -- returns 1 if successful, 0 if contention +*/ +static inline int down_read_trylock (struct rw_semaphore *sem) +{ +int ret; +rwsemtrace (sem,"Entering down_read_trylock" ); + ret =__down_read_trylock (sem); +rwsemtrace (sem,"Leaving down_read_trylock" ); +return ret; +} + +/* * lock for writing */ static inline void down_write (struct rw_semaphore *sem)
@@ -56,6 +68,18 @@ }/* +* trylock for writing -- returns 1 if successful, 0 if contention +*/ +static inline int down_write_trylock (struct rw_semaphore *sem) +{ +int ret; +rwsemtrace (sem,"Entering down_write_trylock" ); + ret =__down_write_trylock (sem); +rwsemtrace (sem,"Leaving down_write_trylock" ); +return ret; +} + +/* * release a read lock */ static inline void up_read (struct rw_semaphore *sem)
@@ -84,7 +108,6 @@__downgrade_write (sem);rwsemtrace (sem,"Leaving downgrade_write" ); } -#endif /* __KERNEL__ */ #endif /* _LINUX_RWSEM_H */
lib/rwsem-spinlock.c +83 -6
144 lines not on this page · raw message
===================================================================
This BitKeeper patch contains the following changesets:
1.477
## Wrapped with gzip_uu ##
begin 664 bkpatch9967 M'XL(`+1#1#T``\U9;7,:-Q#^S/T*E8Q=;/,BZ5XA0QK')BU3M_9@IVEG,G,C M[@1<<MS1N\/$+?WO74E@,!P$J#U3;/.BE5:[SZZ>7>%7Z$/*DT9AXVT5^BG M.,T:A;1;[:9^'(5!Q*MQT@=!)XY!4$OX**[!\/AKA59-#00W+/,&Z)XG::- MJOKC2/8PXHU"I_7CAZOSCJ8UF^ABP*(^O^49:C:U+$[N6>BG;UDV"..HFB4L M2H<\8U4O'DX?ITXIQA1^3&+KV+2FQ,*&/?6(3P@S"/<Q-1S+T$9L'([3MRD; M=IDP>%6!36VLZQ:E4TRL.M8N$:D:MHTPK6&[1AU$28,X#5(_P[2!,0(PWJZ" M@,X,5,':._2\IE]H'FH/1R$?\BA#?CR)W(0SW\V2AS#VOI1.$(M\-3Y)@HRO M")@/?Z"BSR.>!!Y*1T$DQ"B8ZV19$$>H%R=223]A/E>:2B=5[6=DV(9VLXB- M5MGSH6F88>T-&HFHYT,21%XX]KG*FUHR2?FP.ECXQ"B&P"/Z1A3W^>^W[5M MG=IUW\0L-Q+;%-K4(750J4^QC1USNV%AT%6K*W/8JMZR7;I)IIA:%IERO^=; M78?;S+,\9O7R[=JL;\DL;-6MW?!BZ;2Z(Z5!QG&9$HIJ9M3WS%ZV-?K/<NF MON\9VR'+U[DPCQ*=.GN'<^%O3EP-@T[K%C.,'NSB]S!SNG3GN*YI7C+5=BQ; M,LLFYP31O!C.FC^()SP,T[<)]P<LVT&E34UBFA37X2,0DJ0A@M=82-_*0KKU M4C1469&<MTU*JK-QI[0$#"(2IEK5$DF\A<XX69C2[@ES:A&%%=0Z=HMJED M,V%:$/51I0)OLW$2I8B@H(?2L>?Q-.V-PS+"8L"+HPQ<A8$%34M%8SH@8$" M4GC)];649LG8RUR<<%L-AK$"4>G\/9$^ULKN&ZJ4]@U'8=9&67#T6LQ!JZZ M+BB[CT/8(>2N6](*A>(KU.7]((J$K3D[?8H^944Q#Z%A?!\B^3C"Y2/R*"&- ME4D%-8F4C^B2!$K!?+G^5/(YY&H)[:G1J^N+G]V;3NM]^W<A]X:CK]Z@#ZN/ M:/D(+Z^,_E(K2?=QE"[,>85XY'_#L08JG@V+)7&6WWCQ.,I.RJC8/&;%D@)0 M?4R*)<#Q1,T/BJ7.Q]O6+^[YQ5W[MY;;:9U?NN_:Y[<S^9/X^2A"L]KW@" MX*L$F$7D31.C'R7&@B_UO[1/FFU4\@APT!$GW]<2261T<^:2D\K]=9<2H-^ MQ'T$)[@O-D?->31*QPO(RN!W0*A4/GPJXA?Z]+][?SJ0ZN,G@AGD'WLM.]:
M"C/!TPO2>7-7!4"UAF$9($FH+=,KOFDO"/%_I=:\3SZ;0S-GU-W',FZZZW? M-TCWY3A7='"[LNUL<*F)$_PKZ^&_LT'YA6-BU$-/XUXY:(M7?G]_>79Q? M797VHD_(QK9I;]>TX^F1JNH+5?=QX*_J6FYWMRG:D.B'Y/>NK>W6_B&WLUTT M#[JNF@=GSS2F<(4A+YC'ZUF<VS'(SOS;"7M8GAH.(O3EFH4]6P6Q!'84K"I< MJ]+FIAN=B"C1)ATYK&>4F#6I![MD!UCKXKSNZWJE,5,EO41#,/J>>KA?M6 MPEVA>J)R':N5'7<*U?A*EJ7CFMP1-YM[QOT,3A%\W_II5.3<?2+<D5=$^N M<*#F6?^;>T9NY1,WZ14:R</D4!811Z,B#P1/4L0@5P&?!S2)O_!(G()^\*E M%4IBN*H\A=/8NW2Q+"T+9^?'HK<['==:2YXYPI]&X](69ZIQRU/8)^ZW*>. M'-7@?;<0(CA.<FS"A/&5-[V0]5-T/.O^/IZW[]J__NB^O^ZH1E$T@(5^G,4H M'HL#J-Y#.F32*'>&4C$:2C43J7[7&+"PA#JF]Y(JU[QL")\8@8FW0RD< MMWF1>H;JA[*!CSAWP.V6@&P5BL1R\0XZB6P/8KE)/3GF(^YUK8%J.MV-;1+ MFPHPX%G7"I,!W+Y6?#]>]US<*A12,\S#(,W<60B.HV@IP!*F:L0DJH8>PWN M7]IU1+6VY=26*NFH*9:#2F=/)3$S/)C($5TU:RRF',B46P3DR#Z;'7JH&OL MC'#!=KR-='/T"I*$/!!'S)7[J+N*\%)^5F*1@'*<>5EP'V0/XF9V?#Q#:CC* M'IZL$]BH>$!^R;2!K+?(#[+2L[.7JOK"MA-YADI+1E'FVW95``V.)=;+TG= [email protected]?C%;JVP'!*WY'$$#>ROD!>*V6^FFU!3LH%ZD9;)=6"%>P;%$ M7"JH3A"IS[XG>*PZP&'+Y!4!MS%Y7N6JA6?QZGB:#0>(18]2+DL'ALY38E M;RY[7%A$(FP)_=ROF;;=XKX:+C+[VN"[;8'?"B9>VO>P$.<X(D(*`=(AD*W? M;ZX[=^[M'[^\N\Z]A:I8&INF/LD=-=?:,'<I*N*R./\?ES?@WI=T/&Q:O&<[ -W/.T?P%XL2Z'3AL`````
`
end
PATCH 1/1 rwsem trylock and downgrade part II
Hi Linus, Christoph,
I'm not sure what happened, but I think I applied an old incomplete patch when patching 2.5.28, one that was missing Christoph's rwsem-spinlock stuff and the trylock stuff. The attached patch adds these back (as per Christoph's patch), it also adds a missing export to lib/rwsem.c.
When compiled for PentiumIII SMP, I see:
dhowells>nm vmlinux | grep rwsem c01c5dbd t .text.lock.rwsem c02995a0 ? __kstrtab_rwsem_down_read_failed c02995b7 ? __kstrtab_rwsem_down_write_failed c02995da ? __kstrtab_rwsem_downgrade_wake c02995cf ? __kstrtab_rwsem_wake c02a1cf8 ? __ksymtab_rwsem_down_read_failed c02a1d00 ? __ksymtab_rwsem_down_write_failed c02a1d10 ? __ksymtab_rwsem_downgrade_wake c02a1d08 ? __ksymtab_rwsem_wake c01c5870 T rwsem_down_read_failed c01c5a20 T rwsem_down_write_failed c01c5cf0 T rwsem_downgrade_wake c01c5bd0 T rwsem_wake
When compiled for i386 SMP, I see:
dhowells>nm vmlinux | grep 'rwsem\|__\(up\|down.*\)_\(read\|write\)' c01be49a t .text.lock.rwsem_spinlock c01bdf8c T __down_read c01be080 T __down_read_trylock c01be0f4 T __down_write c01be1ec T __down_write_trylock c01be3e4 T __downgrade_write c028c0f9 ? __kstrtab___down_read c028c120 ? __kstrtab___down_read_trylock c028c142 ? __kstrtab___down_write c028c160 ? __kstrtab___down_write_trylock c028c1c0 ? __kstrtab___downgrade_write c028c183 ? __kstrtab___up_read c028c19b ? __kstrtab___up_write c028c0e0 ? __kstrtab_init_rwsem c0295b80 ? __ksymtab___down_read c0295b88 ? __ksymtab___down_read_trylock c0295b90 ? __ksymtab___down_write c0295b98 ? __ksymtab___down_write_trylock c0295bb0 ? __ksymtab___downgrade_write c0295ba0 ? __ksymtab___up_read c0295ba8 ? __ksymtab___up_write c0295b78 ? __ksymtab_init_rwsem c01be264 T __up_read c01be2fc T __up_write c01bdf6c T init_rwsem
So I think I've got all the functions there and that they're all exported now.
David
include/asm-i386/rwsem.h +36 -0
@@ -118,6 +118,29 @@ }/* +* trylock for reading -- returns 1 if successful, 0 if contention +*/ +static inline int __down_read_trylock (struct rw_semaphore *sem) +{ +__s32 result, tmp; + __asm__ __volatile__( +"# beginning __down_read_trylock\n\t" +" movl %0,%1\n\t" +"1:\n\t" +" movl %1,%2\n\t" +" addl %3,%2\n\t" +" jle 2f\n\t" +LOCK_PREFIX " cmpxchgl %2,%0\n\t" +" jnz 1b\n\t" +"2:\n\t" +"# ending __down_read_trylock\n\t" + :"+m" (sem->count),"=&a" (result),"=&r" (tmp) + :"i" (RWSEM_ACTIVE_READ_BIAS ) + :"memory" ,"cc" ); +return result>=0 ?1 :0 ; +} + +/* * lock for writing */ static inline void __down_write (struct rw_semaphore *sem)
@@ -145,6 +168,19 @@ }/* +* trylock for writing -- returns 1 if successful, 0 if contention +*/ +static inline int __down_write_trylock (struct rw_semaphore *sem) +{ +signed long ret =cmpxchg (&sem->count, +RWSEM_UNLOCKED_VALUE , +RWSEM_ACTIVE_WRITE_BIAS ); +if (ret ==RWSEM_UNLOCKED_VALUE ) +return 1 ; +return 0 ; +} + +/* * unlock after reading */ static inline void __up_read (struct rw_semaphore *sem)
include/linux/rwsem-spinlock.h +3 -0
@@ -54,9 +54,12 @@extern void FASTCALL (init_rwsem (struct rw_semaphore *sem));extern void FASTCALL (__down_read (struct rw_semaphore *sem)); +extern int FASTCALL (__down_read_trylock (struct rw_semaphore *sem));extern void FASTCALL (__down_write (struct rw_semaphore *sem)); +extern int FASTCALL (__down_write_trylock (struct rw_semaphore *sem));extern void FASTCALL (__up_read (struct rw_semaphore *sem));extern void FASTCALL (__up_write (struct rw_semaphore *sem)); +extern void FASTCALL (__downgrade_write (struct rw_semaphore *sem));#endif /* __KERNEL__ */ #endif /* _LINUX_RWSEM_SPINLOCK_H */
include/linux/rwsem.h +24 -1
@@ -46,6 +46,18 @@ }/* +* trylock for reading -- returns 1 if successful, 0 if contention +*/ +static inline int down_read_trylock (struct rw_semaphore *sem) +{ +int ret; +rwsemtrace (sem,"Entering down_read_trylock" ); + ret =__down_read_trylock (sem); +rwsemtrace (sem,"Leaving down_read_trylock" ); +return ret; +} + +/* * lock for writing */ static inline void down_write (struct rw_semaphore *sem)
@@ -56,6 +68,18 @@ }/* +* trylock for writing -- returns 1 if successful, 0 if contention +*/ +static inline int down_write_trylock (struct rw_semaphore *sem) +{ +int ret; +rwsemtrace (sem,"Entering down_write_trylock" ); + ret =__down_write_trylock (sem); +rwsemtrace (sem,"Leaving down_write_trylock" ); +return ret; +} + +/* * release a read lock */ static inline void up_read (struct rw_semaphore *sem)
@@ -85,6 +109,5 @@rwsemtrace (sem,"Leaving downgrade_write" ); } -#endif /* __KERNEL__ */ #endif /* _LINUX_RWSEM_H */
lib/rwsem-spinlock.c +83 -6
144 lines not on this page · raw message
lib/rwsem.c +1 -0
@@ -236,6 +236,7 @@EXPORT_SYMBOL_NOVERS (rwsem_down_read_failed);EXPORT_SYMBOL_NOVERS (rwsem_down_write_failed);EXPORT_SYMBOL_NOVERS (rwsem_wake); +EXPORT_SYMBOL_NOVERS (rwsem_downgrade_wake);#if RWSEM_DEBUG EXPORT_SYMBOL (rwsemtrace);#endif