summaryrefslogtreecommitdiff
path: root/drivers/target/target_core_tpg.c
diff options
context:
space:
mode:
authorNicholas Bellinger <nab@linux-iscsi.org>2013-11-06 21:03:43 -0800
committerNicholas Bellinger <nab@linux-iscsi.org>2013-11-07 14:24:52 -0800
commit5277797dc4ed873d067477d84e910b39d113f649 (patch)
tree5e2aa87dec2cbcb5bbdfadd697c92e86b0e5aa11 /drivers/target/target_core_tpg.c
parentc9e8d128fe316751230ee0c53478740c64f58436 (diff)
target: Add percpu refcounting for se_lun access
This patch adds percpu refcounting for se_lun access that allows the association of an se_lun + se_cmd in transport_lookup_cmd_lun() to occur without an extra list_head for tracking outstanding I/O during se_lun shutdown. This effectively changes se_lun shutdown logic to wait for outstanding I/O percpu references to complete in transport_lun_remove_cmd() using se_lun->lun_ref_comp, instead of explicitly draining the per se_lun command list and waiting for individual se_cmd descriptor processing to complete. Cc: Kent Overstreet <kmo@daterainc.com> Signed-off-by: Nicholas Bellinger <nab@linux-iscsi.org>
Diffstat (limited to 'drivers/target/target_core_tpg.c')
-rw-r--r--drivers/target/target_core_tpg.c27
1 files changed, 24 insertions, 3 deletions
diff --git a/drivers/target/target_core_tpg.c b/drivers/target/target_core_tpg.c
index ec992208dc55..f321af04ef03 100644
--- a/drivers/target/target_core_tpg.c
+++ b/drivers/target/target_core_tpg.c
@@ -634,6 +634,13 @@ int core_tpg_set_initiator_node_tag(
}
EXPORT_SYMBOL(core_tpg_set_initiator_node_tag);
+static void core_tpg_lun_ref_release(struct percpu_ref *ref)
+{
+ struct se_lun *lun = container_of(ref, struct se_lun, lun_ref);
+
+ complete(&lun->lun_ref_comp);
+}
+
static int core_tpg_setup_virtual_lun0(struct se_portal_group *se_tpg)
{
/* Set in core_dev_setup_virtual_lun0() */
@@ -651,11 +658,18 @@ static int core_tpg_setup_virtual_lun0(struct se_portal_group *se_tpg)
spin_lock_init(&lun->lun_acl_lock);
spin_lock_init(&lun->lun_cmd_lock);
spin_lock_init(&lun->lun_sep_lock);
+ init_completion(&lun->lun_ref_comp);
- ret = core_tpg_post_addlun(se_tpg, lun, lun_access, dev);
+ ret = percpu_ref_init(&lun->lun_ref, core_tpg_lun_ref_release);
if (ret < 0)
return ret;
+ ret = core_tpg_post_addlun(se_tpg, lun, lun_access, dev);
+ if (ret < 0) {
+ percpu_ref_cancel_init(&lun->lun_ref);
+ return ret;
+ }
+
return 0;
}
@@ -696,6 +710,7 @@ int core_tpg_register(
spin_lock_init(&lun->lun_acl_lock);
spin_lock_init(&lun->lun_cmd_lock);
spin_lock_init(&lun->lun_sep_lock);
+ init_completion(&lun->lun_ref_comp);
}
se_tpg->se_tpg_type = se_tpg_type;
@@ -816,10 +831,16 @@ int core_tpg_post_addlun(
{
int ret;
- ret = core_dev_export(lun_ptr, tpg, lun);
+ ret = percpu_ref_init(&lun->lun_ref, core_tpg_lun_ref_release);
if (ret < 0)
return ret;
+ ret = core_dev_export(lun_ptr, tpg, lun);
+ if (ret < 0) {
+ percpu_ref_cancel_init(&lun->lun_ref);
+ return ret;
+ }
+
spin_lock(&tpg->tpg_lun_lock);
lun->lun_access = lun_access;
lun->lun_status = TRANSPORT_LUN_STATUS_ACTIVE;
@@ -833,7 +854,7 @@ static void core_tpg_shutdown_lun(
struct se_lun *lun)
{
core_clear_lun_from_tpg(lun, tpg);
- transport_clear_lun_from_sessions(lun);
+ transport_clear_lun_ref(lun);
}
struct se_lun *core_tpg_pre_dellun(