[PATCH 2/2] workqueue rework Delayed works and normal works have been split to allow smaller memory usage. Use struct delayed_work where necessary. Signed-off-by: Mattia Dongili --- ipw3945.c | 106 +++++++++++++++++++++++++++++++++---------------------------- ipw3945.h | 27 ++++++++------- 2 files changed, 71 insertions(+), 62 deletions(-) diff --git a/ipw3945.c b/ipw3945.c index 1a633e7..6c6ec76 100644 --- a/ipw3945.c +++ b/ipw3945.c @@ -1353,7 +1353,8 @@ static void ipw_setup_activity_timer(struct ipw_priv *priv) static void ipw_bg_activity_timer(struct work_struct *work) { - struct ipw_priv *priv = container_of(work, struct ipw_priv, activity_timer); + struct delayed_work *dwork = container_of(work, struct delayed_work, work); + struct ipw_priv *priv = container_of(dwork, struct ipw_priv, activity_timer); if (priv->status & STATUS_EXIT_PENDING) return; @@ -1724,7 +1725,7 @@ static ssize_t store_cmd(struct device *d, list_add_tail(&daemon_cmd->list, &priv->daemon_in_list); spin_unlock_irqrestore(&priv->daemon_lock, flags); - queue_work(priv->daemonqueue, &priv->daemon_cmd_work); + queue_delayed_work(priv->daemonqueue, &priv->daemon_cmd_work, 0); return sizeof(*in_cmd) + in_cmd->data_len; } @@ -2379,11 +2380,8 @@ static int ipw_scan_schedule(struct ipw_priv *priv, unsigned long ms) return 0; } - if (ms) - queue_delayed_work(priv->workqueue, - &priv->request_scan, msecs_to_jiffies(ms)); - else - queue_work(priv->workqueue, &priv->request_scan); + queue_delayed_work(priv->workqueue, + &priv->request_scan, msecs_to_jiffies(ms)); return 0; } @@ -2587,7 +2585,7 @@ static void ipw_radio_kill_sw(struct ipw_priv *priv, int disable_radio) return; } - queue_work(priv->workqueue, &priv->down); + queue_delayed_work(priv->workqueue, &priv->down, 0); return; } @@ -2666,7 +2664,7 @@ static void ipw_irq_handle_error(struct ipw_priv *priv) if (!(priv->status & STATUS_EXIT_PENDING)) { IPW_DEBUG(IPW_DL_INFO | IPW_DL_FW_ERRORS, "Restarting adapter due to uCode error.\n"); - queue_work(priv->workqueue, &priv->down); + queue_delayed_work(priv->workqueue, &priv->down, 0); } } @@ -3396,7 +3394,8 @@ static void ipw_connection_init_rx_config(struct ipw_priv *priv) static void ipw_bg_scan_check(struct work_struct *work) { - struct ipw_priv *priv = container_of(work, struct ipw_priv, scan_check); + struct delayed_work *dwork = container_of(work, struct delayed_work, work); + struct ipw_priv *priv = container_of(dwork, struct ipw_priv, scan_check); if (priv->status & STATUS_EXIT_PENDING) return; @@ -4612,12 +4611,12 @@ static void ipw_handle_daemon_set_state(struct ipw_priv *priv, switch (set->state) { case DAEMON_DRIVER_STATE_UNINIT: IPW_DEBUG_INFO("UNINIT state requested by daemon.\n"); - queue_work(priv->workqueue, &priv->down); + queue_delayed_work(priv->workqueue, &priv->down, 0); break; case DAEMON_DRIVER_STATE_INIT: IPW_DEBUG_INFO("INIT state requested by daemon.\n"); - queue_work(priv->workqueue, &priv->up); + queue_delayed_work(priv->workqueue, &priv->up, 0); break; case DAEMON_DRIVER_STATE_CALIBRATED: @@ -4724,7 +4723,8 @@ static void ipw_init_geos(struct ipw_priv *priv, static void ipw_bg_daemon_cmd(struct work_struct *work) { - struct ipw_priv *priv = container_of(work, struct ipw_priv, daemon_cmd_work); + struct delayed_work *dwork = container_of(work, struct delayed_work, work); + struct ipw_priv *priv = container_of(dwork, struct ipw_priv, daemon_cmd_work); struct list_head *element; struct ipw_host_cmd cmd = { .id = 0, @@ -7110,7 +7110,8 @@ static void ipw_gather_stats(struct ipw_priv *priv) static void ipw_bg_gather_stats(struct work_struct *work) { - struct ipw_priv *priv = container_of(work, struct ipw_priv, gather_stats); + struct delayed_work *dwork = container_of(work, struct delayed_work, work); + struct ipw_priv *priv = container_of(dwork, struct ipw_priv, gather_stats); if (priv->status & STATUS_EXIT_PENDING) return; @@ -8182,7 +8183,8 @@ static int ipw_get_channels_for_scan(struct ipw_priv *priv, u8 band, static void ipw_bg_request_scan(struct work_struct *work) { struct ipw_daemon_cmd_list *element; - struct ipw_priv *priv = container_of(work, struct ipw_priv, request_scan); + struct delayed_work *dwork = container_of(work, struct delayed_work, work); + struct ipw_priv *priv = container_of(dwork, struct ipw_priv, request_scan); int rc = 0; struct daemon_scan_request *scan; const struct ieee80211_geo *geo = ieee80211_get_geo(priv->ieee); @@ -9463,7 +9465,8 @@ static int ipw_handle_assoc_response(struct net_device *dev, struct ieee80211_as static void ipw_bg_report_work(struct work_struct *work) { - struct ipw_priv *priv = container_of(work, struct ipw_priv, report_work); + struct delayed_work *dwork = container_of(work, struct delayed_work, work); + struct ipw_priv *priv = container_of(dwork, struct ipw_priv, report_work); if (priv->status & STATUS_EXIT_PENDING) return; @@ -10462,7 +10465,7 @@ static int ipw_queue_tx_reclaim(struct ipw_priv *priv, int fifo, int index) q->last_used = ipw_queue_inc_wrap(q->last_used, q->n_bd)) { if (is_next) { IPW_WARNING("XXXL we have skipped command\n"); - queue_work(priv->workqueue, &priv->down); + queue_delayed_work(priv->workqueue, &priv->down, 0); } if (fifo != CMD_QUEUE_NUM) { ipw_queue_tx_free_tfd(priv, txq); @@ -11008,10 +11011,8 @@ static void ipw_rx_handle(struct ipw_priv *priv) /* We delay the ALIVE response by 5ms to * give the HW RF Kill time to activate... */ if (priv->card_alive.is_valid == UCODE_VALID_OK) - queue_delayed_work(priv-> - workqueue, - &priv-> - alive_start, + queue_delayed_work(priv->workqueue, + &priv->alive_start, msecs_to_jiffies(5)); else IPW_WARNING @@ -11072,7 +11073,7 @@ static void ipw_rx_handle(struct ipw_priv *priv) memcpy(&priv->measure_report, report, sizeof(*report)); - queue_work(priv->workqueue, &priv->report_work); + queue_delayed_work(priv->workqueue, &priv->report_work, 0); break; } @@ -11252,8 +11253,8 @@ static void ipw_rx_handle(struct ipw_priv *priv) || ((status & STATUS_RF_KILL_SW) != (priv->status & STATUS_RF_KILL_SW))) { - queue_work(priv->workqueue, - &priv->rf_kill); + queue_delayed_work(priv->workqueue, + &priv->rf_kill, 0); } else wake_up_interruptible(&priv-> wait_command_queue); @@ -13016,7 +13017,7 @@ static int ipw_wx_set_monitor(struct net_device *dev, IPW_DEBUG(IPW_DL_INFO | IPW_DL_WX, "Restarting adapter to MONITOR mode (ch %d).\n", parms[1]); - queue_work(priv->workqueue, &priv->down); + queue_delayed_work(priv->workqueue, &priv->down, 0); } ipw_set_channel(priv, parms[1]); @@ -13028,7 +13029,7 @@ static int ipw_wx_set_monitor(struct net_device *dev, priv->net_dev->type = ARPHRD_ETHER; IPW_DEBUG(IPW_DL_INFO | IPW_DL_WX, "Restarting adapter to NORMAL mode.\n"); - queue_work(priv->workqueue, &priv->down); + queue_delayed_work(priv->workqueue, &priv->down, 0); } mutex_unlock(&priv->mutex); return 0; @@ -13048,7 +13049,7 @@ static int ipw_wx_reset(struct net_device *dev, return 0; IPW_DEBUG(IPW_DL_INFO | IPW_DL_WX, "Restarting adapter.\n"); - queue_work(priv->workqueue, &priv->down); + queue_delayed_work(priv->workqueue, &priv->down, 0); return 0; } @@ -13573,7 +13574,8 @@ static int ipw_rate_scale_flush_old(struct ipw_priv *priv, u32 flush_interval) static void ipw_bg_rate_scale_flush(struct work_struct *work) { - struct ipw_priv *priv = container_of(work, struct ipw_priv, rate_scale_flush); + struct delayed_work *dwork = container_of(work, struct delayed_work, work); + struct ipw_priv *priv = container_of(dwork, struct ipw_priv, rate_scale_flush); int rc = 0; unsigned long flags; u32 tx_ave, duration; @@ -13881,7 +13883,7 @@ static int ipw_rate_scale_tx_resp_handle(struct ipw_priv *priv, if (time_after(jiffies, priv->rate_scale_mgr.stamp + priv->rate_scale_mgr.flush_time)) { cancel_delayed_work(&priv->rate_scale_flush); - queue_work(priv->workqueue, &priv->rate_scale_flush); + queue_delayed_work(priv->workqueue, &priv->rate_scale_flush, 0); priv->rate_scale_mgr.stamp = jiffies; } @@ -14719,7 +14721,7 @@ static int ipw_net_set_mac_address(struct net_device *dev, void *p) printk(KERN_INFO "%s: Setting MAC to " MAC_FMT "\n", priv->net_dev->name, MAC_ARG(priv->mac_addr)); IPW_DEBUG_INFO("Restarting adapter to set new MAC.\n"); - queue_work(priv->workqueue, &priv->down); + queue_delayed_work(priv->workqueue, &priv->down, 0); mutex_unlock(&priv->mutex); return 0; } @@ -14832,7 +14834,8 @@ static irqreturn_t ipw_isr(int irq, void *data) static void ipw_bg_rf_kill(struct work_struct *work) { - struct ipw_priv *priv = container_of(work, struct ipw_priv, rf_kill); + struct delayed_work *dwork = container_of(work, struct delayed_work, work); + struct ipw_priv *priv = container_of(dwork, struct ipw_priv, rf_kill); wake_up_interruptible(&priv->wait_command_queue); @@ -14958,7 +14961,8 @@ static void ipw_bg_link_down(struct work_struct *work) static void ipw_bg_resume_work(struct work_struct *work) { - struct ipw_priv *priv = container_of(work, struct ipw_priv, resume_work); + struct delayed_work *dwork = container_of(work, struct delayed_work, work); + struct ipw_priv *priv = container_of(dwork, struct ipw_priv, resume_work); unsigned long flags; mutex_lock(&priv->mutex); @@ -15019,7 +15023,8 @@ static void ipw_bg_resume_work(struct work_struct *work) static void ipw_bg_assoc_state_retry(struct work_struct *work) { unsigned long flags; - struct ipw_priv *priv = container_of(work, struct ipw_priv, assoc_state_retry); + struct delayed_work *dwork = container_of(work, struct delayed_work, work); + struct ipw_priv *priv = container_of(dwork, struct ipw_priv, assoc_state_retry); mutex_lock(&priv->mutex); @@ -15078,23 +15083,23 @@ static int ipw_setup_deferred_work(struct ipw_priv *priv) INIT_WORK(&priv->calibrated_work, ipw_bg_calibrated_work); INIT_WORK(&priv->disassociate, ipw_bg_disassociate); INIT_WORK(&priv->rx_replenish, ipw_bg_rx_queue_replenish); - INIT_WORK(&priv->rf_kill, ipw_bg_rf_kill); - INIT_WORK(&priv->up, ipw_bg_up); - INIT_WORK(&priv->down, ipw_bg_down); - INIT_WORK(&priv->request_scan, ipw_bg_request_scan); - INIT_WORK(&priv->gather_stats, ipw_bg_gather_stats); + INIT_DELAYED_WORK(&priv->rf_kill, ipw_bg_rf_kill); + INIT_DELAYED_WORK(&priv->up, ipw_bg_up); + INIT_DELAYED_WORK(&priv->down, ipw_bg_down); + INIT_DELAYED_WORK(&priv->request_scan, ipw_bg_request_scan); + INIT_DELAYED_WORK(&priv->gather_stats, ipw_bg_gather_stats); INIT_WORK(&priv->abort_scan, ipw_bg_abort_scan); INIT_WORK(&priv->roam, ipw_bg_roam); - INIT_WORK(&priv->scan_check, ipw_bg_scan_check); + INIT_DELAYED_WORK(&priv->scan_check, ipw_bg_scan_check); INIT_WORK(&priv->link_up, ipw_bg_link_up); INIT_WORK(&priv->update_link_led, ipw_bg_update_link_led); INIT_WORK(&priv->link_down, ipw_bg_link_down); INIT_WORK(&priv->auth_work, ipw_bg_auth_work); INIT_WORK(&priv->merge_networks, ipw_merge_adhoc_network); - INIT_WORK(&priv->assoc_state_retry, ipw_bg_assoc_state_retry); + INIT_DELAYED_WORK(&priv->assoc_state_retry, ipw_bg_assoc_state_retry); - INIT_WORK(&priv->alive_start, ipw_bg_alive_start); - INIT_WORK(&priv->resume_work, ipw_bg_resume_work); + INIT_DELAYED_WORK(&priv->alive_start, ipw_bg_alive_start); + INIT_DELAYED_WORK(&priv->resume_work, ipw_bg_resume_work); #ifdef CONFIG_IPW3945_QOS /* QoS */ @@ -15102,16 +15107,16 @@ static int ipw_setup_deferred_work(struct ipw_priv *priv) #endif /* 802.11h */ - INIT_WORK(&priv->report_work, ipw_bg_report_work); + INIT_DELAYED_WORK(&priv->report_work, ipw_bg_report_work); INIT_WORK(&priv->post_associate, ipw_bg_post_associate); - INIT_WORK(&priv->activity_timer, ipw_bg_activity_timer); + INIT_DELAYED_WORK(&priv->activity_timer, ipw_bg_activity_timer); - INIT_WORK(&priv->daemon_cmd_work, ipw_bg_daemon_cmd); + INIT_DELAYED_WORK(&priv->daemon_cmd_work, ipw_bg_daemon_cmd); INIT_WORK(&priv->daemon_tx_status_sync, ipw_bg_daemon_tx_status_sync); - INIT_WORK(&priv->rate_scale_flush, ipw_bg_rate_scale_flush); + INIT_DELAYED_WORK(&priv->rate_scale_flush, ipw_bg_rate_scale_flush); tasklet_init(&priv->irq_tasklet, (void (*)(unsigned long)) ipw_irq_tasklet, (unsigned long)priv); @@ -15486,7 +15491,8 @@ static void ipw_alive_start(struct ipw_priv *priv) static void ipw_bg_alive_start(struct work_struct *work) { - struct ipw_priv *priv = container_of(work, struct ipw_priv, alive_start); + struct delayed_work *dwork = container_of(work, struct delayed_work, work); + struct ipw_priv *priv = container_of(dwork, struct ipw_priv, alive_start); if (priv->status & STATUS_EXIT_PENDING) return; @@ -15565,7 +15571,8 @@ static int ipw_up(struct ipw_priv *priv) static void ipw_bg_up(struct work_struct *work) { - struct ipw_priv *priv = container_of(work, struct ipw_priv, up); + struct delayed_work *dwork = container_of(work, struct delayed_work, work); + struct ipw_priv *priv = container_of(dwork, struct ipw_priv, up); if (priv->status & STATUS_EXIT_PENDING) return; @@ -15685,7 +15692,8 @@ static void ipw_down(struct ipw_priv *priv) static void ipw_bg_down(struct work_struct *work) { - struct ipw_priv *priv = container_of(work, struct ipw_priv, down); + struct delayed_work *dwork = container_of(work, struct delayed_work, work); + struct ipw_priv *priv = container_of(dwork, struct ipw_priv, down); if (priv->status & STATUS_EXIT_PENDING) return; diff --git a/ipw3945.h b/ipw3945.h index 96ea449..07b327f 100644 --- a/ipw3945.h +++ b/ipw3945.h @@ -2076,7 +2076,7 @@ struct ipw_priv { /* return code for synchronous driver -> daemon commands */ s32 daemon_cmd_rc; /* daemon driven work queue */ - struct work_struct daemon_cmd_work; + struct delayed_work daemon_cmd_work; struct workqueue_struct *daemonqueue; struct work_struct daemon_tx_status_sync; wait_queue_head_t wait_daemon_cmd_done; @@ -2230,33 +2230,34 @@ struct ipw_priv { /* Driver and iwconfig driven work queue */ struct workqueue_struct *workqueue; - struct work_struct up; - struct work_struct down; struct work_struct adhoc_check; struct work_struct calibrated_work; struct work_struct associate; struct work_struct disassociate; struct work_struct rx_replenish; - struct work_struct request_scan; - struct work_struct rf_kill; - struct work_struct gather_stats; struct work_struct abort_scan; struct work_struct roam; - struct work_struct scan_check; struct work_struct link_up; struct work_struct update_link_led; struct work_struct link_down; - struct work_struct assoc_state_retry; - struct work_struct activity_timer; - struct work_struct alive_start; - struct work_struct resume_work; struct work_struct auth_work; struct work_struct merge_networks; struct work_struct post_associate; - struct work_struct rate_scale_flush; + + struct delayed_work up; + struct delayed_work down; + struct delayed_work activity_timer; + struct delayed_work assoc_state_retry; + struct delayed_work request_scan; + struct delayed_work gather_stats; + struct delayed_work scan_check; + struct delayed_work rf_kill; + struct delayed_work rate_scale_flush; + struct delayed_work resume_work; + struct delayed_work alive_start; /* 802.11h */ - struct work_struct report_work; + struct delayed_work report_work; struct tasklet_struct irq_tasklet;