@@ -2728,7 +2728,10 @@ binder_find_outdated_transaction_ilocked(struct binder_transaction *t,
2728
2728
*
2729
2729
* Return: 0 if the transaction was successfully queued
2730
2730
* BR_DEAD_REPLY if the target process or thread is dead
2731
- * BR_FROZEN_REPLY if the target process or thread is frozen
2731
+ * BR_FROZEN_REPLY if the target process or thread is frozen and
2732
+ * the sync transaction was rejected
2733
+ * BR_TRANSACTION_PENDING_FROZEN if the target process is frozen
2734
+ * and the async transaction was successfully queued
2732
2735
*/
2733
2736
static int binder_proc_transaction (struct binder_transaction * t ,
2734
2737
struct binder_proc * proc ,
@@ -2738,6 +2741,7 @@ static int binder_proc_transaction(struct binder_transaction *t,
2738
2741
bool oneway = !!(t -> flags & TF_ONE_WAY );
2739
2742
bool pending_async = false;
2740
2743
struct binder_transaction * t_outdated = NULL ;
2744
+ bool frozen = false;
2741
2745
2742
2746
BUG_ON (!node );
2743
2747
binder_node_lock (node );
@@ -2751,15 +2755,16 @@ static int binder_proc_transaction(struct binder_transaction *t,
2751
2755
2752
2756
binder_inner_proc_lock (proc );
2753
2757
if (proc -> is_frozen ) {
2758
+ frozen = true;
2754
2759
proc -> sync_recv |= !oneway ;
2755
2760
proc -> async_recv |= oneway ;
2756
2761
}
2757
2762
2758
- if ((proc -> is_frozen && !oneway ) || proc -> is_dead ||
2763
+ if ((frozen && !oneway ) || proc -> is_dead ||
2759
2764
(thread && thread -> is_dead )) {
2760
2765
binder_inner_proc_unlock (proc );
2761
2766
binder_node_unlock (node );
2762
- return proc -> is_frozen ? BR_FROZEN_REPLY : BR_DEAD_REPLY ;
2767
+ return frozen ? BR_FROZEN_REPLY : BR_DEAD_REPLY ;
2763
2768
}
2764
2769
2765
2770
if (!thread && !pending_async )
@@ -2770,7 +2775,7 @@ static int binder_proc_transaction(struct binder_transaction *t,
2770
2775
} else if (!pending_async ) {
2771
2776
binder_enqueue_work_ilocked (& t -> work , & proc -> todo );
2772
2777
} else {
2773
- if ((t -> flags & TF_UPDATE_TXN ) && proc -> is_frozen ) {
2778
+ if ((t -> flags & TF_UPDATE_TXN ) && frozen ) {
2774
2779
t_outdated = binder_find_outdated_transaction_ilocked (t ,
2775
2780
& node -> async_todo );
2776
2781
if (t_outdated ) {
@@ -2807,6 +2812,9 @@ static int binder_proc_transaction(struct binder_transaction *t,
2807
2812
binder_stats_deleted (BINDER_STAT_TRANSACTION );
2808
2813
}
2809
2814
2815
+ if (oneway && frozen )
2816
+ return BR_TRANSACTION_PENDING_FROZEN ;
2817
+
2810
2818
return 0 ;
2811
2819
}
2812
2820
@@ -3607,9 +3615,17 @@ static void binder_transaction(struct binder_proc *proc,
3607
3615
} else {
3608
3616
BUG_ON (target_node == NULL );
3609
3617
BUG_ON (t -> buffer -> async_transaction != 1 );
3610
- binder_enqueue_thread_work (thread , tcomplete );
3611
3618
return_error = binder_proc_transaction (t , target_proc , NULL );
3612
- if (return_error )
3619
+ /*
3620
+ * Let the caller know when async transaction reaches a frozen
3621
+ * process and is put in a pending queue, waiting for the target
3622
+ * process to be unfrozen.
3623
+ */
3624
+ if (return_error == BR_TRANSACTION_PENDING_FROZEN )
3625
+ tcomplete -> type = BINDER_WORK_TRANSACTION_PENDING ;
3626
+ binder_enqueue_thread_work (thread , tcomplete );
3627
+ if (return_error &&
3628
+ return_error != BR_TRANSACTION_PENDING_FROZEN )
3613
3629
goto err_dead_proc_or_thread ;
3614
3630
}
3615
3631
if (target_thread )
@@ -4440,10 +4456,13 @@ static int binder_thread_read(struct binder_proc *proc,
4440
4456
binder_stat_br (proc , thread , cmd );
4441
4457
} break ;
4442
4458
case BINDER_WORK_TRANSACTION_COMPLETE :
4459
+ case BINDER_WORK_TRANSACTION_PENDING :
4443
4460
case BINDER_WORK_TRANSACTION_ONEWAY_SPAM_SUSPECT : {
4444
4461
if (proc -> oneway_spam_detection_enabled &&
4445
4462
w -> type == BINDER_WORK_TRANSACTION_ONEWAY_SPAM_SUSPECT )
4446
4463
cmd = BR_ONEWAY_SPAM_SUSPECT ;
4464
+ else if (w -> type == BINDER_WORK_TRANSACTION_PENDING )
4465
+ cmd = BR_TRANSACTION_PENDING_FROZEN ;
4447
4466
else
4448
4467
cmd = BR_TRANSACTION_COMPLETE ;
4449
4468
binder_inner_proc_unlock (proc );
@@ -6159,6 +6178,7 @@ static const char * const binder_return_strings[] = {
6159
6178
"BR_FAILED_REPLY" ,
6160
6179
"BR_FROZEN_REPLY" ,
6161
6180
"BR_ONEWAY_SPAM_SUSPECT" ,
6181
+ "BR_TRANSACTION_PENDING_FROZEN"
6162
6182
};
6163
6183
6164
6184
static const char * const binder_command_strings [] = {
0 commit comments