Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0
0002 #include <linux/ceph/ceph_debug.h>
0003 
0004 #include <linux/err.h>
0005 #include <linux/sched.h>
0006 #include <linux/types.h>
0007 #include <linux/vmalloc.h>
0008 
0009 #include <linux/ceph/messenger.h>
0010 #include <linux/ceph/msgpool.h>
0011 
0012 static void *msgpool_alloc(gfp_t gfp_mask, void *arg)
0013 {
0014     struct ceph_msgpool *pool = arg;
0015     struct ceph_msg *msg;
0016 
0017     msg = ceph_msg_new2(pool->type, pool->front_len, pool->max_data_items,
0018                 gfp_mask, true);
0019     if (!msg) {
0020         dout("msgpool_alloc %s failed\n", pool->name);
0021     } else {
0022         dout("msgpool_alloc %s %p\n", pool->name, msg);
0023         msg->pool = pool;
0024     }
0025     return msg;
0026 }
0027 
0028 static void msgpool_free(void *element, void *arg)
0029 {
0030     struct ceph_msgpool *pool = arg;
0031     struct ceph_msg *msg = element;
0032 
0033     dout("msgpool_release %s %p\n", pool->name, msg);
0034     msg->pool = NULL;
0035     ceph_msg_put(msg);
0036 }
0037 
0038 int ceph_msgpool_init(struct ceph_msgpool *pool, int type,
0039               int front_len, int max_data_items, int size,
0040               const char *name)
0041 {
0042     dout("msgpool %s init\n", name);
0043     pool->type = type;
0044     pool->front_len = front_len;
0045     pool->max_data_items = max_data_items;
0046     pool->pool = mempool_create(size, msgpool_alloc, msgpool_free, pool);
0047     if (!pool->pool)
0048         return -ENOMEM;
0049     pool->name = name;
0050     return 0;
0051 }
0052 
0053 void ceph_msgpool_destroy(struct ceph_msgpool *pool)
0054 {
0055     dout("msgpool %s destroy\n", pool->name);
0056     mempool_destroy(pool->pool);
0057 }
0058 
0059 struct ceph_msg *ceph_msgpool_get(struct ceph_msgpool *pool, int front_len,
0060                   int max_data_items)
0061 {
0062     struct ceph_msg *msg;
0063 
0064     if (front_len > pool->front_len ||
0065         max_data_items > pool->max_data_items) {
0066         pr_warn_ratelimited("%s need %d/%d, pool %s has %d/%d\n",
0067             __func__, front_len, max_data_items, pool->name,
0068             pool->front_len, pool->max_data_items);
0069         WARN_ON_ONCE(1);
0070 
0071         /* try to alloc a fresh message */
0072         return ceph_msg_new2(pool->type, front_len, max_data_items,
0073                      GFP_NOFS, false);
0074     }
0075 
0076     msg = mempool_alloc(pool->pool, GFP_NOFS);
0077     dout("msgpool_get %s %p\n", pool->name, msg);
0078     return msg;
0079 }
0080 
0081 void ceph_msgpool_put(struct ceph_msgpool *pool, struct ceph_msg *msg)
0082 {
0083     dout("msgpool_put %s %p\n", pool->name, msg);
0084 
0085     /* reset msg front_len; user may have changed it */
0086     msg->front.iov_len = pool->front_len;
0087     msg->hdr.front_len = cpu_to_le32(pool->front_len);
0088 
0089     msg->data_length = 0;
0090     msg->num_data_items = 0;
0091 
0092     kref_init(&msg->kref);  /* retake single ref */
0093     mempool_free(msg, pool->pool);
0094 }