@@ -517,7 +517,7 @@ static struct bcmd_msg *binder_realloc_msg(struct bcmd_msg *msg, size_t data_siz
517
517
return binder_alloc_msg (data_size , offsets_size );
518
518
}
519
519
520
- static inline int binder_inform_obj ( struct binder_obj * obj , unsigned int cmd )
520
+ static inline int binder_write_cmd ( msg_queue_id q , void * binder , void * cookie , unsigned int cmd )
521
521
{
522
522
struct bcmd_msg * msg ;
523
523
int r ;
@@ -527,10 +527,10 @@ static inline int binder_inform_obj(struct binder_obj *obj, unsigned int cmd)
527
527
return - ENOMEM ;
528
528
529
529
msg -> type = cmd ;
530
- msg -> binder = obj -> binder ;
531
- msg -> cookie = obj -> cookie ;
530
+ msg -> binder = binder ;
531
+ msg -> cookie = cookie ;
532
532
533
- r = bcmd_write_msg (obj -> owner , msg );
533
+ r = bcmd_write_msg (q , msg );
534
534
if (r < 0 ) {
535
535
kfree (msg );
536
536
return r ;
@@ -539,6 +539,11 @@ static inline int binder_inform_obj(struct binder_obj *obj, unsigned int cmd)
539
539
return 0 ;
540
540
}
541
541
542
+ static inline int binder_inform_owner (struct binder_obj * obj , unsigned int cmd )
543
+ {
544
+ return binder_write_cmd (obj -> owner , obj -> binder , obj -> cookie , cmd );
545
+ }
546
+
542
547
static int _binder_free_obj (struct binder_proc * proc , struct binder_obj * obj )
543
548
{
544
549
debugfs_remove (obj -> info_node );
@@ -561,6 +566,7 @@ static int _binder_free_obj(struct binder_proc *proc, struct binder_obj *obj)
561
566
msg -> type = BR_DEAD_BINDER ;
562
567
msg -> binder = obj -> binder ;
563
568
msg -> cookie = notifier -> cookie ;
569
+ msg -> reply_to = obj -> owner ; // identify the owner
564
570
if (!bcmd_write_msg (notifier -> to_notify , msg ))
565
571
msg = NULL ;
566
572
@@ -571,21 +577,68 @@ static int _binder_free_obj(struct binder_proc *proc, struct binder_obj *obj)
571
577
} else {
572
578
// reference - tell the owner we are no longer referencing the object
573
579
if (atomic_read (& obj -> refs ) > 0 )
574
- binder_inform_obj (obj , BC_RELEASE );
580
+ binder_inform_owner (obj , BC_RELEASE );
575
581
}
576
582
577
583
kfree (obj );
578
584
return 0 ;
579
585
}
580
586
581
- static int binder_free_obj (struct binder_proc * proc , struct binder_obj * obj )
587
+ static int binder_free_obj (struct binder_proc * proc , struct binder_obj * obj , int force )
582
588
{
583
589
spin_lock (& proc -> obj_lock );
584
590
rb_erase (& obj -> rb_node , & proc -> obj_tree );
585
591
hlist_del (& obj -> hash_node );
586
592
spin_unlock (& proc -> obj_lock );
587
593
588
- return _binder_free_obj (proc , obj );
594
+ if (!force )
595
+ return _binder_free_obj (proc , obj );
596
+
597
+ debugfs_remove (obj -> info_node );
598
+ kfree (obj );
599
+ return 0 ;
600
+ }
601
+
602
+ static int drain_msg_buf (struct binder_proc * proc , struct bcmd_msg * msg )
603
+ {
604
+ struct bcmd_msg_buf * mbuf = msg -> buf ;
605
+
606
+ if (mbuf -> offsets_size > 0 ) {
607
+ struct flat_binder_object * bp ;
608
+ size_t * p , * ep , off ;
609
+ int n ;
610
+
611
+ p = (size_t * )mbuf -> offsets ;
612
+ ep = (size_t * )((char * )mbuf -> offsets + mbuf -> offsets_size );
613
+ n = 0 ;
614
+
615
+ while (p < ep ) {
616
+ off = * p ++ ;
617
+ if (off + sizeof (* bp ) > mbuf -> data_size )
618
+ return - EINVAL ;
619
+
620
+ bp = (struct flat_binder_object * )(mbuf -> data + off );
621
+ switch (bp -> type ) {
622
+ case BINDER_TYPE_BINDER :
623
+ case BINDER_TYPE_HANDLE :
624
+ if (mbuf -> owners [n ] != msg_queue_id (proc -> queue ))
625
+ binder_write_cmd (mbuf -> owners [n ], bp -> binder , bp -> cookie , BC_RELEASE );
626
+ break ;
627
+
628
+ case BINDER_TYPE_FD :
629
+ if (bp -> binder )
630
+ fput (bp -> binder );
631
+ break ;
632
+
633
+ default :
634
+ break ;
635
+ }
636
+
637
+ n ++ ;
638
+ }
639
+ }
640
+
641
+ return 0 ;
589
642
}
590
643
591
644
static void drain_msg_queue (struct binder_proc * proc , struct msg_queue * q )
@@ -596,11 +649,16 @@ static void drain_msg_queue(struct binder_proc *proc, struct msg_queue *q)
596
649
while ((entry = msg_queue_pop (q ))) {
597
650
msg = container_of (entry , struct bcmd_msg , list );
598
651
599
- //TODO: call free buffer
600
- if ((msg -> type == BC_TRANSACTION ) && !(msg -> flags & TF_ONE_WAY )) {
601
- msg -> type = BR_DEAD_REPLY ;
602
- if (!bcmd_write_msg (msg -> reply_to , msg ))
603
- continue ;
652
+ if (msg -> type == BC_TRANSACTION ) {
653
+ drain_msg_buf (proc , msg );
654
+
655
+ if (!(msg -> flags & TF_ONE_WAY )) {
656
+ msg -> type = BR_DEAD_REPLY ;
657
+ if (!bcmd_write_msg (msg -> reply_to , msg ))
658
+ continue ;
659
+ }
660
+ } else if (msg -> type == BC_REPLY ) {
661
+ drain_msg_buf (proc , msg );
604
662
} else if (msg -> type == BC_CLEAR_DEATH_NOTIFICATION ) {
605
663
struct binder_obj * obj ;
606
664
@@ -899,7 +957,7 @@ static inline int binder_release_obj(struct binder_proc *proc, struct binder_thr
899
957
900
958
// regardless it's an object or a reference, it should cease to exist now
901
959
// TODO: review the risk of deleting the object here
902
- r = binder_free_obj (proc , obj );
960
+ r = binder_free_obj (proc , obj , 0 );
903
961
if (r < 0 )
904
962
return r ;
905
963
}
@@ -942,7 +1000,7 @@ static int bcmd_write_flat_obj(struct binder_proc *proc, struct binder_thread *t
942
1000
bp -> cookie = obj -> cookie ;
943
1001
* owner = obj -> owner ;
944
1002
945
- r = binder_inform_obj (obj , BC_ACQUIRE );
1003
+ r = binder_inform_owner (obj , BC_ACQUIRE );
946
1004
if (r < 0 )
947
1005
return r ;
948
1006
break ;
@@ -1001,7 +1059,7 @@ static int bcmd_read_flat_obj(struct binder_proc *proc, struct binder_thread *th
1001
1059
if (atomic_inc_return (& obj -> refs ) > 1 ) {
1002
1060
/* We aleady have a reference to the object, so tell
1003
1061
the owner to decrease one reference */
1004
- r = binder_inform_obj (obj , BC_RELEASE );
1062
+ r = binder_inform_owner (obj , BC_RELEASE );
1005
1063
if (r < 0 )
1006
1064
return r ;
1007
1065
}
@@ -1019,7 +1077,7 @@ static int bcmd_read_flat_obj(struct binder_proc *proc, struct binder_thread *th
1019
1077
}
1020
1078
1021
1079
fd_install (fd , file );
1022
- bp -> handle = fd ; // TODO: fput() when free unread msg!!!
1080
+ bp -> handle = fd ;
1023
1081
break ;
1024
1082
1025
1083
default :
@@ -1069,7 +1127,7 @@ static int bcmd_write_msg_buf(struct binder_proc *proc, struct binder_thread *th
1069
1127
2. A -> B -> C -> A. In this case, B's transaction is delivered to C's process queue, but C's transaction
1070
1128
is delivered to thread A.
1071
1129
1072
- It doesn't impose above thread preference if a caller thread makes consective calls to more than one destination
1130
+ It doesn't impose above thread preference if a caller thread makes consecutive calls to more than one destination
1073
1131
before getting the reply back. For example, like in case 2, if A -> B -> C, and before getting reply back from B,
1074
1132
A makes another call to C (A -> C), in which case, the second message is not guranteed to be delivered to thread
1075
1133
C who received B's transaction (triggered by A's transaction).
@@ -1650,17 +1708,23 @@ static long bcmd_read_transaction_complete(struct binder_proc *proc, struct bind
1650
1708
1651
1709
static long bcmd_read_dead_binder (struct binder_proc * proc , struct binder_thread * thread , struct bcmd_msg * * pmsg , void __user * buf , unsigned long size )
1652
1710
{
1653
- uint32_t cmd = (* pmsg )-> type , cookie = (uint32_t )(* pmsg )-> cookie ;
1711
+ struct bcmd_msg * msg = * pmsg ;
1712
+ uint32_t cmd = msg -> type , cookie = (uint32_t )msg -> cookie ;
1713
+ struct binder_obj * obj ;
1654
1714
1655
1715
if (size < sizeof (cmd ) * 2 )
1656
1716
return - ENOSPC ;
1657
1717
1658
- if ( put_user ( cmd , ( uint32_t * ) buf ) ||
1659
- put_user ( cookie , ( uint32_t * )(( char * ) buf + sizeof ( cmd ))))
1660
- return - EFAULT ;
1718
+ obj = binder_find_obj ( proc , msg -> reply_to , msg -> binder );
1719
+ if ( obj ) {
1720
+ binder_free_obj ( proc , obj , 1 ) ;
1661
1721
1662
- printk ("pid %d/%d (tid %d/%d) read DEAD_BINDER command with cookie %08x\n" , proc -> pid , task_tgid_vnr (current ), thread -> pid , task_pid_vnr (current ), cookie );
1663
- kfree (* pmsg );
1722
+ if (put_user (cmd , (uint32_t * )buf ) ||
1723
+ put_user (cookie , (uint32_t * )((char * )buf + sizeof (cmd ))))
1724
+ return - EFAULT ;
1725
+ }
1726
+
1727
+ kfree (msg );
1664
1728
* pmsg = NULL ;
1665
1729
return sizeof (cmd ) * 2 ;
1666
1730
}
@@ -1680,7 +1744,6 @@ static long bcmd_read_dead_reply(struct binder_proc *proc, struct binder_thread
1680
1744
if (put_user (cmd , (uint32_t * )buf ))
1681
1745
return - EFAULT ;
1682
1746
1683
- printk ("pid %d (tid %d) read DEAD_REPLY command\n" , proc -> pid , thread -> pid );
1684
1747
kfree (* pmsg );
1685
1748
* pmsg = NULL ;
1686
1749
return sizeof (cmd );
@@ -1715,13 +1778,12 @@ static long bcmd_read_acquire(struct binder_proc *proc, struct binder_thread *th
1715
1778
} else {
1716
1779
if (atomic_dec_return (& obj -> refs ) == 0 ) {
1717
1780
cmd = BR_RELEASE ;
1718
- binder_free_obj (proc , obj );
1781
+ binder_free_obj (proc , obj , 0 );
1719
1782
}
1720
1783
}
1721
1784
}
1722
1785
1723
1786
if (cmd ) {
1724
- printk ("pid %d (tid %d) read %s binder command on object %p/%p\n" , proc -> pid , thread -> pid , cmd == BR_ACQUIRE ?"ACQUIRE" :"RELEASE" , msg -> binder , msg -> cookie );
1725
1787
ref_cmd .cmd = cmd ;
1726
1788
ref_cmd .binder = msg -> binder ;
1727
1789
ref_cmd .cookie = msg -> cookie ;
@@ -1896,19 +1958,15 @@ static inline int cmd_write_read(struct binder_proc *proc, struct binder_thread
1896
1958
1897
1959
if (bwr -> write_size > 0 ) {
1898
1960
r = binder_thread_write (proc , thread , (void __user * )bwr -> write_buffer + bwr -> write_consumed , bwr -> write_size );
1899
- if (r < 0 ) {
1900
- printk ("proc %d (tid %d) BWR write %d\n" , proc -> pid , thread -> pid , r );
1961
+ if (r < 0 )
1901
1962
return r ;
1902
- }
1903
1963
bwr -> write_consumed += r ;
1904
1964
}
1905
1965
1906
1966
if (bwr -> read_size > 0 ) {
1907
1967
r = binder_thread_read (proc , thread , (void __user * )bwr -> read_buffer + bwr -> read_consumed , bwr -> read_size );
1908
- if (r < 0 ) {
1909
- printk ("proc %d (tid %d) BWR read %d\n" , proc -> pid , thread -> pid , r );
1968
+ if (r < 0 )
1910
1969
return r ;
1911
- }
1912
1970
bwr -> read_consumed += r ;
1913
1971
}
1914
1972
0 commit comments