>> Okay. If callers must already handle 0 as a valid return code, then >> it is fine to add another case that does this. >> >> The extra branch in the hot path is still rather unfortunately. Could >> this be integrated in the existing if (nonblock) branch below? > > that's where I first started. it got even hairier because the > callers expect a retval of 0 (-EAGAIN threw rds-stress into an > infinite loop of continulally trying to recv) and the end result > was just confusing code with the same number of branches..
I do mean returning 0 instead of -EAGAIN if control data is ready. Something like @@ -611,7 +611,8 @@ int rds_recvmsg(struct socket *sock, struct msghdr *msg, size_t size, if (!rds_next_incoming(rs, &inc)) { if (nonblock) { - ret = -EAGAIN; + ncookies = rds_recvmsg_zcookie(rs, msg); + ret = ncookies ? 0 : -EAGAIN; break; } By the way, the put_cmsg is unconditional even if the caller did not supply msg_control. So it is basically no longer safe to ever call read, recv or recvfrom on a socket if zerocopy notifications are outstanding. It is possible to check msg_controllen before even deciding whether to try to dequeue notifications (and take the lock). I see that this is not common. But RDS of all cases seems to do this, in rds_notify_queue_get: max_messages = msghdr->msg_controllen / CMSG_SPACE(sizeof(cmsg));