On Wed, Jan 8, 2025 at 7:06 AM Matthew Wilcox <willy@xxxxxxxxxxxxx> wrote: > > On Wed, Jan 08, 2025 at 10:16:04AM +0100, Vlastimil Babka wrote: > > > static inline __must_check __signed_wrap > > > -bool __refcount_add_not_zero(int i, refcount_t *r, int *oldp) > > > +bool __refcount_add_not_zero_limited(int i, refcount_t *r, int *oldp, > > > + int limit) > > > { > > > int old = refcount_read(r); > > > > > > do { > > > if (!old) > > > break; > > > + if (limit && old + i > limit) { > > > > Should this be e.g. "old > limit - i" to avoid overflow and false negative > > if someone sets limit close to INT_MAX? > > Although 'i' might also be INT_MAX, whereas we know that old < limit. > So "i > limit - old" is the correct condition to check, IMO. > > I'd further suggest that using a limit of 0 to mean "unlimited" introduces > an unnecessary arithmetic operation. Make 'limit' inclusive instead > of exclusive, pass INT_MAX instead of 0, and Vlastimil's suggestion, > and this becomes: > > if (i > limit - old) Thanks for the suggestions, Vlastimil and Matthew! Yes, this looks much better. Will use it in the next version. > > > > + if (oldp) > > > + *oldp = old; > > > + return false; > > > + } > > > } while (!atomic_try_cmpxchg_relaxed(&r->refs, &old, old + i)); > > ... > > > > +static inline __must_check __signed_wrap > > > +bool __refcount_add_not_zero(int i, refcount_t *r, int *oldp) > > > +{ > > > + return __refcount_add_not_zero_limited(i, r, oldp, 0); > > Just to be clear, this becomes: > > return __refcount_add_not_zero_limited(i, r, oldp, INT_MAX); Ack. >