2010-04-07 02:14:15 +04:00
# include <linux/ceph/ceph_debug.h>
2009-10-06 22:31:13 +04:00
# include <linux/err.h>
# include <linux/sched.h>
# include <linux/types.h>
# include <linux/vmalloc.h>
2010-04-07 02:14:15 +04:00
# include <linux/ceph/msgpool.h>
2009-10-06 22:31:13 +04:00
2011-08-10 01:48:11 +04:00
static void * msgpool_alloc ( gfp_t gfp_mask , void * arg )
2010-04-02 02:23:14 +04:00
{
struct ceph_msgpool * pool = arg ;
2011-08-10 01:48:11 +04:00
struct ceph_msg * msg ;
2009-10-06 22:31:13 +04:00
2012-07-10 01:22:34 +04:00
msg = ceph_msg_new ( pool - > type , pool - > front_len , gfp_mask , true ) ;
2011-08-10 01:48:11 +04:00
if ( ! msg ) {
dout ( " msgpool_alloc %s failed \n " , pool - > name ) ;
} else {
dout ( " msgpool_alloc %s %p \n " , pool - > name , msg ) ;
msg - > pool = pool ;
}
return msg ;
2010-04-02 02:23:14 +04:00
}
2009-10-06 22:31:13 +04:00
2011-08-10 01:48:11 +04:00
static void msgpool_free ( void * element , void * arg )
2009-10-06 22:31:13 +04:00
{
2011-08-10 01:48:11 +04:00
struct ceph_msgpool * pool = arg ;
struct ceph_msg * msg = element ;
dout ( " msgpool_release %s %p \n " , pool - > name , msg ) ;
msg - > pool = NULL ;
ceph_msg_put ( msg ) ;
2009-10-06 22:31:13 +04:00
}
2012-07-10 01:22:34 +04:00
int ceph_msgpool_init ( struct ceph_msgpool * pool , int type ,
2010-04-24 20:56:35 +04:00
int front_len , int size , bool blocking , const char * name )
2009-10-06 22:31:13 +04:00
{
2011-08-10 01:48:11 +04:00
dout ( " msgpool %s init \n " , name ) ;
2012-07-10 01:22:34 +04:00
pool - > type = type ;
2009-10-06 22:31:13 +04:00
pool - > front_len = front_len ;
2011-08-10 01:48:11 +04:00
pool - > pool = mempool_create ( size , msgpool_alloc , msgpool_free , pool ) ;
2010-04-02 02:23:14 +04:00
if ( ! pool - > pool )
return - ENOMEM ;
2010-04-24 20:56:35 +04:00
pool - > name = name ;
2010-04-02 02:23:14 +04:00
return 0 ;
2009-10-06 22:31:13 +04:00
}
void ceph_msgpool_destroy ( struct ceph_msgpool * pool )
{
2011-08-10 01:48:11 +04:00
dout ( " msgpool %s destroy \n " , pool - > name ) ;
2010-04-02 02:23:14 +04:00
mempool_destroy ( pool - > pool ) ;
2009-10-06 22:31:13 +04:00
}
2010-04-02 02:23:14 +04:00
struct ceph_msg * ceph_msgpool_get ( struct ceph_msgpool * pool ,
int front_len )
2009-10-06 22:31:13 +04:00
{
2011-08-10 01:48:11 +04:00
struct ceph_msg * msg ;
2010-04-02 02:23:14 +04:00
if ( front_len > pool - > front_len ) {
2011-08-10 01:48:11 +04:00
dout ( " msgpool_get %s need front %d, pool size is %d \n " ,
2010-04-24 20:56:35 +04:00
pool - > name , front_len , pool - > front_len ) ;
2009-10-15 04:36:07 +04:00
WARN_ON ( 1 ) ;
/* try to alloc a fresh message */
2012-07-10 01:22:34 +04:00
return ceph_msg_new ( pool - > type , front_len , GFP_NOFS , false ) ;
2009-10-15 04:36:07 +04:00
}
2011-08-10 01:48:11 +04:00
msg = mempool_alloc ( pool - > pool , GFP_NOFS ) ;
dout ( " msgpool_get %s %p \n " , pool - > name , msg ) ;
return msg ;
2009-10-06 22:31:13 +04:00
}
void ceph_msgpool_put ( struct ceph_msgpool * pool , struct ceph_msg * msg )
{
2011-08-10 01:48:11 +04:00
dout ( " msgpool_put %s %p \n " , pool - > name , msg ) ;
2010-04-02 02:23:14 +04:00
/* reset msg front_len; user may have changed it */
msg - > front . iov_len = pool - > front_len ;
msg - > hdr . front_len = cpu_to_le32 ( pool - > front_len ) ;
2010-03-02 02:25:00 +03:00
2010-04-02 02:23:14 +04:00
kref_init ( & msg - > kref ) ; /* retake single ref */
2011-08-10 01:48:11 +04:00
mempool_free ( msg , pool - > pool ) ;
2009-10-06 22:31:13 +04:00
}