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
2010-04-02 02:23:14 +04:00
static void * alloc_fn ( gfp_t gfp_mask , void * arg )
{
struct ceph_msgpool * pool = arg ;
2010-04-24 20:56:35 +04:00
void * p ;
2009-10-06 22:31:13 +04:00
2010-04-07 01:33:58 +04:00
p = ceph_msg_new ( 0 , pool - > front_len , gfp_mask ) ;
2010-04-24 20:56:35 +04:00
if ( ! p )
pr_err ( " msgpool %s alloc failed \n " , pool - > name ) ;
return p ;
2010-04-02 02:23:14 +04:00
}
2009-10-06 22:31:13 +04:00
2010-04-02 02:23:14 +04:00
static void free_fn ( void * element , void * arg )
2009-10-06 22:31:13 +04:00
{
2010-04-02 02:23:14 +04:00
ceph_msg_put ( element ) ;
2009-10-06 22:31:13 +04:00
}
int ceph_msgpool_init ( struct ceph_msgpool * pool ,
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
{
pool - > front_len = front_len ;
2010-04-02 02:23:14 +04:00
pool - > pool = mempool_create ( size , alloc_fn , free_fn , pool ) ;
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 )
{
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
{
2010-04-02 02:23:14 +04:00
if ( front_len > pool - > front_len ) {
2010-04-24 20:56:35 +04:00
pr_err ( " msgpool_get pool %s need front %d, pool size is %d \n " ,
pool - > name , front_len , pool - > front_len ) ;
2009-10-15 04:36:07 +04:00
WARN_ON ( 1 ) ;
/* try to alloc a fresh message */
2010-04-07 01:33:58 +04:00
return ceph_msg_new ( 0 , front_len , GFP_NOFS ) ;
2009-10-15 04:36:07 +04:00
}
2010-04-02 02:23:14 +04:00
return mempool_alloc ( pool - > pool , GFP_NOFS ) ;
2009-10-06 22:31:13 +04:00
}
void ceph_msgpool_put ( struct ceph_msgpool * pool , struct ceph_msg * 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 */
2009-10-06 22:31:13 +04:00
}