On Thu, Mar 17, 2022 at 07:25:27AM +0000, Visa Hankala wrote: > On Thu, Mar 17, 2022 at 12:42:13AM +0100, Alexander Bluhm wrote: > > I would like to use btrace to debug refernce counting. The idea > > is to a a tracepoint for every type of refcnt we have. When it > > changes, print the actual object, the current counter and the change > > value. > > > Do we want that feature? > > I am against this in its current form. The code would become more > complex, and the trace points can affect timing. There is a risk that > the kernel behaves slightly differently when dt has been compiled in.
Can we get in this part then? - Remove DIAGNOSTIC to keep similar in non DIAGNOSTIC case. - Rename refcnt to refs. refcnt is the struct, refs contains the r_refs value. - Add KASSERT(refs != ~0) in refcnt_finalize(). - Always use u_int refs so I can insert my btrace diff easily. Maybe I can optimize btrace diff later. bluhm Index: kern/kern_synch.c =================================================================== RCS file: /data/mirror/openbsd/cvs/src/sys/kern/kern_synch.c,v retrieving revision 1.184 diff -u -p -r1.184 kern_synch.c --- kern/kern_synch.c 16 Mar 2022 14:13:01 -0000 1.184 +++ kern/kern_synch.c 17 Mar 2022 16:12:50 -0000 @@ -810,25 +810,21 @@ refcnt_init(struct refcnt *r) void refcnt_take(struct refcnt *r) { -#ifdef DIAGNOSTIC - u_int refcnt; + u_int refs; - refcnt = atomic_inc_int_nv(&r->r_refs); - KASSERT(refcnt != 0); -#else - atomic_inc_int(&r->r_refs); -#endif + refs = atomic_inc_int_nv(&r->r_refs); + KASSERT(refs != 0); + (void)refs; } int refcnt_rele(struct refcnt *r) { - u_int refcnt; + u_int refs; - refcnt = atomic_dec_int_nv(&r->r_refs); - KASSERT(refcnt != ~0); - - return (refcnt == 0); + refs = atomic_dec_int_nv(&r->r_refs); + KASSERT(refs != ~0); + return (refs == 0); } void @@ -842,26 +838,33 @@ void refcnt_finalize(struct refcnt *r, const char *wmesg) { struct sleep_state sls; - u_int refcnt; + u_int refs; - refcnt = atomic_dec_int_nv(&r->r_refs); - while (refcnt) { + refs = atomic_dec_int_nv(&r->r_refs); + KASSERT(refs != ~0); + while (refs) { sleep_setup(&sls, r, PWAIT, wmesg, 0); - refcnt = atomic_load_int(&r->r_refs); - sleep_finish(&sls, refcnt); + refs = atomic_load_int(&r->r_refs); + sleep_finish(&sls, refs); } } int refcnt_shared(struct refcnt *r) { - return (atomic_load_int(&r->r_refs) > 1); + u_int refs; + + refs = atomic_load_int(&r->r_refs); + return (refs > 1); } unsigned int refcnt_read(struct refcnt *r) { - return (atomic_load_int(&r->r_refs)); + u_int refs; + + refs = atomic_load_int(&r->r_refs); + return (refs); } void