aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/target
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 /drivers/target
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>
Diffstat (limited to 'drivers/target')
-rw-r--r--drivers/target/target_core_transport.c48
1 files changed, 48 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);