qcacld-3.0: Use delayed work instead of qdf_mc_timer for iface change

Currently, the interface idle (aka interface change) timeout uses a
qdf_mc_timer. This dependency on the MC thread means the MC thread
cannot be shutdown as part of the interface idle timeout work. This
wastes resources, and leads to the init/deinit paths to be out of sync
with respect to starting and stopping the MC thread. To address these
issues, use a delayed work to schedule the interface idle work instead
of a qdf_mc_timer.

Change-Id: I7570081112fa236a15d823e2a3857d252567f041
CRs-Fixed: 2112696
This commit is contained in:
Dustin Brown 2017-09-19 12:19:00 -07:00 • committed by snandini
commit 6f42792885
4 changed files with 17 additions and 35 deletions

View file

@ -1653,8 +1653,8 @@ struct hdd_context {
#endif
/* Present state of driver cds modules */
enum driver_modules_status driver_status;
/* MC timer interface change */
qdf_mc_timer_t iface_change_timer;
/* interface idle work */
qdf_delayed_work_t iface_idle_work;
/* Interface change lock */
struct mutex iface_change_lock;
bool rps;

View file

@ -1428,10 +1428,7 @@ static void wlan_hdd_purge_notifier(void)
}
mutex_lock(&hdd_ctx->iface_change_lock);
if (QDF_TIMER_STATE_RUNNING ==
qdf_mc_timer_get_current_state(&hdd_ctx->iface_change_timer))
qdf_mc_timer_stop(&hdd_ctx->iface_change_timer);
qdf_cancel_delayed_work(&hdd_ctx->iface_idle_work);
cds_shutdown_notifier_call();
cds_shutdown_notifier_purge();
mutex_unlock(&hdd_ctx->iface_change_lock);

View file

@ -2319,13 +2319,8 @@ int hdd_wlan_start_modules(struct hdd_context *hdd_ctx,
mutex_lock(&hdd_ctx->iface_change_lock);
hdd_ctx->start_modules_in_progress = true;
if (QDF_TIMER_STATE_RUNNING ==
qdf_mc_timer_get_current_state(&hdd_ctx->iface_change_timer)) {
hdd_set_idle_ps_config(hdd_ctx, false);
hdd_debug("Interface change Timer running Stop timer");
qdf_mc_timer_stop(&hdd_ctx->iface_change_timer);
}
hdd_set_idle_ps_config(hdd_ctx, false);
qdf_cancel_delayed_work(&hdd_ctx->iface_idle_work);
switch (hdd_ctx->driver_status) {
case DRIVER_MODULES_UNINITIALIZED:
@ -2756,8 +2751,8 @@ static int __hdd_stop(struct net_device *dev)
*/
if (hdd_check_for_opened_interfaces(hdd_ctx)) {
hdd_debug("Closing all modules from the hdd_stop");
qdf_mc_timer_start(&hdd_ctx->iface_change_timer,
hdd_ctx->config->iface_change_wait_time);
qdf_sched_delayed_work(&hdd_ctx->iface_idle_work,
hdd_ctx->config->iface_change_wait_time);
hdd_prevent_suspend_timeout(
hdd_ctx->config->iface_change_wait_time,
WIFI_POWER_EVENT_WAKELOCK_IFACE_CHANGE_TIMER);
@ -5977,16 +5972,7 @@ static void hdd_wlan_exit(struct hdd_context *hdd_ctx)
ENTER();
if (QDF_TIMER_STATE_RUNNING ==
qdf_mc_timer_get_current_state(&hdd_ctx->iface_change_timer)) {
hdd_debug("Stop interface change timer");
qdf_mc_timer_stop(&hdd_ctx->iface_change_timer);
}
if (!QDF_IS_STATUS_SUCCESS
(qdf_mc_timer_destroy(&hdd_ctx->iface_change_timer)))
hdd_err("Cannot delete interface change timer");
qdf_cancel_delayed_work(&hdd_ctx->iface_idle_work);
hdd_unregister_notifiers(hdd_ctx);
@ -7842,8 +7828,9 @@ static struct hdd_context *hdd_context_create(struct device *dev)
goto err_out;
}
qdf_mc_timer_init(&hdd_ctx->iface_change_timer, QDF_TIMER_TYPE_SW,
hdd_iface_change_callback, (void *)hdd_ctx);
qdf_create_delayed_work(&hdd_ctx->iface_idle_work,
hdd_iface_change_callback,
(void *)hdd_ctx);
mutex_init(&hdd_ctx->iface_change_lock);
@ -7924,7 +7911,6 @@ err_free_config:
err_free_hdd_context:
wiphy_free(hdd_ctx->wiphy);
qdf_mc_timer_destroy(&hdd_ctx->iface_change_timer);
mutex_destroy(&hdd_ctx->iface_change_lock);
err_out:
@ -9579,8 +9565,8 @@ int hdd_wlan_stop_modules(struct hdd_context *hdd_ctx, bool ftm_mode)
if (is_idle_stop && !ftm_mode) {
mutex_unlock(&hdd_ctx->iface_change_lock);
qdf_mc_timer_start(&hdd_ctx->iface_change_timer,
hdd_ctx->config->iface_change_wait_time);
qdf_sched_delayed_work(&hdd_ctx->iface_idle_work,
hdd_ctx->config->iface_change_wait_time);
hdd_prevent_suspend_timeout(
hdd_ctx->config->iface_change_wait_time,
WIFI_POWER_EVENT_WAKELOCK_IFACE_CHANGE_TIMER);
@ -9863,7 +9849,6 @@ int hdd_wlan_startup(struct device *dev)
goto err_hdd_free_context;
}
qdf_nbuf_init_replenish_timer();
#ifdef FEATURE_WLAN_CH_AVOID
mutex_init(&hdd_ctx->avoid_freq_lock);
@ -9950,8 +9935,8 @@ int hdd_wlan_startup(struct device *dev)
hdd_set_idle_ps_config(hdd_ctx, false);
if (QDF_GLOBAL_FTM_MODE != hdd_get_conparam()) {
qdf_mc_timer_start(&hdd_ctx->iface_change_timer,
hdd_ctx->config->iface_change_wait_time);
qdf_sched_delayed_work(&hdd_ctx->iface_idle_work,
hdd_ctx->config->iface_change_wait_time);
hdd_prevent_suspend_timeout(
hdd_ctx->config->iface_change_wait_time,
WIFI_POWER_EVENT_WAKELOCK_IFACE_CHANGE_TIMER);

View file

@ -672,8 +672,8 @@ stop_modules:
*/
if (hdd_check_for_opened_interfaces(hdd_ctx)) {
hdd_debug("Closing all modules from the add_virt_iface");
qdf_mc_timer_start(&hdd_ctx->iface_change_timer,
hdd_ctx->config->iface_change_wait_time);
qdf_sched_delayed_work(&hdd_ctx->iface_idle_work,
hdd_ctx->config->iface_change_wait_time);
hdd_prevent_suspend_timeout(
hdd_ctx->config->iface_change_wait_time,
WIFI_POWER_EVENT_WAKELOCK_IFACE_CHANGE_TIMER);