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 git://git.kvack.org/~bcrl/aio-next

Pull aio updates from Ben LaHaise.

* git://git.kvack.org/~bcrl/aio-next:
aio: use iovec array rather than the single one
aio: fix some comments
aio: use the macro rather than the inline magic number
aio: remove the needless registration of ring file's private_data
aio: remove no longer needed preempt_disable()
aio: kill the misleading rcu read locks in ioctx_add_table() and kill_ioctx()
aio: change exit_aio() to load mm->ioctx_table once and avoid rcu_read_lock()

+30 -56
+30 -56
fs/aio.c
··· 192 192 } 193 193 194 194 file->f_flags = O_RDWR; 195 - file->private_data = ctx; 196 195 return file; 197 196 } 198 197 ··· 201 202 static const struct dentry_operations ops = { 202 203 .d_dname = simple_dname, 203 204 }; 204 - return mount_pseudo(fs_type, "aio:", NULL, &ops, 0xa10a10a1); 205 + return mount_pseudo(fs_type, "aio:", NULL, &ops, AIO_RING_MAGIC); 205 206 } 206 207 207 208 /* aio_setup ··· 555 556 struct aio_ring *ring; 556 557 557 558 spin_lock(&mm->ioctx_lock); 558 - rcu_read_lock(); 559 - table = rcu_dereference(mm->ioctx_table); 559 + table = rcu_dereference_raw(mm->ioctx_table); 560 560 561 561 while (1) { 562 562 if (table) ··· 563 565 if (!table->table[i]) { 564 566 ctx->id = i; 565 567 table->table[i] = ctx; 566 - rcu_read_unlock(); 567 568 spin_unlock(&mm->ioctx_lock); 568 569 569 570 /* While kioctx setup is in progress, ··· 576 579 } 577 580 578 581 new_nr = (table ? table->nr : 1) * 4; 579 - 580 - rcu_read_unlock(); 581 582 spin_unlock(&mm->ioctx_lock); 582 583 583 584 table = kzalloc(sizeof(*table) + sizeof(struct kioctx *) * ··· 586 591 table->nr = new_nr; 587 592 588 593 spin_lock(&mm->ioctx_lock); 589 - rcu_read_lock(); 590 - old = rcu_dereference(mm->ioctx_table); 594 + old = rcu_dereference_raw(mm->ioctx_table); 591 595 592 596 if (!old) { 593 597 rcu_assign_pointer(mm->ioctx_table, table); ··· 733 739 734 740 735 741 spin_lock(&mm->ioctx_lock); 736 - rcu_read_lock(); 737 - table = rcu_dereference(mm->ioctx_table); 738 - 742 + table = rcu_dereference_raw(mm->ioctx_table); 739 743 WARN_ON(ctx != table->table[ctx->id]); 740 744 table->table[ctx->id] = NULL; 741 - rcu_read_unlock(); 742 745 spin_unlock(&mm->ioctx_lock); 743 746 744 747 /* percpu_ref_kill() will do the necessary call_rcu() */ ··· 784 793 */ 785 794 void exit_aio(struct mm_struct *mm) 786 795 { 787 - struct kioctx_table *table; 788 - struct kioctx *ctx; 789 - unsigned i = 0; 796 + struct kioctx_table *table = rcu_dereference_raw(mm->ioctx_table); 797 + int i; 790 798 791 - while (1) { 792 - rcu_read_lock(); 793 - table = rcu_dereference(mm->ioctx_table); 799 + if (!table) 800 + return; 794 801 795 - do { 796 - if (!table || i >= table->nr) { 797 - rcu_read_unlock(); 798 - rcu_assign_pointer(mm->ioctx_table, NULL); 799 - if (table) 800 - kfree(table); 801 - return; 802 - } 802 + for (i = 0; i < table->nr; ++i) { 803 + struct kioctx *ctx = table->table[i]; 803 804 804 - ctx = table->table[i++]; 805 - } while (!ctx); 806 - 807 - rcu_read_unlock(); 808 - 805 + if (!ctx) 806 + continue; 809 807 /* 810 - * We don't need to bother with munmap() here - 811 - * exit_mmap(mm) is coming and it'll unmap everything. 812 - * Since aio_free_ring() uses non-zero ->mmap_size 813 - * as indicator that it needs to unmap the area, 814 - * just set it to 0; aio_free_ring() is the only 815 - * place that uses ->mmap_size, so it's safe. 808 + * We don't need to bother with munmap() here - exit_mmap(mm) 809 + * is coming and it'll unmap everything. And we simply can't, 810 + * this is not necessarily our ->mm. 811 + * Since kill_ioctx() uses non-zero ->mmap_size as indicator 812 + * that it needs to unmap the area, just set it to 0. 816 813 */ 817 814 ctx->mmap_size = 0; 818 - 819 815 kill_ioctx(mm, ctx, NULL); 820 816 } 817 + 818 + RCU_INIT_POINTER(mm->ioctx_table, NULL); 819 + kfree(table); 821 820 } 822 821 823 822 static void put_reqs_available(struct kioctx *ctx, unsigned nr) ··· 815 834 struct kioctx_cpu *kcpu; 816 835 unsigned long flags; 817 836 818 - preempt_disable(); 819 - kcpu = this_cpu_ptr(ctx->cpu); 820 - 821 837 local_irq_save(flags); 838 + kcpu = this_cpu_ptr(ctx->cpu); 822 839 kcpu->reqs_available += nr; 823 840 824 841 while (kcpu->reqs_available >= ctx->req_batch * 2) { ··· 825 846 } 826 847 827 848 local_irq_restore(flags); 828 - preempt_enable(); 829 849 } 830 850 831 851 static bool get_reqs_available(struct kioctx *ctx) ··· 833 855 bool ret = false; 834 856 unsigned long flags; 835 857 836 - preempt_disable(); 837 - kcpu = this_cpu_ptr(ctx->cpu); 838 - 839 858 local_irq_save(flags); 859 + kcpu = this_cpu_ptr(ctx->cpu); 840 860 if (!kcpu->reqs_available) { 841 861 int old, avail = atomic_read(&ctx->reqs_available); 842 862 ··· 854 878 kcpu->reqs_available--; 855 879 out: 856 880 local_irq_restore(flags); 857 - preempt_enable(); 858 881 return ret; 859 882 } 860 883 ··· 1022 1047 } 1023 1048 EXPORT_SYMBOL(aio_complete); 1024 1049 1025 - /* aio_read_events 1050 + /* aio_read_events_ring 1026 1051 * Pull an event off of the ioctx's event ring. Returns the number of 1027 1052 * events fetched 1028 1053 */ ··· 1245 1270 if (compat) 1246 1271 ret = compat_rw_copy_check_uvector(rw, 1247 1272 (struct compat_iovec __user *)buf, 1248 - *nr_segs, 1, *iovec, iovec); 1273 + *nr_segs, UIO_FASTIOV, *iovec, iovec); 1249 1274 else 1250 1275 #endif 1251 1276 ret = rw_copy_check_uvector(rw, 1252 1277 (struct iovec __user *)buf, 1253 - *nr_segs, 1, *iovec, iovec); 1278 + *nr_segs, UIO_FASTIOV, *iovec, iovec); 1254 1279 if (ret < 0) 1255 1280 return ret; 1256 1281 ··· 1274 1299 } 1275 1300 1276 1301 /* 1277 - * aio_setup_iocb: 1278 - * Performs the initial checks and aio retry method 1279 - * setup for the kiocb at the time of io submission. 1302 + * aio_run_iocb: 1303 + * Performs the initial checks and io submission. 1280 1304 */ 1281 1305 static ssize_t aio_run_iocb(struct kiocb *req, unsigned opcode, 1282 1306 char __user *buf, bool compat) ··· 1287 1313 fmode_t mode; 1288 1314 aio_rw_op *rw_op; 1289 1315 rw_iter_op *iter_op; 1290 - struct iovec inline_vec, *iovec = &inline_vec; 1316 + struct iovec inline_vecs[UIO_FASTIOV], *iovec = inline_vecs; 1291 1317 struct iov_iter iter; 1292 1318 1293 1319 switch (opcode) { ··· 1322 1348 if (!ret) 1323 1349 ret = rw_verify_area(rw, file, &req->ki_pos, req->ki_nbytes); 1324 1350 if (ret < 0) { 1325 - if (iovec != &inline_vec) 1351 + if (iovec != inline_vecs) 1326 1352 kfree(iovec); 1327 1353 return ret; 1328 1354 } ··· 1369 1395 return -EINVAL; 1370 1396 } 1371 1397 1372 - if (iovec != &inline_vec) 1398 + if (iovec != inline_vecs) 1373 1399 kfree(iovec); 1374 1400 1375 1401 if (ret != -EIOCBQUEUED) {