Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]
Groups > linux.kernel > #1490866
| Path | csiph.com!eternal-september.org!feeder.eternal-september.org!aioe.org!bofh.it!news.nic.it!robomod |
|---|---|
| From | Tomas Winkler <tomas.winkler@intel.com> |
| Newsgroups | linux.kernel |
| Subject | [char-misc-next] mei: stop the stall timer worker if not needed |
| Date | Sun, 25 Sep 2016 12:30:01 +0200 |
| Message-ID | <sleR3-5oz-9@gated-at.bofh.it> (permalink) |
| X-Original-To | Greg Kroah-Hartman <gregkh@linuxfoundation.org> |
| X-Extloop1 | 1 |
| X-Ironport-Av | E=Sophos;i="5.30,392,1470726000"; d="scan'208";a="13090388" |
| X-Mailer | git-send-email 2.7.4 |
| Sender | robomod@news.nic.it |
| List-ID | <linux-kernel.vger.kernel.org> |
| X-Mailing-List | linux-kernel@vger.kernel.org |
| Approved | robomod@news.nic.it |
| Lines | 190 |
| Organization | linux.* mail to news gateway |
| X-Original-Cc | Alexander Usyskin <alexander.usyskin@intel.com>, linux-kernel@vger.kernel.org, Andy Lutomirski <luto@kernel.org>, Tomas Winkler <tomas.winkler@intel.com> |
| X-Original-Date | Sun, 25 Sep 2016 13:25:31 +0300 |
| X-Original-Message-ID | <1474799131-19837-1-git-send-email-tomas.winkler@intel.com> |
| X-Original-Sender | linux-kernel-owner@vger.kernel.org |
| Xref | csiph.com linux.kernel:1490866 |
Show key headers only | View raw
From: Alexander Usyskin <alexander.usyskin@intel.com>
The stall timer worker checks periodically if there is a stalled i/o
transaction. The issue with the current implementation is that the timer
is ticking also when there is no pending i/o transaction.
This patch provides a simple change that prevents rescheduling
of the delayed work when there is no pending i/o.
Cc: Andy Lutomirski <luto@kernel.org>
Signed-off-by: Alexander Usyskin <alexander.usyskin@intel.com>
Signed-off-by: Tomas Winkler <tomas.winkler@intel.com>
---
drivers/misc/mei/amthif.c | 1 +
drivers/misc/mei/client.c | 2 ++
drivers/misc/mei/hbm.c | 3 +++
drivers/misc/mei/init.c | 2 +-
drivers/misc/mei/interrupt.c | 25 +++++++++++++++++++++----
drivers/misc/mei/mei_dev.h | 1 +
drivers/misc/mei/pci-me.c | 2 --
7 files changed, 29 insertions(+), 7 deletions(-)
diff --git a/drivers/misc/mei/amthif.c b/drivers/misc/mei/amthif.c
index 082462ea90c9..7ae89b4a21d5 100644
--- a/drivers/misc/mei/amthif.c
+++ b/drivers/misc/mei/amthif.c
@@ -277,6 +277,7 @@ void mei_amthif_complete(struct mei_cl *cl, struct mei_cl_cb *cb)
case MEI_FOP_WRITE:
if (!cb->status) {
dev->iamthif_stall_timer = MEI_IAMTHIF_STALL_TIMER;
+ mei_schedule_stall_timer(dev);
mei_io_cb_free(cb);
return;
}
diff --git a/drivers/misc/mei/client.c b/drivers/misc/mei/client.c
index 45a7652820cf..6fe02350578d 100644
--- a/drivers/misc/mei/client.c
+++ b/drivers/misc/mei/client.c
@@ -826,6 +826,7 @@ static int mei_cl_send_disconnect(struct mei_cl *cl, struct mei_cl_cb *cb)
list_move_tail(&cb->list, &dev->ctrl_rd_list.list);
cl->timer_count = MEI_CONNECT_TIMEOUT;
+ mei_schedule_stall_timer(dev);
return 0;
}
@@ -1011,6 +1012,7 @@ static int mei_cl_send_connect(struct mei_cl *cl, struct mei_cl_cb *cb)
list_move_tail(&cb->list, &dev->ctrl_rd_list.list);
cl->timer_count = MEI_CONNECT_TIMEOUT;
+ mei_schedule_stall_timer(dev);
return 0;
}
diff --git a/drivers/misc/mei/hbm.c b/drivers/misc/mei/hbm.c
index 4b9495f0394c..dd7f15a65eed 100644
--- a/drivers/misc/mei/hbm.c
+++ b/drivers/misc/mei/hbm.c
@@ -277,6 +277,7 @@ int mei_hbm_start_req(struct mei_device *dev)
dev->hbm_state = MEI_HBM_STARTING;
dev->init_clients_timer = MEI_CLIENTS_INIT_TIMEOUT;
+ mei_schedule_stall_timer(dev);
return 0;
}
@@ -312,6 +313,7 @@ static int mei_hbm_enum_clients_req(struct mei_device *dev)
}
dev->hbm_state = MEI_HBM_ENUM_CLIENTS;
dev->init_clients_timer = MEI_CLIENTS_INIT_TIMEOUT;
+ mei_schedule_stall_timer(dev);
return 0;
}
@@ -562,6 +564,7 @@ static int mei_hbm_prop_req(struct mei_device *dev, unsigned long start_idx)
}
dev->init_clients_timer = MEI_CLIENTS_INIT_TIMEOUT;
+ mei_schedule_stall_timer(dev);
return 0;
}
diff --git a/drivers/misc/mei/init.c b/drivers/misc/mei/init.c
index f7c8dfdb6a12..9a9c2484d107 100644
--- a/drivers/misc/mei/init.c
+++ b/drivers/misc/mei/init.c
@@ -94,7 +94,7 @@ void mei_cancel_work(struct mei_device *dev)
cancel_work_sync(&dev->reset_work);
cancel_work_sync(&dev->bus_rescan_work);
- cancel_delayed_work(&dev->timer_work);
+ cancel_delayed_work_sync(&dev->timer_work);
}
EXPORT_SYMBOL_GPL(mei_cancel_work);
diff --git a/drivers/misc/mei/interrupt.c b/drivers/misc/mei/interrupt.c
index bf745e03f21e..5a4893ce9c24 100644
--- a/drivers/misc/mei/interrupt.c
+++ b/drivers/misc/mei/interrupt.c
@@ -459,6 +459,19 @@ static void mei_connect_timeout(struct mei_cl *cl)
mei_reset(dev);
}
+#define MEI_STALL_TIMER_FREQ (2 * HZ)
+/**
+ * mei_schedule_stall_timer - re-arm stall_timer work
+ *
+ * Schedule stall timer
+ *
+ * @dev: the device structure
+ */
+void mei_schedule_stall_timer(struct mei_device *dev)
+{
+ schedule_delayed_work(&dev->timer_work, MEI_STALL_TIMER_FREQ);
+}
+
/**
* mei_timer - timer function.
*
@@ -468,10 +481,9 @@ static void mei_connect_timeout(struct mei_cl *cl)
void mei_timer(struct work_struct *work)
{
struct mei_cl *cl;
-
struct mei_device *dev = container_of(work,
struct mei_device, timer_work.work);
-
+ bool reschedule_timer = false;
mutex_lock(&dev->device_lock);
@@ -486,6 +498,7 @@ void mei_timer(struct work_struct *work)
mei_reset(dev);
goto out;
}
+ reschedule_timer = true;
}
}
@@ -500,6 +513,7 @@ void mei_timer(struct work_struct *work)
mei_connect_timeout(cl);
goto out;
}
+ reschedule_timer = true;
}
}
@@ -512,11 +526,14 @@ void mei_timer(struct work_struct *work)
mei_reset(dev);
mei_amthif_run_next_cmd(dev);
+ goto out;
}
+ reschedule_timer = true;
}
out:
- if (dev->dev_state != MEI_DEV_DISABLED)
- schedule_delayed_work(&dev->timer_work, 2 * HZ);
+ if (dev->dev_state != MEI_DEV_DISABLED && reschedule_timer)
+ mei_schedule_stall_timer(dev);
+
mutex_unlock(&dev->device_lock);
}
diff --git a/drivers/misc/mei/mei_dev.h b/drivers/misc/mei/mei_dev.h
index 397ae2b45c9e..1169fd9e7d02 100644
--- a/drivers/misc/mei/mei_dev.h
+++ b/drivers/misc/mei/mei_dev.h
@@ -548,6 +548,7 @@ void mei_cancel_work(struct mei_device *dev);
*/
void mei_timer(struct work_struct *work);
+void mei_schedule_stall_timer(struct mei_device *dev);
int mei_irq_read_handler(struct mei_device *dev,
struct mei_cl_cb *cmpl_list, s32 *slots);
diff --git a/drivers/misc/mei/pci-me.c b/drivers/misc/mei/pci-me.c
index e85bb371c87d..f3ffd883b232 100644
--- a/drivers/misc/mei/pci-me.c
+++ b/drivers/misc/mei/pci-me.c
@@ -220,8 +220,6 @@ static int mei_me_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
pci_set_drvdata(pdev, dev);
- schedule_delayed_work(&dev->timer_work, HZ);
-
/*
* For not wake-able HW runtime pm framework
* can't be used on pci device level.
--
2.7.4
Back to linux.kernel | Previous | Next | Find similar | Unroll thread
[char-misc-next] mei: stop the stall timer worker if not needed Tomas Winkler <tomas.winkler@intel.com> - 2016-09-25 12:30 +0200
csiph-web