From: Mathieu Desnoyers <[email protected]> Provide a new hazptr_detach() function that detaches a given hazard pointer from its acquisition context. This context might be a task or an interrupt handler.
[ paulmck: s/hazptr_detach_from_task/hazptr_detach/ per Mathieu. ] Signed-off-by: Mathieu Desnoyers <[email protected]> Signed-off-by: Paul E. McKenney <[email protected]> --- include/linux/hazptr.h | 55 ++++++++++++++++++++++++++++-------------- 1 file changed, 37 insertions(+), 18 deletions(-) diff --git a/include/linux/hazptr.h b/include/linux/hazptr.h index 461f481a480b9c..fd19579d1260e7 100644 --- a/include/linux/hazptr.h +++ b/include/linux/hazptr.h @@ -98,6 +98,41 @@ bool hazptr_slot_is_backup(struct hazptr_ctx *ctx, struct hazptr_slot *slot) return slot == &ctx->backup_slot.slot; } +/* Internal helper. */ +static inline +void hazptr_promote_to_backup_slot(struct hazptr_ctx *ctx, struct hazptr_slot *slot) +{ + struct hazptr_slot *backup_slot; + + backup_slot = hazptr_chain_backup_slot(ctx); + /* + * Move hazard pointer from the per-CPU slot to the + * backup slot. This requires hazard pointer + * synchronize to iterate on per-CPU slots with + * load-acquire before iterating on the overflow list. + */ + WRITE_ONCE(backup_slot->addr, slot->addr); + /* + * store-release orders store to backup slot addr before + * store to per-CPU slot addr. + */ + smp_store_release(&slot->addr, NULL); + /* Use the backup slot for context. */ + ctx->slot = backup_slot; +} + +static inline +void hazptr_detach(struct hazptr_ctx *ctx) +{ + struct hazptr_slot *slot; + + guard(preempt)(); + slot = ctx->slot; + if (unlikely(hazptr_slot_is_backup(ctx, slot))) + return; + hazptr_promote_to_backup_slot(ctx, slot); +} + static inline void hazptr_note_context_switch(void) { @@ -106,27 +141,11 @@ void hazptr_note_context_switch(void) for (idx = 0; idx < NR_HAZPTR_PERCPU_SLOTS; idx++) { struct hazptr_slot_item *item = &percpu_slots->items[idx]; - struct hazptr_slot *slot = &item->slot, *backup_slot; - struct hazptr_ctx *ctx; + struct hazptr_slot *slot = &item->slot; if (!slot->addr) continue; - ctx = item->ctx.ctx; - backup_slot = hazptr_chain_backup_slot(ctx); - /* - * Move hazard pointer from the per-CPU slot to the - * backup slot. This requires hazard pointer - * synchronize to iterate on per-CPU slots with - * load-acquire before iterating on the overflow list. - */ - WRITE_ONCE(backup_slot->addr, slot->addr); - /* - * store-release orders store to backup slot addr before - * store to per-CPU slot addr. - */ - smp_store_release(&slot->addr, NULL); - /* Use the backup slot for context. */ - ctx->slot = backup_slot; + hazptr_promote_to_backup_slot(item->ctx.ctx, slot); } } -- 2.40.1

