summaryrefslogtreecommitdiff
path: root/drivers/android
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2024-11-29 11:58:27 -0800
committerLinus Torvalds <torvalds@linux-foundation.org>2024-11-29 11:58:27 -0800
commit2eff01ee2881becc9daaa0d53477ec202136b1f4 (patch)
treed90cf5527266962e3a249a1f96e10e4afe29d246 /drivers/android
parent55cb93fd243bad2c6e15f9151a32f575d2f5371f (diff)
parent5a6c35258d10a4966f45ee48ae24a7d4dad303ce (diff)
Merge tag 'char-misc-6.13-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/char-misc
Pull char/misc/IIO/whatever driver subsystem updates from Greg KH: "Here is the 'big and hairy' char/misc/iio and other small driver subsystem updates for 6.13-rc1. Loads of things in here, and even a fun merge conflict! - rust misc driver bindings and other rust changes to make misc drivers actually possible. I think this is the tipping point, expect to see way more rust drivers going forward now that these bindings are present. Next merge window hopefully we will have pci and platform drivers working, which will fully enable almost all driver subsystems to start accepting (or at least getting) rust drivers. This is the end result of a lot of work from a lot of people, congrats to all of them for getting this far, you've proved many of us wrong in the best way possible, working code :) - IIO driver updates, too many to list individually, that subsystem keeps growing and growing... - Interconnect driver updates - nvmem driver updates - pwm driver updates - platform_driver::remove() fixups, loads of them - counter driver updates - misc driver updates (keba?) - binder driver updates and fixes - loads of other small char/misc/etc driver updates and additions, full details in the shortlog. All of these have been in linux-next for a while, with no other reported issues other than that merge conflict" * tag 'char-misc-6.13-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/char-misc: (401 commits) mei: vsc: Fix typo "maintstepping" -> "mainstepping" firmware: Switch back to struct platform_driver::remove() misc: isl29020: Fix the wrong format specifier scripts/tags.sh: Don't tag usages of DEFINE_MUTEX fpga: Switch back to struct platform_driver::remove() mei: vsc: Improve error logging in vsc_identify_silicon() mei: vsc: Do not re-enable interrupt from vsc_tp_reset() dt-bindings: spmi: qcom,x1e80100-spmi-pmic-arb: Add SAR2130P compatible dt-bindings: spmi: spmi-mtk-pmif: Add compatible for MT8188 spmi: pmic-arb: fix return path in for_each_available_child_of_node() iio: Move __private marking before struct element priv in struct iio_dev docs: iio: ad7380: add adaq4370-4 and adaq4380-4 iio: adc: ad7380: add support for adaq4370-4 and adaq4380-4 iio: adc: ad7380: use local dev variable to shorten long lines iio: adc: ad7380: fix oversampling formula dt-bindings: iio: adc: ad7380: add adaq4370-4 and adaq4380-4 compatible parts bus: mhi: host: pci_generic: Use pcim_iomap_region() to request and map MHI BAR bus: mhi: host: Switch trace_mhi_gen_tre fields to native endian misc: atmel-ssc: Use of_property_present() for non-boolean properties misc: keba: Add hardware dependency ...
Diffstat (limited to 'drivers/android')
-rw-r--r--drivers/android/binder.c64
1 files changed, 49 insertions, 15 deletions
diff --git a/drivers/android/binder.c b/drivers/android/binder.c
index 978740537a1a..ef353ca13c35 100644
--- a/drivers/android/binder.c
+++ b/drivers/android/binder.c
@@ -1225,6 +1225,12 @@ static void binder_cleanup_ref_olocked(struct binder_ref *ref)
binder_dequeue_work(ref->proc, &ref->death->work);
binder_stats_deleted(BINDER_STAT_DEATH);
}
+
+ if (ref->freeze) {
+ binder_dequeue_work(ref->proc, &ref->freeze->work);
+ binder_stats_deleted(BINDER_STAT_FREEZE);
+ }
+
binder_stats_deleted(BINDER_STAT_REF);
}
@@ -3850,7 +3856,6 @@ binder_request_freeze_notification(struct binder_proc *proc,
{
struct binder_ref_freeze *freeze;
struct binder_ref *ref;
- bool is_frozen;
freeze = kzalloc(sizeof(*freeze), GFP_KERNEL);
if (!freeze)
@@ -3866,32 +3871,31 @@ binder_request_freeze_notification(struct binder_proc *proc,
}
binder_node_lock(ref->node);
-
- if (ref->freeze || !ref->node->proc) {
- binder_user_error("%d:%d invalid BC_REQUEST_FREEZE_NOTIFICATION %s\n",
- proc->pid, thread->pid,
- ref->freeze ? "already set" : "dead node");
+ if (ref->freeze) {
+ binder_user_error("%d:%d BC_REQUEST_FREEZE_NOTIFICATION already set\n",
+ proc->pid, thread->pid);
binder_node_unlock(ref->node);
binder_proc_unlock(proc);
kfree(freeze);
return -EINVAL;
}
- binder_inner_proc_lock(ref->node->proc);
- is_frozen = ref->node->proc->is_frozen;
- binder_inner_proc_unlock(ref->node->proc);
binder_stats_created(BINDER_STAT_FREEZE);
INIT_LIST_HEAD(&freeze->work.entry);
freeze->cookie = handle_cookie->cookie;
freeze->work.type = BINDER_WORK_FROZEN_BINDER;
- freeze->is_frozen = is_frozen;
-
ref->freeze = freeze;
- binder_inner_proc_lock(proc);
- binder_enqueue_work_ilocked(&ref->freeze->work, &proc->todo);
- binder_wakeup_proc_ilocked(proc);
- binder_inner_proc_unlock(proc);
+ if (ref->node->proc) {
+ binder_inner_proc_lock(ref->node->proc);
+ freeze->is_frozen = ref->node->proc->is_frozen;
+ binder_inner_proc_unlock(ref->node->proc);
+
+ binder_inner_proc_lock(proc);
+ binder_enqueue_work_ilocked(&freeze->work, &proc->todo);
+ binder_wakeup_proc_ilocked(proc);
+ binder_inner_proc_unlock(proc);
+ }
binder_node_unlock(ref->node);
binder_proc_unlock(proc);
@@ -5151,6 +5155,16 @@ static void binder_release_work(struct binder_proc *proc,
} break;
case BINDER_WORK_NODE:
break;
+ case BINDER_WORK_CLEAR_FREEZE_NOTIFICATION: {
+ struct binder_ref_freeze *freeze;
+
+ freeze = container_of(w, struct binder_ref_freeze, work);
+ binder_debug(BINDER_DEBUG_DEAD_TRANSACTION,
+ "undelivered freeze notification, %016llx\n",
+ (u64)freeze->cookie);
+ kfree(freeze);
+ binder_stats_deleted(BINDER_STAT_FREEZE);
+ } break;
default:
pr_err("unexpected work type, %d, not freed\n",
wtype);
@@ -5552,6 +5566,7 @@ static bool binder_txns_pending_ilocked(struct binder_proc *proc)
static void binder_add_freeze_work(struct binder_proc *proc, bool is_frozen)
{
+ struct binder_node *prev = NULL;
struct rb_node *n;
struct binder_ref *ref;
@@ -5560,7 +5575,10 @@ static void binder_add_freeze_work(struct binder_proc *proc, bool is_frozen)
struct binder_node *node;
node = rb_entry(n, struct binder_node, rb_node);
+ binder_inc_node_tmpref_ilocked(node);
binder_inner_proc_unlock(proc);
+ if (prev)
+ binder_put_node(prev);
binder_node_lock(node);
hlist_for_each_entry(ref, &node->refs, node_entry) {
/*
@@ -5586,10 +5604,15 @@ static void binder_add_freeze_work(struct binder_proc *proc, bool is_frozen)
}
binder_inner_proc_unlock(ref->proc);
}
+ prev = node;
binder_node_unlock(node);
binder_inner_proc_lock(proc);
+ if (proc->is_dead)
+ break;
}
binder_inner_proc_unlock(proc);
+ if (prev)
+ binder_put_node(prev);
}
static int binder_ioctl_freeze(struct binder_freeze_info *info,
@@ -6260,6 +6283,7 @@ static void binder_deferred_release(struct binder_proc *proc)
binder_release_work(proc, &proc->todo);
binder_release_work(proc, &proc->delivered_death);
+ binder_release_work(proc, &proc->delivered_freeze);
binder_debug(BINDER_DEBUG_OPEN_CLOSE,
"%s: %d threads %d, nodes %d (ref %d), refs %d, active transactions %d\n",
@@ -6393,6 +6417,12 @@ static void print_binder_work_ilocked(struct seq_file *m,
case BINDER_WORK_CLEAR_DEATH_NOTIFICATION:
seq_printf(m, "%shas cleared death notification\n", prefix);
break;
+ case BINDER_WORK_FROZEN_BINDER:
+ seq_printf(m, "%shas frozen binder\n", prefix);
+ break;
+ case BINDER_WORK_CLEAR_FREEZE_NOTIFICATION:
+ seq_printf(m, "%shas cleared freeze notification\n", prefix);
+ break;
default:
seq_printf(m, "%sunknown work: type %d\n", prefix, w->type);
break;
@@ -6539,6 +6569,10 @@ static void print_binder_proc(struct seq_file *m,
seq_puts(m, " has delivered dead binder\n");
break;
}
+ list_for_each_entry(w, &proc->delivered_freeze, entry) {
+ seq_puts(m, " has delivered freeze binder\n");
+ break;
+ }
binder_inner_proc_unlock(proc);
if (!print_all && m->count == header_pos)
m->count = start_pos;