AI Trajectory


Trajectory: (Expand/Collapse All)
Seq Timestamp Type Name Duration
0/0 2026/08/23 07:38 flow patch-triage
2m Args:
null

Results:
{
  "EnableConfigs": [
    "SMC",
    "INFINIBAND",
    "DIBS",
    "DIBS_LO",
    "RDMA_RXE"
  ],
  "FocusSymbols": [
    "smcr_link_init",
    "smc_llc_cli_add_link",
    "smc_llc_srv_add_link"
  ],
  "KMSANReasoning": "The patch introduces reference counting for `smc_ib_device` objects to fix object lifetime issues (likely use-after-free). It replaces `kfree(ini)` with `smc_init_info_free(ini)`, which drops the references if they were acquired. The new boolean fields `ib_dev_ref` and `ib_dev_v2_ref` are added to `struct smc_init_info`, which is always allocated using `kzalloc` (via `kzalloc_obj`), ensuring they are properly zero-initialized. There are no new structures sent to user space, and no uninitialized memory risks are introduced or exposed. KASAN is the appropriate tool for detecting use-after-free bugs, which this patch addresses.",
  "NeedsKMSAN": false,
  "Reasoning": "The patch fixes a reference leak of `smc_ib_device` in the SMC subsystem by introducing `smc_init_info_free` and properly managing the object lifetime with reference counting (`smc_ibdev_get`/`put`). It also adds an initialization counter (`init_cnt`) to track unpublished link initializations. The changes affect connection establishment (`__smc_connect`, `smc_listen_work`) and LLC link management (`smc_llc_cli_add_link`, `smc_llc_srv_add_link`). These paths are reachable from userspace via socket operations and incoming network packets. To properly test this, we need to enable SMC, InfiniBand, and software-emulated RDMA/DIBS devices (`RDMA_RXE`, `DIBS_LO`).",
  "WorthFuzzing": true
}

1/1 2026/08/23 07:38 action read-patch-diff
0m Args:
null

Results:
{
  "PatchDiff": "commit 777f30715c6d50544d6f80c030ab5bbb11c9142b\nAuthor: syz-cluster \u003ctriage@syzkaller.com\u003e\nDate:   Sun Aug 23 07:38:50 2026 +0000\n\n    syz-cluster: applied patch under review\n\ndiff --git a/net/smc/af_smc.c b/net/smc/af_smc.c\nindex e9f93b3ab435b..d781dee1b3293 100644\n--- a/net/smc/af_smc.c\n+++ b/net/smc/af_smc.c\n@@ -1225,7 +1225,7 @@ void smc_fill_gid_list(struct smc_link_group *lgr,\n \t       SMC_GID_SIZE);\n \n out:\n-\tkfree(alt_ini);\n+\tsmc_init_info_free(alt_ini);\n }\n \n static int smc_connect_rdma_v2_prepare(struct smc_sock *smc,\n@@ -1596,14 +1596,14 @@ static int __smc_connect(struct smc_sock *smc)\n \tSMC_STAT_CLNT_SUCC_INC(sock_net(smc-\u003eclcsock-\u003esk), aclc);\n \tsmc_connect_ism_vlan_cleanup(ini);\n \tkfree(buf);\n-\tkfree(ini);\n+\tsmc_init_info_free(ini);\n \treturn 0;\n \n vlan_cleanup:\n \tsmc_connect_ism_vlan_cleanup(ini);\n \tkfree(buf);\n fallback:\n-\tkfree(ini);\n+\tsmc_init_info_free(ini);\n \treturn smc_connect_decline_fallback(smc, rc, version);\n }\n \n@@ -2344,7 +2344,10 @@ static void smc_find_rdma_v2_device_serv(struct smc_sock *new_smc,\n \n not_found:\n \tini-\u003esmcr_version \u0026= ~SMC_V2;\n+\tif (ini-\u003esmcrv2.ib_dev_v2_ref)\n+\t\tsmc_ibdev_put(ini-\u003esmcrv2.ib_dev_v2);\n \tini-\u003esmcrv2.ib_dev_v2 = NULL;\n+\tini-\u003esmcrv2.ib_dev_v2_ref = false;\n \tini-\u003echeck_smcrv2 = false;\n }\n \n@@ -2588,7 +2591,7 @@ static void smc_listen_work(struct work_struct *work)\n \tsmc_listen_decline(new_smc, rc, ini ? ini-\u003efirst_contact_local : 0,\n \t\t\t   proposal_version);\n out_free:\n-\tkfree(ini);\n+\tsmc_init_info_free(ini);\n \tkfree(buf);\n }\n \ndiff --git a/net/smc/smc_core.c b/net/smc/smc_core.c\nindex 181647982490b..d97bc73231069 100644\n--- a/net/smc/smc_core.c\n+++ b/net/smc/smc_core.c\n@@ -55,6 +55,17 @@ static void __smc_lgr_terminate(struct smc_link_group *lgr, bool soft);\n \n static void smc_link_down_work(struct work_struct *work);\n \n+void smc_init_info_free(struct smc_init_info *ini)\n+{\n+\tif (!ini)\n+\t\treturn;\n+\tif (ini-\u003eib_dev_ref)\n+\t\tsmc_ibdev_put(ini-\u003eib_dev);\n+\tif (ini-\u003esmcrv2.ib_dev_v2_ref)\n+\t\tsmc_ibdev_put(ini-\u003esmcrv2.ib_dev_v2);\n+\tkfree(ini);\n+}\n+\n /* return head of link group list and its lock for a given link group */\n static inline struct list_head *smc_lgr_list_head(struct smc_link_group *lgr,\n \t\t\t\t\t\t  spinlock_t **lgr_lock)\n@@ -793,14 +804,21 @@ int smcr_link_init(struct smc_link_group *lgr, struct smc_link *lnk,\n \tint rc;\n \n \tif (lgr-\u003esmc_version == SMC_V2) {\n-\t\tlnk-\u003esmcibdev = ini-\u003esmcrv2.ib_dev_v2;\n+\t\tsmcibdev = ini-\u003esmcrv2.ib_dev_v2;\n \t\tlnk-\u003eibport = ini-\u003esmcrv2.ib_port_v2;\n-\t\tlnk-\u003ewr_rx_sge_cnt = lnk-\u003esmcibdev-\u003eibdev-\u003eattrs.max_recv_sge \u003c 2 ? 1 : 2;\n+\t} else {\n+\t\tsmcibdev = ini-\u003eib_dev;\n+\t\tlnk-\u003eibport = ini-\u003eib_port;\n+\t}\n+\trc = smc_ibdev_init_begin(smcibdev);\n+\tif (rc)\n+\t\treturn rc;\n+\tlnk-\u003esmcibdev = smcibdev;\n+\tif (lgr-\u003esmc_version == SMC_V2) {\n+\t\tlnk-\u003ewr_rx_sge_cnt = smcibdev-\u003eibdev-\u003eattrs.max_recv_sge \u003c 2 ? 1 : 2;\n \t\tlnk-\u003ewr_rx_buflen = smc_link_shared_v2_rxbuf(lnk) ?\n \t\t\tSMC_WR_BUF_SIZE : SMC_WR_BUF_V2_SIZE;\n \t} else {\n-\t\tlnk-\u003esmcibdev = ini-\u003eib_dev;\n-\t\tlnk-\u003eibport = ini-\u003eib_port;\n \t\tlnk-\u003ewr_rx_sge_cnt = 1;\n \t\tlnk-\u003ewr_rx_buflen = SMC_WR_BUF_SIZE;\n \t}\n@@ -882,6 +900,7 @@ int smcr_link_init(struct smc_link_group *lgr, struct smc_link *lnk,\n \tif (!atomic_dec_return(\u0026smcibdev-\u003elnk_cnt))\n \t\twake_up(\u0026smcibdev-\u003elnks_deleted);\n \tsmc_lgr_put(lgr); /* lgr_hold above */\n+\tsmc_ibdev_init_end(smcibdev);\n \treturn rc;\n }\n \n@@ -997,6 +1016,8 @@ static int smc_lgr_create(struct smc_sock *smc, struct smc_init_info *ini)\n \tspin_lock_bh(lgr_lock);\n \tlist_add_tail(\u0026lgr-\u003elist, lgr_list);\n \tspin_unlock_bh(lgr_lock);\n+\tif (!ini-\u003eis_smcd)\n+\t\tsmc_ibdev_init_end(lnk-\u003esmcibdev);\n \treturn 0;\n \n free_wq:\ndiff --git a/net/smc/smc_core.h b/net/smc/smc_core.h\nindex 5c18f08a4c8a5..9f5a69a30cb3f 100644\n--- a/net/smc/smc_core.h\n+++ b/net/smc/smc_core.h\n@@ -403,6 +403,7 @@ struct smc_init_info_smcrv2 {\n \n \t/* Output fields when saddr is set */\n \tstruct smc_ib_device\t*ib_dev_v2;\n+\tbool\t\t\tib_dev_v2_ref; /* owns an smc_ibdev reference */\n \tu8\t\t\tib_port_v2;\n \tu8\t\t\tib_gid_v2[SMC_GID_SIZE];\n \n@@ -438,6 +439,7 @@ struct smc_init_info {\n \tu8\t\t\tpeer_mac[ETH_ALEN];\n \tu8\t\t\tpeer_systemid[SMC_SYSTEMID_LEN];\n \tstruct smc_ib_device\t*ib_dev;\n+\tbool\t\t\tib_dev_ref; /* owns an smc_ibdev reference */\n \tu8\t\t\tib_gid[SMC_GID_SIZE];\n \tu8\t\t\tib_port;\n \tu32\t\t\tib_clcqpn;\n@@ -594,6 +596,7 @@ void smc_rtoken_set2(struct smc_link_group *lgr, int rtok_idx, int link_id,\n void smc_sndbuf_sync_sg_for_device(struct smc_connection *conn);\n void smc_rmb_sync_sg_for_cpu(struct smc_connection *conn);\n int smc_vlan_by_tcpsk(struct socket *clcsock, struct smc_init_info *ini);\n+void smc_init_info_free(struct smc_init_info *ini);\n \n void smc_conn_free(struct smc_connection *conn);\n int smc_conn_create(struct smc_sock *smc, struct smc_init_info *ini);\ndiff --git a/net/smc/smc_ib.c b/net/smc/smc_ib.c\nindex 9bb495707445e..d858453c64d92 100644\n--- a/net/smc/smc_ib.c\n+++ b/net/smc/smc_ib.c\n@@ -934,6 +934,44 @@ void smc_ib_ndev_change(struct net_device *ndev, unsigned long event)\n \tmutex_unlock(\u0026smc_ib_devices.mutex);\n }\n \n+static void smc_ibdev_release(struct smc_ib_device *smcibdev)\n+{\n+\tput_device(\u0026smcibdev-\u003eibdev-\u003edev);\n+\tkfree(smcibdev);\n+}\n+\n+void smc_ibdev_get(struct smc_ib_device *smcibdev)\n+{\n+\trefcount_inc(\u0026smcibdev-\u003erefcnt);\n+}\n+\n+void smc_ibdev_put(struct smc_ib_device *smcibdev)\n+{\n+\tif (refcount_dec_and_test(\u0026smcibdev-\u003erefcnt))\n+\t\tsmc_ibdev_release(smcibdev);\n+}\n+\n+int smc_ibdev_init_begin(struct smc_ib_device *smcibdev)\n+{\n+\tint rc = 0;\n+\n+\tmutex_lock(\u0026smc_ib_devices.mutex);\n+\tif (list_empty(\u0026smcibdev-\u003elist))\n+\t\trc = -ENODEV;\n+\telse\n+\t\tatomic_inc(\u0026smcibdev-\u003einit_cnt);\n+\tmutex_unlock(\u0026smc_ib_devices.mutex);\n+\treturn rc;\n+}\n+\n+void smc_ibdev_init_end(struct smc_ib_device *smcibdev)\n+{\n+\tmutex_lock(\u0026smc_ib_devices.mutex);\n+\tif (atomic_dec_and_test(\u0026smcibdev-\u003einit_cnt))\n+\t\twake_up(\u0026smcibdev-\u003einit_wait);\n+\tmutex_unlock(\u0026smc_ib_devices.mutex);\n+}\n+\n /* callback function for ib_register_client() */\n static int smc_ib_add_dev(struct ib_device *ibdev)\n {\n@@ -949,7 +987,11 @@ static int smc_ib_add_dev(struct ib_device *ibdev)\n \t\treturn -ENOMEM;\n \n \tsmcibdev-\u003eibdev = ibdev;\n+\tget_device(\u0026ibdev-\u003edev);\n+\trefcount_set(\u0026smcibdev-\u003erefcnt, 1);\n \tINIT_WORK(\u0026smcibdev-\u003eport_event_work, smc_ib_port_event_work);\n+\tatomic_set(\u0026smcibdev-\u003einit_cnt, 0);\n+\tinit_waitqueue_head(\u0026smcibdev-\u003einit_wait);\n \tatomic_set(\u0026smcibdev-\u003elnk_cnt, 0);\n \tinit_waitqueue_head(\u0026smcibdev-\u003elnks_deleted);\n \tmutex_init(\u0026smcibdev-\u003emutex);\n@@ -1000,11 +1042,14 @@ static void smc_ib_remove_dev(struct ib_device *ibdev, void *client_data)\n \tmutex_unlock(\u0026smc_ib_devices.mutex);\n \tpr_warn_ratelimited(\"smc: removing ib device %s\\n\",\n \t\t\t    smcibdev-\u003eibdev-\u003ename);\n+\tif (atomic_read(\u0026smcibdev-\u003einit_cnt))\n+\t\twait_event(smcibdev-\u003einit_wait,\n+\t\t\t   !atomic_read(\u0026smcibdev-\u003einit_cnt));\n \tsmc_smcr_terminate_all(smcibdev);\n \tsmc_ib_cleanup_per_ibdev(smcibdev);\n \tib_unregister_event_handler(\u0026smcibdev-\u003eevent_handler);\n \tcancel_work_sync(\u0026smcibdev-\u003eport_event_work);\n-\tkfree(smcibdev);\n+\tsmc_ibdev_put(smcibdev);\n }\n \n static struct ib_client smc_ib_client = {\ndiff --git a/net/smc/smc_ib.h b/net/smc/smc_ib.h\nindex ef8ac2b7546df..d32547350e8b8 100644\n--- a/net/smc/smc_ib.h\n+++ b/net/smc/smc_ib.h\n@@ -15,6 +15,7 @@\n #include \u003clinux/interrupt.h\u003e\n #include \u003clinux/if_ether.h\u003e\n #include \u003clinux/mutex.h\u003e\n+#include \u003clinux/refcount.h\u003e\n #include \u003clinux/wait.h\u003e\n #include \u003crdma/ib_verbs.h\u003e\n #include \u003cnet/smc.h\u003e\n@@ -51,6 +52,9 @@ struct smc_ib_device {\t\t\t\t/* ib-device infos for smc */\n \tstruct work_struct\tport_event_work;\n \tunsigned long\t\tport_event_mask;\n \tDECLARE_BITMAP(ports_going_away, SMC_MAX_PORTS);\n+\trefcount_t\t\trefcnt;\t\t/* object lifetime */\n+\tatomic_t\t\tinit_cnt;\t/* unpublished link initializations */\n+\twait_queue_head_t\tinit_wait;\t/* wait for links to be published */\n \tatomic_t\t\tlnk_cnt;\t/* number of links on ibdev */\n \twait_queue_head_t\tlnks_deleted;\t/* wait 4 removal of all links*/\n \tstruct mutex\t\tmutex;\t\t/* protect dev setup+cleanup */\n@@ -59,6 +63,11 @@ struct smc_ib_device {\t\t\t\t/* ib-device infos for smc */\n \tint\t\t\tndev_ifidx[SMC_MAX_PORTS]; /* ndev if indexes */\n };\n \n+void smc_ibdev_get(struct smc_ib_device *smcibdev);\n+void smc_ibdev_put(struct smc_ib_device *smcibdev);\n+int smc_ibdev_init_begin(struct smc_ib_device *smcibdev);\n+void smc_ibdev_init_end(struct smc_ib_device *smcibdev);\n+\n static inline __be32 smc_ib_gid_to_ipv4(u8 gid[SMC_GID_SIZE])\n {\n \tstruct in6_addr *addr6 = (struct in6_addr *)gid;\ndiff --git a/net/smc/smc_llc.c b/net/smc/smc_llc.c\nindex c9ccd8480369c..e16aaa514368a 100644\n--- a/net/smc/smc_llc.c\n+++ b/net/smc/smc_llc.c\n@@ -1108,6 +1108,7 @@ int smc_llc_cli_add_link(struct smc_link *link, struct smc_llc_qentry *qentry)\n \trc = smcr_link_init(lgr, lnk_new, lnk_idx, ini);\n \tif (rc)\n \t\tgoto out_reject;\n+\tsmc_ibdev_init_end(lnk_new-\u003esmcibdev);\n \tsmc_llc_save_add_link_info(lnk_new, llc);\n \tlnk_new-\u003elink_id = llc-\u003elink_num;\t/* SMC server assigns link id */\n \tsmc_llc_link_set_uid(lnk_new);\n@@ -1143,7 +1144,7 @@ int smc_llc_cli_add_link(struct smc_link *link, struct smc_llc_qentry *qentry)\n out_reject:\n \tsmc_llc_cli_add_link_reject(qentry);\n out:\n-\tkfree(ini);\n+\tsmc_init_info_free(ini);\n \tkfree(qentry);\n \treturn rc;\n }\n@@ -1217,7 +1218,7 @@ static void smc_llc_cli_add_link_invite(struct smc_link *link,\n \tsmc_llc_send_add_link(link, ini-\u003eib_dev-\u003emac[ini-\u003eib_port - 1],\n \t\t\t      ini-\u003eib_gid, NULL, SMC_LLC_REQ);\n out:\n-\tkfree(ini);\n+\tsmc_init_info_free(ini);\n \tkfree(qentry);\n }\n \n@@ -1487,6 +1488,7 @@ int smc_llc_srv_add_link(struct smc_link *link,\n \tif (rc)\n \t\tgoto out;\n \tlink_new = \u0026lgr-\u003elnk[lnk_idx];\n+\tsmc_ibdev_init_end(link_new-\u003esmcibdev);\n \n \trc = smcr_buf_map_lgr(link_new);\n \tif (rc)\n@@ -1544,7 +1546,7 @@ int smc_llc_srv_add_link(struct smc_link *link,\n \t}\n out:\n \tkfree(qentry);\n-\tkfree(ini);\n+\tsmc_init_info_free(ini);\n \tif (send_req_add_link_resp)\n \t\tsmc_llc_send_req_add_link_response(req_qentry);\n \treturn rc;\ndiff --git a/net/smc/smc_pnet.c b/net/smc/smc_pnet.c\nindex 63e286e2dfaa8..be1f5137c8ee7 100644\n--- a/net/smc/smc_pnet.c\n+++ b/net/smc/smc_pnet.c\n@@ -980,14 +980,22 @@ static int smc_pnet_determine_gid(struct smc_ib_device *ibdev, int i,\n \tif (!ini-\u003echeck_smcrv2 \u0026\u0026\n \t    !smc_ib_determine_gid(ibdev, i, ini-\u003evlan_id, ini-\u003eib_gid, NULL,\n \t\t\t\t  NULL)) {\n+\t\tif (ini-\u003eib_dev_ref)\n+\t\t\tsmc_ibdev_put(ini-\u003eib_dev);\n+\t\tsmc_ibdev_get(ibdev);\n \t\tini-\u003eib_dev = ibdev;\n+\t\tini-\u003eib_dev_ref = true;\n \t\tini-\u003eib_port = i;\n \t\treturn 0;\n \t}\n \tif (ini-\u003echeck_smcrv2 \u0026\u0026\n \t    !smc_ib_determine_gid(ibdev, i, ini-\u003evlan_id, ini-\u003esmcrv2.ib_gid_v2,\n \t\t\t\t  NULL, \u0026ini-\u003esmcrv2)) {\n+\t\tif (ini-\u003esmcrv2.ib_dev_v2_ref)\n+\t\t\tsmc_ibdev_put(ini-\u003esmcrv2.ib_dev_v2);\n+\t\tsmc_ibdev_get(ibdev);\n \t\tini-\u003esmcrv2.ib_dev_v2 = ibdev;\n+\t\tini-\u003esmcrv2.ib_dev_v2_ref = true;\n \t\tini-\u003esmcrv2.ib_port_v2 = i;\n \t\treturn 0;\n \t}\n"
}

2/1 2026/08/23 07:38 agent patch-evaluator
1m Model:
best-expensive

Args:
null

Results:
{
  "EnableConfigs": [
    "SMC",
    "INFINIBAND",
    "DIBS",
    "DIBS_LO",
    "RDMA_RXE"
  ],
  "FocusSymbols": [
    "smcr_link_init",
    "smc_llc_cli_add_link",
    "smc_llc_srv_add_link"
  ],
  "Reasoning": "The patch fixes a reference leak of `smc_ib_device` in the SMC subsystem by introducing `smc_init_info_free` and properly managing the object lifetime with reference counting (`smc_ibdev_get`/`put`). It also adds an initialization counter (`init_cnt`) to track unpublished link initializations. The changes affect connection establishment (`__smc_connect`, `smc_listen_work`) and LLC link management (`smc_llc_cli_add_link`, `smc_llc_srv_add_link`). These paths are reachable from userspace via socket operations and incoming network packets. To properly test this, we need to enable SMC, InfiniBand, and software-emulated RDMA/DIBS devices (`RDMA_RXE`, `DIBS_LO`).",
  "WorthFuzzing": true
}

Instruction:
You are an expert Linux kernel maintainer.
Your job is to review a provided patch series and determine
if it makes functional changes to the kernel that should be fuzzed.

IMPORTANT: The changes have ALREADY been applied and committed as the HEAD commit in
your workspace. Do NOT rely on your internal knowledge of the kernel. You must actively
use your code access tools to examine the actual source code and confirm any assumptions.

Return WorthFuzzing=false if the patch only contains:
- Modifications to Documentation/, Kconfig files, or code comments.
- Purely decorative changes, such as logging (e.g., pr_err, printk) or tracepoints.
- Changes to numeric constants or macros that do not functionally alter execution flow.
- Code paths that are impossible to reach in virtualized environments like GCE or QEMU,
  even when utilizing software-emulated hardware (e.g., usb gadget, mac80211_hwsim).
- Code in vendor-specific PCIe switch, SmartNIC, or GPU drivers (e.g., mlxsw, pds_core, qed,
  ionic, amdgpu) that require physical PCIe hardware cards not emulated in standard QEMU.
- Driver .remove, .shutdown, or pci_unregister_driver teardown callbacks (e.g., igb_remove)
  that are executed only during PCI hot-unplug or sysfs driver unbind operations.

If it modifies reachable core kernel logic, drivers, or architectures, use your code search
tools to verify the code can be executed, then return WorthFuzzing=true.

When returning WorthFuzzing=true, you MUST ALSO:
1. Extract any specific kernel functions that should be heavily fuzzed into FocusSymbols.
   Avoid listing generic hot-path functions to prevent skewed test distributions.
   Prefer non-static, non-inlined API entrypoint functions over internal static helper functions
   (which are inlined by the compiler and do not have distinct symbol addresses).
2. Identify any specific CONFIG_ options required to properly test this new/modified feature.
   Go and look into the Kconfig files and check for ifdefs around the code, do not make assumptions.
   Also check "depends on" lines in Kconfig to include any non-standard parent subsystem configs
   needed for Kbuild to compile the code statically into vmlinux. List them in the EnableConfigs
   output array, and DO NOT add a 'CONFIG_' prefix (e.g., return "NET_IPV4" instead of "CONFIG_NET_IPV4").
Prefer calling several tools at the same time to save round-trips.


Use set-results tool to provide results of the analysis.
It must be called exactly once before the final reply.
Ignore results of this tool.

Prompt:
For your convenience, here is the diff of the changes:
commit 777f30715c6d50544d6f80c030ab5bbb11c9142b
Author: syz-cluster <triage@syzkaller.com>
Date:   Sun Aug 23 07:38:50 2026 +0000

    syz-cluster: applied patch under review

diff --git a/net/smc/af_smc.c b/net/smc/af_smc.c
index e9f93b3ab435b..d781dee1b3293 100644
--- a/net/smc/af_smc.c
+++ b/net/smc/af_smc.c
@@ -1225,7 +1225,7 @@ void smc_fill_gid_list(struct smc_link_group *lgr,
 	       SMC_GID_SIZE);
 
 out:
-	kfree(alt_ini);
+	smc_init_info_free(alt_ini);
 }
 
 static int smc_connect_rdma_v2_prepare(struct smc_sock *smc,
@@ -1596,14 +1596,14 @@ static int __smc_connect(struct smc_sock *smc)
 	SMC_STAT_CLNT_SUCC_INC(sock_net(smc->clcsock->sk), aclc);
 	smc_connect_ism_vlan_cleanup(ini);
 	kfree(buf);
-	kfree(ini);
+	smc_init_info_free(ini);
 	return 0;
 
 vlan_cleanup:
 	smc_connect_ism_vlan_cleanup(ini);
 	kfree(buf);
 fallback:
-	kfree(ini);
+	smc_init_info_free(ini);
 	return smc_connect_decline_fallback(smc, rc, version);
 }
 
@@ -2344,7 +2344,10 @@ static void smc_find_rdma_v2_device_serv(struct smc_sock *new_smc,
 
 not_found:
 	ini->smcr_version &= ~SMC_V2;
+	if (ini->smcrv2.ib_dev_v2_ref)
+		smc_ibdev_put(ini->smcrv2.ib_dev_v2);
 	ini->smcrv2.ib_dev_v2 = NULL;
+	ini->smcrv2.ib_dev_v2_ref = false;
 	ini->check_smcrv2 = false;
 }
 
@@ -2588,7 +2591,7 @@ static void smc_listen_work(struct work_struct *work)
 	smc_listen_decline(new_smc, rc, ini ? ini->first_contact_local : 0,
 			   proposal_version);
 out_free:
-	kfree(ini);
+	smc_init_info_free(ini);
 	kfree(buf);
 }
 
diff --git a/net/smc/smc_core.c b/net/smc/smc_core.c
index 181647982490b..d97bc73231069 100644
--- a/net/smc/smc_core.c
+++ b/net/smc/smc_core.c
@@ -55,6 +55,17 @@ static void __smc_lgr_terminate(struct smc_link_group *lgr, bool soft);
 
 static void smc_link_down_work(struct work_struct *work);
 
+void smc_init_info_free(struct smc_init_info *ini)
+{
+	if (!ini)
+		return;
+	if (ini->ib_dev_ref)
+		smc_ibdev_put(ini->ib_dev);
+	if (ini->smcrv2.ib_dev_v2_ref)
+		smc_ibdev_put(ini->smcrv2.ib_dev_v2);
+	kfree(ini);
+}
+
 /* return head of link group list and its lock for a given link group */
 static inline struct list_head *smc_lgr_list_head(struct smc_link_group *lgr,
 						  spinlock_t **lgr_lock)
@@ -793,14 +804,21 @@ int smcr_link_init(struct smc_link_group *lgr, struct smc_link *lnk,
 	int rc;
 
 	if (lgr->smc_version == SMC_V2) {
-		lnk->smcibdev = ini->smcrv2.ib_dev_v2;
+		smcibdev = ini->smcrv2.ib_dev_v2;
 		lnk->ibport = ini->smcrv2.ib_port_v2;
-		lnk->wr_rx_sge_cnt = lnk->smcibdev->ibdev->attrs.max_recv_sge < 2 ? 1 : 2;
+	} else {
+		smcibdev = ini->ib_dev;
+		lnk->ibport = ini->ib_port;
+	}
+	rc = smc_ibdev_init_begin(smcibdev);
+	if (rc)
+		return rc;
+	lnk->smcibdev = smcibdev;
+	if (lgr->smc_version == SMC_V2) {
+		lnk->wr_rx_sge_cnt = smcibdev->ibdev->attrs.max_recv_sge < 2 ? 1 : 2;
 		lnk->wr_rx_buflen = smc_link_shared_v2_rxbuf(lnk) ?
 			SMC_WR_BUF_SIZE : SMC_WR_BUF_V2_SIZE;
 	} else {
-		lnk->smcibdev = ini->ib_dev;
-		lnk->ibport = ini->ib_port;
 		lnk->wr_rx_sge_cnt = 1;
 		lnk->wr_rx_buflen = SMC_WR_BUF_SIZE;
 	}
@@ -882,6 +900,7 @@ int smcr_link_init(struct smc_link_group *lgr, struct smc_link *lnk,
 	if (!atomic_dec_return(&smcibdev->lnk_cnt))
 		wake_up(&smcibdev->lnks_deleted);
 	smc_lgr_put(lgr); /* lgr_hold above */
+	smc_ibdev_init_end(smcibdev);
 	return rc;
 }
 
@@ -997,6 +1016,8 @@ static int smc_lgr_create(struct smc_sock *smc, struct smc_init_info *ini)
 	spin_lock_bh(lgr_lock);
 	list_add_tail(&lgr->list, lgr_list);
 	spin_unlock_bh(lgr_lock);
+	if (!ini->is_smcd)
+		smc_ibdev_init_end(lnk->smcibdev);
 	return 0;
 
 free_wq:
diff --git a/net/smc/smc_core.h b/net/smc/smc_core.h
index 5c18f08a4c8a5..9f5a69a30cb3f 100644
--- a/net/smc/smc_core.h
+++ b/net/smc/smc_core.h
@@ -403,6 +403,7 @@ struct smc_init_info_smcrv2 {
 
 	/* Output fields when saddr is set */
 	struct smc_ib_device	*ib_dev_v2;
+	bool			ib_dev_v2_ref; /* owns an smc_ibdev reference */
 	u8			ib_port_v2;
 	u8			ib_gid_v2[SMC_GID_SIZE];
 
@@ -438,6 +439,7 @@ struct smc_init_info {
 	u8			peer_mac[ETH_ALEN];
 	u8			peer_systemid[SMC_SYSTEMID_LEN];
 	struct smc_ib_device	*ib_dev;
+	bool			ib_dev_ref; /* owns an smc_ibdev reference */
 	u8			ib_gid[SMC_GID_SIZE];
 	u8			ib_port;
 	u32			ib_clcqpn;
@@ -594,6 +596,7 @@ void smc_rtoken_set2(struct smc_link_group *lgr, int rtok_idx, int link_id,
 void smc_sndbuf_sync_sg_for_device(struct smc_connection *conn);
 void smc_rmb_sync_sg_for_cpu(struct smc_connection *conn);
 int smc_vlan_by_tcpsk(struct socket *clcsock, struct smc_init_info *ini);
+void smc_init_info_free(struct smc_init_info *ini);
 
 void smc_conn_free(struct smc_connection *conn);
 int smc_conn_create(struct smc_sock *smc, struct smc_init_info *ini);
diff --git a/net/smc/smc_ib.c b/net/smc/smc_ib.c
index 9bb495707445e..d858453c64d92 100644
--- a/net/smc/smc_ib.c
+++ b/net/smc/smc_ib.c
@@ -934,6 +934,44 @@ void smc_ib_ndev_change(struct net_device *ndev, unsigned long event)
 	mutex_unlock(&smc_ib_devices.mutex);
 }
 
+static void smc_ibdev_release(struct smc_ib_device *smcibdev)
+{
+	put_device(&smcibdev->ibdev->dev);
+	kfree(smcibdev);
+}
+
+void smc_ibdev_get(struct smc_ib_device *smcibdev)
+{
+	refcount_inc(&smcibdev->refcnt);
+}
+
+void smc_ibdev_put(struct smc_ib_device *smcibdev)
+{
+	if (refcount_dec_and_test(&smcibdev->refcnt))
+		smc_ibdev_release(smcibdev);
+}
+
+int smc_ibdev_init_begin(struct smc_ib_device *smcibdev)
+{
+	int rc = 0;
+
+	mutex_lock(&smc_ib_devices.mutex);
+	if (list_empty(&smcibdev->list))
+		rc = -ENODEV;
+	else
+		atomic_inc(&smcibdev->init_cnt);
+	mutex_unlock(&smc_ib_devices.mutex);
+	return rc;
+}
+
+void smc_ibdev_init_end(struct smc_ib_device *smcibdev)
+{
+	mutex_lock(&smc_ib_devices.mutex);
+	if (atomic_dec_and_test(&smcibdev->init_cnt))
+		wake_up(&smcibdev->init_wait);
+	mutex_unlock(&smc_ib_devices.mutex);
+}
+
 /* callback function for ib_register_client() */
 static int smc_ib_add_dev(struct ib_device *ibdev)
 {
@@ -949,7 +987,11 @@ static int smc_ib_add_dev(struct ib_device *ibdev)
 		return -ENOMEM;
 
 	smcibdev->ibdev = ibdev;
+	get_device(&ibdev->dev);
+	refcount_set(&smcibdev->refcnt, 1);
 	INIT_WORK(&smcibdev->port_event_work, smc_ib_port_event_work);
+	atomic_set(&smcibdev->init_cnt, 0);
+	init_waitqueue_head(&smcibdev->init_wait);
 	atomic_set(&smcibdev->lnk_cnt, 0);
 	init_waitqueue_head(&smcibdev->lnks_deleted);
 	mutex_init(&smcibdev->mutex);
@@ -1000,11 +1042,14 @@ static void smc_ib_remove_dev(struct ib_device *ibdev, void *client_data)
 	mutex_unlock(&smc_ib_devices.mutex);
 	pr_warn_ratelimited("smc: removing ib device %s\n",
 			    smcibdev->ibdev->name);
+	if (atomic_read(&smcibdev->init_cnt))
+		wait_event(smcibdev->init_wait,
+			   !atomic_read(&smcibdev->init_cnt));
 	smc_smcr_terminate_all(smcibdev);
 	smc_ib_cleanup_per_ibdev(smcibdev);
 	ib_unregister_event_handler(&smcibdev->event_handler);
 	cancel_work_sync(&smcibdev->port_event_work);
-	kfree(smcibdev);
+	smc_ibdev_put(smcibdev);
 }
 
 static struct ib_client smc_ib_client = {
diff --git a/net/smc/smc_ib.h b/net/smc/smc_ib.h
index ef8ac2b7546df..d32547350e8b8 100644
--- a/net/smc/smc_ib.h
+++ b/net/smc/smc_ib.h
@@ -15,6 +15,7 @@
 #include <linux/interrupt.h>
 #include <linux/if_ether.h>
 #include <linux/mutex.h>
+#include <linux/refcount.h>
 #include <linux/wait.h>
 #include <rdma/ib_verbs.h>
 #include <net/smc.h>
@@ -51,6 +52,9 @@ struct smc_ib_device {				/* ib-device infos for smc */
 	struct work_struct	port_event_work;
 	unsigned long		port_event_mask;
 	DECLARE_BITMAP(ports_going_away, SMC_MAX_PORTS);
+	refcount_t		refcnt;		/* object lifetime */
+	atomic_t		init_cnt;	/* unpublished link initializations */
+	wait_queue_head_t	init_wait;	/* wait for links to be published */
 	atomic_t		lnk_cnt;	/* number of links on ibdev */
 	wait_queue_head_t	lnks_deleted;	/* wait 4 removal of all links*/
 	struct mutex		mutex;		/* protect dev setup+cleanup */
@@ -59,6 +63,11 @@ struct smc_ib_device {				/* ib-device infos for smc */
 	int			ndev_ifidx[SMC_MAX_PORTS]; /* ndev if indexes */
 };
 
+void smc_ibdev_get(struct smc_ib_device *smcibdev);
+void smc_ibdev_put(struct smc_ib_device *smcibdev);
+int smc_ibdev_init_begin(struct smc_ib_device *smcibdev);
+void smc_ibdev_init_end(struct smc_ib_device *smcibdev);
+
 static inline __be32 smc_ib_gid_to_ipv4(u8 gid[SMC_GID_SIZE])
 {
 	struct in6_addr *addr6 = (struct in6_addr *)gid;
diff --git a/net/smc/smc_llc.c b/net/smc/smc_llc.c
index c9ccd8480369c..e16aaa514368a 100644
--- a/net/smc/smc_llc.c
+++ b/net/smc/smc_llc.c
@@ -1108,6 +1108,7 @@ int smc_llc_cli_add_link(struct smc_link *link, struct smc_llc_qentry *qentry)
 	rc = smcr_link_init(lgr, lnk_new, lnk_idx, ini);
 	if (rc)
 		goto out_reject;
+	smc_ibdev_init_end(lnk_new->smcibdev);
 	smc_llc_save_add_link_info(lnk_new, llc);
 	lnk_new->link_id = llc->link_num;	/* SMC server assigns link id */
 	smc_llc_link_set_uid(lnk_new);
@@ -1143,7 +1144,7 @@ int smc_llc_cli_add_link(struct smc_link *link, struct smc_llc_qentry *qentry)
 out_reject:
 	smc_llc_cli_add_link_reject(qentry);
 out:
-	kfree(ini);
+	smc_init_info_free(ini);
 	kfree(qentry);
 	return rc;
 }
@@ -1217,7 +1218,7 @@ static void smc_llc_cli_add_link_invite(struct smc_link *link,
 	smc_llc_send_add_link(link, ini->ib_dev->mac[ini->ib_port - 1],
 			      ini->ib_gid, NULL, SMC_LLC_REQ);
 out:
-	kfree(ini);
+	smc_init_info_free(ini);
 	kfree(qentry);
 }
 
@@ -1487,6 +1488,7 @@ int smc_llc_srv_add_link(struct smc_link *link,
 	if (rc)
 		goto out;
 	link_new = &lgr->lnk[lnk_idx];
+	smc_ibdev_init_end(link_new->smcibdev);
 
 	rc = smcr_buf_map_lgr(link_new);
 	if (rc)
@@ -1544,7 +1546,7 @@ int smc_llc_srv_add_link(struct smc_link *link,
 	}
 out:
 	kfree(qentry);
-	kfree(ini);
+	smc_init_info_free(ini);
 	if (send_req_add_link_resp)
 		smc_llc_send_req_add_link_response(req_qentry);
 	return rc;
diff --git a/net/smc/smc_pnet.c b/net/smc/smc_pnet.c
index 63e286e2dfaa8..be1f5137c8ee7 100644
--- a/net/smc/smc_pnet.c
+++ b/net/smc/smc_pnet.c
@@ -980,14 +980,22 @@ static int smc_pnet_determine_gid(struct smc_ib_device *ibdev, int i,
 	if (!ini->check_smcrv2 &&
 	    !smc_ib_determine_gid(ibdev, i, ini->vlan_id, ini->ib_gid, NULL,
 				  NULL)) {
+		if (ini->ib_dev_ref)
+			smc_ibdev_put(ini->ib_dev);
+		smc_ibdev_get(ibdev);
 		ini->ib_dev = ibdev;
+		ini->ib_dev_ref = true;
 		ini->ib_port = i;
 		return 0;
 	}
 	if (ini->check_smcrv2 &&
 	    !smc_ib_determine_gid(ibdev, i, ini->vlan_id, ini->smcrv2.ib_gid_v2,
 				  NULL, &ini->smcrv2)) {
+		if (ini->smcrv2.ib_dev_v2_ref)
+			smc_ibdev_put(ini->smcrv2.ib_dev_v2);
+		smc_ibdev_get(ibdev);
 		ini->smcrv2.ib_dev_v2 = ibdev;
+		ini->smcrv2.ib_dev_v2_ref = true;
 		ini->smcrv2.ib_port_v2 = i;
 		return 0;
 	}

3/2 2026/08/23 07:38 llm patch-evaluator
0m Model:
gemini-3.1-pro-preview

Args:
null

Results:
null

Tokens:
							input: 7002
							output: 29
							thoughts: 294
						

Thoughts:
**My Initial Thoughts on This Patch**

Okay, so I'm looking at a patch that's touching a decent chunk of the SMC code – `af_smc.c`, `smc_core.c`, `smc_core.h`, `smc_ib.c`, `smc_ib.h`, `smc_llc.c`, and `smc_pnet.c`. My initial reaction is that's quite a wide scope, so I need to pay close attention to the implications. It looks like the core of the change revolves around properly freeing the `struct smc_init_info` structure with the introduction of `smc_init_info_free`, which is a good sign for preventing potential memory leaks. I see the patch also includes managing the `smc_ib_device` with reference counting (`refcnt`) and an initialization counter (`init_cnt`), along with using `smc_ibdev_put`, which indicates they're addressing how these devices are managed.

Since this is in the SMC subsystem, I immediately start thinking about how it fits into the broader picture. SMC is relevant in virtualized environments, which means it can be running over TCP/IP or RDMA emulators, like siw or rxe. I'm also remembering that SMC can utilize RoCE or ISM, and that soft-RoCE (RXE) is even available in QEMU. That's interesting, because it means we could potentially fuzz this.

Now, my next move is to check the configuration options. I'll need to confirm that `CONFIG_SMC` is set correctly. I'll also check `net/smc/Kconfig` to see if there are any other related options that I should be aware of or might need to configure for testing.



4/2 2026/08/23 07:38 tool grepper
0m Args:
{
  "Expression": "config SMC",
  "PathPrefix": "net/smc/Kconfig"
}

Results:
{
  "Output": "net/smc/Kconfig-1-# SPDX-License-Identifier: GPL-2.0-only\nnet/smc/Kconfig:2:config SMC\nnet/smc/Kconfig-3-\ttristate \"SMC socket protocol family\"\n--\nnet/smc/Kconfig-13-\nnet/smc/Kconfig:14:config SMC_DIAG\nnet/smc/Kconfig-15-\ttristate \"SMC: socket monitoring interface\"\n--\nnet/smc/Kconfig-22-\nnet/smc/Kconfig:23:config SMC_HS_CTRL_BPF\nnet/smc/Kconfig-24-\tbool \"Generic eBPF hook for SMC handshake flow\"\n"
}

5/2 2026/08/23 07:38 llm patch-evaluator
0m Model:
gemini-3.1-pro-preview

Args:
null

Results:
null

Tokens:
							input: 7895
							output: 29
							thoughts: 14
						

Thoughts:
Here's my attempt at summarizing the thought process, tailored for an expert audience:

**Investigating `CONFIG_SMC` Dependencies**

Okay, time to dive in. My immediate thought is, "Right, `CONFIG_SMC`... what *exactly* is that tied to?" I need to understand the architectural implications before I even consider making any modifications or integrations. It's a quick reflex, really, a mental checklist of potential dependencies. I'm essentially running a dependency analysis in my head. What other kernel components, drivers, or even higher-level features might rely on the functionality enabled by that particular configuration option? Is it a core component, or something more peripheral? My aim is to build a complete mental map of the configuration's reach. I want to minimize unforeseen consequences.



6/2 2026/08/23 07:39 tool grepper
0m Args:
{
  "Expression": "depends on",
  "PathPrefix": "net/smc/Kconfig"
}

Results:
{
  "Output": "net/smc/Kconfig=2=config SMC\nnet/smc/Kconfig-3-\ttristate \"SMC socket protocol family\"\nnet/smc/Kconfig:4:\tdepends on INET \u0026\u0026 INFINIBAND \u0026\u0026 DIBS\nnet/smc/Kconfig-5-\thelp\n--\nnet/smc/Kconfig=14=config SMC_DIAG\nnet/smc/Kconfig-15-\ttristate \"SMC: socket monitoring interface\"\nnet/smc/Kconfig:16:\tdepends on SMC\nnet/smc/Kconfig-17-\thelp\n--\nnet/smc/Kconfig=23=config SMC_HS_CTRL_BPF\nnet/smc/Kconfig-24-\tbool \"Generic eBPF hook for SMC handshake flow\"\nnet/smc/Kconfig:25:\tdepends on SMC \u0026\u0026 BPF_JIT \u0026\u0026 BPF_SYSCALL\nnet/smc/Kconfig-26-\tdefault y\n"
}

7/2 2026/08/23 07:39 llm patch-evaluator
0m Model:
gemini-3.1-pro-preview

Args:
null

Results:
null

Tokens:
							input: 8352
							output: 33
							thoughts: 58
						

Thoughts:
**Decoding the Kernel Configuration**

Okay, hold on a second. This dependency chain... `depends on INET && INFINIBAND && DIBS`... DIBS? That doesn't immediately ring a bell. My initial reading might have been off, or perhaps there's a typo in my mental processing. Let me quickly cross-reference that. I'll need to double check the configuration files. Right, let me pull up `net/smc/Kconfig`, and take a look at the first ten lines. That should clear this up quickly.



8/2 2026/08/23 07:39 tool read-file
0m Args:
{
  "File": "net/smc/Kconfig",
  "FirstLine": 1,
  "LineCount": 10
}

Results:
{
  "Contents": "   1:\t# SPDX-License-Identifier: GPL-2.0-only\n   2:\tconfig SMC\n   3:\t\ttristate \"SMC socket protocol family\"\n   4:\t\tdepends on INET \u0026\u0026 INFINIBAND \u0026\u0026 DIBS\n   5:\t\thelp\n   6:\t\t  SMC-R provides a \"sockets over RDMA\" solution making use of\n   7:\t\t  RDMA over Converged Ethernet (RoCE) technology to upgrade\n   8:\t\t  AF_INET TCP connections transparently.\n   9:\t\t  The Linux implementation of the SMC-R solution is designed as\n  10:\t\t  a separate socket family SMC.\n"
}

9/2 2026/08/23 07:39 llm patch-evaluator
0m Model:
gemini-3.1-pro-preview

Args:
null

Results:
null

Tokens:
							input: 8721
							output: 17
							thoughts: 54
						

Thoughts:
**Investigating This "DIBS" Business**

Okay, hold on a second. "DIBS"? That term's throwing me for a loop. Let me quickly double-check – I need to make sure this isn't some obscure typo sneaking into the kernel tree. Maybe there's a new commit that slipped through? Ah, nope, still "DIBS".

Alright, let's step back, maybe I'm looking at it wrong. "DIBS"... is this related to IPv6 somehow? Maybe it's a configuration option? The Kconfig files are my next stop. Time to run a grep and see what this mystery "DIBS" is all about in the context of the kernel config.



10/2 2026/08/23 07:39 tool grepper
0m Args:
{
  "Expression": "config DIBS"
}

Results:
{
  "Output": "drivers/dibs/Kconfig-1-# SPDX-License-Identifier: GPL-2.0\ndrivers/dibs/Kconfig:2:config DIBS\ndrivers/dibs/Kconfig-3-\ttristate \"Direct Internal Buffer Sharing support\"\n--\ndrivers/dibs/Kconfig-13-\ndrivers/dibs/Kconfig:14:config DIBS_LO\ndrivers/dibs/Kconfig-15-\tbool \"Intra-OS shortcut with dibs loopback\"\n"
}

11/2 2026/08/23 07:39 llm patch-evaluator
0m Model:
gemini-3.1-pro-preview

Args:
null

Results:
null

Tokens:
							input: 9069
							output: 54
							thoughts: 570
						

Thoughts:
**My Analysis of the SMC Configuration and Code Changes**

Alright, let's break this down. From what I'm seeing, `DIBS` is an internal piece within this kernel tree. `SMC` clearly depends on `INET`, `INFINIBAND`, and, of course, `DIBS`. So, to enable `SMC`, all three dependencies must be enabled. I'll need to double-check if `INFINIBAND`, the RDMA subsystem, has any other configuration requirements, just to be thorough. I'll make sure to add `SMC`, `INFINIBAND`, and `DIBS` to `EnableConfigs` to ensure everything is enabled.

Now, let's get into the code changes. I've got a list of functions that have been modified: `smc_fill_gid_list`, `smc_connect_rdma_v2_prepare`, `__smc_connect`, `smc_find_rdma_v2_device_serv`, `smc_listen_work`, `smc_init_info_free`, `smcr_link_init`, `smc_lgr_create`, `smc_ib_ndev_change`, `smc_ibdev_release`, `smc_ibdev_get`, `smc_ibdev_put`, `smc_ibdev_init_begin`, `smc_ibdev_init_end`, `smc_ib_add_dev`, `smc_ib_remove_dev`, `smc_llc_cli_add_link`, `smc_llc_cli_add_link_invite`, `smc_llc_srv_add_link`, and `smc_pnet_determine_gid`.

Looking at that list, I'll need to concentrate on the functions that are going to be most impacted by the changes; those are `__smc_connect`, `smc_listen_work`, `smc_ib_add_dev`, `smc_ib_remove_dev`, `smc_llc_cli_add_link`, `smc_llc_srv_add_link`, and `smcr_link_init`.

Okay, let's see, `__smc_connect` is a static function. That helps narrow things down, which means it likely has some scope restrictions. Let's check `smc_connect`, `smc_listen`, and `smc_listen_work`. It looks like `smc_connect` is the `connect` syscall handler for AF_SMC. `smc_listen` must be the `listen` syscall handler. `smc_ib_add_dev` is called when an IB device is added, and `smc_llc_cli_add_link` is called when an LLC ADD_LINK message is received. Now I'll need to focus on those non-static functions for a more detailed review.



12/2 2026/08/23 07:39 tool grepper
0m Args:
{
  "Expression": "^(int|void|static int|static void) [a-zA-Z0-9_]+\\(",
  "PathPrefix": "net/smc/smc_ib.c"
}

Results:
{
  "Output": "net/smc/smc_ib.c=45=u8 local_systemid[SMC_SYSTEMID_LEN];\t\t/* unique system identifier */\nnet/smc/smc_ib.c-46-\nnet/smc/smc_ib.c:47:static int smc_ib_modify_qp_init(struct smc_link *lnk)\nnet/smc/smc_ib.c-48-{\n--\nnet/smc/smc_ib.c-61-\nnet/smc/smc_ib.c:62:static int smc_ib_modify_qp_rtr(struct smc_link *lnk)\nnet/smc/smc_ib.c-63-{\n--\nnet/smc/smc_ib.c-94-\nnet/smc/smc_ib.c:95:int smc_ib_modify_qp_rts(struct smc_link *lnk)\nnet/smc/smc_ib.c-96-{\n--\nnet/smc/smc_ib.c-113-\nnet/smc/smc_ib.c:114:int smc_ib_modify_qp_error(struct smc_link *lnk)\nnet/smc/smc_ib.c-115-{\n--\nnet/smc/smc_ib.c-122-\nnet/smc/smc_ib.c:123:int smc_ib_ready_link(struct smc_link *lnk)\nnet/smc/smc_ib.c-124-{\n--\nnet/smc/smc_ib.c-154-\nnet/smc/smc_ib.c:155:static int smc_ib_fill_mac(struct smc_ib_device *smcibdev, u8 ibport)\nnet/smc/smc_ib.c-156-{\n--\nnet/smc/smc_ib.c=181=bool smc_ib_is_valid_local_systemid(void)\n--\nnet/smc/smc_ib.c-185-\nnet/smc/smc_ib.c:186:static void smc_ib_init_local_systemid(void)\nnet/smc/smc_ib.c-187-{\n--\nnet/smc/smc_ib.c=191=bool smc_ib_port_active(struct smc_ib_device *smcibdev, u8 ibport)\n--\nnet/smc/smc_ib.c-195-\nnet/smc/smc_ib.c:196:int smc_ib_find_route(struct net *net, __be32 saddr, __be32 daddr,\nnet/smc/smc_ib.c-197-\t\t      u8 nexthop_mac[], u8 *uses_gateway)\n--\nnet/smc/smc_ib.c-227-\nnet/smc/smc_ib.c:228:static int smc_ib_determine_gid_rcu(const struct net_device *ndev,\nnet/smc/smc_ib.c-229-\t\t\t\t    const struct ib_gid_attr *attr,\n--\nnet/smc/smc_ib.c-273-/* determine the gid for an ib-device port and vlan id */\nnet/smc/smc_ib.c:274:int smc_ib_determine_gid(struct smc_ib_device *smcibdev, u8 ibport,\nnet/smc/smc_ib.c-275-\t\t\t unsigned short vlan_id, u8 gid[], u8 *sgid_index,\n--\nnet/smc/smc_ib.c=307=static bool smc_ib_check_link_gid(u8 gid[SMC_GID_SIZE], bool smcrv2,\n--\nnet/smc/smc_ib.c-332-/* check all links if the gid is still defined on smcibdev */\nnet/smc/smc_ib.c:333:static void smc_ib_gid_check(struct smc_ib_device *smcibdev, u8 ibport)\nnet/smc/smc_ib.c-334-{\n--\nnet/smc/smc_ib.c-357-\nnet/smc/smc_ib.c:358:static int smc_ib_remember_port_attr(struct smc_ib_device *smcibdev, u8 ibport)\nnet/smc/smc_ib.c-359-{\n--\nnet/smc/smc_ib.c-380-/* process context wrapper for might_sleep smc_ib_remember_port_attr */\nnet/smc/smc_ib.c:381:static void smc_ib_port_event_work(struct work_struct *work)\nnet/smc/smc_ib.c-382-{\n--\nnet/smc/smc_ib.c-401-/* can be called in IRQ context */\nnet/smc/smc_ib.c:402:static void smc_ib_global_event_handler(struct ib_event_handler *handler,\nnet/smc/smc_ib.c-403-\t\t\t\t\tstruct ib_event *ibevent)\n--\nnet/smc/smc_ib.c-450-\nnet/smc/smc_ib.c:451:void smc_ib_dealloc_protection_domain(struct smc_link *lnk)\nnet/smc/smc_ib.c-452-{\n--\nnet/smc/smc_ib.c-457-\nnet/smc/smc_ib.c:458:int smc_ib_create_protection_domain(struct smc_link *lnk)\nnet/smc/smc_ib.c-459-{\n--\nnet/smc/smc_ib.c=469=static bool smcr_diag_is_dev_critical(struct smc_lgr_list *smc_lgr,\n--\nnet/smc/smc_ib.c-495-\nnet/smc/smc_ib.c:496:static int smc_nl_handle_dev_port(struct sk_buff *skb,\nnet/smc/smc_ib.c-497-\t\t\t\t  struct ib_device *ibdev,\n--\nnet/smc/smc_ib.c=536=static bool smc_nl_handle_pci_values(const struct smc_pci_dev *smc_pci_dev,\n--\nnet/smc/smc_ib.c-551-\nnet/smc/smc_ib.c:552:static int smc_nl_handle_smcr_dev(struct smc_ib_device *smcibdev,\nnet/smc/smc_ib.c-553-\t\t\t\t  struct sk_buff *skb,\n--\nnet/smc/smc_ib.c-604-\nnet/smc/smc_ib.c:605:static void smc_nl_prep_smcr_dev(struct smc_ib_devices *dev_list,\nnet/smc/smc_ib.c-606-\t\t\t\t struct sk_buff *skb,\n--\nnet/smc/smc_ib.c-627-\nnet/smc/smc_ib.c:628:int smcr_nl_get_device(struct sk_buff *skb, struct netlink_callback *cb)\nnet/smc/smc_ib.c-629-{\n--\nnet/smc/smc_ib.c-633-\nnet/smc/smc_ib.c:634:static void smc_ib_qp_event_handler(struct ib_event *ibevent, void *priv)\nnet/smc/smc_ib.c-635-{\n--\nnet/smc/smc_ib.c-654-\nnet/smc/smc_ib.c:655:void smc_ib_destroy_queue_pair(struct smc_link *lnk)\nnet/smc/smc_ib.c-656-{\n--\nnet/smc/smc_ib.c-662-/* create a queue pair within the protection domain for a link */\nnet/smc/smc_ib.c:663:int smc_ib_create_queue_pair(struct smc_link *lnk)\nnet/smc/smc_ib.c-664-{\n--\nnet/smc/smc_ib.c-694-\nnet/smc/smc_ib.c:695:void smc_ib_put_memory_region(struct ib_mr *mr)\nnet/smc/smc_ib.c-696-{\n--\nnet/smc/smc_ib.c-699-\nnet/smc/smc_ib.c:700:static int smc_ib_map_mr_sg(struct smc_buf_desc *buf_slot, u8 link_idx)\nnet/smc/smc_ib.c-701-{\n--\nnet/smc/smc_ib.c-714-/* Allocate a memory region and map the dma mapped SG list of buf_slot */\nnet/smc/smc_ib.c:715:int smc_ib_get_memory_region(struct ib_pd *pd, int access_flags,\nnet/smc/smc_ib.c-716-\t\t\t     struct smc_buf_desc *buf_slot, u8 link_idx)\n--\nnet/smc/smc_ib.c=738=bool smc_ib_is_sg_need_sync(struct smc_link *lnk,\n--\nnet/smc/smc_ib.c-764-/* synchronize buffer usage for cpu access */\nnet/smc/smc_ib.c:765:void smc_ib_sync_sg_for_cpu(struct smc_link *lnk,\nnet/smc/smc_ib.c-766-\t\t\t    struct smc_buf_desc *buf_slot,\n--\nnet/smc/smc_ib.c-787-/* synchronize buffer usage for device access */\nnet/smc/smc_ib.c:788:void smc_ib_sync_sg_for_device(struct smc_link *lnk,\nnet/smc/smc_ib.c-789-\t\t\t       struct smc_buf_desc *buf_slot,\n--\nnet/smc/smc_ib.c-810-/* Map a new TX or RX buffer SG-table to DMA */\nnet/smc/smc_ib.c:811:int smc_ib_buf_map_sg(struct smc_link *lnk,\nnet/smc/smc_ib.c-812-\t\t      struct smc_buf_desc *buf_slot,\n--\nnet/smc/smc_ib.c-826-\nnet/smc/smc_ib.c:827:void smc_ib_buf_unmap_sg(struct smc_link *lnk,\nnet/smc/smc_ib.c-828-\t\t\t struct smc_buf_desc *buf_slot,\n--\nnet/smc/smc_ib.c=841=long smc_ib_setup_per_ibdev(struct smc_ib_device *smcibdev)\n--\nnet/smc/smc_ib.c-883-\nnet/smc/smc_ib.c:884:static void smc_ib_cleanup_per_ibdev(struct smc_ib_device *smcibdev)\nnet/smc/smc_ib.c-885-{\n--\nnet/smc/smc_ib.c=897=static struct ib_client smc_ib_client;\nnet/smc/smc_ib.c-898-\nnet/smc/smc_ib.c:899:static void smc_copy_netdev_ifindex(struct smc_ib_device *smcibdev, int port)\nnet/smc/smc_ib.c-900-{\n--\nnet/smc/smc_ib.c-910-\nnet/smc/smc_ib.c:911:void smc_ib_ndev_change(struct net_device *ndev, unsigned long event)\nnet/smc/smc_ib.c-912-{\n--\nnet/smc/smc_ib.c-936-\nnet/smc/smc_ib.c:937:static void smc_ibdev_release(struct smc_ib_device *smcibdev)\nnet/smc/smc_ib.c-938-{\n--\nnet/smc/smc_ib.c-942-\nnet/smc/smc_ib.c:943:void smc_ibdev_get(struct smc_ib_device *smcibdev)\nnet/smc/smc_ib.c-944-{\n--\nnet/smc/smc_ib.c-947-\nnet/smc/smc_ib.c:948:void smc_ibdev_put(struct smc_ib_device *smcibdev)\nnet/smc/smc_ib.c-949-{\n--\nnet/smc/smc_ib.c-953-\nnet/smc/smc_ib.c:954:int smc_ibdev_init_begin(struct smc_ib_device *smcibdev)\nnet/smc/smc_ib.c-955-{\n--\nnet/smc/smc_ib.c-966-\nnet/smc/smc_ib.c:967:void smc_ibdev_init_end(struct smc_ib_device *smcibdev)\nnet/smc/smc_ib.c-968-{\n--\nnet/smc/smc_ib.c-975-/* callback function for ib_register_client() */\nnet/smc/smc_ib.c:976:static int smc_ib_add_dev(struct ib_device *ibdev)\nnet/smc/smc_ib.c-977-{\n--\nnet/smc/smc_ib.c-1035-/* callback function for ib_unregister_client() */\nnet/smc/smc_ib.c:1036:static void smc_ib_remove_dev(struct ib_device *ibdev, void *client_data)\nnet/smc/smc_ib.c-1037-{\n--\nnet/smc/smc_ib.c=1061=int __init smc_ib_register_client(void)\n--\nnet/smc/smc_ib.c-1066-\nnet/smc/smc_ib.c:1067:void smc_ib_unregister_client(void)\nnet/smc/smc_ib.c-1068-{\n"
}

13/2 2026/08/23 07:39 llm patch-evaluator
0m Model:
gemini-3.1-pro-preview

Args:
null

Results:
null

Tokens:
							input: 14180
							output: 54
							thoughts: 113
						

Thoughts:
**Analyzing the SMC IB Device Registration**

Okay, so I'm looking at this SMC code and immediately notice that `smc_ib_add_dev` and `smc_ib_remove_dev` are static. That's standard practice, but good to keep in mind for scoping. Wait a minute... `smc_ib_add_dev` is actually a callback! It's invoked by `ib_register_client()` when an InfiniBand device is added. That makes more sense; it has to be how the SMC layer hooks into the IB subsystem. Now, what's this `smc_listen_work` function? Ah, it's a workqueue function. That hints at asynchronous processing, which is often crucial for network interactions. Finally, `smc_connect` and `smc_listen` are the real syscall entry points. I should probably dig into `net/smc/af_smc.c` to see how those are implemented and how they interact with everything else I've just identified. Time to dive deeper and see how the pieces fit together.



14/2 2026/08/23 07:39 tool grepper
0m Args:
{
  "Expression": "^(int|void|static int|static void) [a-zA-Z0-9_]+\\(",
  "PathPrefix": "net/smc/af_smc.c"
}

Results:
{
  "Output": "net/smc/af_smc.c=71=struct workqueue_struct\t*smc_close_wq;\t/* wq for close work */\nnet/smc/af_smc.c-72-\nnet/smc/af_smc.c:73:static void smc_tcp_listen_work(struct work_struct *);\nnet/smc/af_smc.c:74:static void smc_connect_work(struct work_struct *);\nnet/smc/af_smc.c-75-\nnet/smc/af_smc.c:76:int smc_nl_dump_hs_limitation(struct sk_buff *skb, struct netlink_callback *cb)\nnet/smc/af_smc.c-77-{\n--\nnet/smc/af_smc.c-102-\nnet/smc/af_smc.c:103:int smc_nl_enable_hs_limitation(struct sk_buff *skb, struct genl_info *info)\nnet/smc/af_smc.c-104-{\n--\nnet/smc/af_smc.c-108-\nnet/smc/af_smc.c:109:int smc_nl_disable_hs_limitation(struct sk_buff *skb, struct genl_info *info)\nnet/smc/af_smc.c-110-{\n--\nnet/smc/af_smc.c-114-\nnet/smc/af_smc.c:115:static void smc_set_keepalive(struct sock *sk, int val)\nnet/smc/af_smc.c-116-{\n--\nnet/smc/af_smc.c=194=struct smc_hashinfo smc_v6_hashinfo = {\n--\nnet/smc/af_smc.c-198-\nnet/smc/af_smc.c:199:int smc_hash_sk(struct sock *sk)\nnet/smc/af_smc.c-200-{\n--\nnet/smc/af_smc.c-213-\nnet/smc/af_smc.c:214:void smc_unhash_sk(struct sock *sk)\nnet/smc/af_smc.c-215-{\n--\nnet/smc/af_smc.c-227- */\nnet/smc/af_smc.c:228:void smc_release_cb(struct sock *sk)\nnet/smc/af_smc.c-229-{\n--\nnet/smc/af_smc.c=262=EXPORT_SYMBOL_GPL(smc_proto6);\nnet/smc/af_smc.c-263-\nnet/smc/af_smc.c:264:static void smc_fback_restore_callbacks(struct smc_sock *smc)\nnet/smc/af_smc.c-265-{\n--\nnet/smc/af_smc.c-278-\nnet/smc/af_smc.c:279:static void smc_restore_fallback_changes(struct smc_sock *smc)\nnet/smc/af_smc.c-280-{\n--\nnet/smc/af_smc.c-287-\nnet/smc/af_smc.c:288:static int __smc_release(struct smc_sock *smc)\nnet/smc/af_smc.c-289-{\n--\nnet/smc/af_smc.c-327-\nnet/smc/af_smc.c:328:int smc_release(struct socket *sock)\nnet/smc/af_smc.c-329-{\n--\nnet/smc/af_smc.c-373-\nnet/smc/af_smc.c:374:static void smc_destruct(struct sock *sk)\nnet/smc/af_smc.c-375-{\n--\nnet/smc/af_smc.c=393=static struct lock_class_key smc_slock_key;\nnet/smc/af_smc.c-394-\nnet/smc/af_smc.c:395:void smc_sk_init(struct net *net, struct sock *sk, int protocol)\nnet/smc/af_smc.c-396-{\n--\nnet/smc/af_smc.c=421=static struct sock *smc_sock_alloc(struct net *net, struct socket *sock,\n--\nnet/smc/af_smc.c-437-\nnet/smc/af_smc.c:438:int smc_bind(struct socket *sock, struct sockaddr_unsized *uaddr,\nnet/smc/af_smc.c-439-\t     int addr_len)\n--\nnet/smc/af_smc.c-500-/* if set, use value set by setsockopt() - else use IPv4 or SMC sysctl value */\nnet/smc/af_smc.c:501:static void smc_adjust_sock_bufsizes(struct sock *nsk, struct sock *osk,\nnet/smc/af_smc.c-502-\t\t\t\t     unsigned long mask)\n--\nnet/smc/af_smc.c-510-\nnet/smc/af_smc.c:511:static void smc_copy_sock_settings(struct sock *nsk, struct sock *osk,\nnet/smc/af_smc.c-512-\t\t\t\t   unsigned long mask)\n--\nnet/smc/af_smc.c-529-\nnet/smc/af_smc.c:530:static void smc_copy_sock_settings_to_clc(struct smc_sock *smc)\nnet/smc/af_smc.c-531-{\n--\nnet/smc/af_smc.c-539-/* copy only settings and flags relevant for smc from clc to smc socket */\nnet/smc/af_smc.c:540:static void smc_copy_sock_settings_to_smc(struct smc_sock *smc)\nnet/smc/af_smc.c-541-{\n--\nnet/smc/af_smc.c-545-/* register the new vzalloced sndbuf on all links */\nnet/smc/af_smc.c:546:static int smcr_lgr_reg_sndbufs(struct smc_link *link,\nnet/smc/af_smc.c-547-\t\t\t\tstruct smc_buf_desc *snd_desc)\n--\nnet/smc/af_smc.c-568-/* register the new rmb on all links */\nnet/smc/af_smc.c:569:static int smcr_lgr_reg_rmbs(struct smc_link *link,\nnet/smc/af_smc.c-570-\t\t\t     struct smc_buf_desc *rmb_desc)\n--\nnet/smc/af_smc.c-617-\nnet/smc/af_smc.c:618:static int smcr_clnt_conf_first_link(struct smc_sock *smc)\nnet/smc/af_smc.c-619-{\n--\nnet/smc/af_smc.c=690=static bool smc_isascii(char *hostname)\n--\nnet/smc/af_smc.c-699-\nnet/smc/af_smc.c:700:static void smc_conn_save_peer_info_fce(struct smc_sock *smc,\nnet/smc/af_smc.c-701-\t\t\t\t\tstruct smc_clc_msg_accept_confirm *clc)\n--\nnet/smc/af_smc.c-726-\nnet/smc/af_smc.c:727:static void smcr_conn_save_peer_info(struct smc_sock *smc,\nnet/smc/af_smc.c-728-\t\t\t\t     struct smc_clc_msg_accept_confirm *clc)\n--\nnet/smc/af_smc.c-738-\nnet/smc/af_smc.c:739:static void smcd_conn_save_peer_info(struct smc_sock *smc,\nnet/smc/af_smc.c-740-\t\t\t\t     struct smc_clc_msg_accept_confirm *clc)\n--\nnet/smc/af_smc.c-751-\nnet/smc/af_smc.c:752:static void smc_conn_save_peer_info(struct smc_sock *smc,\nnet/smc/af_smc.c-753-\t\t\t\t    struct smc_clc_msg_accept_confirm *clc)\n--\nnet/smc/af_smc.c-761-\nnet/smc/af_smc.c:762:static void smc_link_save_peer_info(struct smc_link *link,\nnet/smc/af_smc.c-763-\t\t\t\t    struct smc_clc_msg_accept_confirm *clc,\n--\nnet/smc/af_smc.c-772-\nnet/smc/af_smc.c:773:static void smc_stat_inc_fback_rsn_cnt(struct smc_sock *smc,\nnet/smc/af_smc.c-774-\t\t\t\t       struct smc_stats_fback *fback_arr)\n--\nnet/smc/af_smc.c-790-\nnet/smc/af_smc.c:791:static void smc_stat_fallback(struct smc_sock *smc)\nnet/smc/af_smc.c-792-{\n--\nnet/smc/af_smc.c-806-/* must be called under rcu read lock */\nnet/smc/af_smc.c:807:static void smc_fback_wakeup_waitqueue(struct smc_sock *smc, void *key)\nnet/smc/af_smc.c-808-{\n--\nnet/smc/af_smc.c-830-\nnet/smc/af_smc.c:831:static int smc_fback_mark_woken(wait_queue_entry_t *wait,\nnet/smc/af_smc.c-832-\t\t\t\tunsigned int mode, int sync, void *key)\n--\nnet/smc/af_smc.c-841-\nnet/smc/af_smc.c:842:static void smc_fback_forward_wakeup(struct smc_sock *smc, struct sock *clcsk,\nnet/smc/af_smc.c-843-\t\t\t\t     void (*clcsock_callback)(struct sock *sk))\n--\nnet/smc/af_smc.c-863-\nnet/smc/af_smc.c:864:static void smc_fback_state_change(struct sock *clcsk)\nnet/smc/af_smc.c-865-{\n--\nnet/smc/af_smc.c-875-\nnet/smc/af_smc.c:876:static void smc_fback_data_ready(struct sock *clcsk)\nnet/smc/af_smc.c-877-{\n--\nnet/smc/af_smc.c-887-\nnet/smc/af_smc.c:888:static void smc_fback_write_space(struct sock *clcsk)\nnet/smc/af_smc.c-889-{\n--\nnet/smc/af_smc.c-899-\nnet/smc/af_smc.c:900:static void smc_fback_error_report(struct sock *clcsk)\nnet/smc/af_smc.c-901-{\n--\nnet/smc/af_smc.c-911-\nnet/smc/af_smc.c:912:static void smc_fback_replace_callbacks(struct smc_sock *smc)\nnet/smc/af_smc.c-913-{\n--\nnet/smc/af_smc.c-930-\nnet/smc/af_smc.c:931:static int smc_switch_to_fallback(struct smc_sock *smc, int reason_code)\nnet/smc/af_smc.c-932-{\n--\nnet/smc/af_smc.c-963-/* fall back during connect */\nnet/smc/af_smc.c:964:static int smc_connect_fallback(struct smc_sock *smc, int reason_code)\nnet/smc/af_smc.c-965-{\n--\nnet/smc/af_smc.c-983-/* decline and fall back during connect */\nnet/smc/af_smc.c:984:static int smc_connect_decline_fallback(struct smc_sock *smc, int reason_code,\nnet/smc/af_smc.c-985-\t\t\t\t\tu8 version)\n--\nnet/smc/af_smc.c-1007-\nnet/smc/af_smc.c:1008:static void smc_conn_abort(struct smc_sock *smc, int local_first)\nnet/smc/af_smc.c-1009-{\n--\nnet/smc/af_smc.c-1023-/* called for connect and listen */\nnet/smc/af_smc.c:1024:static int smc_find_rdma_device(struct smc_sock *smc, struct smc_init_info *ini)\nnet/smc/af_smc.c-1025-{\n--\nnet/smc/af_smc.c-1039-/* called for connect and listen */\nnet/smc/af_smc.c:1040:static int smc_find_ism_device(struct smc_sock *smc, struct smc_init_info *ini)\nnet/smc/af_smc.c-1041-{\n--\nnet/smc/af_smc.c=1052=static bool smc_find_ism_v2_is_unique_chid(u16 chid, struct smc_init_info *ini,\n--\nnet/smc/af_smc.c-1065- */\nnet/smc/af_smc.c:1066:static int smc_find_ism_v2_device_clnt(struct smc_sock *smc,\nnet/smc/af_smc.c-1067-\t\t\t\t       struct smc_init_info *ini)\n--\nnet/smc/af_smc.c-1112-/* Check for VLAN ID and register it on ISM device just for CLC handshake */\nnet/smc/af_smc.c:1113:static int smc_connect_ism_vlan_setup(struct smc_init_info *ini)\nnet/smc/af_smc.c-1114-{\n--\nnet/smc/af_smc.c-1119-\nnet/smc/af_smc.c:1120:static int smc_find_proposal_devices(struct smc_sock *smc,\nnet/smc/af_smc.c-1121-\t\t\t\t     struct smc_init_info *ini)\n--\nnet/smc/af_smc.c-1172- */\nnet/smc/af_smc.c:1173:static int smc_connect_ism_vlan_cleanup(struct smc_init_info *ini)\nnet/smc/af_smc.c-1174-{\n--\nnet/smc/af_smc.c-1187-/* CLC handshake during connect */\nnet/smc/af_smc.c:1188:static int smc_connect_clc(struct smc_sock *smc,\nnet/smc/af_smc.c-1189-\t\t\t   struct smc_clc_msg_accept_confirm *aclc,\n--\nnet/smc/af_smc.c-1202-\nnet/smc/af_smc.c:1203:void smc_fill_gid_list(struct smc_link_group *lgr,\nnet/smc/af_smc.c-1204-\t\t       struct smc_gidlist *gidlist,\n--\nnet/smc/af_smc.c-1230-\nnet/smc/af_smc.c:1231:static int smc_connect_rdma_v2_prepare(struct smc_sock *smc,\nnet/smc/af_smc.c-1232-\t\t\t\t       struct smc_clc_msg_accept_confirm *aclc,\n--\nnet/smc/af_smc.c-1266-/* setup for RDMA connection of client */\nnet/smc/af_smc.c:1267:static int smc_connect_rdma(struct smc_sock *smc,\nnet/smc/af_smc.c-1268-\t\t\t    struct smc_clc_msg_accept_confirm *aclc,\n--\nnet/smc/af_smc.c=1399=smc_v2_determine_accepted_chid(struct smc_clc_msg_accept_confirm *aclc,\n--\nnet/smc/af_smc.c-1415-/* setup for ISM connection of client */\nnet/smc/af_smc.c:1416:static int smc_connect_ism(struct smc_sock *smc,\nnet/smc/af_smc.c-1417-\t\t\t   struct smc_clc_msg_accept_confirm *aclc,\n--\nnet/smc/af_smc.c-1498-/* check if received accept type and version matches a proposed one */\nnet/smc/af_smc.c:1499:static int smc_connect_check_aclc(struct smc_init_info *ini,\nnet/smc/af_smc.c-1500-\t\t\t\t  struct smc_clc_msg_accept_confirm *aclc)\n--\nnet/smc/af_smc.c-1519-/* perform steps before actually connecting */\nnet/smc/af_smc.c:1520:static int __smc_connect(struct smc_sock *smc)\nnet/smc/af_smc.c-1521-{\n--\nnet/smc/af_smc.c-1609-\nnet/smc/af_smc.c:1610:static void smc_connect_work(struct work_struct *work)\nnet/smc/af_smc.c-1611-{\n--\nnet/smc/af_smc.c-1655-\nnet/smc/af_smc.c:1656:int smc_connect(struct socket *sock, struct sockaddr_unsized *addr,\nnet/smc/af_smc.c-1657-\t\tint alen, int flags)\n--\nnet/smc/af_smc.c-1736-\nnet/smc/af_smc.c:1737:static int smc_clcsock_accept(struct smc_sock *lsmc, struct smc_sock **new_smc)\nnet/smc/af_smc.c-1738-{\n--\nnet/smc/af_smc.c-1797- */\nnet/smc/af_smc.c:1798:static void smc_accept_enqueue(struct sock *parent, struct sock *sk)\nnet/smc/af_smc.c-1799-{\n--\nnet/smc/af_smc.c-1809-/* remove a socket from the accept queue of its parental listening socket */\nnet/smc/af_smc.c:1810:static void smc_accept_unlink(struct sock *sk)\nnet/smc/af_smc.c-1811-{\n--\nnet/smc/af_smc.c=1824=struct sock *smc_accept_dequeue(struct sock *parent,\n--\nnet/smc/af_smc.c-1856-/* clean up for a created but never accepted sock */\nnet/smc/af_smc.c:1857:void smc_close_non_accepted(struct sock *sk)\nnet/smc/af_smc.c-1858-{\n--\nnet/smc/af_smc.c-1871-\nnet/smc/af_smc.c:1872:static int smcr_serv_conf_first_link(struct smc_sock *smc)\nnet/smc/af_smc.c-1873-{\n--\nnet/smc/af_smc.c-1924-/* listen worker: finish */\nnet/smc/af_smc.c:1925:static void smc_listen_out(struct smc_sock *new_smc)\nnet/smc/af_smc.c-1926-{\n--\nnet/smc/af_smc.c-1948-/* listen worker: finish in state connected */\nnet/smc/af_smc.c:1949:static void smc_listen_out_connected(struct smc_sock *new_smc)\nnet/smc/af_smc.c-1950-{\n--\nnet/smc/af_smc.c-1959-/* listen worker: finish in error state */\nnet/smc/af_smc.c:1960:static void smc_listen_out_err(struct smc_sock *new_smc)\nnet/smc/af_smc.c-1961-{\n--\nnet/smc/af_smc.c-1973-/* listen worker: decline and fall back if possible */\nnet/smc/af_smc.c:1974:static void smc_listen_decline(struct smc_sock *new_smc, int reason_code,\nnet/smc/af_smc.c-1975-\t\t\t       int local_first, u8 version)\n--\nnet/smc/af_smc.c-1994-/* listen worker: version checking */\nnet/smc/af_smc.c:1995:static int smc_listen_v2_check(struct smc_sock *new_smc,\nnet/smc/af_smc.c-1996-\t\t\t       struct smc_clc_msg_proposal *pclc,\n--\nnet/smc/af_smc.c-2056-/* listen worker: check prefixes */\nnet/smc/af_smc.c:2057:static int smc_listen_prfx_check(struct smc_sock *new_smc,\nnet/smc/af_smc.c-2058-\t\t\t\t struct smc_clc_msg_proposal *pclc)\n--\nnet/smc/af_smc.c-2074-/* listen worker: initialize connection and buffers */\nnet/smc/af_smc.c:2075:static int smc_listen_rdma_init(struct smc_sock *new_smc,\nnet/smc/af_smc.c-2076-\t\t\t\tstruct smc_init_info *ini)\n--\nnet/smc/af_smc.c-2094-/* listen worker: initialize connection and buffers for SMC-D */\nnet/smc/af_smc.c:2095:static int smc_listen_ism_init(struct smc_sock *new_smc,\nnet/smc/af_smc.c-2096-\t\t\t       struct smc_init_info *ini)\n--\nnet/smc/af_smc.c=2115=static bool smc_is_already_selected(struct smcd_dev *smcd,\n--\nnet/smc/af_smc.c-2128-/* check for ISM devices matching proposed ISM devices */\nnet/smc/af_smc.c:2129:static void smc_check_ism_v2_match(struct smc_init_info *ini,\nnet/smc/af_smc.c-2130-\t\t\t\t   u16 proposed_chid,\n--\nnet/smc/af_smc.c-2154-\nnet/smc/af_smc.c:2155:static void smc_init_info_store_rc(u32 rc, struct smc_init_info *ini)\nnet/smc/af_smc.c-2156-{\n--\nnet/smc/af_smc.c-2160-\nnet/smc/af_smc.c:2161:static void smc_find_ism_v2_device_serv(struct smc_sock *new_smc,\nnet/smc/af_smc.c-2162-\t\t\t\t\tstruct smc_clc_msg_proposal *pclc,\n--\nnet/smc/af_smc.c-2250-\nnet/smc/af_smc.c:2251:static void smc_find_ism_v1_device_serv(struct smc_sock *new_smc,\nnet/smc/af_smc.c-2252-\t\t\t\t\tstruct smc_clc_msg_proposal *pclc,\n--\nnet/smc/af_smc.c-2281-/* listen worker: register buffers */\nnet/smc/af_smc.c:2282:static int smc_listen_rdma_reg(struct smc_sock *new_smc, bool local_first)\nnet/smc/af_smc.c-2283-{\n--\nnet/smc/af_smc.c-2299-\nnet/smc/af_smc.c:2300:static void smc_find_rdma_v2_device_serv(struct smc_sock *new_smc,\nnet/smc/af_smc.c-2301-\t\t\t\t\t struct smc_clc_msg_proposal *pclc,\n--\nnet/smc/af_smc.c-2353-\nnet/smc/af_smc.c:2354:static int smc_find_rdma_v1_device_serv(struct smc_sock *new_smc,\nnet/smc/af_smc.c-2355-\t\t\t\t\tstruct smc_clc_msg_proposal *pclc,\n--\nnet/smc/af_smc.c-2378-/* determine the local device matching to proposal */\nnet/smc/af_smc.c:2379:static int smc_listen_find_device(struct smc_sock *new_smc,\nnet/smc/af_smc.c-2380-\t\t\t\t  struct smc_clc_msg_proposal *pclc,\n--\nnet/smc/af_smc.c-2426-/* listen worker: finish RDMA setup */\nnet/smc/af_smc.c:2427:static int smc_listen_rdma_finish(struct smc_sock *new_smc,\nnet/smc/af_smc.c-2428-\t\t\t\t  struct smc_clc_msg_accept_confirm *cclc,\n--\nnet/smc/af_smc.c-2452-/* setup for connection of server */\nnet/smc/af_smc.c:2453:static void smc_listen_work(struct work_struct *work)\nnet/smc/af_smc.c-2454-{\n--\nnet/smc/af_smc.c-2597-\nnet/smc/af_smc.c:2598:static void smc_tcp_listen_work(struct work_struct *work)\nnet/smc/af_smc.c-2599-{\n--\nnet/smc/af_smc.c-2632-\nnet/smc/af_smc.c:2633:static void smc_clcsock_data_ready(struct sock *listen_clcsock)\nnet/smc/af_smc.c-2634-{\n--\nnet/smc/af_smc.c-2650-\nnet/smc/af_smc.c:2651:int smc_listen(struct socket *sock, int backlog)\nnet/smc/af_smc.c-2652-{\n--\nnet/smc/af_smc.c-2716-\nnet/smc/af_smc.c:2717:int smc_accept(struct socket *sock, struct socket *new_sock,\nnet/smc/af_smc.c-2718-\t       struct proto_accept_arg *arg)\n--\nnet/smc/af_smc.c-2785-\nnet/smc/af_smc.c:2786:int smc_getname(struct socket *sock, struct sockaddr *addr,\nnet/smc/af_smc.c-2787-\t\tint peer)\n--\nnet/smc/af_smc.c-2799-\nnet/smc/af_smc.c:2800:int smc_sendmsg(struct socket *sock, struct msghdr *msg, size_t len)\nnet/smc/af_smc.c-2801-{\n--\nnet/smc/af_smc.c-2837-\nnet/smc/af_smc.c:2838:int smc_recvmsg(struct socket *sock, struct msghdr *msg, size_t len,\nnet/smc/af_smc.c-2839-\t\tint flags)\n--\nnet/smc/af_smc.c=2888=__poll_t smc_poll(struct file *file, struct socket *sock,\n--\nnet/smc/af_smc.c-2947-\nnet/smc/af_smc.c:2948:int smc_shutdown(struct socket *sock, int how)\nnet/smc/af_smc.c-2949-{\n--\nnet/smc/af_smc.c-3022-\nnet/smc/af_smc.c:3023:static int __smc_getsockopt(struct socket *sock, int level, int optname,\nnet/smc/af_smc.c-3024-\t\t\t    char __user *optval, int __user *optlen)\n--\nnet/smc/af_smc.c-3054-\nnet/smc/af_smc.c:3055:static int __smc_setsockopt(struct socket *sock, int level, int optname,\nnet/smc/af_smc.c-3056-\t\t\t    sockptr_t optval, unsigned int optlen)\n--\nnet/smc/af_smc.c-3086-\nnet/smc/af_smc.c:3087:int smc_setsockopt(struct socket *sock, int level, int optname,\nnet/smc/af_smc.c-3088-\t\t   sockptr_t optval, unsigned int optlen)\n--\nnet/smc/af_smc.c-3173-\nnet/smc/af_smc.c:3174:int smc_getsockopt(struct socket *sock, int level, int optname,\nnet/smc/af_smc.c-3175-\t\t   char __user *optval, int __user *optlen)\n--\nnet/smc/af_smc.c-3199-\nnet/smc/af_smc.c:3200:int smc_ioctl(struct socket *sock, unsigned int cmd,\nnet/smc/af_smc.c-3201-\t      unsigned long arg)\n--\nnet/smc/af_smc.c=3335=static const struct proto_ops smc_sock_ops = {\n--\nnet/smc/af_smc.c-3355-\nnet/smc/af_smc.c:3356:int smc_create_clcsk(struct net *net, struct sock *sk, int family)\nnet/smc/af_smc.c-3357-{\n--\nnet/smc/af_smc.c-3375-\nnet/smc/af_smc.c:3376:static int smc_create(struct net *net, struct socket *sock, int protocol,\nnet/smc/af_smc.c-3377-\t\t      int kern)\n"
}

15/2 2026/08/23 07:39 llm patch-evaluator
0m Model:
gemini-3.1-pro-preview

Args:
null

Results:
null

Tokens:
							input: 23104
							output: 55
							thoughts: 308
						

Thoughts:
**My Analysis of the SMC Subsystem Patch**

Okay, so this patch addresses a pretty critical memory management issue within the SMC subsystem. It looks like `smc_init_info` was being freed with `kfree` instead of the proper `smc_init_info_free` function. That's a classic leak, specifically leaking references to `smc_ib_device`. We definitely need to fix that.

Beyond the bug fix, there's a functional change with the addition of `smc_ibdev_init_begin` and `smc_ibdev_init_end`, presumably to manage the initial setup of unpublished links. Interesting.

Now, let's see which functions are affected. I see `__smc_connect`, `smc_listen_work`, `smc_llc_cli_add_link`, `smc_llc_srv_add_link`, `smcr_link_init`, and `smc_pnet_determine_gid`. These functions are called via the typical user-space access of `connect`, `listen`, or, indirectly, through network packets like the LLC messages.

Since these functions are reachable from userspace, I'll need to make sure to include `smc_connect`, `smc_listen`, `smc_llc_cli_add_link`, and `smc_llc_srv_add_link` in `FocusSymbols`. Wait a minute, `smc_connect` and `smc_listen` are the actual syscall entry points, aren't they? And the LLC functions handle those incoming network messages. I should check `net/smc/smc_llc.c` to confirm whether `smc_llc_cli_add_link` and `smc_llc_srv_add_link` are static. Gotta be sure.



16/2 2026/08/23 07:39 tool grepper
0m Args:
{
  "Expression": "^(int|void|static int|static void) [a-zA-Z0-9_]+\\(",
  "PathPrefix": "net/smc/smc_llc.c"
}

Results:
{
  "Output": "net/smc/smc_llc.c=217=struct smc_llc_qentry {\n--\nnet/smc/smc_llc.c-224-\nnet/smc/smc_llc.c:225:static void smc_llc_enqueue(struct smc_link *link, union smc_llc_msg *llc,\nnet/smc/smc_llc.c-226-\t\t\t    u32 byte_len);\n--\nnet/smc/smc_llc.c=228=struct smc_llc_qentry *smc_llc_flow_qentry_clr(struct smc_llc_flow *flow)\n--\nnet/smc/smc_llc.c-235-\nnet/smc/smc_llc.c:236:void smc_llc_flow_qentry_del(struct smc_llc_flow *flow)\nnet/smc/smc_llc.c-237-{\n--\nnet/smc/smc_llc.c=247=static inline void smc_llc_flow_qentry_set(struct smc_llc_flow *flow,\n--\nnet/smc/smc_llc.c-252-\nnet/smc/smc_llc.c:253:static void smc_llc_flow_parallel(struct smc_link_group *lgr, u8 flow_type,\nnet/smc/smc_llc.c-254-\t\t\t\t  struct smc_llc_qentry *qentry)\n--\nnet/smc/smc_llc.c=275=static bool smc_llc_flow_start(struct smc_llc_flow *flow,\n--\nnet/smc/smc_llc.c-306-/* start a new local llc flow, wait till current flow finished */\nnet/smc/smc_llc.c:307:int smc_llc_flow_initiate(struct smc_link_group *lgr,\nnet/smc/smc_llc.c-308-\t\t\t  enum smc_llc_flowtype type)\n--\nnet/smc/smc_llc.c-340-/* finish the current llc flow */\nnet/smc/smc_llc.c:341:void smc_llc_flow_stop(struct smc_link_group *lgr, struct smc_llc_flow *flow)\nnet/smc/smc_llc.c-342-{\n--\nnet/smc/smc_llc.c=398=struct smc_llc_tx_pend {\n--\nnet/smc/smc_llc.c-401-/* handler for send/transmission completion of an LLC msg */\nnet/smc/smc_llc.c:402:static void smc_llc_tx_handler(struct smc_wr_tx_pend_priv *pend,\nnet/smc/smc_llc.c-403-\t\t\t       struct smc_link *link,\n--\nnet/smc/smc_llc.c-421- */\nnet/smc/smc_llc.c:422:static int smc_llc_add_pending_send(struct smc_link *link,\nnet/smc/smc_llc.c-423-\t\t\t\t    struct smc_wr_buf **wr_buf,\n--\nnet/smc/smc_llc.c-443-\nnet/smc/smc_llc.c:444:static int smc_llc_add_pending_send_v2(struct smc_link *link,\nnet/smc/smc_llc.c-445-\t\t\t\t       struct smc_wr_v2_buf **wr_buf,\n--\nnet/smc/smc_llc.c-455-\nnet/smc/smc_llc.c:456:static void smc_llc_init_msg_hdr(struct smc_llc_hdr *hdr,\nnet/smc/smc_llc.c-457-\t\t\t\t struct smc_link_group *lgr, size_t len)\n--\nnet/smc/smc_llc.c-468-/* high-level API to send LLC confirm link */\nnet/smc/smc_llc.c:469:int smc_llc_send_confirm_link(struct smc_link *link,\nnet/smc/smc_llc.c-470-\t\t\t      enum smc_llc_reqresp reqresp)\n--\nnet/smc/smc_llc.c-508-/* send LLC confirm rkey request */\nnet/smc/smc_llc.c:509:static int smc_llc_send_confirm_rkey(struct smc_link *send_link,\nnet/smc/smc_llc.c-510-\t\t\t\t     struct smc_buf_desc *rmb_desc)\n--\nnet/smc/smc_llc.c-557-/* send LLC delete rkey request */\nnet/smc/smc_llc.c:558:static int smc_llc_send_delete_rkey(struct smc_link *link,\nnet/smc/smc_llc.c-559-\t\t\t\t    struct smc_buf_desc *rmb_desc)\n--\nnet/smc/smc_llc.c=618=static struct smc_buf_desc *smc_llc_get_first_rmb(struct smc_link_group *lgr,\n--\nnet/smc/smc_llc.c-624-\nnet/smc/smc_llc.c:625:static int smc_llc_fill_ext_v2(struct smc_llc_msg_add_link_v2_ext *ext,\nnet/smc/smc_llc.c-626-\t\t\t       struct smc_link *link, struct smc_link *link_new)\n--\nnet/smc/smc_llc.c-664-/* send ADD LINK request or response */\nnet/smc/smc_llc.c:665:int smc_llc_send_add_link(struct smc_link *link, u8 mac[], u8 gid[],\nnet/smc/smc_llc.c-666-\t\t\t  struct smc_link *link_new,\n--\nnet/smc/smc_llc.c-725-/* send DELETE LINK request or response */\nnet/smc/smc_llc.c:726:int smc_llc_send_delete_link(struct smc_link *link, u8 link_del_id,\nnet/smc/smc_llc.c-727-\t\t\t     enum smc_llc_reqresp reqresp, bool orderly,\n--\nnet/smc/smc_llc.c-761-/* send LLC test link request */\nnet/smc/smc_llc.c:762:static int smc_llc_send_test_link(struct smc_link *link, u8 user_data[16])\nnet/smc/smc_llc.c-763-{\n--\nnet/smc/smc_llc.c-786-/* schedule an llc send on link, may wait for buffers */\nnet/smc/smc_llc.c:787:static int smc_llc_send_message(struct smc_link *link, void *llcbuf)\nnet/smc/smc_llc.c-788-{\n--\nnet/smc/smc_llc.c-808- */\nnet/smc/smc_llc.c:809:static int smc_llc_send_message_wait(struct smc_link *link, void *llcbuf)\nnet/smc/smc_llc.c-810-{\n--\nnet/smc/smc_llc.c-828-\nnet/smc/smc_llc.c:829:static int smc_llc_alloc_alt_link(struct smc_link_group *lgr,\nnet/smc/smc_llc.c-830-\t\t\t\t  enum smc_lgr_type lgr_new_t)\n--\nnet/smc/smc_llc.c-853-/* send one add_link_continue msg */\nnet/smc/smc_llc.c:854:static int smc_llc_add_link_cont(struct smc_link *link,\nnet/smc/smc_llc.c-855-\t\t\t\t struct smc_link *link_new, u8 *num_rkeys_todo,\n--\nnet/smc/smc_llc.c-908-\nnet/smc/smc_llc.c:909:static int smc_llc_cli_rkey_exchange(struct smc_link *link,\nnet/smc/smc_llc.c-910-\t\t\t\t     struct smc_link *link_new)\n--\nnet/smc/smc_llc.c-952-/* prepare and send an add link reject response */\nnet/smc/smc_llc.c:953:static int smc_llc_cli_add_link_reject(struct smc_llc_qentry *qentry)\nnet/smc/smc_llc.c-954-{\n--\nnet/smc/smc_llc.c-962-\nnet/smc/smc_llc.c:963:static int smc_llc_cli_conf_link(struct smc_link *link,\nnet/smc/smc_llc.c-964-\t\t\t\t struct smc_init_info *ini,\n--\nnet/smc/smc_llc.c-1020-\nnet/smc/smc_llc.c:1021:static void smc_llc_save_add_link_rkeys(struct smc_link *link,\nnet/smc/smc_llc.c-1022-\t\t\t\t\tstruct smc_link *link_new,\n--\nnet/smc/smc_llc.c-1046-\nnet/smc/smc_llc.c:1047:static void smc_llc_save_add_link_info(struct smc_link *link,\nnet/smc/smc_llc.c-1048-\t\t\t\t       struct smc_llc_msg_add_link *add_llc)\n--\nnet/smc/smc_llc.c-1057-/* as an SMC client, process an add link request */\nnet/smc/smc_llc.c:1058:int smc_llc_cli_add_link(struct smc_link *link, struct smc_llc_qentry *qentry)\nnet/smc/smc_llc.c-1059-{\n--\nnet/smc/smc_llc.c-1151-\nnet/smc/smc_llc.c:1152:static void smc_llc_send_request_add_link(struct smc_link *link)\nnet/smc/smc_llc.c-1153-{\n--\nnet/smc/smc_llc.c-1190-/* as an SMC client, invite server to start the add_link processing */\nnet/smc/smc_llc.c:1191:static void smc_llc_cli_add_link_invite(struct smc_link *link,\nnet/smc/smc_llc.c-1192-\t\t\t\t\tstruct smc_llc_qentry *qentry)\n--\nnet/smc/smc_llc.c=1235=static bool smc_llc_is_local_add_link(union smc_llc_msg *llc)\n--\nnet/smc/smc_llc.c-1242-\nnet/smc/smc_llc.c:1243:static void smc_llc_process_cli_add_link(struct smc_link_group *lgr)\nnet/smc/smc_llc.c-1244-{\n--\nnet/smc/smc_llc.c-1256-\nnet/smc/smc_llc.c:1257:static int smc_llc_active_link_count(struct smc_link_group *lgr)\nnet/smc/smc_llc.c-1258-{\n--\nnet/smc/smc_llc.c=1270=static struct smc_link *smc_llc_find_asym_link(struct smc_link_group *lgr)\n--\nnet/smc/smc_llc.c-1313-\nnet/smc/smc_llc.c:1314:static void smc_llc_delete_asym_link(struct smc_link_group *lgr)\nnet/smc/smc_llc.c-1315-{\n--\nnet/smc/smc_llc.c-1347-\nnet/smc/smc_llc.c:1348:static int smc_llc_srv_rkey_exchange(struct smc_link *link,\nnet/smc/smc_llc.c-1349-\t\t\t\t     struct smc_link *link_new)\n--\nnet/smc/smc_llc.c-1388-\nnet/smc/smc_llc.c:1389:static int smc_llc_srv_conf_link(struct smc_link *link,\nnet/smc/smc_llc.c-1390-\t\t\t\t struct smc_link *link_new,\n--\nnet/smc/smc_llc.c-1422-\nnet/smc/smc_llc.c:1423:static void smc_llc_send_req_add_link_response(struct smc_llc_qentry *qentry)\nnet/smc/smc_llc.c-1424-{\n--\nnet/smc/smc_llc.c-1431-\nnet/smc/smc_llc.c:1432:int smc_llc_srv_add_link(struct smc_link *link,\nnet/smc/smc_llc.c-1433-\t\t\t struct smc_llc_qentry *req_qentry)\n--\nnet/smc/smc_llc.c-1554-\nnet/smc/smc_llc.c:1555:static void smc_llc_process_srv_add_link(struct smc_link_group *lgr)\nnet/smc/smc_llc.c-1556-{\n--\nnet/smc/smc_llc.c-1573-/* enqueue a local add_link req to trigger a new add_link flow */\nnet/smc/smc_llc.c:1574:void smc_llc_add_link_local(struct smc_link *link)\nnet/smc/smc_llc.c-1575-{\n--\nnet/smc/smc_llc.c-1585-/* worker to process an add link message */\nnet/smc/smc_llc.c:1586:static void smc_llc_add_link_work(struct work_struct *work)\nnet/smc/smc_llc.c-1587-{\n--\nnet/smc/smc_llc.c-1608- */\nnet/smc/smc_llc.c:1609:void smc_llc_srv_delete_link_local(struct smc_link *link, u8 del_link_id)\nnet/smc/smc_llc.c-1610-{\n--\nnet/smc/smc_llc.c-1621-\nnet/smc/smc_llc.c:1622:static void smc_llc_process_cli_delete_link(struct smc_link_group *lgr)\nnet/smc/smc_llc.c-1623-{\n--\nnet/smc/smc_llc.c-1679- */\nnet/smc/smc_llc.c:1680:void smc_llc_send_link_delete_all(struct smc_link_group *lgr, bool ord, u32 rsn)\nnet/smc/smc_llc.c-1681-{\n--\nnet/smc/smc_llc.c-1699-\nnet/smc/smc_llc.c:1700:static void smc_llc_process_srv_delete_link(struct smc_link_group *lgr)\nnet/smc/smc_llc.c-1701-{\n--\nnet/smc/smc_llc.c-1767-\nnet/smc/smc_llc.c:1768:static void smc_llc_delete_link_work(struct work_struct *work)\nnet/smc/smc_llc.c-1769-{\n--\nnet/smc/smc_llc.c-1787-/* process a confirm_rkey request from peer, remote flow */\nnet/smc/smc_llc.c:1788:static void smc_llc_rmt_conf_rkey(struct smc_link_group *lgr)\nnet/smc/smc_llc.c-1789-{\n--\nnet/smc/smc_llc.c-1827-/* process a delete_rkey request from peer, remote flow */\nnet/smc/smc_llc.c:1828:static void smc_llc_rmt_delete_rkey(struct smc_link_group *lgr)\nnet/smc/smc_llc.c-1829-{\n--\nnet/smc/smc_llc.c-1889-\nnet/smc/smc_llc.c:1890:static void smc_llc_protocol_violation(struct smc_link_group *lgr, u8 type)\nnet/smc/smc_llc.c-1891-{\n--\nnet/smc/smc_llc.c-1899-/* flush the llc event queue */\nnet/smc/smc_llc.c:1900:static void smc_llc_event_flush(struct smc_link_group *lgr)\nnet/smc/smc_llc.c-1901-{\n--\nnet/smc/smc_llc.c-1911-\nnet/smc/smc_llc.c:1912:static void smc_llc_event_handler(struct smc_llc_qentry *qentry)\nnet/smc/smc_llc.c-1913-{\n--\nnet/smc/smc_llc.c-2033-/* worker to process llc messages on the event queue */\nnet/smc/smc_llc.c:2034:static void smc_llc_event_work(struct work_struct *work)\nnet/smc/smc_llc.c-2035-{\n--\nnet/smc/smc_llc.c-2062-/* process llc responses in tasklet context */\nnet/smc/smc_llc.c:2063:static void smc_llc_rx_response(struct smc_link *link,\nnet/smc/smc_llc.c-2064-\t\t\t\tstruct smc_llc_qentry *qentry)\n--\nnet/smc/smc_llc.c=2107=static u32 smc_llc_max_body_len(union smc_llc_msg *llc)\n--\nnet/smc/smc_llc.c-2121-\nnet/smc/smc_llc.c:2122:static void smc_llc_enqueue(struct smc_link *link, union smc_llc_msg *llc,\nnet/smc/smc_llc.c-2123-\t\t\t    u32 byte_len)\n--\nnet/smc/smc_llc.c-2167-/* copy received msg and add it to the event queue */\nnet/smc/smc_llc.c:2168:static void smc_llc_rx_handler(struct ib_wc *wc, void *buf)\nnet/smc/smc_llc.c-2169-{\n--\nnet/smc/smc_llc.c-2187-\nnet/smc/smc_llc.c:2188:static void smc_llc_testlink_work(struct work_struct *work)\nnet/smc/smc_llc.c-2189-{\n--\nnet/smc/smc_llc.c-2219-\nnet/smc/smc_llc.c:2220:void smc_llc_lgr_init(struct smc_link_group *lgr, struct smc_sock *smc)\nnet/smc/smc_llc.c-2221-{\n--\nnet/smc/smc_llc.c-2238-/* called after lgr was removed from lgr_list */\nnet/smc/smc_llc.c:2239:void smc_llc_lgr_clear(struct smc_link_group *lgr)\nnet/smc/smc_llc.c-2240-{\n--\nnet/smc/smc_llc.c-2252-\nnet/smc/smc_llc.c:2253:int smc_llc_link_init(struct smc_link *link)\nnet/smc/smc_llc.c-2254-{\n--\nnet/smc/smc_llc.c-2259-\nnet/smc/smc_llc.c:2260:void smc_llc_link_active(struct smc_link *link)\nnet/smc/smc_llc.c-2261-{\n--\nnet/smc/smc_llc.c-2277-/* called in worker context */\nnet/smc/smc_llc.c:2278:void smc_llc_link_clear(struct smc_link *link, bool log)\nnet/smc/smc_llc.c-2279-{\n--\nnet/smc/smc_llc.c-2292-/* register a new rtoken at the remote peer (for all links) */\nnet/smc/smc_llc.c:2293:int smc_llc_do_confirm_rkey(struct smc_link *send_link,\nnet/smc/smc_llc.c-2294-\t\t\t    struct smc_buf_desc *rmb_desc)\n--\nnet/smc/smc_llc.c-2314-/* unregister an rtoken at the remote peer */\nnet/smc/smc_llc.c:2315:int smc_llc_do_delete_rkey(struct smc_link_group *lgr,\nnet/smc/smc_llc.c-2316-\t\t\t   struct smc_buf_desc *rmb_desc)\n--\nnet/smc/smc_llc.c-2340-\nnet/smc/smc_llc.c:2341:void smc_llc_link_set_uid(struct smc_link *link)\nnet/smc/smc_llc.c-2342-{\n--\nnet/smc/smc_llc.c-2349-/* save peers link user id, used for debug purposes */\nnet/smc/smc_llc.c:2350:void smc_llc_save_peer_uid(struct smc_llc_qentry *qentry)\nnet/smc/smc_llc.c-2351-{\n--\nnet/smc/smc_llc.c-2356-/* evaluate confirm link request or response */\nnet/smc/smc_llc.c:2357:int smc_llc_eval_conf_link(struct smc_llc_qentry *qentry,\nnet/smc/smc_llc.c-2358-\t\t\t   enum smc_llc_reqresp type)\n"
}

17/2 2026/08/23 07:39 llm patch-evaluator
0m Model:
gemini-3.1-pro-preview

Args:
null

Results:
null

Tokens:
							input: 30240
							output: 54
							thoughts: 58
						

Thoughts:
Here's my summary, as if I were thinking these things:

**Analyzing SMC Link Initialization**

Okay, so `smc_llc_cli_add_link` and `smc_llc_srv_add_link` aren't static functions, which is important to remember. That probably means they're subject to some sort of dynamic behavior, which needs understanding. Right, let's dive into the core implementation. I need to track down exactly how these links are initialized. The obvious place to start is `net/smc/smc_core.c`. Specifically, I'm going to look for the `smcr_link_init` function. That seems like the logical starting point for understanding the complete initialization process and seeing what influences these non-static functions.



18/2 2026/08/23 07:39 tool grepper
0m Args:
{
  "Expression": "^(int|void|static int|static void) [a-zA-Z0-9_]+\\(",
  "PathPrefix": "net/smc/smc_core.c"
}

Results:
{
  "Output": "net/smc/smc_core.c=50=static DECLARE_WAIT_QUEUE_HEAD(lgrs_deleted);\nnet/smc/smc_core.c-51-\nnet/smc/smc_core.c:52:static void smc_buf_free(struct smc_link_group *lgr, bool is_rmb,\nnet/smc/smc_core.c-53-\t\t\t struct smc_buf_desc *buf_desc);\nnet/smc/smc_core.c:54:static void __smc_lgr_terminate(struct smc_link_group *lgr, bool soft);\nnet/smc/smc_core.c-55-\nnet/smc/smc_core.c:56:static void smc_link_down_work(struct work_struct *work);\nnet/smc/smc_core.c-57-\nnet/smc/smc_core.c:58:void smc_init_info_free(struct smc_init_info *ini)\nnet/smc/smc_core.c-59-{\n--\nnet/smc/smc_core.c=70=static inline struct list_head *smc_lgr_list_head(struct smc_link_group *lgr,\n--\nnet/smc/smc_core.c-81-\nnet/smc/smc_core.c:82:static void smc_ibdev_cnt_inc(struct smc_link *lnk)\nnet/smc/smc_core.c-83-{\n--\nnet/smc/smc_core.c-86-\nnet/smc/smc_core.c:87:static void smc_ibdev_cnt_dec(struct smc_link *lnk)\nnet/smc/smc_core.c-88-{\n--\nnet/smc/smc_core.c-91-\nnet/smc/smc_core.c:92:static void smc_lgr_schedule_free_work(struct smc_link_group *lgr)\nnet/smc/smc_core.c-93-{\n--\nnet/smc/smc_core.c-111- */\nnet/smc/smc_core.c:112:static void smc_lgr_add_alert_token(struct smc_connection *conn)\nnet/smc/smc_core.c-113-{\n--\nnet/smc/smc_core.c-133-/* assign an SMC-R link to the connection */\nnet/smc/smc_core.c:134:static int smcr_lgr_conn_assign_link(struct smc_connection *conn, bool first)\nnet/smc/smc_core.c-135-{\n--\nnet/smc/smc_core.c-177- */\nnet/smc/smc_core.c:178:static int smc_lgr_register_conn(struct smc_connection *conn, bool first)\nnet/smc/smc_core.c-179-{\n--\nnet/smc/smc_core.c-206- */\nnet/smc/smc_core.c:207:static void __smc_lgr_unregister_conn(struct smc_connection *conn)\nnet/smc/smc_core.c-208-{\n--\nnet/smc/smc_core.c-221- */\nnet/smc/smc_core.c:222:static void smc_lgr_unregister_conn(struct smc_connection *conn)\nnet/smc/smc_core.c-223-{\n--\nnet/smc/smc_core.c-234-\nnet/smc/smc_core.c:235:static void smc_lgr_buf_list_add(struct smc_link_group *lgr,\nnet/smc/smc_core.c-236-\t\t\t\t bool is_rmb,\n--\nnet/smc/smc_core.c-249-\nnet/smc/smc_core.c:250:static void smc_lgr_buf_list_del(struct smc_link_group *lgr,\nnet/smc/smc_core.c-251-\t\t\t\t bool is_rmb,\n--\nnet/smc/smc_core.c-263-\nnet/smc/smc_core.c:264:int smc_nl_get_sys_info(struct sk_buff *skb, struct netlink_callback *cb)\nnet/smc/smc_core.c-265-{\n--\nnet/smc/smc_core.c-319-/* Fill SMC_NLA_LGR_D_V2_COMMON/SMC_NLA_LGR_R_V2_COMMON nested attributes */\nnet/smc/smc_core.c:320:static int smc_nl_fill_lgr_v2_common(struct smc_link_group *lgr,\nnet/smc/smc_core.c-321-\t\t\t\t     struct sk_buff *skb,\n--\nnet/smc/smc_core.c-350-\nnet/smc/smc_core.c:351:static int smc_nl_fill_smcr_lgr_v2(struct smc_link_group *lgr,\nnet/smc/smc_core.c-352-\t\t\t\t   struct sk_buff *skb,\n--\nnet/smc/smc_core.c-375-\nnet/smc/smc_core.c:376:static int smc_nl_fill_lgr(struct smc_link_group *lgr,\nnet/smc/smc_core.c-377-\t\t\t   struct sk_buff *skb,\n--\nnet/smc/smc_core.c-427-\nnet/smc/smc_core.c:428:static int smc_nl_fill_lgr_link(struct smc_link_group *lgr,\nnet/smc/smc_core.c-429-\t\t\t\tstruct smc_link *link,\n--\nnet/smc/smc_core.c-488-\nnet/smc/smc_core.c:489:static int smc_nl_handle_lgr(struct smc_link_group *lgr,\nnet/smc/smc_core.c-490-\t\t\t     struct sk_buff *skb,\n--\nnet/smc/smc_core.c-522-\nnet/smc/smc_core.c:523:static void smc_nl_fill_lgr_list(struct smc_lgr_list *smc_lgr,\nnet/smc/smc_core.c-524-\t\t\t\t struct sk_buff *skb,\n--\nnet/smc/smc_core.c-546-\nnet/smc/smc_core.c:547:static int smc_nl_fill_smcd_lgr(struct smc_link_group *lgr,\nnet/smc/smc_core.c-548-\t\t\t\tstruct sk_buff *skb,\n--\nnet/smc/smc_core.c-616-\nnet/smc/smc_core.c:617:static int smc_nl_handle_smcd_lgr(struct smcd_dev *dev,\nnet/smc/smc_core.c-618-\t\t\t\t  struct sk_buff *skb,\n--\nnet/smc/smc_core.c-643-\nnet/smc/smc_core.c:644:static int smc_nl_fill_smcd_dev(struct smcd_dev_list *dev_list,\nnet/smc/smc_core.c-645-\t\t\t\tstruct sk_buff *skb,\n--\nnet/smc/smc_core.c-670-\nnet/smc/smc_core.c:671:int smcr_nl_get_lgr(struct sk_buff *skb, struct netlink_callback *cb)\nnet/smc/smc_core.c-672-{\n--\nnet/smc/smc_core.c-678-\nnet/smc/smc_core.c:679:int smcr_nl_get_link(struct sk_buff *skb, struct netlink_callback *cb)\nnet/smc/smc_core.c-680-{\n--\nnet/smc/smc_core.c-686-\nnet/smc/smc_core.c:687:int smcd_nl_get_lgr(struct sk_buff *skb, struct netlink_callback *cb)\nnet/smc/smc_core.c-688-{\n--\nnet/smc/smc_core.c-692-\nnet/smc/smc_core.c:693:void smc_lgr_cleanup_early(struct smc_link_group *lgr)\nnet/smc/smc_core.c-694-{\n--\nnet/smc/smc_core.c-708-\nnet/smc/smc_core.c:709:static void smcr_lgr_link_deactivate_all(struct smc_link_group *lgr)\nnet/smc/smc_core.c-710-{\n--\nnet/smc/smc_core.c-722-\nnet/smc/smc_core.c:723:static void smc_lgr_free(struct smc_link_group *lgr);\nnet/smc/smc_core.c-724-\nnet/smc/smc_core.c:725:static void smc_lgr_free_work(struct work_struct *work)\nnet/smc/smc_core.c-726-{\n--\nnet/smc/smc_core.c-760-\nnet/smc/smc_core.c:761:static void smc_lgr_terminate_work(struct work_struct *work)\nnet/smc/smc_core.c-762-{\n--\nnet/smc/smc_core.c=770=static u8 smcr_next_link_id(struct smc_link_group *lgr)\n--\nnet/smc/smc_core.c-789-\nnet/smc/smc_core.c:790:static void smcr_copy_dev_info_to_link(struct smc_link *link)\nnet/smc/smc_core.c-791-{\n--\nnet/smc/smc_core.c-798-\nnet/smc/smc_core.c:799:int smcr_link_init(struct smc_link_group *lgr, struct smc_link *lnk,\nnet/smc/smc_core.c-800-\t\t   u8 link_idx, struct smc_init_info *ini)\n--\nnet/smc/smc_core.c-907-/* create a new SMC link group */\nnet/smc/smc_core.c:908:static int smc_lgr_create(struct smc_sock *smc, struct smc_init_info *ini)\nnet/smc/smc_core.c-909-{\n--\nnet/smc/smc_core.c-1039-\nnet/smc/smc_core.c:1040:static int smc_write_space(struct smc_connection *conn)\nnet/smc/smc_core.c-1041-{\n--\nnet/smc/smc_core.c-1053-\nnet/smc/smc_core.c:1054:static int smc_switch_cursor(struct smc_sock *smc, struct smc_cdc_tx_pend *pend,\nnet/smc/smc_core.c-1055-\t\t\t     struct smc_wr_buf *wr_buf)\n--\nnet/smc/smc_core.c-1103-\nnet/smc/smc_core.c:1104:void smc_switch_link_and_count(struct smc_connection *conn,\nnet/smc/smc_core.c-1105-\t\t\t       struct smc_link *to_lnk)\n--\nnet/smc/smc_core.c=1116=struct smc_link *smc_switch_conns(struct smc_link_group *lgr,\n--\nnet/smc/smc_core.c-1193-\nnet/smc/smc_core.c:1194:static void smcr_buf_unuse(struct smc_buf_desc *buf_desc, bool is_rmb,\nnet/smc/smc_core.c-1195-\t\t\t   struct smc_link_group *lgr)\n--\nnet/smc/smc_core.c-1228-\nnet/smc/smc_core.c:1229:static void smcd_buf_detach(struct smc_connection *conn)\nnet/smc/smc_core.c-1230-{\n--\nnet/smc/smc_core.c-1244-\nnet/smc/smc_core.c:1245:static void smc_buf_unuse(struct smc_connection *conn,\nnet/smc/smc_core.c-1246-\t\t\t  struct smc_link_group *lgr)\n--\nnet/smc/smc_core.c-1275-/* remove a finished connection from its link group */\nnet/smc/smc_core.c:1276:void smc_conn_free(struct smc_connection *conn)\nnet/smc/smc_core.c-1277-{\n--\nnet/smc/smc_core.c-1316-/* unregister a link from a buf_desc */\nnet/smc/smc_core.c:1317:static void smcr_buf_unmap_link(struct smc_buf_desc *buf_desc, bool is_rmb,\nnet/smc/smc_core.c-1318-\t\t\t\tstruct smc_link *lnk)\n--\nnet/smc/smc_core.c-1339-/* unmap all buffers of lgr for a deleted link */\nnet/smc/smc_core.c:1340:static void smcr_buf_unmap_lgr(struct smc_link *lnk)\nnet/smc/smc_core.c-1341-{\n--\nnet/smc/smc_core.c-1359-\nnet/smc/smc_core.c:1360:static void smcr_rtoken_clear_link(struct smc_link *lnk)\nnet/smc/smc_core.c-1361-{\n--\nnet/smc/smc_core.c-1370-\nnet/smc/smc_core.c:1371:static void __smcr_link_clear(struct smc_link *lnk)\nnet/smc/smc_core.c-1372-{\n--\nnet/smc/smc_core.c-1387-/* must be called under lgr-\u003ellc_conf_mutex lock */\nnet/smc/smc_core.c:1388:void smcr_link_clear(struct smc_link *lnk, bool log)\nnet/smc/smc_core.c-1389-{\n--\nnet/smc/smc_core.c-1404-\nnet/smc/smc_core.c:1405:void smcr_link_hold(struct smc_link *lnk)\nnet/smc/smc_core.c-1406-{\n--\nnet/smc/smc_core.c-1409-\nnet/smc/smc_core.c:1410:void smcr_link_put(struct smc_link *lnk)\nnet/smc/smc_core.c-1411-{\n--\nnet/smc/smc_core.c-1415-\nnet/smc/smc_core.c:1416:static void smcr_buf_free(struct smc_link_group *lgr, bool is_rmb,\nnet/smc/smc_core.c-1417-\t\t\t  struct smc_buf_desc *buf_desc)\n--\nnet/smc/smc_core.c-1430-\nnet/smc/smc_core.c:1431:static void smcd_buf_free(struct smc_link_group *lgr, bool is_dmb,\nnet/smc/smc_core.c-1432-\t\t\t  struct smc_buf_desc *buf_desc)\n--\nnet/smc/smc_core.c-1443-\nnet/smc/smc_core.c:1444:static void smc_buf_free(struct smc_link_group *lgr, bool is_rmb,\nnet/smc/smc_core.c-1445-\t\t\t struct smc_buf_desc *buf_desc)\n--\nnet/smc/smc_core.c-1452-\nnet/smc/smc_core.c:1453:static void __smc_lgr_free_bufs(struct smc_link_group *lgr, bool is_rmb)\nnet/smc/smc_core.c-1454-{\n--\nnet/smc/smc_core.c-1471-\nnet/smc/smc_core.c:1472:static void smc_lgr_free_bufs(struct smc_link_group *lgr)\nnet/smc/smc_core.c-1473-{\n--\nnet/smc/smc_core.c-1480-/* won't be freed until no one accesses to lgr anymore */\nnet/smc/smc_core.c:1481:static void __smc_lgr_free(struct smc_link_group *lgr)\nnet/smc/smc_core.c-1482-{\n--\nnet/smc/smc_core.c-1495-/* remove a link group */\nnet/smc/smc_core.c:1496:static void smc_lgr_free(struct smc_link_group *lgr)\nnet/smc/smc_core.c-1497-{\n--\nnet/smc/smc_core.c-1517-\nnet/smc/smc_core.c:1518:void smc_lgr_hold(struct smc_link_group *lgr)\nnet/smc/smc_core.c-1519-{\n--\nnet/smc/smc_core.c-1522-\nnet/smc/smc_core.c:1523:void smc_lgr_put(struct smc_link_group *lgr)\nnet/smc/smc_core.c-1524-{\n--\nnet/smc/smc_core.c-1528-\nnet/smc/smc_core.c:1529:static void smc_sk_wake_ups(struct smc_sock *smc)\nnet/smc/smc_core.c-1530-{\n--\nnet/smc/smc_core.c-1536-/* kill a connection */\nnet/smc/smc_core.c:1537:static void smc_conn_kill(struct smc_connection *conn, bool soft)\nnet/smc/smc_core.c-1538-{\n--\nnet/smc/smc_core.c-1562-\nnet/smc/smc_core.c:1563:static void smc_lgr_cleanup(struct smc_link_group *lgr)\nnet/smc/smc_core.c-1564-{\n--\nnet/smc/smc_core.c-1580- */\nnet/smc/smc_core.c:1581:static void __smc_lgr_terminate(struct smc_link_group *lgr, bool soft)\nnet/smc/smc_core.c-1582-{\n--\nnet/smc/smc_core.c-1613-/* unlink link group and schedule termination */\nnet/smc/smc_core.c:1614:void smc_lgr_terminate_sched(struct smc_link_group *lgr)\nnet/smc/smc_core.c-1615-{\n--\nnet/smc/smc_core.c-1630-/* Called when peer lgr shutdown (regularly or abnormally) is received */\nnet/smc/smc_core.c:1631:void smc_smcd_terminate(struct smcd_dev *dev, struct smcd_gid *peer_gid,\nnet/smc/smc_core.c-1632-\t\t\tunsigned short vlan)\n--\nnet/smc/smc_core.c-1660-/* Called when an SMCD device is removed or the smc module is unloaded */\nnet/smc/smc_core.c:1661:void smc_smcd_terminate_all(struct smcd_dev *smcd)\nnet/smc/smc_core.c-1662-{\n--\nnet/smc/smc_core.c-1684- */\nnet/smc/smc_core.c:1685:void smc_smcr_terminate_all(struct smc_ib_device *smcibdev)\nnet/smc/smc_core.c-1686-{\n--\nnet/smc/smc_core.c-1722-/* set new lgr type and clear all asymmetric link tagging */\nnet/smc/smc_core.c:1723:void smcr_lgr_set_type(struct smc_link_group *lgr, enum smc_lgr_type new_type)\nnet/smc/smc_core.c-1724-{\n--\nnet/smc/smc_core.c-1757-/* set new lgr type and tag a link as asymmetric */\nnet/smc/smc_core.c:1758:void smcr_lgr_set_type_asym(struct smc_link_group *lgr,\nnet/smc/smc_core.c-1759-\t\t\t    enum smc_lgr_type new_type, int asym_lnk_idx)\n--\nnet/smc/smc_core.c-1765-/* abort connection, abort_work scheduled from tasklet context */\nnet/smc/smc_core.c:1766:static void smc_conn_abort_work(struct work_struct *work)\nnet/smc/smc_core.c-1767-{\n--\nnet/smc/smc_core.c-1778-\nnet/smc/smc_core.c:1779:void smcr_port_add(struct smc_ib_device *smcibdev, u8 ibport)\nnet/smc/smc_core.c-1780-{\n--\nnet/smc/smc_core.c-1807- */\nnet/smc/smc_core.c:1808:static void smcr_link_down(struct smc_link *lnk)\nnet/smc/smc_core.c-1809-{\n--\nnet/smc/smc_core.c-1848-/* must be called under lgr-\u003ellc_conf_mutex lock */\nnet/smc/smc_core.c:1849:void smcr_link_down_cond(struct smc_link *lnk)\nnet/smc/smc_core.c-1850-{\n--\nnet/smc/smc_core.c-1857-/* will get the lgr-\u003ellc_conf_mutex lock */\nnet/smc/smc_core.c:1858:void smcr_link_down_cond_sched(struct smc_link *lnk)\nnet/smc/smc_core.c-1859-{\n--\nnet/smc/smc_core.c-1867-\nnet/smc/smc_core.c:1868:void smcr_port_err(struct smc_ib_device *smcibdev, u8 ibport)\nnet/smc/smc_core.c-1869-{\n--\nnet/smc/smc_core.c-1888-\nnet/smc/smc_core.c:1889:static void smc_link_down_work(struct work_struct *work)\nnet/smc/smc_core.c-1890-{\n--\nnet/smc/smc_core.c-1905-\nnet/smc/smc_core.c:1906:static int smc_vlan_by_tcpsk_walk(struct net_device *lower_dev,\nnet/smc/smc_core.c-1907-\t\t\t\t  struct netdev_nested_priv *priv)\n--\nnet/smc/smc_core.c-1919-/* Determine vlan of internal TCP socket. */\nnet/smc/smc_core.c:1920:int smc_vlan_by_tcpsk(struct socket *clcsock, struct smc_init_info *ini)\nnet/smc/smc_core.c-1921-{\n--\nnet/smc/smc_core.c=1982=static bool smcd_lgr_match(struct smc_link_group *lgr,\n--\nnet/smc/smc_core.c-1997-/* create a new SMC connection (and a new link group if necessary) */\nnet/smc/smc_core.c:1998:int smc_conn_create(struct smc_sock *smc, struct smc_init_info *ini)\nnet/smc/smc_core.c-1999-{\n--\nnet/smc/smc_core.c=2104=static u8 smc_compress_bufsize(int size, bool is_smcd, bool is_rmb)\n--\nnet/smc/smc_core.c-2124-/* convert the RMB size from compressed notation into integer */\nnet/smc/smc_core.c:2125:int smc_uncompress_bufsize(u8 compressed)\nnet/smc/smc_core.c-2126-{\n--\nnet/smc/smc_core.c=2156=static inline int smc_rmb_wnd_update_limit(int rmbe_size)\n--\nnet/smc/smc_core.c-2161-/* map an buf to a link */\nnet/smc/smc_core.c:2162:static int smcr_buf_map_link(struct smc_buf_desc *buf_desc, bool is_rmb,\nnet/smc/smc_core.c-2163-\t\t\t     struct smc_link *lnk)\n--\nnet/smc/smc_core.c-2238- */\nnet/smc/smc_core.c:2239:int smcr_link_reg_buf(struct smc_link *link, struct smc_buf_desc *buf_desc)\nnet/smc/smc_core.c-2240-{\n--\nnet/smc/smc_core.c-2256-\nnet/smc/smc_core.c:2257:static int _smcr_buf_map_lgr(struct smc_link *lnk, struct rw_semaphore *lock,\nnet/smc/smc_core.c-2258-\t\t\t     struct list_head *lst, bool is_rmb)\n--\nnet/smc/smc_core.c-2276-/* map all used buffers of lgr for a new link */\nnet/smc/smc_core.c:2277:int smcr_buf_map_lgr(struct smc_link *lnk)\nnet/smc/smc_core.c-2278-{\n--\nnet/smc/smc_core.c-2297- */\nnet/smc/smc_core.c:2298:int smcr_buf_reg_lgr(struct smc_link *lnk)\nnet/smc/smc_core.c-2299-{\n--\nnet/smc/smc_core.c=2339=static struct smc_buf_desc *smcr_new_buf_create(struct smc_link_group *lgr,\n--\nnet/smc/smc_core.c-2386- */\nnet/smc/smc_core.c:2387:static int smcr_buf_map_usable_links(struct smc_link_group *lgr,\nnet/smc/smc_core.c-2388-\t\t\t\t     struct smc_buf_desc *buf_desc, bool is_rmb)\n--\nnet/smc/smc_core.c=2412=static struct smc_buf_desc *smcd_new_buf_create(struct smc_link_group *lgr,\n--\nnet/smc/smc_core.c-2447-\nnet/smc/smc_core.c:2448:static int __smc_buf_create(struct smc_sock *smc, bool is_smcd, bool is_rmb)\nnet/smc/smc_core.c-2449-{\n--\nnet/smc/smc_core.c-2539-\nnet/smc/smc_core.c:2540:void smc_sndbuf_sync_sg_for_device(struct smc_connection *conn)\nnet/smc/smc_core.c-2541-{\n--\nnet/smc/smc_core.c-2549-\nnet/smc/smc_core.c:2550:void smc_rmb_sync_sg_for_cpu(struct smc_connection *conn)\nnet/smc/smc_core.c-2551-{\n--\nnet/smc/smc_core.c-2571- */\nnet/smc/smc_core.c:2572:int smc_buf_create(struct smc_sock *smc, bool is_smcd)\nnet/smc/smc_core.c-2573-{\n--\nnet/smc/smc_core.c-2598-\nnet/smc/smc_core.c:2599:int smcd_buf_attach(struct smc_sock *smc)\nnet/smc/smc_core.c-2600-{\n--\nnet/smc/smc_core.c=2634=static inline int smc_rmb_reserve_rtoken_idx(struct smc_link_group *lgr)\n--\nnet/smc/smc_core.c-2644-\nnet/smc/smc_core.c:2645:static int smc_rtoken_find_by_link(struct smc_link_group *lgr, int lnk_idx,\nnet/smc/smc_core.c-2646-\t\t\t\t   u32 rkey)\n--\nnet/smc/smc_core.c-2658-/* set rtoken for a new link to an existing rmb */\nnet/smc/smc_core.c:2659:void smc_rtoken_set(struct smc_link_group *lgr, int link_idx, int link_idx_new,\nnet/smc/smc_core.c-2660-\t\t    __be32 nw_rkey_known, __be64 nw_vaddr, __be32 nw_rkey)\n--\nnet/smc/smc_core.c-2671-/* set rtoken for a new link whose link_id is given */\nnet/smc/smc_core.c:2672:void smc_rtoken_set2(struct smc_link_group *lgr, int rtok_idx, int link_id,\nnet/smc/smc_core.c-2673-\t\t     __be64 nw_vaddr, __be32 nw_rkey)\n--\nnet/smc/smc_core.c-2692-/* add a new rtoken from peer */\nnet/smc/smc_core.c:2693:int smc_rtoken_add(struct smc_link *lnk, __be64 nw_vaddr, __be32 nw_rkey)\nnet/smc/smc_core.c-2694-{\n--\nnet/smc/smc_core.c-2716-/* delete an rtoken from all links */\nnet/smc/smc_core.c:2717:int smc_rtoken_delete(struct smc_link *lnk, __be32 nw_rkey)\nnet/smc/smc_core.c-2718-{\n--\nnet/smc/smc_core.c-2737-/* save rkey and dma_addr received from peer during clc handshake */\nnet/smc/smc_core.c:2738:int smc_rmb_rtoken_handling(struct smc_connection *conn,\nnet/smc/smc_core.c-2739-\t\t\t    struct smc_link *lnk,\n--\nnet/smc/smc_core.c-2748-\nnet/smc/smc_core.c:2749:static void smc_core_going_away(void)\nnet/smc/smc_core.c-2750-{\n--\nnet/smc/smc_core.c-2770-/* Clean up all SMC link groups */\nnet/smc/smc_core.c:2771:static void smc_lgrs_shutdown(void)\nnet/smc/smc_core.c-2772-{\n--\nnet/smc/smc_core.c-2784-\nnet/smc/smc_core.c:2785:static int smc_core_reboot_event(struct notifier_block *this,\nnet/smc/smc_core.c-2786-\t\t\t\t unsigned long event, void *ptr)\n--\nnet/smc/smc_core.c=2798=int __init smc_core_init(void)\n--\nnet/smc/smc_core.c-2803-/* Called (from smc_exit) when module is removed */\nnet/smc/smc_core.c:2804:void smc_core_exit(void)\nnet/smc/smc_core.c-2805-{\n"
}

19/2 2026/08/23 07:39 llm patch-evaluator
0m Model:
gemini-3.1-pro-preview

Args:
null

Results:
null

Tokens:
							input: 39509
							output: 55
							thoughts: 235
						

Thoughts:
**Fuzzing Target Selection**

Okay, so I'm looking at these functions, trying to figure out the best targets for fuzzing this SMC code. I see that `smcr_link_init`, `smc_ibdev_init_begin`, `smc_ibdev_init_end`, `smc_ibdev_get`, `smc_ibdev_put`, and `smc_init_info_free` are all non-static. Good, that broadens the scope for potential instrumentation.

However, the real question is which ones are *interesting* for fuzzing. I'm focusing on the ones that represent key logic or are likely to have complex state transitions. I'm thinking `smc_connect`, `smc_listen`, `smc_llc_cli_add_link`, `smc_llc_srv_add_link`, and `smcr_link_init` are the prime candidates.

But wait a minute... `smc_connect` and `smc_listen` are standard syscalls, right? They're going to be heavily exercised paths for any socket-based communication. I'm probably going to find tons of existing fuzzing on those, and the SMC-specific logic embedded there might be minimal. It's likely that focusing on `smc_llc_cli_add_link`, `smc_llc_srv_add_link`, and `smcr_link_init` will give me more "bang for my buck." They seem more SMC-specific and less likely to be saturated with standard socket fuzzing.

Now, I'm also seeing that `smc_pnet_determine_gid` has been modified. I need to double-check if that's static, because I could've missed it at the start.



20/2 2026/08/23 07:39 tool grepper
0m Args:
{
  "Expression": "^(int|void|static int|static void) [a-zA-Z0-9_]+\\(",
  "PathPrefix": "net/smc/smc_pnet.c"
}

Results:
{
  "Output": "net/smc/smc_pnet.c=85=static bool smc_pnet_match(u8 *pnetid1, u8 *pnetid2)\n--\nnet/smc/smc_pnet.c-100- */\nnet/smc/smc_pnet.c:101:static int smc_pnet_remove_by_pnetid(struct net *net, char *pnet_name)\nnet/smc/smc_pnet.c-102-{\n--\nnet/smc/smc_pnet.c-184- */\nnet/smc/smc_pnet.c:185:static int smc_pnet_add_by_ndev(struct net_device *ndev)\nnet/smc/smc_pnet.c-186-{\n--\nnet/smc/smc_pnet.c-216- */\nnet/smc/smc_pnet.c:217:static int smc_pnet_remove_by_ndev(struct net_device *ndev)\nnet/smc/smc_pnet.c-218-{\n--\nnet/smc/smc_pnet.c=329=static struct smcd_dev *smc_pnet_find_smcd(char *smcd_name)\n--\nnet/smc/smc_pnet.c-347-\nnet/smc/smc_pnet.c:348:static int smc_pnet_add_eth(struct smc_pnettable *pnettable, struct net *net,\nnet/smc/smc_pnet.c-349-\t\t\t    char *eth_name, char *pnet_name)\n--\nnet/smc/smc_pnet.c-410-\nnet/smc/smc_pnet.c:411:static int smc_pnet_add_ib(struct smc_pnettable *pnettable, char *ib_name,\nnet/smc/smc_pnet.c-412-\t\t\t   u8 ib_port, char *pnet_name)\n--\nnet/smc/smc_pnet.c-476- */\nnet/smc/smc_pnet.c:477:static int smc_pnet_enter(struct net *net, struct nlattr *tb[])\nnet/smc/smc_pnet.c-478-{\n--\nnet/smc/smc_pnet.c-533-/* Convert an smc_pnetentry to a netlink attribute sequence */\nnet/smc/smc_pnet.c:534:static int smc_pnet_set_nla(struct sk_buff *msg,\nnet/smc/smc_pnet.c-535-\t\t\t    struct smc_pnetentry *pnetelem)\n--\nnet/smc/smc_pnet.c-559-\nnet/smc/smc_pnet.c:560:static int smc_pnet_add(struct sk_buff *skb, struct genl_info *info)\nnet/smc/smc_pnet.c-561-{\n--\nnet/smc/smc_pnet.c-566-\nnet/smc/smc_pnet.c:567:static int smc_pnet_del(struct sk_buff *skb, struct genl_info *info)\nnet/smc/smc_pnet.c-568-{\n--\nnet/smc/smc_pnet.c-576-\nnet/smc/smc_pnet.c:577:static int smc_pnet_dump_start(struct netlink_callback *cb)\nnet/smc/smc_pnet.c-578-{\n--\nnet/smc/smc_pnet.c-582-\nnet/smc/smc_pnet.c:583:static int smc_pnet_dumpinfo(struct sk_buff *skb,\nnet/smc/smc_pnet.c-584-\t\t\t     u32 portid, u32 seq, u32 flags,\n--\nnet/smc/smc_pnet.c-600-\nnet/smc/smc_pnet.c:601:static int _smc_pnet_dump(struct net *net, struct sk_buff *skb, u32 portid,\nnet/smc/smc_pnet.c-602-\t\t\t  u32 seq, u8 *pnetid, int start_idx)\n--\nnet/smc/smc_pnet.c-632-\nnet/smc/smc_pnet.c:633:static int smc_pnet_dump(struct sk_buff *skb, struct netlink_callback *cb)\nnet/smc/smc_pnet.c-634-{\n--\nnet/smc/smc_pnet.c-645-/* Retrieve one PNETID entry */\nnet/smc/smc_pnet.c:646:static int smc_pnet_get(struct sk_buff *skb, struct genl_info *info)\nnet/smc/smc_pnet.c-647-{\n--\nnet/smc/smc_pnet.c-673- */\nnet/smc/smc_pnet.c:674:static int smc_pnet_flush(struct sk_buff *skb, struct genl_info *info)\nnet/smc/smc_pnet.c-675-{\n--\nnet/smc/smc_pnet.c=726=bool smc_pnet_is_ndev_pnetid(struct net *net, u8 *pnetid)\n--\nnet/smc/smc_pnet.c-744-\nnet/smc/smc_pnet.c:745:static int smc_pnet_add_pnetid(struct net *net, u8 *pnetid)\nnet/smc/smc_pnet.c-746-{\n--\nnet/smc/smc_pnet.c-770-\nnet/smc/smc_pnet.c:771:static void smc_pnet_remove_pnetid(struct net *net, u8 *pnetid)\nnet/smc/smc_pnet.c-772-{\n--\nnet/smc/smc_pnet.c-788-\nnet/smc/smc_pnet.c:789:static void smc_pnet_add_base_pnetid(struct net *net, struct net_device *dev,\nnet/smc/smc_pnet.c-790-\t\t\t\t     u8 *ndev_pnetid)\n--\nnet/smc/smc_pnet.c-803-/* create initial list of netdevice pnetids */\nnet/smc/smc_pnet.c:804:static void smc_pnet_create_pnetids_list(struct net *net)\nnet/smc/smc_pnet.c-805-{\n--\nnet/smc/smc_pnet.c-825-/* clean up list of netdevice pnetids */\nnet/smc/smc_pnet.c:826:static void smc_pnet_destroy_pnetids_list(struct net *net)\nnet/smc/smc_pnet.c-827-{\n--\nnet/smc/smc_pnet.c-838-\nnet/smc/smc_pnet.c:839:static int smc_pnet_netdev_event(struct notifier_block *this,\nnet/smc/smc_pnet.c-840-\t\t\t\t unsigned long event, void *ptr)\n--\nnet/smc/smc_pnet.c=872=static struct notifier_block smc_netdev_notifier = {\n--\nnet/smc/smc_pnet.c-876-/* init network namespace */\nnet/smc/smc_pnet.c:877:int smc_pnet_net_init(struct net *net)\nnet/smc/smc_pnet.c-878-{\n--\nnet/smc/smc_pnet.c=893=int __init smc_pnet_init(void)\n--\nnet/smc/smc_pnet.c-907-/* exit network namespace */\nnet/smc/smc_pnet.c:908:void smc_pnet_net_exit(struct net *net)\nnet/smc/smc_pnet.c-909-{\n--\nnet/smc/smc_pnet.c-914-\nnet/smc/smc_pnet.c:915:void smc_pnet_exit(void)\nnet/smc/smc_pnet.c-916-{\n--\nnet/smc/smc_pnet.c=943=static struct net_device *pnet_find_base_ndev(struct net_device *ndev)\n--\nnet/smc/smc_pnet.c-950-\nnet/smc/smc_pnet.c:951:static int smc_pnet_find_ndev_pnetid_by_table(struct net_device *ndev,\nnet/smc/smc_pnet.c-952-\t\t\t\t\t      u8 *pnetid)\n--\nnet/smc/smc_pnet.c-976-\nnet/smc/smc_pnet.c:977:static int smc_pnet_determine_gid(struct smc_ib_device *ibdev, int i,\nnet/smc/smc_pnet.c-978-\t\t\t\t  struct smc_init_info *ini)\n--\nnet/smc/smc_pnet.c-1005-/* find a roce device for the given pnetid */\nnet/smc/smc_pnet.c:1006:static void _smc_pnet_find_roce_by_pnetid(u8 *pnet_id,\nnet/smc/smc_pnet.c-1007-\t\t\t\t\t  struct smc_init_info *ini,\n--\nnet/smc/smc_pnet.c-1034-/* find alternate roce device with same pnet_id, vlan_id and net namespace */\nnet/smc/smc_pnet.c:1035:void smc_pnet_find_alt_roce(struct smc_link_group *lgr,\nnet/smc/smc_pnet.c-1036-\t\t\t    struct smc_init_info *ini,\n--\nnet/smc/smc_pnet.c-1046- */\nnet/smc/smc_pnet.c:1047:static void smc_pnet_find_rdma_dev(struct net_device *netdev,\nnet/smc/smc_pnet.c-1048-\t\t\t\t   struct smc_init_info *ini)\n--\nnet/smc/smc_pnet.c-1085- */\nnet/smc/smc_pnet.c:1086:static void smc_pnet_find_roce_by_pnetid(struct net_device *ndev,\nnet/smc/smc_pnet.c-1087-\t\t\t\t\t struct smc_init_info *ini)\n--\nnet/smc/smc_pnet.c-1104-\nnet/smc/smc_pnet.c:1105:static void smc_pnet_find_ism_by_pnetid(struct net_device *ndev,\nnet/smc/smc_pnet.c-1106-\t\t\t\t\tstruct smc_init_info *ini)\n--\nnet/smc/smc_pnet.c-1134- */\nnet/smc/smc_pnet.c:1135:void smc_pnet_find_roce_resource(struct sock *sk, struct smc_init_info *ini)\nnet/smc/smc_pnet.c-1136-{\n--\nnet/smc/smc_pnet.c-1151-\nnet/smc/smc_pnet.c:1152:void smc_pnet_find_ism_resource(struct sock *sk, struct smc_init_info *ini)\nnet/smc/smc_pnet.c-1153-{\n--\nnet/smc/smc_pnet.c-1172- */\nnet/smc/smc_pnet.c:1173:int smc_pnetid_by_table_ib(struct smc_ib_device *smcibdev, u8 ib_port)\nnet/smc/smc_pnet.c-1174-{\n--\nnet/smc/smc_pnet.c-1201- */\nnet/smc/smc_pnet.c:1202:int smc_pnetid_by_table_smcd(struct smcd_dev *smcddev)\nnet/smc/smc_pnet.c-1203-{\n"
}

21/2 2026/08/23 07:39 llm patch-evaluator
0m Model:
gemini-3.1-pro-preview

Args:
null

Results:
null

Tokens:
							input: 43573
							output: 29
							thoughts: 1123
						

Thoughts:
**Refining the Target List for Fuzzing**

Okay, so I'm looking at this code and trying to narrow down the best functions for fuzzing. `smc_pnet_determine_gid` is static, which means it's not directly accessible from outside its compilation unit – that's off the table. Now, the non-static functions related to this one are the ones I'm interested in.

First pass: I've identified `smcr_link_init`, `smc_ibdev_init_begin`, `smc_ibdev_init_end`, `smc_ibdev_get`, `smc_ibdev_put`, `smc_init_info_free`, `smc_llc_cli_add_link`, and `smc_llc_srv_add_link`. I need to sort these.

Are `smc_ibdev_init_begin` and `smc_ibdev_init_end` actually exported? Ah, no, they're just non-static, so the same scoping rules still apply. That makes `smc_llc_cli_add_link` and `smc_llc_srv_add_link` attractive candidates because they're likely involved in handling network communication, which is a common fuzzing target. `smcr_link_init` also seems promising as a core initialization function. `smc_init_info_free` looks like a cleanup function, so I'll keep an eye on it, but it might not be the *best* starting point.

I'll confirm the reachability of `smc_llc_cli_add_link`. It's called from `smc_llc_process_cli_add_link`, which is called from `smc_llc_event_handler`, which is called from `smc_llc_event_work`. That chain tells me this gets triggered by incoming network traffic. Definitely reachable, so good.

Let's summarize the key functions that I am considering for fuzzing: `smc_llc_cli_add_link`, `smc_llc_srv_add_link`, `smcr_link_init`, `smc_ibdev_init_begin`, and `smc_ibdev_init_end`.

Hold on... I'm looking at `smc_ibdev_init_begin` and `smc_ibdev_init_end`. They're simple wrappers with mutex locks and atomic operations:

```c
int smc_ibdev_init_begin(struct smc_ib_device *smcibdev)
{
	int rc = 0;

	mutex_lock(&smc_ib_devices.mutex);
	if (list_empty(&smcibdev->list))
		rc = -ENODEV;
	else
		atomic_inc(&smcibdev->init_cnt);
	mutex_unlock(&smc_ib_devices.mutex);
	return rc;
}

void smc_ibdev_init_end(struct smc_ib_device *smcibdev)
{
	mutex_lock(&smc_ib_devices.mutex);
	if (atomic_dec_and_test(&smcibdev->init_cnt))
		wake_up(&smcibdev->init_wait);
	mutex_unlock(&smc_ib_devices.mutex);
}
```

These functions are likely too simple to offer meaningful fuzzing targets. So, I'll drop these from the primary list. `smcr_link_init` appears better because it is more complex than the previous two. `smc_llc_cli_add_link` and `smc_llc_srv_add_link` are still solid choices.

Let's make sure I didn't miss any other functions modified in this area. Oh, `smc_ib_ndev_change` is modified.

```c
void smc_ib_ndev_change(struct net_device *ndev, unsigned long event)
```

No, wait. That modification looks like context, not functionality. And the diff shows a static `smc_ibdev_release` being introduced. That's not the primary focus here.

What about the new functions, `smc_ibdev_get` and `smc_ibdev_put`?

```c
void smc_ibdev_get(struct smc_ib_device *smcibdev)
void smc_ibdev_put(struct smc_ib_device *smcibdev)
```




22/2 2026/08/23 07:39 tool grepper
0m Args:
{
  "Expression": "depends on",
  "PathPrefix": "net/smc/Kconfig"
}

Results:
{
  "Output": "net/smc/Kconfig=2=config SMC\nnet/smc/Kconfig-3-\ttristate \"SMC socket protocol family\"\nnet/smc/Kconfig:4:\tdepends on INET \u0026\u0026 INFINIBAND \u0026\u0026 DIBS\nnet/smc/Kconfig-5-\thelp\n--\nnet/smc/Kconfig=14=config SMC_DIAG\nnet/smc/Kconfig-15-\ttristate \"SMC: socket monitoring interface\"\nnet/smc/Kconfig:16:\tdepends on SMC\nnet/smc/Kconfig-17-\thelp\n--\nnet/smc/Kconfig=23=config SMC_HS_CTRL_BPF\nnet/smc/Kconfig-24-\tbool \"Generic eBPF hook for SMC handshake flow\"\nnet/smc/Kconfig:25:\tdepends on SMC \u0026\u0026 BPF_JIT \u0026\u0026 BPF_SYSCALL\nnet/smc/Kconfig-26-\tdefault y\n"
}

23/2 2026/08/23 07:39 llm patch-evaluator
0m Model:
gemini-3.1-pro-preview

Args:
null

Results:
null

Tokens:
							input: 45997
							output: 33
							thoughts: 23
						

Thoughts:
Here's my take on those thoughts:

**Analyzing the Dependencies**

Alright, so I've got `DIBS` pegged as a dependency, no surprises there. Now, the real question is, what other packages or libraries are relying on that, especially as it relates to my `INFINIBAND` implementation? Time to dive into the dependency tree and map out what I'm dealing with. Let's see if this creates a tangle or if it's fairly straightforward.



24/2 2026/08/23 07:39 tool grepper
0m Args:
{
  "Expression": "config INFINIBAND",
  "PathPrefix": "drivers/infiniband/Kconfig"
}

Results:
{
  "Output": "drivers/infiniband/Kconfig-1-# SPDX-License-Identifier: GPL-2.0-only\ndrivers/infiniband/Kconfig:2:menuconfig INFINIBAND\ndrivers/infiniband/Kconfig-3-\ttristate \"InfiniBand support\"\n--\ndrivers/infiniband/Kconfig=16=if INFINIBAND\ndrivers/infiniband/Kconfig-17-\ndrivers/infiniband/Kconfig:18:config INFINIBAND_USER_MAD\ndrivers/infiniband/Kconfig-19-\ttristate \"InfiniBand userspace MAD support\"\n--\ndrivers/infiniband/Kconfig-27-\ndrivers/infiniband/Kconfig:28:config INFINIBAND_USER_ACCESS\ndrivers/infiniband/Kconfig-29-\ttristate \"InfiniBand userspace access (verbs and CM)\"\n--\ndrivers/infiniband/Kconfig-39-\ndrivers/infiniband/Kconfig:40:config INFINIBAND_USER_ACCESS_CORE\ndrivers/infiniband/Kconfig-41-\tbool\n--\ndrivers/infiniband/Kconfig-43-\ndrivers/infiniband/Kconfig:44:config INFINIBAND_USER_MEM\ndrivers/infiniband/Kconfig-45-\tbool\n--\ndrivers/infiniband/Kconfig-50-\ndrivers/infiniband/Kconfig:51:config INFINIBAND_ON_DEMAND_PAGING\ndrivers/infiniband/Kconfig-52-\tbool \"InfiniBand on-demand paging support\"\n--\ndrivers/infiniband/Kconfig-63-\ndrivers/infiniband/Kconfig:64:config INFINIBAND_ADDR_TRANS\ndrivers/infiniband/Kconfig-65-\tbool \"RDMA/CM\"\n--\ndrivers/infiniband/Kconfig-71-\ndrivers/infiniband/Kconfig:72:config INFINIBAND_ADDR_TRANS_CONFIGFS\ndrivers/infiniband/Kconfig-73-\tbool\n--\ndrivers/infiniband/Kconfig-80-\ndrivers/infiniband/Kconfig:81:config INFINIBAND_VIRT_DMA\ndrivers/infiniband/Kconfig-82-\tdef_bool !HIGHMEM\n"
}

25/2 2026/08/23 07:39 llm patch-evaluator
0m Model:
gemini-3.1-pro-preview

Args:
null

Results:
null

Tokens:
							input: 46739
							output: 31
							thoughts: 11
						

Thoughts:
Here's my attempt at summarizing the thought process, tailored for an expert audience:

**Checking Infiniband Dependencies**

Alright, let's dive in. My immediate thought is to meticulously verify the `INFINIBAND` dependencies. This isn't just a surface-level scan; I need to ensure a holistic understanding of how these components are interconnected. I'm thinking about the hardware, firmware versions, driver compatibility across the stack, and potential conflicts with other installed software. I'll need to confirm the correct fabric configuration, focusing on link speeds, routing tables, and any potential bottlenecks. Further, I'll need to examine the software layer: are the necessary libraries installed? Are they the correct versions? Does the application environment correctly account for the presence of the InfiniBand fabric? I should be looking at the OS modules, the MPI implementation (if applicable), and any custom drivers involved. I also need to consider the impact of any recent changes in the environment that may affect the InfiniBand setup. Any kernel upgrades or driver updates would need special attention. Ultimately, a smooth and reliable InfiniBand configuration is paramount for peak system performance, so a rigorous and well-considered investigation is essential.



26/2 2026/08/23 07:40 tool grepper
0m Args:
{
  "Expression": "depends on",
  "PathPrefix": "drivers/infiniband/Kconfig"
}

Results:
{
  "Output": "drivers/infiniband/Kconfig=2=menuconfig INFINIBAND\ndrivers/infiniband/Kconfig-3-\ttristate \"InfiniBand support\"\ndrivers/infiniband/Kconfig:4:\tdepends on HAS_IOMEM \u0026\u0026 HAS_DMA\ndrivers/infiniband/Kconfig:5:\tdepends on NET\ndrivers/infiniband/Kconfig:6:\tdepends on INET\ndrivers/infiniband/Kconfig:7:\tdepends on !ALPHA\ndrivers/infiniband/Kconfig-8-\tselect DMA_SHARED_BUFFER\n--\ndrivers/infiniband/Kconfig=18=config INFINIBAND_USER_MAD\ndrivers/infiniband/Kconfig-19-\ttristate \"InfiniBand userspace MAD support\"\ndrivers/infiniband/Kconfig:20:\tdepends on INFINIBAND\ndrivers/infiniband/Kconfig-21-\thelp\n--\ndrivers/infiniband/Kconfig=28=config INFINIBAND_USER_ACCESS\ndrivers/infiniband/Kconfig-29-\ttristate \"InfiniBand userspace access (verbs and CM)\"\ndrivers/infiniband/Kconfig:30:\tdepends on MMU\ndrivers/infiniband/Kconfig-31-\thelp\n--\ndrivers/infiniband/Kconfig=44=config INFINIBAND_USER_MEM\ndrivers/infiniband/Kconfig-45-\tbool\ndrivers/infiniband/Kconfig:46:\tdepends on INFINIBAND_USER_ACCESS != n\ndrivers/infiniband/Kconfig:47:\tdepends on MMU\ndrivers/infiniband/Kconfig-48-\tselect DMA_SHARED_BUFFER\n--\ndrivers/infiniband/Kconfig=51=config INFINIBAND_ON_DEMAND_PAGING\ndrivers/infiniband/Kconfig-52-\tbool \"InfiniBand on-demand paging support\"\ndrivers/infiniband/Kconfig:53:\tdepends on INFINIBAND_USER_MEM\ndrivers/infiniband/Kconfig-54-\tselect MMU_NOTIFIER\n--\ndrivers/infiniband/Kconfig=64=config INFINIBAND_ADDR_TRANS\ndrivers/infiniband/Kconfig-65-\tbool \"RDMA/CM\"\ndrivers/infiniband/Kconfig:66:\tdepends on INFINIBAND\ndrivers/infiniband/Kconfig-67-\tdefault y\n--\ndrivers/infiniband/Kconfig=72=config INFINIBAND_ADDR_TRANS_CONFIGFS\ndrivers/infiniband/Kconfig-73-\tbool\ndrivers/infiniband/Kconfig:74:\tdepends on INFINIBAND_ADDR_TRANS \u0026\u0026 CONFIGFS_FS \u0026\u0026 !(INFINIBAND=y \u0026\u0026 CONFIGFS_FS=m)\ndrivers/infiniband/Kconfig-75-\tdefault y\n"
}

27/2 2026/08/23 07:40 llm patch-evaluator
0m Model:
gemini-3.1-pro-preview

Args:
null

Results:
null

Tokens:
							input: 47748
							output: 29
							thoughts: 163
						

Thoughts:
**My Configuration Quandary**

Alright, let me map this out. To get `INFINIBAND` working, I need to make sure I've got `HAS_IOMEM`, `HAS_DMA`, `NET`, and `INET` enabled, and, importantly, that I *don't* have an `ALPHA` architecture. So, based on those dependencies, my `EnableConfigs` should absolutely include `SMC`, `INFINIBAND`, and `DIBS`.

Hang on a second… Does `SMC` require `SMC_DIAG`? Nope, scratch that. It doesn't. And I recall that `SMC` works with kernel-space RDMA, so it doesn't need `INFINIBAND_USER_ACCESS`. Right. 

Now, if I'm trying to test `SMC` over RDMA in a virtualized context, I'm going to need to think about how to simulate an RDMA environment. That means considering whether `RDMA_RXE` (Soft RoCE), `SMC_LO` (loopback), or `ISM` (dummy ISM) are relevant. I should check if there's a dummy ISM or loopback available, because that will allow for a fully contained, simulated environment. I'll need to figure out which approach is best suited to my test case.



28/2 2026/08/23 07:40 tool grepper
0m Args:
{
  "Expression": "config SMC",
  "PathPrefix": "net/smc/Kconfig"
}

Results:
{
  "Output": "net/smc/Kconfig-1-# SPDX-License-Identifier: GPL-2.0-only\nnet/smc/Kconfig:2:config SMC\nnet/smc/Kconfig-3-\ttristate \"SMC socket protocol family\"\n--\nnet/smc/Kconfig-13-\nnet/smc/Kconfig:14:config SMC_DIAG\nnet/smc/Kconfig-15-\ttristate \"SMC: socket monitoring interface\"\n--\nnet/smc/Kconfig-22-\nnet/smc/Kconfig:23:config SMC_HS_CTRL_BPF\nnet/smc/Kconfig-24-\tbool \"Generic eBPF hook for SMC handshake flow\"\n"
}

29/2 2026/08/23 07:40 llm patch-evaluator
0m Model:
gemini-3.1-pro-preview

Args:
null

Results:
null

Tokens:
							input: 48413
							output: 33
							thoughts: 15
						

Thoughts:
Here's my attempt at summarizing the thought process, tailored for an expert audience:

**Revisiting the SMC Kconfig**

Okay, time to circle back and give `net/smc/Kconfig` another look. I've been focusing on [mention the relevant area or task, e.g., the recent RDMA improvements, a specific bug, a performance issue, or a new feature]. Given the complexities of SMC and its interaction with the broader networking stack, I need to make sure I haven't missed anything crucial in that configuration file. There could be subtle dependencies, options I overlooked, or implications related to [mention a specific kernel configuration option or subsystem]. I need to ensure that the Kconfig is correctly reflecting any changes I've made, and hasn't introduced any regressions or conflicts. Let's see if there's anything I need to explicitly enable, disable, or adjust, or if any new options have been added. Time to dive back in and refresh my understanding.



30/2 2026/08/23 07:40 tool read-file
0m Args:
{
  "File": "net/smc/Kconfig",
  "FirstLine": 1,
  "LineCount": 30
}

Results:
{
  "Contents": "   1:\t# SPDX-License-Identifier: GPL-2.0-only\n   2:\tconfig SMC\n   3:\t\ttristate \"SMC socket protocol family\"\n   4:\t\tdepends on INET \u0026\u0026 INFINIBAND \u0026\u0026 DIBS\n   5:\t\thelp\n   6:\t\t  SMC-R provides a \"sockets over RDMA\" solution making use of\n   7:\t\t  RDMA over Converged Ethernet (RoCE) technology to upgrade\n   8:\t\t  AF_INET TCP connections transparently.\n   9:\t\t  The Linux implementation of the SMC-R solution is designed as\n  10:\t\t  a separate socket family SMC.\n  11:\t\n  12:\t\t  Select this option if you want to run SMC socket applications\n  13:\t\n  14:\tconfig SMC_DIAG\n  15:\t\ttristate \"SMC: socket monitoring interface\"\n  16:\t\tdepends on SMC\n  17:\t\thelp\n  18:\t\t  Support for SMC socket monitoring interface used by tools such as\n  19:\t\t  smcss.\n  20:\t\n  21:\t\t  if unsure, say Y.\n  22:\t\n  23:\tconfig SMC_HS_CTRL_BPF\n  24:\t\tbool \"Generic eBPF hook for SMC handshake flow\"\n  25:\t\tdepends on SMC \u0026\u0026 BPF_JIT \u0026\u0026 BPF_SYSCALL\n  26:\t\tdefault y\n  27:\t\thelp\n  28:\t\t  SMC_HS_CTRL_BPF enables support to register generic eBPF hook for SMC\n  29:\t\t  handshake flow, which offer much greater flexibility in modifying the behavior\n  30:\t\t  of the SMC protocol stack compared to a complete kernel-based approach. Select\n"
}

31/2 2026/08/23 07:40 llm patch-evaluator
0m Model:
gemini-3.1-pro-preview

Args:
null

Results:
null

Tokens:
							input: 49097
							output: 33
							thoughts: 26
						

Thoughts:
Here's my thought process, as if I were considering this:

**Investigating the SMC/DIBS Dependency**

Alright, so `SMC`'s functionality hinges on `DIBS`. Time to dive deeper and see exactly how that relationship is defined. My immediate course of action? Let's go straight to the source – I'll need to examine `drivers/dibs/Kconfig` to see what the dependency is. That's the most logical place to start, given my experience. I need to understand the configuration options and their interactions.



32/2 2026/08/23 07:40 tool read-file
0m Args:
{
  "File": "drivers/dibs/Kconfig",
  "FirstLine": 1,
  "LineCount": 20
}

Results:
{
  "Contents": "   1:\t# SPDX-License-Identifier: GPL-2.0\n   2:\tconfig DIBS\n   3:\t\ttristate \"Direct Internal Buffer Sharing support\"\n   4:\t\tdefault n\n   5:\t\thelp\n   6:\t\t  Direct Internal Buffer Sharing (DIBS) is a communication method that\n   7:\t\t  uses common physical (internal) memory for synchronous direct access\n   8:\t\t  into a remote buffer.\n   9:\t\n  10:\t\t  Select this option to provide the abstraction layer between\n  11:\t\t  dibs devices and dibs clients like the SMC protocol.\n  12:\t\t  The module name is dibs.\n  13:\t\n  14:\tconfig DIBS_LO\n  15:\t\tbool \"Intra-OS shortcut with dibs loopback\"\n  16:\t\tdepends on DIBS\n  17:\t\tdefault n\n  18:\t\thelp\n  19:\t\t  DIBS_LO enables the creation of an software-emulated dibs device\n  20:\t\t  named lo which can be used for transferring data when communication\n"
}

33/2 2026/08/23 07:40 llm patch-evaluator
0m Model:
gemini-3.1-pro-preview

Args:
null

Results:
null

Tokens:
							input: 49543
							output: 40
							thoughts: 61
						

Thoughts:
**My Initial Thoughts on Device Emulation and Network Fuzzing**

Okay, so I'm looking at this system setup, and the potential for some serious testing pops right into my head. The fact that we have `DIBS_LO` available here, and that it's a *software-emulated* dibs device, immediately suggests a key strategy: enable that thing! Why? Because getting SMC fuzzed over loopback is just good practice, and this seems like the perfect, low-hanging fruit opportunity. We can gain valuable insights into the handling of SMC traffic in a controlled environment.

Then, moving on to the RoCE side of things, `RDMA_RXE`, Soft RoCE, naturally catches my eye. It's the same principle as the `DIBS_LO` – a software-based implementation. Enabling that is a must. This allows us to assess the performance of the system. I'm already envisioning the test cases we can build around this setup!



34/2 2026/08/23 07:40 tool grepper
0m Args:
{
  "Expression": "config RDMA_RXE",
  "PathPrefix": "drivers/infiniband/sw/rxe/Kconfig"
}

Results:
{
  "Output": "drivers/infiniband/sw/rxe/Kconfig-1-# SPDX-License-Identifier: GPL-2.0-only\ndrivers/infiniband/sw/rxe/Kconfig:2:config RDMA_RXE\ndrivers/infiniband/sw/rxe/Kconfig-3-\ttristate \"Software RDMA over Ethernet (RoCE) driver\"\n"
}

35/2 2026/08/23 07:40 llm patch-evaluator
0m Model:
gemini-3.1-pro-preview

Args:
null

Results:
null

Tokens:
							input: 49954
							output: 271
							thoughts: 1217
						

Thoughts:
**My Analysis of the SMC Subsystem Patch**

Okay, let's break this down. First, I need to identify the key areas this patch modifies within the SMC subsystem. I started by looking at the `EnableConfigs` and then the relevant functions.

The `EnableConfigs` are: `SMC`, `INFINIBAND`, `DIBS`, `DIBS_LO`, and `RDMA_RXE`. Thinking about the implications, I realize `DIBS_LO` is a boolean, while `DIBS`, `RDMA_RXE`, `SMC`, and `INFINIBAND` are tristates. Good to keep in mind for testing later.

Now, the important functions. Initially, I considered several: `smcr_link_init`, `smc_llc_cli_add_link`, `smc_llc_srv_add_link`, `smc_init_info_free`, `smc_ibdev_init_begin`, and `smc_ibdev_init_end`. I quickly discounted `smc_init_info_free` and the `ibdev` initialization functions as these are only cleanup and very simple initializations, respectively, not complex logic paths. I also checked `smc_pnet_determine_gid`, `smc_listen_work`, `__smc_connect`, and `smc_find_rdma_v2_device_serv`, which are all static. While these are relevant, `__smc_connect` is called by `smc_connect_work` and `smc_connect` (syscall handler) and `smc_listen_work` is a workqueue handler. The syscalls are likely to be fuzzed by default and the LLC functions look like they will be handling incoming packets, so these are all good to test.

I also checked `smc_ibdev_get` and `smc_ibdev_put`, but these are just refcount wrappers so not the focus.

So, I'm going to focus on:
*   `smcr_link_init`
*   `smc_llc_cli_add_link`
*   `smc_llc_srv_add_link`

These are non-static and handle link initialization and management, crucial for testing the connection paths.

Finally, a quick review of the configuration options. I confirmed that both `DIBS` and `DIBS_LO` are present in the tree under `drivers/dibs/Kconfig`.

Now, I can clearly articulate the reasoning behind this patch. The main issue is a reference leak of the `smc_ib_device`. This patch fixes that with a new `smc_init_info_free` function and careful refcounting with `smc_ibdev_get`/`put`, along with an `init_cnt` to monitor unpublished initializations. The changes cover connection establishment (linked to `__smc_connect` and `smc_listen_work`, which in turn call the functions I've identified) and LLC link management (`smc_llc_cli_add_link` and `smc_llc_srv_add_link`). These paths are reachable from userspace via socket operations and network packets, which is ideal for testing. To test comprehensively, I'll need to enable the SMC, InfiniBand, and the software-emulated RDMA/DIBS devices (`RDMA_RXE` and `DIBS_LO`).



36/2 2026/08/23 07:40 tool set-results
0m Args:
{
  "EnableConfigs": [
    "SMC",
    "INFINIBAND",
    "DIBS",
    "DIBS_LO",
    "RDMA_RXE"
  ],
  "FocusSymbols": [
    "smcr_link_init",
    "smc_llc_cli_add_link",
    "smc_llc_srv_add_link"
  ],
  "Reasoning": "The patch fixes a reference leak of `smc_ib_device` in the SMC subsystem by introducing `smc_init_info_free` and properly managing the object lifetime with reference counting (`smc_ibdev_get`/`put`). It also adds an initialization counter (`init_cnt`) to track unpublished link initializations. The changes affect connection establishment (`__smc_connect`, `smc_listen_work`) and LLC link management (`smc_llc_cli_add_link`, `smc_llc_srv_add_link`). These paths are reachable from userspace via socket operations and incoming network packets. To properly test this, we need to enable SMC, InfiniBand, and software-emulated RDMA/DIBS devices (`RDMA_RXE`, `DIBS_LO`).",
  "WorthFuzzing": true
}

Results:
{
  "EnableConfigs": [
    "SMC",
    "INFINIBAND",
    "DIBS",
    "DIBS_LO",
    "RDMA_RXE"
  ],
  "FocusSymbols": [
    "smcr_link_init",
    "smc_llc_cli_add_link",
    "smc_llc_srv_add_link"
  ],
  "Reasoning": "The patch fixes a reference leak of `smc_ib_device` in the SMC subsystem by introducing `smc_init_info_free` and properly managing the object lifetime with reference counting (`smc_ibdev_get`/`put`). It also adds an initialization counter (`init_cnt`) to track unpublished link initializations. The changes affect connection establishment (`__smc_connect`, `smc_listen_work`) and LLC link management (`smc_llc_cli_add_link`, `smc_llc_srv_add_link`). These paths are reachable from userspace via socket operations and incoming network packets. To properly test this, we need to enable SMC, InfiniBand, and software-emulated RDMA/DIBS devices (`RDMA_RXE`, `DIBS_LO`).",
  "WorthFuzzing": true
}

37/1 2026/08/23 07:40 action If
0m Args:
{
  "WorthFuzzing": true
}

Results:
null

38/2 2026/08/23 07:40 agent kmsan-evaluator
0m Model:
best-expensive

Args:
null

Results:
{
  "KMSANReasoning": "The patch introduces reference counting for `smc_ib_device` objects to fix object lifetime issues (likely use-after-free). It replaces `kfree(ini)` with `smc_init_info_free(ini)`, which drops the references if they were acquired. The new boolean fields `ib_dev_ref` and `ib_dev_v2_ref` are added to `struct smc_init_info`, which is always allocated using `kzalloc` (via `kzalloc_obj`), ensuring they are properly zero-initialized. There are no new structures sent to user space, and no uninitialized memory risks are introduced or exposed. KASAN is the appropriate tool for detecting use-after-free bugs, which this patch addresses.",
  "NeedsKMSAN": false
}

Instruction:
You are an expert Linux kernel security engineer specializing in kernel memory
error detectors (KASAN and KMSAN). Your job is to review the provided patch series and
determine if the code changes justify spawning a dedicated KMSAN (KernelMemorySanitizer)
fuzzing session in addition to standard KASAN fuzzing.

CRITICAL DISTINCTION BETWEEN KASAN AND KMSAN:
- Standard KASAN kernel builds (upstream-apparmor-kasan.config) already enable
  a comprehensive suite of debugging tools and sanitizers, including KASAN
  (out-of-bounds accesses, use-after-free, double free, invalid free), LOCKDEP
  (locking bugs and deadlocks), UB-sanitizers, and memory corruption checks.
- KMSAN (KernelMemorySanitizer) detects reads of UNINITIALIZED memory (stack, heap,
  or page allocations) and kernel-to-user memory info-leaks.

Rule: THERE IS NO SENSE IN RUNNING A KMSAN SESSION IF A BUG CAN BE CAUGHT BY KASAN,
LOCKDEP, OR OTHER STANDARD BUG DETECTORS.
A dedicated KMSAN fuzzing session incurs significant resource costs. You must ONLY
set NeedsKMSAN=true if the code changes introduce or expose UNINITIALIZED MEMORY risks
that are detected ONLY by KMSAN.

Look holistically at the patch series and surrounding code. Even if no direct
uninitialized field accesses or new buffer allocations are added in the diff itself,
a patch may alter control flow, bounds checking, or data length calculations in ways
that change how the rest of the code operates on existing buffers (e.g. allowing
uninitialized stack/heap memory to be read, copied to user space, or used in control
flow). Do not hesitate to use your code access tools to inspect the surrounding code,
called functions, and callers.

Set NeedsKMSAN=true ONLY IF the patch introduces or modifies:
1. Kernel structures sent to user space (via copy_to_user, put_user, netlink skb
   attributes, ioctl output arguments, socket options, or BPF buffers) where fields
   or structure padding might not be fully initialized/zeroed.
2. Conditional logic or branching that depends on potentially uninitialized variables
   or struct fields.
3. Allocation or initialization of complex data structures where uninitialized fields
   could be read later in reachable code paths.
4. Bounds checks, lengths, or logic in a way that allows surrounding code to access
   uninitialized bytes of existing buffers.

Set NeedsKMSAN=false IF:
- The code changes primarily risk out-of-bounds access, array overflows, NULL pointer
  dereferences, locking deadlocks, or use-after-free bugs (these are already caught
  by KASAN, LOCKDEP, or standard bug detectors).
- All stack/heap structures touched or introduced by the patch are fully zeroed
  or initialized (e.g. using = {0}, memset, kzalloc) before being read or copied.
- The patch does not introduce any risk of uninitialized memory usage or info-leaks.

Use your code access tools to inspect the surrounding code if necessary, then provide
detailed KMSANReasoning contrasting KASAN vs KMSAN applicability for this patch.
Prefer calling several tools at the same time to save round-trips.


Use set-results tool to provide results of the analysis.
It must be called exactly once before the final reply.
Ignore results of this tool.

Prompt:
For your convenience, here is the diff of the changes:
commit 777f30715c6d50544d6f80c030ab5bbb11c9142b
Author: syz-cluster <triage@syzkaller.com>
Date:   Sun Aug 23 07:38:50 2026 +0000

    syz-cluster: applied patch under review

diff --git a/net/smc/af_smc.c b/net/smc/af_smc.c
index e9f93b3ab435b..d781dee1b3293 100644
--- a/net/smc/af_smc.c
+++ b/net/smc/af_smc.c
@@ -1225,7 +1225,7 @@ void smc_fill_gid_list(struct smc_link_group *lgr,
 	       SMC_GID_SIZE);
 
 out:
-	kfree(alt_ini);
+	smc_init_info_free(alt_ini);
 }
 
 static int smc_connect_rdma_v2_prepare(struct smc_sock *smc,
@@ -1596,14 +1596,14 @@ static int __smc_connect(struct smc_sock *smc)
 	SMC_STAT_CLNT_SUCC_INC(sock_net(smc->clcsock->sk), aclc);
 	smc_connect_ism_vlan_cleanup(ini);
 	kfree(buf);
-	kfree(ini);
+	smc_init_info_free(ini);
 	return 0;
 
 vlan_cleanup:
 	smc_connect_ism_vlan_cleanup(ini);
 	kfree(buf);
 fallback:
-	kfree(ini);
+	smc_init_info_free(ini);
 	return smc_connect_decline_fallback(smc, rc, version);
 }
 
@@ -2344,7 +2344,10 @@ static void smc_find_rdma_v2_device_serv(struct smc_sock *new_smc,
 
 not_found:
 	ini->smcr_version &= ~SMC_V2;
+	if (ini->smcrv2.ib_dev_v2_ref)
+		smc_ibdev_put(ini->smcrv2.ib_dev_v2);
 	ini->smcrv2.ib_dev_v2 = NULL;
+	ini->smcrv2.ib_dev_v2_ref = false;
 	ini->check_smcrv2 = false;
 }
 
@@ -2588,7 +2591,7 @@ static void smc_listen_work(struct work_struct *work)
 	smc_listen_decline(new_smc, rc, ini ? ini->first_contact_local : 0,
 			   proposal_version);
 out_free:
-	kfree(ini);
+	smc_init_info_free(ini);
 	kfree(buf);
 }
 
diff --git a/net/smc/smc_core.c b/net/smc/smc_core.c
index 181647982490b..d97bc73231069 100644
--- a/net/smc/smc_core.c
+++ b/net/smc/smc_core.c
@@ -55,6 +55,17 @@ static void __smc_lgr_terminate(struct smc_link_group *lgr, bool soft);
 
 static void smc_link_down_work(struct work_struct *work);
 
+void smc_init_info_free(struct smc_init_info *ini)
+{
+	if (!ini)
+		return;
+	if (ini->ib_dev_ref)
+		smc_ibdev_put(ini->ib_dev);
+	if (ini->smcrv2.ib_dev_v2_ref)
+		smc_ibdev_put(ini->smcrv2.ib_dev_v2);
+	kfree(ini);
+}
+
 /* return head of link group list and its lock for a given link group */
 static inline struct list_head *smc_lgr_list_head(struct smc_link_group *lgr,
 						  spinlock_t **lgr_lock)
@@ -793,14 +804,21 @@ int smcr_link_init(struct smc_link_group *lgr, struct smc_link *lnk,
 	int rc;
 
 	if (lgr->smc_version == SMC_V2) {
-		lnk->smcibdev = ini->smcrv2.ib_dev_v2;
+		smcibdev = ini->smcrv2.ib_dev_v2;
 		lnk->ibport = ini->smcrv2.ib_port_v2;
-		lnk->wr_rx_sge_cnt = lnk->smcibdev->ibdev->attrs.max_recv_sge < 2 ? 1 : 2;
+	} else {
+		smcibdev = ini->ib_dev;
+		lnk->ibport = ini->ib_port;
+	}
+	rc = smc_ibdev_init_begin(smcibdev);
+	if (rc)
+		return rc;
+	lnk->smcibdev = smcibdev;
+	if (lgr->smc_version == SMC_V2) {
+		lnk->wr_rx_sge_cnt = smcibdev->ibdev->attrs.max_recv_sge < 2 ? 1 : 2;
 		lnk->wr_rx_buflen = smc_link_shared_v2_rxbuf(lnk) ?
 			SMC_WR_BUF_SIZE : SMC_WR_BUF_V2_SIZE;
 	} else {
-		lnk->smcibdev = ini->ib_dev;
-		lnk->ibport = ini->ib_port;
 		lnk->wr_rx_sge_cnt = 1;
 		lnk->wr_rx_buflen = SMC_WR_BUF_SIZE;
 	}
@@ -882,6 +900,7 @@ int smcr_link_init(struct smc_link_group *lgr, struct smc_link *lnk,
 	if (!atomic_dec_return(&smcibdev->lnk_cnt))
 		wake_up(&smcibdev->lnks_deleted);
 	smc_lgr_put(lgr); /* lgr_hold above */
+	smc_ibdev_init_end(smcibdev);
 	return rc;
 }
 
@@ -997,6 +1016,8 @@ static int smc_lgr_create(struct smc_sock *smc, struct smc_init_info *ini)
 	spin_lock_bh(lgr_lock);
 	list_add_tail(&lgr->list, lgr_list);
 	spin_unlock_bh(lgr_lock);
+	if (!ini->is_smcd)
+		smc_ibdev_init_end(lnk->smcibdev);
 	return 0;
 
 free_wq:
diff --git a/net/smc/smc_core.h b/net/smc/smc_core.h
index 5c18f08a4c8a5..9f5a69a30cb3f 100644
--- a/net/smc/smc_core.h
+++ b/net/smc/smc_core.h
@@ -403,6 +403,7 @@ struct smc_init_info_smcrv2 {
 
 	/* Output fields when saddr is set */
 	struct smc_ib_device	*ib_dev_v2;
+	bool			ib_dev_v2_ref; /* owns an smc_ibdev reference */
 	u8			ib_port_v2;
 	u8			ib_gid_v2[SMC_GID_SIZE];
 
@@ -438,6 +439,7 @@ struct smc_init_info {
 	u8			peer_mac[ETH_ALEN];
 	u8			peer_systemid[SMC_SYSTEMID_LEN];
 	struct smc_ib_device	*ib_dev;
+	bool			ib_dev_ref; /* owns an smc_ibdev reference */
 	u8			ib_gid[SMC_GID_SIZE];
 	u8			ib_port;
 	u32			ib_clcqpn;
@@ -594,6 +596,7 @@ void smc_rtoken_set2(struct smc_link_group *lgr, int rtok_idx, int link_id,
 void smc_sndbuf_sync_sg_for_device(struct smc_connection *conn);
 void smc_rmb_sync_sg_for_cpu(struct smc_connection *conn);
 int smc_vlan_by_tcpsk(struct socket *clcsock, struct smc_init_info *ini);
+void smc_init_info_free(struct smc_init_info *ini);
 
 void smc_conn_free(struct smc_connection *conn);
 int smc_conn_create(struct smc_sock *smc, struct smc_init_info *ini);
diff --git a/net/smc/smc_ib.c b/net/smc/smc_ib.c
index 9bb495707445e..d858453c64d92 100644
--- a/net/smc/smc_ib.c
+++ b/net/smc/smc_ib.c
@@ -934,6 +934,44 @@ void smc_ib_ndev_change(struct net_device *ndev, unsigned long event)
 	mutex_unlock(&smc_ib_devices.mutex);
 }
 
+static void smc_ibdev_release(struct smc_ib_device *smcibdev)
+{
+	put_device(&smcibdev->ibdev->dev);
+	kfree(smcibdev);
+}
+
+void smc_ibdev_get(struct smc_ib_device *smcibdev)
+{
+	refcount_inc(&smcibdev->refcnt);
+}
+
+void smc_ibdev_put(struct smc_ib_device *smcibdev)
+{
+	if (refcount_dec_and_test(&smcibdev->refcnt))
+		smc_ibdev_release(smcibdev);
+}
+
+int smc_ibdev_init_begin(struct smc_ib_device *smcibdev)
+{
+	int rc = 0;
+
+	mutex_lock(&smc_ib_devices.mutex);
+	if (list_empty(&smcibdev->list))
+		rc = -ENODEV;
+	else
+		atomic_inc(&smcibdev->init_cnt);
+	mutex_unlock(&smc_ib_devices.mutex);
+	return rc;
+}
+
+void smc_ibdev_init_end(struct smc_ib_device *smcibdev)
+{
+	mutex_lock(&smc_ib_devices.mutex);
+	if (atomic_dec_and_test(&smcibdev->init_cnt))
+		wake_up(&smcibdev->init_wait);
+	mutex_unlock(&smc_ib_devices.mutex);
+}
+
 /* callback function for ib_register_client() */
 static int smc_ib_add_dev(struct ib_device *ibdev)
 {
@@ -949,7 +987,11 @@ static int smc_ib_add_dev(struct ib_device *ibdev)
 		return -ENOMEM;
 
 	smcibdev->ibdev = ibdev;
+	get_device(&ibdev->dev);
+	refcount_set(&smcibdev->refcnt, 1);
 	INIT_WORK(&smcibdev->port_event_work, smc_ib_port_event_work);
+	atomic_set(&smcibdev->init_cnt, 0);
+	init_waitqueue_head(&smcibdev->init_wait);
 	atomic_set(&smcibdev->lnk_cnt, 0);
 	init_waitqueue_head(&smcibdev->lnks_deleted);
 	mutex_init(&smcibdev->mutex);
@@ -1000,11 +1042,14 @@ static void smc_ib_remove_dev(struct ib_device *ibdev, void *client_data)
 	mutex_unlock(&smc_ib_devices.mutex);
 	pr_warn_ratelimited("smc: removing ib device %s\n",
 			    smcibdev->ibdev->name);
+	if (atomic_read(&smcibdev->init_cnt))
+		wait_event(smcibdev->init_wait,
+			   !atomic_read(&smcibdev->init_cnt));
 	smc_smcr_terminate_all(smcibdev);
 	smc_ib_cleanup_per_ibdev(smcibdev);
 	ib_unregister_event_handler(&smcibdev->event_handler);
 	cancel_work_sync(&smcibdev->port_event_work);
-	kfree(smcibdev);
+	smc_ibdev_put(smcibdev);
 }
 
 static struct ib_client smc_ib_client = {
diff --git a/net/smc/smc_ib.h b/net/smc/smc_ib.h
index ef8ac2b7546df..d32547350e8b8 100644
--- a/net/smc/smc_ib.h
+++ b/net/smc/smc_ib.h
@@ -15,6 +15,7 @@
 #include <linux/interrupt.h>
 #include <linux/if_ether.h>
 #include <linux/mutex.h>
+#include <linux/refcount.h>
 #include <linux/wait.h>
 #include <rdma/ib_verbs.h>
 #include <net/smc.h>
@@ -51,6 +52,9 @@ struct smc_ib_device {				/* ib-device infos for smc */
 	struct work_struct	port_event_work;
 	unsigned long		port_event_mask;
 	DECLARE_BITMAP(ports_going_away, SMC_MAX_PORTS);
+	refcount_t		refcnt;		/* object lifetime */
+	atomic_t		init_cnt;	/* unpublished link initializations */
+	wait_queue_head_t	init_wait;	/* wait for links to be published */
 	atomic_t		lnk_cnt;	/* number of links on ibdev */
 	wait_queue_head_t	lnks_deleted;	/* wait 4 removal of all links*/
 	struct mutex		mutex;		/* protect dev setup+cleanup */
@@ -59,6 +63,11 @@ struct smc_ib_device {				/* ib-device infos for smc */
 	int			ndev_ifidx[SMC_MAX_PORTS]; /* ndev if indexes */
 };
 
+void smc_ibdev_get(struct smc_ib_device *smcibdev);
+void smc_ibdev_put(struct smc_ib_device *smcibdev);
+int smc_ibdev_init_begin(struct smc_ib_device *smcibdev);
+void smc_ibdev_init_end(struct smc_ib_device *smcibdev);
+
 static inline __be32 smc_ib_gid_to_ipv4(u8 gid[SMC_GID_SIZE])
 {
 	struct in6_addr *addr6 = (struct in6_addr *)gid;
diff --git a/net/smc/smc_llc.c b/net/smc/smc_llc.c
index c9ccd8480369c..e16aaa514368a 100644
--- a/net/smc/smc_llc.c
+++ b/net/smc/smc_llc.c
@@ -1108,6 +1108,7 @@ int smc_llc_cli_add_link(struct smc_link *link, struct smc_llc_qentry *qentry)
 	rc = smcr_link_init(lgr, lnk_new, lnk_idx, ini);
 	if (rc)
 		goto out_reject;
+	smc_ibdev_init_end(lnk_new->smcibdev);
 	smc_llc_save_add_link_info(lnk_new, llc);
 	lnk_new->link_id = llc->link_num;	/* SMC server assigns link id */
 	smc_llc_link_set_uid(lnk_new);
@@ -1143,7 +1144,7 @@ int smc_llc_cli_add_link(struct smc_link *link, struct smc_llc_qentry *qentry)
 out_reject:
 	smc_llc_cli_add_link_reject(qentry);
 out:
-	kfree(ini);
+	smc_init_info_free(ini);
 	kfree(qentry);
 	return rc;
 }
@@ -1217,7 +1218,7 @@ static void smc_llc_cli_add_link_invite(struct smc_link *link,
 	smc_llc_send_add_link(link, ini->ib_dev->mac[ini->ib_port - 1],
 			      ini->ib_gid, NULL, SMC_LLC_REQ);
 out:
-	kfree(ini);
+	smc_init_info_free(ini);
 	kfree(qentry);
 }
 
@@ -1487,6 +1488,7 @@ int smc_llc_srv_add_link(struct smc_link *link,
 	if (rc)
 		goto out;
 	link_new = &lgr->lnk[lnk_idx];
+	smc_ibdev_init_end(link_new->smcibdev);
 
 	rc = smcr_buf_map_lgr(link_new);
 	if (rc)
@@ -1544,7 +1546,7 @@ int smc_llc_srv_add_link(struct smc_link *link,
 	}
 out:
 	kfree(qentry);
-	kfree(ini);
+	smc_init_info_free(ini);
 	if (send_req_add_link_resp)
 		smc_llc_send_req_add_link_response(req_qentry);
 	return rc;
diff --git a/net/smc/smc_pnet.c b/net/smc/smc_pnet.c
index 63e286e2dfaa8..be1f5137c8ee7 100644
--- a/net/smc/smc_pnet.c
+++ b/net/smc/smc_pnet.c
@@ -980,14 +980,22 @@ static int smc_pnet_determine_gid(struct smc_ib_device *ibdev, int i,
 	if (!ini->check_smcrv2 &&
 	    !smc_ib_determine_gid(ibdev, i, ini->vlan_id, ini->ib_gid, NULL,
 				  NULL)) {
+		if (ini->ib_dev_ref)
+			smc_ibdev_put(ini->ib_dev);
+		smc_ibdev_get(ibdev);
 		ini->ib_dev = ibdev;
+		ini->ib_dev_ref = true;
 		ini->ib_port = i;
 		return 0;
 	}
 	if (ini->check_smcrv2 &&
 	    !smc_ib_determine_gid(ibdev, i, ini->vlan_id, ini->smcrv2.ib_gid_v2,
 				  NULL, &ini->smcrv2)) {
+		if (ini->smcrv2.ib_dev_v2_ref)
+			smc_ibdev_put(ini->smcrv2.ib_dev_v2);
+		smc_ibdev_get(ibdev);
 		ini->smcrv2.ib_dev_v2 = ibdev;
+		ini->smcrv2.ib_dev_v2_ref = true;
 		ini->smcrv2.ib_port_v2 = i;
 		return 0;
 	}

39/3 2026/08/23 07:40 llm kmsan-evaluator
0m Model:
gemini-3.1-pro-preview

Args:
null

Results:
null

Tokens:
							input: 6999
							output: 33
							thoughts: 365
						

Thoughts:
**Analyzing the SMC Subsystem Patch**

Okay, so this patch is aimed squarely at the `net/smc/` subsystem within the Linux kernel, specifically dealing with `smc_ib_device` objects. My initial assessment is that this is a rather straightforward, albeit critical, fix. It's all about bolstering reference counting for these `smc_ib_device` instances.

The key change I see is the introduction of a more robust lifecycle management system. They're ditching the direct `kfree(ini)` call in favor of `smc_init_info_free(ini)`. This function is where the magic happens; it's responsible for managing the references to `ib_dev` and `ib_dev_v2`. The introduction of `smc_ibdev_get`, `smc_ibdev_put`, `smc_ibdev_init_begin`, and `smc_ibdev_init_end` further reinforces this new approach. It's a clear indication that we're moving towards a more structured and less error-prone way of managing the object's dependencies. And by adding `ib_dev_ref` and `ib_dev_v2_ref` to the `smc_init_info`, it appears that the system tracks the ownership of those references by the `smc_init_info`.

It's evident this is a response to a potential use-after-free or, more generally, an object lifetime management problem related to `smc_ib_device`. The good news is that there aren't any new structures being exposed to user space, so that's one less area to worry about from a security perspective. There's also no indication of uninitialized memory issues being addressed or exposed, which is a good sign. The focus here is solely on reference counting and object lifetime.

However, I need to do a quick sanity check for possible regressions. It's a good practice, and I'm looking specifically for potential uninitialized memory risks. Since `smc_init_info` is likely allocated, probably through `kzalloc`, there is a risk that the added fields, `ib_dev_ref` and `ib_dev_v2_ref`, might not be properly initialized. If `smc_init_info` isn't zero-initialized, these boolean flags could be left in an undefined state, leading to incorrect calls to `smc_ibdev_put`. I should verify how `smc_init_info` is actually allocated to determine if this is a concern.



40/3 2026/08/23 07:40 tool grepper
0m Error:
no matches

Args:
{
  "Expression": "alloc.*smc_init_info",
  "PathPrefix": "net/smc/"
}

Results:
{
  "error": "no matches"
}

41/3 2026/08/23 07:40 llm kmsan-evaluator
0m Model:
gemini-3.1-pro-preview

Args:
null

Results:
null

Tokens:
							input: 7957
							output: 30
							thoughts: 21
						

Thoughts:
Here's my thought process, as requested:

**Hunting for Initialization Magic**

Okay, so I need to find where the `ini = ` assignments or the `struct smc_init_info` allocations are happening. That's my starting point. Those will be crucial because they're the places where the initial parameters or the structure defining an SMC (System Management Controller) or similar device is defined, or initialized. Finding those will lead me to the key configuration data. I'm assuming that this initialization is pretty important to the system as a whole, so knowing the place to start looking is the key.



42/3 2026/08/23 07:40 tool grepper
0m Args:
{
  "Expression": "ini = k.*alloc",
  "PathPrefix": "net/smc/"
}

Results:
{
  "Output": "net/smc/af_smc.c=1203=void smc_fill_gid_list(struct smc_link_group *lgr,\n--\nnet/smc/af_smc.c-1211-\nnet/smc/af_smc.c:1212:\talt_ini = kzalloc_obj(*alt_ini);\nnet/smc/af_smc.c-1213-\tif (!alt_ini)\n--\nnet/smc/af_smc.c=1520=static int __smc_connect(struct smc_sock *smc)\n--\nnet/smc/af_smc.c-1539-\nnet/smc/af_smc.c:1540:\tini = kzalloc_obj(*ini);\nnet/smc/af_smc.c-1541-\tif (!ini)\n--\nnet/smc/af_smc.c=2453=static void smc_listen_work(struct work_struct *work)\n--\nnet/smc/af_smc.c-2507-\nnet/smc/af_smc.c:2508:\tini = kzalloc_obj(*ini);\nnet/smc/af_smc.c-2509-\tif (!ini) {\n--\nnet/smc/smc_llc.c=1058=int smc_llc_cli_add_link(struct smc_link *link, struct smc_llc_qentry *qentry)\n--\nnet/smc/smc_llc.c-1069-\nnet/smc/smc_llc.c:1070:\tini = kzalloc_obj(*ini);\nnet/smc/smc_llc.c-1071-\tif (!ini) {\n--\nnet/smc/smc_llc.c=1191=static void smc_llc_cli_add_link_invite(struct smc_link *link,\n--\nnet/smc/smc_llc.c-1208-\nnet/smc/smc_llc.c:1209:\tini = kzalloc_obj(*ini);\nnet/smc/smc_llc.c-1210-\tif (!ini)\n--\nnet/smc/smc_llc.c=1432=int smc_llc_srv_add_link(struct smc_link *link,\n--\nnet/smc/smc_llc.c-1447-\nnet/smc/smc_llc.c:1448:\tini = kzalloc_obj(*ini);\nnet/smc/smc_llc.c-1449-\tif (!ini) {\n"
}

43/3 2026/08/23 07:40 llm kmsan-evaluator
0m Model:
gemini-3.1-pro-preview

Args:
null

Results:
null

Tokens:
							input: 8846
							output: 185
							thoughts: 99
						

Thoughts:
**My Assessment of the Code Change**

Okay, so looking at this code, my initial thought is that `kzalloc_obj` is almost certainly just a macro that's a wrapper for `kzalloc`. That's standard practice, and it makes the code cleaner. The key here, though, is that `kzalloc` zeroes the allocated memory. Knowing that, I can quickly confirm that `ib_dev_ref` and `ib_dev_v2_ref` will be correctly initialized to `false`, which is important for the overall state of these objects.

This patch is obviously addressing a use-after-free or a related object lifetime problem. Considering the zero-initialization, there's no way that uninitialized memory is the root cause. My expertise is that the zero-allocation provides an important guarantee that mitigates the most common risks.

Given the focus on use-after-free, KASAN is the appropriate tool for detecting this kind of bug. We really don't need to involve KMSAN for this specific issue. KASAN is perfectly sufficient for catching the kinds of memory access errors we're likely dealing with here.



44/3 2026/08/23 07:40 tool set-results
0m Args:
{
  "KMSANReasoning": "The patch introduces reference counting for `smc_ib_device` objects to fix object lifetime issues (likely use-after-free). It replaces `kfree(ini)` with `smc_init_info_free(ini)`, which drops the references if they were acquired. The new boolean fields `ib_dev_ref` and `ib_dev_v2_ref` are added to `struct smc_init_info`, which is always allocated using `kzalloc` (via `kzalloc_obj`), ensuring they are properly zero-initialized. There are no new structures sent to user space, and no uninitialized memory risks are introduced or exposed. KASAN is the appropriate tool for detecting use-after-free bugs, which this patch addresses.",
  "NeedsKMSAN": false
}

Results:
{
  "KMSANReasoning": "The patch introduces reference counting for `smc_ib_device` objects to fix object lifetime issues (likely use-after-free). It replaces `kfree(ini)` with `smc_init_info_free(ini)`, which drops the references if they were acquired. The new boolean fields `ib_dev_ref` and `ib_dev_v2_ref` are added to `struct smc_init_info`, which is always allocated using `kzalloc` (via `kzalloc_obj`), ensuring they are properly zero-initialized. There are no new structures sent to user space, and no uninitialized memory risks are introduced or exposed. KASAN is the appropriate tool for detecting use-after-free bugs, which this patch addresses.",
  "NeedsKMSAN": false
}

LLM Calls Summary:
Total Calls Total Tokens Avg Tokens Total Duration (Seconds) Avg Duration (Seconds)
Tool Calls Summary:
Total Calls Total Duration (Seconds) Avg Duration (Seconds)