[rds-devel] [External] : Re: [PATCH net 1/1] net/rds: handle zerocopy send cleanup before the message is queued

Allison Henderson achender at kernel.org
Fri May 1 19:40:26 UTC 2026


On Fri, 2026-05-01 at 09:08 +0800, Ren Wei wrote:
> From: Nan Li <tonanli66 at gmail.com>
> 
> A zerocopy send can fail after user pages have been pinned but before
> the message is attached to the sending socket.
> 
> The purge path currently infers zerocopy state from rm->m_rs, so an
> unqueued message can be cleaned up as if it owned normal payload pages.
> However, zerocopy ownership is really determined by the presence of
> op_mmp_znotifier, regardless of whether the message has reached the
> socket queue.
> 
> Capture op_mmp_znotifier up front in rds_message_purge() and use it as
> the cleanup discriminator. If the message is already associated with a
> socket, keep the existing completion path. Otherwise, drop the pinned
> page accounting directly and release the notifier before putting the
> payload pages.
> 
> This keeps early send failure cleanup consistent with the zerocopy
> lifetime rules without changing the normal queued completion path.
> 
> Fixes: 0cebaccef3ac ("rds: zerocopy Tx support.")
> Cc: stable at kernel.org
> Reported-by: Yuan Tan <yuantan098 at gmail.com>
> Reported-by: Yifan Wu <yifanwucs at gmail.com>
> Reported-by: Juefei Pu <tomapufckgml at gmail.com>
> Reported-by: Xin Liu <bird at lzu.edu.cn>
> Co-developed-by: Xiao Liu <lx24 at stu.ynu.edu.cn>
> Signed-off-by: Xiao Liu <lx24 at stu.ynu.edu.cn>
> Signed-off-by: Nan Li <tonanli66 at gmail.com>
> Signed-off-by: Ren Wei <n05ec at lzu.edu.cn>

This fix looks fine to me.  Thanks Ren Wei!
Reviewed-by: Allison Henderson <achender at kernel.org>

Allison

> ---
>  net/rds/message.c | 20 +++++++++++++++-----
>  1 file changed, 15 insertions(+), 5 deletions(-)
> 
> diff --git a/net/rds/message.c b/net/rds/message.c
> index eaa6f22601a4..25fedcb3cd00 100644
> --- a/net/rds/message.c
> +++ b/net/rds/message.c
> @@ -131,24 +131,34 @@ static void rds_rm_zerocopy_callback(struct rds_sock *rs,
>   */
>  static void rds_message_purge(struct rds_message *rm)
>  {
> +	struct rds_znotifier *znotifier;
>  	unsigned long i, flags;
> -	bool zcopy = false;
> +	bool zcopy;
>  
>  	if (unlikely(test_bit(RDS_MSG_PAGEVEC, &rm->m_flags)))
>  		return;
>  
>  	spin_lock_irqsave(&rm->m_rs_lock, flags);
> +	znotifier = rm->data.op_mmp_znotifier;
> +	rm->data.op_mmp_znotifier = NULL;
> +	zcopy = !!znotifier;
> +
>  	if (rm->m_rs) {
>  		struct rds_sock *rs = rm->m_rs;
>  
> -		if (rm->data.op_mmp_znotifier) {
> -			zcopy = true;
> -			rds_rm_zerocopy_callback(rs, rm->data.op_mmp_znotifier);
> +		if (znotifier) {
> +			rds_rm_zerocopy_callback(rs, znotifier);
>  			rds_wake_sk_sleep(rs);
> -			rm->data.op_mmp_znotifier = NULL;
>  		}
>  		sock_put(rds_rs_to_sk(rs));
>  		rm->m_rs = NULL;
> +	} else if (znotifier) {
> +		/*
> +		 * Zerocopy can fail before the message is queued on the
> +		 * socket, so there is no rs to carry the notification.
> +		 */
> +		mm_unaccount_pinned_pages(&znotifier->z_mmp);
> +		kfree(rds_info_from_znotifier(znotifier));
>  	}
>  	spin_unlock_irqrestore(&rm->m_rs_lock, flags);
>  




More information about the rds-devel mailing list