From 64fad2e6d28cf8887503d712c24416296fa43ea6 Mon Sep 17 00:00:00 2001 From: Vladislav Bolkhovitin Date: Mon, 24 Oct 2011 22:16:42 +0000 Subject: [PATCH] Make usage of scst_suspend_activity() more flexible by making its timeout be explicit git-svn-id: http://svn.code.sf.net/p/scst/svn/trunk@3898 d57e44dd-8a1f-0410-8b47-8ef2f437770f --- scst/include/scst.h | 9 ++++- scst/src/dev_handlers/scst_user.c | 6 ++-- scst/src/dev_handlers/scst_vdisk.c | 4 +-- scst/src/scst_main.c | 54 +++++++++++++++++++----------- scst/src/scst_priv.h | 3 -- scst/src/scst_proc.c | 6 ++-- scst/src/scst_sysfs.c | 10 +++--- 7 files changed, 56 insertions(+), 36 deletions(-) diff --git a/scst/include/scst.h b/scst/include/scst.h index 2be9a13fa..e4886e843 100644 --- a/scst/include/scst.h +++ b/scst/include/scst.h @@ -3899,7 +3899,14 @@ extern struct lockdep_map scst_suspend_dep_map; #else #define scst_assert_activity_suspended() do { } while (0) #endif -int scst_suspend_activity(bool interruptible); + +/* Default suspending timeout for user interface actions */ +#define SCST_SUSPEND_TIMEOUT_USER (90 * HZ) + +/* No timeout in scst_suspend_activity() */ +#define SCST_SUSPEND_TIMEOUT_UNLIMITED 0 + +int scst_suspend_activity(unsigned long timeout); void scst_resume_activity(void); void scst_process_active_cmd(struct scst_cmd *cmd, bool atomic); diff --git a/scst/src/dev_handlers/scst_user.c b/scst/src/dev_handlers/scst_user.c index f8299e299..c519526c8 100644 --- a/scst/src/dev_handlers/scst_user.c +++ b/scst/src/dev_handlers/scst_user.c @@ -3050,7 +3050,7 @@ static int dev_user_unregister_dev(struct file *file) down_read(&dev->dev_rwsem); mutex_unlock(&dev_priv_mutex); - res = scst_suspend_activity(true); + res = scst_suspend_activity(SCST_SUSPEND_TIMEOUT_USER); if (res != 0) goto out_up; @@ -3105,7 +3105,7 @@ static int dev_user_flush_cache(struct file *file) down_read(&dev->dev_rwsem); mutex_unlock(&dev_priv_mutex); - res = scst_suspend_activity(true); + res = scst_suspend_activity(SCST_SUSPEND_TIMEOUT_USER); if (res != 0) goto out_up; @@ -3332,7 +3332,7 @@ static int dev_user_set_opt(struct file *file, const struct scst_user_opt *opt) down_read(&dev->dev_rwsem); mutex_unlock(&dev_priv_mutex); - res = scst_suspend_activity(true); + res = scst_suspend_activity(SCST_SUSPEND_TIMEOUT_USER); if (res != 0) goto out_up; diff --git a/scst/src/dev_handlers/scst_vdisk.c b/scst/src/dev_handlers/scst_vdisk.c index eda154eff..bc76e8b26 100644 --- a/scst/src/dev_handlers/scst_vdisk.c +++ b/scst/src/dev_handlers/scst_vdisk.c @@ -3434,7 +3434,7 @@ static int vdisk_resync_size(struct scst_vdisk_dev *virt_dev) goto out; } - res = scst_suspend_activity(true); + res = scst_suspend_activity(SCST_SUSPEND_TIMEOUT_USER); if (res != 0) goto out; @@ -4087,7 +4087,7 @@ static int vcdrom_change(struct scst_vdisk_dev *virt_dev, } *pp = '\0'; - res = scst_suspend_activity(true); + res = scst_suspend_activity(SCST_SUSPEND_TIMEOUT_USER); if (res != 0) goto out; diff --git a/scst/src/scst_main.c b/scst/src/scst_main.c index 48ec6c96c..874b02313 100644 --- a/scst/src/scst_main.c +++ b/scst/src/scst_main.c @@ -636,7 +636,7 @@ again: wait_event(tgt->unreg_waitQ, test_sess_list(tgt)); TRACE_DBG("%s", "wait_event() returned"); - scst_suspend_activity(false); + scst_suspend_activity(SCST_SUSPEND_TIMEOUT_UNLIMITED); mutex_lock(&scst_mutex); mutex_lock(&scst_mutex2); @@ -685,16 +685,15 @@ int scst_get_cmd_counter(void) return res; } -static int scst_susp_wait(bool interruptible) +static int scst_susp_wait(unsigned long timeout) { int res = 0; TRACE_ENTRY(); - if (interruptible) { + if (timeout != SCST_SUSPEND_TIMEOUT_UNLIMITED) { res = wait_event_interruptible_timeout(scst_dev_cmd_waitQ, - (scst_get_cmd_counter() == 0), - SCST_SUSPENDING_TIMEOUT); + (scst_get_cmd_counter() == 0), timeout); if (res <= 0) { __scst_resume_activity(); if (res == 0) @@ -715,18 +714,20 @@ static int scst_susp_wait(bool interruptible) * * Description: * Globally suspends any activity and doesn't return, until there are any - * active commands (state after SCST_CMD_STATE_INIT). If "interruptible" - * is true, it returns after SCST_SUSPENDING_TIMEOUT or if it was interrupted - * by a signal with the corresponding error status < 0. If "interruptible" - * is false, it will wait virtually forever. On success returns 0. + * active commands (state after SCST_CMD_STATE_INIT). Timeout parameter sets + * max time this function will wait for suspending or interrupted by a + * signal with the corresponding error status < 0. If timeout is + * SCST_SUSPEND_TIMEOUT_UNLIMITED, then it will wait virtually forever. + * On success returns 0. * * New arriving commands stay in the suspended state until * scst_resume_activity() is called. */ -int scst_suspend_activity(bool interruptible) +int scst_suspend_activity(unsigned long timeout) { int res = 0; bool rep = false; + unsigned long cur_time = jiffies, wait_time; TRACE_ENTRY(); @@ -734,7 +735,7 @@ int scst_suspend_activity(bool interruptible) rwlock_acquire_read(&scst_suspend_dep_map, 0, 0, _RET_IP_); #endif - if (interruptible) { + if (timeout != SCST_SUSPEND_TIMEOUT_UNLIMITED) { if (mutex_lock_interruptible(&scst_suspend_mutex) != 0) { res = -EINTR; goto out; @@ -782,7 +783,7 @@ int scst_suspend_activity(bool interruptible) #endif } - res = scst_susp_wait(interruptible); + res = scst_susp_wait(timeout); if (res != 0) goto out_clear; @@ -793,7 +794,22 @@ int scst_suspend_activity(bool interruptible) TRACE_MGMT_DBG("Waiting for %d active commands finally to complete", scst_get_cmd_counter()); - res = scst_susp_wait(interruptible); + if (timeout != SCST_SUSPEND_TIMEOUT_UNLIMITED) { + unsigned long cur_time1 = jiffies; + if (cur_time1 >= cur_time) + wait_time = cur_time1 - cur_time; + else + wait_time = cur_time - cur_time1; + /* just in case */ + if (wait_time >= timeout) { + res = -EBUSY; + goto out_clear; + } + wait_time = timeout - wait_time; + } else + wait_time = SCST_SUSPEND_TIMEOUT_UNLIMITED; + + res = scst_susp_wait(wait_time); if (res != 0) goto out_clear; @@ -895,7 +911,7 @@ static int scst_register_device(struct scsi_device *scsidp) TRACE_ENTRY(); #ifdef CONFIG_SCST_PROC - res = scst_suspend_activity(true); + res = scst_suspend_activity(SCST_SUSPEND_TIMEOUT_USER); if (res != 0) goto out; #endif @@ -989,7 +1005,7 @@ static void scst_unregister_device(struct scsi_device *scsidp) TRACE_ENTRY(); - scst_suspend_activity(false); + scst_suspend_activity(SCST_SUSPEND_TIMEOUT_UNLIMITED); mutex_lock(&scst_mutex); list_for_each_entry(d, &scst_dev_list, dev_list_entry) { @@ -1129,7 +1145,7 @@ int scst_register_virtual_device(struct scst_dev_type *dev_handler, if (res != 0) goto out; - res = scst_suspend_activity(true); + res = scst_suspend_activity(SCST_SUSPEND_TIMEOUT_USER); if (res != 0) goto out; @@ -1241,7 +1257,7 @@ void scst_unregister_virtual_device(int id) TRACE_ENTRY(); - scst_suspend_activity(false); + scst_suspend_activity(SCST_SUSPEND_TIMEOUT_UNLIMITED); mutex_lock(&scst_mutex); list_for_each_entry(d, &scst_dev_list, dev_list_entry) { @@ -1347,7 +1363,7 @@ int __scst_register_dev_driver(struct scst_dev_type *dev_type, #endif /* !defined(SCSI_EXEC_REQ_FIFO_DEFINED) */ #ifdef CONFIG_SCST_PROC - res = scst_suspend_activity(true); + res = scst_suspend_activity(SCST_SUSPEND_TIMEOUT_USER); if (res != 0) goto out; #endif @@ -1430,7 +1446,7 @@ void scst_unregister_dev_driver(struct scst_dev_type *dev_type) TRACE_ENTRY(); - scst_suspend_activity(false); + scst_suspend_activity(SCST_SUSPEND_TIMEOUT_UNLIMITED); mutex_lock(&scst_mutex); list_for_each_entry(dt, &scst_dev_type_list, dev_type_list_entry) { diff --git a/scst/src/scst_priv.h b/scst/src/scst_priv.h index b88f264ba..d3d314619 100644 --- a/scst/src/scst_priv.h +++ b/scst/src/scst_priv.h @@ -106,9 +106,6 @@ extern unsigned long scst_trace_flag; #define SCST_TGT_RETRY_TIMEOUT (3/2*HZ) -/* Activities suspending timeout */ -#define SCST_SUSPENDING_TIMEOUT (90 * HZ) - extern struct mutex scst_mutex2; extern int scst_threads; diff --git a/scst/src/scst_proc.c b/scst/src/scst_proc.c index 0e75b6afe..397a5b986 100644 --- a/scst/src/scst_proc.c +++ b/scst/src/scst_proc.c @@ -1648,7 +1648,7 @@ static ssize_t scst_proc_scsi_tgt_gen_write(struct file *file, goto out_free; } - res = scst_suspend_activity(true); + res = scst_suspend_activity(SCST_SUSPEND_TIMEOUT_USER); if (res != 0) goto out_free; @@ -1957,7 +1957,7 @@ static ssize_t scst_proc_groups_devices_write(struct file *file, goto out_free; } - res = scst_suspend_activity(true); + res = scst_suspend_activity(SCST_SUSPEND_TIMEOUT_USER); if (res != 0) goto out_free; @@ -2216,7 +2216,7 @@ static ssize_t scst_proc_groups_names_write(struct file *file, break; } - rc = scst_suspend_activity(true); + rc = scst_suspend_activity(SCST_SUSPEND_TIMEOUT_USER); if (rc != 0) goto out_free; diff --git a/scst/src/scst_sysfs.c b/scst/src/scst_sysfs.c index 56d029170..4ae31ea92 100644 --- a/scst/src/scst_sysfs.c +++ b/scst/src/scst_sysfs.c @@ -1131,7 +1131,7 @@ static int __scst_process_luns_mgmt_store(char *buffer, goto out; } - res = scst_suspend_activity(true); + res = scst_suspend_activity(SCST_SUSPEND_TIMEOUT_USER); if (res != 0) goto out; @@ -1531,7 +1531,7 @@ static int __scst_acg_process_io_grouping_type_store(struct scst_tgt *tgt, TRACE_DBG("tgt %p, acg %p, io_grouping_type %d", tgt, acg, io_grouping_type); - res = scst_suspend_activity(true); + res = scst_suspend_activity(SCST_SUSPEND_TIMEOUT_USER); if (res != 0) goto out; @@ -1865,7 +1865,7 @@ static int scst_process_ini_group_mgmt_store(char *buffer, goto out; } - res = scst_suspend_activity(true); + res = scst_suspend_activity(SCST_SUSPEND_TIMEOUT_USER); if (res != 0) goto out; @@ -2510,7 +2510,7 @@ static int scst_process_dev_sysfs_threads_data_store( TRACE_DBG("dev %p, threads_num %d, threads_pool_type %d", dev, threads_num, threads_pool_type); - res = scst_suspend_activity(true); + res = scst_suspend_activity(SCST_SUSPEND_TIMEOUT_USER); if (res != 0) goto out; @@ -3929,7 +3929,7 @@ static int scst_process_acg_ini_mgmt_store(char *buffer, goto out; } - res = scst_suspend_activity(true); + res = scst_suspend_activity(SCST_SUSPEND_TIMEOUT_USER); if (res != 0) goto out;