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-linus' of git://git.kernel.dk/linux-block

Pull block fixes from Jens Axboe:
"Been sitting on this for a while, but lets get this out the door.
This fixes various important bugs for 3.3 final, along with a few more
trivial ones. Please pull!"

* 'for-linus' of git://git.kernel.dk/linux-block:
block: fix ioc leak in put_io_context
block, sx8: fix pointer math issue getting fw version
Block: use a freezable workqueue for disk-event polling
drivers/block/DAC960: fix -Wuninitialized warning
drivers/block/DAC960: fix DAC960_V2_IOCTL_Opcode_T -Wenum-compare warning
block: fix __blkdev_get and add_disk race condition
block: Fix setting bio flags in drivers (sd_dif/floppy)
block: Fix NULL pointer dereference in sd_revalidate_disk
block: exit_io_context() should call elevator_exit_icq_fn()
block: simplify ioc_release_fn()
block: replace icq->changed with icq->flags

+198 -95
+87 -46
block/blk-ioc.c
··· 36 36 kmem_cache_free(icq->__rcu_icq_cache, icq); 37 37 } 38 38 39 - /* 40 - * Exit and free an icq. Called with both ioc and q locked. 41 - */ 39 + /* Exit an icq. Called with both ioc and q locked. */ 42 40 static void ioc_exit_icq(struct io_cq *icq) 41 + { 42 + struct elevator_type *et = icq->q->elevator->type; 43 + 44 + if (icq->flags & ICQ_EXITED) 45 + return; 46 + 47 + if (et->ops.elevator_exit_icq_fn) 48 + et->ops.elevator_exit_icq_fn(icq); 49 + 50 + icq->flags |= ICQ_EXITED; 51 + } 52 + 53 + /* Release an icq. Called with both ioc and q locked. */ 54 + static void ioc_destroy_icq(struct io_cq *icq) 43 55 { 44 56 struct io_context *ioc = icq->ioc; 45 57 struct request_queue *q = icq->q; ··· 72 60 if (rcu_dereference_raw(ioc->icq_hint) == icq) 73 61 rcu_assign_pointer(ioc->icq_hint, NULL); 74 62 75 - if (et->ops.elevator_exit_icq_fn) 76 - et->ops.elevator_exit_icq_fn(icq); 63 + ioc_exit_icq(icq); 77 64 78 65 /* 79 66 * @icq->q might have gone away by the time RCU callback runs ··· 90 79 { 91 80 struct io_context *ioc = container_of(work, struct io_context, 92 81 release_work); 93 - struct request_queue *last_q = NULL; 94 82 unsigned long flags; 95 83 96 84 /* ··· 103 93 while (!hlist_empty(&ioc->icq_list)) { 104 94 struct io_cq *icq = hlist_entry(ioc->icq_list.first, 105 95 struct io_cq, ioc_node); 106 - struct request_queue *this_q = icq->q; 96 + struct request_queue *q = icq->q; 107 97 108 - if (this_q != last_q) { 109 - /* 110 - * Need to switch to @this_q. Once we release 111 - * @ioc->lock, it can go away along with @cic. 112 - * Hold on to it. 113 - */ 114 - __blk_get_queue(this_q); 115 - 116 - /* 117 - * blk_put_queue() might sleep thanks to kobject 118 - * idiocy. Always release both locks, put and 119 - * restart. 120 - */ 121 - if (last_q) { 122 - spin_unlock(last_q->queue_lock); 123 - spin_unlock_irqrestore(&ioc->lock, flags); 124 - blk_put_queue(last_q); 125 - } else { 126 - spin_unlock_irqrestore(&ioc->lock, flags); 127 - } 128 - 129 - last_q = this_q; 130 - spin_lock_irqsave(this_q->queue_lock, flags); 131 - spin_lock_nested(&ioc->lock, 1); 132 - continue; 98 + if (spin_trylock(q->queue_lock)) { 99 + ioc_destroy_icq(icq); 100 + spin_unlock(q->queue_lock); 101 + } else { 102 + spin_unlock_irqrestore(&ioc->lock, flags); 103 + cpu_relax(); 104 + spin_lock_irqsave_nested(&ioc->lock, flags, 1); 133 105 } 134 - ioc_exit_icq(icq); 135 106 } 136 107 137 - if (last_q) { 138 - spin_unlock(last_q->queue_lock); 139 - spin_unlock_irqrestore(&ioc->lock, flags); 140 - blk_put_queue(last_q); 141 - } else { 142 - spin_unlock_irqrestore(&ioc->lock, flags); 143 - } 108 + spin_unlock_irqrestore(&ioc->lock, flags); 144 109 145 110 kmem_cache_free(iocontext_cachep, ioc); 146 111 } ··· 130 145 void put_io_context(struct io_context *ioc) 131 146 { 132 147 unsigned long flags; 148 + bool free_ioc = false; 133 149 134 150 if (ioc == NULL) 135 151 return; ··· 145 159 spin_lock_irqsave(&ioc->lock, flags); 146 160 if (!hlist_empty(&ioc->icq_list)) 147 161 schedule_work(&ioc->release_work); 162 + else 163 + free_ioc = true; 148 164 spin_unlock_irqrestore(&ioc->lock, flags); 149 165 } 166 + 167 + if (free_ioc) 168 + kmem_cache_free(iocontext_cachep, ioc); 150 169 } 151 170 EXPORT_SYMBOL(put_io_context); 152 171 ··· 159 168 void exit_io_context(struct task_struct *task) 160 169 { 161 170 struct io_context *ioc; 171 + struct io_cq *icq; 172 + struct hlist_node *n; 173 + unsigned long flags; 162 174 163 175 task_lock(task); 164 176 ioc = task->io_context; 165 177 task->io_context = NULL; 166 178 task_unlock(task); 167 179 168 - atomic_dec(&ioc->nr_tasks); 180 + if (!atomic_dec_and_test(&ioc->nr_tasks)) { 181 + put_io_context(ioc); 182 + return; 183 + } 184 + 185 + /* 186 + * Need ioc lock to walk icq_list and q lock to exit icq. Perform 187 + * reverse double locking. Read comment in ioc_release_fn() for 188 + * explanation on the nested locking annotation. 189 + */ 190 + retry: 191 + spin_lock_irqsave_nested(&ioc->lock, flags, 1); 192 + hlist_for_each_entry(icq, n, &ioc->icq_list, ioc_node) { 193 + if (icq->flags & ICQ_EXITED) 194 + continue; 195 + if (spin_trylock(icq->q->queue_lock)) { 196 + ioc_exit_icq(icq); 197 + spin_unlock(icq->q->queue_lock); 198 + } else { 199 + spin_unlock_irqrestore(&ioc->lock, flags); 200 + cpu_relax(); 201 + goto retry; 202 + } 203 + } 204 + spin_unlock_irqrestore(&ioc->lock, flags); 205 + 169 206 put_io_context(ioc); 170 207 } 171 208 ··· 213 194 struct io_context *ioc = icq->ioc; 214 195 215 196 spin_lock(&ioc->lock); 216 - ioc_exit_icq(icq); 197 + ioc_destroy_icq(icq); 217 198 spin_unlock(&ioc->lock); 218 199 } 219 200 } ··· 382 363 return icq; 383 364 } 384 365 385 - void ioc_set_changed(struct io_context *ioc, int which) 366 + void ioc_set_icq_flags(struct io_context *ioc, unsigned int flags) 386 367 { 387 368 struct io_cq *icq; 388 369 struct hlist_node *n; 389 370 390 371 hlist_for_each_entry(icq, n, &ioc->icq_list, ioc_node) 391 - set_bit(which, &icq->changed); 372 + icq->flags |= flags; 392 373 } 393 374 394 375 /** ··· 406 387 407 388 spin_lock_irqsave(&ioc->lock, flags); 408 389 ioc->ioprio = ioprio; 409 - ioc_set_changed(ioc, ICQ_IOPRIO_CHANGED); 390 + ioc_set_icq_flags(ioc, ICQ_IOPRIO_CHANGED); 410 391 spin_unlock_irqrestore(&ioc->lock, flags); 411 392 } 412 393 ··· 423 404 unsigned long flags; 424 405 425 406 spin_lock_irqsave(&ioc->lock, flags); 426 - ioc_set_changed(ioc, ICQ_CGROUP_CHANGED); 407 + ioc_set_icq_flags(ioc, ICQ_CGROUP_CHANGED); 427 408 spin_unlock_irqrestore(&ioc->lock, flags); 428 409 } 429 410 EXPORT_SYMBOL(ioc_cgroup_changed); 411 + 412 + /** 413 + * icq_get_changed - fetch and clear icq changed mask 414 + * @icq: icq of interest 415 + * 416 + * Fetch and clear ICQ_*_CHANGED bits from @icq. Grabs and releases 417 + * @icq->ioc->lock. 418 + */ 419 + unsigned icq_get_changed(struct io_cq *icq) 420 + { 421 + unsigned int changed = 0; 422 + unsigned long flags; 423 + 424 + if (unlikely(icq->flags & ICQ_CHANGED_MASK)) { 425 + spin_lock_irqsave(&icq->ioc->lock, flags); 426 + changed = icq->flags & ICQ_CHANGED_MASK; 427 + icq->flags &= ~ICQ_CHANGED_MASK; 428 + spin_unlock_irqrestore(&icq->ioc->lock, flags); 429 + } 430 + return changed; 431 + } 432 + EXPORT_SYMBOL(icq_get_changed); 430 433 431 434 static int __init blk_ioc_init(void) 432 435 {
+6 -6
block/cfq-iosched.c
··· 3470 3470 const int rw = rq_data_dir(rq); 3471 3471 const bool is_sync = rq_is_sync(rq); 3472 3472 struct cfq_queue *cfqq; 3473 + unsigned int changed; 3473 3474 3474 3475 might_sleep_if(gfp_mask & __GFP_WAIT); 3475 3476 3476 3477 spin_lock_irq(q->queue_lock); 3477 3478 3478 3479 /* handle changed notifications */ 3479 - if (unlikely(cic->icq.changed)) { 3480 - if (test_and_clear_bit(ICQ_IOPRIO_CHANGED, &cic->icq.changed)) 3481 - changed_ioprio(cic); 3480 + changed = icq_get_changed(&cic->icq); 3481 + if (unlikely(changed & ICQ_IOPRIO_CHANGED)) 3482 + changed_ioprio(cic); 3482 3483 #ifdef CONFIG_CFQ_GROUP_IOSCHED 3483 - if (test_and_clear_bit(ICQ_CGROUP_CHANGED, &cic->icq.changed)) 3484 - changed_cgroup(cic); 3484 + if (unlikely(changed & ICQ_CGROUP_CHANGED)) 3485 + changed_cgroup(cic); 3485 3486 #endif 3486 - } 3487 3487 3488 3488 new_queue: 3489 3489 cfqq = cic_to_cfqq(cic, is_sync);
+24 -18
block/genhd.c
··· 35 35 36 36 static struct device_type disk_type; 37 37 38 + static void disk_alloc_events(struct gendisk *disk); 38 39 static void disk_add_events(struct gendisk *disk); 39 40 static void disk_del_events(struct gendisk *disk); 40 41 static void disk_release_events(struct gendisk *disk); ··· 601 600 */ 602 601 disk->major = MAJOR(devt); 603 602 disk->first_minor = MINOR(devt); 603 + 604 + disk_alloc_events(disk); 604 605 605 606 /* Register BDI before referencing it from bdev */ 606 607 bdi = &disk->queue->backing_dev_info; ··· 1478 1475 intv = disk_events_poll_jiffies(disk); 1479 1476 set_timer_slack(&ev->dwork.timer, intv / 4); 1480 1477 if (check_now) 1481 - queue_delayed_work(system_nrt_wq, &ev->dwork, 0); 1478 + queue_delayed_work(system_nrt_freezable_wq, &ev->dwork, 0); 1482 1479 else if (intv) 1483 - queue_delayed_work(system_nrt_wq, &ev->dwork, intv); 1480 + queue_delayed_work(system_nrt_freezable_wq, &ev->dwork, intv); 1484 1481 out_unlock: 1485 1482 spin_unlock_irqrestore(&ev->lock, flags); 1486 1483 } ··· 1524 1521 ev->clearing |= mask; 1525 1522 if (!ev->block) { 1526 1523 cancel_delayed_work(&ev->dwork); 1527 - queue_delayed_work(system_nrt_wq, &ev->dwork, 0); 1524 + queue_delayed_work(system_nrt_freezable_wq, &ev->dwork, 0); 1528 1525 } 1529 1526 spin_unlock_irq(&ev->lock); 1530 1527 } ··· 1561 1558 1562 1559 /* uncondtionally schedule event check and wait for it to finish */ 1563 1560 disk_block_events(disk); 1564 - queue_delayed_work(system_nrt_wq, &ev->dwork, 0); 1561 + queue_delayed_work(system_nrt_freezable_wq, &ev->dwork, 0); 1565 1562 flush_delayed_work(&ev->dwork); 1566 1563 __disk_unblock_events(disk, false); 1567 1564 ··· 1598 1595 1599 1596 intv = disk_events_poll_jiffies(disk); 1600 1597 if (!ev->block && intv) 1601 - queue_delayed_work(system_nrt_wq, &ev->dwork, intv); 1598 + queue_delayed_work(system_nrt_freezable_wq, &ev->dwork, intv); 1602 1599 1603 1600 spin_unlock_irq(&ev->lock); 1604 1601 ··· 1736 1733 &disk_events_dfl_poll_msecs, 0644); 1737 1734 1738 1735 /* 1739 - * disk_{add|del|release}_events - initialize and destroy disk_events. 1736 + * disk_{alloc|add|del|release}_events - initialize and destroy disk_events. 1740 1737 */ 1741 - static void disk_add_events(struct gendisk *disk) 1738 + static void disk_alloc_events(struct gendisk *disk) 1742 1739 { 1743 1740 struct disk_events *ev; 1744 1741 ··· 1751 1748 return; 1752 1749 } 1753 1750 1754 - if (sysfs_create_files(&disk_to_dev(disk)->kobj, 1755 - disk_events_attrs) < 0) { 1756 - pr_warn("%s: failed to create sysfs files for events\n", 1757 - disk->disk_name); 1758 - kfree(ev); 1759 - return; 1760 - } 1761 - 1762 - disk->ev = ev; 1763 - 1764 1751 INIT_LIST_HEAD(&ev->node); 1765 1752 ev->disk = disk; 1766 1753 spin_lock_init(&ev->lock); ··· 1759 1766 ev->poll_msecs = -1; 1760 1767 INIT_DELAYED_WORK(&ev->dwork, disk_events_workfn); 1761 1768 1769 + disk->ev = ev; 1770 + } 1771 + 1772 + static void disk_add_events(struct gendisk *disk) 1773 + { 1774 + if (!disk->ev) 1775 + return; 1776 + 1777 + /* FIXME: error handling */ 1778 + if (sysfs_create_files(&disk_to_dev(disk)->kobj, disk_events_attrs) < 0) 1779 + pr_warn("%s: failed to create sysfs files for events\n", 1780 + disk->disk_name); 1781 + 1762 1782 mutex_lock(&disk_events_mutex); 1763 - list_add_tail(&ev->node, &disk_events); 1783 + list_add_tail(&disk->ev->node, &disk_events); 1764 1784 mutex_unlock(&disk_events_mutex); 1765 1785 1766 1786 /*
+40 -8
block/partition-generic.c
··· 389 389 } 390 390 } 391 391 392 - int rescan_partitions(struct gendisk *disk, struct block_device *bdev) 392 + static int drop_partitions(struct gendisk *disk, struct block_device *bdev) 393 393 { 394 - struct parsed_partitions *state = NULL; 395 394 struct disk_part_iter piter; 396 395 struct hd_struct *part; 397 - int p, highest, res; 398 - rescan: 399 - if (state && !IS_ERR(state)) { 400 - kfree(state); 401 - state = NULL; 402 - } 396 + int res; 403 397 404 398 if (bdev->bd_part_count) 405 399 return -EBUSY; ··· 405 411 while ((part = disk_part_iter_next(&piter))) 406 412 delete_partition(disk, part->partno); 407 413 disk_part_iter_exit(&piter); 414 + 415 + return 0; 416 + } 417 + 418 + int rescan_partitions(struct gendisk *disk, struct block_device *bdev) 419 + { 420 + struct parsed_partitions *state = NULL; 421 + struct hd_struct *part; 422 + int p, highest, res; 423 + rescan: 424 + if (state && !IS_ERR(state)) { 425 + kfree(state); 426 + state = NULL; 427 + } 428 + 429 + res = drop_partitions(disk, bdev); 430 + if (res) 431 + return res; 408 432 409 433 if (disk->fops->revalidate_disk) 410 434 disk->fops->revalidate_disk(disk); ··· 524 512 #endif 525 513 } 526 514 kfree(state); 515 + return 0; 516 + } 517 + 518 + int invalidate_partitions(struct gendisk *disk, struct block_device *bdev) 519 + { 520 + int res; 521 + 522 + if (!bdev->bd_invalidated) 523 + return 0; 524 + 525 + res = drop_partitions(disk, bdev); 526 + if (res) 527 + return res; 528 + 529 + set_capacity(disk, 0); 530 + check_disk_size_change(disk, bdev); 531 + bdev->bd_invalidated = 0; 532 + /* tell userspace that the media / partition table may have changed */ 533 + kobject_uevent(&disk_to_dev(disk)->kobj, KOBJ_CHANGE); 534 + 527 535 return 0; 528 536 } 529 537
+10 -8
drivers/block/DAC960.c
··· 1177 1177 int TimeoutCounter; 1178 1178 int i; 1179 1179 1180 - 1180 + memset(&CommandMailbox, 0, sizeof(DAC960_V1_CommandMailbox_T)); 1181 + 1181 1182 if (pci_set_dma_mask(Controller->PCIDevice, DMA_BIT_MASK(32))) 1182 1183 return DAC960_Failure(Controller, "DMA mask out of range"); 1183 1184 Controller->BounceBufferLimit = DMA_BIT_MASK(32); ··· 4628 4627 DAC960_Controller_T *Controller = Command->Controller; 4629 4628 DAC960_CommandType_T CommandType = Command->CommandType; 4630 4629 DAC960_V2_CommandMailbox_T *CommandMailbox = &Command->V2.CommandMailbox; 4631 - DAC960_V2_IOCTL_Opcode_T CommandOpcode = CommandMailbox->Common.IOCTL_Opcode; 4630 + DAC960_V2_IOCTL_Opcode_T IOCTLOpcode = CommandMailbox->Common.IOCTL_Opcode; 4631 + DAC960_V2_CommandOpcode_T CommandOpcode = CommandMailbox->SCSI_10.CommandOpcode; 4632 4632 DAC960_V2_CommandStatus_T CommandStatus = Command->V2.CommandStatus; 4633 4633 4634 4634 if (CommandType == DAC960_ReadCommand || ··· 4701 4699 { 4702 4700 if (Controller->ShutdownMonitoringTimer) 4703 4701 return; 4704 - if (CommandOpcode == DAC960_V2_GetControllerInfo) 4702 + if (IOCTLOpcode == DAC960_V2_GetControllerInfo) 4705 4703 { 4706 4704 DAC960_V2_ControllerInfo_T *NewControllerInfo = 4707 4705 Controller->V2.NewControllerInformation; ··· 4721 4719 memcpy(ControllerInfo, NewControllerInfo, 4722 4720 sizeof(DAC960_V2_ControllerInfo_T)); 4723 4721 } 4724 - else if (CommandOpcode == DAC960_V2_GetEvent) 4722 + else if (IOCTLOpcode == DAC960_V2_GetEvent) 4725 4723 { 4726 4724 if (CommandStatus == DAC960_V2_NormalCompletion) { 4727 4725 DAC960_V2_ReportEvent(Controller, Controller->V2.Event); 4728 4726 } 4729 4727 Controller->V2.NextEventSequenceNumber++; 4730 4728 } 4731 - else if (CommandOpcode == DAC960_V2_GetPhysicalDeviceInfoValid && 4729 + else if (IOCTLOpcode == DAC960_V2_GetPhysicalDeviceInfoValid && 4732 4730 CommandStatus == DAC960_V2_NormalCompletion) 4733 4731 { 4734 4732 DAC960_V2_PhysicalDeviceInfo_T *NewPhysicalDeviceInfo = ··· 4917 4915 NewPhysicalDeviceInfo->LogicalUnit++; 4918 4916 Controller->V2.PhysicalDeviceIndex++; 4919 4917 } 4920 - else if (CommandOpcode == DAC960_V2_GetPhysicalDeviceInfoValid) 4918 + else if (IOCTLOpcode == DAC960_V2_GetPhysicalDeviceInfoValid) 4921 4919 { 4922 4920 unsigned int DeviceIndex; 4923 4921 for (DeviceIndex = Controller->V2.PhysicalDeviceIndex; ··· 4940 4938 } 4941 4939 Controller->V2.NeedPhysicalDeviceInformation = false; 4942 4940 } 4943 - else if (CommandOpcode == DAC960_V2_GetLogicalDeviceInfoValid && 4941 + else if (IOCTLOpcode == DAC960_V2_GetLogicalDeviceInfoValid && 4944 4942 CommandStatus == DAC960_V2_NormalCompletion) 4945 4943 { 4946 4944 DAC960_V2_LogicalDeviceInfo_T *NewLogicalDeviceInfo = ··· 5067 5065 [LogicalDeviceNumber] = true; 5068 5066 NewLogicalDeviceInfo->LogicalDeviceNumber++; 5069 5067 } 5070 - else if (CommandOpcode == DAC960_V2_GetLogicalDeviceInfoValid) 5068 + else if (IOCTLOpcode == DAC960_V2_GetLogicalDeviceInfoValid) 5071 5069 { 5072 5070 int LogicalDriveNumber; 5073 5071 for (LogicalDriveNumber = 0;
+1 -1
drivers/block/sx8.c
··· 1120 1120 break; 1121 1121 case MISC_GET_FW_VER: { 1122 1122 struct carm_fw_ver *ver = (struct carm_fw_ver *) 1123 - mem + sizeof(struct carm_msg_get_fw_ver); 1123 + (mem + sizeof(struct carm_msg_get_fw_ver)); 1124 1124 if (!error) { 1125 1125 host->fw_ver = le32_to_cpu(ver->version); 1126 1126 host->flags |= (ver->features & FL_FW_VER_MASK);
+12 -4
fs/block_dev.c
··· 1183 1183 * The latter is necessary to prevent ghost 1184 1184 * partitions on a removed medium. 1185 1185 */ 1186 - if (bdev->bd_invalidated && (!ret || ret == -ENOMEDIUM)) 1187 - rescan_partitions(disk, bdev); 1186 + if (bdev->bd_invalidated) { 1187 + if (!ret) 1188 + rescan_partitions(disk, bdev); 1189 + else if (ret == -ENOMEDIUM) 1190 + invalidate_partitions(disk, bdev); 1191 + } 1188 1192 if (ret) 1189 1193 goto out_clear; 1190 1194 } else { ··· 1218 1214 if (bdev->bd_disk->fops->open) 1219 1215 ret = bdev->bd_disk->fops->open(bdev, mode); 1220 1216 /* the same as first opener case, read comment there */ 1221 - if (bdev->bd_invalidated && (!ret || ret == -ENOMEDIUM)) 1222 - rescan_partitions(bdev->bd_disk, bdev); 1217 + if (bdev->bd_invalidated) { 1218 + if (!ret) 1219 + rescan_partitions(bdev->bd_disk, bdev); 1220 + else if (ret == -ENOMEDIUM) 1221 + invalidate_partitions(bdev->bd_disk, bdev); 1222 + } 1223 1223 if (ret) 1224 1224 goto out_unlock_bdev; 1225 1225 }
+1
include/linux/genhd.h
··· 596 596 597 597 extern int disk_expand_part_tbl(struct gendisk *disk, int target); 598 598 extern int rescan_partitions(struct gendisk *disk, struct block_device *bdev); 599 + extern int invalidate_partitions(struct gendisk *disk, struct block_device *bdev); 599 600 extern struct hd_struct * __must_check add_partition(struct gendisk *disk, 600 601 int partno, sector_t start, 601 602 sector_t len, int flags,
+7 -3
include/linux/iocontext.h
··· 6 6 #include <linux/workqueue.h> 7 7 8 8 enum { 9 - ICQ_IOPRIO_CHANGED, 10 - ICQ_CGROUP_CHANGED, 9 + ICQ_IOPRIO_CHANGED = 1 << 0, 10 + ICQ_CGROUP_CHANGED = 1 << 1, 11 + ICQ_EXITED = 1 << 2, 12 + 13 + ICQ_CHANGED_MASK = ICQ_IOPRIO_CHANGED | ICQ_CGROUP_CHANGED, 11 14 }; 12 15 13 16 /* ··· 91 88 struct rcu_head __rcu_head; 92 89 }; 93 90 94 - unsigned long changed; 91 + unsigned int flags; 95 92 }; 96 93 97 94 /* ··· 142 139 gfp_t gfp_flags, int node); 143 140 void ioc_ioprio_changed(struct io_context *ioc, int ioprio); 144 141 void ioc_cgroup_changed(struct io_context *ioc); 142 + unsigned int icq_get_changed(struct io_cq *icq); 145 143 #else 146 144 struct io_context; 147 145 static inline void put_io_context(struct io_context *ioc) { }
+4
include/linux/workqueue.h
··· 289 289 * 290 290 * system_freezable_wq is equivalent to system_wq except that it's 291 291 * freezable. 292 + * 293 + * system_nrt_freezable_wq is equivalent to system_nrt_wq except that 294 + * it's freezable. 292 295 */ 293 296 extern struct workqueue_struct *system_wq; 294 297 extern struct workqueue_struct *system_long_wq; 295 298 extern struct workqueue_struct *system_nrt_wq; 296 299 extern struct workqueue_struct *system_unbound_wq; 297 300 extern struct workqueue_struct *system_freezable_wq; 301 + extern struct workqueue_struct *system_nrt_freezable_wq; 298 302 299 303 extern struct workqueue_struct * 300 304 __alloc_workqueue_key(const char *fmt, unsigned int flags, int max_active,
+6 -1
kernel/workqueue.c
··· 253 253 struct workqueue_struct *system_nrt_wq __read_mostly; 254 254 struct workqueue_struct *system_unbound_wq __read_mostly; 255 255 struct workqueue_struct *system_freezable_wq __read_mostly; 256 + struct workqueue_struct *system_nrt_freezable_wq __read_mostly; 256 257 EXPORT_SYMBOL_GPL(system_wq); 257 258 EXPORT_SYMBOL_GPL(system_long_wq); 258 259 EXPORT_SYMBOL_GPL(system_nrt_wq); 259 260 EXPORT_SYMBOL_GPL(system_unbound_wq); 260 261 EXPORT_SYMBOL_GPL(system_freezable_wq); 262 + EXPORT_SYMBOL_GPL(system_nrt_freezable_wq); 261 263 262 264 #define CREATE_TRACE_POINTS 263 265 #include <trace/events/workqueue.h> ··· 3835 3833 WQ_UNBOUND_MAX_ACTIVE); 3836 3834 system_freezable_wq = alloc_workqueue("events_freezable", 3837 3835 WQ_FREEZABLE, 0); 3836 + system_nrt_freezable_wq = alloc_workqueue("events_nrt_freezable", 3837 + WQ_NON_REENTRANT | WQ_FREEZABLE, 0); 3838 3838 BUG_ON(!system_wq || !system_long_wq || !system_nrt_wq || 3839 - !system_unbound_wq || !system_freezable_wq); 3839 + !system_unbound_wq || !system_freezable_wq || 3840 + !system_nrt_freezable_wq); 3840 3841 return 0; 3841 3842 } 3842 3843 early_initcall(init_workqueues);