Remove the zerocopy write threshold support, add support for ENOBUFS
authorDan Melnic <dmm@fb.com>
Thu, 9 Nov 2017 19:28:07 +0000 (11:28 -0800)
committerFacebook Github Bot <facebook-github-bot@users.noreply.github.com>
Thu, 9 Nov 2017 19:37:58 +0000 (11:37 -0800)
Summary: Remove the zerocopy write threshold support since it is a little bit confusing

Reviewed By: djwatson

Differential Revision: D6256854

fbshipit-source-id: 1c992f93d7b04c4ede2fbefebde7a7ae89de3764

folly/io/async/AsyncSocket.cpp
folly/io/async/AsyncSocket.h
folly/io/async/test/ZeroCopyBenchmark.cpp

index 0a78e404a5889c6cdd3cae2ed6aa675596e1dea0..67c86bf81676f5e269ac8e056aefc0bbda340a81 100644 (file)
@@ -106,7 +106,7 @@ class AsyncSocket::BytesWriteRequest : public AsyncSocket::WriteRequest {
       writeFlags |= WriteFlags::CORK;
     }
 
-    socket_->adjustZeroCopyFlags(getOps(), getOpCount(), writeFlags);
+    socket_->adjustZeroCopyFlags(writeFlags);
 
     auto writeResult = socket_->performWrite(
         getOps(), getOpCount(), writeFlags, &opsWritten_, &partialBytes_);
@@ -854,44 +854,13 @@ bool AsyncSocket::setZeroCopy(bool enable) {
   return false;
 }
 
-void AsyncSocket::setZeroCopyWriteChainThreshold(size_t threshold) {
-  zeroCopyWriteChainThreshold_ = threshold;
-}
-
 bool AsyncSocket::isZeroCopyRequest(WriteFlags flags) {
   return (zeroCopyEnabled_ && isSet(flags, WriteFlags::WRITE_MSG_ZEROCOPY));
 }
 
-void AsyncSocket::adjustZeroCopyFlags(
-    folly::IOBuf* buf,
-    folly::WriteFlags& flags) {
-  if (zeroCopyEnabled_ && zeroCopyWriteChainThreshold_ && buf &&
-      buf->isManaged()) {
-    if (buf->computeChainDataLength() >= zeroCopyWriteChainThreshold_) {
-      flags |= folly::WriteFlags::WRITE_MSG_ZEROCOPY;
-    } else {
-      flags = unSet(flags, folly::WriteFlags::WRITE_MSG_ZEROCOPY);
-    }
-  }
-}
-
-void AsyncSocket::adjustZeroCopyFlags(
-    const iovec* vec,
-    uint32_t count,
-    folly::WriteFlags& flags) {
-  if (zeroCopyEnabled_ && zeroCopyWriteChainThreshold_) {
-    count = std::min<uint32_t>(count, kIovMax);
-    size_t sum = 0;
-    for (uint32_t i = 0; i < count; ++i) {
-      const iovec* v = vec + i;
-      sum += v->iov_len;
-    }
-
-    if (sum >= zeroCopyWriteChainThreshold_) {
-      flags |= folly::WriteFlags::WRITE_MSG_ZEROCOPY;
-    } else {
-      flags = unSet(flags, folly::WriteFlags::WRITE_MSG_ZEROCOPY);
-    }
+void AsyncSocket::adjustZeroCopyFlags(folly::WriteFlags& flags) {
+  if (!zeroCopyEnabled_) {
+    flags = unSet(flags, folly::WriteFlags::WRITE_MSG_ZEROCOPY);
   }
 }
 
@@ -987,7 +956,7 @@ void AsyncSocket::writev(WriteCallback* callback,
 
 void AsyncSocket::writeChain(WriteCallback* callback, unique_ptr<IOBuf>&& buf,
                               WriteFlags flags) {
-  adjustZeroCopyFlags(buf.get(), flags);
+  adjustZeroCopyFlags(flags);
 
   constexpr size_t kSmallSizeMax = 64;
   size_t count = buf->countChainElements();
@@ -1758,8 +1727,7 @@ void AsyncSocket::handleErrMessages() noexcept {
   // supporting per-socket error queues.
   VLOG(5) << "AsyncSocket::handleErrMessages() this=" << this << ", fd=" << fd_
           << ", state=" << state_;
-  if (errMessageCallback_ == nullptr &&
-      (!zeroCopyEnabled_ || idZeroCopyBufPtrMap_.empty())) {
+  if (errMessageCallback_ == nullptr && idZeroCopyBufPtrMap_.empty()) {
     VLOG(7) << "AsyncSocket::handleErrMessages(): "
             << "no callback installed - exiting.";
     return;
@@ -2358,6 +2326,14 @@ AsyncSocket::WriteResult AsyncSocket::performWrite(
     // this bug is fixed.
     tryAgain |= (errno == ENOTCONN);
 #endif
+
+    // workaround for running with zerocopy enabled but without a proper
+    // memlock value - see ulimit -l
+    if (zeroCopyEnabled_ && (errno == ENOBUFS)) {
+      tryAgain = true;
+      zeroCopyEnabled_ = false;
+    }
+
     if (!writeResult.exception && tryAgain) {
       // TCP buffer is full; we can't write any more data right now.
       *countWritten = 0;
index 22dbc3944d8c63ce35aa18cc4b5c50501e0b1359..17980bb7c82dda9abd2f9767c31d2c58b245ca3e 100644 (file)
@@ -505,18 +505,11 @@ class AsyncSocket : virtual public AsyncTransportWrapper {
   void setReadCB(ReadCallback* callback) override;
   ReadCallback* getReadCallback() const override;
 
-  static const size_t kDefaultZeroCopyThreshold = 0;
-
   bool setZeroCopy(bool enable);
   bool getZeroCopy() const {
     return zeroCopyEnabled_;
   }
 
-  void setZeroCopyWriteChainThreshold(size_t threshold);
-  size_t getZeroCopyWriteChainThreshold() const {
-    return zeroCopyWriteChainThreshold_;
-  }
-
   uint32_t getZeroCopyBufId() const {
     return zeroCopyBufId_;
   }
@@ -1164,11 +1157,7 @@ class AsyncSocket : virtual public AsyncTransportWrapper {
   uint32_t getNextZeroCopyBufId() {
     return zeroCopyBufId_++;
   }
-  void adjustZeroCopyFlags(folly::IOBuf* buf, folly::WriteFlags& flags);
-  void adjustZeroCopyFlags(
-      const iovec* vec,
-      uint32_t count,
-      folly::WriteFlags& flags);
+  void adjustZeroCopyFlags(folly::WriteFlags& flags);
   void addZeroCopyBuf(std::unique_ptr<folly::IOBuf>&& buf);
   void addZeroCopyBuf(folly::IOBuf* ptr);
   void setZeroCopyBuf(std::unique_ptr<folly::IOBuf>&& buf);
@@ -1240,7 +1229,6 @@ class AsyncSocket : virtual public AsyncTransportWrapper {
   bool trackEor_{false};
   bool zeroCopyEnabled_{false};
   bool zeroCopyVal_{false};
-  size_t zeroCopyWriteChainThreshold_{kDefaultZeroCopyThreshold};
 };
 #ifdef _MSC_VER
 #pragma vtordisp(pop)
index 6ef917ea9848068fee5ac55e14adae2706fce864..f7dd422dad3e10f029272000e5828f62c6d16c35 100644 (file)
@@ -27,8 +27,6 @@
 
 using namespace folly;
 
-static constexpr auto const kZeroCopyThreshold = 4096;
-
 class TestAsyncSocket {
  public:
   explicit TestAsyncSocket(
@@ -79,9 +77,6 @@ class TestAsyncSocket {
     zeroCopy_ = enable;
     if (sock_) {
       sock_->setZeroCopy(zeroCopy_);
-      if (zeroCopy_) {
-        sock_->setZeroCopyWriteChainThreshold(kZeroCopyThreshold);
-      }
     }
   }