diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2017-02-20 16:23:30 -0500 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2017-02-20 16:23:30 -0500 |
commit | 42e1b14b6e1455ece2ccbe474c25388d0230a590 (patch) | |
tree | 7f62d95f795a2ac5c183248dce39e75340ccfb76 | |
parent | 828cad8ea05d194d8a9452e0793261c2024c23a2 (diff) | |
parent | 95cb64c1fe61e70685a95f6260c8e9cd219fe08c (diff) |
Merge branch 'locking-core-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip
Pull locking updates from Ingo Molnar:
"The main changes in this cycle were:
- Implement wraparound-safe refcount_t and kref_t types based on
generic atomic primitives (Peter Zijlstra)
- Improve and fix the ww_mutex code (Nicolai Hähnle)
- Add self-tests to the ww_mutex code (Chris Wilson)
- Optimize percpu-rwsems with the 'rcuwait' mechanism (Davidlohr
Bueso)
- Micro-optimize the current-task logic all around the core kernel
(Davidlohr Bueso)
- Tidy up after recent optimizations: remove stale code and APIs,
clean up the code (Waiman Long)
- ... plus misc fixes, updates and cleanups"
* 'locking-core-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip: (50 commits)
fork: Fix task_struct alignment
locking/spinlock/debug: Remove spinlock lockup detection code
lockdep: Fix incorrect condition to print bug msgs for MAX_LOCKDEP_CHAIN_HLOCKS
lkdtm: Convert to refcount_t testing
kref: Implement 'struct kref' using refcount_t
refcount_t: Introduce a special purpose refcount type
sched/wake_q: Clarify queue reinit comment
sched/wait, rcuwait: Fix typo in comment
locking/mutex: Fix lockdep_assert_held() fail
locking/rtmutex: Flip unlikely() branch to likely() in __rt_mutex_slowlock()
locking/rwsem: Reinit wake_q after use
locking/rwsem: Remove unnecessary atomic_long_t casts
jump_labels: Move header guard #endif down where it belongs
locking/atomic, kref: Implement kref_put_lock()
locking/ww_mutex: Turn off __must_check for now
locking/atomic, kref: Avoid more abuse
locking/atomic, kref: Use kref_get_unless_zero() more
locking/atomic, kref: Kill kref_sub()
locking/atomic, kref: Add kref_read()
locking/atomic, kref: Add KREF_INIT()
...
116 files changed, 1864 insertions, 761 deletions
diff --git a/Documentation/locking/ww-mutex-design.txt b/Documentation/locking/ww-mutex-design.txt index 8a112dc304c3..34c3a1b50b9a 100644 --- a/Documentation/locking/ww-mutex-design.txt +++ b/Documentation/locking/ww-mutex-design.txt | |||
@@ -309,11 +309,15 @@ Design: | |||
309 | normal mutex locks, which are far more common. As such there is only a small | 309 | normal mutex locks, which are far more common. As such there is only a small |
310 | increase in code size if wait/wound mutexes are not used. | 310 | increase in code size if wait/wound mutexes are not used. |
311 | 311 | ||
312 | We maintain the following invariants for the wait list: | ||
313 | (1) Waiters with an acquire context are sorted by stamp order; waiters | ||
314 | without an acquire context are interspersed in FIFO order. | ||
315 | (2) Among waiters with contexts, only the first one can have other locks | ||
316 | acquired already (ctx->acquired > 0). Note that this waiter may come | ||
317 | after other waiters without contexts in the list. | ||
318 | |||
312 | In general, not much contention is expected. The locks are typically used to | 319 | In general, not much contention is expected. The locks are typically used to |
313 | serialize access to resources for devices. The only way to make wakeups | 320 | serialize access to resources for devices. |
314 | smarter would be at the cost of adding a field to struct mutex_waiter. This | ||
315 | would add overhead to all cases where normal mutexes are used, and | ||
316 | ww_mutexes are generally less performance sensitive. | ||
317 | 321 | ||
318 | Lockdep: | 322 | Lockdep: |
319 | Special care has been taken to warn for as many cases of api abuse | 323 | Special care has been taken to warn for as many cases of api abuse |
diff --git a/arch/um/drivers/random.c b/arch/um/drivers/random.c index 05523f14d7b2..57f03050c850 100644 --- a/arch/um/drivers/random.c +++ b/arch/um/drivers/random.c | |||
@@ -76,7 +76,7 @@ static ssize_t rng_dev_read (struct file *filp, char __user *buf, size_t size, | |||
76 | add_sigio_fd(random_fd); | 76 | add_sigio_fd(random_fd); |
77 | 77 | ||
78 | add_wait_queue(&host_read_wait, &wait); | 78 | add_wait_queue(&host_read_wait, &wait); |
79 | set_task_state(current, TASK_INTERRUPTIBLE); | 79 | set_current_state(TASK_INTERRUPTIBLE); |
80 | 80 | ||
81 | schedule(); | 81 | schedule(); |
82 | remove_wait_queue(&host_read_wait, &wait); | 82 | remove_wait_queue(&host_read_wait, &wait); |
diff --git a/arch/x86/include/asm/spinlock.h b/arch/x86/include/asm/spinlock.h index 921bea7a2708..6d391909e864 100644 --- a/arch/x86/include/asm/spinlock.h +++ b/arch/x86/include/asm/spinlock.h | |||
@@ -23,9 +23,6 @@ | |||
23 | /* How long a lock should spin before we consider blocking */ | 23 | /* How long a lock should spin before we consider blocking */ |
24 | #define SPIN_THRESHOLD (1 << 15) | 24 | #define SPIN_THRESHOLD (1 << 15) |
25 | 25 | ||
26 | extern struct static_key paravirt_ticketlocks_enabled; | ||
27 | static __always_inline bool static_key_false(struct static_key *key); | ||
28 | |||
29 | #include <asm/qspinlock.h> | 26 | #include <asm/qspinlock.h> |
30 | 27 | ||
31 | /* | 28 | /* |
diff --git a/arch/x86/kernel/jump_label.c b/arch/x86/kernel/jump_label.c index fc25f698d792..c37bd0f39c70 100644 --- a/arch/x86/kernel/jump_label.c +++ b/arch/x86/kernel/jump_label.c | |||
@@ -32,8 +32,7 @@ static void bug_at(unsigned char *ip, int line) | |||
32 | * Something went wrong. Crash the box, as something could be | 32 | * Something went wrong. Crash the box, as something could be |
33 | * corrupting the kernel. | 33 | * corrupting the kernel. |
34 | */ | 34 | */ |
35 | pr_warning("Unexpected op at %pS [%p] (%02x %02x %02x %02x %02x) %s:%d\n", | 35 | pr_crit("jump_label: Fatal kernel bug, unexpected op at %pS [%p] (%5ph) %d\n", ip, ip, ip, line); |
36 | ip, ip, ip[0], ip[1], ip[2], ip[3], ip[4], __FILE__, line); | ||
37 | BUG(); | 36 | BUG(); |
38 | } | 37 | } |
39 | 38 | ||
diff --git a/arch/x86/kernel/kvm.c b/arch/x86/kernel/kvm.c index 36bc66416021..099fcba4981d 100644 --- a/arch/x86/kernel/kvm.c +++ b/arch/x86/kernel/kvm.c | |||
@@ -620,18 +620,4 @@ void __init kvm_spinlock_init(void) | |||
620 | } | 620 | } |
621 | } | 621 | } |
622 | 622 | ||
623 | static __init int kvm_spinlock_init_jump(void) | ||
624 | { | ||
625 | if (!kvm_para_available()) | ||
626 | return 0; | ||
627 | if (!kvm_para_has_feature(KVM_FEATURE_PV_UNHALT)) | ||
628 | return 0; | ||
629 | |||
630 | static_key_slow_inc(¶virt_ticketlocks_enabled); | ||
631 | printk(KERN_INFO "KVM setup paravirtual spinlock\n"); | ||
632 | |||
633 | return 0; | ||
634 | } | ||
635 | early_initcall(kvm_spinlock_init_jump); | ||
636 | |||
637 | #endif /* CONFIG_PARAVIRT_SPINLOCKS */ | 623 | #endif /* CONFIG_PARAVIRT_SPINLOCKS */ |
diff --git a/arch/x86/kernel/paravirt-spinlocks.c b/arch/x86/kernel/paravirt-spinlocks.c index 6d4bf812af45..6259327f3454 100644 --- a/arch/x86/kernel/paravirt-spinlocks.c +++ b/arch/x86/kernel/paravirt-spinlocks.c | |||
@@ -42,6 +42,3 @@ struct pv_lock_ops pv_lock_ops = { | |||
42 | #endif /* SMP */ | 42 | #endif /* SMP */ |
43 | }; | 43 | }; |
44 | EXPORT_SYMBOL(pv_lock_ops); | 44 | EXPORT_SYMBOL(pv_lock_ops); |
45 | |||
46 | struct static_key paravirt_ticketlocks_enabled = STATIC_KEY_INIT_FALSE; | ||
47 | EXPORT_SYMBOL(paravirt_ticketlocks_enabled); | ||
diff --git a/arch/x86/xen/spinlock.c b/arch/x86/xen/spinlock.c index e8a9ea7d7a21..25a7c4302ce7 100644 --- a/arch/x86/xen/spinlock.c +++ b/arch/x86/xen/spinlock.c | |||
@@ -141,25 +141,6 @@ void __init xen_init_spinlocks(void) | |||
141 | pv_lock_ops.vcpu_is_preempted = PV_CALLEE_SAVE(xen_vcpu_stolen); | 141 | pv_lock_ops.vcpu_is_preempted = PV_CALLEE_SAVE(xen_vcpu_stolen); |
142 | } | 142 | } |
143 | 143 | ||
144 | /* | ||
145 | * While the jump_label init code needs to happend _after_ the jump labels are | ||
146 | * enabled and before SMP is started. Hence we use pre-SMP initcall level | ||
147 | * init. We cannot do it in xen_init_spinlocks as that is done before | ||
148 | * jump labels are activated. | ||
149 | */ | ||
150 | static __init int xen_init_spinlocks_jump(void) | ||
151 | { | ||
152 | if (!xen_pvspin) | ||
153 | return 0; | ||
154 | |||
155 | if (!xen_domain()) | ||
156 | return 0; | ||
157 | |||
158 | static_key_slow_inc(¶virt_ticketlocks_enabled); | ||
159 | return 0; | ||
160 | } | ||
161 | early_initcall(xen_init_spinlocks_jump); | ||
162 | |||
163 | static __init int xen_parse_nopvspin(char *arg) | 144 | static __init int xen_parse_nopvspin(char *arg) |
164 | { | 145 | { |
165 | xen_pvspin = false; | 146 | xen_pvspin = false; |
diff --git a/drivers/block/drbd/drbd_bitmap.c b/drivers/block/drbd/drbd_bitmap.c index ab62b81c2ca7..dece26f119d4 100644 --- a/drivers/block/drbd/drbd_bitmap.c +++ b/drivers/block/drbd/drbd_bitmap.c | |||
@@ -1070,7 +1070,7 @@ static int bm_rw(struct drbd_device *device, const unsigned int flags, unsigned | |||
1070 | .done = 0, | 1070 | .done = 0, |
1071 | .flags = flags, | 1071 | .flags = flags, |
1072 | .error = 0, | 1072 | .error = 0, |
1073 | .kref = { ATOMIC_INIT(2) }, | 1073 | .kref = KREF_INIT(2), |
1074 | }; | 1074 | }; |
1075 | 1075 | ||
1076 | if (!get_ldev_if_state(device, D_ATTACHING)) { /* put is in drbd_bm_aio_ctx_destroy() */ | 1076 | if (!get_ldev_if_state(device, D_ATTACHING)) { /* put is in drbd_bm_aio_ctx_destroy() */ |
diff --git a/drivers/block/drbd/drbd_main.c b/drivers/block/drbd/drbd_main.c index 83482721bc01..c3ff60c30dde 100644 --- a/drivers/block/drbd/drbd_main.c +++ b/drivers/block/drbd/drbd_main.c | |||
@@ -2948,7 +2948,6 @@ void drbd_delete_device(struct drbd_device *device) | |||
2948 | struct drbd_resource *resource = device->resource; | 2948 | struct drbd_resource *resource = device->resource; |
2949 | struct drbd_connection *connection; | 2949 | struct drbd_connection *connection; |
2950 | struct drbd_peer_device *peer_device; | 2950 | struct drbd_peer_device *peer_device; |
2951 | int refs = 3; | ||
2952 | 2951 | ||
2953 | /* move to free_peer_device() */ | 2952 | /* move to free_peer_device() */ |
2954 | for_each_peer_device(peer_device, device) | 2953 | for_each_peer_device(peer_device, device) |
@@ -2956,13 +2955,15 @@ void drbd_delete_device(struct drbd_device *device) | |||
2956 | drbd_debugfs_device_cleanup(device); | 2955 | drbd_debugfs_device_cleanup(device); |
2957 | for_each_connection(connection, resource) { | 2956 | for_each_connection(connection, resource) { |
2958 | idr_remove(&connection->peer_devices, device->vnr); | 2957 | idr_remove(&connection->peer_devices, device->vnr); |
2959 | refs++; | 2958 | kref_put(&device->kref, drbd_destroy_device); |
2960 | } | 2959 | } |
2961 | idr_remove(&resource->devices, device->vnr); | 2960 | idr_remove(&resource->devices, device->vnr); |
2961 | kref_put(&device->kref, drbd_destroy_device); | ||
2962 | idr_remove(&drbd_devices, device_to_minor(device)); | 2962 | idr_remove(&drbd_devices, device_to_minor(device)); |
2963 | kref_put(&device->kref, drbd_destroy_device); | ||
2963 | del_gendisk(device->vdisk); | 2964 | del_gendisk(device->vdisk); |
2964 | synchronize_rcu(); | 2965 | synchronize_rcu(); |
2965 | kref_sub(&device->kref, refs, drbd_destroy_device); | 2966 | kref_put(&device->kref, drbd_destroy_device); |
2966 | } | 2967 | } |
2967 | 2968 | ||
2968 | static int __init drbd_init(void) | 2969 | static int __init drbd_init(void) |
diff --git a/drivers/block/drbd/drbd_req.c b/drivers/block/drbd/drbd_req.c index de279fe4e4fd..b489ac2e9c44 100644 --- a/drivers/block/drbd/drbd_req.c +++ b/drivers/block/drbd/drbd_req.c | |||
@@ -421,7 +421,6 @@ static void mod_rq_state(struct drbd_request *req, struct bio_and_error *m, | |||
421 | struct drbd_peer_device *peer_device = first_peer_device(device); | 421 | struct drbd_peer_device *peer_device = first_peer_device(device); |
422 | unsigned s = req->rq_state; | 422 | unsigned s = req->rq_state; |
423 | int c_put = 0; | 423 | int c_put = 0; |
424 | int k_put = 0; | ||
425 | 424 | ||
426 | if (drbd_suspended(device) && !((s | clear) & RQ_COMPLETION_SUSP)) | 425 | if (drbd_suspended(device) && !((s | clear) & RQ_COMPLETION_SUSP)) |
427 | set |= RQ_COMPLETION_SUSP; | 426 | set |= RQ_COMPLETION_SUSP; |
@@ -437,6 +436,8 @@ static void mod_rq_state(struct drbd_request *req, struct bio_and_error *m, | |||
437 | 436 | ||
438 | /* intent: get references */ | 437 | /* intent: get references */ |
439 | 438 | ||
439 | kref_get(&req->kref); | ||
440 | |||
440 | if (!(s & RQ_LOCAL_PENDING) && (set & RQ_LOCAL_PENDING)) | 441 | if (!(s & RQ_LOCAL_PENDING) && (set & RQ_LOCAL_PENDING)) |
441 | atomic_inc(&req->completion_ref); | 442 | atomic_inc(&req->completion_ref); |
442 | 443 | ||
@@ -473,15 +474,12 @@ static void mod_rq_state(struct drbd_request *req, struct bio_and_error *m, | |||
473 | 474 | ||
474 | if (!(s & RQ_LOCAL_ABORTED) && (set & RQ_LOCAL_ABORTED)) { | 475 | if (!(s & RQ_LOCAL_ABORTED) && (set & RQ_LOCAL_ABORTED)) { |
475 | D_ASSERT(device, req->rq_state & RQ_LOCAL_PENDING); | 476 | D_ASSERT(device, req->rq_state & RQ_LOCAL_PENDING); |
476 | /* local completion may still come in later, | ||
477 | * we need to keep the req object around. */ | ||
478 | kref_get(&req->kref); | ||
479 | ++c_put; | 477 | ++c_put; |
480 | } | 478 | } |
481 | 479 | ||
482 | if ((s & RQ_LOCAL_PENDING) && (clear & RQ_LOCAL_PENDING)) { | 480 | if ((s & RQ_LOCAL_PENDING) && (clear & RQ_LOCAL_PENDING)) { |
483 | if (req->rq_state & RQ_LOCAL_ABORTED) | 481 | if (req->rq_state & RQ_LOCAL_ABORTED) |
484 | ++k_put; | 482 | kref_put(&req->kref, drbd_req_destroy); |
485 | else | 483 | else |
486 | ++c_put; | 484 | ++c_put; |
487 | list_del_init(&req->req_pending_local); | 485 | list_del_init(&req->req_pending_local); |
@@ -503,7 +501,7 @@ static void mod_rq_state(struct drbd_request *req, struct bio_and_error *m, | |||
503 | if (s & RQ_NET_SENT) | 501 | if (s & RQ_NET_SENT) |
504 | atomic_sub(req->i.size >> 9, &device->ap_in_flight); | 502 | atomic_sub(req->i.size >> 9, &device->ap_in_flight); |
505 | if (s & RQ_EXP_BARR_ACK) | 503 | if (s & RQ_EXP_BARR_ACK) |
506 | ++k_put; | 504 | kref_put(&req->kref, drbd_req_destroy); |
507 | req->net_done_jif = jiffies; | 505 | req->net_done_jif = jiffies; |
508 | 506 | ||
509 | /* in ahead/behind mode, or just in case, | 507 | /* in ahead/behind mode, or just in case, |
@@ -516,25 +514,16 @@ static void mod_rq_state(struct drbd_request *req, struct bio_and_error *m, | |||
516 | 514 | ||
517 | /* potentially complete and destroy */ | 515 | /* potentially complete and destroy */ |
518 | 516 | ||
519 | if (k_put || c_put) { | ||
520 | /* Completion does it's own kref_put. If we are going to | ||
521 | * kref_sub below, we need req to be still around then. */ | ||
522 | int at_least = k_put + !!c_put; | ||
523 | int refcount = atomic_read(&req->kref.refcount); | ||
524 | if (refcount < at_least) | ||
525 | drbd_err(device, | ||
526 | "mod_rq_state: Logic BUG: %x -> %x: refcount = %d, should be >= %d\n", | ||
527 | s, req->rq_state, refcount, at_least); | ||
528 | } | ||
529 | |||
530 | /* If we made progress, retry conflicting peer requests, if any. */ | 517 | /* If we made progress, retry conflicting peer requests, if any. */ |
531 | if (req->i.waiting) | 518 | if (req->i.waiting) |
532 | wake_up(&device->misc_wait); | 519 | wake_up(&device->misc_wait); |
533 | 520 | ||
534 | if (c_put) | 521 | if (c_put) { |
535 | k_put += drbd_req_put_completion_ref(req, m, c_put); | 522 | if (drbd_req_put_completion_ref(req, m, c_put)) |
536 | if (k_put) | 523 | kref_put(&req->kref, drbd_req_destroy); |
537 | kref_sub(&req->kref, k_put, drbd_req_destroy); | 524 | } else { |
525 | kref_put(&req->kref, drbd_req_destroy); | ||
526 | } | ||
538 | } | 527 | } |
539 | 528 | ||
540 | static void drbd_report_io_error(struct drbd_device *device, struct drbd_request *req) | 529 | static void drbd_report_io_error(struct drbd_device *device, struct drbd_request *req) |
diff --git a/drivers/block/rbd.c b/drivers/block/rbd.c index 36d2b9f4e836..436baa66f701 100644 --- a/drivers/block/rbd.c +++ b/drivers/block/rbd.c | |||
@@ -1535,7 +1535,7 @@ static bool obj_request_overlaps_parent(struct rbd_obj_request *obj_request) | |||
1535 | static void rbd_obj_request_get(struct rbd_obj_request *obj_request) | 1535 | static void rbd_obj_request_get(struct rbd_obj_request *obj_request) |
1536 | { | 1536 | { |
1537 | dout("%s: obj %p (was %d)\n", __func__, obj_request, | 1537 | dout("%s: obj %p (was %d)\n", __func__, obj_request, |
1538 | atomic_read(&obj_request->kref.refcount)); | 1538 | kref_read(&obj_request->kref)); |
1539 | kref_get(&obj_request->kref); | 1539 | kref_get(&obj_request->kref); |
1540 | } | 1540 | } |
1541 | 1541 | ||
@@ -1544,14 +1544,14 @@ static void rbd_obj_request_put(struct rbd_obj_request *obj_request) | |||
1544 | { | 1544 | { |
1545 | rbd_assert(obj_request != NULL); | 1545 | rbd_assert(obj_request != NULL); |
1546 | dout("%s: obj %p (was %d)\n", __func__, obj_request, | 1546 | dout("%s: obj %p (was %d)\n", __func__, obj_request, |
1547 | atomic_read(&obj_request->kref.refcount)); | 1547 | kref_read(&obj_request->kref)); |
1548 | kref_put(&obj_request->kref, rbd_obj_request_destroy); | 1548 | kref_put(&obj_request->kref, rbd_obj_request_destroy); |
1549 | } | 1549 | } |
1550 | 1550 | ||
1551 | static void rbd_img_request_get(struct rbd_img_request *img_request) | 1551 | static void rbd_img_request_get(struct rbd_img_request *img_request) |
1552 | { | 1552 | { |
1553 | dout("%s: img %p (was %d)\n", __func__, img_request, | 1553 | dout("%s: img %p (was %d)\n", __func__, img_request, |
1554 | atomic_read(&img_request->kref.refcount)); | 1554 | kref_read(&img_request->kref)); |
1555 | kref_get(&img_request->kref); | 1555 | kref_get(&img_request->kref); |
1556 | } | 1556 | } |
1557 | 1557 | ||
@@ -1562,7 +1562,7 @@ static void rbd_img_request_put(struct rbd_img_request *img_request) | |||
1562 | { | 1562 | { |
1563 | rbd_assert(img_request != NULL); | 1563 | rbd_assert(img_request != NULL); |
1564 | dout("%s: img %p (was %d)\n", __func__, img_request, | 1564 | dout("%s: img %p (was %d)\n", __func__, img_request, |
1565 | atomic_read(&img_request->kref.refcount)); | 1565 | kref_read(&img_request->kref)); |
1566 | if (img_request_child_test(img_request)) | 1566 | if (img_request_child_test(img_request)) |
1567 | kref_put(&img_request->kref, rbd_parent_request_destroy); | 1567 | kref_put(&img_request->kref, rbd_parent_request_destroy); |
1568 | else | 1568 | else |
diff --git a/drivers/block/virtio_blk.c b/drivers/block/virtio_blk.c index 10332c24f961..264c5eac12b0 100644 --- a/drivers/block/virtio_blk.c +++ b/drivers/block/virtio_blk.c | |||
@@ -770,7 +770,7 @@ static void virtblk_remove(struct virtio_device *vdev) | |||
770 | /* Stop all the virtqueues. */ | 770 | /* Stop all the virtqueues. */ |
771 | vdev->config->reset(vdev); | 771 | vdev->config->reset(vdev); |
772 | 772 | ||
773 | refc = atomic_read(&disk_to_dev(vblk->disk)->kobj.kref.refcount); | 773 | refc = kref_read(&disk_to_dev(vblk->disk)->kobj.kref); |
774 | put_disk(vblk->disk); | 774 | put_disk(vblk->disk); |
775 | vdev->config->del_vqs(vdev); | 775 | vdev->config->del_vqs(vdev); |
776 | kfree(vblk->vqs); | 776 | kfree(vblk->vqs); |
diff --git a/drivers/gpu/drm/drm_gem_cma_helper.c b/drivers/gpu/drm/drm_gem_cma_helper.c index 1d6c335584ec..33cd51632721 100644 --- a/drivers/gpu/drm/drm_gem_cma_helper.c +++ b/drivers/gpu/drm/drm_gem_cma_helper.c | |||
@@ -376,7 +376,7 @@ void drm_gem_cma_describe(struct drm_gem_cma_object *cma_obj, | |||
376 | off = drm_vma_node_start(&obj->vma_node); | 376 | off = drm_vma_node_start(&obj->vma_node); |
377 | 377 | ||
378 | seq_printf(m, "%2d (%2d) %08llx %pad %p %zu", | 378 | seq_printf(m, "%2d (%2d) %08llx %pad %p %zu", |
379 | obj->name, obj->refcount.refcount.counter, | 379 | obj->name, kref_read(&obj->refcount), |
380 | off, &cma_obj->paddr, cma_obj->vaddr, obj->size); | 380 | off, &cma_obj->paddr, cma_obj->vaddr, obj->size); |
381 | 381 | ||
382 | seq_printf(m, "\n"); | 382 | seq_printf(m, "\n"); |
diff --git a/drivers/gpu/drm/drm_info.c b/drivers/gpu/drm/drm_info.c index ffb2ab389d1d..6b68e9088436 100644 --- a/drivers/gpu/drm/drm_info.c +++ b/drivers/gpu/drm/drm_info.c | |||
@@ -118,7 +118,7 @@ static int drm_gem_one_name_info(int id, void *ptr, void *data) | |||
118 | seq_printf(m, "%6d %8zd %7d %8d\n", | 118 | seq_printf(m, "%6d %8zd %7d %8d\n", |
119 | obj->name, obj->size, | 119 | obj->name, obj->size, |
120 | obj->handle_count, | 120 | obj->handle_count, |
121 | atomic_read(&obj->refcount.refcount)); | 121 | kref_read(&obj->refcount)); |
122 | return 0; | 122 | return 0; |
123 | } | 123 | } |
124 | 124 | ||
diff --git a/drivers/gpu/drm/drm_mode_object.c b/drivers/gpu/drm/drm_mode_object.c index 9f17085b1fdd..c6885a4911c0 100644 --- a/drivers/gpu/drm/drm_mode_object.c +++ b/drivers/gpu/drm/drm_mode_object.c | |||
@@ -159,7 +159,7 @@ EXPORT_SYMBOL(drm_mode_object_find); | |||
159 | void drm_mode_object_unreference(struct drm_mode_object *obj) | 159 | void drm_mode_object_unreference(struct drm_mode_object *obj) |
160 | { | 160 | { |
161 | if (obj->free_cb) { | 161 | if (obj->free_cb) { |
162 | DRM_DEBUG("OBJ ID: %d (%d)\n", obj->id, atomic_read(&obj->refcount.refcount)); | 162 | DRM_DEBUG("OBJ ID: %d (%d)\n", obj->id, kref_read(&obj->refcount)); |
163 | kref_put(&obj->refcount, obj->free_cb); | 163 | kref_put(&obj->refcount, obj->free_cb); |
164 | } | 164 | } |
165 | } | 165 | } |
@@ -176,7 +176,7 @@ EXPORT_SYMBOL(drm_mode_object_unreference); | |||
176 | void drm_mode_object_reference(struct drm_mode_object *obj) | 176 | void drm_mode_object_reference(struct drm_mode_object *obj) |
177 | { | 177 | { |
178 | if (obj->free_cb) { | 178 | if (obj->free_cb) { |
179 | DRM_DEBUG("OBJ ID: %d (%d)\n", obj->id, atomic_read(&obj->refcount.refcount)); | 179 | DRM_DEBUG("OBJ ID: %d (%d)\n", obj->id, kref_read(&obj->refcount)); |
180 | kref_get(&obj->refcount); | 180 | kref_get(&obj->refcount); |
181 | } | 181 | } |
182 | } | 182 | } |
diff --git a/drivers/gpu/drm/etnaviv/etnaviv_gem.c b/drivers/gpu/drm/etnaviv/etnaviv_gem.c index 114dddbd297b..aa6e35ddc87f 100644 --- a/drivers/gpu/drm/etnaviv/etnaviv_gem.c +++ b/drivers/gpu/drm/etnaviv/etnaviv_gem.c | |||
@@ -486,7 +486,7 @@ static void etnaviv_gem_describe(struct drm_gem_object *obj, struct seq_file *m) | |||
486 | 486 | ||
487 | seq_printf(m, "%08x: %c %2d (%2d) %08lx %p %zd\n", | 487 | seq_printf(m, "%08x: %c %2d (%2d) %08lx %p %zd\n", |
488 | etnaviv_obj->flags, is_active(etnaviv_obj) ? 'A' : 'I', | 488 | etnaviv_obj->flags, is_active(etnaviv_obj) ? 'A' : 'I', |
489 | obj->name, obj->refcount.refcount.counter, | 489 | obj->name, kref_read(&obj->refcount), |
490 | off, etnaviv_obj->vaddr, obj->size); | 490 | off, etnaviv_obj->vaddr, obj->size); |
491 | 491 | ||
492 | rcu_read_lock(); | 492 | rcu_read_lock(); |
diff --git a/drivers/gpu/drm/i915/i915_gem_object.h b/drivers/gpu/drm/i915/i915_gem_object.h index 6a368de9d81e..ecfefb9d42e4 100644 --- a/drivers/gpu/drm/i915/i915_gem_object.h +++ b/drivers/gpu/drm/i915/i915_gem_object.h | |||
@@ -256,7 +256,7 @@ extern void drm_gem_object_unreference_unlocked(struct drm_gem_object *); | |||
256 | static inline bool | 256 | static inline bool |
257 | i915_gem_object_is_dead(const struct drm_i915_gem_object *obj) | 257 | i915_gem_object_is_dead(const struct drm_i915_gem_object *obj) |
258 | { | 258 | { |
259 | return atomic_read(&obj->base.refcount.refcount) == 0; | 259 | return kref_read(&obj->base.refcount) == 0; |
260 | } | 260 | } |
261 | 261 | ||
262 | static inline bool | 262 | static inline bool |
diff --git a/drivers/gpu/drm/msm/msm_gem.c b/drivers/gpu/drm/msm/msm_gem.c index 8098677a3916..1974ccb781de 100644 --- a/drivers/gpu/drm/msm/msm_gem.c +++ b/drivers/gpu/drm/msm/msm_gem.c | |||
@@ -642,7 +642,7 @@ void msm_gem_describe(struct drm_gem_object *obj, struct seq_file *m) | |||
642 | 642 | ||
643 | seq_printf(m, "%08x: %c %2d (%2d) %08llx %p\t", | 643 | seq_printf(m, "%08x: %c %2d (%2d) %08llx %p\t", |
644 | msm_obj->flags, is_active(msm_obj) ? 'A' : 'I', | 644 | msm_obj->flags, is_active(msm_obj) ? 'A' : 'I', |
645 | obj->name, obj->refcount.refcount.counter, | 645 | obj->name, kref_read(&obj->refcount), |
646 | off, msm_obj->vaddr); | 646 | off, msm_obj->vaddr); |
647 | 647 | ||
648 | for (id = 0; id < priv->num_aspaces; id++) | 648 | for (id = 0; id < priv->num_aspaces; id++) |
diff --git a/drivers/gpu/drm/nouveau/nouveau_fence.c b/drivers/gpu/drm/nouveau/nouveau_fence.c index a6126c93f215..88ee60d1b907 100644 --- a/drivers/gpu/drm/nouveau/nouveau_fence.c +++ b/drivers/gpu/drm/nouveau/nouveau_fence.c | |||
@@ -527,7 +527,7 @@ static bool nouveau_fence_no_signaling(struct dma_fence *f) | |||
527 | * caller should have a reference on the fence, | 527 | * caller should have a reference on the fence, |
528 | * else fence could get freed here | 528 | * else fence could get freed here |
529 | */ | 529 | */ |
530 | WARN_ON(atomic_read(&fence->base.refcount.refcount) <= 1); | 530 | WARN_ON(kref_read(&fence->base.refcount) <= 1); |
531 | 531 | ||
532 | /* | 532 | /* |
533 | * This needs uevents to work correctly, but dma_fence_add_callback relies on | 533 | * This needs uevents to work correctly, but dma_fence_add_callback relies on |
diff --git a/drivers/gpu/drm/omapdrm/omap_gem.c b/drivers/gpu/drm/omapdrm/omap_gem.c index 4a90c690f09e..74a9968df421 100644 --- a/drivers/gpu/drm/omapdrm/omap_gem.c +++ b/drivers/gpu/drm/omapdrm/omap_gem.c | |||
@@ -1033,7 +1033,7 @@ void omap_gem_describe(struct drm_gem_object *obj, struct seq_file *m) | |||
1033 | off = drm_vma_node_start(&obj->vma_node); | 1033 | off = drm_vma_node_start(&obj->vma_node); |
1034 | 1034 | ||
1035 | seq_printf(m, "%08x: %2d (%2d) %08llx %pad (%2d) %p %4d", | 1035 | seq_printf(m, "%08x: %2d (%2d) %08llx %pad (%2d) %p %4d", |
1036 | omap_obj->flags, obj->name, obj->refcount.refcount.counter, | 1036 | omap_obj->flags, obj->name, kref_read(&obj->refcount), |
1037 | off, &omap_obj->paddr, omap_obj->paddr_cnt, | 1037 | off, &omap_obj->paddr, omap_obj->paddr_cnt, |
1038 | omap_obj->vaddr, omap_obj->roll); | 1038 | omap_obj->vaddr, omap_obj->roll); |
1039 | 1039 | ||
diff --git a/drivers/gpu/drm/ttm/ttm_bo.c b/drivers/gpu/drm/ttm/ttm_bo.c index d5063618efa7..ffc6cb55c78c 100644 --- a/drivers/gpu/drm/ttm/ttm_bo.c +++ b/drivers/gpu/drm/ttm/ttm_bo.c | |||
@@ -140,8 +140,8 @@ static void ttm_bo_release_list(struct kref *list_kref) | |||
140 | struct ttm_bo_device *bdev = bo->bdev; | 140 | struct ttm_bo_device *bdev = bo->bdev; |
141 | size_t acc_size = bo->acc_size; | 141 | size_t acc_size = bo->acc_size; |
142 | 142 | ||
143 | BUG_ON(atomic_read(&bo->list_kref.refcount)); | 143 | BUG_ON(kref_read(&bo->list_kref)); |
144 | BUG_ON(atomic_read(&bo->kref.refcount)); | 144 | BUG_ON(kref_read(&bo->kref)); |
145 | BUG_ON(atomic_read(&bo->cpu_writers)); | 145 | BUG_ON(atomic_read(&bo->cpu_writers)); |
146 | BUG_ON(bo->mem.mm_node != NULL); | 146 | BUG_ON(bo->mem.mm_node != NULL); |
147 | BUG_ON(!list_empty(&bo->lru)); | 147 | BUG_ON(!list_empty(&bo->lru)); |
@@ -181,61 +181,46 @@ void ttm_bo_add_to_lru(struct ttm_buffer_object *bo) | |||
181 | } | 181 | } |
182 | EXPORT_SYMBOL(ttm_bo_add_to_lru); | 182 | EXPORT_SYMBOL(ttm_bo_add_to_lru); |
183 | 183 | ||
184 | int ttm_bo_del_from_lru(struct ttm_buffer_object *bo) | 184 | static void ttm_bo_ref_bug(struct kref *list_kref) |
185 | { | ||
186 | BUG(); | ||
187 | } | ||
188 | |||
189 | void ttm_bo_del_from_lru(struct ttm_buffer_object *bo) | ||
185 | { | 190 | { |
186 | struct ttm_bo_device *bdev = bo->bdev; | 191 | struct ttm_bo_device *bdev = bo->bdev; |
187 | int put_count = 0; | ||
188 | 192 | ||
189 | if (bdev->driver->lru_removal) | 193 | if (bdev->driver->lru_removal) |
190 | bdev->driver->lru_removal(bo); | 194 | bdev->driver->lru_removal(bo); |
191 | 195 | ||
192 | if (!list_empty(&bo->swap)) { | 196 | if (!list_empty(&bo->swap)) { |
193 | list_del_init(&bo->swap); | 197 | list_del_init(&bo->swap); |
194 | ++put_count; | 198 | kref_put(&bo->list_kref, ttm_bo_ref_bug); |
195 | } | 199 | } |
196 | if (!list_empty(&bo->lru)) { | 200 | if (!list_empty(&bo->lru)) { |
197 | list_del_init(&bo->lru); | 201 | list_del_init(&bo->lru); |
198 | ++put_count; | 202 | kref_put(&bo->list_kref, ttm_bo_ref_bug); |
199 | } | 203 | } |
200 | |||
201 | return put_count; | ||
202 | } | ||
203 | |||
204 | static void ttm_bo_ref_bug(struct kref *list_kref) | ||
205 | { | ||
206 | BUG(); | ||
207 | } | ||
208 | |||
209 | void ttm_bo_list_ref_sub(struct ttm_buffer_object *bo, int count, | ||
210 | bool never_free) | ||
211 | { | ||
212 | kref_sub(&bo->list_kref, count, | ||
213 | (never_free) ? ttm_bo_ref_bug : ttm_bo_release_list); | ||
214 | } | 204 | } |
215 | 205 | ||
216 | void ttm_bo_del_sub_from_lru(struct ttm_buffer_object *bo) | 206 | void ttm_bo_del_sub_from_lru(struct ttm_buffer_object *bo) |
217 | { | 207 | { |
218 | int put_count; | ||
219 | |||
220 | spin_lock(&bo->glob->lru_lock); | 208 | spin_lock(&bo->glob->lru_lock); |
221 | put_count = ttm_bo_del_from_lru(bo); | 209 | ttm_bo_del_from_lru(bo); |
222 | spin_unlock(&bo->glob->lru_lock); | 210 | spin_unlock(&bo->glob->lru_lock); |
223 | ttm_bo_list_ref_sub(bo, put_count, true); | ||
224 | } | 211 | } |
225 | EXPORT_SYMBOL(ttm_bo_del_sub_from_lru); | 212 | EXPORT_SYMBOL(ttm_bo_del_sub_from_lru); |
226 | 213 | ||
227 | void ttm_bo_move_to_lru_tail(struct ttm_buffer_object *bo) | 214 | void ttm_bo_move_to_lru_tail(struct ttm_buffer_object *bo) |
228 | { | 215 | { |
229 | struct ttm_bo_device *bdev = bo->bdev; | 216 | struct ttm_bo_device *bdev = bo->bdev; |
230 | int put_count = 0; | ||
231 | 217 | ||
232 | lockdep_assert_held(&bo->resv->lock.base); | 218 | lockdep_assert_held(&bo->resv->lock.base); |
233 | 219 | ||
234 | if (bdev->driver->lru_removal) | 220 | if (bdev->driver->lru_removal) |
235 | bdev->driver->lru_removal(bo); | 221 | bdev->driver->lru_removal(bo); |
236 | 222 | ||
237 | put_count = ttm_bo_del_from_lru(bo); | 223 | ttm_bo_del_from_lru(bo); |
238 | ttm_bo_list_ref_sub(bo, put_count, true); | ||
239 | ttm_bo_add_to_lru(bo); | 224 | ttm_bo_add_to_lru(bo); |
240 | } | 225 | } |
241 | EXPORT_SYMBOL(ttm_bo_move_to_lru_tail); | 226 | EXPORT_SYMBOL(ttm_bo_move_to_lru_tail); |
@@ -447,7 +432,6 @@ static void ttm_bo_cleanup_refs_or_queue(struct ttm_buffer_object *bo) | |||
447 | { | 432 | { |
448 | struct ttm_bo_device *bdev = bo->bdev; | 433 | struct ttm_bo_device *bdev = bo->bdev; |
449 | struct ttm_bo_global *glob = bo->glob; | 434 | struct ttm_bo_global *glob = bo->glob; |
450 | int put_count; | ||
451 | int ret; | 435 | int ret; |
452 | 436 | ||
453 | spin_lock(&glob->lru_lock); | 437 | spin_lock(&glob->lru_lock); |
@@ -455,13 +439,10 @@ static void ttm_bo_cleanup_refs_or_queue(struct ttm_buffer_object *bo) | |||
455 | 439 | ||
456 | if (!ret) { | 440 | if (!ret) { |
457 | if (!ttm_bo_wait(bo, false, true)) { | 441 | if (!ttm_bo_wait(bo, false, true)) { |
458 | put_count = ttm_bo_del_from_lru(bo); | 442 | ttm_bo_del_from_lru(bo); |
459 | |||
460 | spin_unlock(&glob->lru_lock); | 443 | spin_unlock(&glob->lru_lock); |
461 | ttm_bo_cleanup_memtype_use(bo); | 444 | ttm_bo_cleanup_memtype_use(bo); |
462 | 445 | ||
463 | ttm_bo_list_ref_sub(bo, put_count, true); | ||
464 | |||
465 | return; | 446 | return; |
466 | } else | 447 | } else |
467 | ttm_bo_flush_all_fences(bo); | 448 | ttm_bo_flush_all_fences(bo); |
@@ -504,7 +485,6 @@ static int ttm_bo_cleanup_refs_and_unlock(struct ttm_buffer_object *bo, | |||
504 | bool no_wait_gpu) | 485 | bool no_wait_gpu) |
505 | { | 486 | { |
506 | struct ttm_bo_global *glob = bo->glob; | 487 | struct ttm_bo_global *glob = bo->glob; |
507 | int put_count; | ||
508 | int ret; | 488 | int ret; |
509 | 489 | ||
510 | ret = ttm_bo_wait(bo, false, true); | 490 | ret = ttm_bo_wait(bo, false, true); |
@@ -554,15 +534,13 @@ static int ttm_bo_cleanup_refs_and_unlock(struct ttm_buffer_object *bo, | |||
554 | return ret; | 534 | return ret; |
555 | } | 535 | } |
556 | 536 | ||
557 | put_count = ttm_bo_del_from_lru(bo); | 537 | ttm_bo_del_from_lru(bo); |
558 | list_del_init(&bo->ddestroy); | 538 | list_del_init(&bo->ddestroy); |
559 | ++put_count; | 539 | kref_put(&bo->list_kref, ttm_bo_ref_bug); |
560 | 540 | ||
561 | spin_unlock(&glob->lru_lock); | 541 | spin_unlock(&glob->lru_lock); |
562 | ttm_bo_cleanup_memtype_use(bo); | 542 | ttm_bo_cleanup_memtype_use(bo); |
563 | 543 | ||
564 | ttm_bo_list_ref_sub(bo, put_count, true); | ||
565 | |||
566 | return 0; | 544 | return 0; |
567 | } | 545 | } |
568 | 546 | ||
@@ -740,7 +718,7 @@ static int ttm_mem_evict_first(struct ttm_bo_device *bdev, | |||
740 | struct ttm_bo_global *glob = bdev->glob; | 718 | struct ttm_bo_global *glob = bdev->glob; |
741 | struct ttm_mem_type_manager *man = &bdev->man[mem_type]; | 719 | struct ttm_mem_type_manager *man = &bdev->man[mem_type]; |
742 | struct ttm_buffer_object *bo; | 720 | struct ttm_buffer_object *bo; |
743 | int ret = -EBUSY, put_count; | 721 | int ret = -EBUSY; |
744 | 722 | ||
745 | spin_lock(&glob->lru_lock); | 723 | spin_lock(&glob->lru_lock); |
746 | list_for_each_entry(bo, &man->lru, lru) { | 724 | list_for_each_entry(bo, &man->lru, lru) { |
@@ -771,13 +749,11 @@ static int ttm_mem_evict_first(struct ttm_bo_device *bdev, | |||
771 | return ret; | 749 | return ret; |
772 | } | 750 | } |
773 | 751 | ||
774 | put_count = ttm_bo_del_from_lru(bo); | 752 | ttm_bo_del_from_lru(bo); |
775 | spin_unlock(&glob->lru_lock); | 753 | spin_unlock(&glob->lru_lock); |
776 | 754 | ||
777 | BUG_ON(ret != 0); | 755 | BUG_ON(ret != 0); |
778 | 756 | ||
779 | ttm_bo_list_ref_sub(bo, put_count, true); | ||
780 | |||
781 | ret = ttm_bo_evict(bo, interruptible, no_wait_gpu); | 757 | ret = ttm_bo_evict(bo, interruptible, no_wait_gpu); |
782 | ttm_bo_unreserve(bo); | 758 | ttm_bo_unreserve(bo); |
783 | 759 | ||
@@ -1669,7 +1645,6 @@ static int ttm_bo_swapout(struct ttm_mem_shrink *shrink) | |||
1669 | container_of(shrink, struct ttm_bo_global, shrink); | 1645 | container_of(shrink, struct ttm_bo_global, shrink); |
1670 | struct ttm_buffer_object *bo; | 1646 | struct ttm_buffer_object *bo; |
1671 | int ret = -EBUSY; | 1647 | int ret = -EBUSY; |
1672 | int put_count; | ||
1673 | uint32_t swap_placement = (TTM_PL_FLAG_CACHED | TTM_PL_FLAG_SYSTEM); | 1648 | uint32_t swap_placement = (TTM_PL_FLAG_CACHED | TTM_PL_FLAG_SYSTEM); |
1674 | 1649 | ||
1675 | spin_lock(&glob->lru_lock); | 1650 | spin_lock(&glob->lru_lock); |
@@ -1692,11 +1667,9 @@ static int ttm_bo_swapout(struct ttm_mem_shrink *shrink) | |||
1692 | return ret; | 1667 | return ret; |
1693 | } | 1668 | } |
1694 | 1669 | ||
1695 | put_count = ttm_bo_del_from_lru(bo); | 1670 | ttm_bo_del_from_lru(bo); |
1696 | spin_unlock(&glob->lru_lock); | 1671 | spin_unlock(&glob->lru_lock); |
1697 | 1672 | ||
1698 | ttm_bo_list_ref_sub(bo, put_count, true); | ||
1699 | |||
1700 | /** | 1673 | /** |
1701 | * Move to system cached | 1674 | * Move to system cached |
1702 | */ | 1675 | */ |
diff --git a/drivers/gpu/drm/ttm/ttm_execbuf_util.c b/drivers/gpu/drm/ttm/ttm_execbuf_util.c index d35bc491e8de..5e1bcabffef5 100644 --- a/drivers/gpu/drm/ttm/ttm_execbuf_util.c +++ b/drivers/gpu/drm/ttm/ttm_execbuf_util.c | |||
@@ -48,9 +48,7 @@ static void ttm_eu_del_from_lru_locked(struct list_head *list) | |||
48 | 48 | ||
49 | list_for_each_entry(entry, list, head) { | 49 | list_for_each_entry(entry, list, head) { |
50 | struct ttm_buffer_object *bo = entry->bo; | 50 | struct ttm_buffer_object *bo = entry->bo; |
51 | unsigned put_count = ttm_bo_del_from_lru(bo); | 51 | ttm_bo_del_from_lru(bo); |
52 | |||
53 | ttm_bo_list_ref_sub(bo, put_count, true); | ||
54 | } | 52 | } |
55 | } | 53 | } |
56 | 54 | ||
diff --git a/drivers/gpu/drm/ttm/ttm_object.c b/drivers/gpu/drm/ttm/ttm_object.c index 4f5fa8d65fe9..fdb451e3ec01 100644 --- a/drivers/gpu/drm/ttm/ttm_object.c +++ b/drivers/gpu/drm/ttm/ttm_object.c | |||
@@ -304,7 +304,7 @@ bool ttm_ref_object_exists(struct ttm_object_file *tfile, | |||
304 | * Verify that the ref->obj pointer was actually valid! | 304 | * Verify that the ref->obj pointer was actually valid! |
305 | */ | 305 | */ |
306 | rmb(); | 306 | rmb(); |
307 | if (unlikely(atomic_read(&ref->kref.refcount) == 0)) | 307 | if (unlikely(kref_read(&ref->kref) == 0)) |
308 | goto out_false; | 308 | goto out_false; |
309 | 309 | ||
310 | rcu_read_unlock(); | 310 | rcu_read_unlock(); |
diff --git a/drivers/infiniband/hw/cxgb3/iwch_cm.h b/drivers/infiniband/hw/cxgb3/iwch_cm.h index b9efadfffb4f..e66e75921797 100644 --- a/drivers/infiniband/hw/cxgb3/iwch_cm.h +++ b/drivers/infiniband/hw/cxgb3/iwch_cm.h | |||
@@ -55,14 +55,14 @@ | |||
55 | 55 | ||
56 | #define put_ep(ep) { \ | 56 | #define put_ep(ep) { \ |
57 | PDBG("put_ep (via %s:%u) ep %p refcnt %d\n", __func__, __LINE__, \ | 57 | PDBG("put_ep (via %s:%u) ep %p refcnt %d\n", __func__, __LINE__, \ |
58 | ep, atomic_read(&((ep)->kref.refcount))); \ | 58 | ep, kref_read(&((ep)->kref))); \ |
59 | WARN_ON(atomic_read(&((ep)->kref.refcount)) < 1); \ | 59 | WARN_ON(kref_read(&((ep)->kref)) < 1); \ |
60 | kref_put(&((ep)->kref), __free_ep); \ | 60 | kref_put(&((ep)->kref), __free_ep); \ |
61 | } | 61 | } |
62 | 62 | ||
63 | #define get_ep(ep) { \ | 63 | #define get_ep(ep) { \ |
64 | PDBG("get_ep (via %s:%u) ep %p, refcnt %d\n", __func__, __LINE__, \ | 64 | PDBG("get_ep (via %s:%u) ep %p, refcnt %d\n", __func__, __LINE__, \ |
65 | ep, atomic_read(&((ep)->kref.refcount))); \ | 65 | ep, kref_read(&((ep)->kref))); \ |
66 | kref_get(&((ep)->kref)); \ | 66 | kref_get(&((ep)->kref)); \ |
67 | } | 67 | } |
68 | 68 | ||
diff --git a/drivers/infiniband/hw/cxgb3/iwch_qp.c b/drivers/infiniband/hw/cxgb3/iwch_qp.c index d939980a708f..a9194db7f9b8 100644 --- a/drivers/infiniband/hw/cxgb3/iwch_qp.c +++ b/drivers/infiniband/hw/cxgb3/iwch_qp.c | |||
@@ -961,7 +961,7 @@ int iwch_modify_qp(struct iwch_dev *rhp, struct iwch_qp *qhp, | |||
961 | case IWCH_QP_STATE_RTS: | 961 | case IWCH_QP_STATE_RTS: |
962 | switch (attrs->next_state) { | 962 | switch (attrs->next_state) { |
963 | case IWCH_QP_STATE_CLOSING: | 963 | case IWCH_QP_STATE_CLOSING: |
964 | BUG_ON(atomic_read(&qhp->ep->com.kref.refcount) < 2); | 964 | BUG_ON(kref_read(&qhp->ep->com.kref) < 2); |
965 | qhp->attr.state = IWCH_QP_STATE_CLOSING; | 965 | qhp->attr.state = IWCH_QP_STATE_CLOSING; |
966 | if (!internal) { | 966 | if (!internal) { |
967 | abort=0; | 967 | abort=0; |
diff --git a/drivers/infiniband/hw/cxgb4/iw_cxgb4.h b/drivers/infiniband/hw/cxgb4/iw_cxgb4.h index 8cd4d054a87e..d19662f635b1 100644 --- a/drivers/infiniband/hw/cxgb4/iw_cxgb4.h +++ b/drivers/infiniband/hw/cxgb4/iw_cxgb4.h | |||
@@ -672,14 +672,14 @@ enum c4iw_mmid_state { | |||
672 | 672 | ||
673 | #define c4iw_put_ep(ep) { \ | 673 | #define c4iw_put_ep(ep) { \ |
674 | PDBG("put_ep (via %s:%u) ep %p refcnt %d\n", __func__, __LINE__, \ | 674 | PDBG("put_ep (via %s:%u) ep %p refcnt %d\n", __func__, __LINE__, \ |
675 | ep, atomic_read(&((ep)->kref.refcount))); \ | 675 | ep, kref_read(&((ep)->kref))); \ |
676 | WARN_ON(atomic_read(&((ep)->kref.refcount)) < 1); \ | 676 | WARN_ON(kref_read(&((ep)->kref)) < 1); \ |
677 | kref_put(&((ep)->kref), _c4iw_free_ep); \ | 677 | kref_put(&((ep)->kref), _c4iw_free_ep); \ |
678 | } | 678 | } |
679 | 679 | ||
680 | #define c4iw_get_ep(ep) { \ | 680 | #define c4iw_get_ep(ep) { \ |
681 | PDBG("get_ep (via %s:%u) ep %p, refcnt %d\n", __func__, __LINE__, \ | 681 | PDBG("get_ep (via %s:%u) ep %p, refcnt %d\n", __func__, __LINE__, \ |
682 | ep, atomic_read(&((ep)->kref.refcount))); \ | 682 | ep, kref_read(&((ep)->kref))); \ |
683 | kref_get(&((ep)->kref)); \ | 683 | kref_get(&((ep)->kref)); \ |
684 | } | 684 | } |
685 | void _c4iw_free_ep(struct kref *kref); | 685 | void _c4iw_free_ep(struct kref *kref); |
diff --git a/drivers/infiniband/hw/cxgb4/qp.c b/drivers/infiniband/hw/cxgb4/qp.c index 04c1c382dedb..d4fd2f5c8326 100644 --- a/drivers/infiniband/hw/cxgb4/qp.c +++ b/drivers/infiniband/hw/cxgb4/qp.c | |||
@@ -1580,7 +1580,7 @@ int c4iw_modify_qp(struct c4iw_dev *rhp, struct c4iw_qp *qhp, | |||
1580 | case C4IW_QP_STATE_RTS: | 1580 | case C4IW_QP_STATE_RTS: |
1581 | switch (attrs->next_state) { | 1581 | switch (attrs->next_state) { |
1582 | case C4IW_QP_STATE_CLOSING: | 1582 | case C4IW_QP_STATE_CLOSING: |
1583 | BUG_ON(atomic_read(&qhp->ep->com.kref.refcount) < 2); | 1583 | BUG_ON(kref_read(&qhp->ep->com.kref) < 2); |
1584 | t4_set_wq_in_error(&qhp->wq); | 1584 | t4_set_wq_in_error(&qhp->wq); |
1585 | set_state(qhp, C4IW_QP_STATE_CLOSING); | 1585 | set_state(qhp, C4IW_QP_STATE_CLOSING); |
1586 | ep = qhp->ep; | 1586 | ep = qhp->ep; |
diff --git a/drivers/infiniband/hw/usnic/usnic_ib_sysfs.c b/drivers/infiniband/hw/usnic/usnic_ib_sysfs.c index 80ef3f8998c8..04443242e258 100644 --- a/drivers/infiniband/hw/usnic/usnic_ib_sysfs.c +++ b/drivers/infiniband/hw/usnic/usnic_ib_sysfs.c | |||
@@ -80,7 +80,7 @@ usnic_ib_show_config(struct device *device, struct device_attribute *attr, | |||
80 | left = PAGE_SIZE; | 80 | left = PAGE_SIZE; |
81 | 81 | ||
82 | mutex_lock(&us_ibdev->usdev_lock); | 82 | mutex_lock(&us_ibdev->usdev_lock); |
83 | if (atomic_read(&us_ibdev->vf_cnt.refcount) > 0) { | 83 | if (kref_read(&us_ibdev->vf_cnt) > 0) { |
84 | char *busname; | 84 | char *busname; |
85 | 85 | ||
86 | /* | 86 | /* |
@@ -99,7 +99,7 @@ usnic_ib_show_config(struct device *device, struct device_attribute *attr, | |||
99 | PCI_FUNC(us_ibdev->pdev->devfn), | 99 | PCI_FUNC(us_ibdev->pdev->devfn), |
100 | netdev_name(us_ibdev->netdev), | 100 | netdev_name(us_ibdev->netdev), |
101 | us_ibdev->ufdev->mac, | 101 | us_ibdev->ufdev->mac, |
102 | atomic_read(&us_ibdev->vf_cnt.refcount)); | 102 | kref_read(&us_ibdev->vf_cnt)); |
103 | UPDATE_PTR_LEFT(n, ptr, left); | 103 | UPDATE_PTR_LEFT(n, ptr, left); |
104 | 104 | ||
105 | for (res_type = USNIC_VNIC_RES_TYPE_EOL; | 105 | for (res_type = USNIC_VNIC_RES_TYPE_EOL; |
@@ -147,7 +147,7 @@ usnic_ib_show_max_vf(struct device *device, struct device_attribute *attr, | |||
147 | us_ibdev = container_of(device, struct usnic_ib_dev, ib_dev.dev); | 147 | us_ibdev = container_of(device, struct usnic_ib_dev, ib_dev.dev); |
148 | 148 | ||
149 | return scnprintf(buf, PAGE_SIZE, "%u\n", | 149 | return scnprintf(buf, PAGE_SIZE, "%u\n", |
150 | atomic_read(&us_ibdev->vf_cnt.refcount)); | 150 | kref_read(&us_ibdev->vf_cnt)); |
151 | } | 151 | } |
152 | 152 | ||
153 | static ssize_t | 153 | static ssize_t |
diff --git a/drivers/infiniband/hw/usnic/usnic_ib_verbs.c b/drivers/infiniband/hw/usnic/usnic_ib_verbs.c index 74819a7951e2..69df8e353123 100644 --- a/drivers/infiniband/hw/usnic/usnic_ib_verbs.c +++ b/drivers/infiniband/hw/usnic/usnic_ib_verbs.c | |||
@@ -291,11 +291,11 @@ int usnic_ib_query_device(struct ib_device *ibdev, | |||
291 | qp_per_vf = max(us_ibdev->vf_res_cnt[USNIC_VNIC_RES_TYPE_WQ], | 291 | qp_per_vf = max(us_ibdev->vf_res_cnt[USNIC_VNIC_RES_TYPE_WQ], |
292 | us_ibdev->vf_res_cnt[USNIC_VNIC_RES_TYPE_RQ]); | 292 | us_ibdev->vf_res_cnt[USNIC_VNIC_RES_TYPE_RQ]); |
293 | props->max_qp = qp_per_vf * | 293 | props->max_qp = qp_per_vf * |
294 | atomic_read(&us_ibdev->vf_cnt.refcount); | 294 | kref_read(&us_ibdev->vf_cnt); |
295 | props->device_cap_flags = IB_DEVICE_PORT_ACTIVE_EVENT | | 295 | props->device_cap_flags = IB_DEVICE_PORT_ACTIVE_EVENT | |
296 | IB_DEVICE_SYS_IMAGE_GUID | IB_DEVICE_BLOCK_MULTICAST_LOOPBACK; | 296 | IB_DEVICE_SYS_IMAGE_GUID | IB_DEVICE_BLOCK_MULTICAST_LOOPBACK; |
297 | props->max_cq = us_ibdev->vf_res_cnt[USNIC_VNIC_RES_TYPE_CQ] * | 297 | props->max_cq = us_ibdev->vf_res_cnt[USNIC_VNIC_RES_TYPE_CQ] * |
298 | atomic_read(&us_ibdev->vf_cnt.refcount); | 298 | kref_read(&us_ibdev->vf_cnt); |
299 | props->max_pd = USNIC_UIOM_MAX_PD_CNT; | 299 | props->max_pd = USNIC_UIOM_MAX_PD_CNT; |
300 | props->max_mr = USNIC_UIOM_MAX_MR_CNT; | 300 | props->max_mr = USNIC_UIOM_MAX_MR_CNT; |
301 | props->local_ca_ack_delay = 0; | 301 | props->local_ca_ack_delay = 0; |
diff --git a/drivers/md/dm-bufio.c b/drivers/md/dm-bufio.c index 84d2f0e4c754..d36d427a9efb 100644 --- a/drivers/md/dm-bufio.c +++ b/drivers/md/dm-bufio.c | |||
@@ -794,7 +794,7 @@ static void __wait_for_free_buffer(struct dm_bufio_client *c) | |||
794 | DECLARE_WAITQUEUE(wait, current); | 794 | DECLARE_WAITQUEUE(wait, current); |
795 | 795 | ||
796 | add_wait_queue(&c->free_buffer_wait, &wait); | 796 | add_wait_queue(&c->free_buffer_wait, &wait); |
797 | set_task_state(current, TASK_UNINTERRUPTIBLE); | 797 | set_current_state(TASK_UNINTERRUPTIBLE); |
798 | dm_bufio_unlock(c); | 798 | dm_bufio_unlock(c); |
799 | 799 | ||
800 | io_schedule(); | 800 | io_schedule(); |
diff --git a/drivers/md/dm-crypt.c b/drivers/md/dm-crypt.c index 8a9f742d8ed7..1cb2ca9dfae3 100644 --- a/drivers/md/dm-crypt.c +++ b/drivers/md/dm-crypt.c | |||
@@ -1210,14 +1210,14 @@ continue_locked: | |||
1210 | spin_unlock_irq(&cc->write_thread_wait.lock); | 1210 | spin_unlock_irq(&cc->write_thread_wait.lock); |
1211 | 1211 | ||
1212 | if (unlikely(kthread_should_stop())) { | 1212 | if (unlikely(kthread_should_stop())) { |
1213 | set_task_state(current, TASK_RUNNING); | 1213 | set_current_state(TASK_RUNNING); |
1214 | remove_wait_queue(&cc->write_thread_wait, &wait); | 1214 | remove_wait_queue(&cc->write_thread_wait, &wait); |
1215 | break; | 1215 | break; |
1216 | } | 1216 | } |
1217 | 1217 | ||
1218 | schedule(); | 1218 | schedule(); |
1219 | 1219 | ||
1220 | set_task_state(current, TASK_RUNNING); | 1220 | set_current_state(TASK_RUNNING); |
1221 | spin_lock_irq(&cc->write_thread_wait.lock); | 1221 | spin_lock_irq(&cc->write_thread_wait.lock); |
1222 | __remove_wait_queue(&cc->write_thread_wait, &wait); | 1222 | __remove_wait_queue(&cc->write_thread_wait, &wait); |
1223 | goto continue_locked; | 1223 | goto continue_locked; |
diff --git a/drivers/md/persistent-data/dm-block-manager.c b/drivers/md/persistent-data/dm-block-manager.c index a6dde7cab458..758d90cc2733 100644 --- a/drivers/md/persistent-data/dm-block-manager.c +++ b/drivers/md/persistent-data/dm-block-manager.c | |||
@@ -120,7 +120,7 @@ static int __check_holder(struct block_lock *lock) | |||
120 | static void __wait(struct waiter *w) | 120 | static void __wait(struct waiter *w) |
121 | { | 121 | { |
122 | for (;;) { | 122 | for (;;) { |
123 | set_task_state(current, TASK_UNINTERRUPTIBLE); | 123 | set_current_state(TASK_UNINTERRUPTIBLE); |
124 | 124 | ||
125 | if (!w->task) | 125 | if (!w->task) |
126 | break; | 126 | break; |
@@ -128,7 +128,7 @@ static void __wait(struct waiter *w) | |||
128 | schedule(); | 128 | schedule(); |
129 | } | 129 | } |
130 | 130 | ||
131 | set_task_state(current, TASK_RUNNING); | 131 | set_current_state(TASK_RUNNING); |
132 | } | 132 | } |
133 | 133 | ||
134 | static void __wake_waiter(struct waiter *w) | 134 | static void __wake_waiter(struct waiter *w) |
diff --git a/drivers/misc/genwqe/card_dev.c b/drivers/misc/genwqe/card_dev.c index 7f1b282d7d96..cb290b8ca0c8 100644 --- a/drivers/misc/genwqe/card_dev.c +++ b/drivers/misc/genwqe/card_dev.c | |||
@@ -1396,7 +1396,7 @@ int genwqe_device_remove(struct genwqe_dev *cd) | |||
1396 | * application which will decrease this reference from | 1396 | * application which will decrease this reference from |
1397 | * 1/unused to 0/illegal and not from 2/used 1/empty. | 1397 | * 1/unused to 0/illegal and not from 2/used 1/empty. |
1398 | */ | 1398 | */ |
1399 | rc = atomic_read(&cd->cdev_genwqe.kobj.kref.refcount); | 1399 | rc = kref_read(&cd->cdev_genwqe.kobj.kref); |
1400 | if (rc != 1) { | 1400 | if (rc != 1) { |
1401 | dev_err(&pci_dev->dev, | 1401 | dev_err(&pci_dev->dev, |
1402 | "[%s] err: cdev_genwqe...refcount=%d\n", __func__, rc); | 1402 | "[%s] err: cdev_genwqe...refcount=%d\n", __func__, rc); |
diff --git a/drivers/misc/lkdtm.h b/drivers/misc/lkdtm.h index cfa1039c62e7..67d27be60405 100644 --- a/drivers/misc/lkdtm.h +++ b/drivers/misc/lkdtm.h | |||
@@ -19,8 +19,12 @@ void lkdtm_SOFTLOCKUP(void); | |||
19 | void lkdtm_HARDLOCKUP(void); | 19 | void lkdtm_HARDLOCKUP(void); |
20 | void lkdtm_SPINLOCKUP(void); | 20 | void lkdtm_SPINLOCKUP(void); |
21 | void lkdtm_HUNG_TASK(void); | 21 | void lkdtm_HUNG_TASK(void); |
22 | void lkdtm_ATOMIC_UNDERFLOW(void); | 22 | void lkdtm_REFCOUNT_SATURATE_INC(void); |
23 | void lkdtm_ATOMIC_OVERFLOW(void); | 23 | void lkdtm_REFCOUNT_SATURATE_ADD(void); |
24 | void lkdtm_REFCOUNT_ZERO_DEC(void); | ||
25 | void lkdtm_REFCOUNT_ZERO_INC(void); | ||
26 | void lkdtm_REFCOUNT_ZERO_SUB(void); | ||
27 | void lkdtm_REFCOUNT_ZERO_ADD(void); | ||
24 | void lkdtm_CORRUPT_LIST_ADD(void); | 28 | void lkdtm_CORRUPT_LIST_ADD(void); |
25 | void lkdtm_CORRUPT_LIST_DEL(void); | 29 | void lkdtm_CORRUPT_LIST_DEL(void); |
26 | 30 | ||
diff --git a/drivers/misc/lkdtm_bugs.c b/drivers/misc/lkdtm_bugs.c index 91edd0b55e5c..cba0837aee2e 100644 --- a/drivers/misc/lkdtm_bugs.c +++ b/drivers/misc/lkdtm_bugs.c | |||
@@ -6,6 +6,7 @@ | |||
6 | */ | 6 | */ |
7 | #include "lkdtm.h" | 7 | #include "lkdtm.h" |
8 | #include <linux/list.h> | 8 | #include <linux/list.h> |
9 | #include <linux/refcount.h> | ||
9 | #include <linux/sched.h> | 10 | #include <linux/sched.h> |
10 | 11 | ||
11 | struct lkdtm_list { | 12 | struct lkdtm_list { |
@@ -129,28 +130,86 @@ void lkdtm_HUNG_TASK(void) | |||
129 | schedule(); | 130 | schedule(); |
130 | } | 131 | } |
131 | 132 | ||
132 | void lkdtm_ATOMIC_UNDERFLOW(void) | 133 | void lkdtm_REFCOUNT_SATURATE_INC(void) |
133 | { | 134 | { |
134 | atomic_t under = ATOMIC_INIT(INT_MIN); | 135 | refcount_t over = REFCOUNT_INIT(UINT_MAX - 1); |
135 | 136 | ||
136 | pr_info("attempting good atomic increment\n"); | 137 | pr_info("attempting good refcount decrement\n"); |
137 | atomic_inc(&under); | 138 | refcount_dec(&over); |
138 | atomic_dec(&under); | 139 | refcount_inc(&over); |
139 | 140 | ||
140 | pr_info("attempting bad atomic underflow\n"); | 141 | pr_info("attempting bad refcount inc overflow\n"); |
141 | atomic_dec(&under); | 142 | refcount_inc(&over); |
143 | refcount_inc(&over); | ||
144 | if (refcount_read(&over) == UINT_MAX) | ||
145 | pr_err("Correctly stayed saturated, but no BUG?!\n"); | ||
146 | else | ||
147 | pr_err("Fail: refcount wrapped\n"); | ||
148 | } | ||
149 | |||
150 | void lkdtm_REFCOUNT_SATURATE_ADD(void) | ||
151 | { | ||
152 | refcount_t over = REFCOUNT_INIT(UINT_MAX - 1); | ||
153 | |||
154 | pr_info("attempting good refcount decrement\n"); | ||
155 | refcount_dec(&over); | ||
156 | refcount_inc(&over); | ||
157 | |||
158 | pr_info("attempting bad refcount add overflow\n"); | ||
159 | refcount_add(2, &over); | ||
160 | if (refcount_read(&over) == UINT_MAX) | ||
161 | pr_err("Correctly stayed saturated, but no BUG?!\n"); | ||
162 | else | ||
163 | pr_err("Fail: refcount wrapped\n"); | ||
164 | } | ||
165 | |||
166 | void lkdtm_REFCOUNT_ZERO_DEC(void) | ||
167 | { | ||
168 | refcount_t zero = REFCOUNT_INIT(1); | ||
169 | |||
170 | pr_info("attempting bad refcount decrement to zero\n"); | ||
171 | refcount_dec(&zero); | ||
172 | if (refcount_read(&zero) == 0) | ||
173 | pr_err("Stayed at zero, but no BUG?!\n"); | ||
174 | else | ||
175 | pr_err("Fail: refcount went crazy\n"); | ||
142 | } | 176 | } |
143 | 177 | ||
144 | void lkdtm_ATOMIC_OVERFLOW(void) | 178 | void lkdtm_REFCOUNT_ZERO_SUB(void) |
145 | { | 179 | { |
146 | atomic_t over = ATOMIC_INIT(INT_MAX); | 180 | refcount_t zero = REFCOUNT_INIT(1); |
181 | |||
182 | pr_info("attempting bad refcount subtract past zero\n"); | ||
183 | if (!refcount_sub_and_test(2, &zero)) | ||
184 | pr_info("wrap attempt was noticed\n"); | ||
185 | if (refcount_read(&zero) == 1) | ||
186 | pr_err("Correctly stayed above 0, but no BUG?!\n"); | ||
187 | else | ||
188 | pr_err("Fail: refcount wrapped\n"); | ||
189 | } | ||
147 | 190 | ||
148 | pr_info("attempting good atomic decrement\n"); | 191 | void lkdtm_REFCOUNT_ZERO_INC(void) |
149 | atomic_dec(&over); | 192 | { |
150 | atomic_inc(&over); | 193 | refcount_t zero = REFCOUNT_INIT(0); |
151 | 194 | ||
152 | pr_info("attempting bad atomic overflow\n"); | 195 | pr_info("attempting bad refcount increment from zero\n"); |
153 | atomic_inc(&over); | 196 | refcount_inc(&zero); |
197 | if (refcount_read(&zero) == 0) | ||
198 | pr_err("Stayed at zero, but no BUG?!\n"); | ||
199 | else | ||
200 | pr_err("Fail: refcount went past zero\n"); | ||
201 | } | ||
202 | |||
203 | void lkdtm_REFCOUNT_ZERO_ADD(void) | ||
204 | { | ||
205 | refcount_t zero = REFCOUNT_INIT(0); | ||
206 | |||
207 | pr_info("attempting bad refcount addition from zero\n"); | ||
208 | refcount_add(2, &zero); | ||
209 | if (refcount_read(&zero) == 0) | ||
210 | pr_err("Stayed at zero, but no BUG?!\n"); | ||
211 | else | ||
212 | pr_err("Fail: refcount went past zero\n"); | ||
154 | } | 213 | } |
155 | 214 | ||
156 | void lkdtm_CORRUPT_LIST_ADD(void) | 215 | void lkdtm_CORRUPT_LIST_ADD(void) |
diff --git a/drivers/misc/lkdtm_core.c b/drivers/misc/lkdtm_core.c index 7eeb71a75549..16e4cf110930 100644 --- a/drivers/misc/lkdtm_core.c +++ b/drivers/misc/lkdtm_core.c | |||
@@ -220,8 +220,12 @@ struct crashtype crashtypes[] = { | |||
220 | CRASHTYPE(WRITE_RO), | 220 | CRASHTYPE(WRITE_RO), |
221 | CRASHTYPE(WRITE_RO_AFTER_INIT), | 221 | CRASHTYPE(WRITE_RO_AFTER_INIT), |
222 | CRASHTYPE(WRITE_KERN), | 222 | CRASHTYPE(WRITE_KERN), |
223 | CRASHTYPE(ATOMIC_UNDERFLOW), | 223 | CRASHTYPE(REFCOUNT_SATURATE_INC), |
224 | CRASHTYPE(ATOMIC_OVERFLOW), | 224 | CRASHTYPE(REFCOUNT_SATURATE_ADD), |
225 | CRASHTYPE(REFCOUNT_ZERO_DEC), | ||
226 | CRASHTYPE(REFCOUNT_ZERO_INC), | ||
227 | CRASHTYPE(REFCOUNT_ZERO_SUB), | ||
228 | CRASHTYPE(REFCOUNT_ZERO_ADD), | ||
225 | CRASHTYPE(USERCOPY_HEAP_SIZE_TO), | 229 | CRASHTYPE(USERCOPY_HEAP_SIZE_TO), |
226 | CRASHTYPE(USERCOPY_HEAP_SIZE_FROM), | 230 | CRASHTYPE(USERCOPY_HEAP_SIZE_FROM), |
227 | CRASHTYPE(USERCOPY_HEAP_FLAG_TO), | 231 | CRASHTYPE(USERCOPY_HEAP_FLAG_TO), |
diff --git a/drivers/misc/mei/debugfs.c b/drivers/misc/mei/debugfs.c index c6217a4993ad..a617aa5a3ad8 100644 --- a/drivers/misc/mei/debugfs.c +++ b/drivers/misc/mei/debugfs.c | |||
@@ -67,7 +67,7 @@ static ssize_t mei_dbgfs_read_meclients(struct file *fp, char __user *ubuf, | |||
67 | me_cl->props.max_number_of_connections, | 67 | me_cl->props.max_number_of_connections, |
68 | me_cl->props.max_msg_length, | 68 | me_cl->props.max_msg_length, |
69 | me_cl->props.single_recv_buf, | 69 | me_cl->props.single_recv_buf, |
70 | atomic_read(&me_cl->refcnt.refcount)); | 70 | kref_read(&me_cl->refcnt)); |
71 | 71 | ||
72 | mei_me_cl_put(me_cl); | 72 | mei_me_cl_put(me_cl); |
73 | } | 73 | } |
diff --git a/drivers/pci/hotplug/pnv_php.c b/drivers/pci/hotplug/pnv_php.c index 56efaf72d08e..d2961ef39a3a 100644 --- a/drivers/pci/hotplug/pnv_php.c +++ b/drivers/pci/hotplug/pnv_php.c | |||
@@ -155,7 +155,7 @@ static void pnv_php_detach_device_nodes(struct device_node *parent) | |||
155 | pnv_php_detach_device_nodes(dn); | 155 | pnv_php_detach_device_nodes(dn); |
156 | 156 | ||
157 | of_node_put(dn); | 157 | of_node_put(dn); |
158 | refcount = atomic_read(&dn->kobj.kref.refcount); | 158 | refcount = kref_read(&dn->kobj.kref); |
159 | if (refcount != 1) | 159 | if (refcount != 1) |
160 | pr_warn("Invalid refcount %d on <%s>\n", | 160 | pr_warn("Invalid refcount %d on <%s>\n", |
161 | refcount, of_node_full_name(dn)); | 161 | refcount, of_node_full_name(dn)); |
diff --git a/drivers/pci/slot.c b/drivers/pci/slot.c index 429d34c348b9..e42909524dee 100644 --- a/drivers/pci/slot.c +++ b/drivers/pci/slot.c | |||
@@ -345,7 +345,7 @@ EXPORT_SYMBOL_GPL(pci_create_slot); | |||
345 | void pci_destroy_slot(struct pci_slot *slot) | 345 | void pci_destroy_slot(struct pci_slot *slot) |
346 | { | 346 | { |
347 | dev_dbg(&slot->bus->dev, "dev %02x, dec refcount to %d\n", | 347 | dev_dbg(&slot->bus->dev, "dev %02x, dec refcount to %d\n", |
348 | slot->number, atomic_read(&slot->kobj.kref.refcount) - 1); | 348 | slot->number, kref_read(&slot->kobj.kref) - 1); |
349 | 349 | ||
350 | mutex_lock(&pci_slot_mutex); | 350 | mutex_lock(&pci_slot_mutex); |
351 | kobject_put(&slot->kobj); | 351 | kobject_put(&slot->kobj); |
diff --git a/drivers/scsi/bnx2fc/bnx2fc_io.c b/drivers/scsi/bnx2fc/bnx2fc_io.c index f501095f91ac..898461b146cc 100644 --- a/drivers/scsi/bnx2fc/bnx2fc_io.c +++ b/drivers/scsi/bnx2fc/bnx2fc_io.c | |||
@@ -74,7 +74,7 @@ static void bnx2fc_cmd_timeout(struct work_struct *work) | |||
74 | &io_req->req_flags)) { | 74 | &io_req->req_flags)) { |
75 | /* Handle internally generated ABTS timeout */ | 75 | /* Handle internally generated ABTS timeout */ |
76 | BNX2FC_IO_DBG(io_req, "ABTS timed out refcnt = %d\n", | 76 | BNX2FC_IO_DBG(io_req, "ABTS timed out refcnt = %d\n", |
77 | io_req->refcount.refcount.counter); | 77 | kref_read(&io_req->refcount)); |
78 | if (!(test_and_set_bit(BNX2FC_FLAG_ABTS_DONE, | 78 | if (!(test_and_set_bit(BNX2FC_FLAG_ABTS_DONE, |
79 | &io_req->req_flags))) { | 79 | &io_req->req_flags))) { |
80 | /* | 80 | /* |
@@ -1141,7 +1141,7 @@ int bnx2fc_eh_abort(struct scsi_cmnd *sc_cmd) | |||
1141 | return SUCCESS; | 1141 | return SUCCESS; |
1142 | } | 1142 | } |
1143 | BNX2FC_IO_DBG(io_req, "eh_abort - refcnt = %d\n", | 1143 | BNX2FC_IO_DBG(io_req, "eh_abort - refcnt = %d\n", |
1144 | io_req->refcount.refcount.counter); | 1144 | kref_read(&io_req->refcount)); |
1145 | 1145 | ||
1146 | /* Hold IO request across abort processing */ | 1146 | /* Hold IO request across abort processing */ |
1147 | kref_get(&io_req->refcount); | 1147 | kref_get(&io_req->refcount); |
@@ -1299,7 +1299,7 @@ void bnx2fc_process_cleanup_compl(struct bnx2fc_cmd *io_req, | |||
1299 | { | 1299 | { |
1300 | BNX2FC_IO_DBG(io_req, "Entered process_cleanup_compl " | 1300 | BNX2FC_IO_DBG(io_req, "Entered process_cleanup_compl " |
1301 | "refcnt = %d, cmd_type = %d\n", | 1301 | "refcnt = %d, cmd_type = %d\n", |
1302 | io_req->refcount.refcount.counter, io_req->cmd_type); | 1302 | kref_read(&io_req->refcount), io_req->cmd_type); |
1303 | bnx2fc_scsi_done(io_req, DID_ERROR); | 1303 | bnx2fc_scsi_done(io_req, DID_ERROR); |
1304 | kref_put(&io_req->refcount, bnx2fc_cmd_release); | 1304 | kref_put(&io_req->refcount, bnx2fc_cmd_release); |
1305 | if (io_req->wait_for_comp) | 1305 | if (io_req->wait_for_comp) |
@@ -1318,7 +1318,7 @@ void bnx2fc_process_abts_compl(struct bnx2fc_cmd *io_req, | |||
1318 | BNX2FC_IO_DBG(io_req, "Entered process_abts_compl xid = 0x%x" | 1318 | BNX2FC_IO_DBG(io_req, "Entered process_abts_compl xid = 0x%x" |
1319 | "refcnt = %d, cmd_type = %d\n", | 1319 | "refcnt = %d, cmd_type = %d\n", |
1320 | io_req->xid, | 1320 | io_req->xid, |
1321 | io_req->refcount.refcount.counter, io_req->cmd_type); | 1321 | kref_read(&io_req->refcount), io_req->cmd_type); |
1322 | 1322 | ||
1323 | if (test_and_set_bit(BNX2FC_FLAG_ABTS_DONE, | 1323 | if (test_and_set_bit(BNX2FC_FLAG_ABTS_DONE, |
1324 | &io_req->req_flags)) { | 1324 | &io_req->req_flags)) { |
diff --git a/drivers/scsi/cxgbi/libcxgbi.h b/drivers/scsi/cxgbi/libcxgbi.h index 95ba99044c3e..18e0ea83d361 100644 --- a/drivers/scsi/cxgbi/libcxgbi.h +++ b/drivers/scsi/cxgbi/libcxgbi.h | |||
@@ -301,7 +301,7 @@ static inline void __cxgbi_sock_put(const char *fn, struct cxgbi_sock *csk) | |||
301 | { | 301 | { |
302 | log_debug(1 << CXGBI_DBG_SOCK, | 302 | log_debug(1 << CXGBI_DBG_SOCK, |
303 | "%s, put csk 0x%p, ref %u-1.\n", | 303 | "%s, put csk 0x%p, ref %u-1.\n", |
304 | fn, csk, atomic_read(&csk->refcnt.refcount)); | 304 | fn, csk, kref_read(&csk->refcnt)); |
305 | kref_put(&csk->refcnt, cxgbi_sock_free); | 305 | kref_put(&csk->refcnt, cxgbi_sock_free); |
306 | } | 306 | } |
307 | #define cxgbi_sock_put(csk) __cxgbi_sock_put(__func__, csk) | 307 | #define cxgbi_sock_put(csk) __cxgbi_sock_put(__func__, csk) |
@@ -310,7 +310,7 @@ static inline void __cxgbi_sock_get(const char *fn, struct cxgbi_sock *csk) | |||
310 | { | 310 | { |
311 | log_debug(1 << CXGBI_DBG_SOCK, | 311 | log_debug(1 << CXGBI_DBG_SOCK, |
312 | "%s, get csk 0x%p, ref %u+1.\n", | 312 | "%s, get csk 0x%p, ref %u+1.\n", |
313 | fn, csk, atomic_read(&csk->refcnt.refcount)); | 313 | fn, csk, kref_read(&csk->refcnt)); |
314 | kref_get(&csk->refcnt); | 314 | kref_get(&csk->refcnt); |
315 | } | 315 | } |
316 | #define cxgbi_sock_get(csk) __cxgbi_sock_get(__func__, csk) | 316 | #define cxgbi_sock_get(csk) __cxgbi_sock_get(__func__, csk) |
diff --git a/drivers/scsi/lpfc/lpfc_debugfs.c b/drivers/scsi/lpfc/lpfc_debugfs.c index a63542bac153..caa7a7b0ec53 100644 --- a/drivers/scsi/lpfc/lpfc_debugfs.c +++ b/drivers/scsi/lpfc/lpfc_debugfs.c | |||
@@ -607,7 +607,7 @@ lpfc_debugfs_nodelist_data(struct lpfc_vport *vport, char *buf, int size) | |||
607 | len += snprintf(buf+len, size-len, "usgmap:%x ", | 607 | len += snprintf(buf+len, size-len, "usgmap:%x ", |
608 | ndlp->nlp_usg_map); | 608 | ndlp->nlp_usg_map); |
609 | len += snprintf(buf+len, size-len, "refcnt:%x", | 609 | len += snprintf(buf+len, size-len, "refcnt:%x", |
610 | atomic_read(&ndlp->kref.refcount)); | 610 | kref_read(&ndlp->kref)); |
611 | len += snprintf(buf+len, size-len, "\n"); | 611 | len += snprintf(buf+len, size-len, "\n"); |
612 | } | 612 | } |
613 | spin_unlock_irq(shost->host_lock); | 613 | spin_unlock_irq(shost->host_lock); |
diff --git a/drivers/scsi/lpfc/lpfc_els.c b/drivers/scsi/lpfc/lpfc_els.c index 7b6bd8ed0d0b..63bef4566548 100644 --- a/drivers/scsi/lpfc/lpfc_els.c +++ b/drivers/scsi/lpfc/lpfc_els.c | |||
@@ -3690,7 +3690,7 @@ lpfc_mbx_cmpl_dflt_rpi(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmb) | |||
3690 | lpfc_printf_vlog(ndlp->vport, KERN_INFO, LOG_NODE, | 3690 | lpfc_printf_vlog(ndlp->vport, KERN_INFO, LOG_NODE, |
3691 | "0006 rpi%x DID:%x flg:%x %d map:%x %p\n", | 3691 | "0006 rpi%x DID:%x flg:%x %d map:%x %p\n", |
3692 | ndlp->nlp_rpi, ndlp->nlp_DID, ndlp->nlp_flag, | 3692 | ndlp->nlp_rpi, ndlp->nlp_DID, ndlp->nlp_flag, |
3693 | atomic_read(&ndlp->kref.refcount), | 3693 | kref_read(&ndlp->kref), |
3694 | ndlp->nlp_usg_map, ndlp); | 3694 | ndlp->nlp_usg_map, ndlp); |
3695 | if (NLP_CHK_NODE_ACT(ndlp)) { | 3695 | if (NLP_CHK_NODE_ACT(ndlp)) { |
3696 | lpfc_nlp_put(ndlp); | 3696 | lpfc_nlp_put(ndlp); |
diff --git a/drivers/scsi/lpfc/lpfc_hbadisc.c b/drivers/scsi/lpfc/lpfc_hbadisc.c index ed223937798a..82047070cdc9 100644 --- a/drivers/scsi/lpfc/lpfc_hbadisc.c +++ b/drivers/scsi/lpfc/lpfc_hbadisc.c | |||
@@ -3440,7 +3440,7 @@ lpfc_mbx_cmpl_reg_login(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmb) | |||
3440 | lpfc_printf_vlog(vport, KERN_INFO, LOG_SLI, | 3440 | lpfc_printf_vlog(vport, KERN_INFO, LOG_SLI, |
3441 | "0002 rpi:%x DID:%x flg:%x %d map:%x %p\n", | 3441 | "0002 rpi:%x DID:%x flg:%x %d map:%x %p\n", |
3442 | ndlp->nlp_rpi, ndlp->nlp_DID, ndlp->nlp_flag, | 3442 | ndlp->nlp_rpi, ndlp->nlp_DID, ndlp->nlp_flag, |
3443 | atomic_read(&ndlp->kref.refcount), | 3443 | kref_read(&ndlp->kref), |
3444 | ndlp->nlp_usg_map, ndlp); | 3444 | ndlp->nlp_usg_map, ndlp); |
3445 | if (ndlp->nlp_flag & NLP_REG_LOGIN_SEND) | 3445 | if (ndlp->nlp_flag & NLP_REG_LOGIN_SEND) |
3446 | ndlp->nlp_flag &= ~NLP_REG_LOGIN_SEND; | 3446 | ndlp->nlp_flag &= ~NLP_REG_LOGIN_SEND; |
@@ -3861,7 +3861,7 @@ out: | |||
3861 | lpfc_printf_vlog(vport, KERN_INFO, LOG_SLI, | 3861 | lpfc_printf_vlog(vport, KERN_INFO, LOG_SLI, |
3862 | "0003 rpi:%x DID:%x flg:%x %d map%x %p\n", | 3862 | "0003 rpi:%x DID:%x flg:%x %d map%x %p\n", |
3863 | ndlp->nlp_rpi, ndlp->nlp_DID, ndlp->nlp_flag, | 3863 | ndlp->nlp_rpi, ndlp->nlp_DID, ndlp->nlp_flag, |
3864 | atomic_read(&ndlp->kref.refcount), | 3864 | kref_read(&ndlp->kref), |
3865 | ndlp->nlp_usg_map, ndlp); | 3865 | ndlp->nlp_usg_map, ndlp); |
3866 | 3866 | ||
3867 | if (vport->port_state < LPFC_VPORT_READY) { | 3867 | if (vport->port_state < LPFC_VPORT_READY) { |
@@ -4238,7 +4238,7 @@ lpfc_enable_node(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp, | |||
4238 | "0277 lpfc_enable_node: ndlp:x%p " | 4238 | "0277 lpfc_enable_node: ndlp:x%p " |
4239 | "usgmap:x%x refcnt:%d\n", | 4239 | "usgmap:x%x refcnt:%d\n", |
4240 | (void *)ndlp, ndlp->nlp_usg_map, | 4240 | (void *)ndlp, ndlp->nlp_usg_map, |
4241 | atomic_read(&ndlp->kref.refcount)); | 4241 | kref_read(&ndlp->kref)); |
4242 | return NULL; | 4242 | return NULL; |
4243 | } | 4243 | } |
4244 | /* The ndlp should not already be in active mode */ | 4244 | /* The ndlp should not already be in active mode */ |
@@ -4248,7 +4248,7 @@ lpfc_enable_node(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp, | |||
4248 | "0278 lpfc_enable_node: ndlp:x%p " | 4248 | "0278 lpfc_enable_node: ndlp:x%p " |
4249 | "usgmap:x%x refcnt:%d\n", | 4249 | "usgmap:x%x refcnt:%d\n", |
4250 | (void *)ndlp, ndlp->nlp_usg_map, | 4250 | (void *)ndlp, ndlp->nlp_usg_map, |
4251 | atomic_read(&ndlp->kref.refcount)); | 4251 | kref_read(&ndlp->kref)); |
4252 | return NULL; | 4252 | return NULL; |
4253 | } | 4253 | } |
4254 | 4254 | ||
@@ -4272,7 +4272,7 @@ lpfc_enable_node(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp, | |||
4272 | "0008 rpi:%x DID:%x flg:%x refcnt:%d " | 4272 | "0008 rpi:%x DID:%x flg:%x refcnt:%d " |
4273 | "map:%x %p\n", ndlp->nlp_rpi, ndlp->nlp_DID, | 4273 | "map:%x %p\n", ndlp->nlp_rpi, ndlp->nlp_DID, |
4274 | ndlp->nlp_flag, | 4274 | ndlp->nlp_flag, |
4275 | atomic_read(&ndlp->kref.refcount), | 4275 | kref_read(&ndlp->kref), |
4276 | ndlp->nlp_usg_map, ndlp); | 4276 | ndlp->nlp_usg_map, ndlp); |
4277 | } | 4277 | } |
4278 | 4278 | ||
@@ -4546,7 +4546,7 @@ lpfc_unreg_rpi(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp) | |||
4546 | (bf_get(lpfc_sli_intf_if_type, | 4546 | (bf_get(lpfc_sli_intf_if_type, |
4547 | &phba->sli4_hba.sli_intf) == | 4547 | &phba->sli4_hba.sli_intf) == |
4548 | LPFC_SLI_INTF_IF_TYPE_2) && | 4548 | LPFC_SLI_INTF_IF_TYPE_2) && |
4549 | (atomic_read(&ndlp->kref.refcount) > 0)) { | 4549 | (kref_read(&ndlp->kref) > 0)) { |
4550 | mbox->context1 = lpfc_nlp_get(ndlp); | 4550 | mbox->context1 = lpfc_nlp_get(ndlp); |
4551 | mbox->mbox_cmpl = | 4551 | mbox->mbox_cmpl = |
4552 | lpfc_sli4_unreg_rpi_cmpl_clr; | 4552 | lpfc_sli4_unreg_rpi_cmpl_clr; |
@@ -4695,14 +4695,14 @@ lpfc_cleanup_node(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp) | |||
4695 | "0280 lpfc_cleanup_node: ndlp:x%p " | 4695 | "0280 lpfc_cleanup_node: ndlp:x%p " |
4696 | "usgmap:x%x refcnt:%d\n", | 4696 | "usgmap:x%x refcnt:%d\n", |
4697 | (void *)ndlp, ndlp->nlp_usg_map, | 4697 | (void *)ndlp, ndlp->nlp_usg_map, |
4698 | atomic_read(&ndlp->kref.refcount)); | 4698 | kref_read(&ndlp->kref)); |
4699 | lpfc_dequeue_node(vport, ndlp); | 4699 | lpfc_dequeue_node(vport, ndlp); |
4700 | } else { | 4700 | } else { |
4701 | lpfc_printf_vlog(vport, KERN_WARNING, LOG_NODE, | 4701 | lpfc_printf_vlog(vport, KERN_WARNING, LOG_NODE, |
4702 | "0281 lpfc_cleanup_node: ndlp:x%p " | 4702 | "0281 lpfc_cleanup_node: ndlp:x%p " |
4703 | "usgmap:x%x refcnt:%d\n", | 4703 | "usgmap:x%x refcnt:%d\n", |
4704 | (void *)ndlp, ndlp->nlp_usg_map, | 4704 | (void *)ndlp, ndlp->nlp_usg_map, |
4705 | atomic_read(&ndlp->kref.refcount)); | 4705 | kref_read(&ndlp->kref)); |
4706 | lpfc_disable_node(vport, ndlp); | 4706 | lpfc_disable_node(vport, ndlp); |
4707 | } | 4707 | } |
4708 | 4708 | ||
@@ -4791,7 +4791,7 @@ lpfc_nlp_remove(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp) | |||
4791 | lpfc_printf_vlog(vport, KERN_INFO, LOG_NODE, | 4791 | lpfc_printf_vlog(vport, KERN_INFO, LOG_NODE, |
4792 | "0005 rpi:%x DID:%x flg:%x %d map:%x %p\n", | 4792 | "0005 rpi:%x DID:%x flg:%x %d map:%x %p\n", |
4793 | ndlp->nlp_rpi, ndlp->nlp_DID, ndlp->nlp_flag, | 4793 | ndlp->nlp_rpi, ndlp->nlp_DID, ndlp->nlp_flag, |
4794 | atomic_read(&ndlp->kref.refcount), | 4794 | kref_read(&ndlp->kref), |
4795 | ndlp->nlp_usg_map, ndlp); | 4795 | ndlp->nlp_usg_map, ndlp); |
4796 | if ((mbox = mempool_alloc(phba->mbox_mem_pool, GFP_KERNEL)) | 4796 | if ((mbox = mempool_alloc(phba->mbox_mem_pool, GFP_KERNEL)) |
4797 | != NULL) { | 4797 | != NULL) { |
@@ -5557,7 +5557,7 @@ lpfc_mbx_cmpl_fdmi_reg_login(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmb) | |||
5557 | lpfc_printf_vlog(vport, KERN_INFO, LOG_SLI, | 5557 | lpfc_printf_vlog(vport, KERN_INFO, LOG_SLI, |
5558 | "0004 rpi:%x DID:%x flg:%x %d map:%x %p\n", | 5558 | "0004 rpi:%x DID:%x flg:%x %d map:%x %p\n", |
5559 | ndlp->nlp_rpi, ndlp->nlp_DID, ndlp->nlp_flag, | 5559 | ndlp->nlp_rpi, ndlp->nlp_DID, ndlp->nlp_flag, |
5560 | atomic_read(&ndlp->kref.refcount), | 5560 | kref_read(&ndlp->kref), |
5561 | ndlp->nlp_usg_map, ndlp); | 5561 | ndlp->nlp_usg_map, ndlp); |
5562 | /* | 5562 | /* |
5563 | * Start issuing Fabric-Device Management Interface (FDMI) command to | 5563 | * Start issuing Fabric-Device Management Interface (FDMI) command to |
@@ -5728,7 +5728,7 @@ lpfc_nlp_init(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp, | |||
5728 | "0007 rpi:%x DID:%x flg:%x refcnt:%d " | 5728 | "0007 rpi:%x DID:%x flg:%x refcnt:%d " |
5729 | "map:%x %p\n", ndlp->nlp_rpi, ndlp->nlp_DID, | 5729 | "map:%x %p\n", ndlp->nlp_rpi, ndlp->nlp_DID, |
5730 | ndlp->nlp_flag, | 5730 | ndlp->nlp_flag, |
5731 | atomic_read(&ndlp->kref.refcount), | 5731 | kref_read(&ndlp->kref), |
5732 | ndlp->nlp_usg_map, ndlp); | 5732 | ndlp->nlp_usg_map, ndlp); |
5733 | 5733 | ||
5734 | ndlp->active_rrqs_xri_bitmap = | 5734 | ndlp->active_rrqs_xri_bitmap = |
@@ -5767,7 +5767,7 @@ lpfc_nlp_release(struct kref *kref) | |||
5767 | "0279 lpfc_nlp_release: ndlp:x%p did %x " | 5767 | "0279 lpfc_nlp_release: ndlp:x%p did %x " |
5768 | "usgmap:x%x refcnt:%d rpi:%x\n", | 5768 | "usgmap:x%x refcnt:%d rpi:%x\n", |
5769 | (void *)ndlp, ndlp->nlp_DID, ndlp->nlp_usg_map, | 5769 | (void *)ndlp, ndlp->nlp_DID, ndlp->nlp_usg_map, |
5770 | atomic_read(&ndlp->kref.refcount), ndlp->nlp_rpi); | 5770 | kref_read(&ndlp->kref), ndlp->nlp_rpi); |
5771 | 5771 | ||
5772 | /* remove ndlp from action. */ | 5772 | /* remove ndlp from action. */ |
5773 | lpfc_nlp_remove(ndlp->vport, ndlp); | 5773 | lpfc_nlp_remove(ndlp->vport, ndlp); |
@@ -5804,7 +5804,7 @@ lpfc_nlp_get(struct lpfc_nodelist *ndlp) | |||
5804 | lpfc_debugfs_disc_trc(ndlp->vport, LPFC_DISC_TRC_NODE, | 5804 | lpfc_debugfs_disc_trc(ndlp->vport, LPFC_DISC_TRC_NODE, |
5805 | "node get: did:x%x flg:x%x refcnt:x%x", | 5805 | "node get: did:x%x flg:x%x refcnt:x%x", |
5806 | ndlp->nlp_DID, ndlp->nlp_flag, | 5806 | ndlp->nlp_DID, ndlp->nlp_flag, |
5807 | atomic_read(&ndlp->kref.refcount)); | 5807 | kref_read(&ndlp->kref)); |
5808 | /* The check of ndlp usage to prevent incrementing the | 5808 | /* The check of ndlp usage to prevent incrementing the |
5809 | * ndlp reference count that is in the process of being | 5809 | * ndlp reference count that is in the process of being |
5810 | * released. | 5810 | * released. |
@@ -5817,7 +5817,7 @@ lpfc_nlp_get(struct lpfc_nodelist *ndlp) | |||
5817 | "0276 lpfc_nlp_get: ndlp:x%p " | 5817 | "0276 lpfc_nlp_get: ndlp:x%p " |
5818 | "usgmap:x%x refcnt:%d\n", | 5818 | "usgmap:x%x refcnt:%d\n", |
5819 | (void *)ndlp, ndlp->nlp_usg_map, | 5819 | (void *)ndlp, ndlp->nlp_usg_map, |
5820 | atomic_read(&ndlp->kref.refcount)); | 5820 | kref_read(&ndlp->kref)); |
5821 | return NULL; | 5821 | return NULL; |
5822 | } else | 5822 | } else |
5823 | kref_get(&ndlp->kref); | 5823 | kref_get(&ndlp->kref); |
@@ -5844,7 +5844,7 @@ lpfc_nlp_put(struct lpfc_nodelist *ndlp) | |||
5844 | lpfc_debugfs_disc_trc(ndlp->vport, LPFC_DISC_TRC_NODE, | 5844 | lpfc_debugfs_disc_trc(ndlp->vport, LPFC_DISC_TRC_NODE, |
5845 | "node put: did:x%x flg:x%x refcnt:x%x", | 5845 | "node put: did:x%x flg:x%x refcnt:x%x", |
5846 | ndlp->nlp_DID, ndlp->nlp_flag, | 5846 | ndlp->nlp_DID, ndlp->nlp_flag, |
5847 | atomic_read(&ndlp->kref.refcount)); | 5847 | kref_read(&ndlp->kref)); |
5848 | phba = ndlp->phba; | 5848 | phba = ndlp->phba; |
5849 | spin_lock_irqsave(&phba->ndlp_lock, flags); | 5849 | spin_lock_irqsave(&phba->ndlp_lock, flags); |
5850 | /* Check the ndlp memory free acknowledge flag to avoid the | 5850 | /* Check the ndlp memory free acknowledge flag to avoid the |
@@ -5857,7 +5857,7 @@ lpfc_nlp_put(struct lpfc_nodelist *ndlp) | |||
5857 | "0274 lpfc_nlp_put: ndlp:x%p " | 5857 | "0274 lpfc_nlp_put: ndlp:x%p " |
5858 | "usgmap:x%x refcnt:%d\n", | 5858 | "usgmap:x%x refcnt:%d\n", |
5859 | (void *)ndlp, ndlp->nlp_usg_map, | 5859 | (void *)ndlp, ndlp->nlp_usg_map, |
5860 | atomic_read(&ndlp->kref.refcount)); | 5860 | kref_read(&ndlp->kref)); |
5861 | return 1; | 5861 | return 1; |
5862 | } | 5862 | } |
5863 | /* Check the ndlp inactivate log flag to avoid the possible | 5863 | /* Check the ndlp inactivate log flag to avoid the possible |
@@ -5870,7 +5870,7 @@ lpfc_nlp_put(struct lpfc_nodelist *ndlp) | |||
5870 | "0275 lpfc_nlp_put: ndlp:x%p " | 5870 | "0275 lpfc_nlp_put: ndlp:x%p " |
5871 | "usgmap:x%x refcnt:%d\n", | 5871 | "usgmap:x%x refcnt:%d\n", |
5872 | (void *)ndlp, ndlp->nlp_usg_map, | 5872 | (void *)ndlp, ndlp->nlp_usg_map, |
5873 | atomic_read(&ndlp->kref.refcount)); | 5873 | kref_read(&ndlp->kref)); |
5874 | return 1; | 5874 | return 1; |
5875 | } | 5875 | } |
5876 | /* For last put, mark the ndlp usage flags to make sure no | 5876 | /* For last put, mark the ndlp usage flags to make sure no |
@@ -5878,7 +5878,7 @@ lpfc_nlp_put(struct lpfc_nodelist *ndlp) | |||
5878 | * in between the process when the final kref_put has been | 5878 | * in between the process when the final kref_put has been |
5879 | * invoked on this ndlp. | 5879 | * invoked on this ndlp. |
5880 | */ | 5880 | */ |
5881 | if (atomic_read(&ndlp->kref.refcount) == 1) { | 5881 | if (kref_read(&ndlp->kref) == 1) { |
5882 | /* Indicate ndlp is put to inactive state. */ | 5882 | /* Indicate ndlp is put to inactive state. */ |
5883 | NLP_SET_IACT_REQ(ndlp); | 5883 | NLP_SET_IACT_REQ(ndlp); |
5884 | /* Acknowledge ndlp memory free has been seen. */ | 5884 | /* Acknowledge ndlp memory free has been seen. */ |
@@ -5906,8 +5906,8 @@ lpfc_nlp_not_used(struct lpfc_nodelist *ndlp) | |||
5906 | lpfc_debugfs_disc_trc(ndlp->vport, LPFC_DISC_TRC_NODE, | 5906 | lpfc_debugfs_disc_trc(ndlp->vport, LPFC_DISC_TRC_NODE, |
5907 | "node not used: did:x%x flg:x%x refcnt:x%x", | 5907 | "node not used: did:x%x flg:x%x refcnt:x%x", |
5908 | ndlp->nlp_DID, ndlp->nlp_flag, | 5908 | ndlp->nlp_DID, ndlp->nlp_flag, |
5909 | atomic_read(&ndlp->kref.refcount)); | 5909 | kref_read(&ndlp->kref)); |
5910 | if (atomic_read(&ndlp->kref.refcount) == 1) | 5910 | if (kref_read(&ndlp->kref) == 1) |
5911 | if (lpfc_nlp_put(ndlp)) | 5911 | if (lpfc_nlp_put(ndlp)) |
5912 | return 1; | 5912 | return 1; |
5913 | return 0; | 5913 | return 0; |
diff --git a/drivers/scsi/lpfc/lpfc_init.c b/drivers/scsi/lpfc/lpfc_init.c index 4776fd85514f..64717c171b15 100644 --- a/drivers/scsi/lpfc/lpfc_init.c +++ b/drivers/scsi/lpfc/lpfc_init.c | |||
@@ -2660,8 +2660,7 @@ lpfc_cleanup(struct lpfc_vport *vport) | |||
2660 | "usgmap:x%x refcnt:%d\n", | 2660 | "usgmap:x%x refcnt:%d\n", |
2661 | ndlp->nlp_DID, (void *)ndlp, | 2661 | ndlp->nlp_DID, (void *)ndlp, |
2662 | ndlp->nlp_usg_map, | 2662 | ndlp->nlp_usg_map, |
2663 | atomic_read( | 2663 | kref_read(&ndlp->kref)); |
2664 | &ndlp->kref.refcount)); | ||
2665 | } | 2664 | } |
2666 | break; | 2665 | break; |
2667 | } | 2666 | } |
diff --git a/drivers/scsi/qla2xxx/tcm_qla2xxx.c b/drivers/scsi/qla2xxx/tcm_qla2xxx.c index d925910be761..3084983c1287 100644 --- a/drivers/scsi/qla2xxx/tcm_qla2xxx.c +++ b/drivers/scsi/qla2xxx/tcm_qla2xxx.c | |||
@@ -371,7 +371,7 @@ static int tcm_qla2xxx_write_pending(struct se_cmd *se_cmd) | |||
371 | */ | 371 | */ |
372 | pr_debug("write_pending aborted cmd[%p] refcount %d " | 372 | pr_debug("write_pending aborted cmd[%p] refcount %d " |
373 | "transport_state %x, t_state %x, se_cmd_flags %x\n", | 373 | "transport_state %x, t_state %x, se_cmd_flags %x\n", |
374 | cmd,cmd->se_cmd.cmd_kref.refcount.counter, | 374 | cmd, kref_read(&cmd->se_cmd.cmd_kref), |
375 | cmd->se_cmd.transport_state, | 375 | cmd->se_cmd.transport_state, |
376 | cmd->se_cmd.t_state, | 376 | cmd->se_cmd.t_state, |
377 | cmd->se_cmd.se_cmd_flags); | 377 | cmd->se_cmd.se_cmd_flags); |
@@ -584,7 +584,7 @@ static int tcm_qla2xxx_queue_data_in(struct se_cmd *se_cmd) | |||
584 | */ | 584 | */ |
585 | pr_debug("queue_data_in aborted cmd[%p] refcount %d " | 585 | pr_debug("queue_data_in aborted cmd[%p] refcount %d " |
586 | "transport_state %x, t_state %x, se_cmd_flags %x\n", | 586 | "transport_state %x, t_state %x, se_cmd_flags %x\n", |
587 | cmd,cmd->se_cmd.cmd_kref.refcount.counter, | 587 | cmd, kref_read(&cmd->se_cmd.cmd_kref), |
588 | cmd->se_cmd.transport_state, | 588 | cmd->se_cmd.transport_state, |
589 | cmd->se_cmd.t_state, | 589 | cmd->se_cmd.t_state, |
590 | cmd->se_cmd.se_cmd_flags); | 590 | cmd->se_cmd.se_cmd_flags); |
diff --git a/drivers/staging/android/ion/ion.c b/drivers/staging/android/ion/ion.c index b653451843c8..937c2d5d7ec3 100644 --- a/drivers/staging/android/ion/ion.c +++ b/drivers/staging/android/ion/ion.c | |||
@@ -1300,7 +1300,7 @@ static int ion_debug_heap_show(struct seq_file *s, void *unused) | |||
1300 | seq_printf(s, "%16s %16u %16zu %d %d\n", | 1300 | seq_printf(s, "%16s %16u %16zu %d %d\n", |
1301 | buffer->task_comm, buffer->pid, | 1301 | buffer->task_comm, buffer->pid, |
1302 | buffer->size, buffer->kmap_cnt, | 1302 | buffer->size, buffer->kmap_cnt, |
1303 | atomic_read(&buffer->ref.refcount)); | 1303 | kref_read(&buffer->ref)); |
1304 | total_orphaned_size += buffer->size; | 1304 | total_orphaned_size += buffer->size; |
1305 | } | 1305 | } |
1306 | } | 1306 | } |
diff --git a/drivers/staging/comedi/comedi_buf.c b/drivers/staging/comedi/comedi_buf.c index c7d7682b1412..1e1df89b5018 100644 --- a/drivers/staging/comedi/comedi_buf.c +++ b/drivers/staging/comedi/comedi_buf.c | |||
@@ -188,7 +188,7 @@ bool comedi_buf_is_mmapped(struct comedi_subdevice *s) | |||
188 | { | 188 | { |
189 | struct comedi_buf_map *bm = s->async->buf_map; | 189 | struct comedi_buf_map *bm = s->async->buf_map; |
190 | 190 | ||
191 | return bm && (atomic_read(&bm->refcount.refcount) > 1); | 191 | return bm && (kref_read(&bm->refcount) > 1); |
192 | } | 192 | } |
193 | 193 | ||
194 | int comedi_buf_alloc(struct comedi_device *dev, struct comedi_subdevice *s, | 194 | int comedi_buf_alloc(struct comedi_device *dev, struct comedi_subdevice *s, |
diff --git a/drivers/staging/lustre/lnet/libcfs/linux/linux-debug.c b/drivers/staging/lustre/lnet/libcfs/linux/linux-debug.c index 39a72e3f0c18..7035356e56b3 100644 --- a/drivers/staging/lustre/lnet/libcfs/linux/linux-debug.c +++ b/drivers/staging/lustre/lnet/libcfs/linux/linux-debug.c | |||
@@ -107,7 +107,7 @@ void __noreturn lbug_with_loc(struct libcfs_debug_msg_data *msgdata) | |||
107 | libcfs_debug_dumplog(); | 107 | libcfs_debug_dumplog(); |
108 | if (libcfs_panic_on_lbug) | 108 | if (libcfs_panic_on_lbug) |
109 | panic("LBUG"); | 109 | panic("LBUG"); |
110 | set_task_state(current, TASK_UNINTERRUPTIBLE); | 110 | set_current_state(TASK_UNINTERRUPTIBLE); |
111 | while (1) | 111 | while (1) |
112 | schedule(); | 112 | schedule(); |
113 | } | 113 | } |
diff --git a/drivers/target/target_core_pr.c b/drivers/target/target_core_pr.c index d761025144f9..e18051185846 100644 --- a/drivers/target/target_core_pr.c +++ b/drivers/target/target_core_pr.c | |||
@@ -788,7 +788,7 @@ static struct t10_pr_registration *__core_scsi3_alloc_registration( | |||
788 | * __core_scsi3_add_registration() | 788 | * __core_scsi3_add_registration() |
789 | */ | 789 | */ |
790 | dest_lun = rcu_dereference_check(deve_tmp->se_lun, | 790 | dest_lun = rcu_dereference_check(deve_tmp->se_lun, |
791 | atomic_read(&deve_tmp->pr_kref.refcount) != 0); | 791 | kref_read(&deve_tmp->pr_kref) != 0); |
792 | 792 | ||
793 | pr_reg_atp = __core_scsi3_do_alloc_registration(dev, | 793 | pr_reg_atp = __core_scsi3_do_alloc_registration(dev, |
794 | nacl_tmp, dest_lun, deve_tmp, | 794 | nacl_tmp, dest_lun, deve_tmp, |
@@ -1463,7 +1463,7 @@ static int core_scsi3_lunacl_depend_item(struct se_dev_entry *se_deve) | |||
1463 | * For nacl->dynamic_node_acl=1 | 1463 | * For nacl->dynamic_node_acl=1 |
1464 | */ | 1464 | */ |
1465 | lun_acl = rcu_dereference_check(se_deve->se_lun_acl, | 1465 | lun_acl = rcu_dereference_check(se_deve->se_lun_acl, |
1466 | atomic_read(&se_deve->pr_kref.refcount) != 0); | 1466 | kref_read(&se_deve->pr_kref) != 0); |
1467 | if (!lun_acl) | 1467 | if (!lun_acl) |
1468 | return 0; | 1468 | return 0; |
1469 | 1469 | ||
@@ -1478,7 +1478,7 @@ static void core_scsi3_lunacl_undepend_item(struct se_dev_entry *se_deve) | |||
1478 | * For nacl->dynamic_node_acl=1 | 1478 | * For nacl->dynamic_node_acl=1 |
1479 | */ | 1479 | */ |
1480 | lun_acl = rcu_dereference_check(se_deve->se_lun_acl, | 1480 | lun_acl = rcu_dereference_check(se_deve->se_lun_acl, |
1481 | atomic_read(&se_deve->pr_kref.refcount) != 0); | 1481 | kref_read(&se_deve->pr_kref) != 0); |
1482 | if (!lun_acl) { | 1482 | if (!lun_acl) { |
1483 | kref_put(&se_deve->pr_kref, target_pr_kref_release); | 1483 | kref_put(&se_deve->pr_kref, target_pr_kref_release); |
1484 | return; | 1484 | return; |
@@ -1759,7 +1759,7 @@ core_scsi3_decode_spec_i_port( | |||
1759 | * 2nd loop which will never fail. | 1759 | * 2nd loop which will never fail. |
1760 | */ | 1760 | */ |
1761 | dest_lun = rcu_dereference_check(dest_se_deve->se_lun, | 1761 | dest_lun = rcu_dereference_check(dest_se_deve->se_lun, |
1762 | atomic_read(&dest_se_deve->pr_kref.refcount) != 0); | 1762 | kref_read(&dest_se_deve->pr_kref) != 0); |
1763 | 1763 | ||
1764 | dest_pr_reg = __core_scsi3_alloc_registration(cmd->se_dev, | 1764 | dest_pr_reg = __core_scsi3_alloc_registration(cmd->se_dev, |
1765 | dest_node_acl, dest_lun, dest_se_deve, | 1765 | dest_node_acl, dest_lun, dest_se_deve, |
@@ -3466,7 +3466,7 @@ after_iport_check: | |||
3466 | iport_ptr); | 3466 | iport_ptr); |
3467 | if (!dest_pr_reg) { | 3467 | if (!dest_pr_reg) { |
3468 | struct se_lun *dest_lun = rcu_dereference_check(dest_se_deve->se_lun, | 3468 | struct se_lun *dest_lun = rcu_dereference_check(dest_se_deve->se_lun, |
3469 | atomic_read(&dest_se_deve->pr_kref.refcount) != 0); | 3469 | kref_read(&dest_se_deve->pr_kref) != 0); |
3470 | 3470 | ||
3471 | spin_unlock(&dev->dev_reservation_lock); | 3471 | spin_unlock(&dev->dev_reservation_lock); |
3472 | if (core_scsi3_alloc_registration(cmd->se_dev, dest_node_acl, | 3472 | if (core_scsi3_alloc_registration(cmd->se_dev, dest_node_acl, |
diff --git a/drivers/target/tcm_fc/tfc_sess.c b/drivers/target/tcm_fc/tfc_sess.c index fd5c3de79470..c91979c1463d 100644 --- a/drivers/target/tcm_fc/tfc_sess.c +++ b/drivers/target/tcm_fc/tfc_sess.c | |||
@@ -454,7 +454,7 @@ static void ft_sess_free(struct kref *kref) | |||
454 | 454 | ||
455 | void ft_sess_put(struct ft_sess *sess) | 455 | void ft_sess_put(struct ft_sess *sess) |
456 | { | 456 | { |
457 | int sess_held = atomic_read(&sess->kref.refcount); | 457 | int sess_held = kref_read(&sess->kref); |
458 | 458 | ||
459 | BUG_ON(!sess_held); | 459 | BUG_ON(!sess_held); |
460 | kref_put(&sess->kref, ft_sess_free); | 460 | kref_put(&sess->kref, ft_sess_free); |
diff --git a/drivers/tty/tty_ldsem.c b/drivers/tty/tty_ldsem.c index 1bf8ed13f827..9229de43e19d 100644 --- a/drivers/tty/tty_ldsem.c +++ b/drivers/tty/tty_ldsem.c | |||
@@ -200,7 +200,6 @@ static struct ld_semaphore __sched * | |||
200 | down_read_failed(struct ld_semaphore *sem, long count, long timeout) | 200 | down_read_failed(struct ld_semaphore *sem, long count, long timeout) |
201 | { | 201 | { |
202 | struct ldsem_waiter waiter; | 202 | struct ldsem_waiter waiter; |
203 | struct task_struct *tsk = current; | ||
204 | long adjust = -LDSEM_ACTIVE_BIAS + LDSEM_WAIT_BIAS; | 203 | long adjust = -LDSEM_ACTIVE_BIAS + LDSEM_WAIT_BIAS; |
205 | 204 | ||
206 | /* set up my own style of waitqueue */ | 205 | /* set up my own style of waitqueue */ |
@@ -221,8 +220,8 @@ down_read_failed(struct ld_semaphore *sem, long count, long timeout) | |||
221 | list_add_tail(&waiter.list, &sem->read_wait); | 220 | list_add_tail(&waiter.list, &sem->read_wait); |
222 | sem->wait_readers++; | 221 | sem->wait_readers++; |
223 | 222 | ||
224 | waiter.task = tsk; | 223 | waiter.task = current; |
225 | get_task_struct(tsk); | 224 | get_task_struct(current); |
226 | 225 | ||
227 | /* if there are no active locks, wake the new lock owner(s) */ | 226 | /* if there are no active locks, wake the new lock owner(s) */ |
228 | if ((count & LDSEM_ACTIVE_MASK) == 0) | 227 | if ((count & LDSEM_ACTIVE_MASK) == 0) |
@@ -232,7 +231,7 @@ down_read_failed(struct ld_semaphore *sem, long count, long timeout) | |||
232 | 231 | ||
233 | /* wait to be given the lock */ | 232 | /* wait to be given the lock */ |
234 | for (;;) { | 233 | for (;;) { |
235 | set_task_state(tsk, TASK_UNINTERRUPTIBLE); | 234 | set_current_state(TASK_UNINTERRUPTIBLE); |
236 | 235 | ||
237 | if (!waiter.task) | 236 | if (!waiter.task) |
238 | break; | 237 | break; |
@@ -241,7 +240,7 @@ down_read_failed(struct ld_semaphore *sem, long count, long timeout) | |||
241 | timeout = schedule_timeout(timeout); | 240 | timeout = schedule_timeout(timeout); |
242 | } | 241 | } |
243 | 242 | ||
244 | __set_task_state(tsk, TASK_RUNNING); | 243 | __set_current_state(TASK_RUNNING); |
245 | 244 | ||
246 | if (!timeout) { | 245 | if (!timeout) { |
247 | /* lock timed out but check if this task was just | 246 | /* lock timed out but check if this task was just |
@@ -268,7 +267,6 @@ static struct ld_semaphore __sched * | |||
268 | down_write_failed(struct ld_semaphore *sem, long count, long timeout) | 267 | down_write_failed(struct ld_semaphore *sem, long count, long timeout) |
269 | { | 268 | { |
270 | struct ldsem_waiter waiter; | 269 | struct ldsem_waiter waiter; |
271 | struct task_struct *tsk = current; | ||
272 | long adjust = -LDSEM_ACTIVE_BIAS; | 270 | long adjust = -LDSEM_ACTIVE_BIAS; |
273 | int locked = 0; | 271 | int locked = 0; |
274 | 272 | ||
@@ -289,16 +287,16 @@ down_write_failed(struct ld_semaphore *sem, long count, long timeout) | |||
289 | 287 | ||
290 | list_add_tail(&waiter.list, &sem->write_wait); | 288 | list_add_tail(&waiter.list, &sem->write_wait); |
291 | 289 | ||
292 | waiter.task = tsk; | 290 | waiter.task = current; |
293 | 291 | ||
294 | set_task_state(tsk, TASK_UNINTERRUPTIBLE); | 292 | set_current_state(TASK_UNINTERRUPTIBLE); |
295 | for (;;) { | 293 | for (;;) { |
296 | if (!timeout) | 294 | if (!timeout) |
297 | break; | 295 | break; |
298 | raw_spin_unlock_irq(&sem->wait_lock); | 296 | raw_spin_unlock_irq(&sem->wait_lock); |
299 | timeout = schedule_timeout(timeout); | 297 | timeout = schedule_timeout(timeout); |
300 | raw_spin_lock_irq(&sem->wait_lock); | 298 | raw_spin_lock_irq(&sem->wait_lock); |
301 | set_task_state(tsk, TASK_UNINTERRUPTIBLE); | 299 | set_current_state(TASK_UNINTERRUPTIBLE); |
302 | locked = writer_trylock(sem); | 300 | locked = writer_trylock(sem); |
303 | if (locked) | 301 | if (locked) |
304 | break; | 302 | break; |
@@ -309,7 +307,7 @@ down_write_failed(struct ld_semaphore *sem, long count, long timeout) | |||
309 | list_del(&waiter.list); | 307 | list_del(&waiter.list); |
310 | raw_spin_unlock_irq(&sem->wait_lock); | 308 | raw_spin_unlock_irq(&sem->wait_lock); |
311 | 309 | ||
312 | __set_task_state(tsk, TASK_RUNNING); | 310 | __set_current_state(TASK_RUNNING); |
313 | 311 | ||
314 | /* lock wait may have timed out */ | 312 | /* lock wait may have timed out */ |
315 | if (!locked) | 313 | if (!locked) |
diff --git a/drivers/usb/gadget/function/f_fs.c b/drivers/usb/gadget/function/f_fs.c index fd80c1b9c823..e6a17455adac 100644 --- a/drivers/usb/gadget/function/f_fs.c +++ b/drivers/usb/gadget/function/f_fs.c | |||
@@ -3698,7 +3698,7 @@ static void ffs_closed(struct ffs_data *ffs) | |||
3698 | goto done; | 3698 | goto done; |
3699 | 3699 | ||
3700 | if (opts->no_configfs || !opts->func_inst.group.cg_item.ci_parent | 3700 | if (opts->no_configfs || !opts->func_inst.group.cg_item.ci_parent |
3701 | || !atomic_read(&opts->func_inst.group.cg_item.ci_kref.refcount)) | 3701 | || !kref_read(&opts->func_inst.group.cg_item.ci_kref)) |
3702 | goto done; | 3702 | goto done; |
3703 | 3703 | ||
3704 | ci = opts->func_inst.group.cg_item.ci_parent->ci_parent; | 3704 | ci = opts->func_inst.group.cg_item.ci_parent->ci_parent; |
diff --git a/drivers/usb/mon/mon_main.c b/drivers/usb/mon/mon_main.c index 33ff49c4cea4..46847340b819 100644 --- a/drivers/usb/mon/mon_main.c +++ b/drivers/usb/mon/mon_main.c | |||
@@ -409,7 +409,7 @@ static void __exit mon_exit(void) | |||
409 | printk(KERN_ERR TAG | 409 | printk(KERN_ERR TAG |
410 | ": Outstanding opens (%d) on usb%d, leaking...\n", | 410 | ": Outstanding opens (%d) on usb%d, leaking...\n", |
411 | mbus->nreaders, mbus->u_bus->busnum); | 411 | mbus->nreaders, mbus->u_bus->busnum); |
412 | atomic_set(&mbus->ref.refcount, 2); /* Force leak */ | 412 | kref_get(&mbus->ref); /* Force leak */ |
413 | } | 413 | } |
414 | 414 | ||
415 | mon_dissolve(mbus, mbus->u_bus); | 415 | mon_dissolve(mbus, mbus->u_bus); |
diff --git a/fs/exofs/sys.c b/fs/exofs/sys.c index 5e6a2c0a1f0b..1f7d5e46cdda 100644 --- a/fs/exofs/sys.c +++ b/fs/exofs/sys.c | |||
@@ -122,7 +122,7 @@ void exofs_sysfs_dbg_print(void) | |||
122 | list_for_each_entry_safe(k_name, k_tmp, &exofs_kset->list, entry) { | 122 | list_for_each_entry_safe(k_name, k_tmp, &exofs_kset->list, entry) { |
123 | printk(KERN_INFO "%s: name %s ref %d\n", | 123 | printk(KERN_INFO "%s: name %s ref %d\n", |
124 | __func__, kobject_name(k_name), | 124 | __func__, kobject_name(k_name), |
125 | (int)atomic_read(&k_name->kref.refcount)); | 125 | (int)kref_read(&k_name->kref)); |
126 | } | 126 | } |
127 | #endif | 127 | #endif |
128 | } | 128 | } |
diff --git a/fs/fuse/fuse_i.h b/fs/fuse/fuse_i.h index 91307940c8ac..052f8d3c41cb 100644 --- a/fs/fuse/fuse_i.h +++ b/fs/fuse/fuse_i.h | |||
@@ -256,7 +256,7 @@ struct fuse_io_priv { | |||
256 | 256 | ||
257 | #define FUSE_IO_PRIV_SYNC(f) \ | 257 | #define FUSE_IO_PRIV_SYNC(f) \ |
258 | { \ | 258 | { \ |
259 | .refcnt = { ATOMIC_INIT(1) }, \ | 259 | .refcnt = KREF_INIT(1), \ |
260 | .async = 0, \ | 260 | .async = 0, \ |
261 | .file = f, \ | 261 | .file = f, \ |
262 | } | 262 | } |
diff --git a/fs/ocfs2/cluster/netdebug.c b/fs/ocfs2/cluster/netdebug.c index 27d1242c8383..564c504d6efd 100644 --- a/fs/ocfs2/cluster/netdebug.c +++ b/fs/ocfs2/cluster/netdebug.c | |||
@@ -349,7 +349,7 @@ static void sc_show_sock_container(struct seq_file *seq, | |||
349 | " func key: 0x%08x\n" | 349 | " func key: 0x%08x\n" |
350 | " func type: %u\n", | 350 | " func type: %u\n", |
351 | sc, | 351 | sc, |
352 | atomic_read(&sc->sc_kref.refcount), | 352 | kref_read(&sc->sc_kref), |
353 | &saddr, inet ? ntohs(sport) : 0, | 353 | &saddr, inet ? ntohs(sport) : 0, |
354 | &daddr, inet ? ntohs(dport) : 0, | 354 | &daddr, inet ? ntohs(dport) : 0, |
355 | sc->sc_node->nd_name, | 355 | sc->sc_node->nd_name, |
diff --git a/fs/ocfs2/cluster/tcp.c b/fs/ocfs2/cluster/tcp.c index d4b5c81f0445..ec000575e863 100644 --- a/fs/ocfs2/cluster/tcp.c +++ b/fs/ocfs2/cluster/tcp.c | |||
@@ -97,7 +97,7 @@ | |||
97 | typeof(sc) __sc = (sc); \ | 97 | typeof(sc) __sc = (sc); \ |
98 | mlog(ML_SOCKET, "[sc %p refs %d sock %p node %u page %p " \ | 98 | mlog(ML_SOCKET, "[sc %p refs %d sock %p node %u page %p " \ |
99 | "pg_off %zu] " fmt, __sc, \ | 99 | "pg_off %zu] " fmt, __sc, \ |
100 | atomic_read(&__sc->sc_kref.refcount), __sc->sc_sock, \ | 100 | kref_read(&__sc->sc_kref), __sc->sc_sock, \ |
101 | __sc->sc_node->nd_num, __sc->sc_page, __sc->sc_page_off , \ | 101 | __sc->sc_node->nd_num, __sc->sc_page, __sc->sc_page_off , \ |
102 | ##args); \ | 102 | ##args); \ |
103 | } while (0) | 103 | } while (0) |
diff --git a/fs/ocfs2/dlm/dlmdebug.c b/fs/ocfs2/dlm/dlmdebug.c index e7b760deefae..9b984cae4c4e 100644 --- a/fs/ocfs2/dlm/dlmdebug.c +++ b/fs/ocfs2/dlm/dlmdebug.c | |||
@@ -81,7 +81,7 @@ static void __dlm_print_lock(struct dlm_lock *lock) | |||
81 | lock->ml.type, lock->ml.convert_type, lock->ml.node, | 81 | lock->ml.type, lock->ml.convert_type, lock->ml.node, |
82 | dlm_get_lock_cookie_node(be64_to_cpu(lock->ml.cookie)), | 82 | dlm_get_lock_cookie_node(be64_to_cpu(lock->ml.cookie)), |
83 | dlm_get_lock_cookie_seq(be64_to_cpu(lock->ml.cookie)), | 83 | dlm_get_lock_cookie_seq(be64_to_cpu(lock->ml.cookie)), |
84 | atomic_read(&lock->lock_refs.refcount), | 84 | kref_read(&lock->lock_refs), |
85 | (list_empty(&lock->ast_list) ? 'y' : 'n'), | 85 | (list_empty(&lock->ast_list) ? 'y' : 'n'), |
86 | (lock->ast_pending ? 'y' : 'n'), | 86 | (lock->ast_pending ? 'y' : 'n'), |
87 | (list_empty(&lock->bast_list) ? 'y' : 'n'), | 87 | (list_empty(&lock->bast_list) ? 'y' : 'n'), |
@@ -106,7 +106,7 @@ void __dlm_print_one_lock_resource(struct dlm_lock_resource *res) | |||
106 | printk("lockres: %s, owner=%u, state=%u\n", | 106 | printk("lockres: %s, owner=%u, state=%u\n", |
107 | buf, res->owner, res->state); | 107 | buf, res->owner, res->state); |
108 | printk(" last used: %lu, refcnt: %u, on purge list: %s\n", | 108 | printk(" last used: %lu, refcnt: %u, on purge list: %s\n", |
109 | res->last_used, atomic_read(&res->refs.refcount), | 109 | res->last_used, kref_read(&res->refs), |
110 | list_empty(&res->purge) ? "no" : "yes"); | 110 | list_empty(&res->purge) ? "no" : "yes"); |
111 | printk(" on dirty list: %s, on reco list: %s, " | 111 | printk(" on dirty list: %s, on reco list: %s, " |
112 | "migrating pending: %s\n", | 112 | "migrating pending: %s\n", |
@@ -298,7 +298,7 @@ static int dump_mle(struct dlm_master_list_entry *mle, char *buf, int len) | |||
298 | mle_type, mle->master, mle->new_master, | 298 | mle_type, mle->master, mle->new_master, |
299 | !list_empty(&mle->hb_events), | 299 | !list_empty(&mle->hb_events), |
300 | !!mle->inuse, | 300 | !!mle->inuse, |
301 | atomic_read(&mle->mle_refs.refcount)); | 301 | kref_read(&mle->mle_refs)); |
302 | 302 | ||
303 | out += snprintf(buf + out, len - out, "Maybe="); | 303 | out += snprintf(buf + out, len - out, "Maybe="); |
304 | out += stringify_nodemap(mle->maybe_map, O2NM_MAX_NODES, | 304 | out += stringify_nodemap(mle->maybe_map, O2NM_MAX_NODES, |
@@ -494,7 +494,7 @@ static int dump_lock(struct dlm_lock *lock, int list_type, char *buf, int len) | |||
494 | lock->ast_pending, lock->bast_pending, | 494 | lock->ast_pending, lock->bast_pending, |
495 | lock->convert_pending, lock->lock_pending, | 495 | lock->convert_pending, lock->lock_pending, |
496 | lock->cancel_pending, lock->unlock_pending, | 496 | lock->cancel_pending, lock->unlock_pending, |
497 | atomic_read(&lock->lock_refs.refcount)); | 497 | kref_read(&lock->lock_refs)); |
498 | spin_unlock(&lock->spinlock); | 498 | spin_unlock(&lock->spinlock); |
499 | 499 | ||
500 | return out; | 500 | return out; |
@@ -521,7 +521,7 @@ static int dump_lockres(struct dlm_lock_resource *res, char *buf, int len) | |||
521 | !list_empty(&res->recovering), | 521 | !list_empty(&res->recovering), |
522 | res->inflight_locks, res->migration_pending, | 522 | res->inflight_locks, res->migration_pending, |
523 | atomic_read(&res->asts_reserved), | 523 | atomic_read(&res->asts_reserved), |
524 | atomic_read(&res->refs.refcount)); | 524 | kref_read(&res->refs)); |
525 | 525 | ||
526 | /* refmap */ | 526 | /* refmap */ |
527 | out += snprintf(buf + out, len - out, "RMAP:"); | 527 | out += snprintf(buf + out, len - out, "RMAP:"); |
@@ -777,7 +777,7 @@ static int debug_state_print(struct dlm_ctxt *dlm, char *buf, int len) | |||
777 | /* Purge Count: xxx Refs: xxx */ | 777 | /* Purge Count: xxx Refs: xxx */ |
778 | out += snprintf(buf + out, len - out, | 778 | out += snprintf(buf + out, len - out, |
779 | "Purge Count: %d Refs: %d\n", dlm->purge_count, | 779 | "Purge Count: %d Refs: %d\n", dlm->purge_count, |
780 | atomic_read(&dlm->dlm_refs.refcount)); | 780 | kref_read(&dlm->dlm_refs)); |
781 | 781 | ||
782 | /* Dead Node: xxx */ | 782 | /* Dead Node: xxx */ |
783 | out += snprintf(buf + out, len - out, | 783 | out += snprintf(buf + out, len - out, |
diff --git a/fs/ocfs2/dlm/dlmdomain.c b/fs/ocfs2/dlm/dlmdomain.c index 733e4e79c8e2..32fd261ae13d 100644 --- a/fs/ocfs2/dlm/dlmdomain.c +++ b/fs/ocfs2/dlm/dlmdomain.c | |||
@@ -2072,7 +2072,7 @@ static struct dlm_ctxt *dlm_alloc_ctxt(const char *domain, | |||
2072 | INIT_LIST_HEAD(&dlm->dlm_eviction_callbacks); | 2072 | INIT_LIST_HEAD(&dlm->dlm_eviction_callbacks); |
2073 | 2073 | ||
2074 | mlog(0, "context init: refcount %u\n", | 2074 | mlog(0, "context init: refcount %u\n", |
2075 | atomic_read(&dlm->dlm_refs.refcount)); | 2075 | kref_read(&dlm->dlm_refs)); |
2076 | 2076 | ||
2077 | leave: | 2077 | leave: |
2078 | if (ret < 0 && dlm) { | 2078 | if (ret < 0 && dlm) { |
diff --git a/fs/ocfs2/dlm/dlmmaster.c b/fs/ocfs2/dlm/dlmmaster.c index a464c8088170..7025d8c27999 100644 --- a/fs/ocfs2/dlm/dlmmaster.c +++ b/fs/ocfs2/dlm/dlmmaster.c | |||
@@ -233,7 +233,7 @@ static void __dlm_put_mle(struct dlm_master_list_entry *mle) | |||
233 | 233 | ||
234 | assert_spin_locked(&dlm->spinlock); | 234 | assert_spin_locked(&dlm->spinlock); |
235 | assert_spin_locked(&dlm->master_lock); | 235 | assert_spin_locked(&dlm->master_lock); |
236 | if (!atomic_read(&mle->mle_refs.refcount)) { | 236 | if (!kref_read(&mle->mle_refs)) { |
237 | /* this may or may not crash, but who cares. | 237 | /* this may or may not crash, but who cares. |
238 | * it's a BUG. */ | 238 | * it's a BUG. */ |
239 | mlog(ML_ERROR, "bad mle: %p\n", mle); | 239 | mlog(ML_ERROR, "bad mle: %p\n", mle); |
@@ -1124,9 +1124,9 @@ recheck: | |||
1124 | unsigned long timeo = msecs_to_jiffies(DLM_MASTERY_TIMEOUT_MS); | 1124 | unsigned long timeo = msecs_to_jiffies(DLM_MASTERY_TIMEOUT_MS); |
1125 | 1125 | ||
1126 | /* | 1126 | /* |
1127 | if (atomic_read(&mle->mle_refs.refcount) < 2) | 1127 | if (kref_read(&mle->mle_refs) < 2) |
1128 | mlog(ML_ERROR, "mle (%p) refs=%d, name=%.*s\n", mle, | 1128 | mlog(ML_ERROR, "mle (%p) refs=%d, name=%.*s\n", mle, |
1129 | atomic_read(&mle->mle_refs.refcount), | 1129 | kref_read(&mle->mle_refs), |
1130 | res->lockname.len, res->lockname.name); | 1130 | res->lockname.len, res->lockname.name); |
1131 | */ | 1131 | */ |
1132 | atomic_set(&mle->woken, 0); | 1132 | atomic_set(&mle->woken, 0); |
@@ -1979,7 +1979,7 @@ ok: | |||
1979 | * on this mle. */ | 1979 | * on this mle. */ |
1980 | spin_lock(&dlm->master_lock); | 1980 | spin_lock(&dlm->master_lock); |
1981 | 1981 | ||
1982 | rr = atomic_read(&mle->mle_refs.refcount); | 1982 | rr = kref_read(&mle->mle_refs); |
1983 | if (mle->inuse > 0) { | 1983 | if (mle->inuse > 0) { |
1984 | if (extra_ref && rr < 3) | 1984 | if (extra_ref && rr < 3) |
1985 | err = 1; | 1985 | err = 1; |
diff --git a/fs/ocfs2/dlm/dlmunlock.c b/fs/ocfs2/dlm/dlmunlock.c index 1082b2c3014b..63d701cd1e2e 100644 --- a/fs/ocfs2/dlm/dlmunlock.c +++ b/fs/ocfs2/dlm/dlmunlock.c | |||
@@ -251,7 +251,7 @@ leave: | |||
251 | mlog(0, "lock %u:%llu should be gone now! refs=%d\n", | 251 | mlog(0, "lock %u:%llu should be gone now! refs=%d\n", |
252 | dlm_get_lock_cookie_node(be64_to_cpu(lock->ml.cookie)), | 252 | dlm_get_lock_cookie_node(be64_to_cpu(lock->ml.cookie)), |
253 | dlm_get_lock_cookie_seq(be64_to_cpu(lock->ml.cookie)), | 253 | dlm_get_lock_cookie_seq(be64_to_cpu(lock->ml.cookie)), |
254 | atomic_read(&lock->lock_refs.refcount)-1); | 254 | kref_read(&lock->lock_refs)-1); |
255 | dlm_lock_put(lock); | 255 | dlm_lock_put(lock); |
256 | } | 256 | } |
257 | if (actions & DLM_UNLOCK_CALL_AST) | 257 | if (actions & DLM_UNLOCK_CALL_AST) |
diff --git a/include/asm-generic/rwsem.h b/include/asm-generic/rwsem.h index 5be122e3d326..6c6a2141f271 100644 --- a/include/asm-generic/rwsem.h +++ b/include/asm-generic/rwsem.h | |||
@@ -33,7 +33,7 @@ | |||
33 | */ | 33 | */ |
34 | static inline void __down_read(struct rw_semaphore *sem) | 34 | static inline void __down_read(struct rw_semaphore *sem) |
35 | { | 35 | { |
36 | if (unlikely(atomic_long_inc_return_acquire((atomic_long_t *)&sem->count) <= 0)) | 36 | if (unlikely(atomic_long_inc_return_acquire(&sem->count) <= 0)) |
37 | rwsem_down_read_failed(sem); | 37 | rwsem_down_read_failed(sem); |
38 | } | 38 | } |
39 | 39 | ||
@@ -58,7 +58,7 @@ static inline void __down_write(struct rw_semaphore *sem) | |||
58 | long tmp; | 58 | long tmp; |
59 | 59 | ||
60 | tmp = atomic_long_add_return_acquire(RWSEM_ACTIVE_WRITE_BIAS, | 60 | tmp = atomic_long_add_return_acquire(RWSEM_ACTIVE_WRITE_BIAS, |
61 | (atomic_long_t *)&sem->count); | 61 | &sem->count); |
62 | if (unlikely(tmp != RWSEM_ACTIVE_WRITE_BIAS)) | 62 | if (unlikely(tmp != RWSEM_ACTIVE_WRITE_BIAS)) |
63 | rwsem_down_write_failed(sem); | 63 | rwsem_down_write_failed(sem); |
64 | } | 64 | } |
@@ -68,7 +68,7 @@ static inline int __down_write_killable(struct rw_semaphore *sem) | |||
68 | long tmp; | 68 | long tmp; |
69 | 69 | ||
70 | tmp = atomic_long_add_return_acquire(RWSEM_ACTIVE_WRITE_BIAS, | 70 | tmp = atomic_long_add_return_acquire(RWSEM_ACTIVE_WRITE_BIAS, |
71 | (atomic_long_t *)&sem->count); | 71 | &sem->count); |
72 | if (unlikely(tmp != RWSEM_ACTIVE_WRITE_BIAS)) | 72 | if (unlikely(tmp != RWSEM_ACTIVE_WRITE_BIAS)) |
73 | if (IS_ERR(rwsem_down_write_failed_killable(sem))) | 73 | if (IS_ERR(rwsem_down_write_failed_killable(sem))) |
74 | return -EINTR; | 74 | return -EINTR; |
@@ -91,7 +91,7 @@ static inline void __up_read(struct rw_semaphore *sem) | |||
91 | { | 91 | { |
92 | long tmp; | 92 | long tmp; |
93 | 93 | ||
94 | tmp = atomic_long_dec_return_release((atomic_long_t *)&sem->count); | 94 | tmp = atomic_long_dec_return_release(&sem->count); |
95 | if (unlikely(tmp < -1 && (tmp & RWSEM_ACTIVE_MASK) == 0)) | 95 | if (unlikely(tmp < -1 && (tmp & RWSEM_ACTIVE_MASK) == 0)) |
96 | rwsem_wake(sem); | 96 | rwsem_wake(sem); |
97 | } | 97 | } |
@@ -102,7 +102,7 @@ static inline void __up_read(struct rw_semaphore *sem) | |||
102 | static inline void __up_write(struct rw_semaphore *sem) | 102 | static inline void __up_write(struct rw_semaphore *sem) |
103 | { | 103 | { |
104 | if (unlikely(atomic_long_sub_return_release(RWSEM_ACTIVE_WRITE_BIAS, | 104 | if (unlikely(atomic_long_sub_return_release(RWSEM_ACTIVE_WRITE_BIAS, |
105 | (atomic_long_t *)&sem->count) < 0)) | 105 | &sem->count) < 0)) |
106 | rwsem_wake(sem); | 106 | rwsem_wake(sem); |
107 | } | 107 | } |
108 | 108 | ||
@@ -120,8 +120,7 @@ static inline void __downgrade_write(struct rw_semaphore *sem) | |||
120 | * read-locked region is ok to be re-ordered into the | 120 | * read-locked region is ok to be re-ordered into the |
121 | * write side. As such, rely on RELEASE semantics. | 121 | * write side. As such, rely on RELEASE semantics. |
122 | */ | 122 | */ |
123 | tmp = atomic_long_add_return_release(-RWSEM_WAITING_BIAS, | 123 | tmp = atomic_long_add_return_release(-RWSEM_WAITING_BIAS, &sem->count); |
124 | (atomic_long_t *)&sem->count); | ||
125 | if (tmp < 0) | 124 | if (tmp < 0) |
126 | rwsem_downgrade_wake(sem); | 125 | rwsem_downgrade_wake(sem); |
127 | } | 126 | } |
diff --git a/include/drm/drm_framebuffer.h b/include/drm/drm_framebuffer.h index 1ddfa2928802..a232e7f0c869 100644 --- a/include/drm/drm_framebuffer.h +++ b/include/drm/drm_framebuffer.h | |||
@@ -247,7 +247,7 @@ static inline void drm_framebuffer_unreference(struct drm_framebuffer *fb) | |||
247 | */ | 247 | */ |
248 | static inline uint32_t drm_framebuffer_read_refcount(struct drm_framebuffer *fb) | 248 | static inline uint32_t drm_framebuffer_read_refcount(struct drm_framebuffer *fb) |
249 | { | 249 | { |
250 | return atomic_read(&fb->base.refcount.refcount); | 250 | return kref_read(&fb->base.refcount); |
251 | } | 251 | } |
252 | 252 | ||
253 | /** | 253 | /** |
diff --git a/include/drm/ttm/ttm_bo_api.h b/include/drm/ttm/ttm_bo_api.h index 652e45be97c8..9a465314572c 100644 --- a/include/drm/ttm/ttm_bo_api.h +++ b/include/drm/ttm/ttm_bo_api.h | |||
@@ -332,19 +332,6 @@ extern int ttm_bo_validate(struct ttm_buffer_object *bo, | |||
332 | */ | 332 | */ |
333 | extern void ttm_bo_unref(struct ttm_buffer_object **bo); | 333 | extern void ttm_bo_unref(struct ttm_buffer_object **bo); |
334 | 334 | ||
335 | |||
336 | /** | ||
337 | * ttm_bo_list_ref_sub | ||
338 | * | ||
339 | * @bo: The buffer object. | ||
340 | * @count: The number of references with which to decrease @bo::list_kref; | ||
341 | * @never_free: The refcount should not reach zero with this operation. | ||
342 | * | ||
343 | * Release @count lru list references to this buffer object. | ||
344 | */ | ||
345 | extern void ttm_bo_list_ref_sub(struct ttm_buffer_object *bo, int count, | ||
346 | bool never_free); | ||
347 | |||
348 | /** | 335 | /** |
349 | * ttm_bo_add_to_lru | 336 | * ttm_bo_add_to_lru |
350 | * | 337 | * |
@@ -367,7 +354,7 @@ extern void ttm_bo_add_to_lru(struct ttm_buffer_object *bo); | |||
367 | * and is usually called just immediately after the bo has been reserved to | 354 | * and is usually called just immediately after the bo has been reserved to |
368 | * avoid recursive reservation from lru lists. | 355 | * avoid recursive reservation from lru lists. |
369 | */ | 356 | */ |
370 | extern int ttm_bo_del_from_lru(struct ttm_buffer_object *bo); | 357 | extern void ttm_bo_del_from_lru(struct ttm_buffer_object *bo); |
371 | 358 | ||
372 | /** | 359 | /** |
373 | * ttm_bo_move_to_lru_tail | 360 | * ttm_bo_move_to_lru_tail |
diff --git a/include/drm/ttm/ttm_bo_driver.h b/include/drm/ttm/ttm_bo_driver.h index cdbdb40eb5bd..feecf33a1212 100644 --- a/include/drm/ttm/ttm_bo_driver.h +++ b/include/drm/ttm/ttm_bo_driver.h | |||
@@ -878,7 +878,7 @@ static inline int ttm_bo_reserve(struct ttm_buffer_object *bo, | |||
878 | { | 878 | { |
879 | int ret; | 879 | int ret; |
880 | 880 | ||
881 | WARN_ON(!atomic_read(&bo->kref.refcount)); | 881 | WARN_ON(!kref_read(&bo->kref)); |
882 | 882 | ||
883 | ret = __ttm_bo_reserve(bo, interruptible, no_wait, ticket); | 883 | ret = __ttm_bo_reserve(bo, interruptible, no_wait, ticket); |
884 | if (likely(ret == 0)) | 884 | if (likely(ret == 0)) |
@@ -903,7 +903,7 @@ static inline int ttm_bo_reserve_slowpath(struct ttm_buffer_object *bo, | |||
903 | { | 903 | { |
904 | int ret = 0; | 904 | int ret = 0; |
905 | 905 | ||
906 | WARN_ON(!atomic_read(&bo->kref.refcount)); | 906 | WARN_ON(!kref_read(&bo->kref)); |
907 | 907 | ||
908 | if (interruptible) | 908 | if (interruptible) |
909 | ret = ww_mutex_lock_slow_interruptible(&bo->resv->lock, | 909 | ret = ww_mutex_lock_slow_interruptible(&bo->resv->lock, |
diff --git a/include/linux/jump_label.h b/include/linux/jump_label.h index a0547c571800..b63d6b7b0db0 100644 --- a/include/linux/jump_label.h +++ b/include/linux/jump_label.h | |||
@@ -402,6 +402,6 @@ extern bool ____wrong_branch_error(void); | |||
402 | #define static_branch_enable(x) static_key_enable(&(x)->key) | 402 | #define static_branch_enable(x) static_key_enable(&(x)->key) |
403 | #define static_branch_disable(x) static_key_disable(&(x)->key) | 403 | #define static_branch_disable(x) static_key_disable(&(x)->key) |
404 | 404 | ||
405 | #endif /* _LINUX_JUMP_LABEL_H */ | ||
406 | |||
407 | #endif /* __ASSEMBLY__ */ | 405 | #endif /* __ASSEMBLY__ */ |
406 | |||
407 | #endif /* _LINUX_JUMP_LABEL_H */ | ||
diff --git a/include/linux/kref.h b/include/linux/kref.h index e15828fd71f1..f4156f88f557 100644 --- a/include/linux/kref.h +++ b/include/linux/kref.h | |||
@@ -15,22 +15,27 @@ | |||
15 | #ifndef _KREF_H_ | 15 | #ifndef _KREF_H_ |
16 | #define _KREF_H_ | 16 | #define _KREF_H_ |
17 | 17 | ||
18 | #include <linux/bug.h> | 18 | #include <linux/spinlock.h> |
19 | #include <linux/atomic.h> | 19 | #include <linux/refcount.h> |
20 | #include <linux/kernel.h> | ||
21 | #include <linux/mutex.h> | ||
22 | 20 | ||
23 | struct kref { | 21 | struct kref { |
24 | atomic_t refcount; | 22 | refcount_t refcount; |
25 | }; | 23 | }; |
26 | 24 | ||
25 | #define KREF_INIT(n) { .refcount = REFCOUNT_INIT(n), } | ||
26 | |||
27 | /** | 27 | /** |
28 | * kref_init - initialize object. | 28 | * kref_init - initialize object. |
29 | * @kref: object in question. | 29 | * @kref: object in question. |
30 | */ | 30 | */ |
31 | static inline void kref_init(struct kref *kref) | 31 | static inline void kref_init(struct kref *kref) |
32 | { | 32 | { |
33 | atomic_set(&kref->refcount, 1); | 33 | refcount_set(&kref->refcount, 1); |
34 | } | ||
35 | |||
36 | static inline unsigned int kref_read(const struct kref *kref) | ||
37 | { | ||
38 | return refcount_read(&kref->refcount); | ||
34 | } | 39 | } |
35 | 40 | ||
36 | /** | 41 | /** |
@@ -39,17 +44,12 @@ static inline void kref_init(struct kref *kref) | |||
39 | */ | 44 | */ |
40 | static inline void kref_get(struct kref *kref) | 45 | static inline void kref_get(struct kref *kref) |
41 | { | 46 | { |
42 | /* If refcount was 0 before incrementing then we have a race | 47 | refcount_inc(&kref->refcount); |
43 | * condition when this kref is freeing by some other thread right now. | ||
44 | * In this case one should use kref_get_unless_zero() | ||
45 | */ | ||
46 | WARN_ON_ONCE(atomic_inc_return(&kref->refcount) < 2); | ||
47 | } | 48 | } |
48 | 49 | ||
49 | /** | 50 | /** |
50 | * kref_sub - subtract a number of refcounts for object. | 51 | * kref_put - decrement refcount for object. |
51 | * @kref: object. | 52 | * @kref: object. |
52 | * @count: Number of recounts to subtract. | ||
53 | * @release: pointer to the function that will clean up the object when the | 53 | * @release: pointer to the function that will clean up the object when the |
54 | * last reference to the object is released. | 54 | * last reference to the object is released. |
55 | * This pointer is required, and it is not acceptable to pass kfree | 55 | * This pointer is required, and it is not acceptable to pass kfree |
@@ -58,57 +58,43 @@ static inline void kref_get(struct kref *kref) | |||
58 | * maintainer, and anyone else who happens to notice it. You have | 58 | * maintainer, and anyone else who happens to notice it. You have |
59 | * been warned. | 59 | * been warned. |
60 | * | 60 | * |
61 | * Subtract @count from the refcount, and if 0, call release(). | 61 | * Decrement the refcount, and if 0, call release(). |
62 | * Return 1 if the object was removed, otherwise return 0. Beware, if this | 62 | * Return 1 if the object was removed, otherwise return 0. Beware, if this |
63 | * function returns 0, you still can not count on the kref from remaining in | 63 | * function returns 0, you still can not count on the kref from remaining in |
64 | * memory. Only use the return value if you want to see if the kref is now | 64 | * memory. Only use the return value if you want to see if the kref is now |
65 | * gone, not present. | 65 | * gone, not present. |
66 | */ | 66 | */ |
67 | static inline int kref_sub(struct kref *kref, unsigned int count, | 67 | static inline int kref_put(struct kref *kref, void (*release)(struct kref *kref)) |
68 | void (*release)(struct kref *kref)) | ||
69 | { | 68 | { |
70 | WARN_ON(release == NULL); | 69 | WARN_ON(release == NULL); |
71 | 70 | ||
72 | if (atomic_sub_and_test((int) count, &kref->refcount)) { | 71 | if (refcount_dec_and_test(&kref->refcount)) { |
73 | release(kref); | 72 | release(kref); |
74 | return 1; | 73 | return 1; |
75 | } | 74 | } |
76 | return 0; | 75 | return 0; |
77 | } | 76 | } |
78 | 77 | ||
79 | /** | ||
80 | * kref_put - decrement refcount for object. | ||
81 | * @kref: object. | ||
82 | * @release: pointer to the function that will clean up the object when the | ||
83 | * last reference to the object is released. | ||
84 | * This pointer is required, and it is not acceptable to pass kfree | ||
85 | * in as this function. If the caller does pass kfree to this | ||
86 | * function, you will be publicly mocked mercilessly by the kref | ||
87 | * maintainer, and anyone else who happens to notice it. You have | ||
88 | * been warned. | ||
89 | * | ||
90 | * Decrement the refcount, and if 0, call release(). | ||
91 | * Return 1 if the object was removed, otherwise return 0. Beware, if this | ||
92 | * function returns 0, you still can not count on the kref from remaining in | ||
93 | * memory. Only use the return value if you want to see if the kref is now | ||
94 | * gone, not present. | ||
95 | */ | ||
96 | static inline int kref_put(struct kref *kref, void (*release)(struct kref *kref)) | ||
97 | { | ||
98 | return kref_sub(kref, 1, release); | ||
99 | } | ||
100 | |||
101 | static inline int kref_put_mutex(struct kref *kref, | 78 | static inline int kref_put_mutex(struct kref *kref, |
102 | void (*release)(struct kref *kref), | 79 | void (*release)(struct kref *kref), |
103 | struct mutex *lock) | 80 | struct mutex *lock) |
104 | { | 81 | { |
105 | WARN_ON(release == NULL); | 82 | WARN_ON(release == NULL); |
106 | if (unlikely(!atomic_add_unless(&kref->refcount, -1, 1))) { | 83 | |
107 | mutex_lock(lock); | 84 | if (refcount_dec_and_mutex_lock(&kref->refcount, lock)) { |
108 | if (unlikely(!atomic_dec_and_test(&kref->refcount))) { | 85 | release(kref); |
109 | mutex_unlock(lock); | 86 | return 1; |
110 | return 0; | 87 | } |
111 | } | 88 | return 0; |
89 | } | ||
90 | |||
91 | static inline int kref_put_lock(struct kref *kref, | ||
92 | void (*release)(struct kref *kref), | ||
93 | spinlock_t *lock) | ||
94 | { | ||
95 | WARN_ON(release == NULL); | ||
96 | |||
97 | if (refcount_dec_and_lock(&kref->refcount, lock)) { | ||
112 | release(kref); | 98 | release(kref); |
113 | return 1; | 99 | return 1; |
114 | } | 100 | } |
@@ -133,6 +119,6 @@ static inline int kref_put_mutex(struct kref *kref, | |||
133 | */ | 119 | */ |
134 | static inline int __must_check kref_get_unless_zero(struct kref *kref) | 120 | static inline int __must_check kref_get_unless_zero(struct kref *kref) |
135 | { | 121 | { |
136 | return atomic_add_unless(&kref->refcount, 1, 0); | 122 | return refcount_inc_not_zero(&kref->refcount); |
137 | } | 123 | } |
138 | #endif /* _KREF_H_ */ | 124 | #endif /* _KREF_H_ */ |
diff --git a/include/linux/mutex.h b/include/linux/mutex.h index 7fffbfcd5430..1127fe31645d 100644 --- a/include/linux/mutex.h +++ b/include/linux/mutex.h | |||
@@ -20,6 +20,8 @@ | |||
20 | #include <linux/osq_lock.h> | 20 | #include <linux/osq_lock.h> |
21 | #include <linux/debug_locks.h> | 21 | #include <linux/debug_locks.h> |
22 | 22 | ||
23 | struct ww_acquire_ctx; | ||
24 | |||
23 | /* | 25 | /* |
24 | * Simple, straightforward mutexes with strict semantics: | 26 | * Simple, straightforward mutexes with strict semantics: |
25 | * | 27 | * |
@@ -65,7 +67,7 @@ struct mutex { | |||
65 | 67 | ||
66 | static inline struct task_struct *__mutex_owner(struct mutex *lock) | 68 | static inline struct task_struct *__mutex_owner(struct mutex *lock) |
67 | { | 69 | { |
68 | return (struct task_struct *)(atomic_long_read(&lock->owner) & ~0x03); | 70 | return (struct task_struct *)(atomic_long_read(&lock->owner) & ~0x07); |
69 | } | 71 | } |
70 | 72 | ||
71 | /* | 73 | /* |
@@ -75,6 +77,7 @@ static inline struct task_struct *__mutex_owner(struct mutex *lock) | |||
75 | struct mutex_waiter { | 77 | struct mutex_waiter { |
76 | struct list_head list; | 78 | struct list_head list; |
77 | struct task_struct *task; | 79 | struct task_struct *task; |
80 | struct ww_acquire_ctx *ww_ctx; | ||
78 | #ifdef CONFIG_DEBUG_MUTEXES | 81 | #ifdef CONFIG_DEBUG_MUTEXES |
79 | void *magic; | 82 | void *magic; |
80 | #endif | 83 | #endif |
diff --git a/include/linux/percpu-rwsem.h b/include/linux/percpu-rwsem.h index 5b2e6159b744..93664f022ecf 100644 --- a/include/linux/percpu-rwsem.h +++ b/include/linux/percpu-rwsem.h | |||
@@ -4,15 +4,15 @@ | |||
4 | #include <linux/atomic.h> | 4 | #include <linux/atomic.h> |
5 | #include <linux/rwsem.h> | 5 | #include <linux/rwsem.h> |
6 | #include <linux/percpu.h> | 6 | #include <linux/percpu.h> |
7 | #include <linux/wait.h> | 7 | #include <linux/rcuwait.h> |
8 | #include <linux/rcu_sync.h> | 8 | #include <linux/rcu_sync.h> |
9 | #include <linux/lockdep.h> | 9 | #include <linux/lockdep.h> |
10 | 10 | ||
11 | struct percpu_rw_semaphore { | 11 | struct percpu_rw_semaphore { |
12 | struct rcu_sync rss; | 12 | struct rcu_sync rss; |
13 | unsigned int __percpu *read_count; | 13 | unsigned int __percpu *read_count; |
14 | struct rw_semaphore rw_sem; | 14 | struct rw_semaphore rw_sem; /* slowpath */ |
15 | wait_queue_head_t writer; | 15 | struct rcuwait writer; /* blocked writer */ |
16 | int readers_block; | 16 | int readers_block; |
17 | }; | 17 | }; |
18 | 18 | ||
@@ -22,7 +22,7 @@ static struct percpu_rw_semaphore name = { \ | |||
22 | .rss = __RCU_SYNC_INITIALIZER(name.rss, RCU_SCHED_SYNC), \ | 22 | .rss = __RCU_SYNC_INITIALIZER(name.rss, RCU_SCHED_SYNC), \ |
23 | .read_count = &__percpu_rwsem_rc_##name, \ | 23 | .read_count = &__percpu_rwsem_rc_##name, \ |
24 | .rw_sem = __RWSEM_INITIALIZER(name.rw_sem), \ | 24 | .rw_sem = __RWSEM_INITIALIZER(name.rw_sem), \ |
25 | .writer = __WAIT_QUEUE_HEAD_INITIALIZER(name.writer), \ | 25 | .writer = __RCUWAIT_INITIALIZER(name.writer), \ |
26 | } | 26 | } |
27 | 27 | ||
28 | extern int __percpu_down_read(struct percpu_rw_semaphore *, int); | 28 | extern int __percpu_down_read(struct percpu_rw_semaphore *, int); |
diff --git a/include/linux/poison.h b/include/linux/poison.h index 51334edec506..a39540326417 100644 --- a/include/linux/poison.h +++ b/include/linux/poison.h | |||
@@ -80,6 +80,7 @@ | |||
80 | /********** kernel/mutexes **********/ | 80 | /********** kernel/mutexes **********/ |
81 | #define MUTEX_DEBUG_INIT 0x11 | 81 | #define MUTEX_DEBUG_INIT 0x11 |
82 | #define MUTEX_DEBUG_FREE 0x22 | 82 | #define MUTEX_DEBUG_FREE 0x22 |
83 | #define MUTEX_POISON_WW_CTX ((void *) 0x500 + POISON_POINTER_DELTA) | ||
83 | 84 | ||
84 | /********** lib/flex_array.c **********/ | 85 | /********** lib/flex_array.c **********/ |
85 | #define FLEX_ARRAY_FREE 0x6c /* for use-after-free poisoning */ | 86 | #define FLEX_ARRAY_FREE 0x6c /* for use-after-free poisoning */ |
diff --git a/include/linux/rcuwait.h b/include/linux/rcuwait.h new file mode 100644 index 000000000000..a4ede51b3e7c --- /dev/null +++ b/include/linux/rcuwait.h | |||
@@ -0,0 +1,63 @@ | |||
1 | #ifndef _LINUX_RCUWAIT_H_ | ||
2 | #define _LINUX_RCUWAIT_H_ | ||
3 | |||
4 | #include <linux/rcupdate.h> | ||
5 | |||
6 | /* | ||
7 | * rcuwait provides a way of blocking and waking up a single | ||
8 | * task in an rcu-safe manner; where it is forbidden to use | ||
9 | * after exit_notify(). task_struct is not properly rcu protected, | ||
10 | * unless dealing with rcu-aware lists, ie: find_task_by_*(). | ||
11 | * | ||
12 | * Alternatively we have task_rcu_dereference(), but the return | ||
13 | * semantics have different implications which would break the | ||
14 | * wakeup side. The only time @task is non-nil is when a user is | ||
15 | * blocked (or checking if it needs to) on a condition, and reset | ||
16 | * as soon as we know that the condition has succeeded and are | ||
17 | * awoken. | ||
18 | */ | ||
19 | struct rcuwait { | ||
20 | struct task_struct *task; | ||
21 | }; | ||
22 | |||
23 | #define __RCUWAIT_INITIALIZER(name) \ | ||
24 | { .task = NULL, } | ||
25 | |||
26 | static inline void rcuwait_init(struct rcuwait *w) | ||
27 | { | ||
28 | w->task = NULL; | ||
29 | } | ||
30 | |||
31 | extern void rcuwait_wake_up(struct rcuwait *w); | ||
32 | |||
33 | /* | ||
34 | * The caller is responsible for locking around rcuwait_wait_event(), | ||
35 | * such that writes to @task are properly serialized. | ||
36 | */ | ||
37 | #define rcuwait_wait_event(w, condition) \ | ||
38 | ({ \ | ||
39 | /* \ | ||
40 | * Complain if we are called after do_exit()/exit_notify(), \ | ||
41 | * as we cannot rely on the rcu critical region for the \ | ||
42 | * wakeup side. \ | ||
43 | */ \ | ||
44 | WARN_ON(current->exit_state); \ | ||
45 | \ | ||
46 | rcu_assign_pointer((w)->task, current); \ | ||
47 | for (;;) { \ | ||
48 | /* \ | ||
49 | * Implicit barrier (A) pairs with (B) in \ | ||
50 | * rcuwait_wake_up(). \ | ||
51 | */ \ | ||
52 | set_current_state(TASK_UNINTERRUPTIBLE); \ | ||
53 | if (condition) \ | ||
54 | break; \ | ||
55 | \ | ||
56 | schedule(); \ | ||
57 | } \ | ||
58 | \ | ||
59 | WRITE_ONCE((w)->task, NULL); \ | ||
60 | __set_current_state(TASK_RUNNING); \ | ||
61 | }) | ||
62 | |||
63 | #endif /* _LINUX_RCUWAIT_H_ */ | ||
diff --git a/include/linux/refcount.h b/include/linux/refcount.h new file mode 100644 index 000000000000..600aadf9cca4 --- /dev/null +++ b/include/linux/refcount.h | |||
@@ -0,0 +1,294 @@ | |||
1 | #ifndef _LINUX_REFCOUNT_H | ||
2 | #define _LINUX_REFCOUNT_H | ||
3 | |||
4 | /* | ||
5 | * Variant of atomic_t specialized for reference counts. | ||
6 | * | ||
7 | * The interface matches the atomic_t interface (to aid in porting) but only | ||
8 | * provides the few functions one should use for reference counting. | ||
9 | * | ||
10 | * It differs in that the counter saturates at UINT_MAX and will not move once | ||
11 | * there. This avoids wrapping the counter and causing 'spurious' | ||
12 | * use-after-free issues. | ||
13 | * | ||
14 | * Memory ordering rules are slightly relaxed wrt regular atomic_t functions | ||
15 | * and provide only what is strictly required for refcounts. | ||
16 | * | ||
17 | * The increments are fully relaxed; these will not provide ordering. The | ||
18 | * rationale is that whatever is used to obtain the object we're increasing the | ||
19 | * reference count on will provide the ordering. For locked data structures, | ||
20 | * its the lock acquire, for RCU/lockless data structures its the dependent | ||
21 | * load. | ||
22 | * | ||
23 | * Do note that inc_not_zero() provides a control dependency which will order | ||
24 | * future stores against the inc, this ensures we'll never modify the object | ||
25 | * if we did not in fact acquire a reference. | ||
26 | * | ||
27 | * The decrements will provide release order, such that all the prior loads and | ||
28 | * stores will be issued before, it also provides a control dependency, which | ||
29 | * will order us against the subsequent free(). | ||
30 | * | ||
31 | * The control dependency is against the load of the cmpxchg (ll/sc) that | ||
32 | * succeeded. This means the stores aren't fully ordered, but this is fine | ||
33 | * because the 1->0 transition indicates no concurrency. | ||
34 | * | ||
35 | * Note that the allocator is responsible for ordering things between free() | ||
36 | * and alloc(). | ||
37 | * | ||
38 | */ | ||
39 | |||
40 | #include <linux/atomic.h> | ||
41 | #include <linux/bug.h> | ||
42 | #include <linux/mutex.h> | ||
43 | #include <linux/spinlock.h> | ||
44 | |||
45 | #ifdef CONFIG_DEBUG_REFCOUNT | ||
46 | #define REFCOUNT_WARN(cond, str) WARN_ON(cond) | ||
47 | #define __refcount_check __must_check | ||
48 | #else | ||
49 | #define REFCOUNT_WARN(cond, str) (void)(cond) | ||
50 | #define __refcount_check | ||
51 | #endif | ||
52 | |||
53 | typedef struct refcount_struct { | ||
54 | atomic_t refs; | ||
55 | } refcount_t; | ||
56 | |||
57 | #define REFCOUNT_INIT(n) { .refs = ATOMIC_INIT(n), } | ||
58 | |||
59 | static inline void refcount_set(refcount_t *r, unsigned int n) | ||
60 | { | ||
61 | atomic_set(&r->refs, n); | ||
62 | } | ||
63 | |||
64 | static inline unsigned int refcount_read(const refcount_t *r) | ||
65 | { | ||
66 | return atomic_read(&r->refs); | ||
67 | } | ||
68 | |||
69 | static inline __refcount_check | ||
70 | bool refcount_add_not_zero(unsigned int i, refcount_t *r) | ||
71 | { | ||
72 | unsigned int old, new, val = atomic_read(&r->refs); | ||
73 | |||
74 | for (;;) { | ||
75 | if (!val) | ||
76 | return false; | ||
77 | |||
78 | if (unlikely(val == UINT_MAX)) | ||
79 | return true; | ||
80 | |||
81 | new = val + i; | ||
82 | if (new < val) | ||
83 | new = UINT_MAX; | ||
84 | old = atomic_cmpxchg_relaxed(&r->refs, val, new); | ||
85 | if (old == val) | ||
86 | break; | ||
87 | |||
88 | val = old; | ||
89 | } | ||
90 | |||
91 | REFCOUNT_WARN(new == UINT_MAX, "refcount_t: saturated; leaking memory.\n"); | ||
92 | |||
93 | return true; | ||
94 | } | ||
95 | |||
96 | static inline void refcount_add(unsigned int i, refcount_t *r) | ||
97 | { | ||
98 | REFCOUNT_WARN(!refcount_add_not_zero(i, r), "refcount_t: addition on 0; use-after-free.\n"); | ||
99 | } | ||
100 | |||
101 | /* | ||
102 | * Similar to atomic_inc_not_zero(), will saturate at UINT_MAX and WARN. | ||
103 | * | ||
104 | * Provides no memory ordering, it is assumed the caller has guaranteed the | ||
105 | * object memory to be stable (RCU, etc.). It does provide a control dependency | ||
106 | * and thereby orders future stores. See the comment on top. | ||
107 | */ | ||
108 | static inline __refcount_check | ||
109 | bool refcount_inc_not_zero(refcount_t *r) | ||
110 | { | ||
111 | unsigned int old, new, val = atomic_read(&r->refs); | ||
112 | |||
113 | for (;;) { | ||
114 | new = val + 1; | ||
115 | |||
116 | if (!val) | ||
117 | return false; | ||
118 | |||
119 | if (unlikely(!new)) | ||
120 | return true; | ||
121 | |||
122 | old = atomic_cmpxchg_relaxed(&r->refs, val, new); | ||
123 | if (old == val) | ||
124 | break; | ||
125 | |||
126 | val = old; | ||
127 | } | ||
128 | |||
129 | REFCOUNT_WARN(new == UINT_MAX, "refcount_t: saturated; leaking memory.\n"); | ||
130 | |||
131 | return true; | ||
132 | } | ||
133 | |||
134 | /* | ||
135 | * Similar to atomic_inc(), will saturate at UINT_MAX and WARN. | ||
136 | * | ||
137 | * Provides no memory ordering, it is assumed the caller already has a | ||
138 | * reference on the object, will WARN when this is not so. | ||
139 | */ | ||
140 | static inline void refcount_inc(refcount_t *r) | ||
141 | { | ||
142 | REFCOUNT_WARN(!refcount_inc_not_zero(r), "refcount_t: increment on 0; use-after-free.\n"); | ||
143 | } | ||
144 | |||
145 | /* | ||
146 | * Similar to atomic_dec_and_test(), it will WARN on underflow and fail to | ||
147 | * decrement when saturated at UINT_MAX. | ||
148 | * | ||
149 | * Provides release memory ordering, such that prior loads and stores are done | ||
150 | * before, and provides a control dependency such that free() must come after. | ||
151 | * See the comment on top. | ||
152 | */ | ||
153 | static inline __refcount_check | ||
154 | bool refcount_sub_and_test(unsigned int i, refcount_t *r) | ||
155 | { | ||
156 | unsigned int old, new, val = atomic_read(&r->refs); | ||
157 | |||
158 | for (;;) { | ||
159 | if (unlikely(val == UINT_MAX)) | ||
160 | return false; | ||
161 | |||
162 | new = val - i; | ||
163 | if (new > val) { | ||
164 | REFCOUNT_WARN(new > val, "refcount_t: underflow; use-after-free.\n"); | ||
165 | return false; | ||
166 | } | ||
167 | |||
168 | old = atomic_cmpxchg_release(&r->refs, val, new); | ||
169 | if (old == val) | ||
170 | break; | ||
171 | |||
172 | val = old; | ||
173 | } | ||
174 | |||
175 | return !new; | ||
176 | } | ||
177 | |||
178 | static inline __refcount_check | ||
179 | bool refcount_dec_and_test(refcount_t *r) | ||
180 | { | ||
181 | return refcount_sub_and_test(1, r); | ||
182 | } | ||
183 | |||
184 | /* | ||
185 | * Similar to atomic_dec(), it will WARN on underflow and fail to decrement | ||
186 | * when saturated at UINT_MAX. | ||
187 | * | ||
188 | * Provides release memory ordering, such that prior loads and stores are done | ||
189 | * before. | ||
190 | */ | ||
191 | static inline | ||
192 | void refcount_dec(refcount_t *r) | ||
193 | { | ||
194 | REFCOUNT_WARN(refcount_dec_and_test(r), "refcount_t: decrement hit 0; leaking memory.\n"); | ||
195 | } | ||
196 | |||
197 | /* | ||
198 | * No atomic_t counterpart, it attempts a 1 -> 0 transition and returns the | ||
199 | * success thereof. | ||
200 | * | ||
201 | * Like all decrement operations, it provides release memory order and provides | ||
202 | * a control dependency. | ||
203 | * | ||
204 | * It can be used like a try-delete operator; this explicit case is provided | ||
205 | * and not cmpxchg in generic, because that would allow implementing unsafe | ||
206 | * operations. | ||
207 | */ | ||
208 | static inline __refcount_check | ||
209 | bool refcount_dec_if_one(refcount_t *r) | ||
210 | { | ||
211 | return atomic_cmpxchg_release(&r->refs, 1, 0) == 1; | ||
212 | } | ||
213 | |||
214 | /* | ||
215 | * No atomic_t counterpart, it decrements unless the value is 1, in which case | ||
216 | * it will return false. | ||
217 | * | ||
218 | * Was often done like: atomic_add_unless(&var, -1, 1) | ||
219 | */ | ||
220 | static inline __refcount_check | ||
221 | bool refcount_dec_not_one(refcount_t *r) | ||
222 | { | ||
223 | unsigned int old, new, val = atomic_read(&r->refs); | ||
224 | |||
225 | for (;;) { | ||
226 | if (unlikely(val == UINT_MAX)) | ||
227 | return true; | ||
228 | |||
229 | if (val == 1) | ||
230 | return false; | ||
231 | |||
232 | new = val - 1; | ||
233 | if (new > val) { | ||
234 | REFCOUNT_WARN(new > val, "refcount_t: underflow; use-after-free.\n"); | ||
235 | return true; | ||
236 | } | ||
237 | |||
238 | old = atomic_cmpxchg_release(&r->refs, val, new); | ||
239 | if (old == val) | ||
240 | break; | ||
241 | |||
242 | val = old; | ||
243 | } | ||
244 | |||
245 | return true; | ||
246 | } | ||
247 | |||
248 | /* | ||
249 | * Similar to atomic_dec_and_mutex_lock(), it will WARN on underflow and fail | ||
250 | * to decrement when saturated at UINT_MAX. | ||
251 | * | ||
252 | * Provides release memory ordering, such that prior loads and stores are done | ||
253 | * before, and provides a control dependency such that free() must come after. | ||
254 | * See the comment on top. | ||
255 | */ | ||
256 | static inline __refcount_check | ||
257 | bool refcount_dec_and_mutex_lock(refcount_t *r, struct mutex *lock) | ||
258 | { | ||
259 | if (refcount_dec_not_one(r)) | ||
260 | return false; | ||
261 | |||
262 | mutex_lock(lock); | ||
263 | if (!refcount_dec_and_test(r)) { | ||
264 | mutex_unlock(lock); | ||
265 | return false; | ||
266 | } | ||
267 | |||
268 | return true; | ||
269 | } | ||
270 | |||
271 | /* | ||
272 | * Similar to atomic_dec_and_lock(), it will WARN on underflow and fail to | ||
273 | * decrement when saturated at UINT_MAX. | ||
274 | * | ||
275 | * Provides release memory ordering, such that prior loads and stores are done | ||
276 | * before, and provides a control dependency such that free() must come after. | ||
277 | * See the comment on top. | ||
278 | */ | ||
279 | static inline __refcount_check | ||
280 | bool refcount_dec_and_lock(refcount_t *r, spinlock_t *lock) | ||
281 | { | ||
282 | if (refcount_dec_not_one(r)) | ||
283 | return false; | ||
284 | |||
285 | spin_lock(lock); | ||
286 | if (!refcount_dec_and_test(r)) { | ||
287 | spin_unlock(lock); | ||
288 | return false; | ||
289 | } | ||
290 | |||
291 | return true; | ||
292 | } | ||
293 | |||
294 | #endif /* _LINUX_REFCOUNT_H */ | ||
diff --git a/include/linux/sched.h b/include/linux/sched.h index c89b7fdec41e..c8e519d0b4a3 100644 --- a/include/linux/sched.h +++ b/include/linux/sched.h | |||
@@ -226,7 +226,7 @@ extern void proc_sched_set_task(struct task_struct *p); | |||
226 | extern char ___assert_task_state[1 - 2*!!( | 226 | extern char ___assert_task_state[1 - 2*!!( |
227 | sizeof(TASK_STATE_TO_CHAR_STR)-1 != ilog2(TASK_STATE_MAX)+1)]; | 227 | sizeof(TASK_STATE_TO_CHAR_STR)-1 != ilog2(TASK_STATE_MAX)+1)]; |
228 | 228 | ||
229 | /* Convenience macros for the sake of set_task_state */ | 229 | /* Convenience macros for the sake of set_current_state */ |
230 | #define TASK_KILLABLE (TASK_WAKEKILL | TASK_UNINTERRUPTIBLE) | 230 | #define TASK_KILLABLE (TASK_WAKEKILL | TASK_UNINTERRUPTIBLE) |
231 | #define TASK_STOPPED (TASK_WAKEKILL | __TASK_STOPPED) | 231 | #define TASK_STOPPED (TASK_WAKEKILL | __TASK_STOPPED) |
232 | #define TASK_TRACED (TASK_WAKEKILL | __TASK_TRACED) | 232 | #define TASK_TRACED (TASK_WAKEKILL | __TASK_TRACED) |
@@ -253,17 +253,6 @@ extern char ___assert_task_state[1 - 2*!!( | |||
253 | 253 | ||
254 | #ifdef CONFIG_DEBUG_ATOMIC_SLEEP | 254 | #ifdef CONFIG_DEBUG_ATOMIC_SLEEP |
255 | 255 | ||
256 | #define __set_task_state(tsk, state_value) \ | ||
257 | do { \ | ||
258 | (tsk)->task_state_change = _THIS_IP_; \ | ||
259 | (tsk)->state = (state_value); \ | ||
260 | } while (0) | ||
261 | #define set_task_state(tsk, state_value) \ | ||
262 | do { \ | ||
263 | (tsk)->task_state_change = _THIS_IP_; \ | ||
264 | smp_store_mb((tsk)->state, (state_value)); \ | ||
265 | } while (0) | ||
266 | |||
267 | #define __set_current_state(state_value) \ | 256 | #define __set_current_state(state_value) \ |
268 | do { \ | 257 | do { \ |
269 | current->task_state_change = _THIS_IP_; \ | 258 | current->task_state_change = _THIS_IP_; \ |
@@ -276,20 +265,6 @@ extern char ___assert_task_state[1 - 2*!!( | |||
276 | } while (0) | 265 | } while (0) |
277 | 266 | ||
278 | #else | 267 | #else |
279 | |||
280 | /* | ||
281 | * @tsk had better be current, or you get to keep the pieces. | ||
282 | * | ||
283 | * The only reason is that computing current can be more expensive than | ||
284 | * using a pointer that's already available. | ||
285 | * | ||
286 | * Therefore, see set_current_state(). | ||
287 | */ | ||
288 | #define __set_task_state(tsk, state_value) \ | ||
289 | do { (tsk)->state = (state_value); } while (0) | ||
290 | #define set_task_state(tsk, state_value) \ | ||
291 | smp_store_mb((tsk)->state, (state_value)) | ||
292 | |||
293 | /* | 268 | /* |
294 | * set_current_state() includes a barrier so that the write of current->state | 269 | * set_current_state() includes a barrier so that the write of current->state |
295 | * is correctly serialised wrt the caller's subsequent test of whether to | 270 | * is correctly serialised wrt the caller's subsequent test of whether to |
@@ -1018,8 +993,8 @@ enum cpu_idle_type { | |||
1018 | * | 993 | * |
1019 | * The DEFINE_WAKE_Q macro declares and initializes the list head. | 994 | * The DEFINE_WAKE_Q macro declares and initializes the list head. |
1020 | * wake_up_q() does NOT reinitialize the list; it's expected to be | 995 | * wake_up_q() does NOT reinitialize the list; it's expected to be |
1021 | * called near the end of a function, where the fact that the queue is | 996 | * called near the end of a function. Otherwise, the list can be |
1022 | * not used again will be easy to see by inspection. | 997 | * re-initialized for later re-use by wake_q_init(). |
1023 | * | 998 | * |
1024 | * Note that this can cause spurious wakeups. schedule() callers | 999 | * Note that this can cause spurious wakeups. schedule() callers |
1025 | * must ensure the call is done inside a loop, confirming that the | 1000 | * must ensure the call is done inside a loop, confirming that the |
@@ -1039,6 +1014,12 @@ struct wake_q_head { | |||
1039 | #define DEFINE_WAKE_Q(name) \ | 1014 | #define DEFINE_WAKE_Q(name) \ |
1040 | struct wake_q_head name = { WAKE_Q_TAIL, &name.first } | 1015 | struct wake_q_head name = { WAKE_Q_TAIL, &name.first } |
1041 | 1016 | ||
1017 | static inline void wake_q_init(struct wake_q_head *head) | ||
1018 | { | ||
1019 | head->first = WAKE_Q_TAIL; | ||
1020 | head->lastp = &head->first; | ||
1021 | } | ||
1022 | |||
1042 | extern void wake_q_add(struct wake_q_head *head, | 1023 | extern void wake_q_add(struct wake_q_head *head, |
1043 | struct task_struct *task); | 1024 | struct task_struct *task); |
1044 | extern void wake_up_q(struct wake_q_head *head); | 1025 | extern void wake_up_q(struct wake_q_head *head); |
diff --git a/include/linux/spinlock.h b/include/linux/spinlock.h index 47dd0cebd204..59248dcc6ef3 100644 --- a/include/linux/spinlock.h +++ b/include/linux/spinlock.h | |||
@@ -180,8 +180,6 @@ static inline void do_raw_spin_unlock(raw_spinlock_t *lock) __releases(lock) | |||
180 | #ifdef CONFIG_DEBUG_LOCK_ALLOC | 180 | #ifdef CONFIG_DEBUG_LOCK_ALLOC |
181 | # define raw_spin_lock_nested(lock, subclass) \ | 181 | # define raw_spin_lock_nested(lock, subclass) \ |
182 | _raw_spin_lock_nested(lock, subclass) | 182 | _raw_spin_lock_nested(lock, subclass) |
183 | # define raw_spin_lock_bh_nested(lock, subclass) \ | ||
184 | _raw_spin_lock_bh_nested(lock, subclass) | ||
185 | 183 | ||
186 | # define raw_spin_lock_nest_lock(lock, nest_lock) \ | 184 | # define raw_spin_lock_nest_lock(lock, nest_lock) \ |
187 | do { \ | 185 | do { \ |
@@ -197,7 +195,6 @@ static inline void do_raw_spin_unlock(raw_spinlock_t *lock) __releases(lock) | |||
197 | # define raw_spin_lock_nested(lock, subclass) \ | 195 | # define raw_spin_lock_nested(lock, subclass) \ |
198 | _raw_spin_lock(((void)(subclass), (lock))) | 196 | _raw_spin_lock(((void)(subclass), (lock))) |
199 | # define raw_spin_lock_nest_lock(lock, nest_lock) _raw_spin_lock(lock) | 197 | # define raw_spin_lock_nest_lock(lock, nest_lock) _raw_spin_lock(lock) |
200 | # define raw_spin_lock_bh_nested(lock, subclass) _raw_spin_lock_bh(lock) | ||
201 | #endif | 198 | #endif |
202 | 199 | ||
203 | #if defined(CONFIG_SMP) || defined(CONFIG_DEBUG_SPINLOCK) | 200 | #if defined(CONFIG_SMP) || defined(CONFIG_DEBUG_SPINLOCK) |
@@ -317,11 +314,6 @@ do { \ | |||
317 | raw_spin_lock_nested(spinlock_check(lock), subclass); \ | 314 | raw_spin_lock_nested(spinlock_check(lock), subclass); \ |
318 | } while (0) | 315 | } while (0) |
319 | 316 | ||
320 | #define spin_lock_bh_nested(lock, subclass) \ | ||
321 | do { \ | ||
322 | raw_spin_lock_bh_nested(spinlock_check(lock), subclass);\ | ||
323 | } while (0) | ||
324 | |||
325 | #define spin_lock_nest_lock(lock, nest_lock) \ | 317 | #define spin_lock_nest_lock(lock, nest_lock) \ |
326 | do { \ | 318 | do { \ |
327 | raw_spin_lock_nest_lock(spinlock_check(lock), nest_lock); \ | 319 | raw_spin_lock_nest_lock(spinlock_check(lock), nest_lock); \ |
diff --git a/include/linux/spinlock_api_smp.h b/include/linux/spinlock_api_smp.h index 5344268e6e62..42dfab89e740 100644 --- a/include/linux/spinlock_api_smp.h +++ b/include/linux/spinlock_api_smp.h | |||
@@ -22,8 +22,6 @@ int in_lock_functions(unsigned long addr); | |||
22 | void __lockfunc _raw_spin_lock(raw_spinlock_t *lock) __acquires(lock); | 22 | void __lockfunc _raw_spin_lock(raw_spinlock_t *lock) __acquires(lock); |
23 | void __lockfunc _raw_spin_lock_nested(raw_spinlock_t *lock, int subclass) | 23 | void __lockfunc _raw_spin_lock_nested(raw_spinlock_t *lock, int subclass) |
24 | __acquires(lock); | 24 | __acquires(lock); |
25 | void __lockfunc _raw_spin_lock_bh_nested(raw_spinlock_t *lock, int subclass) | ||
26 | __acquires(lock); | ||
27 | void __lockfunc | 25 | void __lockfunc |
28 | _raw_spin_lock_nest_lock(raw_spinlock_t *lock, struct lockdep_map *map) | 26 | _raw_spin_lock_nest_lock(raw_spinlock_t *lock, struct lockdep_map *map) |
29 | __acquires(lock); | 27 | __acquires(lock); |
diff --git a/include/linux/spinlock_api_up.h b/include/linux/spinlock_api_up.h index d3afef9d8dbe..d0d188861ad6 100644 --- a/include/linux/spinlock_api_up.h +++ b/include/linux/spinlock_api_up.h | |||
@@ -57,7 +57,6 @@ | |||
57 | 57 | ||
58 | #define _raw_spin_lock(lock) __LOCK(lock) | 58 | #define _raw_spin_lock(lock) __LOCK(lock) |
59 | #define _raw_spin_lock_nested(lock, subclass) __LOCK(lock) | 59 | #define _raw_spin_lock_nested(lock, subclass) __LOCK(lock) |
60 | #define _raw_spin_lock_bh_nested(lock, subclass) __LOCK(lock) | ||
61 | #define _raw_read_lock(lock) __LOCK(lock) | 60 | #define _raw_read_lock(lock) __LOCK(lock) |
62 | #define _raw_write_lock(lock) __LOCK(lock) | 61 | #define _raw_write_lock(lock) __LOCK(lock) |
63 | #define _raw_spin_lock_bh(lock) __LOCK_BH(lock) | 62 | #define _raw_spin_lock_bh(lock) __LOCK_BH(lock) |
diff --git a/include/linux/sunrpc/cache.h b/include/linux/sunrpc/cache.h index 62a60eeacb0a..8a511c0985aa 100644 --- a/include/linux/sunrpc/cache.h +++ b/include/linux/sunrpc/cache.h | |||
@@ -198,7 +198,7 @@ static inline struct cache_head *cache_get(struct cache_head *h) | |||
198 | 198 | ||
199 | static inline void cache_put(struct cache_head *h, struct cache_detail *cd) | 199 | static inline void cache_put(struct cache_head *h, struct cache_detail *cd) |
200 | { | 200 | { |
201 | if (atomic_read(&h->ref.refcount) <= 2 && | 201 | if (kref_read(&h->ref) <= 2 && |
202 | h->expiry_time < cd->nextcheck) | 202 | h->expiry_time < cd->nextcheck) |
203 | cd->nextcheck = h->expiry_time; | 203 | cd->nextcheck = h->expiry_time; |
204 | kref_put(&h->ref, cd->cache_put); | 204 | kref_put(&h->ref, cd->cache_put); |
diff --git a/include/linux/ww_mutex.h b/include/linux/ww_mutex.h index 7b0066814fa0..5dd9a7682227 100644 --- a/include/linux/ww_mutex.h +++ b/include/linux/ww_mutex.h | |||
@@ -51,10 +51,10 @@ struct ww_mutex { | |||
51 | }; | 51 | }; |
52 | 52 | ||
53 | #ifdef CONFIG_DEBUG_LOCK_ALLOC | 53 | #ifdef CONFIG_DEBUG_LOCK_ALLOC |
54 | # define __WW_CLASS_MUTEX_INITIALIZER(lockname, ww_class) \ | 54 | # define __WW_CLASS_MUTEX_INITIALIZER(lockname, class) \ |
55 | , .ww_class = &ww_class | 55 | , .ww_class = class |
56 | #else | 56 | #else |
57 | # define __WW_CLASS_MUTEX_INITIALIZER(lockname, ww_class) | 57 | # define __WW_CLASS_MUTEX_INITIALIZER(lockname, class) |
58 | #endif | 58 | #endif |
59 | 59 | ||
60 | #define __WW_CLASS_INITIALIZER(ww_class) \ | 60 | #define __WW_CLASS_INITIALIZER(ww_class) \ |
@@ -63,7 +63,7 @@ struct ww_mutex { | |||
63 | , .mutex_name = #ww_class "_mutex" } | 63 | , .mutex_name = #ww_class "_mutex" } |
64 | 64 | ||
65 | #define __WW_MUTEX_INITIALIZER(lockname, class) \ | 65 | #define __WW_MUTEX_INITIALIZER(lockname, class) \ |
66 | { .base = { \__MUTEX_INITIALIZER(lockname) } \ | 66 | { .base = __MUTEX_INITIALIZER(lockname.base) \ |
67 | __WW_CLASS_MUTEX_INITIALIZER(lockname, class) } | 67 | __WW_CLASS_MUTEX_INITIALIZER(lockname, class) } |
68 | 68 | ||
69 | #define DEFINE_WW_CLASS(classname) \ | 69 | #define DEFINE_WW_CLASS(classname) \ |
@@ -186,11 +186,6 @@ static inline void ww_acquire_fini(struct ww_acquire_ctx *ctx) | |||
186 | #endif | 186 | #endif |
187 | } | 187 | } |
188 | 188 | ||
189 | extern int __must_check __ww_mutex_lock(struct ww_mutex *lock, | ||
190 | struct ww_acquire_ctx *ctx); | ||
191 | extern int __must_check __ww_mutex_lock_interruptible(struct ww_mutex *lock, | ||
192 | struct ww_acquire_ctx *ctx); | ||
193 | |||
194 | /** | 189 | /** |
195 | * ww_mutex_lock - acquire the w/w mutex | 190 | * ww_mutex_lock - acquire the w/w mutex |
196 | * @lock: the mutex to be acquired | 191 | * @lock: the mutex to be acquired |
@@ -220,14 +215,7 @@ extern int __must_check __ww_mutex_lock_interruptible(struct ww_mutex *lock, | |||
220 | * | 215 | * |
221 | * A mutex acquired with this function must be released with ww_mutex_unlock. | 216 | * A mutex acquired with this function must be released with ww_mutex_unlock. |
222 | */ | 217 | */ |
223 | static inline int ww_mutex_lock(struct ww_mutex *lock, struct ww_acquire_ctx *ctx) | 218 | extern int /* __must_check */ ww_mutex_lock(struct ww_mutex *lock, struct ww_acquire_ctx *ctx); |
224 | { | ||
225 | if (ctx) | ||
226 | return __ww_mutex_lock(lock, ctx); | ||
227 | |||
228 | mutex_lock(&lock->base); | ||
229 | return 0; | ||
230 | } | ||
231 | 219 | ||
232 | /** | 220 | /** |
233 | * ww_mutex_lock_interruptible - acquire the w/w mutex, interruptible | 221 | * ww_mutex_lock_interruptible - acquire the w/w mutex, interruptible |
@@ -259,14 +247,8 @@ static inline int ww_mutex_lock(struct ww_mutex *lock, struct ww_acquire_ctx *ct | |||
259 | * | 247 | * |
260 | * A mutex acquired with this function must be released with ww_mutex_unlock. | 248 | * A mutex acquired with this function must be released with ww_mutex_unlock. |
261 | */ | 249 | */ |
262 | static inline int __must_check ww_mutex_lock_interruptible(struct ww_mutex *lock, | 250 | extern int __must_check ww_mutex_lock_interruptible(struct ww_mutex *lock, |
263 | struct ww_acquire_ctx *ctx) | 251 | struct ww_acquire_ctx *ctx); |
264 | { | ||
265 | if (ctx) | ||
266 | return __ww_mutex_lock_interruptible(lock, ctx); | ||
267 | else | ||
268 | return mutex_lock_interruptible(&lock->base); | ||
269 | } | ||
270 | 252 | ||
271 | /** | 253 | /** |
272 | * ww_mutex_lock_slow - slowpath acquiring of the w/w mutex | 254 | * ww_mutex_lock_slow - slowpath acquiring of the w/w mutex |
diff --git a/include/net/bluetooth/hci_core.h b/include/net/bluetooth/hci_core.h index 554671c81f4a..90708f68cc02 100644 --- a/include/net/bluetooth/hci_core.h +++ b/include/net/bluetooth/hci_core.h | |||
@@ -987,7 +987,7 @@ static inline void hci_conn_drop(struct hci_conn *conn) | |||
987 | static inline void hci_dev_put(struct hci_dev *d) | 987 | static inline void hci_dev_put(struct hci_dev *d) |
988 | { | 988 | { |
989 | BT_DBG("%s orig refcnt %d", d->name, | 989 | BT_DBG("%s orig refcnt %d", d->name, |
990 | atomic_read(&d->dev.kobj.kref.refcount)); | 990 | kref_read(&d->dev.kobj.kref)); |
991 | 991 | ||
992 | put_device(&d->dev); | 992 | put_device(&d->dev); |
993 | } | 993 | } |
@@ -995,7 +995,7 @@ static inline void hci_dev_put(struct hci_dev *d) | |||
995 | static inline struct hci_dev *hci_dev_hold(struct hci_dev *d) | 995 | static inline struct hci_dev *hci_dev_hold(struct hci_dev *d) |
996 | { | 996 | { |
997 | BT_DBG("%s orig refcnt %d", d->name, | 997 | BT_DBG("%s orig refcnt %d", d->name, |
998 | atomic_read(&d->dev.kobj.kref.refcount)); | 998 | kref_read(&d->dev.kobj.kref)); |
999 | 999 | ||
1000 | get_device(&d->dev); | 1000 | get_device(&d->dev); |
1001 | return d; | 1001 | return d; |
diff --git a/init/version.c b/init/version.c index fe41a63efed6..5606341e9efd 100644 --- a/init/version.c +++ b/init/version.c | |||
@@ -23,9 +23,7 @@ int version_string(LINUX_VERSION_CODE); | |||
23 | #endif | 23 | #endif |
24 | 24 | ||
25 | struct uts_namespace init_uts_ns = { | 25 | struct uts_namespace init_uts_ns = { |
26 | .kref = { | 26 | .kref = KREF_INIT(2), |
27 | .refcount = ATOMIC_INIT(2), | ||
28 | }, | ||
29 | .name = { | 27 | .name = { |
30 | .sysname = UTS_SYSNAME, | 28 | .sysname = UTS_SYSNAME, |
31 | .nodename = UTS_NODENAME, | 29 | .nodename = UTS_NODENAME, |
diff --git a/kernel/exit.c b/kernel/exit.c index 8e5e21338b3a..b67c57faa705 100644 --- a/kernel/exit.c +++ b/kernel/exit.c | |||
@@ -55,6 +55,7 @@ | |||
55 | #include <linux/shm.h> | 55 | #include <linux/shm.h> |
56 | #include <linux/kcov.h> | 56 | #include <linux/kcov.h> |
57 | #include <linux/random.h> | 57 | #include <linux/random.h> |
58 | #include <linux/rcuwait.h> | ||
58 | 59 | ||
59 | #include <linux/uaccess.h> | 60 | #include <linux/uaccess.h> |
60 | #include <asm/unistd.h> | 61 | #include <asm/unistd.h> |
@@ -282,6 +283,35 @@ retry: | |||
282 | return task; | 283 | return task; |
283 | } | 284 | } |
284 | 285 | ||
286 | void rcuwait_wake_up(struct rcuwait *w) | ||
287 | { | ||
288 | struct task_struct *task; | ||
289 | |||
290 | rcu_read_lock(); | ||
291 | |||
292 | /* | ||
293 | * Order condition vs @task, such that everything prior to the load | ||
294 | * of @task is visible. This is the condition as to why the user called | ||
295 | * rcuwait_trywake() in the first place. Pairs with set_current_state() | ||
296 | * barrier (A) in rcuwait_wait_event(). | ||
297 | * | ||
298 | * WAIT WAKE | ||
299 | * [S] tsk = current [S] cond = true | ||
300 | * MB (A) MB (B) | ||
301 | * [L] cond [L] tsk | ||
302 | */ | ||
303 | smp_rmb(); /* (B) */ | ||
304 | |||
305 | /* | ||
306 | * Avoid using task_rcu_dereference() magic as long as we are careful, | ||
307 | * see comment in rcuwait_wait_event() regarding ->exit_state. | ||
308 | */ | ||
309 | task = rcu_dereference(w->task); | ||
310 | if (task) | ||
311 | wake_up_process(task); | ||
312 | rcu_read_unlock(); | ||
313 | } | ||
314 | |||
285 | struct task_struct *try_get_task_struct(struct task_struct **ptask) | 315 | struct task_struct *try_get_task_struct(struct task_struct **ptask) |
286 | { | 316 | { |
287 | struct task_struct *task; | 317 | struct task_struct *task; |
@@ -468,12 +498,12 @@ assign_new_owner: | |||
468 | * Turn us into a lazy TLB process if we | 498 | * Turn us into a lazy TLB process if we |
469 | * aren't already.. | 499 | * aren't already.. |
470 | */ | 500 | */ |
471 | static void exit_mm(struct task_struct *tsk) | 501 | static void exit_mm(void) |
472 | { | 502 | { |
473 | struct mm_struct *mm = tsk->mm; | 503 | struct mm_struct *mm = current->mm; |
474 | struct core_state *core_state; | 504 | struct core_state *core_state; |
475 | 505 | ||
476 | mm_release(tsk, mm); | 506 | mm_release(current, mm); |
477 | if (!mm) | 507 | if (!mm) |
478 | return; | 508 | return; |
479 | sync_mm_rss(mm); | 509 | sync_mm_rss(mm); |
@@ -491,7 +521,7 @@ static void exit_mm(struct task_struct *tsk) | |||
491 | 521 | ||
492 | up_read(&mm->mmap_sem); | 522 | up_read(&mm->mmap_sem); |
493 | 523 | ||
494 | self.task = tsk; | 524 | self.task = current; |
495 | self.next = xchg(&core_state->dumper.next, &self); | 525 | self.next = xchg(&core_state->dumper.next, &self); |
496 | /* | 526 | /* |
497 | * Implies mb(), the result of xchg() must be visible | 527 | * Implies mb(), the result of xchg() must be visible |
@@ -501,22 +531,22 @@ static void exit_mm(struct task_struct *tsk) | |||
501 | complete(&core_state->startup); | 531 | complete(&core_state->startup); |
502 | 532 | ||
503 | for (;;) { | 533 | for (;;) { |
504 | set_task_state(tsk, TASK_UNINTERRUPTIBLE); | 534 | set_current_state(TASK_UNINTERRUPTIBLE); |
505 | if (!self.task) /* see coredump_finish() */ | 535 | if (!self.task) /* see coredump_finish() */ |
506 | break; | 536 | break; |
507 | freezable_schedule(); | 537 | freezable_schedule(); |
508 | } | 538 | } |
509 | __set_task_state(tsk, TASK_RUNNING); | 539 | __set_current_state(TASK_RUNNING); |
510 | down_read(&mm->mmap_sem); | 540 | down_read(&mm->mmap_sem); |
511 | } | 541 | } |
512 | atomic_inc(&mm->mm_count); | 542 | atomic_inc(&mm->mm_count); |
513 | BUG_ON(mm != tsk->active_mm); | 543 | BUG_ON(mm != current->active_mm); |
514 | /* more a memory barrier than a real lock */ | 544 | /* more a memory barrier than a real lock */ |
515 | task_lock(tsk); | 545 | task_lock(current); |
516 | tsk->mm = NULL; | 546 | current->mm = NULL; |
517 | up_read(&mm->mmap_sem); | 547 | up_read(&mm->mmap_sem); |
518 | enter_lazy_tlb(mm, current); | 548 | enter_lazy_tlb(mm, current); |
519 | task_unlock(tsk); | 549 | task_unlock(current); |
520 | mm_update_next_owner(mm); | 550 | mm_update_next_owner(mm); |
521 | mmput(mm); | 551 | mmput(mm); |
522 | if (test_thread_flag(TIF_MEMDIE)) | 552 | if (test_thread_flag(TIF_MEMDIE)) |
@@ -823,7 +853,7 @@ void __noreturn do_exit(long code) | |||
823 | tsk->exit_code = code; | 853 | tsk->exit_code = code; |
824 | taskstats_exit(tsk, group_dead); | 854 | taskstats_exit(tsk, group_dead); |
825 | 855 | ||
826 | exit_mm(tsk); | 856 | exit_mm(); |
827 | 857 | ||
828 | if (group_dead) | 858 | if (group_dead) |
829 | acct_process(); | 859 | acct_process(); |
diff --git a/kernel/fork.c b/kernel/fork.c index f6995cdfe714..ff82e24573b6 100644 --- a/kernel/fork.c +++ b/kernel/fork.c | |||
@@ -432,11 +432,13 @@ void __init fork_init(void) | |||
432 | int i; | 432 | int i; |
433 | #ifndef CONFIG_ARCH_TASK_STRUCT_ALLOCATOR | 433 | #ifndef CONFIG_ARCH_TASK_STRUCT_ALLOCATOR |
434 | #ifndef ARCH_MIN_TASKALIGN | 434 | #ifndef ARCH_MIN_TASKALIGN |
435 | #define ARCH_MIN_TASKALIGN L1_CACHE_BYTES | 435 | #define ARCH_MIN_TASKALIGN 0 |
436 | #endif | 436 | #endif |
437 | int align = max_t(int, L1_CACHE_BYTES, ARCH_MIN_TASKALIGN); | ||
438 | |||
437 | /* create a slab on which task_structs can be allocated */ | 439 | /* create a slab on which task_structs can be allocated */ |
438 | task_struct_cachep = kmem_cache_create("task_struct", | 440 | task_struct_cachep = kmem_cache_create("task_struct", |
439 | arch_task_struct_size, ARCH_MIN_TASKALIGN, | 441 | arch_task_struct_size, align, |
440 | SLAB_PANIC|SLAB_NOTRACK|SLAB_ACCOUNT, NULL); | 442 | SLAB_PANIC|SLAB_NOTRACK|SLAB_ACCOUNT, NULL); |
441 | #endif | 443 | #endif |
442 | 444 | ||
diff --git a/kernel/locking/Makefile b/kernel/locking/Makefile index 6f88e352cd4f..760158d9d98d 100644 --- a/kernel/locking/Makefile +++ b/kernel/locking/Makefile | |||
@@ -28,3 +28,4 @@ obj-$(CONFIG_RWSEM_GENERIC_SPINLOCK) += rwsem-spinlock.o | |||
28 | obj-$(CONFIG_RWSEM_XCHGADD_ALGORITHM) += rwsem-xadd.o | 28 | obj-$(CONFIG_RWSEM_XCHGADD_ALGORITHM) += rwsem-xadd.o |
29 | obj-$(CONFIG_QUEUED_RWLOCKS) += qrwlock.o | 29 | obj-$(CONFIG_QUEUED_RWLOCKS) += qrwlock.o |
30 | obj-$(CONFIG_LOCK_TORTURE_TEST) += locktorture.o | 30 | obj-$(CONFIG_LOCK_TORTURE_TEST) += locktorture.o |
31 | obj-$(CONFIG_WW_MUTEX_SELFTEST) += test-ww_mutex.o | ||
diff --git a/kernel/locking/lockdep.c b/kernel/locking/lockdep.c index d9a698e8458f..9812e5dd409e 100644 --- a/kernel/locking/lockdep.c +++ b/kernel/locking/lockdep.c | |||
@@ -2203,7 +2203,7 @@ cache_hit: | |||
2203 | * Important for check_no_collision(). | 2203 | * Important for check_no_collision(). |
2204 | */ | 2204 | */ |
2205 | if (unlikely(nr_chain_hlocks > MAX_LOCKDEP_CHAIN_HLOCKS)) { | 2205 | if (unlikely(nr_chain_hlocks > MAX_LOCKDEP_CHAIN_HLOCKS)) { |
2206 | if (debug_locks_off_graph_unlock()) | 2206 | if (!debug_locks_off_graph_unlock()) |
2207 | return 0; | 2207 | return 0; |
2208 | 2208 | ||
2209 | print_lockdep_off("BUG: MAX_LOCKDEP_CHAIN_HLOCKS too low!"); | 2209 | print_lockdep_off("BUG: MAX_LOCKDEP_CHAIN_HLOCKS too low!"); |
diff --git a/kernel/locking/locktorture.c b/kernel/locking/locktorture.c index d3de04b12f8c..28350dc8ecbb 100644 --- a/kernel/locking/locktorture.c +++ b/kernel/locking/locktorture.c | |||
@@ -372,6 +372,78 @@ static struct lock_torture_ops mutex_lock_ops = { | |||
372 | .name = "mutex_lock" | 372 | .name = "mutex_lock" |
373 | }; | 373 | }; |
374 | 374 | ||
375 | #include <linux/ww_mutex.h> | ||
376 | static DEFINE_WW_CLASS(torture_ww_class); | ||
377 | static DEFINE_WW_MUTEX(torture_ww_mutex_0, &torture_ww_class); | ||
378 | static DEFINE_WW_MUTEX(torture_ww_mutex_1, &torture_ww_class); | ||
379 | static DEFINE_WW_MUTEX(torture_ww_mutex_2, &torture_ww_class); | ||
380 | |||
381 | static int torture_ww_mutex_lock(void) | ||
382 | __acquires(torture_ww_mutex_0) | ||
383 | __acquires(torture_ww_mutex_1) | ||
384 | __acquires(torture_ww_mutex_2) | ||
385 | { | ||
386 | LIST_HEAD(list); | ||
387 | struct reorder_lock { | ||
388 | struct list_head link; | ||
389 | struct ww_mutex *lock; | ||
390 | } locks[3], *ll, *ln; | ||
391 | struct ww_acquire_ctx ctx; | ||
392 | |||
393 | locks[0].lock = &torture_ww_mutex_0; | ||
394 | list_add(&locks[0].link, &list); | ||
395 | |||
396 | locks[1].lock = &torture_ww_mutex_1; | ||
397 | list_add(&locks[1].link, &list); | ||
398 | |||
399 | locks[2].lock = &torture_ww_mutex_2; | ||
400 | list_add(&locks[2].link, &list); | ||
401 | |||
402 | ww_acquire_init(&ctx, &torture_ww_class); | ||
403 | |||
404 | list_for_each_entry(ll, &list, link) { | ||
405 | int err; | ||
406 | |||
407 | err = ww_mutex_lock(ll->lock, &ctx); | ||
408 | if (!err) | ||
409 | continue; | ||
410 | |||
411 | ln = ll; | ||
412 | list_for_each_entry_continue_reverse(ln, &list, link) | ||
413 | ww_mutex_unlock(ln->lock); | ||
414 | |||
415 | if (err != -EDEADLK) | ||
416 | return err; | ||
417 | |||
418 | ww_mutex_lock_slow(ll->lock, &ctx); | ||
419 | list_move(&ll->link, &list); | ||
420 | } | ||
421 | |||
422 | ww_acquire_fini(&ctx); | ||
423 | return 0; | ||
424 | } | ||
425 | |||
426 | static void torture_ww_mutex_unlock(void) | ||
427 | __releases(torture_ww_mutex_0) | ||
428 | __releases(torture_ww_mutex_1) | ||
429 | __releases(torture_ww_mutex_2) | ||
430 | { | ||
431 | ww_mutex_unlock(&torture_ww_mutex_0); | ||
432 | ww_mutex_unlock(&torture_ww_mutex_1); | ||
433 | ww_mutex_unlock(&torture_ww_mutex_2); | ||
434 | } | ||
435 | |||
436 | static struct lock_torture_ops ww_mutex_lock_ops = { | ||
437 | .writelock = torture_ww_mutex_lock, | ||
438 | .write_delay = torture_mutex_delay, | ||
439 | .task_boost = torture_boost_dummy, | ||
440 | .writeunlock = torture_ww_mutex_unlock, | ||
441 | .readlock = NULL, | ||
442 | .read_delay = NULL, | ||
443 | .readunlock = NULL, | ||
444 | .name = "ww_mutex_lock" | ||
445 | }; | ||
446 | |||
375 | #ifdef CONFIG_RT_MUTEXES | 447 | #ifdef CONFIG_RT_MUTEXES |
376 | static DEFINE_RT_MUTEX(torture_rtmutex); | 448 | static DEFINE_RT_MUTEX(torture_rtmutex); |
377 | 449 | ||
@@ -797,6 +869,7 @@ static int __init lock_torture_init(void) | |||
797 | &spin_lock_ops, &spin_lock_irq_ops, | 869 | &spin_lock_ops, &spin_lock_irq_ops, |
798 | &rw_lock_ops, &rw_lock_irq_ops, | 870 | &rw_lock_ops, &rw_lock_irq_ops, |
799 | &mutex_lock_ops, | 871 | &mutex_lock_ops, |
872 | &ww_mutex_lock_ops, | ||
800 | #ifdef CONFIG_RT_MUTEXES | 873 | #ifdef CONFIG_RT_MUTEXES |
801 | &rtmutex_lock_ops, | 874 | &rtmutex_lock_ops, |
802 | #endif | 875 | #endif |
diff --git a/kernel/locking/mutex-debug.h b/kernel/locking/mutex-debug.h index a459faa48987..4174417d5309 100644 --- a/kernel/locking/mutex-debug.h +++ b/kernel/locking/mutex-debug.h | |||
@@ -26,20 +26,3 @@ extern void mutex_remove_waiter(struct mutex *lock, struct mutex_waiter *waiter, | |||
26 | extern void debug_mutex_unlock(struct mutex *lock); | 26 | extern void debug_mutex_unlock(struct mutex *lock); |
27 | extern void debug_mutex_init(struct mutex *lock, const char *name, | 27 | extern void debug_mutex_init(struct mutex *lock, const char *name, |
28 | struct lock_class_key *key); | 28 | struct lock_class_key *key); |
29 | |||
30 | #define spin_lock_mutex(lock, flags) \ | ||
31 | do { \ | ||
32 | struct mutex *l = container_of(lock, struct mutex, wait_lock); \ | ||
33 | \ | ||
34 | DEBUG_LOCKS_WARN_ON(in_interrupt()); \ | ||
35 | local_irq_save(flags); \ | ||
36 | arch_spin_lock(&(lock)->rlock.raw_lock);\ | ||
37 | DEBUG_LOCKS_WARN_ON(l->magic != l); \ | ||
38 | } while (0) | ||
39 | |||
40 | #define spin_unlock_mutex(lock, flags) \ | ||
41 | do { \ | ||
42 | arch_spin_unlock(&(lock)->rlock.raw_lock); \ | ||
43 | local_irq_restore(flags); \ | ||
44 | preempt_check_resched(); \ | ||
45 | } while (0) | ||
diff --git a/kernel/locking/mutex.c b/kernel/locking/mutex.c index 8464a5cbab97..ad2d9e22697b 100644 --- a/kernel/locking/mutex.c +++ b/kernel/locking/mutex.c | |||
@@ -50,16 +50,17 @@ EXPORT_SYMBOL(__mutex_init); | |||
50 | /* | 50 | /* |
51 | * @owner: contains: 'struct task_struct *' to the current lock owner, | 51 | * @owner: contains: 'struct task_struct *' to the current lock owner, |
52 | * NULL means not owned. Since task_struct pointers are aligned at | 52 | * NULL means not owned. Since task_struct pointers are aligned at |
53 | * ARCH_MIN_TASKALIGN (which is at least sizeof(void *)), we have low | 53 | * at least L1_CACHE_BYTES, we have low bits to store extra state. |
54 | * bits to store extra state. | ||
55 | * | 54 | * |
56 | * Bit0 indicates a non-empty waiter list; unlock must issue a wakeup. | 55 | * Bit0 indicates a non-empty waiter list; unlock must issue a wakeup. |
57 | * Bit1 indicates unlock needs to hand the lock to the top-waiter | 56 | * Bit1 indicates unlock needs to hand the lock to the top-waiter |
57 | * Bit2 indicates handoff has been done and we're waiting for pickup. | ||
58 | */ | 58 | */ |
59 | #define MUTEX_FLAG_WAITERS 0x01 | 59 | #define MUTEX_FLAG_WAITERS 0x01 |
60 | #define MUTEX_FLAG_HANDOFF 0x02 | 60 | #define MUTEX_FLAG_HANDOFF 0x02 |
61 | #define MUTEX_FLAG_PICKUP 0x04 | ||
61 | 62 | ||
62 | #define MUTEX_FLAGS 0x03 | 63 | #define MUTEX_FLAGS 0x07 |
63 | 64 | ||
64 | static inline struct task_struct *__owner_task(unsigned long owner) | 65 | static inline struct task_struct *__owner_task(unsigned long owner) |
65 | { | 66 | { |
@@ -72,38 +73,29 @@ static inline unsigned long __owner_flags(unsigned long owner) | |||
72 | } | 73 | } |
73 | 74 | ||
74 | /* | 75 | /* |
75 | * Actual trylock that will work on any unlocked state. | 76 | * Trylock variant that retuns the owning task on failure. |
76 | * | ||
77 | * When setting the owner field, we must preserve the low flag bits. | ||
78 | * | ||
79 | * Be careful with @handoff, only set that in a wait-loop (where you set | ||
80 | * HANDOFF) to avoid recursive lock attempts. | ||
81 | */ | 77 | */ |
82 | static inline bool __mutex_trylock(struct mutex *lock, const bool handoff) | 78 | static inline struct task_struct *__mutex_trylock_or_owner(struct mutex *lock) |
83 | { | 79 | { |
84 | unsigned long owner, curr = (unsigned long)current; | 80 | unsigned long owner, curr = (unsigned long)current; |
85 | 81 | ||
86 | owner = atomic_long_read(&lock->owner); | 82 | owner = atomic_long_read(&lock->owner); |
87 | for (;;) { /* must loop, can race against a flag */ | 83 | for (;;) { /* must loop, can race against a flag */ |
88 | unsigned long old, flags = __owner_flags(owner); | 84 | unsigned long old, flags = __owner_flags(owner); |
85 | unsigned long task = owner & ~MUTEX_FLAGS; | ||
89 | 86 | ||
90 | if (__owner_task(owner)) { | 87 | if (task) { |
91 | if (handoff && unlikely(__owner_task(owner) == current)) { | 88 | if (likely(task != curr)) |
92 | /* | 89 | break; |
93 | * Provide ACQUIRE semantics for the lock-handoff. | ||
94 | * | ||
95 | * We cannot easily use load-acquire here, since | ||
96 | * the actual load is a failed cmpxchg, which | ||
97 | * doesn't imply any barriers. | ||
98 | * | ||
99 | * Also, this is a fairly unlikely scenario, and | ||
100 | * this contains the cost. | ||
101 | */ | ||
102 | smp_mb(); /* ACQUIRE */ | ||
103 | return true; | ||
104 | } | ||
105 | 90 | ||
106 | return false; | 91 | if (likely(!(flags & MUTEX_FLAG_PICKUP))) |
92 | break; | ||
93 | |||
94 | flags &= ~MUTEX_FLAG_PICKUP; | ||
95 | } else { | ||
96 | #ifdef CONFIG_DEBUG_MUTEXES | ||
97 | DEBUG_LOCKS_WARN_ON(flags & MUTEX_FLAG_PICKUP); | ||
98 | #endif | ||
107 | } | 99 | } |
108 | 100 | ||
109 | /* | 101 | /* |
@@ -111,15 +103,24 @@ static inline bool __mutex_trylock(struct mutex *lock, const bool handoff) | |||
111 | * past the point where we acquire it. This would be possible | 103 | * past the point where we acquire it. This would be possible |
112 | * if we (accidentally) set the bit on an unlocked mutex. | 104 | * if we (accidentally) set the bit on an unlocked mutex. |
113 | */ | 105 | */ |
114 | if (handoff) | 106 | flags &= ~MUTEX_FLAG_HANDOFF; |
115 | flags &= ~MUTEX_FLAG_HANDOFF; | ||
116 | 107 | ||
117 | old = atomic_long_cmpxchg_acquire(&lock->owner, owner, curr | flags); | 108 | old = atomic_long_cmpxchg_acquire(&lock->owner, owner, curr | flags); |
118 | if (old == owner) | 109 | if (old == owner) |
119 | return true; | 110 | return NULL; |
120 | 111 | ||
121 | owner = old; | 112 | owner = old; |
122 | } | 113 | } |
114 | |||
115 | return __owner_task(owner); | ||
116 | } | ||
117 | |||
118 | /* | ||
119 | * Actual trylock that will work on any unlocked state. | ||
120 | */ | ||
121 | static inline bool __mutex_trylock(struct mutex *lock) | ||
122 | { | ||
123 | return !__mutex_trylock_or_owner(lock); | ||
123 | } | 124 | } |
124 | 125 | ||
125 | #ifndef CONFIG_DEBUG_LOCK_ALLOC | 126 | #ifndef CONFIG_DEBUG_LOCK_ALLOC |
@@ -171,9 +172,9 @@ static inline bool __mutex_waiter_is_first(struct mutex *lock, struct mutex_wait | |||
171 | 172 | ||
172 | /* | 173 | /* |
173 | * Give up ownership to a specific task, when @task = NULL, this is equivalent | 174 | * Give up ownership to a specific task, when @task = NULL, this is equivalent |
174 | * to a regular unlock. Clears HANDOFF, preserves WAITERS. Provides RELEASE | 175 | * to a regular unlock. Sets PICKUP on a handoff, clears HANDOF, preserves |
175 | * semantics like a regular unlock, the __mutex_trylock() provides matching | 176 | * WAITERS. Provides RELEASE semantics like a regular unlock, the |
176 | * ACQUIRE semantics for the handoff. | 177 | * __mutex_trylock() provides a matching ACQUIRE semantics for the handoff. |
177 | */ | 178 | */ |
178 | static void __mutex_handoff(struct mutex *lock, struct task_struct *task) | 179 | static void __mutex_handoff(struct mutex *lock, struct task_struct *task) |
179 | { | 180 | { |
@@ -184,10 +185,13 @@ static void __mutex_handoff(struct mutex *lock, struct task_struct *task) | |||
184 | 185 | ||
185 | #ifdef CONFIG_DEBUG_MUTEXES | 186 | #ifdef CONFIG_DEBUG_MUTEXES |
186 | DEBUG_LOCKS_WARN_ON(__owner_task(owner) != current); | 187 | DEBUG_LOCKS_WARN_ON(__owner_task(owner) != current); |
188 | DEBUG_LOCKS_WARN_ON(owner & MUTEX_FLAG_PICKUP); | ||
187 | #endif | 189 | #endif |
188 | 190 | ||
189 | new = (owner & MUTEX_FLAG_WAITERS); | 191 | new = (owner & MUTEX_FLAG_WAITERS); |
190 | new |= (unsigned long)task; | 192 | new |= (unsigned long)task; |
193 | if (task) | ||
194 | new |= MUTEX_FLAG_PICKUP; | ||
191 | 195 | ||
192 | old = atomic_long_cmpxchg_release(&lock->owner, owner, new); | 196 | old = atomic_long_cmpxchg_release(&lock->owner, owner, new); |
193 | if (old == owner) | 197 | if (old == owner) |
@@ -237,8 +241,8 @@ void __sched mutex_lock(struct mutex *lock) | |||
237 | EXPORT_SYMBOL(mutex_lock); | 241 | EXPORT_SYMBOL(mutex_lock); |
238 | #endif | 242 | #endif |
239 | 243 | ||
240 | static __always_inline void ww_mutex_lock_acquired(struct ww_mutex *ww, | 244 | static __always_inline void |
241 | struct ww_acquire_ctx *ww_ctx) | 245 | ww_mutex_lock_acquired(struct ww_mutex *ww, struct ww_acquire_ctx *ww_ctx) |
242 | { | 246 | { |
243 | #ifdef CONFIG_DEBUG_MUTEXES | 247 | #ifdef CONFIG_DEBUG_MUTEXES |
244 | /* | 248 | /* |
@@ -277,17 +281,50 @@ static __always_inline void ww_mutex_lock_acquired(struct ww_mutex *ww, | |||
277 | ww_ctx->acquired++; | 281 | ww_ctx->acquired++; |
278 | } | 282 | } |
279 | 283 | ||
284 | static inline bool __sched | ||
285 | __ww_ctx_stamp_after(struct ww_acquire_ctx *a, struct ww_acquire_ctx *b) | ||
286 | { | ||
287 | return a->stamp - b->stamp <= LONG_MAX && | ||
288 | (a->stamp != b->stamp || a > b); | ||
289 | } | ||
290 | |||
291 | /* | ||
292 | * Wake up any waiters that may have to back off when the lock is held by the | ||
293 | * given context. | ||
294 | * | ||
295 | * Due to the invariants on the wait list, this can only affect the first | ||
296 | * waiter with a context. | ||
297 | * | ||
298 | * The current task must not be on the wait list. | ||
299 | */ | ||
300 | static void __sched | ||
301 | __ww_mutex_wakeup_for_backoff(struct mutex *lock, struct ww_acquire_ctx *ww_ctx) | ||
302 | { | ||
303 | struct mutex_waiter *cur; | ||
304 | |||
305 | lockdep_assert_held(&lock->wait_lock); | ||
306 | |||
307 | list_for_each_entry(cur, &lock->wait_list, list) { | ||
308 | if (!cur->ww_ctx) | ||
309 | continue; | ||
310 | |||
311 | if (cur->ww_ctx->acquired > 0 && | ||
312 | __ww_ctx_stamp_after(cur->ww_ctx, ww_ctx)) { | ||
313 | debug_mutex_wake_waiter(lock, cur); | ||
314 | wake_up_process(cur->task); | ||
315 | } | ||
316 | |||
317 | break; | ||
318 | } | ||
319 | } | ||
320 | |||
280 | /* | 321 | /* |
281 | * After acquiring lock with fastpath or when we lost out in contested | 322 | * After acquiring lock with fastpath or when we lost out in contested |
282 | * slowpath, set ctx and wake up any waiters so they can recheck. | 323 | * slowpath, set ctx and wake up any waiters so they can recheck. |
283 | */ | 324 | */ |
284 | static __always_inline void | 325 | static __always_inline void |
285 | ww_mutex_set_context_fastpath(struct ww_mutex *lock, | 326 | ww_mutex_set_context_fastpath(struct ww_mutex *lock, struct ww_acquire_ctx *ctx) |
286 | struct ww_acquire_ctx *ctx) | ||
287 | { | 327 | { |
288 | unsigned long flags; | ||
289 | struct mutex_waiter *cur; | ||
290 | |||
291 | ww_mutex_lock_acquired(lock, ctx); | 328 | ww_mutex_lock_acquired(lock, ctx); |
292 | 329 | ||
293 | lock->ctx = ctx; | 330 | lock->ctx = ctx; |
@@ -311,46 +348,79 @@ ww_mutex_set_context_fastpath(struct ww_mutex *lock, | |||
311 | * Uh oh, we raced in fastpath, wake up everyone in this case, | 348 | * Uh oh, we raced in fastpath, wake up everyone in this case, |
312 | * so they can see the new lock->ctx. | 349 | * so they can see the new lock->ctx. |
313 | */ | 350 | */ |
314 | spin_lock_mutex(&lock->base.wait_lock, flags); | 351 | spin_lock(&lock->base.wait_lock); |
315 | list_for_each_entry(cur, &lock->base.wait_list, list) { | 352 | __ww_mutex_wakeup_for_backoff(&lock->base, ctx); |
316 | debug_mutex_wake_waiter(&lock->base, cur); | 353 | spin_unlock(&lock->base.wait_lock); |
317 | wake_up_process(cur->task); | ||
318 | } | ||
319 | spin_unlock_mutex(&lock->base.wait_lock, flags); | ||
320 | } | 354 | } |
321 | 355 | ||
322 | /* | 356 | /* |
323 | * After acquiring lock in the slowpath set ctx and wake up any | 357 | * After acquiring lock in the slowpath set ctx. |
324 | * waiters so they can recheck. | 358 | * |
359 | * Unlike for the fast path, the caller ensures that waiters are woken up where | ||
360 | * necessary. | ||
325 | * | 361 | * |
326 | * Callers must hold the mutex wait_lock. | 362 | * Callers must hold the mutex wait_lock. |
327 | */ | 363 | */ |
328 | static __always_inline void | 364 | static __always_inline void |
329 | ww_mutex_set_context_slowpath(struct ww_mutex *lock, | 365 | ww_mutex_set_context_slowpath(struct ww_mutex *lock, struct ww_acquire_ctx *ctx) |
330 | struct ww_acquire_ctx *ctx) | ||
331 | { | 366 | { |
332 | struct mutex_waiter *cur; | ||
333 | |||
334 | ww_mutex_lock_acquired(lock, ctx); | 367 | ww_mutex_lock_acquired(lock, ctx); |
335 | lock->ctx = ctx; | 368 | lock->ctx = ctx; |
369 | } | ||
370 | |||
371 | #ifdef CONFIG_MUTEX_SPIN_ON_OWNER | ||
372 | |||
373 | static inline | ||
374 | bool ww_mutex_spin_on_owner(struct mutex *lock, struct ww_acquire_ctx *ww_ctx, | ||
375 | struct mutex_waiter *waiter) | ||
376 | { | ||
377 | struct ww_mutex *ww; | ||
378 | |||
379 | ww = container_of(lock, struct ww_mutex, base); | ||
336 | 380 | ||
337 | /* | 381 | /* |
338 | * Give any possible sleeping processes the chance to wake up, | 382 | * If ww->ctx is set the contents are undefined, only |
339 | * so they can recheck if they have to back off. | 383 | * by acquiring wait_lock there is a guarantee that |
384 | * they are not invalid when reading. | ||
385 | * | ||
386 | * As such, when deadlock detection needs to be | ||
387 | * performed the optimistic spinning cannot be done. | ||
388 | * | ||
389 | * Check this in every inner iteration because we may | ||
390 | * be racing against another thread's ww_mutex_lock. | ||
340 | */ | 391 | */ |
341 | list_for_each_entry(cur, &lock->base.wait_list, list) { | 392 | if (ww_ctx->acquired > 0 && READ_ONCE(ww->ctx)) |
342 | debug_mutex_wake_waiter(&lock->base, cur); | 393 | return false; |
343 | wake_up_process(cur->task); | 394 | |
344 | } | 395 | /* |
396 | * If we aren't on the wait list yet, cancel the spin | ||
397 | * if there are waiters. We want to avoid stealing the | ||
398 | * lock from a waiter with an earlier stamp, since the | ||
399 | * other thread may already own a lock that we also | ||
400 | * need. | ||
401 | */ | ||
402 | if (!waiter && (atomic_long_read(&lock->owner) & MUTEX_FLAG_WAITERS)) | ||
403 | return false; | ||
404 | |||
405 | /* | ||
406 | * Similarly, stop spinning if we are no longer the | ||
407 | * first waiter. | ||
408 | */ | ||
409 | if (waiter && !__mutex_waiter_is_first(lock, waiter)) | ||
410 | return false; | ||
411 | |||
412 | return true; | ||
345 | } | 413 | } |
346 | 414 | ||
347 | #ifdef CONFIG_MUTEX_SPIN_ON_OWNER | ||
348 | /* | 415 | /* |
349 | * Look out! "owner" is an entirely speculative pointer | 416 | * Look out! "owner" is an entirely speculative pointer access and not |
350 | * access and not reliable. | 417 | * reliable. |
418 | * | ||
419 | * "noinline" so that this function shows up on perf profiles. | ||
351 | */ | 420 | */ |
352 | static noinline | 421 | static noinline |
353 | bool mutex_spin_on_owner(struct mutex *lock, struct task_struct *owner) | 422 | bool mutex_spin_on_owner(struct mutex *lock, struct task_struct *owner, |
423 | struct ww_acquire_ctx *ww_ctx, struct mutex_waiter *waiter) | ||
354 | { | 424 | { |
355 | bool ret = true; | 425 | bool ret = true; |
356 | 426 | ||
@@ -373,6 +443,11 @@ bool mutex_spin_on_owner(struct mutex *lock, struct task_struct *owner) | |||
373 | break; | 443 | break; |
374 | } | 444 | } |
375 | 445 | ||
446 | if (ww_ctx && !ww_mutex_spin_on_owner(lock, ww_ctx, waiter)) { | ||
447 | ret = false; | ||
448 | break; | ||
449 | } | ||
450 | |||
376 | cpu_relax(); | 451 | cpu_relax(); |
377 | } | 452 | } |
378 | rcu_read_unlock(); | 453 | rcu_read_unlock(); |
@@ -431,12 +506,10 @@ static inline int mutex_can_spin_on_owner(struct mutex *lock) | |||
431 | * with the spinner at the head of the OSQ, if present, until the owner is | 506 | * with the spinner at the head of the OSQ, if present, until the owner is |
432 | * changed to itself. | 507 | * changed to itself. |
433 | */ | 508 | */ |
434 | static bool mutex_optimistic_spin(struct mutex *lock, | 509 | static __always_inline bool |
435 | struct ww_acquire_ctx *ww_ctx, | 510 | mutex_optimistic_spin(struct mutex *lock, struct ww_acquire_ctx *ww_ctx, |
436 | const bool use_ww_ctx, const bool waiter) | 511 | const bool use_ww_ctx, struct mutex_waiter *waiter) |
437 | { | 512 | { |
438 | struct task_struct *task = current; | ||
439 | |||
440 | if (!waiter) { | 513 | if (!waiter) { |
441 | /* | 514 | /* |
442 | * The purpose of the mutex_can_spin_on_owner() function is | 515 | * The purpose of the mutex_can_spin_on_owner() function is |
@@ -460,40 +533,17 @@ static bool mutex_optimistic_spin(struct mutex *lock, | |||
460 | for (;;) { | 533 | for (;;) { |
461 | struct task_struct *owner; | 534 | struct task_struct *owner; |
462 | 535 | ||
463 | if (use_ww_ctx && ww_ctx->acquired > 0) { | 536 | /* Try to acquire the mutex... */ |
464 | struct ww_mutex *ww; | 537 | owner = __mutex_trylock_or_owner(lock); |
465 | 538 | if (!owner) | |
466 | ww = container_of(lock, struct ww_mutex, base); | 539 | break; |
467 | /* | ||
468 | * If ww->ctx is set the contents are undefined, only | ||
469 | * by acquiring wait_lock there is a guarantee that | ||
470 | * they are not invalid when reading. | ||
471 | * | ||
472 | * As such, when deadlock detection needs to be | ||
473 | * performed the optimistic spinning cannot be done. | ||
474 | */ | ||
475 | if (READ_ONCE(ww->ctx)) | ||
476 | goto fail_unlock; | ||
477 | } | ||
478 | 540 | ||
479 | /* | 541 | /* |
480 | * If there's an owner, wait for it to either | 542 | * There's an owner, wait for it to either |
481 | * release the lock or go to sleep. | 543 | * release the lock or go to sleep. |
482 | */ | 544 | */ |
483 | owner = __mutex_owner(lock); | 545 | if (!mutex_spin_on_owner(lock, owner, ww_ctx, waiter)) |
484 | if (owner) { | 546 | goto fail_unlock; |
485 | if (waiter && owner == task) { | ||
486 | smp_mb(); /* ACQUIRE */ | ||
487 | break; | ||
488 | } | ||
489 | |||
490 | if (!mutex_spin_on_owner(lock, owner)) | ||
491 | goto fail_unlock; | ||
492 | } | ||
493 | |||
494 | /* Try to acquire the mutex if it is unlocked. */ | ||
495 | if (__mutex_trylock(lock, waiter)) | ||
496 | break; | ||
497 | 547 | ||
498 | /* | 548 | /* |
499 | * The cpu_relax() call is a compiler barrier which forces | 549 | * The cpu_relax() call is a compiler barrier which forces |
@@ -532,9 +582,9 @@ fail: | |||
532 | return false; | 582 | return false; |
533 | } | 583 | } |
534 | #else | 584 | #else |
535 | static bool mutex_optimistic_spin(struct mutex *lock, | 585 | static __always_inline bool |
536 | struct ww_acquire_ctx *ww_ctx, | 586 | mutex_optimistic_spin(struct mutex *lock, struct ww_acquire_ctx *ww_ctx, |
537 | const bool use_ww_ctx, const bool waiter) | 587 | const bool use_ww_ctx, struct mutex_waiter *waiter) |
538 | { | 588 | { |
539 | return false; | 589 | return false; |
540 | } | 590 | } |
@@ -594,23 +644,88 @@ void __sched ww_mutex_unlock(struct ww_mutex *lock) | |||
594 | EXPORT_SYMBOL(ww_mutex_unlock); | 644 | EXPORT_SYMBOL(ww_mutex_unlock); |
595 | 645 | ||
596 | static inline int __sched | 646 | static inline int __sched |
597 | __ww_mutex_lock_check_stamp(struct mutex *lock, struct ww_acquire_ctx *ctx) | 647 | __ww_mutex_lock_check_stamp(struct mutex *lock, struct mutex_waiter *waiter, |
648 | struct ww_acquire_ctx *ctx) | ||
598 | { | 649 | { |
599 | struct ww_mutex *ww = container_of(lock, struct ww_mutex, base); | 650 | struct ww_mutex *ww = container_of(lock, struct ww_mutex, base); |
600 | struct ww_acquire_ctx *hold_ctx = READ_ONCE(ww->ctx); | 651 | struct ww_acquire_ctx *hold_ctx = READ_ONCE(ww->ctx); |
652 | struct mutex_waiter *cur; | ||
653 | |||
654 | if (hold_ctx && __ww_ctx_stamp_after(ctx, hold_ctx)) | ||
655 | goto deadlock; | ||
601 | 656 | ||
602 | if (!hold_ctx) | 657 | /* |
658 | * If there is a waiter in front of us that has a context, then its | ||
659 | * stamp is earlier than ours and we must back off. | ||
660 | */ | ||
661 | cur = waiter; | ||
662 | list_for_each_entry_continue_reverse(cur, &lock->wait_list, list) { | ||
663 | if (cur->ww_ctx) | ||
664 | goto deadlock; | ||
665 | } | ||
666 | |||
667 | return 0; | ||
668 | |||
669 | deadlock: | ||
670 | #ifdef CONFIG_DEBUG_MUTEXES | ||
671 | DEBUG_LOCKS_WARN_ON(ctx->contending_lock); | ||
672 | ctx->contending_lock = ww; | ||
673 | #endif | ||
674 | return -EDEADLK; | ||
675 | } | ||
676 | |||
677 | static inline int __sched | ||
678 | __ww_mutex_add_waiter(struct mutex_waiter *waiter, | ||
679 | struct mutex *lock, | ||
680 | struct ww_acquire_ctx *ww_ctx) | ||
681 | { | ||
682 | struct mutex_waiter *cur; | ||
683 | struct list_head *pos; | ||
684 | |||
685 | if (!ww_ctx) { | ||
686 | list_add_tail(&waiter->list, &lock->wait_list); | ||
603 | return 0; | 687 | return 0; |
688 | } | ||
604 | 689 | ||
605 | if (ctx->stamp - hold_ctx->stamp <= LONG_MAX && | 690 | /* |
606 | (ctx->stamp != hold_ctx->stamp || ctx > hold_ctx)) { | 691 | * Add the waiter before the first waiter with a higher stamp. |
692 | * Waiters without a context are skipped to avoid starving | ||
693 | * them. | ||
694 | */ | ||
695 | pos = &lock->wait_list; | ||
696 | list_for_each_entry_reverse(cur, &lock->wait_list, list) { | ||
697 | if (!cur->ww_ctx) | ||
698 | continue; | ||
699 | |||
700 | if (__ww_ctx_stamp_after(ww_ctx, cur->ww_ctx)) { | ||
701 | /* Back off immediately if necessary. */ | ||
702 | if (ww_ctx->acquired > 0) { | ||
607 | #ifdef CONFIG_DEBUG_MUTEXES | 703 | #ifdef CONFIG_DEBUG_MUTEXES |
608 | DEBUG_LOCKS_WARN_ON(ctx->contending_lock); | 704 | struct ww_mutex *ww; |
609 | ctx->contending_lock = ww; | 705 | |
706 | ww = container_of(lock, struct ww_mutex, base); | ||
707 | DEBUG_LOCKS_WARN_ON(ww_ctx->contending_lock); | ||
708 | ww_ctx->contending_lock = ww; | ||
610 | #endif | 709 | #endif |
611 | return -EDEADLK; | 710 | return -EDEADLK; |
711 | } | ||
712 | |||
713 | break; | ||
714 | } | ||
715 | |||
716 | pos = &cur->list; | ||
717 | |||
718 | /* | ||
719 | * Wake up the waiter so that it gets a chance to back | ||
720 | * off. | ||
721 | */ | ||
722 | if (cur->ww_ctx->acquired > 0) { | ||
723 | debug_mutex_wake_waiter(lock, cur); | ||
724 | wake_up_process(cur->task); | ||
725 | } | ||
612 | } | 726 | } |
613 | 727 | ||
728 | list_add_tail(&waiter->list, pos); | ||
614 | return 0; | 729 | return 0; |
615 | } | 730 | } |
616 | 731 | ||
@@ -622,15 +737,15 @@ __mutex_lock_common(struct mutex *lock, long state, unsigned int subclass, | |||
622 | struct lockdep_map *nest_lock, unsigned long ip, | 737 | struct lockdep_map *nest_lock, unsigned long ip, |
623 | struct ww_acquire_ctx *ww_ctx, const bool use_ww_ctx) | 738 | struct ww_acquire_ctx *ww_ctx, const bool use_ww_ctx) |
624 | { | 739 | { |
625 | struct task_struct *task = current; | ||
626 | struct mutex_waiter waiter; | 740 | struct mutex_waiter waiter; |
627 | unsigned long flags; | ||
628 | bool first = false; | 741 | bool first = false; |
629 | struct ww_mutex *ww; | 742 | struct ww_mutex *ww; |
630 | int ret; | 743 | int ret; |
631 | 744 | ||
632 | if (use_ww_ctx) { | 745 | might_sleep(); |
633 | ww = container_of(lock, struct ww_mutex, base); | 746 | |
747 | ww = container_of(lock, struct ww_mutex, base); | ||
748 | if (use_ww_ctx && ww_ctx) { | ||
634 | if (unlikely(ww_ctx == READ_ONCE(ww->ctx))) | 749 | if (unlikely(ww_ctx == READ_ONCE(ww->ctx))) |
635 | return -EALREADY; | 750 | return -EALREADY; |
636 | } | 751 | } |
@@ -638,36 +753,54 @@ __mutex_lock_common(struct mutex *lock, long state, unsigned int subclass, | |||
638 | preempt_disable(); | 753 | preempt_disable(); |
639 | mutex_acquire_nest(&lock->dep_map, subclass, 0, nest_lock, ip); | 754 | mutex_acquire_nest(&lock->dep_map, subclass, 0, nest_lock, ip); |
640 | 755 | ||
641 | if (__mutex_trylock(lock, false) || | 756 | if (__mutex_trylock(lock) || |
642 | mutex_optimistic_spin(lock, ww_ctx, use_ww_ctx, false)) { | 757 | mutex_optimistic_spin(lock, ww_ctx, use_ww_ctx, NULL)) { |
643 | /* got the lock, yay! */ | 758 | /* got the lock, yay! */ |
644 | lock_acquired(&lock->dep_map, ip); | 759 | lock_acquired(&lock->dep_map, ip); |
645 | if (use_ww_ctx) | 760 | if (use_ww_ctx && ww_ctx) |
646 | ww_mutex_set_context_fastpath(ww, ww_ctx); | 761 | ww_mutex_set_context_fastpath(ww, ww_ctx); |
647 | preempt_enable(); | 762 | preempt_enable(); |
648 | return 0; | 763 | return 0; |
649 | } | 764 | } |
650 | 765 | ||
651 | spin_lock_mutex(&lock->wait_lock, flags); | 766 | spin_lock(&lock->wait_lock); |
652 | /* | 767 | /* |
653 | * After waiting to acquire the wait_lock, try again. | 768 | * After waiting to acquire the wait_lock, try again. |
654 | */ | 769 | */ |
655 | if (__mutex_trylock(lock, false)) | 770 | if (__mutex_trylock(lock)) { |
771 | if (use_ww_ctx && ww_ctx) | ||
772 | __ww_mutex_wakeup_for_backoff(lock, ww_ctx); | ||
773 | |||
656 | goto skip_wait; | 774 | goto skip_wait; |
775 | } | ||
657 | 776 | ||
658 | debug_mutex_lock_common(lock, &waiter); | 777 | debug_mutex_lock_common(lock, &waiter); |
659 | debug_mutex_add_waiter(lock, &waiter, task); | 778 | debug_mutex_add_waiter(lock, &waiter, current); |
660 | 779 | ||
661 | /* add waiting tasks to the end of the waitqueue (FIFO): */ | 780 | lock_contended(&lock->dep_map, ip); |
662 | list_add_tail(&waiter.list, &lock->wait_list); | 781 | |
663 | waiter.task = task; | 782 | if (!use_ww_ctx) { |
783 | /* add waiting tasks to the end of the waitqueue (FIFO): */ | ||
784 | list_add_tail(&waiter.list, &lock->wait_list); | ||
785 | |||
786 | #ifdef CONFIG_DEBUG_MUTEXES | ||
787 | waiter.ww_ctx = MUTEX_POISON_WW_CTX; | ||
788 | #endif | ||
789 | } else { | ||
790 | /* Add in stamp order, waking up waiters that must back off. */ | ||
791 | ret = __ww_mutex_add_waiter(&waiter, lock, ww_ctx); | ||
792 | if (ret) | ||
793 | goto err_early_backoff; | ||
794 | |||
795 | waiter.ww_ctx = ww_ctx; | ||
796 | } | ||
797 | |||
798 | waiter.task = current; | ||
664 | 799 | ||
665 | if (__mutex_waiter_is_first(lock, &waiter)) | 800 | if (__mutex_waiter_is_first(lock, &waiter)) |
666 | __mutex_set_flag(lock, MUTEX_FLAG_WAITERS); | 801 | __mutex_set_flag(lock, MUTEX_FLAG_WAITERS); |
667 | 802 | ||
668 | lock_contended(&lock->dep_map, ip); | 803 | set_current_state(state); |
669 | |||
670 | set_task_state(task, state); | ||
671 | for (;;) { | 804 | for (;;) { |
672 | /* | 805 | /* |
673 | * Once we hold wait_lock, we're serialized against | 806 | * Once we hold wait_lock, we're serialized against |
@@ -675,7 +808,7 @@ __mutex_lock_common(struct mutex *lock, long state, unsigned int subclass, | |||
675 | * before testing the error conditions to make sure we pick up | 808 | * before testing the error conditions to make sure we pick up |
676 | * the handoff. | 809 | * the handoff. |
677 | */ | 810 | */ |
678 | if (__mutex_trylock(lock, first)) | 811 | if (__mutex_trylock(lock)) |
679 | goto acquired; | 812 | goto acquired; |
680 | 813 | ||
681 | /* | 814 | /* |
@@ -683,42 +816,47 @@ __mutex_lock_common(struct mutex *lock, long state, unsigned int subclass, | |||
683 | * wait_lock. This ensures the lock cancellation is ordered | 816 | * wait_lock. This ensures the lock cancellation is ordered |
684 | * against mutex_unlock() and wake-ups do not go missing. | 817 | * against mutex_unlock() and wake-ups do not go missing. |
685 | */ | 818 | */ |
686 | if (unlikely(signal_pending_state(state, task))) { | 819 | if (unlikely(signal_pending_state(state, current))) { |
687 | ret = -EINTR; | 820 | ret = -EINTR; |
688 | goto err; | 821 | goto err; |
689 | } | 822 | } |
690 | 823 | ||
691 | if (use_ww_ctx && ww_ctx->acquired > 0) { | 824 | if (use_ww_ctx && ww_ctx && ww_ctx->acquired > 0) { |
692 | ret = __ww_mutex_lock_check_stamp(lock, ww_ctx); | 825 | ret = __ww_mutex_lock_check_stamp(lock, &waiter, ww_ctx); |
693 | if (ret) | 826 | if (ret) |
694 | goto err; | 827 | goto err; |
695 | } | 828 | } |
696 | 829 | ||
697 | spin_unlock_mutex(&lock->wait_lock, flags); | 830 | spin_unlock(&lock->wait_lock); |
698 | schedule_preempt_disabled(); | 831 | schedule_preempt_disabled(); |
699 | 832 | ||
700 | if (!first && __mutex_waiter_is_first(lock, &waiter)) { | 833 | /* |
701 | first = true; | 834 | * ww_mutex needs to always recheck its position since its waiter |
702 | __mutex_set_flag(lock, MUTEX_FLAG_HANDOFF); | 835 | * list is not FIFO ordered. |
836 | */ | ||
837 | if ((use_ww_ctx && ww_ctx) || !first) { | ||
838 | first = __mutex_waiter_is_first(lock, &waiter); | ||
839 | if (first) | ||
840 | __mutex_set_flag(lock, MUTEX_FLAG_HANDOFF); | ||
703 | } | 841 | } |
704 | 842 | ||
705 | set_task_state(task, state); | 843 | set_current_state(state); |
706 | /* | 844 | /* |
707 | * Here we order against unlock; we must either see it change | 845 | * Here we order against unlock; we must either see it change |
708 | * state back to RUNNING and fall through the next schedule(), | 846 | * state back to RUNNING and fall through the next schedule(), |
709 | * or we must see its unlock and acquire. | 847 | * or we must see its unlock and acquire. |
710 | */ | 848 | */ |
711 | if ((first && mutex_optimistic_spin(lock, ww_ctx, use_ww_ctx, true)) || | 849 | if (__mutex_trylock(lock) || |
712 | __mutex_trylock(lock, first)) | 850 | (first && mutex_optimistic_spin(lock, ww_ctx, use_ww_ctx, &waiter))) |
713 | break; | 851 | break; |
714 | 852 | ||
715 | spin_lock_mutex(&lock->wait_lock, flags); | 853 | spin_lock(&lock->wait_lock); |
716 | } | 854 | } |
717 | spin_lock_mutex(&lock->wait_lock, flags); | 855 | spin_lock(&lock->wait_lock); |
718 | acquired: | 856 | acquired: |
719 | __set_task_state(task, TASK_RUNNING); | 857 | __set_current_state(TASK_RUNNING); |
720 | 858 | ||
721 | mutex_remove_waiter(lock, &waiter, task); | 859 | mutex_remove_waiter(lock, &waiter, current); |
722 | if (likely(list_empty(&lock->wait_list))) | 860 | if (likely(list_empty(&lock->wait_list))) |
723 | __mutex_clear_flag(lock, MUTEX_FLAGS); | 861 | __mutex_clear_flag(lock, MUTEX_FLAGS); |
724 | 862 | ||
@@ -728,30 +866,44 @@ skip_wait: | |||
728 | /* got the lock - cleanup and rejoice! */ | 866 | /* got the lock - cleanup and rejoice! */ |
729 | lock_acquired(&lock->dep_map, ip); | 867 | lock_acquired(&lock->dep_map, ip); |
730 | 868 | ||
731 | if (use_ww_ctx) | 869 | if (use_ww_ctx && ww_ctx) |
732 | ww_mutex_set_context_slowpath(ww, ww_ctx); | 870 | ww_mutex_set_context_slowpath(ww, ww_ctx); |
733 | 871 | ||
734 | spin_unlock_mutex(&lock->wait_lock, flags); | 872 | spin_unlock(&lock->wait_lock); |
735 | preempt_enable(); | 873 | preempt_enable(); |
736 | return 0; | 874 | return 0; |
737 | 875 | ||
738 | err: | 876 | err: |
739 | __set_task_state(task, TASK_RUNNING); | 877 | __set_current_state(TASK_RUNNING); |
740 | mutex_remove_waiter(lock, &waiter, task); | 878 | mutex_remove_waiter(lock, &waiter, current); |
741 | spin_unlock_mutex(&lock->wait_lock, flags); | 879 | err_early_backoff: |
880 | spin_unlock(&lock->wait_lock); | ||
742 | debug_mutex_free_waiter(&waiter); | 881 | debug_mutex_free_waiter(&waiter); |
743 | mutex_release(&lock->dep_map, 1, ip); | 882 | mutex_release(&lock->dep_map, 1, ip); |
744 | preempt_enable(); | 883 | preempt_enable(); |
745 | return ret; | 884 | return ret; |
746 | } | 885 | } |
747 | 886 | ||
887 | static int __sched | ||
888 | __mutex_lock(struct mutex *lock, long state, unsigned int subclass, | ||
889 | struct lockdep_map *nest_lock, unsigned long ip) | ||
890 | { | ||
891 | return __mutex_lock_common(lock, state, subclass, nest_lock, ip, NULL, false); | ||
892 | } | ||
893 | |||
894 | static int __sched | ||
895 | __ww_mutex_lock(struct mutex *lock, long state, unsigned int subclass, | ||
896 | struct lockdep_map *nest_lock, unsigned long ip, | ||
897 | struct ww_acquire_ctx *ww_ctx) | ||
898 | { | ||
899 | return __mutex_lock_common(lock, state, subclass, nest_lock, ip, ww_ctx, true); | ||
900 | } | ||
901 | |||
748 | #ifdef CONFIG_DEBUG_LOCK_ALLOC | 902 | #ifdef CONFIG_DEBUG_LOCK_ALLOC |
749 | void __sched | 903 | void __sched |
750 | mutex_lock_nested(struct mutex *lock, unsigned int subclass) | 904 | mutex_lock_nested(struct mutex *lock, unsigned int subclass) |
751 | { | 905 | { |
752 | might_sleep(); | 906 | __mutex_lock(lock, TASK_UNINTERRUPTIBLE, subclass, NULL, _RET_IP_); |
753 | __mutex_lock_common(lock, TASK_UNINTERRUPTIBLE, | ||
754 | subclass, NULL, _RET_IP_, NULL, 0); | ||
755 | } | 907 | } |
756 | 908 | ||
757 | EXPORT_SYMBOL_GPL(mutex_lock_nested); | 909 | EXPORT_SYMBOL_GPL(mutex_lock_nested); |
@@ -759,27 +911,21 @@ EXPORT_SYMBOL_GPL(mutex_lock_nested); | |||
759 | void __sched | 911 | void __sched |
760 | _mutex_lock_nest_lock(struct mutex *lock, struct lockdep_map *nest) | 912 | _mutex_lock_nest_lock(struct mutex *lock, struct lockdep_map *nest) |
761 | { | 913 | { |
762 | might_sleep(); | 914 | __mutex_lock(lock, TASK_UNINTERRUPTIBLE, 0, nest, _RET_IP_); |
763 | __mutex_lock_common(lock, TASK_UNINTERRUPTIBLE, | ||
764 | 0, nest, _RET_IP_, NULL, 0); | ||
765 | } | 915 | } |
766 | EXPORT_SYMBOL_GPL(_mutex_lock_nest_lock); | 916 | EXPORT_SYMBOL_GPL(_mutex_lock_nest_lock); |
767 | 917 | ||
768 | int __sched | 918 | int __sched |
769 | mutex_lock_killable_nested(struct mutex *lock, unsigned int subclass) | 919 | mutex_lock_killable_nested(struct mutex *lock, unsigned int subclass) |
770 | { | 920 | { |
771 | might_sleep(); | 921 | return __mutex_lock(lock, TASK_KILLABLE, subclass, NULL, _RET_IP_); |
772 | return __mutex_lock_common(lock, TASK_KILLABLE, | ||
773 | subclass, NULL, _RET_IP_, NULL, 0); | ||
774 | } | 922 | } |
775 | EXPORT_SYMBOL_GPL(mutex_lock_killable_nested); | 923 | EXPORT_SYMBOL_GPL(mutex_lock_killable_nested); |
776 | 924 | ||
777 | int __sched | 925 | int __sched |
778 | mutex_lock_interruptible_nested(struct mutex *lock, unsigned int subclass) | 926 | mutex_lock_interruptible_nested(struct mutex *lock, unsigned int subclass) |
779 | { | 927 | { |
780 | might_sleep(); | 928 | return __mutex_lock(lock, TASK_INTERRUPTIBLE, subclass, NULL, _RET_IP_); |
781 | return __mutex_lock_common(lock, TASK_INTERRUPTIBLE, | ||
782 | subclass, NULL, _RET_IP_, NULL, 0); | ||
783 | } | 929 | } |
784 | EXPORT_SYMBOL_GPL(mutex_lock_interruptible_nested); | 930 | EXPORT_SYMBOL_GPL(mutex_lock_interruptible_nested); |
785 | 931 | ||
@@ -824,35 +970,37 @@ ww_mutex_deadlock_injection(struct ww_mutex *lock, struct ww_acquire_ctx *ctx) | |||
824 | } | 970 | } |
825 | 971 | ||
826 | int __sched | 972 | int __sched |
827 | __ww_mutex_lock(struct ww_mutex *lock, struct ww_acquire_ctx *ctx) | 973 | ww_mutex_lock(struct ww_mutex *lock, struct ww_acquire_ctx *ctx) |
828 | { | 974 | { |
829 | int ret; | 975 | int ret; |
830 | 976 | ||
831 | might_sleep(); | 977 | might_sleep(); |
832 | ret = __mutex_lock_common(&lock->base, TASK_UNINTERRUPTIBLE, | 978 | ret = __ww_mutex_lock(&lock->base, TASK_UNINTERRUPTIBLE, |
833 | 0, &ctx->dep_map, _RET_IP_, ctx, 1); | 979 | 0, ctx ? &ctx->dep_map : NULL, _RET_IP_, |
834 | if (!ret && ctx->acquired > 1) | 980 | ctx); |
981 | if (!ret && ctx && ctx->acquired > 1) | ||
835 | return ww_mutex_deadlock_injection(lock, ctx); | 982 | return ww_mutex_deadlock_injection(lock, ctx); |
836 | 983 | ||
837 | return ret; | 984 | return ret; |
838 | } | 985 | } |
839 | EXPORT_SYMBOL_GPL(__ww_mutex_lock); | 986 | EXPORT_SYMBOL_GPL(ww_mutex_lock); |
840 | 987 | ||
841 | int __sched | 988 | int __sched |
842 | __ww_mutex_lock_interruptible(struct ww_mutex *lock, struct ww_acquire_ctx *ctx) | 989 | ww_mutex_lock_interruptible(struct ww_mutex *lock, struct ww_acquire_ctx *ctx) |
843 | { | 990 | { |
844 | int ret; | 991 | int ret; |
845 | 992 | ||
846 | might_sleep(); | 993 | might_sleep(); |
847 | ret = __mutex_lock_common(&lock->base, TASK_INTERRUPTIBLE, | 994 | ret = __ww_mutex_lock(&lock->base, TASK_INTERRUPTIBLE, |
848 | 0, &ctx->dep_map, _RET_IP_, ctx, 1); | 995 | 0, ctx ? &ctx->dep_map : NULL, _RET_IP_, |
996 | ctx); | ||
849 | 997 | ||
850 | if (!ret && ctx->acquired > 1) | 998 | if (!ret && ctx && ctx->acquired > 1) |
851 | return ww_mutex_deadlock_injection(lock, ctx); | 999 | return ww_mutex_deadlock_injection(lock, ctx); |
852 | 1000 | ||
853 | return ret; | 1001 | return ret; |
854 | } | 1002 | } |
855 | EXPORT_SYMBOL_GPL(__ww_mutex_lock_interruptible); | 1003 | EXPORT_SYMBOL_GPL(ww_mutex_lock_interruptible); |
856 | 1004 | ||
857 | #endif | 1005 | #endif |
858 | 1006 | ||
@@ -862,8 +1010,8 @@ EXPORT_SYMBOL_GPL(__ww_mutex_lock_interruptible); | |||
862 | static noinline void __sched __mutex_unlock_slowpath(struct mutex *lock, unsigned long ip) | 1010 | static noinline void __sched __mutex_unlock_slowpath(struct mutex *lock, unsigned long ip) |
863 | { | 1011 | { |
864 | struct task_struct *next = NULL; | 1012 | struct task_struct *next = NULL; |
865 | unsigned long owner, flags; | ||
866 | DEFINE_WAKE_Q(wake_q); | 1013 | DEFINE_WAKE_Q(wake_q); |
1014 | unsigned long owner; | ||
867 | 1015 | ||
868 | mutex_release(&lock->dep_map, 1, ip); | 1016 | mutex_release(&lock->dep_map, 1, ip); |
869 | 1017 | ||
@@ -880,6 +1028,7 @@ static noinline void __sched __mutex_unlock_slowpath(struct mutex *lock, unsigne | |||
880 | 1028 | ||
881 | #ifdef CONFIG_DEBUG_MUTEXES | 1029 | #ifdef CONFIG_DEBUG_MUTEXES |
882 | DEBUG_LOCKS_WARN_ON(__owner_task(owner) != current); | 1030 | DEBUG_LOCKS_WARN_ON(__owner_task(owner) != current); |
1031 | DEBUG_LOCKS_WARN_ON(owner & MUTEX_FLAG_PICKUP); | ||
883 | #endif | 1032 | #endif |
884 | 1033 | ||
885 | if (owner & MUTEX_FLAG_HANDOFF) | 1034 | if (owner & MUTEX_FLAG_HANDOFF) |
@@ -897,7 +1046,7 @@ static noinline void __sched __mutex_unlock_slowpath(struct mutex *lock, unsigne | |||
897 | owner = old; | 1046 | owner = old; |
898 | } | 1047 | } |
899 | 1048 | ||
900 | spin_lock_mutex(&lock->wait_lock, flags); | 1049 | spin_lock(&lock->wait_lock); |
901 | debug_mutex_unlock(lock); | 1050 | debug_mutex_unlock(lock); |
902 | if (!list_empty(&lock->wait_list)) { | 1051 | if (!list_empty(&lock->wait_list)) { |
903 | /* get the first entry from the wait-list: */ | 1052 | /* get the first entry from the wait-list: */ |
@@ -914,7 +1063,7 @@ static noinline void __sched __mutex_unlock_slowpath(struct mutex *lock, unsigne | |||
914 | if (owner & MUTEX_FLAG_HANDOFF) | 1063 | if (owner & MUTEX_FLAG_HANDOFF) |
915 | __mutex_handoff(lock, next); | 1064 | __mutex_handoff(lock, next); |
916 | 1065 | ||
917 | spin_unlock_mutex(&lock->wait_lock, flags); | 1066 | spin_unlock(&lock->wait_lock); |
918 | 1067 | ||
919 | wake_up_q(&wake_q); | 1068 | wake_up_q(&wake_q); |
920 | } | 1069 | } |
@@ -977,37 +1126,34 @@ EXPORT_SYMBOL_GPL(mutex_lock_io); | |||
977 | static noinline void __sched | 1126 | static noinline void __sched |
978 | __mutex_lock_slowpath(struct mutex *lock) | 1127 | __mutex_lock_slowpath(struct mutex *lock) |
979 | { | 1128 | { |
980 | __mutex_lock_common(lock, TASK_UNINTERRUPTIBLE, 0, | 1129 | __mutex_lock(lock, TASK_UNINTERRUPTIBLE, 0, NULL, _RET_IP_); |
981 | NULL, _RET_IP_, NULL, 0); | ||
982 | } | 1130 | } |
983 | 1131 | ||
984 | static noinline int __sched | 1132 | static noinline int __sched |
985 | __mutex_lock_killable_slowpath(struct mutex *lock) | 1133 | __mutex_lock_killable_slowpath(struct mutex *lock) |
986 | { | 1134 | { |
987 | return __mutex_lock_common(lock, TASK_KILLABLE, 0, | 1135 | return __mutex_lock(lock, TASK_KILLABLE, 0, NULL, _RET_IP_); |
988 | NULL, _RET_IP_, NULL, 0); | ||
989 | } | 1136 | } |
990 | 1137 | ||
991 | static noinline int __sched | 1138 | static noinline int __sched |
992 | __mutex_lock_interruptible_slowpath(struct mutex *lock) | 1139 | __mutex_lock_interruptible_slowpath(struct mutex *lock) |
993 | { | 1140 | { |
994 | return __mutex_lock_common(lock, TASK_INTERRUPTIBLE, 0, | 1141 | return __mutex_lock(lock, TASK_INTERRUPTIBLE, 0, NULL, _RET_IP_); |
995 | NULL, _RET_IP_, NULL, 0); | ||
996 | } | 1142 | } |
997 | 1143 | ||
998 | static noinline int __sched | 1144 | static noinline int __sched |
999 | __ww_mutex_lock_slowpath(struct ww_mutex *lock, struct ww_acquire_ctx *ctx) | 1145 | __ww_mutex_lock_slowpath(struct ww_mutex *lock, struct ww_acquire_ctx *ctx) |
1000 | { | 1146 | { |
1001 | return __mutex_lock_common(&lock->base, TASK_UNINTERRUPTIBLE, 0, | 1147 | return __ww_mutex_lock(&lock->base, TASK_UNINTERRUPTIBLE, 0, NULL, |
1002 | NULL, _RET_IP_, ctx, 1); | 1148 | _RET_IP_, ctx); |
1003 | } | 1149 | } |
1004 | 1150 | ||
1005 | static noinline int __sched | 1151 | static noinline int __sched |
1006 | __ww_mutex_lock_interruptible_slowpath(struct ww_mutex *lock, | 1152 | __ww_mutex_lock_interruptible_slowpath(struct ww_mutex *lock, |
1007 | struct ww_acquire_ctx *ctx) | 1153 | struct ww_acquire_ctx *ctx) |
1008 | { | 1154 | { |
1009 | return __mutex_lock_common(&lock->base, TASK_INTERRUPTIBLE, 0, | 1155 | return __ww_mutex_lock(&lock->base, TASK_INTERRUPTIBLE, 0, NULL, |
1010 | NULL, _RET_IP_, ctx, 1); | 1156 | _RET_IP_, ctx); |
1011 | } | 1157 | } |
1012 | 1158 | ||
1013 | #endif | 1159 | #endif |
@@ -1028,7 +1174,7 @@ __ww_mutex_lock_interruptible_slowpath(struct ww_mutex *lock, | |||
1028 | */ | 1174 | */ |
1029 | int __sched mutex_trylock(struct mutex *lock) | 1175 | int __sched mutex_trylock(struct mutex *lock) |
1030 | { | 1176 | { |
1031 | bool locked = __mutex_trylock(lock, false); | 1177 | bool locked = __mutex_trylock(lock); |
1032 | 1178 | ||
1033 | if (locked) | 1179 | if (locked) |
1034 | mutex_acquire(&lock->dep_map, 0, 1, _RET_IP_); | 1180 | mutex_acquire(&lock->dep_map, 0, 1, _RET_IP_); |
@@ -1039,32 +1185,34 @@ EXPORT_SYMBOL(mutex_trylock); | |||
1039 | 1185 | ||
1040 | #ifndef CONFIG_DEBUG_LOCK_ALLOC | 1186 | #ifndef CONFIG_DEBUG_LOCK_ALLOC |
1041 | int __sched | 1187 | int __sched |
1042 | __ww_mutex_lock(struct ww_mutex *lock, struct ww_acquire_ctx *ctx) | 1188 | ww_mutex_lock(struct ww_mutex *lock, struct ww_acquire_ctx *ctx) |
1043 | { | 1189 | { |
1044 | might_sleep(); | 1190 | might_sleep(); |
1045 | 1191 | ||
1046 | if (__mutex_trylock_fast(&lock->base)) { | 1192 | if (__mutex_trylock_fast(&lock->base)) { |
1047 | ww_mutex_set_context_fastpath(lock, ctx); | 1193 | if (ctx) |
1194 | ww_mutex_set_context_fastpath(lock, ctx); | ||
1048 | return 0; | 1195 | return 0; |
1049 | } | 1196 | } |
1050 | 1197 | ||
1051 | return __ww_mutex_lock_slowpath(lock, ctx); | 1198 | return __ww_mutex_lock_slowpath(lock, ctx); |
1052 | } | 1199 | } |
1053 | EXPORT_SYMBOL(__ww_mutex_lock); | 1200 | EXPORT_SYMBOL(ww_mutex_lock); |
1054 | 1201 | ||
1055 | int __sched | 1202 | int __sched |
1056 | __ww_mutex_lock_interruptible(struct ww_mutex *lock, struct ww_acquire_ctx *ctx) | 1203 | ww_mutex_lock_interruptible(struct ww_mutex *lock, struct ww_acquire_ctx *ctx) |
1057 | { | 1204 | { |
1058 | might_sleep(); | 1205 | might_sleep(); |
1059 | 1206 | ||
1060 | if (__mutex_trylock_fast(&lock->base)) { | 1207 | if (__mutex_trylock_fast(&lock->base)) { |
1061 | ww_mutex_set_context_fastpath(lock, ctx); | 1208 | if (ctx) |
1209 | ww_mutex_set_context_fastpath(lock, ctx); | ||
1062 | return 0; | 1210 | return 0; |
1063 | } | 1211 | } |
1064 | 1212 | ||
1065 | return __ww_mutex_lock_interruptible_slowpath(lock, ctx); | 1213 | return __ww_mutex_lock_interruptible_slowpath(lock, ctx); |
1066 | } | 1214 | } |
1067 | EXPORT_SYMBOL(__ww_mutex_lock_interruptible); | 1215 | EXPORT_SYMBOL(ww_mutex_lock_interruptible); |
1068 | 1216 | ||
1069 | #endif | 1217 | #endif |
1070 | 1218 | ||
diff --git a/kernel/locking/mutex.h b/kernel/locking/mutex.h index 4410a4af42a3..6ebc1902f779 100644 --- a/kernel/locking/mutex.h +++ b/kernel/locking/mutex.h | |||
@@ -9,10 +9,6 @@ | |||
9 | * !CONFIG_DEBUG_MUTEXES case. Most of them are NOPs: | 9 | * !CONFIG_DEBUG_MUTEXES case. Most of them are NOPs: |
10 | */ | 10 | */ |
11 | 11 | ||
12 | #define spin_lock_mutex(lock, flags) \ | ||
13 | do { spin_lock(lock); (void)(flags); } while (0) | ||
14 | #define spin_unlock_mutex(lock, flags) \ | ||
15 | do { spin_unlock(lock); (void)(flags); } while (0) | ||
16 | #define mutex_remove_waiter(lock, waiter, task) \ | 12 | #define mutex_remove_waiter(lock, waiter, task) \ |
17 | __list_del((waiter)->list.prev, (waiter)->list.next) | 13 | __list_del((waiter)->list.prev, (waiter)->list.next) |
18 | 14 | ||
diff --git a/kernel/locking/percpu-rwsem.c b/kernel/locking/percpu-rwsem.c index ce182599cf2e..883cf1b92d90 100644 --- a/kernel/locking/percpu-rwsem.c +++ b/kernel/locking/percpu-rwsem.c | |||
@@ -1,7 +1,6 @@ | |||
1 | #include <linux/atomic.h> | 1 | #include <linux/atomic.h> |
2 | #include <linux/rwsem.h> | 2 | #include <linux/rwsem.h> |
3 | #include <linux/percpu.h> | 3 | #include <linux/percpu.h> |
4 | #include <linux/wait.h> | ||
5 | #include <linux/lockdep.h> | 4 | #include <linux/lockdep.h> |
6 | #include <linux/percpu-rwsem.h> | 5 | #include <linux/percpu-rwsem.h> |
7 | #include <linux/rcupdate.h> | 6 | #include <linux/rcupdate.h> |
@@ -18,7 +17,7 @@ int __percpu_init_rwsem(struct percpu_rw_semaphore *sem, | |||
18 | /* ->rw_sem represents the whole percpu_rw_semaphore for lockdep */ | 17 | /* ->rw_sem represents the whole percpu_rw_semaphore for lockdep */ |
19 | rcu_sync_init(&sem->rss, RCU_SCHED_SYNC); | 18 | rcu_sync_init(&sem->rss, RCU_SCHED_SYNC); |
20 | __init_rwsem(&sem->rw_sem, name, rwsem_key); | 19 | __init_rwsem(&sem->rw_sem, name, rwsem_key); |
21 | init_waitqueue_head(&sem->writer); | 20 | rcuwait_init(&sem->writer); |
22 | sem->readers_block = 0; | 21 | sem->readers_block = 0; |
23 | return 0; | 22 | return 0; |
24 | } | 23 | } |
@@ -103,7 +102,7 @@ void __percpu_up_read(struct percpu_rw_semaphore *sem) | |||
103 | __this_cpu_dec(*sem->read_count); | 102 | __this_cpu_dec(*sem->read_count); |
104 | 103 | ||
105 | /* Prod writer to recheck readers_active */ | 104 | /* Prod writer to recheck readers_active */ |
106 | wake_up(&sem->writer); | 105 | rcuwait_wake_up(&sem->writer); |
107 | } | 106 | } |
108 | EXPORT_SYMBOL_GPL(__percpu_up_read); | 107 | EXPORT_SYMBOL_GPL(__percpu_up_read); |
109 | 108 | ||
@@ -160,7 +159,7 @@ void percpu_down_write(struct percpu_rw_semaphore *sem) | |||
160 | */ | 159 | */ |
161 | 160 | ||
162 | /* Wait for all now active readers to complete. */ | 161 | /* Wait for all now active readers to complete. */ |
163 | wait_event(sem->writer, readers_active_check(sem)); | 162 | rcuwait_wait_event(&sem->writer, readers_active_check(sem)); |
164 | } | 163 | } |
165 | EXPORT_SYMBOL_GPL(percpu_down_write); | 164 | EXPORT_SYMBOL_GPL(percpu_down_write); |
166 | 165 | ||
diff --git a/kernel/locking/qspinlock_paravirt.h b/kernel/locking/qspinlock_paravirt.h index e3b5520005db..e6b2f7ad3e51 100644 --- a/kernel/locking/qspinlock_paravirt.h +++ b/kernel/locking/qspinlock_paravirt.h | |||
@@ -263,7 +263,7 @@ pv_wait_early(struct pv_node *prev, int loop) | |||
263 | if ((loop & PV_PREV_CHECK_MASK) != 0) | 263 | if ((loop & PV_PREV_CHECK_MASK) != 0) |
264 | return false; | 264 | return false; |
265 | 265 | ||
266 | return READ_ONCE(prev->state) != vcpu_running; | 266 | return READ_ONCE(prev->state) != vcpu_running || vcpu_is_preempted(prev->cpu); |
267 | } | 267 | } |
268 | 268 | ||
269 | /* | 269 | /* |
diff --git a/kernel/locking/rtmutex.c b/kernel/locking/rtmutex.c index 2f443ed2320a..d340be3a488f 100644 --- a/kernel/locking/rtmutex.c +++ b/kernel/locking/rtmutex.c | |||
@@ -1179,7 +1179,7 @@ __rt_mutex_slowlock(struct rt_mutex *lock, int state, | |||
1179 | * TASK_INTERRUPTIBLE checks for signals and | 1179 | * TASK_INTERRUPTIBLE checks for signals and |
1180 | * timeout. Ignored otherwise. | 1180 | * timeout. Ignored otherwise. |
1181 | */ | 1181 | */ |
1182 | if (unlikely(state == TASK_INTERRUPTIBLE)) { | 1182 | if (likely(state == TASK_INTERRUPTIBLE)) { |
1183 | /* Signal pending? */ | 1183 | /* Signal pending? */ |
1184 | if (signal_pending(current)) | 1184 | if (signal_pending(current)) |
1185 | ret = -EINTR; | 1185 | ret = -EINTR; |
diff --git a/kernel/locking/rwsem-spinlock.c b/kernel/locking/rwsem-spinlock.c index 1591f6b3539f..5eacab880f67 100644 --- a/kernel/locking/rwsem-spinlock.c +++ b/kernel/locking/rwsem-spinlock.c | |||
@@ -128,7 +128,6 @@ __rwsem_wake_one_writer(struct rw_semaphore *sem) | |||
128 | void __sched __down_read(struct rw_semaphore *sem) | 128 | void __sched __down_read(struct rw_semaphore *sem) |
129 | { | 129 | { |
130 | struct rwsem_waiter waiter; | 130 | struct rwsem_waiter waiter; |
131 | struct task_struct *tsk; | ||
132 | unsigned long flags; | 131 | unsigned long flags; |
133 | 132 | ||
134 | raw_spin_lock_irqsave(&sem->wait_lock, flags); | 133 | raw_spin_lock_irqsave(&sem->wait_lock, flags); |
@@ -140,13 +139,12 @@ void __sched __down_read(struct rw_semaphore *sem) | |||
140 | goto out; | 139 | goto out; |
141 | } | 140 | } |
142 | 141 | ||
143 | tsk = current; | 142 | set_current_state(TASK_UNINTERRUPTIBLE); |
144 | set_task_state(tsk, TASK_UNINTERRUPTIBLE); | ||
145 | 143 | ||
146 | /* set up my own style of waitqueue */ | 144 | /* set up my own style of waitqueue */ |
147 | waiter.task = tsk; | 145 | waiter.task = current; |
148 | waiter.type = RWSEM_WAITING_FOR_READ; | 146 | waiter.type = RWSEM_WAITING_FOR_READ; |
149 | get_task_struct(tsk); | 147 | get_task_struct(current); |
150 | 148 | ||
151 | list_add_tail(&waiter.list, &sem->wait_list); | 149 | list_add_tail(&waiter.list, &sem->wait_list); |
152 | 150 | ||
@@ -158,10 +156,10 @@ void __sched __down_read(struct rw_semaphore *sem) | |||
158 | if (!waiter.task) | 156 | if (!waiter.task) |
159 | break; | 157 | break; |
160 | schedule(); | 158 | schedule(); |
161 | set_task_state(tsk, TASK_UNINTERRUPTIBLE); | 159 | set_current_state(TASK_UNINTERRUPTIBLE); |
162 | } | 160 | } |
163 | 161 | ||
164 | __set_task_state(tsk, TASK_RUNNING); | 162 | __set_current_state(TASK_RUNNING); |
165 | out: | 163 | out: |
166 | ; | 164 | ; |
167 | } | 165 | } |
@@ -194,15 +192,13 @@ int __down_read_trylock(struct rw_semaphore *sem) | |||
194 | int __sched __down_write_common(struct rw_semaphore *sem, int state) | 192 | int __sched __down_write_common(struct rw_semaphore *sem, int state) |
195 | { | 193 | { |
196 | struct rwsem_waiter waiter; | 194 | struct rwsem_waiter waiter; |
197 | struct task_struct *tsk; | ||
198 | unsigned long flags; | 195 | unsigned long flags; |
199 | int ret = 0; | 196 | int ret = 0; |
200 | 197 | ||
201 | raw_spin_lock_irqsave(&sem->wait_lock, flags); | 198 | raw_spin_lock_irqsave(&sem->wait_lock, flags); |
202 | 199 | ||
203 | /* set up my own style of waitqueue */ | 200 | /* set up my own style of waitqueue */ |
204 | tsk = current; | 201 | waiter.task = current; |
205 | waiter.task = tsk; | ||
206 | waiter.type = RWSEM_WAITING_FOR_WRITE; | 202 | waiter.type = RWSEM_WAITING_FOR_WRITE; |
207 | list_add_tail(&waiter.list, &sem->wait_list); | 203 | list_add_tail(&waiter.list, &sem->wait_list); |
208 | 204 | ||
@@ -220,7 +216,7 @@ int __sched __down_write_common(struct rw_semaphore *sem, int state) | |||
220 | ret = -EINTR; | 216 | ret = -EINTR; |
221 | goto out; | 217 | goto out; |
222 | } | 218 | } |
223 | set_task_state(tsk, state); | 219 | set_current_state(state); |
224 | raw_spin_unlock_irqrestore(&sem->wait_lock, flags); | 220 | raw_spin_unlock_irqrestore(&sem->wait_lock, flags); |
225 | schedule(); | 221 | schedule(); |
226 | raw_spin_lock_irqsave(&sem->wait_lock, flags); | 222 | raw_spin_lock_irqsave(&sem->wait_lock, flags); |
diff --git a/kernel/locking/rwsem-xadd.c b/kernel/locking/rwsem-xadd.c index 631506004f9e..2ad8d8dc3bb1 100644 --- a/kernel/locking/rwsem-xadd.c +++ b/kernel/locking/rwsem-xadd.c | |||
@@ -224,10 +224,9 @@ struct rw_semaphore __sched *rwsem_down_read_failed(struct rw_semaphore *sem) | |||
224 | { | 224 | { |
225 | long count, adjustment = -RWSEM_ACTIVE_READ_BIAS; | 225 | long count, adjustment = -RWSEM_ACTIVE_READ_BIAS; |
226 | struct rwsem_waiter waiter; | 226 | struct rwsem_waiter waiter; |
227 | struct task_struct *tsk = current; | ||
228 | DEFINE_WAKE_Q(wake_q); | 227 | DEFINE_WAKE_Q(wake_q); |
229 | 228 | ||
230 | waiter.task = tsk; | 229 | waiter.task = current; |
231 | waiter.type = RWSEM_WAITING_FOR_READ; | 230 | waiter.type = RWSEM_WAITING_FOR_READ; |
232 | 231 | ||
233 | raw_spin_lock_irq(&sem->wait_lock); | 232 | raw_spin_lock_irq(&sem->wait_lock); |
@@ -254,13 +253,13 @@ struct rw_semaphore __sched *rwsem_down_read_failed(struct rw_semaphore *sem) | |||
254 | 253 | ||
255 | /* wait to be given the lock */ | 254 | /* wait to be given the lock */ |
256 | while (true) { | 255 | while (true) { |
257 | set_task_state(tsk, TASK_UNINTERRUPTIBLE); | 256 | set_current_state(TASK_UNINTERRUPTIBLE); |
258 | if (!waiter.task) | 257 | if (!waiter.task) |
259 | break; | 258 | break; |
260 | schedule(); | 259 | schedule(); |
261 | } | 260 | } |
262 | 261 | ||
263 | __set_task_state(tsk, TASK_RUNNING); | 262 | __set_current_state(TASK_RUNNING); |
264 | return sem; | 263 | return sem; |
265 | } | 264 | } |
266 | EXPORT_SYMBOL(rwsem_down_read_failed); | 265 | EXPORT_SYMBOL(rwsem_down_read_failed); |
@@ -503,8 +502,6 @@ __rwsem_down_write_failed_common(struct rw_semaphore *sem, int state) | |||
503 | * wake any read locks that were queued ahead of us. | 502 | * wake any read locks that were queued ahead of us. |
504 | */ | 503 | */ |
505 | if (count > RWSEM_WAITING_BIAS) { | 504 | if (count > RWSEM_WAITING_BIAS) { |
506 | DEFINE_WAKE_Q(wake_q); | ||
507 | |||
508 | __rwsem_mark_wake(sem, RWSEM_WAKE_READERS, &wake_q); | 505 | __rwsem_mark_wake(sem, RWSEM_WAKE_READERS, &wake_q); |
509 | /* | 506 | /* |
510 | * The wakeup is normally called _after_ the wait_lock | 507 | * The wakeup is normally called _after_ the wait_lock |
@@ -514,6 +511,11 @@ __rwsem_down_write_failed_common(struct rw_semaphore *sem, int state) | |||
514 | * for attempting rwsem_try_write_lock(). | 511 | * for attempting rwsem_try_write_lock(). |
515 | */ | 512 | */ |
516 | wake_up_q(&wake_q); | 513 | wake_up_q(&wake_q); |
514 | |||
515 | /* | ||
516 | * Reinitialize wake_q after use. | ||
517 | */ | ||
518 | wake_q_init(&wake_q); | ||
517 | } | 519 | } |
518 | 520 | ||
519 | } else | 521 | } else |
diff --git a/kernel/locking/semaphore.c b/kernel/locking/semaphore.c index b8120abe594b..9512e37637dc 100644 --- a/kernel/locking/semaphore.c +++ b/kernel/locking/semaphore.c | |||
@@ -204,19 +204,18 @@ struct semaphore_waiter { | |||
204 | static inline int __sched __down_common(struct semaphore *sem, long state, | 204 | static inline int __sched __down_common(struct semaphore *sem, long state, |
205 | long timeout) | 205 | long timeout) |
206 | { | 206 | { |
207 | struct task_struct *task = current; | ||
208 | struct semaphore_waiter waiter; | 207 | struct semaphore_waiter waiter; |
209 | 208 | ||
210 | list_add_tail(&waiter.list, &sem->wait_list); | 209 | list_add_tail(&waiter.list, &sem->wait_list); |
211 | waiter.task = task; | 210 | waiter.task = current; |
212 | waiter.up = false; | 211 | waiter.up = false; |
213 | 212 | ||
214 | for (;;) { | 213 | for (;;) { |
215 | if (signal_pending_state(state, task)) | 214 | if (signal_pending_state(state, current)) |
216 | goto interrupted; | 215 | goto interrupted; |
217 | if (unlikely(timeout <= 0)) | 216 | if (unlikely(timeout <= 0)) |
218 | goto timed_out; | 217 | goto timed_out; |
219 | __set_task_state(task, state); | 218 | __set_current_state(state); |
220 | raw_spin_unlock_irq(&sem->lock); | 219 | raw_spin_unlock_irq(&sem->lock); |
221 | timeout = schedule_timeout(timeout); | 220 | timeout = schedule_timeout(timeout); |
222 | raw_spin_lock_irq(&sem->lock); | 221 | raw_spin_lock_irq(&sem->lock); |
diff --git a/kernel/locking/spinlock.c b/kernel/locking/spinlock.c index db3ccb1dd614..4b082b5cac9e 100644 --- a/kernel/locking/spinlock.c +++ b/kernel/locking/spinlock.c | |||
@@ -363,14 +363,6 @@ void __lockfunc _raw_spin_lock_nested(raw_spinlock_t *lock, int subclass) | |||
363 | } | 363 | } |
364 | EXPORT_SYMBOL(_raw_spin_lock_nested); | 364 | EXPORT_SYMBOL(_raw_spin_lock_nested); |
365 | 365 | ||
366 | void __lockfunc _raw_spin_lock_bh_nested(raw_spinlock_t *lock, int subclass) | ||
367 | { | ||
368 | __local_bh_disable_ip(_RET_IP_, SOFTIRQ_LOCK_OFFSET); | ||
369 | spin_acquire(&lock->dep_map, subclass, 0, _RET_IP_); | ||
370 | LOCK_CONTENDED(lock, do_raw_spin_trylock, do_raw_spin_lock); | ||
371 | } | ||
372 | EXPORT_SYMBOL(_raw_spin_lock_bh_nested); | ||
373 | |||
374 | unsigned long __lockfunc _raw_spin_lock_irqsave_nested(raw_spinlock_t *lock, | 366 | unsigned long __lockfunc _raw_spin_lock_irqsave_nested(raw_spinlock_t *lock, |
375 | int subclass) | 367 | int subclass) |
376 | { | 368 | { |
diff --git a/kernel/locking/spinlock_debug.c b/kernel/locking/spinlock_debug.c index 0374a596cffa..9aa0fccd5d43 100644 --- a/kernel/locking/spinlock_debug.c +++ b/kernel/locking/spinlock_debug.c | |||
@@ -103,38 +103,14 @@ static inline void debug_spin_unlock(raw_spinlock_t *lock) | |||
103 | lock->owner_cpu = -1; | 103 | lock->owner_cpu = -1; |
104 | } | 104 | } |
105 | 105 | ||
106 | static void __spin_lock_debug(raw_spinlock_t *lock) | 106 | /* |
107 | { | 107 | * We are now relying on the NMI watchdog to detect lockup instead of doing |
108 | u64 i; | 108 | * the detection here with an unfair lock which can cause problem of its own. |
109 | u64 loops = loops_per_jiffy * HZ; | 109 | */ |
110 | |||
111 | for (i = 0; i < loops; i++) { | ||
112 | if (arch_spin_trylock(&lock->raw_lock)) | ||
113 | return; | ||
114 | __delay(1); | ||
115 | } | ||
116 | /* lockup suspected: */ | ||
117 | spin_dump(lock, "lockup suspected"); | ||
118 | #ifdef CONFIG_SMP | ||
119 | trigger_all_cpu_backtrace(); | ||
120 | #endif | ||
121 | |||
122 | /* | ||
123 | * The trylock above was causing a livelock. Give the lower level arch | ||
124 | * specific lock code a chance to acquire the lock. We have already | ||
125 | * printed a warning/backtrace at this point. The non-debug arch | ||
126 | * specific code might actually succeed in acquiring the lock. If it is | ||
127 | * not successful, the end-result is the same - there is no forward | ||
128 | * progress. | ||
129 | */ | ||
130 | arch_spin_lock(&lock->raw_lock); | ||
131 | } | ||
132 | |||
133 | void do_raw_spin_lock(raw_spinlock_t *lock) | 110 | void do_raw_spin_lock(raw_spinlock_t *lock) |
134 | { | 111 | { |
135 | debug_spin_lock_before(lock); | 112 | debug_spin_lock_before(lock); |
136 | if (unlikely(!arch_spin_trylock(&lock->raw_lock))) | 113 | arch_spin_lock(&lock->raw_lock); |
137 | __spin_lock_debug(lock); | ||
138 | debug_spin_lock_after(lock); | 114 | debug_spin_lock_after(lock); |
139 | } | 115 | } |
140 | 116 | ||
@@ -172,32 +148,6 @@ static void rwlock_bug(rwlock_t *lock, const char *msg) | |||
172 | 148 | ||
173 | #define RWLOCK_BUG_ON(cond, lock, msg) if (unlikely(cond)) rwlock_bug(lock, msg) | 149 | #define RWLOCK_BUG_ON(cond, lock, msg) if (unlikely(cond)) rwlock_bug(lock, msg) |
174 | 150 | ||
175 | #if 0 /* __write_lock_debug() can lock up - maybe this can too? */ | ||
176 | static void __read_lock_debug(rwlock_t *lock) | ||
177 | { | ||
178 | u64 i; | ||
179 | u64 loops = loops_per_jiffy * HZ; | ||
180 | int print_once = 1; | ||
181 | |||
182 | for (;;) { | ||
183 | for (i = 0; i < loops; i++) { | ||
184 | if (arch_read_trylock(&lock->raw_lock)) | ||
185 | return; | ||
186 | __delay(1); | ||
187 | } | ||
188 | /* lockup suspected: */ | ||
189 | if (print_once) { | ||
190 | print_once = 0; | ||
191 | printk(KERN_EMERG "BUG: read-lock lockup on CPU#%d, " | ||
192 | "%s/%d, %p\n", | ||
193 | raw_smp_processor_id(), current->comm, | ||
194 | current->pid, lock); | ||
195 | dump_stack(); | ||
196 | } | ||
197 | } | ||
198 | } | ||
199 | #endif | ||
200 | |||
201 | void do_raw_read_lock(rwlock_t *lock) | 151 | void do_raw_read_lock(rwlock_t *lock) |
202 | { | 152 | { |
203 | RWLOCK_BUG_ON(lock->magic != RWLOCK_MAGIC, lock, "bad magic"); | 153 | RWLOCK_BUG_ON(lock->magic != RWLOCK_MAGIC, lock, "bad magic"); |
@@ -247,32 +197,6 @@ static inline void debug_write_unlock(rwlock_t *lock) | |||
247 | lock->owner_cpu = -1; | 197 | lock->owner_cpu = -1; |
248 | } | 198 | } |
249 | 199 | ||
250 | #if 0 /* This can cause lockups */ | ||
251 | static void __write_lock_debug(rwlock_t *lock) | ||
252 | { | ||
253 | u64 i; | ||
254 | u64 loops = loops_per_jiffy * HZ; | ||
255 | int print_once = 1; | ||
256 | |||
257 | for (;;) { | ||
258 | for (i = 0; i < loops; i++) { | ||
259 | if (arch_write_trylock(&lock->raw_lock)) | ||
260 | return; | ||
261 | __delay(1); | ||
262 | } | ||
263 | /* lockup suspected: */ | ||
264 | if (print_once) { | ||
265 | print_once = 0; | ||
266 | printk(KERN_EMERG "BUG: write-lock lockup on CPU#%d, " | ||
267 | "%s/%d, %p\n", | ||
268 | raw_smp_processor_id(), current->comm, | ||
269 | current->pid, lock); | ||
270 | dump_stack(); | ||
271 | } | ||
272 | } | ||
273 | } | ||
274 | #endif | ||
275 | |||
276 | void do_raw_write_lock(rwlock_t *lock) | 200 | void do_raw_write_lock(rwlock_t *lock) |
277 | { | 201 | { |
278 | debug_write_lock_before(lock); | 202 | debug_write_lock_before(lock); |
diff --git a/kernel/locking/test-ww_mutex.c b/kernel/locking/test-ww_mutex.c new file mode 100644 index 000000000000..da6c9a34f62f --- /dev/null +++ b/kernel/locking/test-ww_mutex.c | |||
@@ -0,0 +1,646 @@ | |||
1 | /* | ||
2 | * Module-based API test facility for ww_mutexes | ||
3 | * | ||
4 | * This program is free software; you can redistribute it and/or modify | ||
5 | * it under the terms of the GNU General Public License as published by | ||
6 | * the Free Software Foundation; either version 2 of the License, or | ||
7 | * (at your option) any later version. | ||
8 | * | ||
9 | * This program is distributed in the hope that it will be useful, | ||
10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
12 | * GNU General Public License for more details. | ||
13 | * | ||
14 | * You should have received a copy of the GNU General Public License | ||
15 | * along with this program; if not, you can access it online at | ||
16 | * http://www.gnu.org/licenses/gpl-2.0.html. | ||
17 | */ | ||
18 | |||
19 | #include <linux/kernel.h> | ||
20 | |||
21 | #include <linux/completion.h> | ||
22 | #include <linux/delay.h> | ||
23 | #include <linux/kthread.h> | ||
24 | #include <linux/module.h> | ||
25 | #include <linux/random.h> | ||
26 | #include <linux/slab.h> | ||
27 | #include <linux/ww_mutex.h> | ||
28 | |||
29 | static DEFINE_WW_CLASS(ww_class); | ||
30 | struct workqueue_struct *wq; | ||
31 | |||
32 | struct test_mutex { | ||
33 | struct work_struct work; | ||
34 | struct ww_mutex mutex; | ||
35 | struct completion ready, go, done; | ||
36 | unsigned int flags; | ||
37 | }; | ||
38 | |||
39 | #define TEST_MTX_SPIN BIT(0) | ||
40 | #define TEST_MTX_TRY BIT(1) | ||
41 | #define TEST_MTX_CTX BIT(2) | ||
42 | #define __TEST_MTX_LAST BIT(3) | ||
43 | |||
44 | static void test_mutex_work(struct work_struct *work) | ||
45 | { | ||
46 | struct test_mutex *mtx = container_of(work, typeof(*mtx), work); | ||
47 | |||
48 | complete(&mtx->ready); | ||
49 | wait_for_completion(&mtx->go); | ||
50 | |||
51 | if (mtx->flags & TEST_MTX_TRY) { | ||
52 | while (!ww_mutex_trylock(&mtx->mutex)) | ||
53 | cpu_relax(); | ||
54 | } else { | ||
55 | ww_mutex_lock(&mtx->mutex, NULL); | ||
56 | } | ||
57 | complete(&mtx->done); | ||
58 | ww_mutex_unlock(&mtx->mutex); | ||
59 | } | ||
60 | |||
61 | static int __test_mutex(unsigned int flags) | ||
62 | { | ||
63 | #define TIMEOUT (HZ / 16) | ||
64 | struct test_mutex mtx; | ||
65 | struct ww_acquire_ctx ctx; | ||
66 | int ret; | ||
67 | |||
68 | ww_mutex_init(&mtx.mutex, &ww_class); | ||
69 | ww_acquire_init(&ctx, &ww_class); | ||
70 | |||
71 | INIT_WORK_ONSTACK(&mtx.work, test_mutex_work); | ||
72 | init_completion(&mtx.ready); | ||
73 | init_completion(&mtx.go); | ||
74 | init_completion(&mtx.done); | ||
75 | mtx.flags = flags; | ||
76 | |||
77 | schedule_work(&mtx.work); | ||
78 | |||
79 | wait_for_completion(&mtx.ready); | ||
80 | ww_mutex_lock(&mtx.mutex, (flags & TEST_MTX_CTX) ? &ctx : NULL); | ||
81 | complete(&mtx.go); | ||
82 | if (flags & TEST_MTX_SPIN) { | ||
83 | unsigned long timeout = jiffies + TIMEOUT; | ||
84 | |||
85 | ret = 0; | ||
86 | do { | ||
87 | if (completion_done(&mtx.done)) { | ||
88 | ret = -EINVAL; | ||
89 | break; | ||
90 | } | ||
91 | cpu_relax(); | ||
92 | } while (time_before(jiffies, timeout)); | ||
93 | } else { | ||
94 | ret = wait_for_completion_timeout(&mtx.done, TIMEOUT); | ||
95 | } | ||
96 | ww_mutex_unlock(&mtx.mutex); | ||
97 | ww_acquire_fini(&ctx); | ||
98 | |||
99 | if (ret) { | ||
100 | pr_err("%s(flags=%x): mutual exclusion failure\n", | ||
101 | __func__, flags); | ||
102 | ret = -EINVAL; | ||
103 | } | ||
104 | |||
105 | flush_work(&mtx.work); | ||
106 | destroy_work_on_stack(&mtx.work); | ||
107 | return ret; | ||
108 | #undef TIMEOUT | ||
109 | } | ||
110 | |||
111 | static int test_mutex(void) | ||
112 | { | ||
113 | int ret; | ||
114 | int i; | ||
115 | |||
116 | for (i = 0; i < __TEST_MTX_LAST; i++) { | ||
117 | ret = __test_mutex(i); | ||
118 | if (ret) | ||
119 | return ret; | ||
120 | } | ||
121 | |||
122 | return 0; | ||
123 | } | ||
124 | |||
125 | static int test_aa(void) | ||
126 | { | ||
127 | struct ww_mutex mutex; | ||
128 | struct ww_acquire_ctx ctx; | ||
129 | int ret; | ||
130 | |||
131 | ww_mutex_init(&mutex, &ww_class); | ||
132 | ww_acquire_init(&ctx, &ww_class); | ||
133 | |||
134 | ww_mutex_lock(&mutex, &ctx); | ||
135 | |||
136 | if (ww_mutex_trylock(&mutex)) { | ||
137 | pr_err("%s: trylocked itself!\n", __func__); | ||
138 | ww_mutex_unlock(&mutex); | ||
139 | ret = -EINVAL; | ||
140 | goto out; | ||
141 | } | ||
142 | |||
143 | ret = ww_mutex_lock(&mutex, &ctx); | ||
144 | if (ret != -EALREADY) { | ||
145 | pr_err("%s: missed deadlock for recursing, ret=%d\n", | ||
146 | __func__, ret); | ||
147 | if (!ret) | ||
148 | ww_mutex_unlock(&mutex); | ||
149 | ret = -EINVAL; | ||
150 | goto out; | ||
151 | } | ||
152 | |||
153 | ret = 0; | ||
154 | out: | ||
155 | ww_mutex_unlock(&mutex); | ||
156 | ww_acquire_fini(&ctx); | ||
157 | return ret; | ||
158 | } | ||
159 | |||
160 | struct test_abba { | ||
161 | struct work_struct work; | ||
162 | struct ww_mutex a_mutex; | ||
163 | struct ww_mutex b_mutex; | ||
164 | struct completion a_ready; | ||
165 | struct completion b_ready; | ||
166 | bool resolve; | ||
167 | int result; | ||
168 | }; | ||
169 | |||
170 | static void test_abba_work(struct work_struct *work) | ||
171 | { | ||
172 | struct test_abba *abba = container_of(work, typeof(*abba), work); | ||
173 | struct ww_acquire_ctx ctx; | ||
174 | int err; | ||
175 | |||
176 | ww_acquire_init(&ctx, &ww_class); | ||
177 | ww_mutex_lock(&abba->b_mutex, &ctx); | ||
178 | |||
179 | complete(&abba->b_ready); | ||
180 | wait_for_completion(&abba->a_ready); | ||
181 | |||
182 | err = ww_mutex_lock(&abba->a_mutex, &ctx); | ||
183 | if (abba->resolve && err == -EDEADLK) { | ||
184 | ww_mutex_unlock(&abba->b_mutex); | ||
185 | ww_mutex_lock_slow(&abba->a_mutex, &ctx); | ||
186 | err = ww_mutex_lock(&abba->b_mutex, &ctx); | ||
187 | } | ||
188 | |||
189 | if (!err) | ||
190 | ww_mutex_unlock(&abba->a_mutex); | ||
191 | ww_mutex_unlock(&abba->b_mutex); | ||
192 | ww_acquire_fini(&ctx); | ||
193 | |||
194 | abba->result = err; | ||
195 | } | ||
196 | |||
197 | static int test_abba(bool resolve) | ||
198 | { | ||
199 | struct test_abba abba; | ||
200 | struct ww_acquire_ctx ctx; | ||
201 | int err, ret; | ||
202 | |||
203 | ww_mutex_init(&abba.a_mutex, &ww_class); | ||
204 | ww_mutex_init(&abba.b_mutex, &ww_class); | ||
205 | INIT_WORK_ONSTACK(&abba.work, test_abba_work); | ||
206 | init_completion(&abba.a_ready); | ||
207 | init_completion(&abba.b_ready); | ||
208 | abba.resolve = resolve; | ||
209 | |||
210 | schedule_work(&abba.work); | ||
211 | |||
212 | ww_acquire_init(&ctx, &ww_class); | ||
213 | ww_mutex_lock(&abba.a_mutex, &ctx); | ||
214 | |||
215 | complete(&abba.a_ready); | ||
216 | wait_for_completion(&abba.b_ready); | ||
217 | |||
218 | err = ww_mutex_lock(&abba.b_mutex, &ctx); | ||
219 | if (resolve && err == -EDEADLK) { | ||
220 | ww_mutex_unlock(&abba.a_mutex); | ||
221 | ww_mutex_lock_slow(&abba.b_mutex, &ctx); | ||
222 | err = ww_mutex_lock(&abba.a_mutex, &ctx); | ||
223 | } | ||
224 | |||
225 | if (!err) | ||
226 | ww_mutex_unlock(&abba.b_mutex); | ||
227 | ww_mutex_unlock(&abba.a_mutex); | ||
228 | ww_acquire_fini(&ctx); | ||
229 | |||
230 | flush_work(&abba.work); | ||
231 | destroy_work_on_stack(&abba.work); | ||
232 | |||
233 | ret = 0; | ||
234 | if (resolve) { | ||
235 | if (err || abba.result) { | ||
236 | pr_err("%s: failed to resolve ABBA deadlock, A err=%d, B err=%d\n", | ||
237 | __func__, err, abba.result); | ||
238 | ret = -EINVAL; | ||
239 | } | ||
240 | } else { | ||
241 | if (err != -EDEADLK && abba.result != -EDEADLK) { | ||
242 | pr_err("%s: missed ABBA deadlock, A err=%d, B err=%d\n", | ||
243 | __func__, err, abba.result); | ||
244 | ret = -EINVAL; | ||
245 | } | ||
246 | } | ||
247 | return ret; | ||
248 | } | ||
249 | |||
250 | struct test_cycle { | ||
251 | struct work_struct work; | ||
252 | struct ww_mutex a_mutex; | ||
253 | struct ww_mutex *b_mutex; | ||
254 | struct completion *a_signal; | ||
255 | struct completion b_signal; | ||
256 | int result; | ||
257 | }; | ||
258 | |||
259 | static void test_cycle_work(struct work_struct *work) | ||
260 | { | ||
261 | struct test_cycle *cycle = container_of(work, typeof(*cycle), work); | ||
262 | struct ww_acquire_ctx ctx; | ||
263 | int err; | ||
264 | |||
265 | ww_acquire_init(&ctx, &ww_class); | ||
266 | ww_mutex_lock(&cycle->a_mutex, &ctx); | ||
267 | |||
268 | complete(cycle->a_signal); | ||
269 | wait_for_completion(&cycle->b_signal); | ||
270 | |||
271 | err = ww_mutex_lock(cycle->b_mutex, &ctx); | ||
272 | if (err == -EDEADLK) { | ||
273 | ww_mutex_unlock(&cycle->a_mutex); | ||
274 | ww_mutex_lock_slow(cycle->b_mutex, &ctx); | ||
275 | err = ww_mutex_lock(&cycle->a_mutex, &ctx); | ||
276 | } | ||
277 | |||
278 | if (!err) | ||
279 | ww_mutex_unlock(cycle->b_mutex); | ||
280 | ww_mutex_unlock(&cycle->a_mutex); | ||
281 | ww_acquire_fini(&ctx); | ||
282 | |||
283 | cycle->result = err; | ||
284 | } | ||
285 | |||
286 | static int __test_cycle(unsigned int nthreads) | ||
287 | { | ||
288 | struct test_cycle *cycles; | ||
289 | unsigned int n, last = nthreads - 1; | ||
290 | int ret; | ||
291 | |||
292 | cycles = kmalloc_array(nthreads, sizeof(*cycles), GFP_KERNEL); | ||
293 | if (!cycles) | ||
294 | return -ENOMEM; | ||
295 | |||
296 | for (n = 0; n < nthreads; n++) { | ||
297 | struct test_cycle *cycle = &cycles[n]; | ||
298 | |||
299 | ww_mutex_init(&cycle->a_mutex, &ww_class); | ||
300 | if (n == last) | ||
301 | cycle->b_mutex = &cycles[0].a_mutex; | ||
302 | else | ||
303 | cycle->b_mutex = &cycles[n + 1].a_mutex; | ||
304 | |||
305 | if (n == 0) | ||
306 | cycle->a_signal = &cycles[last].b_signal; | ||
307 | else | ||
308 | cycle->a_signal = &cycles[n - 1].b_signal; | ||
309 | init_completion(&cycle->b_signal); | ||
310 | |||
311 | INIT_WORK(&cycle->work, test_cycle_work); | ||
312 | cycle->result = 0; | ||
313 | } | ||
314 | |||
315 | for (n = 0; n < nthreads; n++) | ||
316 | queue_work(wq, &cycles[n].work); | ||
317 | |||
318 | flush_workqueue(wq); | ||
319 | |||
320 | ret = 0; | ||
321 | for (n = 0; n < nthreads; n++) { | ||
322 | struct test_cycle *cycle = &cycles[n]; | ||
323 | |||
324 | if (!cycle->result) | ||
325 | continue; | ||
326 | |||
327 | pr_err("cylic deadlock not resolved, ret[%d/%d] = %d\n", | ||
328 | n, nthreads, cycle->result); | ||
329 | ret = -EINVAL; | ||
330 | break; | ||
331 | } | ||
332 | |||
333 | for (n = 0; n < nthreads; n++) | ||
334 | ww_mutex_destroy(&cycles[n].a_mutex); | ||
335 | kfree(cycles); | ||
336 | return ret; | ||
337 | } | ||
338 | |||
339 | static int test_cycle(unsigned int ncpus) | ||
340 | { | ||
341 | unsigned int n; | ||
342 | int ret; | ||
343 | |||
344 | for (n = 2; n <= ncpus + 1; n++) { | ||
345 | ret = __test_cycle(n); | ||
346 | if (ret) | ||
347 | return ret; | ||
348 | } | ||
349 | |||
350 | return 0; | ||
351 | } | ||
352 | |||
353 | struct stress { | ||
354 | struct work_struct work; | ||
355 | struct ww_mutex *locks; | ||
356 | int nlocks; | ||
357 | int nloops; | ||
358 | }; | ||
359 | |||
360 | static int *get_random_order(int count) | ||
361 | { | ||
362 | int *order; | ||
363 | int n, r, tmp; | ||
364 | |||
365 | order = kmalloc_array(count, sizeof(*order), GFP_TEMPORARY); | ||
366 | if (!order) | ||
367 | return order; | ||
368 | |||
369 | for (n = 0; n < count; n++) | ||
370 | order[n] = n; | ||
371 | |||
372 | for (n = count - 1; n > 1; n--) { | ||
373 | r = get_random_int() % (n + 1); | ||
374 | if (r != n) { | ||
375 | tmp = order[n]; | ||
376 | order[n] = order[r]; | ||
377 | order[r] = tmp; | ||
378 | } | ||
379 | } | ||
380 | |||
381 | return order; | ||
382 | } | ||
383 | |||
384 | static void dummy_load(struct stress *stress) | ||
385 | { | ||
386 | usleep_range(1000, 2000); | ||
387 | } | ||
388 | |||
389 | static void stress_inorder_work(struct work_struct *work) | ||
390 | { | ||
391 | struct stress *stress = container_of(work, typeof(*stress), work); | ||
392 | const int nlocks = stress->nlocks; | ||
393 | struct ww_mutex *locks = stress->locks; | ||
394 | struct ww_acquire_ctx ctx; | ||
395 | int *order; | ||
396 | |||
397 | order = get_random_order(nlocks); | ||
398 | if (!order) | ||
399 | return; | ||
400 | |||
401 | ww_acquire_init(&ctx, &ww_class); | ||
402 | |||
403 | do { | ||
404 | int contended = -1; | ||
405 | int n, err; | ||
406 | |||
407 | retry: | ||
408 | err = 0; | ||
409 | for (n = 0; n < nlocks; n++) { | ||
410 | if (n == contended) | ||
411 | continue; | ||
412 | |||
413 | err = ww_mutex_lock(&locks[order[n]], &ctx); | ||
414 | if (err < 0) | ||
415 | break; | ||
416 | } | ||
417 | if (!err) | ||
418 | dummy_load(stress); | ||
419 | |||
420 | if (contended > n) | ||
421 | ww_mutex_unlock(&locks[order[contended]]); | ||
422 | contended = n; | ||
423 | while (n--) | ||
424 | ww_mutex_unlock(&locks[order[n]]); | ||
425 | |||
426 | if (err == -EDEADLK) { | ||
427 | ww_mutex_lock_slow(&locks[order[contended]], &ctx); | ||
428 | goto retry; | ||
429 | } | ||
430 | |||
431 | if (err) { | ||
432 | pr_err_once("stress (%s) failed with %d\n", | ||
433 | __func__, err); | ||
434 | break; | ||
435 | } | ||
436 | } while (--stress->nloops); | ||
437 | |||
438 | ww_acquire_fini(&ctx); | ||
439 | |||
440 | kfree(order); | ||
441 | kfree(stress); | ||
442 | } | ||
443 | |||
444 | struct reorder_lock { | ||
445 | struct list_head link; | ||
446 | struct ww_mutex *lock; | ||
447 | }; | ||
448 | |||
449 | static void stress_reorder_work(struct work_struct *work) | ||
450 | { | ||
451 | struct stress *stress = container_of(work, typeof(*stress), work); | ||
452 | LIST_HEAD(locks); | ||
453 | struct ww_acquire_ctx ctx; | ||
454 | struct reorder_lock *ll, *ln; | ||
455 | int *order; | ||
456 | int n, err; | ||
457 | |||
458 | order = get_random_order(stress->nlocks); | ||
459 | if (!order) | ||
460 | return; | ||
461 | |||
462 | for (n = 0; n < stress->nlocks; n++) { | ||
463 | ll = kmalloc(sizeof(*ll), GFP_KERNEL); | ||
464 | if (!ll) | ||
465 | goto out; | ||
466 | |||
467 | ll->lock = &stress->locks[order[n]]; | ||
468 | list_add(&ll->link, &locks); | ||
469 | } | ||
470 | kfree(order); | ||
471 | order = NULL; | ||
472 | |||
473 | ww_acquire_init(&ctx, &ww_class); | ||
474 | |||
475 | do { | ||
476 | list_for_each_entry(ll, &locks, link) { | ||
477 | err = ww_mutex_lock(ll->lock, &ctx); | ||
478 | if (!err) | ||
479 | continue; | ||
480 | |||
481 | ln = ll; | ||
482 | list_for_each_entry_continue_reverse(ln, &locks, link) | ||
483 | ww_mutex_unlock(ln->lock); | ||
484 | |||
485 | if (err != -EDEADLK) { | ||
486 | pr_err_once("stress (%s) failed with %d\n", | ||
487 | __func__, err); | ||
488 | break; | ||
489 | } | ||
490 | |||
491 | ww_mutex_lock_slow(ll->lock, &ctx); | ||
492 | list_move(&ll->link, &locks); /* restarts iteration */ | ||
493 | } | ||
494 | |||
495 | dummy_load(stress); | ||
496 | list_for_each_entry(ll, &locks, link) | ||
497 | ww_mutex_unlock(ll->lock); | ||
498 | } while (--stress->nloops); | ||
499 | |||
500 | ww_acquire_fini(&ctx); | ||
501 | |||
502 | out: | ||
503 | list_for_each_entry_safe(ll, ln, &locks, link) | ||
504 | kfree(ll); | ||
505 | kfree(order); | ||
506 | kfree(stress); | ||
507 | } | ||
508 | |||
509 | static void stress_one_work(struct work_struct *work) | ||
510 | { | ||
511 | struct stress *stress = container_of(work, typeof(*stress), work); | ||
512 | const int nlocks = stress->nlocks; | ||
513 | struct ww_mutex *lock = stress->locks + (get_random_int() % nlocks); | ||
514 | int err; | ||
515 | |||
516 | do { | ||
517 | err = ww_mutex_lock(lock, NULL); | ||
518 | if (!err) { | ||
519 | dummy_load(stress); | ||
520 | ww_mutex_unlock(lock); | ||
521 | } else { | ||
522 | pr_err_once("stress (%s) failed with %d\n", | ||
523 | __func__, err); | ||
524 | break; | ||
525 | } | ||
526 | } while (--stress->nloops); | ||
527 | |||
528 | kfree(stress); | ||
529 | } | ||
530 | |||
531 | #define STRESS_INORDER BIT(0) | ||
532 | #define STRESS_REORDER BIT(1) | ||
533 | #define STRESS_ONE BIT(2) | ||
534 | #define STRESS_ALL (STRESS_INORDER | STRESS_REORDER | STRESS_ONE) | ||
535 | |||
536 | static int stress(int nlocks, int nthreads, int nloops, unsigned int flags) | ||
537 | { | ||
538 | struct ww_mutex *locks; | ||
539 | int n; | ||
540 | |||
541 | locks = kmalloc_array(nlocks, sizeof(*locks), GFP_KERNEL); | ||
542 | if (!locks) | ||
543 | return -ENOMEM; | ||
544 | |||
545 | for (n = 0; n < nlocks; n++) | ||
546 | ww_mutex_init(&locks[n], &ww_class); | ||
547 | |||
548 | for (n = 0; nthreads; n++) { | ||
549 | struct stress *stress; | ||
550 | void (*fn)(struct work_struct *work); | ||
551 | |||
552 | fn = NULL; | ||
553 | switch (n & 3) { | ||
554 | case 0: | ||
555 | if (flags & STRESS_INORDER) | ||
556 | fn = stress_inorder_work; | ||
557 | break; | ||
558 | case 1: | ||
559 | if (flags & STRESS_REORDER) | ||
560 | fn = stress_reorder_work; | ||
561 | break; | ||
562 | case 2: | ||
563 | if (flags & STRESS_ONE) | ||
564 | fn = stress_one_work; | ||
565 | break; | ||
566 | } | ||
567 | |||
568 | if (!fn) | ||
569 | continue; | ||
570 | |||
571 | stress = kmalloc(sizeof(*stress), GFP_KERNEL); | ||
572 | if (!stress) | ||
573 | break; | ||
574 | |||
575 | INIT_WORK(&stress->work, fn); | ||
576 | stress->locks = locks; | ||
577 | stress->nlocks = nlocks; | ||
578 | stress->nloops = nloops; | ||
579 | |||
580 | queue_work(wq, &stress->work); | ||
581 | nthreads--; | ||
582 | } | ||
583 | |||
584 | flush_workqueue(wq); | ||
585 | |||
586 | for (n = 0; n < nlocks; n++) | ||
587 | ww_mutex_destroy(&locks[n]); | ||
588 | kfree(locks); | ||
589 | |||
590 | return 0; | ||
591 | } | ||
592 | |||
593 | static int __init test_ww_mutex_init(void) | ||
594 | { | ||
595 | int ncpus = num_online_cpus(); | ||
596 | int ret; | ||
597 | |||
598 | wq = alloc_workqueue("test-ww_mutex", WQ_UNBOUND, 0); | ||
599 | if (!wq) | ||
600 | return -ENOMEM; | ||
601 | |||
602 | ret = test_mutex(); | ||
603 | if (ret) | ||
604 | return ret; | ||
605 | |||
606 | ret = test_aa(); | ||
607 | if (ret) | ||
608 | return ret; | ||
609 | |||
610 | ret = test_abba(false); | ||
611 | if (ret) | ||
612 | return ret; | ||
613 | |||
614 | ret = test_abba(true); | ||
615 | if (ret) | ||
616 | return ret; | ||
617 | |||
618 | ret = test_cycle(ncpus); | ||
619 | if (ret) | ||
620 | return ret; | ||
621 | |||
622 | ret = stress(16, 2*ncpus, 1<<10, STRESS_INORDER); | ||
623 | if (ret) | ||
624 | return ret; | ||
625 | |||
626 | ret = stress(16, 2*ncpus, 1<<10, STRESS_REORDER); | ||
627 | if (ret) | ||
628 | return ret; | ||
629 | |||
630 | ret = stress(4096, hweight32(STRESS_ALL)*ncpus, 1<<12, STRESS_ALL); | ||
631 | if (ret) | ||
632 | return ret; | ||
633 | |||
634 | return 0; | ||
635 | } | ||
636 | |||
637 | static void __exit test_ww_mutex_exit(void) | ||
638 | { | ||
639 | destroy_workqueue(wq); | ||
640 | } | ||
641 | |||
642 | module_init(test_ww_mutex_init); | ||
643 | module_exit(test_ww_mutex_exit); | ||
644 | |||
645 | MODULE_LICENSE("GPL"); | ||
646 | MODULE_AUTHOR("Intel Corporation"); | ||
diff --git a/kernel/pid.c b/kernel/pid.c index f66162f2359b..0291804151b5 100644 --- a/kernel/pid.c +++ b/kernel/pid.c | |||
@@ -68,9 +68,7 @@ static inline int mk_pid(struct pid_namespace *pid_ns, | |||
68 | * the scheme scales to up to 4 million PIDs, runtime. | 68 | * the scheme scales to up to 4 million PIDs, runtime. |
69 | */ | 69 | */ |
70 | struct pid_namespace init_pid_ns = { | 70 | struct pid_namespace init_pid_ns = { |
71 | .kref = { | 71 | .kref = KREF_INIT(2), |
72 | .refcount = ATOMIC_INIT(2), | ||
73 | }, | ||
74 | .pidmap = { | 72 | .pidmap = { |
75 | [ 0 ... PIDMAP_ENTRIES-1] = { ATOMIC_INIT(BITS_PER_PAGE), NULL } | 73 | [ 0 ... PIDMAP_ENTRIES-1] = { ATOMIC_INIT(BITS_PER_PAGE), NULL } |
76 | }, | 74 | }, |
diff --git a/lib/Kconfig.debug b/lib/Kconfig.debug index 07c89e4b5d60..acedbe626d47 100644 --- a/lib/Kconfig.debug +++ b/lib/Kconfig.debug | |||
@@ -716,6 +716,19 @@ source "lib/Kconfig.kmemcheck" | |||
716 | 716 | ||
717 | source "lib/Kconfig.kasan" | 717 | source "lib/Kconfig.kasan" |
718 | 718 | ||
719 | config DEBUG_REFCOUNT | ||
720 | bool "Verbose refcount checks" | ||
721 | help | ||
722 | Say Y here if you want reference counters (refcount_t and kref) to | ||
723 | generate WARNs on dubious usage. Without this refcount_t will still | ||
724 | be a saturating counter and avoid Use-After-Free by turning it into | ||
725 | a resource leak Denial-Of-Service. | ||
726 | |||
727 | Use of this option will increase kernel text size but will alert the | ||
728 | admin of potential abuse. | ||
729 | |||
730 | If in doubt, say "N". | ||
731 | |||
719 | endmenu # "Memory Debugging" | 732 | endmenu # "Memory Debugging" |
720 | 733 | ||
721 | config ARCH_HAS_KCOV | 734 | config ARCH_HAS_KCOV |
@@ -1166,6 +1179,18 @@ config LOCK_TORTURE_TEST | |||
1166 | Say M if you want these torture tests to build as a module. | 1179 | Say M if you want these torture tests to build as a module. |
1167 | Say N if you are unsure. | 1180 | Say N if you are unsure. |
1168 | 1181 | ||
1182 | config WW_MUTEX_SELFTEST | ||
1183 | tristate "Wait/wound mutex selftests" | ||
1184 | help | ||
1185 | This option provides a kernel module that runs tests on the | ||
1186 | on the struct ww_mutex locking API. | ||
1187 | |||
1188 | It is recommended to enable DEBUG_WW_MUTEX_SLOWPATH in conjunction | ||
1189 | with this test harness. | ||
1190 | |||
1191 | Say M if you want these self tests to build as a module. | ||
1192 | Say N if you are unsure. | ||
1193 | |||
1169 | endmenu # lock debugging | 1194 | endmenu # lock debugging |
1170 | 1195 | ||
1171 | config TRACE_IRQFLAGS | 1196 | config TRACE_IRQFLAGS |
diff --git a/net/bluetooth/6lowpan.c b/net/bluetooth/6lowpan.c index 1904a93f47d5..d491529332f4 100644 --- a/net/bluetooth/6lowpan.c +++ b/net/bluetooth/6lowpan.c | |||
@@ -920,7 +920,7 @@ static void chan_close_cb(struct l2cap_chan *chan) | |||
920 | BT_DBG("dev %p removing %speer %p", dev, | 920 | BT_DBG("dev %p removing %speer %p", dev, |
921 | last ? "last " : "1 ", peer); | 921 | last ? "last " : "1 ", peer); |
922 | BT_DBG("chan %p orig refcnt %d", chan, | 922 | BT_DBG("chan %p orig refcnt %d", chan, |
923 | atomic_read(&chan->kref.refcount)); | 923 | kref_read(&chan->kref)); |
924 | 924 | ||
925 | l2cap_chan_put(chan); | 925 | l2cap_chan_put(chan); |
926 | break; | 926 | break; |
diff --git a/net/bluetooth/a2mp.c b/net/bluetooth/a2mp.c index 5f123c3320a7..f0095fd79818 100644 --- a/net/bluetooth/a2mp.c +++ b/net/bluetooth/a2mp.c | |||
@@ -810,7 +810,7 @@ static struct l2cap_chan *a2mp_chan_open(struct l2cap_conn *conn, bool locked) | |||
810 | /* AMP Manager functions */ | 810 | /* AMP Manager functions */ |
811 | struct amp_mgr *amp_mgr_get(struct amp_mgr *mgr) | 811 | struct amp_mgr *amp_mgr_get(struct amp_mgr *mgr) |
812 | { | 812 | { |
813 | BT_DBG("mgr %p orig refcnt %d", mgr, atomic_read(&mgr->kref.refcount)); | 813 | BT_DBG("mgr %p orig refcnt %d", mgr, kref_read(&mgr->kref)); |
814 | 814 | ||
815 | kref_get(&mgr->kref); | 815 | kref_get(&mgr->kref); |
816 | 816 | ||
@@ -833,7 +833,7 @@ static void amp_mgr_destroy(struct kref *kref) | |||
833 | 833 | ||
834 | int amp_mgr_put(struct amp_mgr *mgr) | 834 | int amp_mgr_put(struct amp_mgr *mgr) |
835 | { | 835 | { |
836 | BT_DBG("mgr %p orig refcnt %d", mgr, atomic_read(&mgr->kref.refcount)); | 836 | BT_DBG("mgr %p orig refcnt %d", mgr, kref_read(&mgr->kref)); |
837 | 837 | ||
838 | return kref_put(&mgr->kref, &_mgr_destroy); | 838 | return kref_put(&mgr->kref, &_mgr_destroy); |
839 | } | 839 | } |
diff --git a/net/bluetooth/amp.c b/net/bluetooth/amp.c index e32f34189007..02a4ccc04e1e 100644 --- a/net/bluetooth/amp.c +++ b/net/bluetooth/amp.c | |||
@@ -24,7 +24,7 @@ | |||
24 | void amp_ctrl_get(struct amp_ctrl *ctrl) | 24 | void amp_ctrl_get(struct amp_ctrl *ctrl) |
25 | { | 25 | { |
26 | BT_DBG("ctrl %p orig refcnt %d", ctrl, | 26 | BT_DBG("ctrl %p orig refcnt %d", ctrl, |
27 | atomic_read(&ctrl->kref.refcount)); | 27 | kref_read(&ctrl->kref)); |
28 | 28 | ||
29 | kref_get(&ctrl->kref); | 29 | kref_get(&ctrl->kref); |
30 | } | 30 | } |
@@ -42,7 +42,7 @@ static void amp_ctrl_destroy(struct kref *kref) | |||
42 | int amp_ctrl_put(struct amp_ctrl *ctrl) | 42 | int amp_ctrl_put(struct amp_ctrl *ctrl) |
43 | { | 43 | { |
44 | BT_DBG("ctrl %p orig refcnt %d", ctrl, | 44 | BT_DBG("ctrl %p orig refcnt %d", ctrl, |
45 | atomic_read(&ctrl->kref.refcount)); | 45 | kref_read(&ctrl->kref)); |
46 | 46 | ||
47 | return kref_put(&ctrl->kref, &_ctrl_destroy); | 47 | return kref_put(&ctrl->kref, &_ctrl_destroy); |
48 | } | 48 | } |
diff --git a/net/bluetooth/l2cap_core.c b/net/bluetooth/l2cap_core.c index ce0b5dd01953..fc7f321a3823 100644 --- a/net/bluetooth/l2cap_core.c +++ b/net/bluetooth/l2cap_core.c | |||
@@ -481,14 +481,14 @@ static void l2cap_chan_destroy(struct kref *kref) | |||
481 | 481 | ||
482 | void l2cap_chan_hold(struct l2cap_chan *c) | 482 | void l2cap_chan_hold(struct l2cap_chan *c) |
483 | { | 483 | { |
484 | BT_DBG("chan %p orig refcnt %d", c, atomic_read(&c->kref.refcount)); | 484 | BT_DBG("chan %p orig refcnt %d", c, kref_read(&c->kref)); |
485 | 485 | ||
486 | kref_get(&c->kref); | 486 | kref_get(&c->kref); |
487 | } | 487 | } |
488 | 488 | ||
489 | void l2cap_chan_put(struct l2cap_chan *c) | 489 | void l2cap_chan_put(struct l2cap_chan *c) |
490 | { | 490 | { |
491 | BT_DBG("chan %p orig refcnt %d", c, atomic_read(&c->kref.refcount)); | 491 | BT_DBG("chan %p orig refcnt %d", c, kref_read(&c->kref)); |
492 | 492 | ||
493 | kref_put(&c->kref, l2cap_chan_destroy); | 493 | kref_put(&c->kref, l2cap_chan_destroy); |
494 | } | 494 | } |
diff --git a/net/ceph/messenger.c b/net/ceph/messenger.c index 770c52701efa..bad3d4ae43f6 100644 --- a/net/ceph/messenger.c +++ b/net/ceph/messenger.c | |||
@@ -3425,7 +3425,7 @@ static void ceph_msg_release(struct kref *kref) | |||
3425 | struct ceph_msg *ceph_msg_get(struct ceph_msg *msg) | 3425 | struct ceph_msg *ceph_msg_get(struct ceph_msg *msg) |
3426 | { | 3426 | { |
3427 | dout("%s %p (was %d)\n", __func__, msg, | 3427 | dout("%s %p (was %d)\n", __func__, msg, |
3428 | atomic_read(&msg->kref.refcount)); | 3428 | kref_read(&msg->kref)); |
3429 | kref_get(&msg->kref); | 3429 | kref_get(&msg->kref); |
3430 | return msg; | 3430 | return msg; |
3431 | } | 3431 | } |
@@ -3434,7 +3434,7 @@ EXPORT_SYMBOL(ceph_msg_get); | |||
3434 | void ceph_msg_put(struct ceph_msg *msg) | 3434 | void ceph_msg_put(struct ceph_msg *msg) |
3435 | { | 3435 | { |
3436 | dout("%s %p (was %d)\n", __func__, msg, | 3436 | dout("%s %p (was %d)\n", __func__, msg, |
3437 | atomic_read(&msg->kref.refcount)); | 3437 | kref_read(&msg->kref)); |
3438 | kref_put(&msg->kref, ceph_msg_release); | 3438 | kref_put(&msg->kref, ceph_msg_release); |
3439 | } | 3439 | } |
3440 | EXPORT_SYMBOL(ceph_msg_put); | 3440 | EXPORT_SYMBOL(ceph_msg_put); |
diff --git a/net/ceph/osd_client.c b/net/ceph/osd_client.c index 842f049abb86..f3378ba1a828 100644 --- a/net/ceph/osd_client.c +++ b/net/ceph/osd_client.c | |||
@@ -438,7 +438,7 @@ static void ceph_osdc_release_request(struct kref *kref) | |||
438 | void ceph_osdc_get_request(struct ceph_osd_request *req) | 438 | void ceph_osdc_get_request(struct ceph_osd_request *req) |
439 | { | 439 | { |
440 | dout("%s %p (was %d)\n", __func__, req, | 440 | dout("%s %p (was %d)\n", __func__, req, |
441 | atomic_read(&req->r_kref.refcount)); | 441 | kref_read(&req->r_kref)); |
442 | kref_get(&req->r_kref); | 442 | kref_get(&req->r_kref); |
443 | } | 443 | } |
444 | EXPORT_SYMBOL(ceph_osdc_get_request); | 444 | EXPORT_SYMBOL(ceph_osdc_get_request); |
@@ -447,7 +447,7 @@ void ceph_osdc_put_request(struct ceph_osd_request *req) | |||
447 | { | 447 | { |
448 | if (req) { | 448 | if (req) { |
449 | dout("%s %p (was %d)\n", __func__, req, | 449 | dout("%s %p (was %d)\n", __func__, req, |
450 | atomic_read(&req->r_kref.refcount)); | 450 | kref_read(&req->r_kref)); |
451 | kref_put(&req->r_kref, ceph_osdc_release_request); | 451 | kref_put(&req->r_kref, ceph_osdc_release_request); |
452 | } | 452 | } |
453 | } | 453 | } |
@@ -487,11 +487,11 @@ static void request_reinit(struct ceph_osd_request *req) | |||
487 | struct ceph_msg *reply_msg = req->r_reply; | 487 | struct ceph_msg *reply_msg = req->r_reply; |
488 | 488 | ||
489 | dout("%s req %p\n", __func__, req); | 489 | dout("%s req %p\n", __func__, req); |
490 | WARN_ON(atomic_read(&req->r_kref.refcount) != 1); | 490 | WARN_ON(kref_read(&req->r_kref) != 1); |
491 | request_release_checks(req); | 491 | request_release_checks(req); |
492 | 492 | ||
493 | WARN_ON(atomic_read(&request_msg->kref.refcount) != 1); | 493 | WARN_ON(kref_read(&request_msg->kref) != 1); |
494 | WARN_ON(atomic_read(&reply_msg->kref.refcount) != 1); | 494 | WARN_ON(kref_read(&reply_msg->kref) != 1); |
495 | target_destroy(&req->r_t); | 495 | target_destroy(&req->r_t); |
496 | 496 | ||
497 | request_init(req); | 497 | request_init(req); |
diff --git a/net/sunrpc/cache.c b/net/sunrpc/cache.c index 8147e8d56eb2..f39e3e11f9aa 100644 --- a/net/sunrpc/cache.c +++ b/net/sunrpc/cache.c | |||
@@ -1358,7 +1358,7 @@ static int c_show(struct seq_file *m, void *p) | |||
1358 | ifdebug(CACHE) | 1358 | ifdebug(CACHE) |
1359 | seq_printf(m, "# expiry=%ld refcnt=%d flags=%lx\n", | 1359 | seq_printf(m, "# expiry=%ld refcnt=%d flags=%lx\n", |
1360 | convert_to_wallclock(cp->expiry_time), | 1360 | convert_to_wallclock(cp->expiry_time), |
1361 | atomic_read(&cp->ref.refcount), cp->flags); | 1361 | kref_read(&cp->ref), cp->flags); |
1362 | cache_get(cp); | 1362 | cache_get(cp); |
1363 | if (cache_check(cd, cp, NULL)) | 1363 | if (cache_check(cd, cp, NULL)) |
1364 | /* cache_check does a cache_put on failure */ | 1364 | /* cache_check does a cache_put on failure */ |
diff --git a/net/sunrpc/svc_xprt.c b/net/sunrpc/svc_xprt.c index 9c9db55a0c1e..7bfe1fb42add 100644 --- a/net/sunrpc/svc_xprt.c +++ b/net/sunrpc/svc_xprt.c | |||
@@ -490,7 +490,7 @@ static struct svc_xprt *svc_xprt_dequeue(struct svc_pool *pool) | |||
490 | svc_xprt_get(xprt); | 490 | svc_xprt_get(xprt); |
491 | 491 | ||
492 | dprintk("svc: transport %p dequeued, inuse=%d\n", | 492 | dprintk("svc: transport %p dequeued, inuse=%d\n", |
493 | xprt, atomic_read(&xprt->xpt_ref.refcount)); | 493 | xprt, kref_read(&xprt->xpt_ref)); |
494 | } | 494 | } |
495 | spin_unlock_bh(&pool->sp_lock); | 495 | spin_unlock_bh(&pool->sp_lock); |
496 | out: | 496 | out: |
@@ -822,7 +822,7 @@ static int svc_handle_xprt(struct svc_rqst *rqstp, struct svc_xprt *xprt) | |||
822 | /* XPT_DATA|XPT_DEFERRED case: */ | 822 | /* XPT_DATA|XPT_DEFERRED case: */ |
823 | dprintk("svc: server %p, pool %u, transport %p, inuse=%d\n", | 823 | dprintk("svc: server %p, pool %u, transport %p, inuse=%d\n", |
824 | rqstp, rqstp->rq_pool->sp_id, xprt, | 824 | rqstp, rqstp->rq_pool->sp_id, xprt, |
825 | atomic_read(&xprt->xpt_ref.refcount)); | 825 | kref_read(&xprt->xpt_ref)); |
826 | rqstp->rq_deferred = svc_deferred_dequeue(xprt); | 826 | rqstp->rq_deferred = svc_deferred_dequeue(xprt); |
827 | if (rqstp->rq_deferred) | 827 | if (rqstp->rq_deferred) |
828 | len = svc_deferred_recv(rqstp); | 828 | len = svc_deferred_recv(rqstp); |
@@ -980,7 +980,7 @@ static void svc_age_temp_xprts(unsigned long closure) | |||
980 | * through, close it. */ | 980 | * through, close it. */ |
981 | if (!test_and_set_bit(XPT_OLD, &xprt->xpt_flags)) | 981 | if (!test_and_set_bit(XPT_OLD, &xprt->xpt_flags)) |
982 | continue; | 982 | continue; |
983 | if (atomic_read(&xprt->xpt_ref.refcount) > 1 || | 983 | if (kref_read(&xprt->xpt_ref) > 1 || |
984 | test_bit(XPT_BUSY, &xprt->xpt_flags)) | 984 | test_bit(XPT_BUSY, &xprt->xpt_flags)) |
985 | continue; | 985 | continue; |
986 | list_del_init(le); | 986 | list_del_init(le); |
diff --git a/net/sunrpc/svcauth.c b/net/sunrpc/svcauth.c index e112da8005b5..bb8db3cb8032 100644 --- a/net/sunrpc/svcauth.c +++ b/net/sunrpc/svcauth.c | |||
@@ -126,13 +126,18 @@ EXPORT_SYMBOL_GPL(svc_auth_unregister); | |||
126 | static struct hlist_head auth_domain_table[DN_HASHMAX]; | 126 | static struct hlist_head auth_domain_table[DN_HASHMAX]; |
127 | static DEFINE_SPINLOCK(auth_domain_lock); | 127 | static DEFINE_SPINLOCK(auth_domain_lock); |
128 | 128 | ||
129 | static void auth_domain_release(struct kref *kref) | ||
130 | { | ||
131 | struct auth_domain *dom = container_of(kref, struct auth_domain, ref); | ||
132 | |||
133 | hlist_del(&dom->hash); | ||
134 | dom->flavour->domain_release(dom); | ||
135 | spin_unlock(&auth_domain_lock); | ||
136 | } | ||
137 | |||
129 | void auth_domain_put(struct auth_domain *dom) | 138 | void auth_domain_put(struct auth_domain *dom) |
130 | { | 139 | { |
131 | if (atomic_dec_and_lock(&dom->ref.refcount, &auth_domain_lock)) { | 140 | kref_put_lock(&dom->ref, auth_domain_release, &auth_domain_lock); |
132 | hlist_del(&dom->hash); | ||
133 | dom->flavour->domain_release(dom); | ||
134 | spin_unlock(&auth_domain_lock); | ||
135 | } | ||
136 | } | 141 | } |
137 | EXPORT_SYMBOL_GPL(auth_domain_put); | 142 | EXPORT_SYMBOL_GPL(auth_domain_put); |
138 | 143 | ||
diff --git a/net/sunrpc/xprtrdma/svc_rdma_transport.c b/net/sunrpc/xprtrdma/svc_rdma_transport.c index ca2799af05a6..39652d390a9c 100644 --- a/net/sunrpc/xprtrdma/svc_rdma_transport.c +++ b/net/sunrpc/xprtrdma/svc_rdma_transport.c | |||
@@ -1201,9 +1201,9 @@ static void __svc_rdma_free(struct work_struct *work) | |||
1201 | ib_drain_qp(rdma->sc_qp); | 1201 | ib_drain_qp(rdma->sc_qp); |
1202 | 1202 | ||
1203 | /* We should only be called from kref_put */ | 1203 | /* We should only be called from kref_put */ |
1204 | if (atomic_read(&xprt->xpt_ref.refcount) != 0) | 1204 | if (kref_read(&xprt->xpt_ref) != 0) |
1205 | pr_err("svcrdma: sc_xprt still in use? (%d)\n", | 1205 | pr_err("svcrdma: sc_xprt still in use? (%d)\n", |
1206 | atomic_read(&xprt->xpt_ref.refcount)); | 1206 | kref_read(&xprt->xpt_ref)); |
1207 | 1207 | ||
1208 | /* | 1208 | /* |
1209 | * Destroy queued, but not processed read completions. Note | 1209 | * Destroy queued, but not processed read completions. Note |
diff --git a/security/apparmor/include/apparmor.h b/security/apparmor/include/apparmor.h index 5d721e990876..f067be814626 100644 --- a/security/apparmor/include/apparmor.h +++ b/security/apparmor/include/apparmor.h | |||
@@ -78,12 +78,6 @@ static inline void *kvzalloc(size_t size) | |||
78 | return __aa_kvmalloc(size, __GFP_ZERO); | 78 | return __aa_kvmalloc(size, __GFP_ZERO); |
79 | } | 79 | } |
80 | 80 | ||
81 | /* returns 0 if kref not incremented */ | ||
82 | static inline int kref_get_not0(struct kref *kref) | ||
83 | { | ||
84 | return atomic_inc_not_zero(&kref->refcount); | ||
85 | } | ||
86 | |||
87 | /** | 81 | /** |
88 | * aa_strneq - compare null terminated @str to a non null terminated substring | 82 | * aa_strneq - compare null terminated @str to a non null terminated substring |
89 | * @str: a null terminated string | 83 | * @str: a null terminated string |
diff --git a/security/apparmor/include/policy.h b/security/apparmor/include/policy.h index 52275f040a5f..46467aaa557b 100644 --- a/security/apparmor/include/policy.h +++ b/security/apparmor/include/policy.h | |||
@@ -287,7 +287,7 @@ static inline struct aa_profile *aa_get_profile(struct aa_profile *p) | |||
287 | */ | 287 | */ |
288 | static inline struct aa_profile *aa_get_profile_not0(struct aa_profile *p) | 288 | static inline struct aa_profile *aa_get_profile_not0(struct aa_profile *p) |
289 | { | 289 | { |
290 | if (p && kref_get_not0(&p->count)) | 290 | if (p && kref_get_unless_zero(&p->count)) |
291 | return p; | 291 | return p; |
292 | 292 | ||
293 | return NULL; | 293 | return NULL; |
@@ -307,7 +307,7 @@ static inline struct aa_profile *aa_get_profile_rcu(struct aa_profile __rcu **p) | |||
307 | rcu_read_lock(); | 307 | rcu_read_lock(); |
308 | do { | 308 | do { |
309 | c = rcu_dereference(*p); | 309 | c = rcu_dereference(*p); |
310 | } while (c && !kref_get_not0(&c->count)); | 310 | } while (c && !kref_get_unless_zero(&c->count)); |
311 | rcu_read_unlock(); | 311 | rcu_read_unlock(); |
312 | 312 | ||
313 | return c; | 313 | return c; |
diff --git a/tools/testing/selftests/locking/ww_mutex.sh b/tools/testing/selftests/locking/ww_mutex.sh new file mode 100644 index 000000000000..6905da965f3b --- /dev/null +++ b/tools/testing/selftests/locking/ww_mutex.sh | |||
@@ -0,0 +1,10 @@ | |||
1 | #!/bin/sh | ||
2 | # Runs API tests for struct ww_mutex (Wait/Wound mutexes) | ||
3 | |||
4 | if /sbin/modprobe -q test-ww_mutex; then | ||
5 | /sbin/modprobe -q -r test-ww_mutex | ||
6 | echo "locking/ww_mutex: ok" | ||
7 | else | ||
8 | echo "locking/ww_mutex: [FAIL]" | ||
9 | exit 1 | ||
10 | fi | ||
diff --git a/tools/testing/selftests/rcutorture/configs/lock/CFLIST b/tools/testing/selftests/rcutorture/configs/lock/CFLIST index b9611c523723..41bae5824339 100644 --- a/tools/testing/selftests/rcutorture/configs/lock/CFLIST +++ b/tools/testing/selftests/rcutorture/configs/lock/CFLIST | |||
@@ -4,3 +4,4 @@ LOCK03 | |||
4 | LOCK04 | 4 | LOCK04 |
5 | LOCK05 | 5 | LOCK05 |
6 | LOCK06 | 6 | LOCK06 |
7 | LOCK07 | ||
diff --git a/tools/testing/selftests/rcutorture/configs/lock/LOCK07 b/tools/testing/selftests/rcutorture/configs/lock/LOCK07 new file mode 100644 index 000000000000..1d1da1477fc3 --- /dev/null +++ b/tools/testing/selftests/rcutorture/configs/lock/LOCK07 | |||
@@ -0,0 +1,6 @@ | |||
1 | CONFIG_SMP=y | ||
2 | CONFIG_NR_CPUS=4 | ||
3 | CONFIG_HOTPLUG_CPU=y | ||
4 | CONFIG_PREEMPT_NONE=n | ||
5 | CONFIG_PREEMPT_VOLUNTARY=n | ||
6 | CONFIG_PREEMPT=y | ||
diff --git a/tools/testing/selftests/rcutorture/configs/lock/LOCK07.boot b/tools/testing/selftests/rcutorture/configs/lock/LOCK07.boot new file mode 100644 index 000000000000..97dadd1a9e45 --- /dev/null +++ b/tools/testing/selftests/rcutorture/configs/lock/LOCK07.boot | |||
@@ -0,0 +1 @@ | |||
locktorture.torture_type=ww_mutex_lock | |||