From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from mail.openvz.org (mail.openvz.org [69.168.225.77]) by lore.virtuozzo.com (Postfix) with ESMTPS id 0B5B380BB3 for ; Thu, 22 Oct 2026 20:28:45 +0000 (UTC) Received: from mail.openvz.org (localhost [127.0.0.1]) by mail.openvz.org (8.14.4/8.14.4) with ESMTP id 69MKRUEL016688; Thu, 22 Oct 2026 23:27:31 +0300 DKIM-Filter: OpenDKIM Filter v2.11.0 mail.openvz.org 69MKRUEL016688 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=openvz.org; s=default; t=1792700853; bh=3JhO/77F/YcM8Ah+dUwtamOHt8+voMkHof1LOIjXi4Q=; h=From:To:Date:In-Reply-To:References:Subject:List-Id: List-Unsubscribe:List-Archive:List-Post:List-Help:List-Subscribe; b=luJaP0WUMWDjlDO+DiHwvkFUOlYxKz+o03nJA5I4JQ1seSrxpGfILWdYTro55xn1B TN3TYhesuUT8S9Ex+YZYukx/nfGBSS4ZBdu4HnFEPxli5sEIETnlj8fA29LNat4Wy5 cN3cpl5ru4s7l+ldXM8q9OaAZmbc46Uw6Gv9FYqHvcFIaGpBk7QmIZnJj8qMGpcBsA iJB/EssND7Mlenr6H/MzPBICIbnYY4tIsFwzTjggfUPLZ/JBNKVFJE1Ch+ntS2L+yR QJBa6xVXJPRxdRsrKwWl9EUgJhIBkgq3tW9XIs/6gb68sWoGFklEIy89EX3iIENg5T SQW2Y+UtdYrcg== Received: from mail-wm1-f71.google.com (mail-wm1-f71.google.com [209.85.128.71]) by mail.openvz.org (8.14.4/8.14.4) with ESMTP id 69MKRM1L016670 (version=TLSv1/SSLv3 cipher=AES128-GCM-SHA256 bits=128 verify=FAIL) for ; Thu, 22 Oct 2026 23:27:22 +0300 DKIM-Filter: OpenDKIM Filter v2.11.0 mail.openvz.org 69MKRM1L016670 Authentication-Results: mail.openvz.org; dkim=pass (2048-bit key) header.d=openvz.org header.i=@openvz.org header.b="jzx2nkFh" Received: by mail-wm1-f71.google.com with SMTP id 5b1f17b1804b1-4a009f82bedso1107285e9.0 for ; Thu, 22 Oct 2026 13:27:22 -0700 (PDT) X-Gm-Message-State: AFq9FYJxmnUM/zGGy/zgUNMa6XGwAgAotaMx6zlYiX4jBY6ERh6Y5lXZ /4HH5CBGiBShW95M9fDv4OM5YnqSjSmPbu+n2PnAWO8NhmJ+MQ7WVfqvqPoXsoy/pZ3ItGxHMWL hUNbyAXlck8YpuZynHVwaO/lj2S7w+GqlDI7xjZix98QhH/3GdCGhWw== X-Gm-Gg: AYBFou3gzGmUGrzUuPdCGbVGFuTIPgFcPaIsIpgWx8dCPDXGwD7I9FCBMqlohDTgW+l NARPg2rYPkqblB7v/y2CfOEsHc/HW57qtXD2vAb+gZuqpTu8OFBEQba6HD0pdkce6c/Kqdo+Lpz xjg8Evf/irSScFieEMJB1VAodPu4xIykq1VbpnZfLO+zWACsbaW09gMlQlj+f9YezHBOiv5s+1X G0I5xLjbRPGwjwi5RAN6MwXfQ8J3y9m3lcLB2enCTI1zX+olACRZ4+IruGV1cZLqTsgoZS9RfEH ktvi3kNPDQ== X-Received: by 2002:a05:600d:82e1:b0:4a2:59:f568 with SMTP id 5b1f17b1804b1-4a211ce4c9amr2657435e9.14.1792700842141; Thu, 22 Oct 2026 13:27:22 -0700 (PDT) X-Received: by 2002:a05:600d:82e1:b0:4a2:59:f568 with SMTP id 5b1f17b1804b1-4a211ce4c9amr2657285e9.14.1792700841696; Thu, 22 Oct 2026 13:27:21 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1792700841; cv=none; d=google.com; s=arc-20260327; b=VZV//mrO4id4QsJEQn7sM86LDZVtqWCyNRttA0J87yQYB7cSsyGSk3m+tHgLHFFDOL hjNeq16LKy1H2fVLu9WJHkc8JovtGfD94NT29u6wZ61nwvabpxsLR4UOHv6AvlQpmNaD wjpDWQERwXWGyyuTb/mJOBa/Ip9g4LSP38e2YRagQ36ez81aulNbrL3iJJUHigujJlWL tA1fPH/k9HUDH7xz0/2ZybFpF1AcLEDZhVrIDQ4ccuQkKgOgwRWEzSuGOaLzsV9ktoGv VAr1ZRV+f/I58Xvje2EbUJZuNCaHtZVQG1XQ8mzsOTLtqpy6kciWrLteofU05j+FHk+N gNTg== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20260327; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:dkim-signature; bh=2Ax5ax0cf24PQOjR7thP14RI/RQlZHEFfVPSb90biu0=; fh=9uh4XaPpgi4eEAsqC4+SeZyHNzLz7ufStPU27zuFNdo=; b=lxe/RDneceyjV5FosXxDeCxTGaaspj8u9jKS8NeTpJwT63PEkGejUec5WJPDIOxXS5 f6wk0wt7j4tCgrQ1ATk0j4IhsmvnsxDUbYED6Es6s1KoYeKZv4UJzIxX7CZLs7XMyToK 6VBc73Aj/bLvMSjlgDH5Ob8ey70IajDTrk5QThHDw3Wpnhk5+CZ3VDrfdcsnS1wO/iFp bO90CKoYTRSdWFSq7qYQsRCXm/VLVyVCZWGDq7H5HaOhfUKK/B4QCQ9iEWZuBvOac2Uh dITYS8iCQrDGCOA2vgk5nchG62wja20OC7FJk7BaYo4M3KnyD1jxZjWGENNaVb55g/Z0 gRTQ==; dara=google.com ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@openvz.org header.s=google header.b=jzx2nkFh; spf=softfail (google.com: domain of transitioning den@openvz.org does not designate 2a06:5b06:b600:300:3c49:8d18:710e:ef45 as permitted sender) smtp.mailfrom=den@openvz.org; dara=neutral header.i=@openvz.org Received: from mail-sor-f41.google.com (mail-sor-f41.google.com. [209.85.220.41]) by mx.google.com with SMTPS id 5b1f17b1804b1-4a211b3171esor483185e9.2.2026.10.22.13.27.21 for (Google Transport Security); Thu, 22 Oct 2026 13:27:21 -0700 (PDT) Received-SPF: softfail (google.com: domain of transitioning den@openvz.org does not designate 2a06:5b06:b600:300:3c49:8d18:710e:ef45 as permitted sender) client-ip=2a06:5b06:b600:300:3c49:8d18:710e:ef45; Authentication-Results: mx.google.com; dkim=pass header.i=@openvz.org header.s=google header.b=jzx2nkFh; spf=softfail (google.com: domain of transitioning den@openvz.org does not designate 2a06:5b06:b600:300:3c49:8d18:710e:ef45 as permitted sender) smtp.mailfrom=den@openvz.org; dara=neutral header.i=@openvz.org DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=openvz.org; s=google; t=1792700841; x=1793305641; darn=openvz.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to:content-type; bh=2Ax5ax0cf24PQOjR7thP14RI/RQlZHEFfVPSb90biu0=; b=jzx2nkFhrMyPh5qju21jehquEi/msi9rkXbnWTp5D6S7hUVmVKyK1IEJyulMmIkNIz WjpJioheKjRWPsIMltzYyq3V2wHOckr5TuYC2hUDz7eZB6+dikLw4JaSDnWdPqdOYv8p +vsrNM5atLRZ6ItjdDvJl6x6vDmR/INVO1DZ4neGeAOtiZD8Ga61kpSHAugfsT0bG96g oDbwF/TNdIQvgd4fp2KFTF0YnTtsKeg00OQUKymMCnYmqewzNsPY9MR5mXJx5u+LdFrf S19cGHAGAITe113Cg4QhbzPa2E44NLTeKRAPO4pK0bK/Mfwm/yToWyHO9jvrUgJlXKHm B6lg== X-Received: by 2002:a05:600c:3111:b0:4a1:88de:9e8b with SMTP id 5b1f17b1804b1-4a211cd08b8mr2624435e9.5.1792700841264; Thu, 22 Oct 2026 13:27:21 -0700 (PDT) Received: from athena.sw.ru ([2a06:5b06:b600:300:3c49:8d18:710e:ef45]) by smtp.gmail.com with ESMTPSA id 5b1f17b1804b1-4a21047b524sm21261065e9.14.2026.10.22.13.27.20 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 22 Oct 2026 13:27:20 -0700 (PDT) From: "Denis V. Lunev" To: devel@openvz.org Date: Thu, 22 Oct 2026 22:27:16 +0200 Message-ID: X-Mailer: git-send-email 2.53.0 In-Reply-To: References: MIME-Version: 1.0 X-OZ-Fwd: true Subject: [Devel] [PATCH RK hci-7.4 2/2] fs/fuse kio: repoint RDMA handlers and restrack names on RK load X-BeenThere: devel@openvz.org X-Mailman-Version: 2.1.12 Precedence: list List-Id: OpenVZ development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: 7bit Sender: devel-bounces@openvz.org Errors-To: devel-bounces@openvz.org Up to v8.53 the RK carried its own copies of pcs_rdma_io_event_handler(), pcs_rdma_cq_event_handler() and pcs_rdma_qp_event_handler(), and every RDMA connection opened while such an RK was active points at them. "kpatch replace" unloads the replaced RK right after the new one is enabled, so these connections are left with dangling handlers and crash the node on their next CM, QP or CQ event. The same connections carry that RK's KBUILD_MODNAME as restrack name of their PD and CQ, and the MRs allocated from the PD inherit it. Any "rdma resource show pd|cq|mr", which needs no privileges, reads it. The PD and CQ hang off the connection. MRs in use are on no pcs list, so they are found through the device's restrack MR table. >From a post-patch callback, rewrite the handlers of every live connection to the fuse_kio_pcs originals, and the PD, CQ and MR names to the name of the fuse_kio_pcs module itself. Afterwards nothing points into any RK module, this one included, so neither a later replace nor an unload depends on callbacks of the outgoing RK, which "kpatch replace" does not run anyway. At that point the transition is complete, so the old pcs_rdma_create() can no longer run, while the outgoing RK text is still mapped, so a racing caller still lands in valid code. The values are written unconditionally, which also repairs connections already pointing into an RK that has been unloaded. All endpoints are reached through pcs_client_list and the engine hash. Each one is fixed under ep->mutex: pcs_rdmaconnect_start() holds it from pcs_rdma_create() until ep->conn is set, every RDMA netio op runs under it, so no MR can be allocated from the PD meanwhile, and a connection is detached from ep->conn and queued on rio_destroy_list under the same mutex, so flushing rio_destroy_work afterwards covers the rest. synchronize_rcu_tasks() then waits for anyone preempted between loading an old handler and calling it. https://virtuozzo.atlassian.net/browse/VSTOR-151314 Signed-off-by: Denis V. Lunev --- fs/fuse/kio/pcs/pcs_fuse_kdirect.c | 88 ++++++++++++++++++++++++++++++ fs/fuse/kio/pcs/pcs_rdma_io.c | 44 +++++++++++++++ 2 files changed, 132 insertions(+) diff --git a/fs/fuse/kio/pcs/pcs_fuse_kdirect.c b/fs/fuse/kio/pcs/pcs_fuse_kdirect.c index 1031c43..5c7d461 100644 --- a/fs/fuse/kio/pcs/pcs_fuse_kdirect.c +++ b/fs/fuse/kio/pcs/pcs_fuse_kdirect.c @@ -2121,3 +2121,91 @@ module_exit(kpcs_mod_exit); MODULE_LICENSE("GPL v2"); MODULE_AUTHOR("Virtuozzo "); + +#include +#include "kpatch-macros.h" + +void pcs_rdma_rk_fixup_ep(struct pcs_rpc *ep, const char *name); +void pcs_rdma_rk_fixup_flush(void); + +/* + * [RK] Grab a reference to every RPC endpoint. Returns false if more + * endpoints than @cap were found, the caller has to retry then. + */ +static bool rk_collect_eps(struct pcs_rpc **eps, unsigned int cap, + unsigned int *nr) +{ + struct pcs_fuse_cluster *pfc; + struct pcs_rpc *ep; + unsigned int n = 0, i; + bool fit = true; + + spin_lock(&pcs_clients_lock); + list_for_each_entry(pfc, &pcs_client_list, list) { + struct pcs_rpc_engine *eng = &pfc->cc.eng; + + spin_lock(&eng->lock); + for (i = 0; i <= PCS_RPC_HASH_SIZE && fit; i++) { + struct hlist_head *head = i < PCS_RPC_HASH_SIZE ? + &eng->ht[i] : &eng->unhashed; + + hlist_for_each_entry(ep, head, link) { + if (n == cap) { + fit = false; + break; + } + if (atomic_inc_not_zero(&ep->refcnt)) + eps[n++] = ep; + } + } + spin_unlock(&eng->lock); + if (!fit) + break; + } + spin_unlock(&pcs_clients_lock); + + *nr = n; + return fit; +} + +static unsigned int rk_count_eps(void) +{ + struct pcs_fuse_cluster *pfc; + unsigned int n = 0; + + spin_lock(&pcs_clients_lock); + list_for_each_entry(pfc, &pcs_client_list, list) + n += READ_ONCE(pfc->cc.eng.nrpcs); + spin_unlock(&pcs_clients_lock); + + return n; +} + +static void rk_fixup_rdma(patch_object *obj) +{ + struct pcs_rpc **eps; + unsigned int cap, n, i; + bool done; + + do { + cap = rk_count_eps() + 16; + while (!(eps = kvmalloc_array(cap, sizeof(*eps), GFP_KERNEL))) + msleep(100); + + done = rk_collect_eps(eps, cap, &n); + for (i = 0; i < n; i++) { + mutex_lock(&eps[i]->mutex); + pcs_rdma_rk_fixup_ep(eps[i], obj->mod->name); + mutex_unlock(&eps[i]->mutex); + pcs_rpc_put(eps[i]); + } + kvfree(eps); + } while (!done); + + /* rio detached from its ep under ep->mutex sit here until destroyed */ + pcs_rdma_rk_fixup_flush(); + + /* Wait for anyone preempted between loading a handler and calling it */ + synchronize_rcu_tasks(); +} +KPATCH_POST_PATCH_CALLBACK(rk_fixup_rdma); diff --git a/fs/fuse/kio/pcs/pcs_rdma_io.c b/fs/fuse/kio/pcs/pcs_rdma_io.c index 67f3aad..cf12ede 100644 --- a/fs/fuse/kio/pcs/pcs_rdma_io.c +++ b/fs/fuse/kio/pcs/pcs_rdma_io.c @@ -1823,3 +1823,47 @@ struct pcs_netio_tops pcs_rdma_netio_tops = { .sync_send = pcs_rdma_sync_send, .sync_recv = pcs_rdma_sync_recv, }; + +#include "../../../../drivers/infiniband/core/restrack.h" + +/* + * [RK] Connections created while an older RK was active point to that RK's + * copies of the handlers below, and their PD, CQ and MRs carry that RK's + * KBUILD_MODNAME as restrack name. Repoint them into fuse_kio_pcs before the + * RK module is unloaded. + */ +void pcs_rdma_rk_fixup_ep(struct pcs_rpc *ep, const char *name) +{ + struct pcs_rdmaio *rio; + struct rdma_restrack_entry *res; + struct ib_pd *pd; + struct xarray *xa; + unsigned long index; + + BUG_ON(!mutex_is_locked(&ep->mutex)); + + if (!ep->conn || ((struct pcs_netio *)ep->conn)->tops != &pcs_rdma_netio_tops) + return; + + rio = rio_from_ioconn(ep->conn); + WRITE_ONCE(rio->id.event_handler, pcs_rdma_io_event_handler); + WRITE_ONCE(rio->cq->event_handler, pcs_rdma_cq_event_handler); + WRITE_ONCE(rio->cmid->qp->event_handler, pcs_rdma_qp_event_handler); + + pd = rio->dev->pd; + WRITE_ONCE(pd->res.kern_name, name); + WRITE_ONCE(rio->cq->res.kern_name, name); + + xa = &pd->device->res[RDMA_RESTRACK_MR].xa; + xa_lock(xa); + xa_for_each(xa, index, res) { + if (container_of(res, struct ib_mr, res)->pd == pd) + WRITE_ONCE(res->kern_name, name); + } + xa_unlock(xa); +} + +void pcs_rdma_rk_fixup_flush(void) +{ + flush_work(&rio_destroy_work); +} -- 2.53.0 _______________________________________________ Devel mailing list Devel@openvz.org https://lists.openvz.org/mailman/listinfo/devel