Merge branch 'for-2.6.39' of git://git.kernel.org/pub/scm/linux/kernel/git/tj/wq

* 'for-2.6.39' of git://git.kernel.org/pub/scm/linux/kernel/git/tj/wq:
  workqueue: fix build failure introduced by s/freezeable/freezable/
  workqueue: add system_freezeable_wq
  rds/ib: use system_wq instead of rds_ib_fmr_wq
  net/9p: replace p9_poll_task with a work
  net/9p: use system_wq instead of p9_mux_wq
  xfs: convert to alloc_workqueue()
  reiserfs: make commit_wq use the default concurrency level
  ocfs2: use system_wq instead of ocfs2_quota_wq
  ext4: convert to alloc_workqueue()
  scsi/scsi_tgt_lib: scsi_tgtd isn't used in memory reclaim path
  scsi/be2iscsi,qla2xxx: convert to alloc_workqueue()
  misc/iwmc3200top: use system_wq instead of dedicated workqueues
  i2o: use alloc_workqueue() instead of create_workqueue()
  acpi: kacpi*_wq don't need WQ_MEM_RECLAIM
  fs/aio: aio_wq isn't used in memory reclaim path
  input/tps6507x-ts: use system_wq instead of dedicated workqueue
  cpufreq: use system_wq instead of dedicated workqueues
  wireless/ipw2x00: use system_wq instead of dedicated workqueues
  arm/omap: use system_wq in mailbox
  workqueue: use WQ_MEM_RECLAIM instead of WQ_RESCUER
This commit is contained in:
Linus Torvalds 2011-03-16 08:20:19 -07:00
commit bd2895eead
32 changed files with 190 additions and 339 deletions

View File

@ -32,7 +32,6 @@
#include <plat/mailbox.h> #include <plat/mailbox.h>
static struct workqueue_struct *mboxd;
static struct omap_mbox **mboxes; static struct omap_mbox **mboxes;
static int mbox_configured; static int mbox_configured;
@ -197,7 +196,7 @@ static void __mbox_rx_interrupt(struct omap_mbox *mbox)
/* no more messages in the fifo. clear IRQ source. */ /* no more messages in the fifo. clear IRQ source. */
ack_mbox_irq(mbox, IRQ_RX); ack_mbox_irq(mbox, IRQ_RX);
nomem: nomem:
queue_work(mboxd, &mbox->rxq->work); schedule_work(&mbox->rxq->work);
} }
static irqreturn_t mbox_interrupt(int irq, void *p) static irqreturn_t mbox_interrupt(int irq, void *p)
@ -307,7 +306,7 @@ static void omap_mbox_fini(struct omap_mbox *mbox)
if (!--mbox->use_count) { if (!--mbox->use_count) {
free_irq(mbox->irq, mbox); free_irq(mbox->irq, mbox);
tasklet_kill(&mbox->txq->tasklet); tasklet_kill(&mbox->txq->tasklet);
flush_work(&mbox->rxq->work); flush_work_sync(&mbox->rxq->work);
mbox_queue_free(mbox->txq); mbox_queue_free(mbox->txq);
mbox_queue_free(mbox->rxq); mbox_queue_free(mbox->rxq);
} }
@ -409,10 +408,6 @@ static int __init omap_mbox_init(void)
if (err) if (err)
return err; return err;
mboxd = create_workqueue("mboxd");
if (!mboxd)
return -ENOMEM;
/* kfifo size sanity check: alignment and minimal size */ /* kfifo size sanity check: alignment and minimal size */
mbox_kfifo_size = ALIGN(mbox_kfifo_size, sizeof(mbox_msg_t)); mbox_kfifo_size = ALIGN(mbox_kfifo_size, sizeof(mbox_msg_t));
mbox_kfifo_size = max_t(unsigned int, mbox_kfifo_size, mbox_kfifo_size = max_t(unsigned int, mbox_kfifo_size,
@ -424,7 +419,6 @@ subsys_initcall(omap_mbox_init);
static void __exit omap_mbox_exit(void) static void __exit omap_mbox_exit(void)
{ {
destroy_workqueue(mboxd);
class_unregister(&omap_mbox_class); class_unregister(&omap_mbox_class);
} }
module_exit(omap_mbox_exit); module_exit(omap_mbox_exit);

View File

@ -1589,9 +1589,9 @@ acpi_status __init acpi_os_initialize(void)
acpi_status __init acpi_os_initialize1(void) acpi_status __init acpi_os_initialize1(void)
{ {
kacpid_wq = create_workqueue("kacpid"); kacpid_wq = alloc_workqueue("kacpid", 0, 1);
kacpi_notify_wq = create_workqueue("kacpi_notify"); kacpi_notify_wq = alloc_workqueue("kacpi_notify", 0, 1);
kacpi_hotplug_wq = create_workqueue("kacpi_hotplug"); kacpi_hotplug_wq = alloc_workqueue("kacpi_hotplug", 0, 1);
BUG_ON(!kacpid_wq); BUG_ON(!kacpid_wq);
BUG_ON(!kacpi_notify_wq); BUG_ON(!kacpi_notify_wq);
BUG_ON(!kacpi_hotplug_wq); BUG_ON(!kacpi_hotplug_wq);

View File

@ -81,8 +81,6 @@ static unsigned int dbs_enable; /* number of CPUs using this policy */
*/ */
static DEFINE_MUTEX(dbs_mutex); static DEFINE_MUTEX(dbs_mutex);
static struct workqueue_struct *kconservative_wq;
static struct dbs_tuners { static struct dbs_tuners {
unsigned int sampling_rate; unsigned int sampling_rate;
unsigned int sampling_down_factor; unsigned int sampling_down_factor;
@ -560,7 +558,7 @@ static void do_dbs_timer(struct work_struct *work)
dbs_check_cpu(dbs_info); dbs_check_cpu(dbs_info);
queue_delayed_work_on(cpu, kconservative_wq, &dbs_info->work, delay); schedule_delayed_work_on(cpu, &dbs_info->work, delay);
mutex_unlock(&dbs_info->timer_mutex); mutex_unlock(&dbs_info->timer_mutex);
} }
@ -572,8 +570,7 @@ static inline void dbs_timer_init(struct cpu_dbs_info_s *dbs_info)
dbs_info->enable = 1; dbs_info->enable = 1;
INIT_DELAYED_WORK_DEFERRABLE(&dbs_info->work, do_dbs_timer); INIT_DELAYED_WORK_DEFERRABLE(&dbs_info->work, do_dbs_timer);
queue_delayed_work_on(dbs_info->cpu, kconservative_wq, &dbs_info->work, schedule_delayed_work_on(dbs_info->cpu, &dbs_info->work, delay);
delay);
} }
static inline void dbs_timer_exit(struct cpu_dbs_info_s *dbs_info) static inline void dbs_timer_exit(struct cpu_dbs_info_s *dbs_info)
@ -716,25 +713,12 @@ struct cpufreq_governor cpufreq_gov_conservative = {
static int __init cpufreq_gov_dbs_init(void) static int __init cpufreq_gov_dbs_init(void)
{ {
int err; return cpufreq_register_governor(&cpufreq_gov_conservative);
kconservative_wq = create_workqueue("kconservative");
if (!kconservative_wq) {
printk(KERN_ERR "Creation of kconservative failed\n");
return -EFAULT;
}
err = cpufreq_register_governor(&cpufreq_gov_conservative);
if (err)
destroy_workqueue(kconservative_wq);
return err;
} }
static void __exit cpufreq_gov_dbs_exit(void) static void __exit cpufreq_gov_dbs_exit(void)
{ {
cpufreq_unregister_governor(&cpufreq_gov_conservative); cpufreq_unregister_governor(&cpufreq_gov_conservative);
destroy_workqueue(kconservative_wq);
} }

View File

@ -104,8 +104,6 @@ static unsigned int dbs_enable; /* number of CPUs using this policy */
*/ */
static DEFINE_MUTEX(dbs_mutex); static DEFINE_MUTEX(dbs_mutex);
static struct workqueue_struct *kondemand_wq;
static struct dbs_tuners { static struct dbs_tuners {
unsigned int sampling_rate; unsigned int sampling_rate;
unsigned int up_threshold; unsigned int up_threshold;
@ -667,7 +665,7 @@ static void do_dbs_timer(struct work_struct *work)
__cpufreq_driver_target(dbs_info->cur_policy, __cpufreq_driver_target(dbs_info->cur_policy,
dbs_info->freq_lo, CPUFREQ_RELATION_H); dbs_info->freq_lo, CPUFREQ_RELATION_H);
} }
queue_delayed_work_on(cpu, kondemand_wq, &dbs_info->work, delay); schedule_delayed_work_on(cpu, &dbs_info->work, delay);
mutex_unlock(&dbs_info->timer_mutex); mutex_unlock(&dbs_info->timer_mutex);
} }
@ -681,8 +679,7 @@ static inline void dbs_timer_init(struct cpu_dbs_info_s *dbs_info)
dbs_info->sample_type = DBS_NORMAL_SAMPLE; dbs_info->sample_type = DBS_NORMAL_SAMPLE;
INIT_DELAYED_WORK_DEFERRABLE(&dbs_info->work, do_dbs_timer); INIT_DELAYED_WORK_DEFERRABLE(&dbs_info->work, do_dbs_timer);
queue_delayed_work_on(dbs_info->cpu, kondemand_wq, &dbs_info->work, schedule_delayed_work_on(dbs_info->cpu, &dbs_info->work, delay);
delay);
} }
static inline void dbs_timer_exit(struct cpu_dbs_info_s *dbs_info) static inline void dbs_timer_exit(struct cpu_dbs_info_s *dbs_info)
@ -814,7 +811,6 @@ static int cpufreq_governor_dbs(struct cpufreq_policy *policy,
static int __init cpufreq_gov_dbs_init(void) static int __init cpufreq_gov_dbs_init(void)
{ {
int err;
cputime64_t wall; cputime64_t wall;
u64 idle_time; u64 idle_time;
int cpu = get_cpu(); int cpu = get_cpu();
@ -838,22 +834,12 @@ static int __init cpufreq_gov_dbs_init(void)
MIN_SAMPLING_RATE_RATIO * jiffies_to_usecs(10); MIN_SAMPLING_RATE_RATIO * jiffies_to_usecs(10);
} }
kondemand_wq = create_workqueue("kondemand"); return cpufreq_register_governor(&cpufreq_gov_ondemand);
if (!kondemand_wq) {
printk(KERN_ERR "Creation of kondemand failed\n");
return -EFAULT;
}
err = cpufreq_register_governor(&cpufreq_gov_ondemand);
if (err)
destroy_workqueue(kondemand_wq);
return err;
} }
static void __exit cpufreq_gov_dbs_exit(void) static void __exit cpufreq_gov_dbs_exit(void)
{ {
cpufreq_unregister_governor(&cpufreq_gov_ondemand); cpufreq_unregister_governor(&cpufreq_gov_ondemand);
destroy_workqueue(kondemand_wq);
} }

View File

@ -43,7 +43,6 @@ struct tps6507x_ts {
struct input_dev *input_dev; struct input_dev *input_dev;
struct device *dev; struct device *dev;
char phys[32]; char phys[32];
struct workqueue_struct *wq;
struct delayed_work work; struct delayed_work work;
unsigned polling; /* polling is active */ unsigned polling; /* polling is active */
struct ts_event tc; struct ts_event tc;
@ -220,8 +219,8 @@ done:
poll = 1; poll = 1;
if (poll) { if (poll) {
schd = queue_delayed_work(tsc->wq, &tsc->work, schd = schedule_delayed_work(&tsc->work,
msecs_to_jiffies(tsc->poll_period)); msecs_to_jiffies(tsc->poll_period));
if (schd) if (schd)
tsc->polling = 1; tsc->polling = 1;
else { else {
@ -303,7 +302,6 @@ static int tps6507x_ts_probe(struct platform_device *pdev)
tsc->input_dev = input_dev; tsc->input_dev = input_dev;
INIT_DELAYED_WORK(&tsc->work, tps6507x_ts_handler); INIT_DELAYED_WORK(&tsc->work, tps6507x_ts_handler);
tsc->wq = create_workqueue("TPS6507x Touchscreen");
if (init_data) { if (init_data) {
tsc->poll_period = init_data->poll_period; tsc->poll_period = init_data->poll_period;
@ -325,8 +323,8 @@ static int tps6507x_ts_probe(struct platform_device *pdev)
if (error) if (error)
goto err2; goto err2;
schd = queue_delayed_work(tsc->wq, &tsc->work, schd = schedule_delayed_work(&tsc->work,
msecs_to_jiffies(tsc->poll_period)); msecs_to_jiffies(tsc->poll_period));
if (schd) if (schd)
tsc->polling = 1; tsc->polling = 1;
@ -341,7 +339,6 @@ static int tps6507x_ts_probe(struct platform_device *pdev)
err2: err2:
cancel_delayed_work_sync(&tsc->work); cancel_delayed_work_sync(&tsc->work);
destroy_workqueue(tsc->wq);
input_free_device(input_dev); input_free_device(input_dev);
err1: err1:
kfree(tsc); kfree(tsc);
@ -357,7 +354,6 @@ static int __devexit tps6507x_ts_remove(struct platform_device *pdev)
struct input_dev *input_dev = tsc->input_dev; struct input_dev *input_dev = tsc->input_dev;
cancel_delayed_work_sync(&tsc->work); cancel_delayed_work_sync(&tsc->work);
destroy_workqueue(tsc->wq);
input_unregister_device(input_dev); input_unregister_device(input_dev);

View File

@ -7361,7 +7361,7 @@ static int __init md_init(void)
{ {
int ret = -ENOMEM; int ret = -ENOMEM;
md_wq = alloc_workqueue("md", WQ_RESCUER, 0); md_wq = alloc_workqueue("md", WQ_MEM_RECLAIM, 0);
if (!md_wq) if (!md_wq)
goto err_wq; goto err_wq;

View File

@ -84,7 +84,8 @@ int i2o_driver_register(struct i2o_driver *drv)
osm_debug("Register driver %s\n", drv->name); osm_debug("Register driver %s\n", drv->name);
if (drv->event) { if (drv->event) {
drv->event_queue = create_workqueue(drv->name); drv->event_queue = alloc_workqueue(drv->name,
WQ_MEM_RECLAIM, 1);
if (!drv->event_queue) { if (!drv->event_queue) {
osm_err("Could not initialize event queue for driver " osm_err("Could not initialize event queue for driver "
"%s\n", drv->name); "%s\n", drv->name);

View File

@ -183,9 +183,7 @@ struct iwmct_priv {
u32 barker; u32 barker;
struct iwmct_dbg dbg; struct iwmct_dbg dbg;
/* drivers work queue */ /* drivers work items */
struct workqueue_struct *wq;
struct workqueue_struct *bus_rescan_wq;
struct work_struct bus_rescan_worker; struct work_struct bus_rescan_worker;
struct work_struct isr_worker; struct work_struct isr_worker;

View File

@ -89,7 +89,7 @@ static void op_top_message(struct iwmct_priv *priv, struct top_msg *msg)
switch (msg->hdr.opcode) { switch (msg->hdr.opcode) {
case OP_OPR_ALIVE: case OP_OPR_ALIVE:
LOG_INFO(priv, FW_MSG, "Got ALIVE from device, wake rescan\n"); LOG_INFO(priv, FW_MSG, "Got ALIVE from device, wake rescan\n");
queue_work(priv->bus_rescan_wq, &priv->bus_rescan_worker); schedule_work(&priv->bus_rescan_worker);
break; break;
default: default:
LOG_INFO(priv, FW_MSG, "Received msg opcode 0x%X\n", LOG_INFO(priv, FW_MSG, "Received msg opcode 0x%X\n",
@ -360,7 +360,7 @@ static void iwmct_irq(struct sdio_func *func)
/* clear the function's interrupt request bit (write 1 to clear) */ /* clear the function's interrupt request bit (write 1 to clear) */
sdio_writeb(func, 1, IWMC_SDIO_INTR_CLEAR_ADDR, &ret); sdio_writeb(func, 1, IWMC_SDIO_INTR_CLEAR_ADDR, &ret);
queue_work(priv->wq, &priv->isr_worker); schedule_work(&priv->isr_worker);
LOG_TRACE(priv, IRQ, "exit iwmct_irq\n"); LOG_TRACE(priv, IRQ, "exit iwmct_irq\n");
@ -506,10 +506,6 @@ static int iwmct_probe(struct sdio_func *func,
priv->func = func; priv->func = func;
sdio_set_drvdata(func, priv); sdio_set_drvdata(func, priv);
/* create drivers work queue */
priv->wq = create_workqueue(DRV_NAME "_wq");
priv->bus_rescan_wq = create_workqueue(DRV_NAME "_rescan_wq");
INIT_WORK(&priv->bus_rescan_worker, iwmct_rescan_worker); INIT_WORK(&priv->bus_rescan_worker, iwmct_rescan_worker);
INIT_WORK(&priv->isr_worker, iwmct_irq_read_worker); INIT_WORK(&priv->isr_worker, iwmct_irq_read_worker);
@ -604,9 +600,9 @@ static void iwmct_remove(struct sdio_func *func)
sdio_release_irq(func); sdio_release_irq(func);
sdio_release_host(func); sdio_release_host(func);
/* Safely destroy osc workqueue */ /* Make sure works are finished */
destroy_workqueue(priv->bus_rescan_wq); flush_work_sync(&priv->bus_rescan_worker);
destroy_workqueue(priv->wq); flush_work_sync(&priv->isr_worker);
sdio_claim_host(func); sdio_claim_host(func);
sdio_disable_func(func); sdio_disable_func(func);

View File

@ -706,11 +706,10 @@ static void schedule_reset(struct ipw2100_priv *priv)
netif_stop_queue(priv->net_dev); netif_stop_queue(priv->net_dev);
priv->status |= STATUS_RESET_PENDING; priv->status |= STATUS_RESET_PENDING;
if (priv->reset_backoff) if (priv->reset_backoff)
queue_delayed_work(priv->workqueue, &priv->reset_work, schedule_delayed_work(&priv->reset_work,
priv->reset_backoff * HZ); priv->reset_backoff * HZ);
else else
queue_delayed_work(priv->workqueue, &priv->reset_work, schedule_delayed_work(&priv->reset_work, 0);
0);
if (priv->reset_backoff < MAX_RESET_BACKOFF) if (priv->reset_backoff < MAX_RESET_BACKOFF)
priv->reset_backoff++; priv->reset_backoff++;
@ -1474,7 +1473,7 @@ static int ipw2100_enable_adapter(struct ipw2100_priv *priv)
if (priv->stop_hang_check) { if (priv->stop_hang_check) {
priv->stop_hang_check = 0; priv->stop_hang_check = 0;
queue_delayed_work(priv->workqueue, &priv->hang_check, HZ / 2); schedule_delayed_work(&priv->hang_check, HZ / 2);
} }
fail_up: fail_up:
@ -1808,8 +1807,8 @@ static int ipw2100_up(struct ipw2100_priv *priv, int deferred)
if (priv->stop_rf_kill) { if (priv->stop_rf_kill) {
priv->stop_rf_kill = 0; priv->stop_rf_kill = 0;
queue_delayed_work(priv->workqueue, &priv->rf_kill, schedule_delayed_work(&priv->rf_kill,
round_jiffies_relative(HZ)); round_jiffies_relative(HZ));
} }
deferred = 1; deferred = 1;
@ -2086,7 +2085,7 @@ static void isr_indicate_associated(struct ipw2100_priv *priv, u32 status)
priv->status |= STATUS_ASSOCIATING; priv->status |= STATUS_ASSOCIATING;
priv->connect_start = get_seconds(); priv->connect_start = get_seconds();
queue_delayed_work(priv->workqueue, &priv->wx_event_work, HZ / 10); schedule_delayed_work(&priv->wx_event_work, HZ / 10);
} }
static int ipw2100_set_essid(struct ipw2100_priv *priv, char *essid, static int ipw2100_set_essid(struct ipw2100_priv *priv, char *essid,
@ -2166,9 +2165,9 @@ static void isr_indicate_association_lost(struct ipw2100_priv *priv, u32 status)
return; return;
if (priv->status & STATUS_SECURITY_UPDATED) if (priv->status & STATUS_SECURITY_UPDATED)
queue_delayed_work(priv->workqueue, &priv->security_work, 0); schedule_delayed_work(&priv->security_work, 0);
queue_delayed_work(priv->workqueue, &priv->wx_event_work, 0); schedule_delayed_work(&priv->wx_event_work, 0);
} }
static void isr_indicate_rf_kill(struct ipw2100_priv *priv, u32 status) static void isr_indicate_rf_kill(struct ipw2100_priv *priv, u32 status)
@ -2183,8 +2182,7 @@ static void isr_indicate_rf_kill(struct ipw2100_priv *priv, u32 status)
/* Make sure the RF Kill check timer is running */ /* Make sure the RF Kill check timer is running */
priv->stop_rf_kill = 0; priv->stop_rf_kill = 0;
cancel_delayed_work(&priv->rf_kill); cancel_delayed_work(&priv->rf_kill);
queue_delayed_work(priv->workqueue, &priv->rf_kill, schedule_delayed_work(&priv->rf_kill, round_jiffies_relative(HZ));
round_jiffies_relative(HZ));
} }
static void send_scan_event(void *data) static void send_scan_event(void *data)
@ -2219,13 +2217,12 @@ static void isr_scan_complete(struct ipw2100_priv *priv, u32 status)
/* Only userspace-requested scan completion events go out immediately */ /* Only userspace-requested scan completion events go out immediately */
if (!priv->user_requested_scan) { if (!priv->user_requested_scan) {
if (!delayed_work_pending(&priv->scan_event_later)) if (!delayed_work_pending(&priv->scan_event_later))
queue_delayed_work(priv->workqueue, schedule_delayed_work(&priv->scan_event_later,
&priv->scan_event_later, round_jiffies_relative(msecs_to_jiffies(4000)));
round_jiffies_relative(msecs_to_jiffies(4000)));
} else { } else {
priv->user_requested_scan = 0; priv->user_requested_scan = 0;
cancel_delayed_work(&priv->scan_event_later); cancel_delayed_work(&priv->scan_event_later);
queue_work(priv->workqueue, &priv->scan_event_now); schedule_work(&priv->scan_event_now);
} }
} }
@ -4329,8 +4326,8 @@ static int ipw_radio_kill_sw(struct ipw2100_priv *priv, int disable_radio)
/* Make sure the RF_KILL check timer is running */ /* Make sure the RF_KILL check timer is running */
priv->stop_rf_kill = 0; priv->stop_rf_kill = 0;
cancel_delayed_work(&priv->rf_kill); cancel_delayed_work(&priv->rf_kill);
queue_delayed_work(priv->workqueue, &priv->rf_kill, schedule_delayed_work(&priv->rf_kill,
round_jiffies_relative(HZ)); round_jiffies_relative(HZ));
} else } else
schedule_reset(priv); schedule_reset(priv);
} }
@ -4461,20 +4458,17 @@ static void bd_queue_initialize(struct ipw2100_priv *priv,
IPW_DEBUG_INFO("exit\n"); IPW_DEBUG_INFO("exit\n");
} }
static void ipw2100_kill_workqueue(struct ipw2100_priv *priv) static void ipw2100_kill_works(struct ipw2100_priv *priv)
{ {
if (priv->workqueue) { priv->stop_rf_kill = 1;
priv->stop_rf_kill = 1; priv->stop_hang_check = 1;
priv->stop_hang_check = 1; cancel_delayed_work_sync(&priv->reset_work);
cancel_delayed_work(&priv->reset_work); cancel_delayed_work_sync(&priv->security_work);
cancel_delayed_work(&priv->security_work); cancel_delayed_work_sync(&priv->wx_event_work);
cancel_delayed_work(&priv->wx_event_work); cancel_delayed_work_sync(&priv->hang_check);
cancel_delayed_work(&priv->hang_check); cancel_delayed_work_sync(&priv->rf_kill);
cancel_delayed_work(&priv->rf_kill); cancel_work_sync(&priv->scan_event_now);
cancel_delayed_work(&priv->scan_event_later); cancel_delayed_work_sync(&priv->scan_event_later);
destroy_workqueue(priv->workqueue);
priv->workqueue = NULL;
}
} }
static int ipw2100_tx_allocate(struct ipw2100_priv *priv) static int ipw2100_tx_allocate(struct ipw2100_priv *priv)
@ -6046,7 +6040,7 @@ static void ipw2100_hang_check(struct work_struct *work)
priv->last_rtc = rtc; priv->last_rtc = rtc;
if (!priv->stop_hang_check) if (!priv->stop_hang_check)
queue_delayed_work(priv->workqueue, &priv->hang_check, HZ / 2); schedule_delayed_work(&priv->hang_check, HZ / 2);
spin_unlock_irqrestore(&priv->low_lock, flags); spin_unlock_irqrestore(&priv->low_lock, flags);
} }
@ -6062,8 +6056,8 @@ static void ipw2100_rf_kill(struct work_struct *work)
if (rf_kill_active(priv)) { if (rf_kill_active(priv)) {
IPW_DEBUG_RF_KILL("RF Kill active, rescheduling GPIO check\n"); IPW_DEBUG_RF_KILL("RF Kill active, rescheduling GPIO check\n");
if (!priv->stop_rf_kill) if (!priv->stop_rf_kill)
queue_delayed_work(priv->workqueue, &priv->rf_kill, schedule_delayed_work(&priv->rf_kill,
round_jiffies_relative(HZ)); round_jiffies_relative(HZ));
goto exit_unlock; goto exit_unlock;
} }
@ -6209,8 +6203,6 @@ static struct net_device *ipw2100_alloc_device(struct pci_dev *pci_dev,
INIT_LIST_HEAD(&priv->fw_pend_list); INIT_LIST_HEAD(&priv->fw_pend_list);
INIT_STAT(&priv->fw_pend_stat); INIT_STAT(&priv->fw_pend_stat);
priv->workqueue = create_workqueue(DRV_NAME);
INIT_DELAYED_WORK(&priv->reset_work, ipw2100_reset_adapter); INIT_DELAYED_WORK(&priv->reset_work, ipw2100_reset_adapter);
INIT_DELAYED_WORK(&priv->security_work, ipw2100_security_work); INIT_DELAYED_WORK(&priv->security_work, ipw2100_security_work);
INIT_DELAYED_WORK(&priv->wx_event_work, ipw2100_wx_event_work); INIT_DELAYED_WORK(&priv->wx_event_work, ipw2100_wx_event_work);
@ -6410,7 +6402,7 @@ static int ipw2100_pci_init_one(struct pci_dev *pci_dev,
if (dev->irq) if (dev->irq)
free_irq(dev->irq, priv); free_irq(dev->irq, priv);
ipw2100_kill_workqueue(priv); ipw2100_kill_works(priv);
/* These are safe to call even if they weren't allocated */ /* These are safe to call even if they weren't allocated */
ipw2100_queues_free(priv); ipw2100_queues_free(priv);
@ -6460,9 +6452,7 @@ static void __devexit ipw2100_pci_remove_one(struct pci_dev *pci_dev)
* first, then close() will crash. */ * first, then close() will crash. */
unregister_netdev(dev); unregister_netdev(dev);
/* ipw2100_down will ensure that there is no more pending work ipw2100_kill_works(priv);
* in the workqueue's, so we can safely remove them now. */
ipw2100_kill_workqueue(priv);
ipw2100_queues_free(priv); ipw2100_queues_free(priv);

View File

@ -580,7 +580,6 @@ struct ipw2100_priv {
struct tasklet_struct irq_tasklet; struct tasklet_struct irq_tasklet;
struct workqueue_struct *workqueue;
struct delayed_work reset_work; struct delayed_work reset_work;
struct delayed_work security_work; struct delayed_work security_work;
struct delayed_work wx_event_work; struct delayed_work wx_event_work;

View File

@ -894,9 +894,8 @@ static void ipw_led_link_on(struct ipw_priv *priv)
/* If we aren't associated, schedule turning the LED off */ /* If we aren't associated, schedule turning the LED off */
if (!(priv->status & STATUS_ASSOCIATED)) if (!(priv->status & STATUS_ASSOCIATED))
queue_delayed_work(priv->workqueue, schedule_delayed_work(&priv->led_link_off,
&priv->led_link_off, LD_TIME_LINK_ON);
LD_TIME_LINK_ON);
} }
spin_unlock_irqrestore(&priv->lock, flags); spin_unlock_irqrestore(&priv->lock, flags);
@ -939,8 +938,8 @@ static void ipw_led_link_off(struct ipw_priv *priv)
* turning the LED on (blink while unassociated) */ * turning the LED on (blink while unassociated) */
if (!(priv->status & STATUS_RF_KILL_MASK) && if (!(priv->status & STATUS_RF_KILL_MASK) &&
!(priv->status & STATUS_ASSOCIATED)) !(priv->status & STATUS_ASSOCIATED))
queue_delayed_work(priv->workqueue, &priv->led_link_on, schedule_delayed_work(&priv->led_link_on,
LD_TIME_LINK_OFF); LD_TIME_LINK_OFF);
} }
@ -980,13 +979,11 @@ static void __ipw_led_activity_on(struct ipw_priv *priv)
priv->status |= STATUS_LED_ACT_ON; priv->status |= STATUS_LED_ACT_ON;
cancel_delayed_work(&priv->led_act_off); cancel_delayed_work(&priv->led_act_off);
queue_delayed_work(priv->workqueue, &priv->led_act_off, schedule_delayed_work(&priv->led_act_off, LD_TIME_ACT_ON);
LD_TIME_ACT_ON);
} else { } else {
/* Reschedule LED off for full time period */ /* Reschedule LED off for full time period */
cancel_delayed_work(&priv->led_act_off); cancel_delayed_work(&priv->led_act_off);
queue_delayed_work(priv->workqueue, &priv->led_act_off, schedule_delayed_work(&priv->led_act_off, LD_TIME_ACT_ON);
LD_TIME_ACT_ON);
} }
} }
@ -1795,13 +1792,11 @@ static int ipw_radio_kill_sw(struct ipw_priv *priv, int disable_radio)
if (disable_radio) { if (disable_radio) {
priv->status |= STATUS_RF_KILL_SW; priv->status |= STATUS_RF_KILL_SW;
if (priv->workqueue) { cancel_delayed_work(&priv->request_scan);
cancel_delayed_work(&priv->request_scan); cancel_delayed_work(&priv->request_direct_scan);
cancel_delayed_work(&priv->request_direct_scan); cancel_delayed_work(&priv->request_passive_scan);
cancel_delayed_work(&priv->request_passive_scan); cancel_delayed_work(&priv->scan_event);
cancel_delayed_work(&priv->scan_event); schedule_work(&priv->down);
}
queue_work(priv->workqueue, &priv->down);
} else { } else {
priv->status &= ~STATUS_RF_KILL_SW; priv->status &= ~STATUS_RF_KILL_SW;
if (rf_kill_active(priv)) { if (rf_kill_active(priv)) {
@ -1809,10 +1804,10 @@ static int ipw_radio_kill_sw(struct ipw_priv *priv, int disable_radio)
"disabled by HW switch\n"); "disabled by HW switch\n");
/* Make sure the RF_KILL check timer is running */ /* Make sure the RF_KILL check timer is running */
cancel_delayed_work(&priv->rf_kill); cancel_delayed_work(&priv->rf_kill);
queue_delayed_work(priv->workqueue, &priv->rf_kill, schedule_delayed_work(&priv->rf_kill,
round_jiffies_relative(2 * HZ)); round_jiffies_relative(2 * HZ));
} else } else
queue_work(priv->workqueue, &priv->up); schedule_work(&priv->up);
} }
return 1; return 1;
@ -2063,7 +2058,7 @@ static void ipw_irq_tasklet(struct ipw_priv *priv)
cancel_delayed_work(&priv->request_passive_scan); cancel_delayed_work(&priv->request_passive_scan);
cancel_delayed_work(&priv->scan_event); cancel_delayed_work(&priv->scan_event);
schedule_work(&priv->link_down); schedule_work(&priv->link_down);
queue_delayed_work(priv->workqueue, &priv->rf_kill, 2 * HZ); schedule_delayed_work(&priv->rf_kill, 2 * HZ);
handled |= IPW_INTA_BIT_RF_KILL_DONE; handled |= IPW_INTA_BIT_RF_KILL_DONE;
} }
@ -2103,7 +2098,7 @@ static void ipw_irq_tasklet(struct ipw_priv *priv)
priv->status &= ~STATUS_HCMD_ACTIVE; priv->status &= ~STATUS_HCMD_ACTIVE;
wake_up_interruptible(&priv->wait_command_queue); wake_up_interruptible(&priv->wait_command_queue);
queue_work(priv->workqueue, &priv->adapter_restart); schedule_work(&priv->adapter_restart);
handled |= IPW_INTA_BIT_FATAL_ERROR; handled |= IPW_INTA_BIT_FATAL_ERROR;
} }
@ -2323,11 +2318,6 @@ static int ipw_send_adapter_address(struct ipw_priv *priv, u8 * mac)
return ipw_send_cmd_pdu(priv, IPW_CMD_ADAPTER_ADDRESS, ETH_ALEN, mac); return ipw_send_cmd_pdu(priv, IPW_CMD_ADAPTER_ADDRESS, ETH_ALEN, mac);
} }
/*
* NOTE: This must be executed from our workqueue as it results in udelay
* being called which may corrupt the keyboard if executed on default
* workqueue
*/
static void ipw_adapter_restart(void *adapter) static void ipw_adapter_restart(void *adapter)
{ {
struct ipw_priv *priv = adapter; struct ipw_priv *priv = adapter;
@ -2368,13 +2358,13 @@ static void ipw_scan_check(void *data)
IPW_DEBUG_SCAN("Scan completion watchdog resetting " IPW_DEBUG_SCAN("Scan completion watchdog resetting "
"adapter after (%dms).\n", "adapter after (%dms).\n",
jiffies_to_msecs(IPW_SCAN_CHECK_WATCHDOG)); jiffies_to_msecs(IPW_SCAN_CHECK_WATCHDOG));
queue_work(priv->workqueue, &priv->adapter_restart); schedule_work(&priv->adapter_restart);
} else if (priv->status & STATUS_SCANNING) { } else if (priv->status & STATUS_SCANNING) {
IPW_DEBUG_SCAN("Scan completion watchdog aborting scan " IPW_DEBUG_SCAN("Scan completion watchdog aborting scan "
"after (%dms).\n", "after (%dms).\n",
jiffies_to_msecs(IPW_SCAN_CHECK_WATCHDOG)); jiffies_to_msecs(IPW_SCAN_CHECK_WATCHDOG));
ipw_abort_scan(priv); ipw_abort_scan(priv);
queue_delayed_work(priv->workqueue, &priv->scan_check, HZ); schedule_delayed_work(&priv->scan_check, HZ);
} }
} }
@ -3943,7 +3933,7 @@ static void ipw_send_disassociate(struct ipw_priv *priv, int quiet)
if (priv->status & STATUS_ASSOCIATING) { if (priv->status & STATUS_ASSOCIATING) {
IPW_DEBUG_ASSOC("Disassociating while associating.\n"); IPW_DEBUG_ASSOC("Disassociating while associating.\n");
queue_work(priv->workqueue, &priv->disassociate); schedule_work(&priv->disassociate);
return; return;
} }
@ -4360,8 +4350,7 @@ static void ipw_gather_stats(struct ipw_priv *priv)
priv->quality = quality; priv->quality = quality;
queue_delayed_work(priv->workqueue, &priv->gather_stats, schedule_delayed_work(&priv->gather_stats, IPW_STATS_INTERVAL);
IPW_STATS_INTERVAL);
} }
static void ipw_bg_gather_stats(struct work_struct *work) static void ipw_bg_gather_stats(struct work_struct *work)
@ -4396,10 +4385,10 @@ static void ipw_handle_missed_beacon(struct ipw_priv *priv,
IPW_DEBUG(IPW_DL_INFO | IPW_DL_NOTIF | IPW_DEBUG(IPW_DL_INFO | IPW_DL_NOTIF |
IPW_DL_STATE, IPW_DL_STATE,
"Aborting scan with missed beacon.\n"); "Aborting scan with missed beacon.\n");
queue_work(priv->workqueue, &priv->abort_scan); schedule_work(&priv->abort_scan);
} }
queue_work(priv->workqueue, &priv->disassociate); schedule_work(&priv->disassociate);
return; return;
} }
@ -4425,8 +4414,7 @@ static void ipw_handle_missed_beacon(struct ipw_priv *priv,
if (!(priv->status & STATUS_ROAMING)) { if (!(priv->status & STATUS_ROAMING)) {
priv->status |= STATUS_ROAMING; priv->status |= STATUS_ROAMING;
if (!(priv->status & STATUS_SCANNING)) if (!(priv->status & STATUS_SCANNING))
queue_delayed_work(priv->workqueue, schedule_delayed_work(&priv->request_scan, 0);
&priv->request_scan, 0);
} }
return; return;
} }
@ -4439,7 +4427,7 @@ static void ipw_handle_missed_beacon(struct ipw_priv *priv,
* channels..) */ * channels..) */
IPW_DEBUG(IPW_DL_INFO | IPW_DL_NOTIF | IPW_DL_STATE, IPW_DEBUG(IPW_DL_INFO | IPW_DL_NOTIF | IPW_DL_STATE,
"Aborting scan with missed beacon.\n"); "Aborting scan with missed beacon.\n");
queue_work(priv->workqueue, &priv->abort_scan); schedule_work(&priv->abort_scan);
} }
IPW_DEBUG_NOTIF("Missed beacon: %d\n", missed_count); IPW_DEBUG_NOTIF("Missed beacon: %d\n", missed_count);
@ -4462,8 +4450,8 @@ static void handle_scan_event(struct ipw_priv *priv)
/* Only userspace-requested scan completion events go out immediately */ /* Only userspace-requested scan completion events go out immediately */
if (!priv->user_requested_scan) { if (!priv->user_requested_scan) {
if (!delayed_work_pending(&priv->scan_event)) if (!delayed_work_pending(&priv->scan_event))
queue_delayed_work(priv->workqueue, &priv->scan_event, schedule_delayed_work(&priv->scan_event,
round_jiffies_relative(msecs_to_jiffies(4000))); round_jiffies_relative(msecs_to_jiffies(4000)));
} else { } else {
union iwreq_data wrqu; union iwreq_data wrqu;
@ -4516,20 +4504,17 @@ static void ipw_rx_notification(struct ipw_priv *priv,
IPW_DEBUG_ASSOC IPW_DEBUG_ASSOC
("queueing adhoc check\n"); ("queueing adhoc check\n");
queue_delayed_work(priv-> schedule_delayed_work(
workqueue, &priv->adhoc_check,
&priv-> le16_to_cpu(priv->
adhoc_check, assoc_request.
le16_to_cpu(priv-> beacon_interval));
assoc_request.
beacon_interval));
break; break;
} }
priv->status &= ~STATUS_ASSOCIATING; priv->status &= ~STATUS_ASSOCIATING;
priv->status |= STATUS_ASSOCIATED; priv->status |= STATUS_ASSOCIATED;
queue_work(priv->workqueue, schedule_work(&priv->system_config);
&priv->system_config);
#ifdef CONFIG_IPW2200_QOS #ifdef CONFIG_IPW2200_QOS
#define IPW_GET_PACKET_STYPE(x) WLAN_FC_GET_STYPE( \ #define IPW_GET_PACKET_STYPE(x) WLAN_FC_GET_STYPE( \
@ -4792,43 +4777,37 @@ static void ipw_rx_notification(struct ipw_priv *priv,
#ifdef CONFIG_IPW2200_MONITOR #ifdef CONFIG_IPW2200_MONITOR
if (priv->ieee->iw_mode == IW_MODE_MONITOR) { if (priv->ieee->iw_mode == IW_MODE_MONITOR) {
priv->status |= STATUS_SCAN_FORCED; priv->status |= STATUS_SCAN_FORCED;
queue_delayed_work(priv->workqueue, schedule_delayed_work(&priv->request_scan, 0);
&priv->request_scan, 0);
break; break;
} }
priv->status &= ~STATUS_SCAN_FORCED; priv->status &= ~STATUS_SCAN_FORCED;
#endif /* CONFIG_IPW2200_MONITOR */ #endif /* CONFIG_IPW2200_MONITOR */
/* Do queued direct scans first */ /* Do queued direct scans first */
if (priv->status & STATUS_DIRECT_SCAN_PENDING) { if (priv->status & STATUS_DIRECT_SCAN_PENDING)
queue_delayed_work(priv->workqueue, schedule_delayed_work(&priv->request_direct_scan, 0);
&priv->request_direct_scan, 0);
}
if (!(priv->status & (STATUS_ASSOCIATED | if (!(priv->status & (STATUS_ASSOCIATED |
STATUS_ASSOCIATING | STATUS_ASSOCIATING |
STATUS_ROAMING | STATUS_ROAMING |
STATUS_DISASSOCIATING))) STATUS_DISASSOCIATING)))
queue_work(priv->workqueue, &priv->associate); schedule_work(&priv->associate);
else if (priv->status & STATUS_ROAMING) { else if (priv->status & STATUS_ROAMING) {
if (x->status == SCAN_COMPLETED_STATUS_COMPLETE) if (x->status == SCAN_COMPLETED_STATUS_COMPLETE)
/* If a scan completed and we are in roam mode, then /* If a scan completed and we are in roam mode, then
* the scan that completed was the one requested as a * the scan that completed was the one requested as a
* result of entering roam... so, schedule the * result of entering roam... so, schedule the
* roam work */ * roam work */
queue_work(priv->workqueue, schedule_work(&priv->roam);
&priv->roam);
else else
/* Don't schedule if we aborted the scan */ /* Don't schedule if we aborted the scan */
priv->status &= ~STATUS_ROAMING; priv->status &= ~STATUS_ROAMING;
} else if (priv->status & STATUS_SCAN_PENDING) } else if (priv->status & STATUS_SCAN_PENDING)
queue_delayed_work(priv->workqueue, schedule_delayed_work(&priv->request_scan, 0);
&priv->request_scan, 0);
else if (priv->config & CFG_BACKGROUND_SCAN else if (priv->config & CFG_BACKGROUND_SCAN
&& priv->status & STATUS_ASSOCIATED) && priv->status & STATUS_ASSOCIATED)
queue_delayed_work(priv->workqueue, schedule_delayed_work(&priv->request_scan,
&priv->request_scan, round_jiffies_relative(HZ));
round_jiffies_relative(HZ));
/* Send an empty event to user space. /* Send an empty event to user space.
* We don't send the received data on the event because * We don't send the received data on the event because
@ -5192,7 +5171,7 @@ static void ipw_rx_queue_restock(struct ipw_priv *priv)
/* If the pre-allocated buffer pool is dropping low, schedule to /* If the pre-allocated buffer pool is dropping low, schedule to
* refill it */ * refill it */
if (rxq->free_count <= RX_LOW_WATERMARK) if (rxq->free_count <= RX_LOW_WATERMARK)
queue_work(priv->workqueue, &priv->rx_replenish); schedule_work(&priv->rx_replenish);
/* If we've added more space for the firmware to place data, tell it */ /* If we've added more space for the firmware to place data, tell it */
if (write != rxq->write) if (write != rxq->write)
@ -6133,8 +6112,8 @@ static void ipw_adhoc_check(void *data)
return; return;
} }
queue_delayed_work(priv->workqueue, &priv->adhoc_check, schedule_delayed_work(&priv->adhoc_check,
le16_to_cpu(priv->assoc_request.beacon_interval)); le16_to_cpu(priv->assoc_request.beacon_interval));
} }
static void ipw_bg_adhoc_check(struct work_struct *work) static void ipw_bg_adhoc_check(struct work_struct *work)
@ -6523,8 +6502,7 @@ send_request:
} else } else
priv->status &= ~STATUS_SCAN_PENDING; priv->status &= ~STATUS_SCAN_PENDING;
queue_delayed_work(priv->workqueue, &priv->scan_check, schedule_delayed_work(&priv->scan_check, IPW_SCAN_CHECK_WATCHDOG);
IPW_SCAN_CHECK_WATCHDOG);
done: done:
mutex_unlock(&priv->mutex); mutex_unlock(&priv->mutex);
return err; return err;
@ -6994,8 +6972,7 @@ static int ipw_qos_handle_probe_response(struct ipw_priv *priv,
!memcmp(network->ssid, !memcmp(network->ssid,
priv->assoc_network->ssid, priv->assoc_network->ssid,
network->ssid_len)) { network->ssid_len)) {
queue_work(priv->workqueue, schedule_work(&priv->merge_networks);
&priv->merge_networks);
} }
} }
@ -7663,7 +7640,7 @@ static int ipw_associate(void *data)
if (priv->status & STATUS_DISASSOCIATING) { if (priv->status & STATUS_DISASSOCIATING) {
IPW_DEBUG_ASSOC("Not attempting association (in " IPW_DEBUG_ASSOC("Not attempting association (in "
"disassociating)\n "); "disassociating)\n ");
queue_work(priv->workqueue, &priv->associate); schedule_work(&priv->associate);
return 0; return 0;
} }
@ -7731,12 +7708,10 @@ static int ipw_associate(void *data)
if (!(priv->status & STATUS_SCANNING)) { if (!(priv->status & STATUS_SCANNING)) {
if (!(priv->config & CFG_SPEED_SCAN)) if (!(priv->config & CFG_SPEED_SCAN))
queue_delayed_work(priv->workqueue, schedule_delayed_work(&priv->request_scan,
&priv->request_scan, SCAN_INTERVAL);
SCAN_INTERVAL);
else else
queue_delayed_work(priv->workqueue, schedule_delayed_work(&priv->request_scan, 0);
&priv->request_scan, 0);
} }
return 0; return 0;
@ -8899,7 +8874,7 @@ static int ipw_wx_set_mode(struct net_device *dev,
priv->ieee->iw_mode = wrqu->mode; priv->ieee->iw_mode = wrqu->mode;
queue_work(priv->workqueue, &priv->adapter_restart); schedule_work(&priv->adapter_restart);
mutex_unlock(&priv->mutex); mutex_unlock(&priv->mutex);
return err; return err;
} }
@ -9598,7 +9573,7 @@ static int ipw_wx_set_scan(struct net_device *dev,
IPW_DEBUG_WX("Start scan\n"); IPW_DEBUG_WX("Start scan\n");
queue_delayed_work(priv->workqueue, work, 0); schedule_delayed_work(work, 0);
return 0; return 0;
} }
@ -9937,7 +9912,7 @@ static int ipw_wx_set_monitor(struct net_device *dev,
#else #else
priv->net_dev->type = ARPHRD_IEEE80211; priv->net_dev->type = ARPHRD_IEEE80211;
#endif #endif
queue_work(priv->workqueue, &priv->adapter_restart); schedule_work(&priv->adapter_restart);
} }
ipw_set_channel(priv, parms[1]); ipw_set_channel(priv, parms[1]);
@ -9947,7 +9922,7 @@ static int ipw_wx_set_monitor(struct net_device *dev,
return 0; return 0;
} }
priv->net_dev->type = ARPHRD_ETHER; priv->net_dev->type = ARPHRD_ETHER;
queue_work(priv->workqueue, &priv->adapter_restart); schedule_work(&priv->adapter_restart);
} }
mutex_unlock(&priv->mutex); mutex_unlock(&priv->mutex);
return 0; return 0;
@ -9961,7 +9936,7 @@ static int ipw_wx_reset(struct net_device *dev,
{ {
struct ipw_priv *priv = libipw_priv(dev); struct ipw_priv *priv = libipw_priv(dev);
IPW_DEBUG_WX("RESET\n"); IPW_DEBUG_WX("RESET\n");
queue_work(priv->workqueue, &priv->adapter_restart); schedule_work(&priv->adapter_restart);
return 0; return 0;
} }
@ -10551,7 +10526,7 @@ static int ipw_net_set_mac_address(struct net_device *dev, void *p)
memcpy(priv->mac_addr, addr->sa_data, ETH_ALEN); memcpy(priv->mac_addr, addr->sa_data, ETH_ALEN);
printk(KERN_INFO "%s: Setting MAC to %pM\n", printk(KERN_INFO "%s: Setting MAC to %pM\n",
priv->net_dev->name, priv->mac_addr); priv->net_dev->name, priv->mac_addr);
queue_work(priv->workqueue, &priv->adapter_restart); schedule_work(&priv->adapter_restart);
mutex_unlock(&priv->mutex); mutex_unlock(&priv->mutex);
return 0; return 0;
} }
@ -10684,9 +10659,7 @@ static void ipw_rf_kill(void *adapter)
if (rf_kill_active(priv)) { if (rf_kill_active(priv)) {
IPW_DEBUG_RF_KILL("RF Kill active, rescheduling GPIO check\n"); IPW_DEBUG_RF_KILL("RF Kill active, rescheduling GPIO check\n");
if (priv->workqueue) schedule_delayed_work(&priv->rf_kill, 2 * HZ);
queue_delayed_work(priv->workqueue,
&priv->rf_kill, 2 * HZ);
goto exit_unlock; goto exit_unlock;
} }
@ -10697,7 +10670,7 @@ static void ipw_rf_kill(void *adapter)
"device\n"); "device\n");
/* we can not do an adapter restart while inside an irq lock */ /* we can not do an adapter restart while inside an irq lock */
queue_work(priv->workqueue, &priv->adapter_restart); schedule_work(&priv->adapter_restart);
} else } else
IPW_DEBUG_RF_KILL("HW RF Kill deactivated. SW RF Kill still " IPW_DEBUG_RF_KILL("HW RF Kill deactivated. SW RF Kill still "
"enabled\n"); "enabled\n");
@ -10735,7 +10708,7 @@ static void ipw_link_up(struct ipw_priv *priv)
notify_wx_assoc_event(priv); notify_wx_assoc_event(priv);
if (priv->config & CFG_BACKGROUND_SCAN) if (priv->config & CFG_BACKGROUND_SCAN)
queue_delayed_work(priv->workqueue, &priv->request_scan, HZ); schedule_delayed_work(&priv->request_scan, HZ);
} }
static void ipw_bg_link_up(struct work_struct *work) static void ipw_bg_link_up(struct work_struct *work)
@ -10764,7 +10737,7 @@ static void ipw_link_down(struct ipw_priv *priv)
if (!(priv->status & STATUS_EXIT_PENDING)) { if (!(priv->status & STATUS_EXIT_PENDING)) {
/* Queue up another scan... */ /* Queue up another scan... */
queue_delayed_work(priv->workqueue, &priv->request_scan, 0); schedule_delayed_work(&priv->request_scan, 0);
} else } else
cancel_delayed_work(&priv->scan_event); cancel_delayed_work(&priv->scan_event);
} }
@ -10782,7 +10755,6 @@ static int __devinit ipw_setup_deferred_work(struct ipw_priv *priv)
{ {
int ret = 0; int ret = 0;
priv->workqueue = create_workqueue(DRV_NAME);
init_waitqueue_head(&priv->wait_command_queue); init_waitqueue_head(&priv->wait_command_queue);
init_waitqueue_head(&priv->wait_state); init_waitqueue_head(&priv->wait_state);
@ -11339,8 +11311,7 @@ static int ipw_up(struct ipw_priv *priv)
IPW_WARNING("Radio Frequency Kill Switch is On:\n" IPW_WARNING("Radio Frequency Kill Switch is On:\n"
"Kill switch must be turned off for " "Kill switch must be turned off for "
"wireless networking to work.\n"); "wireless networking to work.\n");
queue_delayed_work(priv->workqueue, &priv->rf_kill, schedule_delayed_work(&priv->rf_kill, 2 * HZ);
2 * HZ);
return 0; return 0;
} }
@ -11350,8 +11321,7 @@ static int ipw_up(struct ipw_priv *priv)
/* If configure to try and auto-associate, kick /* If configure to try and auto-associate, kick
* off a scan. */ * off a scan. */
queue_delayed_work(priv->workqueue, schedule_delayed_work(&priv->request_scan, 0);
&priv->request_scan, 0);
return 0; return 0;
} }
@ -11817,7 +11787,7 @@ static int __devinit ipw_pci_probe(struct pci_dev *pdev,
err = request_irq(pdev->irq, ipw_isr, IRQF_SHARED, DRV_NAME, priv); err = request_irq(pdev->irq, ipw_isr, IRQF_SHARED, DRV_NAME, priv);
if (err) { if (err) {
IPW_ERROR("Error allocating IRQ %d\n", pdev->irq); IPW_ERROR("Error allocating IRQ %d\n", pdev->irq);
goto out_destroy_workqueue; goto out_iounmap;
} }
SET_NETDEV_DEV(net_dev, &pdev->dev); SET_NETDEV_DEV(net_dev, &pdev->dev);
@ -11885,9 +11855,6 @@ static int __devinit ipw_pci_probe(struct pci_dev *pdev,
sysfs_remove_group(&pdev->dev.kobj, &ipw_attribute_group); sysfs_remove_group(&pdev->dev.kobj, &ipw_attribute_group);
out_release_irq: out_release_irq:
free_irq(pdev->irq, priv); free_irq(pdev->irq, priv);
out_destroy_workqueue:
destroy_workqueue(priv->workqueue);
priv->workqueue = NULL;
out_iounmap: out_iounmap:
iounmap(priv->hw_base); iounmap(priv->hw_base);
out_pci_release_regions: out_pci_release_regions:
@ -11930,18 +11897,31 @@ static void __devexit ipw_pci_remove(struct pci_dev *pdev)
kfree(priv->cmdlog); kfree(priv->cmdlog);
priv->cmdlog = NULL; priv->cmdlog = NULL;
} }
/* ipw_down will ensure that there is no more pending work
* in the workqueue's, so we can safely remove them now. */ /* make sure all works are inactive */
cancel_delayed_work(&priv->adhoc_check); cancel_delayed_work_sync(&priv->adhoc_check);
cancel_delayed_work(&priv->gather_stats); cancel_work_sync(&priv->associate);
cancel_delayed_work(&priv->request_scan); cancel_work_sync(&priv->disassociate);
cancel_delayed_work(&priv->request_direct_scan); cancel_work_sync(&priv->system_config);
cancel_delayed_work(&priv->request_passive_scan); cancel_work_sync(&priv->rx_replenish);
cancel_delayed_work(&priv->scan_event); cancel_work_sync(&priv->adapter_restart);
cancel_delayed_work(&priv->rf_kill); cancel_delayed_work_sync(&priv->rf_kill);
cancel_delayed_work(&priv->scan_check); cancel_work_sync(&priv->up);
destroy_workqueue(priv->workqueue); cancel_work_sync(&priv->down);
priv->workqueue = NULL; cancel_delayed_work_sync(&priv->request_scan);
cancel_delayed_work_sync(&priv->request_direct_scan);
cancel_delayed_work_sync(&priv->request_passive_scan);
cancel_delayed_work_sync(&priv->scan_event);
cancel_delayed_work_sync(&priv->gather_stats);
cancel_work_sync(&priv->abort_scan);
cancel_work_sync(&priv->roam);
cancel_delayed_work_sync(&priv->scan_check);
cancel_work_sync(&priv->link_up);
cancel_work_sync(&priv->link_down);
cancel_delayed_work_sync(&priv->led_link_on);
cancel_delayed_work_sync(&priv->led_link_off);
cancel_delayed_work_sync(&priv->led_act_off);
cancel_work_sync(&priv->merge_networks);
/* Free MAC hash list for ADHOC */ /* Free MAC hash list for ADHOC */
for (i = 0; i < IPW_IBSS_MAC_HASH_SIZE; i++) { for (i = 0; i < IPW_IBSS_MAC_HASH_SIZE; i++) {
@ -12029,7 +12009,7 @@ static int ipw_pci_resume(struct pci_dev *pdev)
priv->suspend_time = get_seconds() - priv->suspend_at; priv->suspend_time = get_seconds() - priv->suspend_at;
/* Bring the device back up */ /* Bring the device back up */
queue_work(priv->workqueue, &priv->up); schedule_work(&priv->up);
return 0; return 0;
} }

View File

@ -1299,8 +1299,6 @@ struct ipw_priv {
u8 direct_scan_ssid[IW_ESSID_MAX_SIZE]; u8 direct_scan_ssid[IW_ESSID_MAX_SIZE];
u8 direct_scan_ssid_len; u8 direct_scan_ssid_len;
struct workqueue_struct *workqueue;
struct delayed_work adhoc_check; struct delayed_work adhoc_check;
struct work_struct associate; struct work_struct associate;
struct work_struct disassociate; struct work_struct disassociate;

View File

@ -4277,7 +4277,7 @@ static int __devinit beiscsi_dev_probe(struct pci_dev *pcidev,
snprintf(phba->wq_name, sizeof(phba->wq_name), "beiscsi_q_irq%u", snprintf(phba->wq_name, sizeof(phba->wq_name), "beiscsi_q_irq%u",
phba->shost->host_no); phba->shost->host_no);
phba->wq = create_workqueue(phba->wq_name); phba->wq = alloc_workqueue(phba->wq_name, WQ_MEM_RECLAIM, 1);
if (!phba->wq) { if (!phba->wq) {
shost_printk(KERN_ERR, phba->shost, "beiscsi_dev_probe-" shost_printk(KERN_ERR, phba->shost, "beiscsi_dev_probe-"
"Failed to allocate work queue\n"); "Failed to allocate work queue\n");

View File

@ -349,7 +349,7 @@ static int qla25xx_setup_mode(struct scsi_qla_host *vha)
"Can't create request queue\n"); "Can't create request queue\n");
goto fail; goto fail;
} }
ha->wq = create_workqueue("qla2xxx_wq"); ha->wq = alloc_workqueue("qla2xxx_wq", WQ_MEM_RECLAIM, 1);
vha->req = ha->req_q_map[req]; vha->req = ha->req_q_map[req];
options |= BIT_1; options |= BIT_1;
for (ques = 1; ques < ha->max_rsp_queues; ques++) { for (ques = 1; ques < ha->max_rsp_queues; ques++) {

View File

@ -629,7 +629,7 @@ static int __init scsi_tgt_init(void)
if (!scsi_tgt_cmd_cache) if (!scsi_tgt_cmd_cache)
return -ENOMEM; return -ENOMEM;
scsi_tgtd = create_workqueue("scsi_tgtd"); scsi_tgtd = alloc_workqueue("scsi_tgtd", 0, 1);
if (!scsi_tgtd) { if (!scsi_tgtd) {
err = -ENOMEM; err = -ENOMEM;
goto free_kmemcache; goto free_kmemcache;

View File

@ -85,7 +85,7 @@ static int __init aio_setup(void)
kiocb_cachep = KMEM_CACHE(kiocb, SLAB_HWCACHE_ALIGN|SLAB_PANIC); kiocb_cachep = KMEM_CACHE(kiocb, SLAB_HWCACHE_ALIGN|SLAB_PANIC);
kioctx_cachep = KMEM_CACHE(kioctx,SLAB_HWCACHE_ALIGN|SLAB_PANIC); kioctx_cachep = KMEM_CACHE(kioctx,SLAB_HWCACHE_ALIGN|SLAB_PANIC);
aio_wq = create_workqueue("aio"); aio_wq = alloc_workqueue("aio", 0, 1); /* used to limit concurrency */
abe_pool = mempool_create_kmalloc_pool(1, sizeof(struct aio_batch_entry)); abe_pool = mempool_create_kmalloc_pool(1, sizeof(struct aio_batch_entry));
BUG_ON(!aio_wq || !abe_pool); BUG_ON(!aio_wq || !abe_pool);
@ -577,7 +577,7 @@ static int __aio_put_req(struct kioctx *ctx, struct kiocb *req)
spin_lock(&fput_lock); spin_lock(&fput_lock);
list_add(&req->ki_list, &fput_head); list_add(&req->ki_list, &fput_head);
spin_unlock(&fput_lock); spin_unlock(&fput_lock);
queue_work(aio_wq, &fput_work); schedule_work(&fput_work);
} else { } else {
req->ki_filp = NULL; req->ki_filp = NULL;
really_put_req(ctx, req); really_put_req(ctx, req);

View File

@ -3511,7 +3511,12 @@ static int ext4_fill_super(struct super_block *sb, void *data, int silent)
percpu_counter_set(&sbi->s_dirtyblocks_counter, 0); percpu_counter_set(&sbi->s_dirtyblocks_counter, 0);
no_journal: no_journal:
EXT4_SB(sb)->dio_unwritten_wq = create_workqueue("ext4-dio-unwritten"); /*
* The maximum number of concurrent works can be high and
* concurrency isn't really necessary. Limit it to 1.
*/
EXT4_SB(sb)->dio_unwritten_wq =
alloc_workqueue("ext4-dio-unwritten", WQ_MEM_RECLAIM, 1);
if (!EXT4_SB(sb)->dio_unwritten_wq) { if (!EXT4_SB(sb)->dio_unwritten_wq) {
printk(KERN_ERR "EXT4-fs: failed to create DIO workqueue\n"); printk(KERN_ERR "EXT4-fs: failed to create DIO workqueue\n");
goto failed_mount_wq; goto failed_mount_wq;

View File

@ -1518,7 +1518,7 @@ static int nfsiod_start(void)
{ {
struct workqueue_struct *wq; struct workqueue_struct *wq;
dprintk("RPC: creating workqueue nfsiod\n"); dprintk("RPC: creating workqueue nfsiod\n");
wq = alloc_workqueue("nfsiod", WQ_RESCUER, 0); wq = alloc_workqueue("nfsiod", WQ_MEM_RECLAIM, 0);
if (wq == NULL) if (wq == NULL)
return -ENOMEM; return -ENOMEM;
nfsiod_workqueue = wq; nfsiod_workqueue = wq;

View File

@ -114,7 +114,4 @@ int ocfs2_local_write_dquot(struct dquot *dquot);
extern const struct dquot_operations ocfs2_quota_operations; extern const struct dquot_operations ocfs2_quota_operations;
extern struct quota_format_type ocfs2_quota_format; extern struct quota_format_type ocfs2_quota_format;
int ocfs2_quota_setup(void);
void ocfs2_quota_shutdown(void);
#endif /* _OCFS2_QUOTA_H */ #endif /* _OCFS2_QUOTA_H */

View File

@ -63,8 +63,6 @@
* write to gf * write to gf
*/ */
static struct workqueue_struct *ocfs2_quota_wq = NULL;
static void qsync_work_fn(struct work_struct *work); static void qsync_work_fn(struct work_struct *work);
static void ocfs2_global_disk2memdqb(struct dquot *dquot, void *dp) static void ocfs2_global_disk2memdqb(struct dquot *dquot, void *dp)
@ -400,8 +398,8 @@ int ocfs2_global_read_info(struct super_block *sb, int type)
OCFS2_QBLK_RESERVED_SPACE; OCFS2_QBLK_RESERVED_SPACE;
oinfo->dqi_gi.dqi_qtree_depth = qtree_depth(&oinfo->dqi_gi); oinfo->dqi_gi.dqi_qtree_depth = qtree_depth(&oinfo->dqi_gi);
INIT_DELAYED_WORK(&oinfo->dqi_sync_work, qsync_work_fn); INIT_DELAYED_WORK(&oinfo->dqi_sync_work, qsync_work_fn);
queue_delayed_work(ocfs2_quota_wq, &oinfo->dqi_sync_work, schedule_delayed_work(&oinfo->dqi_sync_work,
msecs_to_jiffies(oinfo->dqi_syncms)); msecs_to_jiffies(oinfo->dqi_syncms));
out_err: out_err:
mlog_exit(status); mlog_exit(status);
@ -635,8 +633,8 @@ static void qsync_work_fn(struct work_struct *work)
struct super_block *sb = oinfo->dqi_gqinode->i_sb; struct super_block *sb = oinfo->dqi_gqinode->i_sb;
dquot_scan_active(sb, ocfs2_sync_dquot_helper, oinfo->dqi_type); dquot_scan_active(sb, ocfs2_sync_dquot_helper, oinfo->dqi_type);
queue_delayed_work(ocfs2_quota_wq, &oinfo->dqi_sync_work, schedule_delayed_work(&oinfo->dqi_sync_work,
msecs_to_jiffies(oinfo->dqi_syncms)); msecs_to_jiffies(oinfo->dqi_syncms));
} }
/* /*
@ -923,20 +921,3 @@ const struct dquot_operations ocfs2_quota_operations = {
.alloc_dquot = ocfs2_alloc_dquot, .alloc_dquot = ocfs2_alloc_dquot,
.destroy_dquot = ocfs2_destroy_dquot, .destroy_dquot = ocfs2_destroy_dquot,
}; };
int ocfs2_quota_setup(void)
{
ocfs2_quota_wq = create_workqueue("o2quot");
if (!ocfs2_quota_wq)
return -ENOMEM;
return 0;
}
void ocfs2_quota_shutdown(void)
{
if (ocfs2_quota_wq) {
flush_workqueue(ocfs2_quota_wq);
destroy_workqueue(ocfs2_quota_wq);
ocfs2_quota_wq = NULL;
}
}

View File

@ -1657,16 +1657,11 @@ static int __init ocfs2_init(void)
mlog(ML_ERROR, "Unable to create ocfs2 debugfs root.\n"); mlog(ML_ERROR, "Unable to create ocfs2 debugfs root.\n");
} }
status = ocfs2_quota_setup();
if (status)
goto leave;
ocfs2_set_locking_protocol(); ocfs2_set_locking_protocol();
status = register_quota_format(&ocfs2_quota_format); status = register_quota_format(&ocfs2_quota_format);
leave: leave:
if (status < 0) { if (status < 0) {
ocfs2_quota_shutdown();
ocfs2_free_mem_caches(); ocfs2_free_mem_caches();
exit_ocfs2_uptodate_cache(); exit_ocfs2_uptodate_cache();
} }
@ -1683,8 +1678,6 @@ static void __exit ocfs2_exit(void)
{ {
mlog_entry_void(); mlog_entry_void();
ocfs2_quota_shutdown();
if (ocfs2_wq) { if (ocfs2_wq) {
flush_workqueue(ocfs2_wq); flush_workqueue(ocfs2_wq);
destroy_workqueue(ocfs2_wq); destroy_workqueue(ocfs2_wq);

View File

@ -2876,7 +2876,7 @@ int journal_init(struct super_block *sb, const char *j_dev_name,
reiserfs_mounted_fs_count++; reiserfs_mounted_fs_count++;
if (reiserfs_mounted_fs_count <= 1) { if (reiserfs_mounted_fs_count <= 1) {
reiserfs_write_unlock(sb); reiserfs_write_unlock(sb);
commit_wq = create_workqueue("reiserfs"); commit_wq = alloc_workqueue("reiserfs", WQ_MEM_RECLAIM, 0);
reiserfs_write_lock(sb); reiserfs_write_lock(sb);
} }

View File

@ -2022,11 +2022,12 @@ xfs_buf_init(void)
if (!xfslogd_workqueue) if (!xfslogd_workqueue)
goto out_free_buf_zone; goto out_free_buf_zone;
xfsdatad_workqueue = create_workqueue("xfsdatad"); xfsdatad_workqueue = alloc_workqueue("xfsdatad", WQ_MEM_RECLAIM, 1);
if (!xfsdatad_workqueue) if (!xfsdatad_workqueue)
goto out_destroy_xfslogd_workqueue; goto out_destroy_xfslogd_workqueue;
xfsconvertd_workqueue = create_workqueue("xfsconvertd"); xfsconvertd_workqueue = alloc_workqueue("xfsconvertd",
WQ_MEM_RECLAIM, 1);
if (!xfsconvertd_workqueue) if (!xfsconvertd_workqueue)
goto out_destroy_xfsdatad_workqueue; goto out_destroy_xfsdatad_workqueue;

View File

@ -309,7 +309,7 @@ xfs_mru_cache_init(void)
if (!xfs_mru_elem_zone) if (!xfs_mru_elem_zone)
goto out; goto out;
xfs_mru_reap_wq = create_singlethread_workqueue("xfs_mru_cache"); xfs_mru_reap_wq = alloc_workqueue("xfs_mru_cache", WQ_MEM_RECLAIM, 1);
if (!xfs_mru_reap_wq) if (!xfs_mru_reap_wq)
goto out_destroy_mru_elem_zone; goto out_destroy_mru_elem_zone;

View File

@ -286,11 +286,15 @@ enum {
* any specific CPU, not concurrency managed, and all queued works are * any specific CPU, not concurrency managed, and all queued works are
* executed immediately as long as max_active limit is not reached and * executed immediately as long as max_active limit is not reached and
* resources are available. * resources are available.
*
* system_freezable_wq is equivalent to system_wq except that it's
* freezable.
*/ */
extern struct workqueue_struct *system_wq; extern struct workqueue_struct *system_wq;
extern struct workqueue_struct *system_long_wq; extern struct workqueue_struct *system_long_wq;
extern struct workqueue_struct *system_nrt_wq; extern struct workqueue_struct *system_nrt_wq;
extern struct workqueue_struct *system_unbound_wq; extern struct workqueue_struct *system_unbound_wq;
extern struct workqueue_struct *system_freezable_wq;
extern struct workqueue_struct * extern struct workqueue_struct *
__alloc_workqueue_key(const char *name, unsigned int flags, int max_active, __alloc_workqueue_key(const char *name, unsigned int flags, int max_active,

View File

@ -251,10 +251,12 @@ struct workqueue_struct *system_wq __read_mostly;
struct workqueue_struct *system_long_wq __read_mostly; struct workqueue_struct *system_long_wq __read_mostly;
struct workqueue_struct *system_nrt_wq __read_mostly; struct workqueue_struct *system_nrt_wq __read_mostly;
struct workqueue_struct *system_unbound_wq __read_mostly; struct workqueue_struct *system_unbound_wq __read_mostly;
struct workqueue_struct *system_freezable_wq __read_mostly;
EXPORT_SYMBOL_GPL(system_wq); EXPORT_SYMBOL_GPL(system_wq);
EXPORT_SYMBOL_GPL(system_long_wq); EXPORT_SYMBOL_GPL(system_long_wq);
EXPORT_SYMBOL_GPL(system_nrt_wq); EXPORT_SYMBOL_GPL(system_nrt_wq);
EXPORT_SYMBOL_GPL(system_unbound_wq); EXPORT_SYMBOL_GPL(system_unbound_wq);
EXPORT_SYMBOL_GPL(system_freezable_wq);
#define CREATE_TRACE_POINTS #define CREATE_TRACE_POINTS
#include <trace/events/workqueue.h> #include <trace/events/workqueue.h>
@ -3781,8 +3783,10 @@ static int __init init_workqueues(void)
system_nrt_wq = alloc_workqueue("events_nrt", WQ_NON_REENTRANT, 0); system_nrt_wq = alloc_workqueue("events_nrt", WQ_NON_REENTRANT, 0);
system_unbound_wq = alloc_workqueue("events_unbound", WQ_UNBOUND, system_unbound_wq = alloc_workqueue("events_unbound", WQ_UNBOUND,
WQ_UNBOUND_MAX_ACTIVE); WQ_UNBOUND_MAX_ACTIVE);
system_freezable_wq = alloc_workqueue("events_freezable",
WQ_FREEZABLE, 0);
BUG_ON(!system_wq || !system_long_wq || !system_nrt_wq || BUG_ON(!system_wq || !system_long_wq || !system_nrt_wq ||
!system_unbound_wq); !system_unbound_wq || !system_freezable_wq);
return 0; return 0;
} }
early_initcall(init_workqueues); early_initcall(init_workqueues);

View File

@ -153,10 +153,11 @@ struct p9_conn {
unsigned long wsched; unsigned long wsched;
}; };
static void p9_poll_workfn(struct work_struct *work);
static DEFINE_SPINLOCK(p9_poll_lock); static DEFINE_SPINLOCK(p9_poll_lock);
static LIST_HEAD(p9_poll_pending_list); static LIST_HEAD(p9_poll_pending_list);
static struct workqueue_struct *p9_mux_wq; static DECLARE_WORK(p9_poll_work, p9_poll_workfn);
static struct task_struct *p9_poll_task;
static void p9_mux_poll_stop(struct p9_conn *m) static void p9_mux_poll_stop(struct p9_conn *m)
{ {
@ -384,7 +385,7 @@ static void p9_read_work(struct work_struct *work)
if (n & POLLIN) { if (n & POLLIN) {
P9_DPRINTK(P9_DEBUG_TRANS, "sched read work %p\n", m); P9_DPRINTK(P9_DEBUG_TRANS, "sched read work %p\n", m);
queue_work(p9_mux_wq, &m->rq); schedule_work(&m->rq);
} else } else
clear_bit(Rworksched, &m->wsched); clear_bit(Rworksched, &m->wsched);
} else } else
@ -497,7 +498,7 @@ static void p9_write_work(struct work_struct *work)
if (n & POLLOUT) { if (n & POLLOUT) {
P9_DPRINTK(P9_DEBUG_TRANS, "sched write work %p\n", m); P9_DPRINTK(P9_DEBUG_TRANS, "sched write work %p\n", m);
queue_work(p9_mux_wq, &m->wq); schedule_work(&m->wq);
} else } else
clear_bit(Wworksched, &m->wsched); clear_bit(Wworksched, &m->wsched);
} else } else
@ -516,15 +517,14 @@ static int p9_pollwake(wait_queue_t *wait, unsigned mode, int sync, void *key)
container_of(wait, struct p9_poll_wait, wait); container_of(wait, struct p9_poll_wait, wait);
struct p9_conn *m = pwait->conn; struct p9_conn *m = pwait->conn;
unsigned long flags; unsigned long flags;
DECLARE_WAITQUEUE(dummy_wait, p9_poll_task);
spin_lock_irqsave(&p9_poll_lock, flags); spin_lock_irqsave(&p9_poll_lock, flags);
if (list_empty(&m->poll_pending_link)) if (list_empty(&m->poll_pending_link))
list_add_tail(&m->poll_pending_link, &p9_poll_pending_list); list_add_tail(&m->poll_pending_link, &p9_poll_pending_list);
spin_unlock_irqrestore(&p9_poll_lock, flags); spin_unlock_irqrestore(&p9_poll_lock, flags);
/* perform the default wake up operation */ schedule_work(&p9_poll_work);
return default_wake_function(&dummy_wait, mode, sync, key); return 1;
} }
/** /**
@ -629,7 +629,7 @@ static void p9_poll_mux(struct p9_conn *m)
P9_DPRINTK(P9_DEBUG_TRANS, "mux %p can read\n", m); P9_DPRINTK(P9_DEBUG_TRANS, "mux %p can read\n", m);
if (!test_and_set_bit(Rworksched, &m->wsched)) { if (!test_and_set_bit(Rworksched, &m->wsched)) {
P9_DPRINTK(P9_DEBUG_TRANS, "sched read work %p\n", m); P9_DPRINTK(P9_DEBUG_TRANS, "sched read work %p\n", m);
queue_work(p9_mux_wq, &m->rq); schedule_work(&m->rq);
} }
} }
@ -639,7 +639,7 @@ static void p9_poll_mux(struct p9_conn *m)
if ((m->wsize || !list_empty(&m->unsent_req_list)) && if ((m->wsize || !list_empty(&m->unsent_req_list)) &&
!test_and_set_bit(Wworksched, &m->wsched)) { !test_and_set_bit(Wworksched, &m->wsched)) {
P9_DPRINTK(P9_DEBUG_TRANS, "sched write work %p\n", m); P9_DPRINTK(P9_DEBUG_TRANS, "sched write work %p\n", m);
queue_work(p9_mux_wq, &m->wq); schedule_work(&m->wq);
} }
} }
} }
@ -677,7 +677,7 @@ static int p9_fd_request(struct p9_client *client, struct p9_req_t *req)
n = p9_fd_poll(m->client, NULL); n = p9_fd_poll(m->client, NULL);
if (n & POLLOUT && !test_and_set_bit(Wworksched, &m->wsched)) if (n & POLLOUT && !test_and_set_bit(Wworksched, &m->wsched))
queue_work(p9_mux_wq, &m->wq); schedule_work(&m->wq);
return 0; return 0;
} }
@ -1047,12 +1047,12 @@ static struct p9_trans_module p9_fd_trans = {
* *
*/ */
static int p9_poll_proc(void *a) static void p9_poll_workfn(struct work_struct *work)
{ {
unsigned long flags; unsigned long flags;
P9_DPRINTK(P9_DEBUG_TRANS, "start %p\n", current); P9_DPRINTK(P9_DEBUG_TRANS, "start %p\n", current);
repeat:
spin_lock_irqsave(&p9_poll_lock, flags); spin_lock_irqsave(&p9_poll_lock, flags);
while (!list_empty(&p9_poll_pending_list)) { while (!list_empty(&p9_poll_pending_list)) {
struct p9_conn *conn = list_first_entry(&p9_poll_pending_list, struct p9_conn *conn = list_first_entry(&p9_poll_pending_list,
@ -1067,35 +1067,11 @@ static int p9_poll_proc(void *a)
} }
spin_unlock_irqrestore(&p9_poll_lock, flags); spin_unlock_irqrestore(&p9_poll_lock, flags);
set_current_state(TASK_INTERRUPTIBLE);
if (list_empty(&p9_poll_pending_list)) {
P9_DPRINTK(P9_DEBUG_TRANS, "sleeping...\n");
schedule();
}
__set_current_state(TASK_RUNNING);
if (!kthread_should_stop())
goto repeat;
P9_DPRINTK(P9_DEBUG_TRANS, "finish\n"); P9_DPRINTK(P9_DEBUG_TRANS, "finish\n");
return 0;
} }
int p9_trans_fd_init(void) int p9_trans_fd_init(void)
{ {
p9_mux_wq = create_workqueue("v9fs");
if (!p9_mux_wq) {
printk(KERN_WARNING "v9fs: mux: creating workqueue failed\n");
return -ENOMEM;
}
p9_poll_task = kthread_run(p9_poll_proc, NULL, "v9fs-poll");
if (IS_ERR(p9_poll_task)) {
destroy_workqueue(p9_mux_wq);
printk(KERN_WARNING "v9fs: mux: creating poll task failed\n");
return PTR_ERR(p9_poll_task);
}
v9fs_register_trans(&p9_tcp_trans); v9fs_register_trans(&p9_tcp_trans);
v9fs_register_trans(&p9_unix_trans); v9fs_register_trans(&p9_unix_trans);
v9fs_register_trans(&p9_fd_trans); v9fs_register_trans(&p9_fd_trans);
@ -1105,10 +1081,8 @@ int p9_trans_fd_init(void)
void p9_trans_fd_exit(void) void p9_trans_fd_exit(void)
{ {
kthread_stop(p9_poll_task); flush_work_sync(&p9_poll_work);
v9fs_unregister_trans(&p9_tcp_trans); v9fs_unregister_trans(&p9_tcp_trans);
v9fs_unregister_trans(&p9_unix_trans); v9fs_unregister_trans(&p9_unix_trans);
v9fs_unregister_trans(&p9_fd_trans); v9fs_unregister_trans(&p9_fd_trans);
destroy_workqueue(p9_mux_wq);
} }

View File

@ -364,7 +364,6 @@ void rds_ib_exit(void)
rds_ib_sysctl_exit(); rds_ib_sysctl_exit();
rds_ib_recv_exit(); rds_ib_recv_exit();
rds_trans_unregister(&rds_ib_transport); rds_trans_unregister(&rds_ib_transport);
rds_ib_fmr_exit();
} }
struct rds_transport rds_ib_transport = { struct rds_transport rds_ib_transport = {
@ -400,13 +399,9 @@ int rds_ib_init(void)
INIT_LIST_HEAD(&rds_ib_devices); INIT_LIST_HEAD(&rds_ib_devices);
ret = rds_ib_fmr_init();
if (ret)
goto out;
ret = ib_register_client(&rds_ib_client); ret = ib_register_client(&rds_ib_client);
if (ret) if (ret)
goto out_fmr_exit; goto out;
ret = rds_ib_sysctl_init(); ret = rds_ib_sysctl_init();
if (ret) if (ret)
@ -430,8 +425,6 @@ out_sysctl:
rds_ib_sysctl_exit(); rds_ib_sysctl_exit();
out_ibreg: out_ibreg:
rds_ib_unregister_client(); rds_ib_unregister_client();
out_fmr_exit:
rds_ib_fmr_exit();
out: out:
return ret; return ret;
} }

View File

@ -307,8 +307,6 @@ void *rds_ib_get_mr(struct scatterlist *sg, unsigned long nents,
void rds_ib_sync_mr(void *trans_private, int dir); void rds_ib_sync_mr(void *trans_private, int dir);
void rds_ib_free_mr(void *trans_private, int invalidate); void rds_ib_free_mr(void *trans_private, int invalidate);
void rds_ib_flush_mrs(void); void rds_ib_flush_mrs(void);
int rds_ib_fmr_init(void);
void rds_ib_fmr_exit(void);
/* ib_recv.c */ /* ib_recv.c */
int rds_ib_recv_init(void); int rds_ib_recv_init(void);

View File

@ -38,8 +38,6 @@
#include "ib.h" #include "ib.h"
#include "xlist.h" #include "xlist.h"
static struct workqueue_struct *rds_ib_fmr_wq;
static DEFINE_PER_CPU(unsigned long, clean_list_grace); static DEFINE_PER_CPU(unsigned long, clean_list_grace);
#define CLEAN_LIST_BUSY_BIT 0 #define CLEAN_LIST_BUSY_BIT 0
@ -307,7 +305,7 @@ static struct rds_ib_mr *rds_ib_alloc_fmr(struct rds_ib_device *rds_ibdev)
int err = 0, iter = 0; int err = 0, iter = 0;
if (atomic_read(&pool->dirty_count) >= pool->max_items / 10) if (atomic_read(&pool->dirty_count) >= pool->max_items / 10)
queue_delayed_work(rds_ib_fmr_wq, &pool->flush_worker, 10); schedule_delayed_work(&pool->flush_worker, 10);
while (1) { while (1) {
ibmr = rds_ib_reuse_fmr(pool); ibmr = rds_ib_reuse_fmr(pool);
@ -696,24 +694,6 @@ out_nolock:
return ret; return ret;
} }
int rds_ib_fmr_init(void)
{
rds_ib_fmr_wq = create_workqueue("rds_fmr_flushd");
if (!rds_ib_fmr_wq)
return -ENOMEM;
return 0;
}
/*
* By the time this is called all the IB devices should have been torn down and
* had their pools freed. As each pool is freed its work struct is waited on,
* so the pool flushing work queue should be idle by the time we get here.
*/
void rds_ib_fmr_exit(void)
{
destroy_workqueue(rds_ib_fmr_wq);
}
static void rds_ib_mr_pool_flush_worker(struct work_struct *work) static void rds_ib_mr_pool_flush_worker(struct work_struct *work)
{ {
struct rds_ib_mr_pool *pool = container_of(work, struct rds_ib_mr_pool, flush_worker.work); struct rds_ib_mr_pool *pool = container_of(work, struct rds_ib_mr_pool, flush_worker.work);
@ -741,7 +721,7 @@ void rds_ib_free_mr(void *trans_private, int invalidate)
/* If we've pinned too many pages, request a flush */ /* If we've pinned too many pages, request a flush */
if (atomic_read(&pool->free_pinned) >= pool->max_free_pinned || if (atomic_read(&pool->free_pinned) >= pool->max_free_pinned ||
atomic_read(&pool->dirty_count) >= pool->max_items / 10) atomic_read(&pool->dirty_count) >= pool->max_items / 10)
queue_delayed_work(rds_ib_fmr_wq, &pool->flush_worker, 10); schedule_delayed_work(&pool->flush_worker, 10);
if (invalidate) { if (invalidate) {
if (likely(!in_interrupt())) { if (likely(!in_interrupt())) {
@ -749,8 +729,7 @@ void rds_ib_free_mr(void *trans_private, int invalidate)
} else { } else {
/* We get here if the user created a MR marked /* We get here if the user created a MR marked
* as use_once and invalidate at the same time. */ * as use_once and invalidate at the same time. */
queue_delayed_work(rds_ib_fmr_wq, schedule_delayed_work(&pool->flush_worker, 10);
&pool->flush_worker, 10);
} }
} }

View File

@ -955,7 +955,7 @@ static int rpciod_start(void)
* Create the rpciod thread and wait for it to start. * Create the rpciod thread and wait for it to start.
*/ */
dprintk("RPC: creating workqueue rpciod\n"); dprintk("RPC: creating workqueue rpciod\n");
wq = alloc_workqueue("rpciod", WQ_RESCUER, 0); wq = alloc_workqueue("rpciod", WQ_MEM_RECLAIM, 0);
rpciod_workqueue = wq; rpciod_workqueue = wq;
return rpciod_workqueue != NULL; return rpciod_workqueue != NULL;
} }