#define MAX_PORTALS 64
+#define LNET_SMALL_MD_SIZE offsetof(lnet_libmd_t, md_iov.iov[1])
+extern struct kmem_cache *lnet_mes_cachep; /* MEs kmem_cache */
+extern struct kmem_cache *lnet_small_mds_cachep; /* <= LNET_SMALL_MD_SIZE bytes
+ * MDs kmem_cache */
+
static inline lnet_eq_t *
lnet_eq_alloc (void)
{
size = offsetof(lnet_libmd_t, md_iov.iov[niov]);
}
- LIBCFS_ALLOC(md, size);
+ if (size <= LNET_SMALL_MD_SIZE) {
+ md = kmem_cache_alloc(lnet_small_mds_cachep,
+ GFP_NOFS | __GFP_ZERO);
+ if (md) {
+ CDEBUG(D_MALLOC, "slab-alloced 'md' of size %u at "
+ "%p.\n", size, md);
+ } else {
+ CDEBUG(D_MALLOC, "failed to allocate 'md' of size %u\n",
+ size);
+ return NULL;
+ }
+ } else {
+ LIBCFS_ALLOC(md, size);
+ }
if (md != NULL) {
/* Set here in case of early free */
else
size = offsetof(lnet_libmd_t, md_iov.iov[md->md_niov]);
- LIBCFS_FREE(md, size);
+ if (size <= LNET_SMALL_MD_SIZE) {
+ CDEBUG(D_MALLOC, "slab-freed 'md' at %p.\n", md);
+ kmem_cache_free(lnet_small_mds_cachep, md);
+ } else {
+ LIBCFS_FREE(md, size);
+ }
}
static inline lnet_me_t *
lnet_me_alloc (void)
{
- lnet_me_t *me;
+ lnet_me_t *me;
+
+ me = kmem_cache_alloc(lnet_mes_cachep, GFP_NOFS | __GFP_ZERO);
+
+ if (me)
+ CDEBUG(D_MALLOC, "slab-alloced 'me' at %p.\n", me);
+ else
+ CDEBUG(D_MALLOC, "failed to allocate 'me'\n");
- LIBCFS_ALLOC(me, sizeof(*me));
- return (me);
+ return me;
}
static inline void
lnet_me_free(lnet_me_t *me)
{
- LIBCFS_FREE(me, sizeof(*me));
+ CDEBUG(D_MALLOC, "slab-freed 'me' at %p.\n", me);
+ kmem_cache_free(lnet_mes_cachep, me);
}
static inline lnet_msg_t *
{
}
+struct kmem_cache *lnet_mes_cachep; /* MEs kmem_cache */
+struct kmem_cache *lnet_small_mds_cachep; /* <= LNET_SMALL_MD_SIZE bytes
+ * MDs kmem_cache */
+
+static int
+lnet_descriptor_setup(void)
+{
+ /* create specific kmem_cache for MEs and small MDs (i.e., originally
+ * allocated in <size-xxx> kmem_cache).
+ */
+ lnet_mes_cachep = kmem_cache_create("lnet_MEs", sizeof(lnet_me_t),
+ 0, 0, NULL);
+ if (!lnet_mes_cachep)
+ return -ENOMEM;
+
+ lnet_small_mds_cachep = kmem_cache_create("lnet_small_MDs",
+ LNET_SMALL_MD_SIZE, 0, 0,
+ NULL);
+ if (!lnet_small_mds_cachep)
+ return -ENOMEM;
+
+ return 0;
+}
+
+static void
+lnet_descriptor_cleanup(void)
+{
+
+ if (lnet_small_mds_cachep) {
+ kmem_cache_destroy(lnet_small_mds_cachep);
+ lnet_small_mds_cachep = NULL;
+ }
+
+ if (lnet_mes_cachep) {
+ kmem_cache_destroy(lnet_mes_cachep);
+ lnet_mes_cachep = NULL;
+ }
+}
+
static int
lnet_create_remote_nets_table(void)
{
INIT_LIST_HEAD(&the_lnet.ln_drop_rules);
INIT_LIST_HEAD(&the_lnet.ln_delay_rules);
+ rc = lnet_descriptor_setup();
+ if (rc != 0)
+ goto failed;
+
rc = lnet_create_remote_nets_table();
if (rc != 0)
goto failed;
the_lnet.ln_counters = NULL;
}
lnet_destroy_remote_nets_table();
+ lnet_descriptor_cleanup();
return 0;
}