Re: [PATCH net v4] net/smc: order the CDC receive path against buffer publication

Bryam Vargas <[email protected]>
Newsgroups org.kernel.vger.linux-rdma,org.kernel.vger.linux-kernel,org.kernel.vger.linux-s390,org.kernel.vger.netdev
Message-ID <[email protected]>
Simon,

> This is a pre-existing issue, but should the unpublish side be fixed in
> the same series, since this patch establishes the publication protocol for
> the ghost buffer?

Real gap, and it is on the list as its own series:

  https://lore.kernel.org/all/[email protected]/

I kept them apart because they are independent revert units with different
Fixes: anchors and stable ranges -- this one is 69cb7dc0218b, where the CDC
path first dereferenced the descriptors; the teardown series is ae2be35cbed2,
which added the ghost buffer. The hunks are disjoint, so either order applies.

There is a coupling worth knowing either way, which I should have said in the
v4 cover: this patch caches sndbuf_desc in a local, so if it lands while the
teardown series has not, that window stops being a NULL dereference and becomes
a read of the freed descriptor. That argues for the teardown series landing
first or alongside, not for merging them. Both orders apply cleanly and give
the same tree; I checked. If you'd rather review them as one series I'll
respin them together.

> Would stopping the tasklet before detaching and freeing the ghost buffer,
> mirroring the publish-last ordering introduced here, close this?

Not on its own. That is what v1 of the teardown patch did, and Dust replied
that it does not fully eliminate the race; he was right. smc_conn_free() calls
smc_ism_unset_conn() only while the link group is still on its device list, and
smc_lgr_terminate_sched() unlinks the group before the worker kills its
connections, so the device can arm the tasklet again after tasklet_kill() has
returned. On an SMC-D loopback rig, with the reorder applied, 78 of 172
connections were still armable when the drain returned and the tasklet was
re-armed 33 times; unregistering first takes that to 0 of 31.

One correction to the review text, since it points at the wrong lock:

> smc_conn_kill() runs from the link group terminate worker with no socket
> lock at all

It does hold it -- __smc_lgr_terminate() takes lock_sock() at smc_core.c:1579,
and f621d6ebeebb did not add that; it only moved the sock_hold() under
conns_lock. The conclusion still stands for a different reason:
smc_cdc_msg_recv() takes only bh_lock_sock() and never checks
sock_owned_by_user(), so it does not defer to the backlog and lock_sock() does
not exclude it.

Thanks for the review.

Bryam
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.