From ea9d34f865d5395b747c65730ef20aab20d80e8d Mon Sep 17 00:00:00 2001 From: Mike Christie Date: Mon, 30 Jun 2008 18:17:17 -0500 Subject: [PATCH 12/12] libfc: mv em exch cache to module A per host cache is overkill. For other storage drivers we do a cache per module. This moves the em exch cache to the module instead of per host. Signed-off-by: Mike Christie --- drivers/scsi/fcoe/fcoe_if.c | 2 +- drivers/scsi/libfc/fc_exch.c | 45 +++++++++++++++++++---------------------- drivers/scsi/libfc/fc_scsi.c | 9 +++++++- include/scsi/libfc/libfc.h | 9 ++++++- 4 files changed, 37 insertions(+), 28 deletions(-) diff --git a/drivers/scsi/fcoe/fcoe_if.c b/drivers/scsi/fcoe/fcoe_if.c index 7e42d0d..3c04f38 100644 --- a/drivers/scsi/fcoe/fcoe_if.c +++ b/drivers/scsi/fcoe/fcoe_if.c @@ -486,7 +486,7 @@ int fcoe_create_interface(const char *ifname) shost->max_channel = 0; /* Allocate an EM for this driver */ - lp->emp = fc_exch_mgr_alloc(lp, FC_CLASS_3, FC_MIN_XID, FC_MAX_XID, 0); + lp->emp = fc_exch_mgr_alloc(lp, FC_CLASS_3, FC_MIN_XID, FC_MAX_XID); if (!lp->emp) goto out_host_put; diff --git a/drivers/scsi/libfc/fc_exch.c b/drivers/scsi/libfc/fc_exch.c index afce253..48ed0dd 100644 --- a/drivers/scsi/libfc/fc_exch.c +++ b/drivers/scsi/libfc/fc_exch.c @@ -37,7 +37,7 @@ * fc_exch_debug can be set in debugger or at compile time to get more logs. */ static int fc_exch_debug; - +static struct kmem_cache *em_cachep; /* cache for exchanges */ /* * Structure and function definitions for managing Fibre Channel Exchanges @@ -113,10 +113,8 @@ struct fc_exch_mgr { fc_xid_t em_last_xid; /* last allocated exchange ID */ fc_xid_t em_min_xid; /* min exchange ID */ fc_xid_t em_max_xid; /* max exchange ID */ - char em_name[16]; /* cache name string */ - struct kmem_cache *em_cp; /* cache for exchanges */ - u32 em_exch_total; /* total allocated exchanges */ - struct list_head em_exch_list; /* allocated exchanges list */ + u32 em_exch_total; /* total allocated exchanges */ + struct list_head em_exch_list; /* allocated exchanges list */ struct fc_lport *lp; /* fc device instance */ /* @@ -1666,8 +1664,7 @@ reject: struct fc_exch_mgr *fc_exch_mgr_alloc(struct fc_lport *lp, enum fc_class class, fc_xid_t min_xid, - fc_xid_t max_xid, - u32 em_idx) + fc_xid_t max_xid) { struct fc_exch_mgr *mp; size_t len; @@ -1696,19 +1693,6 @@ struct fc_exch_mgr *fc_exch_mgr_alloc(struct fc_lport *lp, INIT_LIST_HEAD(&mp->em_exch_list); spin_lock_init(&mp->em_lock); - - sprintf(mp->em_name, - "libfc-host%d-EM%d", - lp->host->host_no, em_idx); - mp->em_cp = kmem_cache_create(mp->em_name, - sizeof(struct fc_exch), - 0, SLAB_HWCACHE_ALIGN, - NULL); - - if (!mp->em_cp) { - kfree(mp); - mp = NULL; - } } return mp; } @@ -1718,7 +1702,6 @@ void fc_exch_mgr_free(struct fc_exch_mgr *mp) { WARN_ON(!mp); - kmem_cache_destroy(mp->em_cp); kfree(mp); } EXPORT_SYMBOL(fc_exch_mgr_free); @@ -1747,7 +1730,7 @@ struct fc_exch *fc_exch_alloc(struct fc_exch_mgr *mp, fc_xid_t ex_id) /* * Allocate new exchange */ - ep = kmem_cache_zalloc(mp->em_cp, GFP_ATOMIC); + ep = kmem_cache_zalloc(em_cachep, GFP_ATOMIC); if (!ep) { atomic_inc(&mp->em_stats.ems_error_no_free_exch); goto out; @@ -1775,7 +1758,7 @@ struct fc_exch *fc_exch_alloc(struct fc_exch_mgr *mp, fc_xid_t ex_id) } else { spin_unlock_bh(&mp->em_lock); atomic_inc(&mp->em_stats.ems_error_no_free_exch_xid); - kmem_cache_free(mp->em_cp, ep); + kmem_cache_free(em_cachep, ep); goto out; } } @@ -1822,7 +1805,7 @@ static void fc_exch_release(struct fc_exch *ep) mp->em_exchpa[ep->ex_xid - mp->em_min_xid] = NULL; list_del(&ep->ex_list); spin_unlock_bh(&mp->em_lock); - kmem_cache_free(mp->em_cp, ep); + kmem_cache_free(em_cachep, ep); } } @@ -2052,3 +2035,17 @@ int fc_exch_init(struct fc_lport *lp, return 0; } EXPORT_SYMBOL(fc_exch_init); + +int fc_setup_exch_mgr(void) +{ + em_cachep = kmem_cache_create("libfc_em", sizeof(struct fc_exch), + 0, SLAB_HWCACHE_ALIGN, NULL); + if (!em_cachep) + return -ENOMEM; + return 0; +} + +void fc_destroy_exch_mgr(void) +{ + kmem_cache_destroy(em_cachep); +} diff --git a/drivers/scsi/libfc/fc_scsi.c b/drivers/scsi/libfc/fc_scsi.c index d67540d..24ddceb 100644 --- a/drivers/scsi/libfc/fc_scsi.c +++ b/drivers/scsi/libfc/fc_scsi.c @@ -2155,6 +2155,8 @@ EXPORT_SYMBOL(fc_scsi_init); static int __init libfc_init(void) { + int rc; + scsi_pkt_cachep = kmem_cache_create("libfc_scsi_pkt", sizeof(struct fc_scsi_pkt), 0, SLAB_HWCACHE_ALIGN, NULL); @@ -2162,12 +2164,17 @@ static int __init libfc_init(void) FC_DBG("Unable to allocate SRB cache...module load failed!"); return -ENOMEM; } - return 0; + + rc = fc_setup_exch_mgr(); + if (rc) + kmem_cache_destroy(scsi_pkt_cachep); + return rc; } static void __exit libfc_exit(void) { kmem_cache_destroy(scsi_pkt_cachep); + fc_destroy_exch_mgr(); } module_init(libfc_init); diff --git a/include/scsi/libfc/libfc.h b/include/scsi/libfc/libfc.h index 3c61b87..92c1e4a 100644 --- a/include/scsi/libfc/libfc.h +++ b/include/scsi/libfc/libfc.h @@ -728,8 +728,7 @@ int fc_exch_init(struct fc_lport *lp, struct fc_exch_mgr *fc_exch_mgr_alloc(struct fc_lport *lp, enum fc_class class, fc_xid_t min_xid, - fc_xid_t max_xid, - u32 em_idx); + fc_xid_t max_xid); /* * Free an exchange manager. @@ -831,4 +830,10 @@ void fc_get_rport_loss_tmo(struct fc_rport *rport); void fc_set_rport_loss_tmo(struct fc_rport *rport, u32 timeout); struct fc_host_statistics *fc_get_host_stats(struct Scsi_Host *); +/* + * module setup functions. + */ +int fc_setup_exch_mgr(void); +void fc_destroy_exch_mgr(void); + #endif /* _LIBFC_H_ */ -- 1.5.4.1