You can import this changeset into BK by piping this whole message to: '| bk receive [path to repository]' or apply the patch as usual. =================================================================== ChangeSet@1.1422.1.19, 2003-11-14 21:52:30-02:00, acme@conectiva.com.br o LLC: use refcounting with struct llc_sap include/net/llc.h | 16 +++++++++++++++- net/802/p8022.c | 2 +- net/802/psnap.c | 2 +- net/llc/af_llc.c | 11 ++++++----- net/llc/llc_c_ac.c | 1 + net/llc/llc_conn.c | 28 ++-------------------------- net/llc/llc_conn.h | 1 - net/llc/llc_core.c | 38 +++++++++++++++++++++++++------------- net/llc/llc_input.c | 9 +++++++-- 9 files changed, 58 insertions(+), 50 deletions(-) diff -Nru a/include/net/llc.h b/include/net/llc.h --- a/include/net/llc.h Sat Nov 15 17:00:27 2003 +++ b/include/net/llc.h Sat Nov 15 17:00:27 2003 @@ -17,6 +17,8 @@ #include #include +#include + struct net_device; struct packet_type; struct sk_buff; @@ -44,6 +46,7 @@ unsigned char state; unsigned char p_bit; unsigned char f_bit; + atomic_t refcnt; int (*rcv_func)(struct sk_buff *skb, struct net_device *dev, struct packet_type *pt); @@ -79,7 +82,18 @@ int (*rcv)(struct sk_buff *skb, struct net_device *dev, struct packet_type *pt)); -extern void llc_sap_close(struct llc_sap *sap); +static inline void llc_sap_hold(struct llc_sap *sap) +{ + atomic_inc(&sap->refcnt); +} + +static inline void llc_sap_put(struct llc_sap *sap) +{ + extern void llc_sap_close(struct llc_sap *sap); + + if (atomic_dec_and_test(&sap->refcnt)) + llc_sap_close(sap); +} extern struct llc_sap *llc_sap_find(unsigned char sap_value); diff -Nru a/net/802/p8022.c b/net/802/p8022.c --- a/net/802/p8022.c Sat Nov 15 17:00:27 2003 +++ b/net/802/p8022.c Sat Nov 15 17:00:27 2003 @@ -55,7 +55,7 @@ void unregister_8022_client(struct datalink_proto *proto) { - llc_sap_close(proto->sap); + llc_sap_put(proto->sap); kfree(proto); } diff -Nru a/net/802/psnap.c b/net/802/psnap.c --- a/net/802/psnap.c Sat Nov 15 17:00:27 2003 +++ b/net/802/psnap.c Sat Nov 15 17:00:27 2003 @@ -106,7 +106,7 @@ static void __exit snap_exit(void) { - llc_sap_close(snap_sap); + llc_sap_put(snap_sap); } module_exit(snap_exit); diff -Nru a/net/llc/af_llc.c b/net/llc/af_llc.c --- a/net/llc/af_llc.c Sat Nov 15 17:00:27 2003 +++ b/net/llc/af_llc.c Sat Nov 15 17:00:27 2003 @@ -21,6 +21,7 @@ * See the GNU General Public License for more details. */ #include +#include #include #include #include @@ -181,10 +182,6 @@ if (!sk->sk_zapped) llc_sap_remove_socket(llc->sap, sk); release_sock(sk); - if (llc->sap && hlist_empty(&llc->sap->sk_list.list)) { - llc_release_sockets(llc->sap); - llc_sap_close(llc->sap); - } if (llc->dev) dev_put(llc->dev); sock_put(sk); @@ -213,6 +210,7 @@ llc_ui_sap_last_autoport = i + 2; goto out; } + llc_sap_put(sap); } llc_ui_sap_last_autoport = LLC_SAP_DYN_START; tries++; @@ -302,6 +300,7 @@ rc = -EBUSY; /* some other network layer is using the sap */ if (!sap) goto out; + llc_sap_hold(sap); } else { struct llc_addr laddr, daddr; struct sock *ask; @@ -318,7 +317,7 @@ ask = llc_lookup_established(sap, &daddr, &laddr); if (ask) { sock_put(ask); - goto out; + goto out_put; } } llc->laddr.lsap = addr->sllc_sap; @@ -327,6 +326,8 @@ /* assign new connection to its SAP */ llc_sap_add_socket(sap, sk); rc = sk->sk_zapped = 0; +out_put: + llc_sap_put(sap); out: return rc; } diff -Nru a/net/llc/llc_c_ac.c b/net/llc/llc_c_ac.c --- a/net/llc/llc_c_ac.c Sat Nov 15 17:00:27 2003 +++ b/net/llc/llc_c_ac.c Sat Nov 15 17:00:27 2003 @@ -63,6 +63,7 @@ llc->dev = skb->dev; ev->ind_prim = LLC_CONN_PRIM; rc = 0; + llc_sap_put(sap); } return rc; } diff -Nru a/net/llc/llc_conn.c b/net/llc/llc_conn.c --- a/net/llc/llc_conn.c Sat Nov 15 17:00:27 2003 +++ b/net/llc/llc_conn.c Sat Nov 15 17:00:27 2003 @@ -628,6 +628,7 @@ */ void llc_sap_add_socket(struct llc_sap *sap, struct sock *sk) { + llc_sap_hold(sap); write_lock_bh(&sap->sk_list.lock); llc_sk(sk)->sap = sap; sk_add_node(sk, &sap->sk_list.list); @@ -647,6 +648,7 @@ write_lock_bh(&sap->sk_list.lock); sk_del_node_init(sk); write_unlock_bh(&sap->sk_list.lock); + llc_sap_put(sap); } /** @@ -724,32 +726,6 @@ #ifdef LLC_REFCNT_DEBUG static atomic_t llc_sock_nr; #endif - -/** - * llc_release_sockets - releases all sockets in a sap - * @sap: sap to release its sockets - * - * Releases all connections of a sap. Returns 0 if all actions complete - * successfully, nonzero otherwise - */ -int llc_release_sockets(struct llc_sap *sap) -{ - int rc = 0; - struct sock *sk; - struct hlist_node *node; - - write_lock_bh(&sap->sk_list.lock); - - sk_for_each(sk, node, &sap->sk_list.list) { - llc_sk(sk)->state = LLC_CONN_STATE_TEMP; - - if (llc_send_disc(sk)) - rc = 1; - } - - write_unlock_bh(&sap->sk_list.lock); - return rc; -} /** * llc_backlog_rcv - Processes rx frames and expired timers. diff -Nru a/net/llc/llc_conn.h b/net/llc/llc_conn.h --- a/net/llc/llc_conn.h Sat Nov 15 17:00:27 2003 +++ b/net/llc/llc_conn.h Sat Nov 15 17:00:27 2003 @@ -113,5 +113,4 @@ extern u8 llc_data_accept_state(u8 state); extern void llc_build_offset_table(void); -extern int llc_release_sockets(struct llc_sap *sap); #endif /* LLC_CONN_H */ diff -Nru a/net/llc/llc_core.c b/net/llc/llc_core.c --- a/net/llc/llc_core.c Sat Nov 15 17:00:27 2003 +++ b/net/llc/llc_core.c Sat Nov 15 17:00:27 2003 @@ -31,7 +31,7 @@ * * Allocates and initializes sap. */ -struct llc_sap *llc_sap_alloc(void) +static struct llc_sap *llc_sap_alloc(void) { struct llc_sap *sap = kmalloc(sizeof(*sap), GFP_ATOMIC); @@ -40,6 +40,7 @@ sap->state = LLC_SAP_STATE_ACTIVE; memcpy(sap->laddr.mac, llc_station_mac_sa, ETH_ALEN); rwlock_init(&sap->sk_list.lock); + atomic_set(&sap->refcnt, 1); } return sap; } @@ -52,9 +53,7 @@ */ void llc_add_sap(struct llc_sap *sap) { - write_lock_bh(&llc_sap_list_lock); list_add_tail(&sap->node, &llc_sap_list); - write_unlock_bh(&llc_sap_list_lock); } /** @@ -70,11 +69,25 @@ write_unlock_bh(&llc_sap_list_lock); } +struct llc_sap *__llc_sap_find(unsigned char sap_value) +{ + struct llc_sap* sap; + + list_for_each_entry(sap, &llc_sap_list, node) + if (sap->laddr.lsap == sap_value) + goto out; + sap = NULL; +out: + return sap; +} + /** * llc_sap_find - searchs a SAP in station * @sap_value: sap to be found * * Searchs for a sap in the sap list of the LLC's station upon the sap ID. + * If the sap is found it will be refcounted and the user will have to do + * a llc_sap_put after use. * Returns the sap or %NULL if not found. */ struct llc_sap *llc_sap_find(unsigned char sap_value) @@ -82,11 +95,9 @@ struct llc_sap* sap; read_lock_bh(&llc_sap_list_lock); - list_for_each_entry(sap, &llc_sap_list, node) - if (sap->laddr.lsap == sap_value) - goto out; - sap = NULL; -out: + sap = __llc_sap_find(sap_value); + if (sap) + llc_sap_hold(sap); read_unlock_bh(&llc_sap_list_lock); return sap; } @@ -105,19 +116,20 @@ struct net_device *dev, struct packet_type *pt)) { - struct llc_sap *sap = llc_sap_find(lsap); - - if (sap) { /* SAP already exists */ - sap = NULL; + struct llc_sap *sap = NULL; + + write_lock_bh(&llc_sap_list_lock); + if (__llc_sap_find(lsap)) /* SAP already exists */ goto out; - } sap = llc_sap_alloc(); if (!sap) goto out; sap->laddr.lsap = lsap; sap->rcv_func = func; + llc_sap_hold(sap); llc_add_sap(sap); out: + write_unlock_bh(&llc_sap_list_lock); return sap; } diff -Nru a/net/llc/llc_input.c b/net/llc/llc_input.c --- a/net/llc/llc_input.c Sat Nov 15 17:00:27 2003 +++ b/net/llc/llc_input.c Sat Nov 15 17:00:27 2003 @@ -165,17 +165,22 @@ */ if (sap->rcv_func) { sap->rcv_func(skb, dev, pt); - goto out; + goto out_put; } dest = llc_pdu_type(skb); if (unlikely(!dest || !llc_type_handlers[dest - 1])) - goto drop; + goto drop_put; llc_type_handlers[dest - 1](sap, skb); +out_put: + llc_sap_put(sap); out: return 0; drop: kfree_skb(skb); goto out; +drop_put: + kfree_skb(skb); + goto out_put; handle_station: if (!llc_station_handler) goto drop; =================================================================== This BitKeeper patch contains the following changesets: 1.1422.1.19 ## Wrapped with gzip_uu ## M'XL( ,MWMC\ ]59;6_;-A#^+/T* @6*)*MMONK%68)NS; %"[:@1;\-,&B) MBH7(4B#):8NI_WU'RHYE6W8DHT R)Y$0OASO^-S=6#.;*?H/^ MR(IR; 59JH(R?I3#()L/ISET?,PRZ!C-LKD:Z;&CZ3T=I:H:\<$.4(9N;CZ,T:)0*%=1D"W2,D[OT)>XG*&BS!=!B9(DF!3R MP?X3@2%,V+?KK;4'/3^VC26V+]O-K.(T2!:ATHB/]*IS&0QGM3&"$=!@T]]<7 M;H4=UR&50X7O84?YS)5\#Y)MDIKJ4(\RUEV=(I4/+>IX^LD=$7DJ<%7D1%/L MD^<46LMJ*D1\2IV]@"VWU8!59,']2I00SGJ)V]@;(CCMIDZ6IBWJ$.&P M*O)\22(**OE,AMSK)6Y#'=?U6>?8,C):@@L KR(5!!X1+(J8DE.7=E5I)[HP M)Z(C8%FNEB9A 83X5-28=_Q& 06B2"%LBF/IL07TW[BFNJX+MV??9KSYZWN M0RGV*TEEZ$+$D$A!H#NB@[0X?5B4;<$N'&*X:G"#WB-P/),0+AF>E M,1&&PBC;YBXB#G,71@/R\MQE//%O-,B_F%^@HMN6;3^"T*X(<5 -XP[;=$>Q M!]5UD[B-(8'\X+ENC2'MBR$1KP-$P]9;*.X8?@2(UU"24?O-4A3Z61;SD2RS M>0SB+NU_[&NN,;;JIDF)5A^MVU<>A?YK_:1V4LSB<&7" M9)8EX@,'J?VOT_208F3M] VN*REGY[;WT&% U(AN^P5JKZ6*D\WQP=) M5JC6&>>PD!5'Z&2I2ZB ^M)P4JJBW%3JU+:L+7EF_O?=A&;(-8)S//=4P@,-$[$%Y'(6XJCT/9S!A^3" H9$&M,:U#+"M/-45UA[U3R]Q M35BA8@"&T[!"L/:$E:(!E+DOCZLIX9YCJ>-P95@#NYF(#+#7#O>;76O(KUSJ M(MB77>AU==45^NZ%G1W*1S5_GR[*8IC&Z;T<@J2]=1W&+F%4,R1W.",&>;2PK93OPKX&629,&)9HI3(#QJ\L"2!PJU MF?[?(:+]0^AD<25BOSS2,9 M 4GKL4.H) 024$GXB*U4V]K#M2'G]LK8)ALW0ON*8 ]QJ&X(@9?5POA/EEN6 M;7W)XU)-P GN)]/9R<;VFM;5@EL*Z1T^/46C,_3IEULDDUS)\!M27V%:@MP"(]J,)V-EJ>KKJEHQX'NP[2-@]VV,><08E:4<)= M5A<8O1.2"TST\NFH/IH>R$=+RX\Z+SF>\0;S6D>B#@3ML:ZII.O7LC?,LX>Z M&]H9A.)R^+B-M&"(![&SF@-C[J-3TC MKN7*RQ0UE'F8U]2&^[J2@P;B%;B2N;3;XTHKLX^I:*A.*NLC&QR+%E]'8-)# MG*A<']NNB,=U]J.DKFG;G(5AOE'O-I,GH\10IWE9VYX*[?XSKKCRK,:%[_-? M1AQQUWS M[;OFALU&/4XK>ME[XA3T"NX#:@ORUL\JV'T,0E*F/PDO.VB^"$' M!QA&NKC^(?[!N& CP;NG'I Y6<*[^F(QF*G@OEC,+R@GT@V$LO\#/ZY;9\T<