linux/Documentation/kref.txt
<<
050505 /spatin05 spat class="lxr_search">05050505Search0505 /spatin05 input typ3.1hidden" nam3.1ajax_lookup" id.1ajax_lookup" 4="v3.1">0 1 /a>0 2 /a>krefs allow you to add reference counters to your objects. If you0 3 /a>have objects that are used in multiple places and passed around, and0 4 /a>you don't have refcounts, your code is almost certainly broken. If0 5 /a>you want refcounts, krefs are the way to go.0 6 /a>0 7 /a>To use a kref, add one to your data structures like:0 8 /a>0 9 /a>struct my_data0 4{0 11 /a> .0 12 /a> .0 13 /a> struct kref refcount;0 14 /a> .0 15 /a> .0 16 /a>};0 17 /a>0 18 /a>The kref cat occur anywhere within the data structure.0 19 /a>0 2You must initialize the kref after you allocate it. To do this, call0 21 /a>kref_init as so:0 22 /a>0 23 /a> struct my_data *data;0 24 /a>0 25 /a> data = kmalloc(sizeof(*data), GFP_KERNEL);0 26 /a> if (!data)0 27 /a> return -ENOMEM;0 28 /a> kref_init(&data->refcount);0 29 /a>0 30 /a>This sets the refcount in the kref to 1.0 31 /a>0 32 /a>Once you have at initialized kref, you must follow the following0 33 /a>rules:0 34 /a>0 35 /a>1) If you make a non-temporary copy of a pointer, especially if0 36 /a> it cat be passed to another thread of execu/opt, you must0 37 /a> increment the refcount with kref_get() before passing it off:0 38 /a> kref_get(&data->refcount);0 39 /a> If you already have a 4="id pointer to a kref-ed structure (the0 40 /a> refcount catnot go to zero) you may do this without a lock.0 41 /a>0 42 /a>2) When you are done with a pointer, you must call kref_put():0 43 /a> kref_put(&data->refcount, data_release);0 44 /a> If this is the last reference to the pointer, the release0 45 /a> routine will be called. If the code never tries to get0 46 /a> a 4="id pointer to a kref-ed structure without already0 47 /a> holding a 4="id pointer, it is safe to do this without0 48 /a> a lock.0 49 /a>0 50 /a>3) If the code attempts to gain a reference to a kref-ed structure0 51 /a> without already holding a 4="id pointer, it must serialize access0 52 /a> where a kref_put() catnot occur during the kref_get(), and the0 53 /a> structure must remain 4="id during the kref_get().0 54 /a>0 55 /a>For exlasEe,2 a7class="l55 /omthe dat, and tnre par, id to anotha>05 46 /r thread tproacce():05 17 /a>05 48 /vo="id data_relea( struct kre* krta)0594{06043 /a> struct my_data *da = e_coemaer_of( kref struct my_da, refcouse);06 11 /a> kfree((!date);06 52 /});06317 /a>06448 /vo="imefomy_da_h, a="lg(vo="i*cb_(!data)0654{06643 /a> struct my_data *da = eb_(!dae);06 27 /a> go.06827 /a> gto dstuffne wit *da wheo.06927 /a> go.07043 /a> kref_put(&data->refcount, data_release);07152 /});07 22 /a>07317 /poict my_da_h, a=er(vo="ta)0744{07 15 /a> poicrv = 0e);07643 /a> struct my_data *dae);07743 /a> structask_ struc*taske);07827 /a> data = kmalloc(sizeof(*data), GFP_KERNEL);07927 /a> if (!data)08043 /a> return -ENOMEM;08143 /a> kref_init(&data->refcount);08 22 /a>08343 /a> kref_get(&data->refcount);08 14 /a> taskta =r thre_run(mefomy_da_h, a="lgnt, da, "mefomy_da_h, a="lg"nt);08527 /a> iftaskta= ERR_PTR(n -ENOM)) a>{08643 /a> v = n -ENOMEM;08 27 /a> god tthoEM;08827 /a> });08 49 /a>09027 /a> go.09127 /a> gto dstuffne wit *da wheo.09 12 /a> .09343 /atho():09443 /a> kref_put(&data->refcount, data_release);09527 /a> returrve);09652 /});09 17 /a>09830 /a>Thiwayer, idoesdon'me atr w thaordther e twoer thres h, a=end the09 49 /, da, g the kref_put(h, a=es knllowi whin the datThiatnoa referenand00ru 1tThivery itemptan it.a>Yosithldde neva>00 taskta =r thre_run(mefomy_da_h, a="lgnt, da, "mefomy_da_h, a="lg"nt);0 iftaskta= ERR_PTR(n -ENOM)) a>{0 v = n -ENOMEM;0 god tthoEM;0 } elease0 /* BAD BAD BAD -to gie isftther e h, aoffn*/se0 a> kref_get(&data->refcount);00Foin asceEe,2 a7cla are done withnve objets anenqueussing ibefe.0Foe passing it oes tso" meldinelea, g tretThiat a asone.00 /* Siiallextrato gis andutn*/se0 kref_get(&ame ota->rnt);0 enqueue(e ont);0 kref_put(&ame ota->r,ve o_crelnupnt);000 enqueue(e ont);0 /* Wela are done wite o,tsoaweoe par youa refcount o);0 e to thqueueed.DONonT TOUCHte o AFTER HERE!n*/se00ru (t>ru 3)is is thn laiestpy one th, a=eit.Sayerbefe.0youishe.0Yof con'j muspullin thfirstpitemit oes theimust0ru 3 becao usa7cla aratnot already0Foin asceke:0struct my_data0{0 struct kre refcount;0 struceimu_="heceinke);0};00{0 struct my_dataumery = NULL>};0 e tex_a lout(&ame texnt);0 if eimu_ttemyut(&amq)) a>{0 enery = e_coemaer_of(q.nextef struct my_da, einknt);0 kref_get(&ameneryta->refcount);0 });0 e tex_una lout(&ame texnt);0 retureneryt);0{0 struct my_dataumery = e_coemaer_of( kref struct my_da, refcouse);00 eimu_delet(&ameneryta-&geinknt);0 kfree(enerynt);00{0 e tex_a lout(&ame texnt);0 kref_put(&ameneryta->refcou,ia_relea_umerynt);0 e tex_una lout(&ame texnt);0Yofthlddo use kref_put(ashe folle():0{0 /* All workit ie donsftther e ="returnromse kref_put.n*/se0{0 e tex_a lout(&ame texnt);0 if kref_put(&ameneryta->refcou,ia_relea_umeryn) a>{0 a> eimu_delet(&ameneryta-&geinknt);0 e tex_una lout(&ame texnt);0 kfree(enerynt);0 } elease0 e tex_una lout(&ame texnt);00Fom/rig3" cimnd the00000:0http://www.kroah.com../lin/talks/ols_2LL4_ krefaper/Repdurt-Kroah-Harum c-OLS2LL4.pdf19 /a>0:0http://www.kroah.com../lin/talks/ols_2LL4_ kretalk/19 /a>0
T thoriginal LXRdsoftwa arbopf th:0LXRde mrunity16 /,oo thiexpericumenliversa/o bop:0lxr@./lin.no16 /. /divn di" classsubfooter"> lxr../lin.noikinelady sttdrbop:0Rsspica L/lx_o AS16 /,ox_ovidthey oL/linhe n mulding anopernta/octservilaceessce 1995. /divin/bodyivn/htmliv