When fd_type is fd_normal, pollfd needs to be replaced with the actual fd instead of the index#1730
When fd_type is fd_normal, pollfd needs to be replaced with the actual fd instead of the index#1730kaolamall wants to merge 1 commit into
Conversation
9786441 to
85e37d7
Compare
|
This PR should include only commits which you should merge, so please rebase your PR to the latest master branch and force push result to this pull request. Thanks |
When using rdma-core's preload library, the poll function needs to correctly distinguish between rsocket-managed fds and normal fds. This change ensures that pollfd structures are properly prepared and the call is routed to either the native poll or rpoll based on the actual fd type. Signed-off-by: zhangwenge <zhangwengege@126.com>
|
|
||
| ret = rpoll(rfds, nfds, timeout); | ||
| if (!has_rsocket) | ||
| ret = real.poll(rfds, nfds, timeout); |
There was a problem hiding this comment.
The existing code does check for a normal fd and calls real.poll() if there are no rsocket fd's. The commit message does not indicate what the error is in the current flow.
There was a problem hiding this comment.
The fds[i].fd passed to the real.poll function is not the correct socket descriptor. It is the "index" returned in the following code. The correct approach is to follow the same fds handling as in rpoll, where rfds[i].fd = fd_getd(fds[i].fd); to obtain the real fd, and then call real.poll.
index = fd_open();
if (index < 0)
return index;
if (fork_support && (domain == PF_INET || domain == PF_INET6) &&
(type == SOCK_STREAM) && (!protocol || protocol == IPPROTO_TCP)) {
ret = real.socket(domain, type, protocol);
if (ret < 0)
return ret;
fd_store(index, ret, fd_normal, fd_fork);
return index;
}
There was a problem hiding this comment.
Sorry, I wasn't clear. Can you please update this information into the commit message itself? The comments in the pull request will be much harder to associate with the commit once merged.
We might be able to make the change simpler. If fork_support is enabled, just always goto use_rpoll. That, or maybe we just remove the 'poll' optimization path. Does your use case go through this flow often?
In the socket function, when in fork_support mode, a normal socket is created, and the return value is the index, not the socket fd. When polling, the fd passed in the pollfd parameter must be the index, not the actual socket fd. Before calling real.poll, the fd in pollfd is not replaced with the actual socket fd, so real.poll cannot poll for the correct event.
In the socket function:
if (fork_support && (domain == PF_INET || domain == PF_INET6) &&
(type == SOCK_STREAM) && (!protocol || protocol == IPPROTO_TCP)) {
ret = real.socket(domain, type, protocol);
if (ret < 0)
return ret;
fd_store(index, ret, fd_normal, fd_fork);
return index; //Here return the index, not real socket fd.
}
In the poll function:
for (i = 0; i < nfds; i++) {
if (fd_gett(fds[i].fd) == fd_rsocket) // If only fd_normal is present in fds, real.poll will be called, and the fd in fds is not a real socket fd
goto use_rpoll;
}
return real.poll(fds, nfds, timeout);