On Mon, Jul 15, 2019 at 03:25:35PM -0400, Alex Kogan wrote: > @@ -36,6 +37,33 @@ struct cna_node { > > #define CNA_NODE(ptr) ((struct cna_node *)(ptr)) > > +/* Per-CPU pseudo-random number seed */ > +static DEFINE_PER_CPU(u32, seed); > + > +/* > + * Controls the probability for intra-node lock hand-off. It can be > + * tuned and depend, e.g., on the number of CPUs per node. For now, > + * choose a value that provides reasonable long-term fairness without > + * sacrificing performance compared to a version that does not have any > + * fairness guarantees. > + */ > +#define INTRA_NODE_HANDOFF_PROB_ARG 0x10000 > + > +/* > + * Return false with probability 1 / @range. > + * @range must be a power of 2. > + */ > +static bool probably(unsigned int range) > +{ > + u32 s; > + > + s = this_cpu_read(seed); > + s = next_pseudo_random32(s); > + this_cpu_write(seed, s); > + > + return s & (range - 1); This is fragile, better to take a number of bits as argument. > +} > + > static void cna_init_node(struct mcs_spinlock *node) > { > struct cna_node *cn = CNA_NODE(node); > @@ -140,7 +168,13 @@ static inline void cna_pass_mcs_lock(struct mcs_spinlock *node, > u64 *var = &next->locked; > u64 val = 1; > > - succ = find_successor(node); > + /* > + * Try to pass the lock to a thread running on the same node. > + * For long-term fairness, search for such a thread with high > + * probability rather than always. > + */ > + if (probably(INTRA_NODE_HANDOFF_PROB_ARG)) > + succ = find_successor(node); > > if (succ) { > var = &succ->mcs.locked; And this is where that tertiary condition comes from.. I think.