aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTejun Heo <tj@kernel.org>2014-03-07 10:24:48 -0500
committerTejun Heo <tj@kernel.org>2014-03-07 10:24:48 -0500
commit75ddb38f0901d12831264cd74224598e4d8f528b (patch)
tree0881a11d77acbbb44b402975cdf6a8316a4f0136
parent4a8bb7f54860a3241b177bdeb06bb880151a23dc (diff)
floppy: don't use PREPARE_[DELAYED_]WORK
PREPARE_[DELAYED_]WORK() are being phased out. They have few users and a nasty surprise in terms of reentrancy guarantee as workqueue considers work items to be different if they don't have the same work function. floppy has been multiplexing floppy_work and fd_timer with multiple work functions. Introduce floppy_work_workfn() and fd_timer_workfn() which invoke floppy_work_fn and fd_timer_fn respectively and always use the two functions as the work functions and update the users to set floppy_work_fn and fd_timer_fn instead of overriding work functions using PREPARE_[DELAYED_]WORK(). It would probably be best to route this with other related updates through the workqueue tree. Lightly tested using qemu. Signed-off-by: Tejun Heo <tj@kernel.org> Acked-by: Jiri Kosina <jkosina@suse.cz>
-rw-r--r--drivers/block/floppy.c42
1 files changed, 28 insertions, 14 deletions
diff --git a/drivers/block/floppy.c b/drivers/block/floppy.c
index 2023043ce7c0..8f5565bf34cd 100644
--- a/drivers/block/floppy.c
+++ b/drivers/block/floppy.c
@@ -961,17 +961,31 @@ static void empty(void)
961{ 961{
962} 962}
963 963
964static DECLARE_WORK(floppy_work, NULL); 964static void (*floppy_work_fn)(void);
965
966static void floppy_work_workfn(struct work_struct *work)
967{
968 floppy_work_fn();
969}
970
971static DECLARE_WORK(floppy_work, floppy_work_workfn);
965 972
966static void schedule_bh(void (*handler)(void)) 973static void schedule_bh(void (*handler)(void))
967{ 974{
968 WARN_ON(work_pending(&floppy_work)); 975 WARN_ON(work_pending(&floppy_work));
969 976
970 PREPARE_WORK(&floppy_work, (work_func_t)handler); 977 floppy_work_fn = handler;
971 queue_work(floppy_wq, &floppy_work); 978 queue_work(floppy_wq, &floppy_work);
972} 979}
973 980
974static DECLARE_DELAYED_WORK(fd_timer, NULL); 981static void (*fd_timer_fn)(void) = NULL;
982
983static void fd_timer_workfn(struct work_struct *work)
984{
985 fd_timer_fn();
986}
987
988static DECLARE_DELAYED_WORK(fd_timer, fd_timer_workfn);
975 989
976static void cancel_activity(void) 990static void cancel_activity(void)
977{ 991{
@@ -982,7 +996,7 @@ static void cancel_activity(void)
982 996
983/* this function makes sure that the disk stays in the drive during the 997/* this function makes sure that the disk stays in the drive during the
984 * transfer */ 998 * transfer */
985static void fd_watchdog(struct work_struct *arg) 999static void fd_watchdog(void)
986{ 1000{
987 debug_dcl(DP->flags, "calling disk change from watchdog\n"); 1001 debug_dcl(DP->flags, "calling disk change from watchdog\n");
988 1002
@@ -993,7 +1007,7 @@ static void fd_watchdog(struct work_struct *arg)
993 reset_fdc(); 1007 reset_fdc();
994 } else { 1008 } else {
995 cancel_delayed_work(&fd_timer); 1009 cancel_delayed_work(&fd_timer);
996 PREPARE_DELAYED_WORK(&fd_timer, fd_watchdog); 1010 fd_timer_fn = fd_watchdog;
997 queue_delayed_work(floppy_wq, &fd_timer, HZ / 10); 1011 queue_delayed_work(floppy_wq, &fd_timer, HZ / 10);
998 } 1012 }
999} 1013}
@@ -1005,7 +1019,8 @@ static void main_command_interrupt(void)
1005} 1019}
1006 1020
1007/* waits for a delay (spinup or select) to pass */ 1021/* waits for a delay (spinup or select) to pass */
1008static int fd_wait_for_completion(unsigned long expires, work_func_t function) 1022static int fd_wait_for_completion(unsigned long expires,
1023 void (*function)(void))
1009{ 1024{
1010 if (FDCS->reset) { 1025 if (FDCS->reset) {
1011 reset_fdc(); /* do the reset during sleep to win time 1026 reset_fdc(); /* do the reset during sleep to win time
@@ -1016,7 +1031,7 @@ static int fd_wait_for_completion(unsigned long expires, work_func_t function)
1016 1031
1017 if (time_before(jiffies, expires)) { 1032 if (time_before(jiffies, expires)) {
1018 cancel_delayed_work(&fd_timer); 1033 cancel_delayed_work(&fd_timer);
1019 PREPARE_DELAYED_WORK(&fd_timer, function); 1034 fd_timer_fn = function;
1020 queue_delayed_work(floppy_wq, &fd_timer, expires - jiffies); 1035 queue_delayed_work(floppy_wq, &fd_timer, expires - jiffies);
1021 return 1; 1036 return 1;
1022 } 1037 }
@@ -1334,8 +1349,7 @@ static int fdc_dtr(void)
1334 * Pause 5 msec to avoid trouble. (Needs to be 2 jiffies) 1349 * Pause 5 msec to avoid trouble. (Needs to be 2 jiffies)
1335 */ 1350 */
1336 FDCS->dtr = raw_cmd->rate & 3; 1351 FDCS->dtr = raw_cmd->rate & 3;
1337 return fd_wait_for_completion(jiffies + 2UL * HZ / 100, 1352 return fd_wait_for_completion(jiffies + 2UL * HZ / 100, floppy_ready);
1338 (work_func_t)floppy_ready);
1339} /* fdc_dtr */ 1353} /* fdc_dtr */
1340 1354
1341static void tell_sector(void) 1355static void tell_sector(void)
@@ -1440,7 +1454,7 @@ static void setup_rw_floppy(void)
1440 int flags; 1454 int flags;
1441 int dflags; 1455 int dflags;
1442 unsigned long ready_date; 1456 unsigned long ready_date;
1443 work_func_t function; 1457 void (*function)(void);
1444 1458
1445 flags = raw_cmd->flags; 1459 flags = raw_cmd->flags;
1446 if (flags & (FD_RAW_READ | FD_RAW_WRITE)) 1460 if (flags & (FD_RAW_READ | FD_RAW_WRITE))
@@ -1454,9 +1468,9 @@ static void setup_rw_floppy(void)
1454 */ 1468 */
1455 if (time_after(ready_date, jiffies + DP->select_delay)) { 1469 if (time_after(ready_date, jiffies + DP->select_delay)) {
1456 ready_date -= DP->select_delay; 1470 ready_date -= DP->select_delay;
1457 function = (work_func_t)floppy_start; 1471 function = floppy_start;
1458 } else 1472 } else
1459 function = (work_func_t)setup_rw_floppy; 1473 function = setup_rw_floppy;
1460 1474
1461 /* wait until the floppy is spinning fast enough */ 1475 /* wait until the floppy is spinning fast enough */
1462 if (fd_wait_for_completion(ready_date, function)) 1476 if (fd_wait_for_completion(ready_date, function))
@@ -1486,7 +1500,7 @@ static void setup_rw_floppy(void)
1486 inr = result(); 1500 inr = result();
1487 cont->interrupt(); 1501 cont->interrupt();
1488 } else if (flags & FD_RAW_NEED_DISK) 1502 } else if (flags & FD_RAW_NEED_DISK)
1489 fd_watchdog(NULL); 1503 fd_watchdog();
1490} 1504}
1491 1505
1492static int blind_seek; 1506static int blind_seek;
@@ -1863,7 +1877,7 @@ static int start_motor(void (*function)(void))
1863 1877
1864 /* wait_for_completion also schedules reset if needed. */ 1878 /* wait_for_completion also schedules reset if needed. */
1865 return fd_wait_for_completion(DRS->select_date + DP->select_delay, 1879 return fd_wait_for_completion(DRS->select_date + DP->select_delay,
1866 (work_func_t)function); 1880 function);
1867} 1881}
1868 1882
1869static void floppy_ready(void) 1883static void floppy_ready(void)