Page MenuHomeFreeBSD

D40356.diff
No OneTemporary

D40356.diff

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
@@ -53,7 +53,7 @@
* The goal of this file is to provide convenient message writing KPI on top of
* different storage methods (mbufs, uio, temporary memory chunks).
*
- * The main KPI guarantee is the the (last) message always resides in the contiguous
+ * The main KPI guarantee is that the (last) message always resides in the contiguous
* memory buffer, so one is able to update the header after writing the entire message.
*
* This guarantee comes with a side effect of potentially reallocating underlying
@@ -79,6 +79,71 @@
* change. It happens transparently to the caller.
*/
+/*
+ * Uma zone for the mbuf-based Netlink storage
+ */
+static uma_zone_t nlmsg_zone;
+
+static void
+nl_free_mbuf_storage(struct mbuf *m)
+{
+ uma_zfree(nlmsg_zone, m->m_ext.ext_buf);
+}
+
+static int
+nl_setup_mbuf_storage(void *mem, int size, void *arg, int how __unused)
+{
+ struct mbuf *m = (struct mbuf *)arg;
+
+ if (m != NULL)
+ m_extadd(m, mem, size, nl_free_mbuf_storage, NULL, NULL, 0, EXT_MOD_TYPE);
+
+ return (0);
+}
+
+static struct mbuf *
+nl_get_mbuf_flags(int size, int malloc_flags, int mbuf_flags)
+{
+ struct mbuf *m, *m_storage;
+
+ if (size <= MHLEN)
+ return (m_get2(size, malloc_flags, MT_DATA, mbuf_flags));
+
+ if (__predict_false(size > NLMBUFSIZE))
+ return (NULL);
+
+ m = m_gethdr(malloc_flags, MT_DATA);
+ if (m == NULL)
+ return (NULL);
+
+ m_storage = uma_zalloc_arg(nlmsg_zone, m, malloc_flags);
+ if (m_storage == NULL) {
+ m_free_raw(m);
+ return (NULL);
+ }
+
+ return (m);
+}
+
+static struct mbuf *
+nl_get_mbuf(int size, int malloc_flags)
+{
+ return (nl_get_mbuf_flags(size, malloc_flags, M_PKTHDR));
+}
+
+void
+nl_init_msg_zone(void)
+{
+ nlmsg_zone = uma_zcreate("netlink", NLMBUFSIZE, nl_setup_mbuf_storage,
+ NULL, NULL, NULL, UMA_ALIGN_PTR, 0);
+}
+
+void
+nl_destroy_msg_zone(void)
+{
+ uma_zdestroy(nlmsg_zone);
+}
+
typedef bool nlwriter_op_init(struct nl_writer *nw, int size, bool waitok);
typedef bool nlwriter_op_write(struct nl_writer *nw, void *buf, int buflen, int cnt);
@@ -196,17 +261,16 @@
* This is the most efficient mechanism as it avoids double-copying.
*
* Allocates a single mbuf suitable to store up to @size bytes of data.
- * If size < MHLEN (around 160 bytes), allocates mbuf with pkghdr
- * If size <= MCLBYTES (2k), allocate a single mbuf cluster
- * Otherwise, return NULL.
+ * If size < MHLEN (around 160 bytes), allocates mbuf with pkghdr.
+ * If the size <= NLMBUFSIZE (2k), allocate mbuf+storage out of nlmsg_zone.
+ * Returns NULL on greater size or the allocation failure.
*/
static bool
nlmsg_get_ns_mbuf(struct nl_writer *nw, int size, bool waitok)
{
- struct mbuf *m;
-
int mflag = waitok ? M_WAITOK : M_NOWAIT;
- m = m_get2(size, mflag, MT_DATA, M_PKTHDR);
+ struct mbuf *m = nl_get_mbuf(size, mflag);
+
if (__predict_false(m == NULL))
return (false);
nw->alloc_len = M_TRAILINGSPACE(m);
diff --git a/sys/netlink/netlink_module.c b/sys/netlink/netlink_module.c
--- a/sys/netlink/netlink_module.c
+++ b/sys/netlink/netlink_module.c
@@ -223,6 +223,7 @@
switch (what) {
case MOD_LOAD:
NL_LOG(LOG_DEBUG2, "Loading");
+ nl_init_msg_zone();
nl_osd_register();
#if !defined(NETLINK) && defined(NETLINK_MODULE)
nl_set_functions(&nl_module);
@@ -238,6 +239,7 @@
nl_set_functions(NULL);
#endif
nl_osd_unregister();
+ nl_destroy_msg_zone();
} else
ret = EBUSY;
break;
diff --git a/sys/netlink/netlink_var.h b/sys/netlink/netlink_var.h
--- a/sys/netlink/netlink_var.h
+++ b/sys/netlink/netlink_var.h
@@ -36,8 +36,10 @@
#include <sys/taskqueue.h>
#include <net/vnet.h>
-#define NLSNDQ 65536 /* Default socket sendspace */
-#define NLRCVQ 65536 /* Default socket recvspace */
+#define NLSNDQ 65536 /* Default socket sendspace */
+#define NLRCVQ 65536 /* Default socket recvspace */
+
+#define NLMBUFSIZE 2048 /* External storage size for Netlink mbufs */
struct ucred;
@@ -152,6 +154,10 @@
void nl_set_source_metadata(struct mbuf *m, int num_messages);
void nl_add_msg_info(struct mbuf *m);
+/* netlink_message_writer.c */
+void nl_init_msg_zone(void);
+void nl_destroy_msg_zone(void);
+
/* netlink_generic.c */
struct genl_family {
const char *family_name;

File Metadata

Mime Type
text/plain
Expires
Wed, Oct 2, 4:44 AM (21 h, 22 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
13305707
Default Alt Text
D40356.diff (4 KB)

Event Timeline