Page MenuHomeFreeBSD

D60249.1793611170.diff
No OneTemporary

Authored By
Unknown
Size
2 KB
Referenced Files
None
Subscribers
None

D60249.1793611170.diff

diff --git a/sys/netlink/netlink_io.c b/sys/netlink/netlink_io.c
--- a/sys/netlink/netlink_io.c
+++ b/sys/netlink/netlink_io.c
@@ -295,6 +295,9 @@
NL_LOG(LOG_DEBUG2, "retcode: %d", error);
}
ack:
+ /* A reply that ran out of memory is incomplete. */
+ if (npt->nw->enomem && error == 0)
+ error = ENOMEM;
if ((hdr->nlmsg_flags & NLM_F_ACK) || (error != 0 && error != EINTR)) {
if (!npt->nw->suppress_ack) {
NL_LOG(LOG_DEBUG3, "ack");
@@ -314,6 +317,7 @@
npt->err_msg = NULL;
npt->err_off = 0;
npt->hdr = NULL;
+ npt->nw->enomem = false;
npt->nw->suppress_ack = false;
}
@@ -329,10 +333,9 @@
NL_LOG(LOG_DEBUG3, "RX netlink buf %p on %p", nb, nlp->nl_socket);
- if (!nl_writer_unicast(&nw, NLMSG_SMALL, nlp, false)) {
- NL_LOG(LOG_DEBUG, "error allocating socket writer");
- return (true);
- }
+ /* Handlers write with locks held: their allocations must not sleep. */
+ (void)nl_writer_unicast(&nw, NLMSG_SMALL, nlp, true);
+ nw.malloc_flag = M_NOWAIT;
nlmsg_ignore_limit(&nw);
diff --git a/sys/netlink/netlink_message_writer.c b/sys/netlink/netlink_message_writer.c
--- a/sys/netlink/netlink_message_writer.c
+++ b/sys/netlink/netlink_message_writer.c
@@ -271,7 +271,17 @@
int payload_len;
uint32_t flags = nlp->nl_flags;
struct nl_writer *nw = npt->nw;
- bool cap_ack;
+ int malloc_flag = nw->malloc_flag;
+ bool cap_ack, ok __diagused;
+
+ /*
+ * The reader waits for the ack. No locks are held here, so wait for
+ * memory, also if the reply has run out of it. Drop a message that
+ * the handler left unfinished.
+ */
+ nlmsg_abort(nw);
+ nw->enomem = false;
+ nw->malloc_flag = M_WAITOK;
payload_len = sizeof(struct nlmsgerr);
@@ -292,10 +302,12 @@
NL_LOG(LOG_DEBUG3, "acknowledging message type %d seq %d",
hdr->nlmsg_type, hdr->nlmsg_seq);
- if (!nlmsg_add(nw, nlp->nl_port, hdr->nlmsg_seq, NLMSG_ERROR, nl_flags, payload_len))
- goto enomem;
+ ok = nlmsg_add(nw, nlp->nl_port, hdr->nlmsg_seq, NLMSG_ERROR, nl_flags,
+ payload_len);
+ MPASS(ok);
errmsg = nlmsg_reserve_data(nw, payload_len, struct nlmsgerr);
+ MPASS(errmsg != NULL);
errmsg->error = error;
/* In case of error copy the whole message, else just the header */
memcpy(&errmsg->msg, hdr, cap_ack ? sizeof(*hdr) : hdr->nlmsg_len);
@@ -307,12 +319,9 @@
if (npt->cookie != NULL)
nlattr_add_raw(nw, npt->cookie);
- if (nlmsg_end(nw))
- return;
-enomem:
- NLP_LOG(LOG_DEBUG, nlp, "error allocating ack data for message %d seq %u",
- hdr->nlmsg_type, hdr->nlmsg_seq);
- nlmsg_abort(nw);
+ ok = nlmsg_end(nw);
+ MPASS(ok);
+ nw->malloc_flag = malloc_flag;
}
bool
@@ -327,7 +336,9 @@
NL_LOG(LOG_DEBUG2, "record error=%d at off %d (%p)", error,
nw->buf->datalen, perror);
*perror = error;
- nlmsg_end(nw);
+ /* A dump that ran out of memory ends with the ack instead. */
+ if (!nlmsg_end(nw))
+ return (false);
nw->suppress_ack = true;
return (true);

File Metadata

Mime Type
text/plain
Expires
Mon, Nov 2, 9:19 AM (18 h, 1 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
41274441
Default Alt Text
D60249.1793611170.diff (2 KB)

Event Timeline