+ ofpbuf_set_data(reply, NULL);
+ ofpbuf_set_size(reply, 0);
+
+ /* If 'buffer' is empty, fetch another batch of nlmsgs. */
+ while (!ofpbuf_size(buffer)) {
+ unsigned int status;
+ int retval, seq;
+
+ seq = seq_read(dump->status_seq);
+ atomic_read(&dump->status, &status);
+ if (status) {
+ return false;
+ }
+
+ /* Take the mutex here to avoid an in-kernel race. If two threads try
+ * to read from a Netlink dump socket at once, then the socket error
+ * can be set to EINVAL, which will be encountered on the next recv on
+ * that socket, which could be anywhere due to the way that we pool
+ * Netlink sockets. Serializing the recv calls avoids the issue. */
+ ovs_mutex_lock(&dump->mutex);
+ retval = nl_sock_recv__(dump->sock, buffer, false);
+ ovs_mutex_unlock(&dump->mutex);