aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorNicholas Bellinger <nab@linux-iscsi.org>2013-06-07 20:38:58 -0400
committerNicholas Bellinger <nab@linux-iscsi.org>2013-09-09 17:29:16 -0400
commitc0add7fd05ff99c3a516c78eb6b1e6460a3efdae (patch)
tree2aa45b7fe481134865e179caf631501bad811959
parent798ab48eecdf659df9ae0064ca5c62626c651827 (diff)
target: Add transport_init_session_tags using per-cpu ida
This patch adds lib/idr.c based transport_init_session_tags() logic that allows fabric drivers to setup a per-cpu se_sess->sess_tag_pool and associated se_sess->sess_cmd_map for basic tagged pre-allocation of fabric descriptor sized memory. v5 changes: - Convert to percpu_ida.h include v4 changes: - Add transport_alloc_session_tags() for fabrics that need early transport_init_session() v3 changes: - Update to percpu-ida usage Cc: Kent Overstreet <kmo@daterainc.com> Cc: Asias He <asias@redhat.com> Cc: Michael S. Tsirkin <mst@redhat.com> Reviewed-by: Asias He <asias@redhat.com> Signed-off-by: Nicholas Bellinger <nab@linux-iscsi.org>
-rw-r--r--drivers/target/target_core_transport.c48
-rw-r--r--include/target/target_core_base.h5
-rw-r--r--include/target/target_core_fabric.h3
3 files changed, 56 insertions, 0 deletions
diff --git a/drivers/target/target_core_transport.c b/drivers/target/target_core_transport.c
index 7172d005d063..98ec7110873b 100644
--- a/drivers/target/target_core_transport.c
+++ b/drivers/target/target_core_transport.c
@@ -232,6 +232,50 @@ struct se_session *transport_init_session(void)
232} 232}
233EXPORT_SYMBOL(transport_init_session); 233EXPORT_SYMBOL(transport_init_session);
234 234
235int transport_alloc_session_tags(struct se_session *se_sess,
236 unsigned int tag_num, unsigned int tag_size)
237{
238 int rc;
239
240 se_sess->sess_cmd_map = kzalloc(tag_num * tag_size, GFP_KERNEL);
241 if (!se_sess->sess_cmd_map) {
242 pr_err("Unable to allocate se_sess->sess_cmd_map\n");
243 return -ENOMEM;
244 }
245
246 rc = percpu_ida_init(&se_sess->sess_tag_pool, tag_num);
247 if (rc < 0) {
248 pr_err("Unable to init se_sess->sess_tag_pool,"
249 " tag_num: %u\n", tag_num);
250 kfree(se_sess->sess_cmd_map);
251 se_sess->sess_cmd_map = NULL;
252 return -ENOMEM;
253 }
254
255 return 0;
256}
257EXPORT_SYMBOL(transport_alloc_session_tags);
258
259struct se_session *transport_init_session_tags(unsigned int tag_num,
260 unsigned int tag_size)
261{
262 struct se_session *se_sess;
263 int rc;
264
265 se_sess = transport_init_session();
266 if (IS_ERR(se_sess))
267 return se_sess;
268
269 rc = transport_alloc_session_tags(se_sess, tag_num, tag_size);
270 if (rc < 0) {
271 transport_free_session(se_sess);
272 return ERR_PTR(-ENOMEM);
273 }
274
275 return se_sess;
276}
277EXPORT_SYMBOL(transport_init_session_tags);
278
235/* 279/*
236 * Called with spin_lock_irqsave(&struct se_portal_group->session_lock called. 280 * Called with spin_lock_irqsave(&struct se_portal_group->session_lock called.
237 */ 281 */
@@ -367,6 +411,10 @@ EXPORT_SYMBOL(transport_deregister_session_configfs);
367 411
368void transport_free_session(struct se_session *se_sess) 412void transport_free_session(struct se_session *se_sess)
369{ 413{
414 if (se_sess->sess_cmd_map) {
415 percpu_ida_destroy(&se_sess->sess_tag_pool);
416 kfree(se_sess->sess_cmd_map);
417 }
370 kmem_cache_free(se_sess_cache, se_sess); 418 kmem_cache_free(se_sess_cache, se_sess);
371} 419}
372EXPORT_SYMBOL(transport_free_session); 420EXPORT_SYMBOL(transport_free_session);
diff --git a/include/target/target_core_base.h b/include/target/target_core_base.h
index e34fc904f2e1..bd55acd43005 100644
--- a/include/target/target_core_base.h
+++ b/include/target/target_core_base.h
@@ -5,6 +5,7 @@
5#include <linux/configfs.h> 5#include <linux/configfs.h>
6#include <linux/dma-mapping.h> 6#include <linux/dma-mapping.h>
7#include <linux/blkdev.h> 7#include <linux/blkdev.h>
8#include <linux/percpu_ida.h>
8#include <scsi/scsi_cmnd.h> 9#include <scsi/scsi_cmnd.h>
9#include <net/sock.h> 10#include <net/sock.h>
10#include <net/tcp.h> 11#include <net/tcp.h>
@@ -415,6 +416,8 @@ struct se_cmd {
415 enum dma_data_direction data_direction; 416 enum dma_data_direction data_direction;
416 /* For SAM Task Attribute */ 417 /* For SAM Task Attribute */
417 int sam_task_attr; 418 int sam_task_attr;
419 /* Used for se_sess->sess_tag_pool */
420 unsigned int map_tag;
418 /* Transport protocol dependent state, see transport_state_table */ 421 /* Transport protocol dependent state, see transport_state_table */
419 enum transport_state_table t_state; 422 enum transport_state_table t_state;
420 unsigned cmd_wait_set:1; 423 unsigned cmd_wait_set:1;
@@ -536,6 +539,8 @@ struct se_session {
536 struct list_head sess_wait_list; 539 struct list_head sess_wait_list;
537 spinlock_t sess_cmd_lock; 540 spinlock_t sess_cmd_lock;
538 struct kref sess_kref; 541 struct kref sess_kref;
542 void *sess_cmd_map;
543 struct percpu_ida sess_tag_pool;
539}; 544};
540 545
541struct se_device; 546struct se_device;
diff --git a/include/target/target_core_fabric.h b/include/target/target_core_fabric.h
index 7a16178424f9..d559c36692af 100644
--- a/include/target/target_core_fabric.h
+++ b/include/target/target_core_fabric.h
@@ -84,6 +84,9 @@ struct target_core_fabric_ops {
84}; 84};
85 85
86struct se_session *transport_init_session(void); 86struct se_session *transport_init_session(void);
87int transport_alloc_session_tags(struct se_session *, unsigned int,
88 unsigned int);
89struct se_session *transport_init_session_tags(unsigned int, unsigned int);
87void __transport_register_session(struct se_portal_group *, 90void __transport_register_session(struct se_portal_group *,
88 struct se_node_acl *, struct se_session *, void *); 91 struct se_node_acl *, struct se_session *, void *);
89void transport_register_session(struct se_portal_group *, 92void transport_register_session(struct se_portal_group *,