)]}'
{
  "commit": "633f91e3408cc65a5237752a3265b031c389e43e",
  "tree": "e5c83d902bbd043b5d763fcfa828c81f6757f86a",
  "parents": [
    "782ef2b8fe9767239d29ce522c3183130a63d557"
  ],
  "author": {
    "name": "Andrea Parri",
    "email": "parri.andrea@gmail.com",
    "time": "Mon Oct 19 18:18:48 2026 +0200"
  },
  "committer": {
    "name": "Paul E. McKenney",
    "email": "paulmck@kernel.org",
    "time": "Wed Oct 21 09:57:57 2026 -0700"
  },
  "message": "hazptr: Record per-CPU slot owner after claiming the slot\n\nAn interrupt that uses a hazard pointer while the interrupted task is\nin the acquire slow path can leave its own context recorded as the\nowner of the per-CPU slot the task then publishes into.  The next\ncontext switch promotes the task\u0027s pointer with the interrupt\u0027s\ncontext.\n\nhazptr_get_free_percpu_slot() records the owner when it picks an empty\nslot, but only Store B in __hazptr_try_acquire() claims the slot.  An\ninterrupt in between picks the same slot, as the lowest free one:\n\n  Task on CPU 0                        IRQ on CPU 0\n  -------------                        ------------\n  hazptr_acquire(ctx)\n    fast path fails\n    __hazptr_acquire(ctx)\n      picks item k (empty)\n      item k-\u003ectx.ctx \u003d ctx\n                                       hazptr_acquire(irq_ctx)\n                                         claims item k\n                                         item k-\u003ectx.ctx \u003d irq_ctx\n                                       hazptr_release(irq_ctx)\n                                         clears slot k\n      __hazptr_try_acquire()\n        Store B into slot k\n      (item k still names irq_ctx)\n  sleeps holding the pointer\n  hazptr_note_context_switch()\n    promotes item k with irq_ctx\n\nThe task gets there with k \u003e 0 when it already holds an outer hazard\npointer in slot 0; no other task can, as its slot is promoted when it\nis switched out.\n\nThe task gets there with k \u003d\u003d 0 when the fast path leaves slot 0\nempty: either its ptr_eq() check fails because an updater changed the\npointer, or the pointer is NULL and an updater publishes a non-NULL one\nbefore the slow path loads it.\n\nThe promotion moves the task\u0027s pointer into irq_ctx\u0027s backup slot,\nwhich nothing unchains, so hazptr_synchronize() on that pointer never\nreturns.  The task\u0027s ctx-\u003eslot still names slot k, so its\nhazptr_release() clears whatever another reader on that CPU has since\npublished there.\n\nIf the interrupt detaches instead, as hazptr_torture_acquire() does,\nthe promotion chains irq_ctx\u0027s backup slot a second time while it is\nstill linked.  The overflow list then loops on that node, or follows\nLIST_POISON1 once hazptr_unchain_backup_slot() removes it.\n\nRecord the owner after __hazptr_try_acquire() succeeds, as the fast\npath in hazptr_acquire() does.  This should be safe because an\ninterrupt that used the slot has released or detached it by the time\nthe task resumes, and only hazptr_note_context_switch() reads the\nowner, which cannot run before the task enables preemption.\n\nFixes: 50b568234163 (\"hazptr: Implement Hazard Pointers\")\nAssisted-by: LLM\nSigned-off-by: Andrea Parri \u003cparri.andrea@gmail.com\u003e\nAcked-by: Bradley Morgan \u003cbrads@mainlining.org\u003e\nReviewed-by: Mathieu Desnoyers \u003cmathieu.desnoyers@efficios.com\u003e\nSigned-off-by: Paul E. McKenney \u003cpaulmck@kernel.org\u003e\n",
  "tree_diff": [
    {
      "type": "modify",
      "old_id": "3ca73b56a5c2549d3d1b70c86a5a86be81cc0870",
      "old_mode": 33188,
      "old_path": "kernel/hazptr.c",
      "new_id": "b15b84ebd4ceb2b33c700c2ce610ec9c729b7cb0",
      "new_mode": 33188,
      "new_path": "kernel/hazptr.c"
    }
  ]
}
