Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

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

Pull workqueue fix from Tejun Heo:
"This pull request contains a workqueue usage fix for firewire.

For quite a long time now, workqueue only treats two work items
identical iff both their addresses and callbacks match. This is to
avoid introducing false dependency through the work item being
recycled while being executed. This changes non-reentrancy guarantee
for the users of PREPARE[_DELAYED]_WORK() - if the function changes,
reentrancy isn't guaranteed against the previous instance. Firewire
depended on such nonreentrancy guarantee.

This is fixed by doing the work item multiplexing from firewire proper
while keeping the work function unchanged"

* 'for-3.14-fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/tj/wq:
firewire: don't use PREPARE_DELAYED_WORK

+29 -11
+15 -7
drivers/firewire/core-device.c
··· 916 916 old->config_rom_retries = 0; 917 917 fw_notice(card, "rediscovered device %s\n", dev_name(dev)); 918 918 919 - PREPARE_DELAYED_WORK(&old->work, fw_device_update); 919 + old->workfn = fw_device_update; 920 920 fw_schedule_device_work(old, 0); 921 921 922 922 if (current_node == card->root_node) ··· 1075 1075 if (atomic_cmpxchg(&device->state, 1076 1076 FW_DEVICE_INITIALIZING, 1077 1077 FW_DEVICE_RUNNING) == FW_DEVICE_GONE) { 1078 - PREPARE_DELAYED_WORK(&device->work, fw_device_shutdown); 1078 + device->workfn = fw_device_shutdown; 1079 1079 fw_schedule_device_work(device, SHUTDOWN_DELAY); 1080 1080 } else { 1081 1081 fw_notice(card, "created device %s: GUID %08x%08x, S%d00\n", ··· 1196 1196 dev_name(&device->device), fw_rcode_string(ret)); 1197 1197 gone: 1198 1198 atomic_set(&device->state, FW_DEVICE_GONE); 1199 - PREPARE_DELAYED_WORK(&device->work, fw_device_shutdown); 1199 + device->workfn = fw_device_shutdown; 1200 1200 fw_schedule_device_work(device, SHUTDOWN_DELAY); 1201 1201 out: 1202 1202 if (node_id == card->root_node->node_id) 1203 1203 fw_schedule_bm_work(card, 0); 1204 + } 1205 + 1206 + static void fw_device_workfn(struct work_struct *work) 1207 + { 1208 + struct fw_device *device = container_of(to_delayed_work(work), 1209 + struct fw_device, work); 1210 + device->workfn(work); 1204 1211 } 1205 1212 1206 1213 void fw_node_event(struct fw_card *card, struct fw_node *node, int event) ··· 1259 1252 * power-up after getting plugged in. We schedule the 1260 1253 * first config rom scan half a second after bus reset. 1261 1254 */ 1262 - INIT_DELAYED_WORK(&device->work, fw_device_init); 1255 + device->workfn = fw_device_init; 1256 + INIT_DELAYED_WORK(&device->work, fw_device_workfn); 1263 1257 fw_schedule_device_work(device, INITIAL_DELAY); 1264 1258 break; 1265 1259 ··· 1276 1268 if (atomic_cmpxchg(&device->state, 1277 1269 FW_DEVICE_RUNNING, 1278 1270 FW_DEVICE_INITIALIZING) == FW_DEVICE_RUNNING) { 1279 - PREPARE_DELAYED_WORK(&device->work, fw_device_refresh); 1271 + device->workfn = fw_device_refresh; 1280 1272 fw_schedule_device_work(device, 1281 1273 device->is_local ? 0 : INITIAL_DELAY); 1282 1274 } ··· 1291 1283 smp_wmb(); /* update node_id before generation */ 1292 1284 device->generation = card->generation; 1293 1285 if (atomic_read(&device->state) == FW_DEVICE_RUNNING) { 1294 - PREPARE_DELAYED_WORK(&device->work, fw_device_update); 1286 + device->workfn = fw_device_update; 1295 1287 fw_schedule_device_work(device, 0); 1296 1288 } 1297 1289 break; ··· 1316 1308 device = node->data; 1317 1309 if (atomic_xchg(&device->state, 1318 1310 FW_DEVICE_GONE) == FW_DEVICE_RUNNING) { 1319 - PREPARE_DELAYED_WORK(&device->work, fw_device_shutdown); 1311 + device->workfn = fw_device_shutdown; 1320 1312 fw_schedule_device_work(device, 1321 1313 list_empty(&card->link) ? 0 : SHUTDOWN_DELAY); 1322 1314 }
+13 -4
drivers/firewire/sbp2.c
··· 146 146 */ 147 147 int generation; 148 148 int retries; 149 + work_func_t workfn; 149 150 struct delayed_work work; 150 151 bool has_sdev; 151 152 bool blocked; ··· 865 864 /* set appropriate retry limit(s) in BUSY_TIMEOUT register */ 866 865 sbp2_set_busy_timeout(lu); 867 866 868 - PREPARE_DELAYED_WORK(&lu->work, sbp2_reconnect); 867 + lu->workfn = sbp2_reconnect; 869 868 sbp2_agent_reset(lu); 870 869 871 870 /* This was a re-login. */ ··· 919 918 * If a bus reset happened, sbp2_update will have requeued 920 919 * lu->work already. Reset the work from reconnect to login. 921 920 */ 922 - PREPARE_DELAYED_WORK(&lu->work, sbp2_login); 921 + lu->workfn = sbp2_login; 923 922 } 924 923 925 924 static void sbp2_reconnect(struct work_struct *work) ··· 953 952 lu->retries++ >= 5) { 954 953 dev_err(tgt_dev(tgt), "failed to reconnect\n"); 955 954 lu->retries = 0; 956 - PREPARE_DELAYED_WORK(&lu->work, sbp2_login); 955 + lu->workfn = sbp2_login; 957 956 } 958 957 sbp2_queue_work(lu, DIV_ROUND_UP(HZ, 5)); 959 958 ··· 971 970 sbp2_agent_reset(lu); 972 971 sbp2_cancel_orbs(lu); 973 972 sbp2_conditionally_unblock(lu); 973 + } 974 + 975 + static void sbp2_lu_workfn(struct work_struct *work) 976 + { 977 + struct sbp2_logical_unit *lu = container_of(to_delayed_work(work), 978 + struct sbp2_logical_unit, work); 979 + lu->workfn(work); 974 980 } 975 981 976 982 static int sbp2_add_logical_unit(struct sbp2_target *tgt, int lun_entry) ··· 1006 998 lu->blocked = false; 1007 999 ++tgt->dont_block; 1008 1000 INIT_LIST_HEAD(&lu->orb_list); 1009 - INIT_DELAYED_WORK(&lu->work, sbp2_login); 1001 + lu->workfn = sbp2_login; 1002 + INIT_DELAYED_WORK(&lu->work, sbp2_lu_workfn); 1010 1003 1011 1004 list_add_tail(&lu->link, &tgt->lu_list); 1012 1005 return 0;
+1
include/linux/firewire.h
··· 200 200 unsigned irmc:1; 201 201 unsigned bc_implemented:2; 202 202 203 + work_func_t workfn; 203 204 struct delayed_work work; 204 205 struct fw_attribute_group attribute_group; 205 206 };