Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit adfc42ea authored by Alex Vakulenko's avatar Alex Vakulenko
Browse files

Reduce the number of Send requests over UDS per IPC invocation

We sent up to 3 separate send requests over a socket. Now combine
then into one sendmgs() to improve performance and thread scheduling.

This improves PDX/UDS performance by up to 2x in some cases.

Bug: 65379030
Test: Sailfish works normally. Was able to run VR apps.
Change-Id: I00734d2c3f06d7d42b089569a8cc11c2273a1b7f
parent fcc70bdc
Loading
Loading
Loading
Loading
+6 −4
Original line number Diff line number Diff line
@@ -90,10 +90,12 @@ Status<void> SendRequest(const BorrowedHandle& socket_fd,
  size_t send_len = CountVectorSize(send_vector, send_count);
  InitRequest(&transaction_state->request, opcode, send_len, max_recv_len,
              false);
  auto status = SendData(socket_fd, transaction_state->request);
  if (status && send_len > 0)
    status = SendDataVector(socket_fd, send_vector, send_count);
  return status;
  if (send_len == 0) {
    send_vector = nullptr;
    send_count = 0;
  }
  return SendData(socket_fd, transaction_state->request, send_vector,
                  send_count);
}

Status<void> ReceiveResponse(const BorrowedHandle& socket_fd,
+34 −25
Original line number Diff line number Diff line
@@ -20,6 +20,9 @@ namespace uds {

namespace {

constexpr size_t kMaxFdCount =
    256;  // Total of 1KiB of data to transfer these FDs.

// Default implementations of Send/Receive interfaces to use standard socket
// send/sendmsg/recv/recvmsg functions.
class SocketSender : public SendInterface {
@@ -175,20 +178,31 @@ Status<void> SendPayload::Send(const BorrowedHandle& socket_fd) {
}

Status<void> SendPayload::Send(const BorrowedHandle& socket_fd,
                               const ucred* cred) {
                               const ucred* cred, const iovec* data_vec,
                               size_t vec_count) {
  if (file_handles_.size() > kMaxFdCount) {
    ALOGE(
        "SendPayload::Send: Trying to send too many file descriptors (%zu), "
        "max allowed = %zu",
        file_handles_.size(), kMaxFdCount);
    return ErrorStatus{EINVAL};
  }

  SendInterface* sender = sender_ ? sender_ : &g_socket_sender;
  MessagePreamble preamble;
  preamble.magic = kMagicPreamble;
  preamble.data_size = buffer_.size();
  preamble.fd_count = file_handles_.size();
  Status<void> ret = SendAll(sender, socket_fd, &preamble, sizeof(preamble));
  if (!ret)
    return ret;

  msghdr msg = {};
  iovec recv_vect = {buffer_.data(), buffer_.size()};
  msg.msg_iov = &recv_vect;
  msg.msg_iovlen = 1;
  msg.msg_iovlen = 2 + vec_count;
  msg.msg_iov = static_cast<iovec*>(alloca(sizeof(iovec) * msg.msg_iovlen));
  msg.msg_iov[0].iov_base = &preamble;
  msg.msg_iov[0].iov_len = sizeof(preamble);
  msg.msg_iov[1].iov_base = buffer_.data();
  msg.msg_iov[1].iov_len = buffer_.size();
  for (size_t i = 0; i < vec_count; i++)
    msg.msg_iov[i + 2] = data_vec[i];

  if (cred || !file_handles_.empty()) {
    const size_t fd_bytes = file_handles_.size() * sizeof(int);
@@ -270,7 +284,15 @@ Status<void> ReceivePayload::Receive(const BorrowedHandle& socket_fd,
                                     ucred* cred) {
  RecvInterface* receiver = receiver_ ? receiver_ : &g_socket_receiver;
  MessagePreamble preamble;
  Status<void> ret = RecvAll(receiver, socket_fd, &preamble, sizeof(preamble));
  msghdr msg = {};
  iovec recv_vect = {&preamble, sizeof(preamble)};
  msg.msg_iov = &recv_vect;
  msg.msg_iovlen = 1;
  const size_t receive_fd_bytes = kMaxFdCount * sizeof(int);
  msg.msg_controllen = CMSG_SPACE(sizeof(ucred)) + CMSG_SPACE(receive_fd_bytes);
  msg.msg_control = alloca(msg.msg_controllen);

  Status<void> ret = RecvMsgAll(receiver, socket_fd, &msg);
  if (!ret)
    return ret;

@@ -284,23 +306,6 @@ Status<void> ReceivePayload::Receive(const BorrowedHandle& socket_fd,
  file_handles_.clear();
  read_pos_ = 0;

  msghdr msg = {};
  iovec recv_vect = {buffer_.data(), buffer_.size()};
  msg.msg_iov = &recv_vect;
  msg.msg_iovlen = 1;

  if (cred || preamble.fd_count) {
    const size_t receive_fd_bytes = preamble.fd_count * sizeof(int);
    msg.msg_controllen =
        (cred ? CMSG_SPACE(sizeof(ucred)) : 0) +
        (receive_fd_bytes == 0 ? 0 : CMSG_SPACE(receive_fd_bytes));
    msg.msg_control = alloca(msg.msg_controllen);
  }

  ret = RecvMsgAll(receiver, socket_fd, &msg);
  if (!ret)
    return ret;

  bool cred_available = false;
  file_handles_.reserve(preamble.fd_count);
  cmsghdr* cmsg = CMSG_FIRSTHDR(&msg);
@@ -320,6 +325,10 @@ Status<void> ReceivePayload::Receive(const BorrowedHandle& socket_fd,
    cmsg = CMSG_NXTHDR(&msg, cmsg);
  }

  ret = RecvAll(receiver, socket_fd, buffer_.data(), buffer_.size());
  if (!ret)
    return ret;

  if (cred && !cred_available) {
    ALOGE("ReceivePayload::Receive: Failed to obtain message credentials");
    ret.SetError(EIO);
+10 −5
Original line number Diff line number Diff line
@@ -59,7 +59,8 @@ class SendPayload : public MessageWriter, public OutputResourceMapper {
 public:
  SendPayload(SendInterface* sender = nullptr) : sender_{sender} {}
  Status<void> Send(const BorrowedHandle& socket_fd);
  Status<void> Send(const BorrowedHandle& socket_fd, const ucred* cred);
  Status<void> Send(const BorrowedHandle& socket_fd, const ucred* cred,
                    const iovec* data_vec = nullptr, size_t vec_count = 0);

  // MessageWriter
  void* GetNextWriteBufferSection(size_t size) override;
@@ -156,18 +157,22 @@ class ResponseHeader {
};

template <typename T>
inline Status<void> SendData(const BorrowedHandle& socket_fd, const T& data) {
inline Status<void> SendData(const BorrowedHandle& socket_fd, const T& data,
                             const iovec* data_vec = nullptr,
                             size_t vec_count = 0) {
  SendPayload payload;
  rpc::Serialize(data, &payload);
  return payload.Send(socket_fd);
  return payload.Send(socket_fd, nullptr, data_vec, vec_count);
}

template <typename FileHandleType>
inline Status<void> SendData(const BorrowedHandle& socket_fd,
                             const RequestHeader<FileHandleType>& request) {
                             const RequestHeader<FileHandleType>& request,
                             const iovec* data_vec = nullptr,
                             size_t vec_count = 0) {
  SendPayload payload;
  rpc::Serialize(request, &payload);
  return payload.Send(socket_fd, &request.cred);
  return payload.Send(socket_fd, &request.cred, data_vec, vec_count);
}

Status<void> SendData(const BorrowedHandle& socket_fd, const void* data,