xref: /openbmc/linux/drivers/android/binder_alloc.h (revision c900529f3d9161bfde5cca0754f83b4d3c3e0220)
19c92ab61SThomas Gleixner /* SPDX-License-Identifier: GPL-2.0-only */
20c972a05STodd Kjos /*
30c972a05STodd Kjos  * Copyright (C) 2017 Google, Inc.
40c972a05STodd Kjos  */
50c972a05STodd Kjos 
60c972a05STodd Kjos #ifndef _LINUX_BINDER_ALLOC_H
70c972a05STodd Kjos #define _LINUX_BINDER_ALLOC_H
80c972a05STodd Kjos 
90c972a05STodd Kjos #include <linux/rbtree.h>
100c972a05STodd Kjos #include <linux/list.h>
110c972a05STodd Kjos #include <linux/mm.h>
120c972a05STodd Kjos #include <linux/rtmutex.h>
130c972a05STodd Kjos #include <linux/vmalloc.h>
140c972a05STodd Kjos #include <linux/slab.h>
15f2517eb7SSherry Yang #include <linux/list_lru.h>
161a7c3d9bSTodd Kjos #include <uapi/linux/android/binder.h>
170c972a05STodd Kjos 
18f2517eb7SSherry Yang extern struct list_lru binder_alloc_lru;
190c972a05STodd Kjos struct binder_transaction;
200c972a05STodd Kjos 
210c972a05STodd Kjos /**
220c972a05STodd Kjos  * struct binder_buffer - buffer used for binder transactions
230c972a05STodd Kjos  * @entry:              entry alloc->buffers
240c972a05STodd Kjos  * @rb_node:            node for allocated_buffers/free_buffers rb trees
257a2670a5STodd Kjos  * @free:               %true if buffer is free
260f966cbaSTodd Kjos  * @clear_on_free:      %true if buffer must be zeroed after use
277a2670a5STodd Kjos  * @allow_user_free:    %true if user is allowed to free buffer
287a2670a5STodd Kjos  * @async_transaction:  %true if buffer is in use for an async txn
29a7dc1e6fSHang Lu  * @oneway_spam_suspect: %true if total async allocate size just exceed
30a7dc1e6fSHang Lu  * spamming detect threshold
317a2670a5STodd Kjos  * @debug_id:           unique ID for debugging
327a2670a5STodd Kjos  * @transaction:        pointer to associated struct binder_transaction
337a2670a5STodd Kjos  * @target_node:        struct binder_node associated with this buffer
347a2670a5STodd Kjos  * @data_size:          size of @transaction data
357a2670a5STodd Kjos  * @offsets_size:       size of array of offsets
367a2670a5STodd Kjos  * @extra_buffers_size: size of space for other objects (like sg lists)
37bde4a19fSTodd Kjos  * @user_data:          user pointer to base of buffer space
38261e7818SMartijn Coenen  * @pid:                pid to attribute the buffer to (caller)
390c972a05STodd Kjos  *
400c972a05STodd Kjos  * Bookkeeping structure for binder transaction buffers
410c972a05STodd Kjos  */
420c972a05STodd Kjos struct binder_buffer {
430c972a05STodd Kjos 	struct list_head entry; /* free and allocated entries by address */
440c972a05STodd Kjos 	struct rb_node rb_node; /* free entry by size or allocated entry */
450c972a05STodd Kjos 				/* by address */
460c972a05STodd Kjos 	unsigned free:1;
470f966cbaSTodd Kjos 	unsigned clear_on_free:1;
480c972a05STodd Kjos 	unsigned allow_user_free:1;
490c972a05STodd Kjos 	unsigned async_transaction:1;
50a7dc1e6fSHang Lu 	unsigned oneway_spam_suspect:1;
51a7dc1e6fSHang Lu 	unsigned debug_id:27;
520c972a05STodd Kjos 
530c972a05STodd Kjos 	struct binder_transaction *transaction;
540c972a05STodd Kjos 
550c972a05STodd Kjos 	struct binder_node *target_node;
560c972a05STodd Kjos 	size_t data_size;
570c972a05STodd Kjos 	size_t offsets_size;
580c972a05STodd Kjos 	size_t extra_buffers_size;
59bde4a19fSTodd Kjos 	void __user *user_data;
60261e7818SMartijn Coenen 	int    pid;
610c972a05STodd Kjos };
620c972a05STodd Kjos 
630c972a05STodd Kjos /**
64f2517eb7SSherry Yang  * struct binder_lru_page - page object used for binder shrinker
65f2517eb7SSherry Yang  * @page_ptr: pointer to physical page in mmap'd space
66f2517eb7SSherry Yang  * @lru:      entry in binder_alloc_lru
67f2517eb7SSherry Yang  * @alloc:    binder_alloc for a proc
68f2517eb7SSherry Yang  */
69f2517eb7SSherry Yang struct binder_lru_page {
70f2517eb7SSherry Yang 	struct list_head lru;
71f2517eb7SSherry Yang 	struct page *page_ptr;
72f2517eb7SSherry Yang 	struct binder_alloc *alloc;
73f2517eb7SSherry Yang };
74f2517eb7SSherry Yang 
75f2517eb7SSherry Yang /**
760c972a05STodd Kjos  * struct binder_alloc - per-binder proc state for binder allocator
777b0dbd94SCarlos Llamas  * @mutex:              protects binder_alloc fields
78c0fd2101SCarlos Llamas  * @vma:                vm_area_struct passed to mmap_handler
7976ff3346SCarlos Llamas  *                      (invariant after mmap)
80e66b77e5SCarlos Llamas  * @mm:                 copy of task->mm (invariant after open)
810c972a05STodd Kjos  * @buffer:             base of per-proc address space mapped via mmap
820c972a05STodd Kjos  * @buffers:            list of all buffers for this proc
830c972a05STodd Kjos  * @free_buffers:       rb tree of buffers available for allocation
840c972a05STodd Kjos  *                      sorted by size
850c972a05STodd Kjos  * @allocated_buffers:  rb tree of allocated buffers sorted by address
860c972a05STodd Kjos  * @free_async_space:   VA space available for async buffers. This is
870c972a05STodd Kjos  *                      initialized at mmap time to 1/2 the full VA space
88f2517eb7SSherry Yang  * @pages:              array of binder_lru_page
890c972a05STodd Kjos  * @buffer_size:        size of address space specified via mmap
900c972a05STodd Kjos  * @pid:                pid for associated binder_proc (invariant after init)
918d9a3ab6SMartijn Coenen  * @pages_high:         high watermark of offset in @pages
92a7dc1e6fSHang Lu  * @oneway_spam_detected: %true if oneway spam detection fired, clear that
93a7dc1e6fSHang Lu  * flag once the async buffer has returned to a healthy state
940c972a05STodd Kjos  *
950c972a05STodd Kjos  * Bookkeeping structure for per-proc address space management for binder
960c972a05STodd Kjos  * buffers. It is normally initialized during binder_init() and binder_mmap()
970c972a05STodd Kjos  * calls. The address space is used for both user-visible buffers and for
980c972a05STodd Kjos  * struct binder_buffer objects used to track the user buffers
990c972a05STodd Kjos  */
1000c972a05STodd Kjos struct binder_alloc {
1010c972a05STodd Kjos 	struct mutex mutex;
102c0fd2101SCarlos Llamas 	struct vm_area_struct *vma;
103e66b77e5SCarlos Llamas 	struct mm_struct *mm;
104bde4a19fSTodd Kjos 	void __user *buffer;
1050c972a05STodd Kjos 	struct list_head buffers;
1060c972a05STodd Kjos 	struct rb_root free_buffers;
1070c972a05STodd Kjos 	struct rb_root allocated_buffers;
1080c972a05STodd Kjos 	size_t free_async_space;
109f2517eb7SSherry Yang 	struct binder_lru_page *pages;
1100c972a05STodd Kjos 	size_t buffer_size;
1110c972a05STodd Kjos 	int pid;
1128d9a3ab6SMartijn Coenen 	size_t pages_high;
113a7dc1e6fSHang Lu 	bool oneway_spam_detected;
1140c972a05STodd Kjos };
1150c972a05STodd Kjos 
1164175e2b4SSherry Yang #ifdef CONFIG_ANDROID_BINDER_IPC_SELFTEST
1174175e2b4SSherry Yang void binder_selftest_alloc(struct binder_alloc *alloc);
1184175e2b4SSherry Yang #else
binder_selftest_alloc(struct binder_alloc * alloc)1194175e2b4SSherry Yang static inline void binder_selftest_alloc(struct binder_alloc *alloc) {}
1204175e2b4SSherry Yang #endif
121f2517eb7SSherry Yang enum lru_status binder_alloc_free_page(struct list_head *item,
122f2517eb7SSherry Yang 				       struct list_lru_one *lru,
123f2517eb7SSherry Yang 				       spinlock_t *lock, void *cb_arg);
1240c972a05STodd Kjos extern struct binder_buffer *binder_alloc_new_buf(struct binder_alloc *alloc,
1250c972a05STodd Kjos 						  size_t data_size,
1260c972a05STodd Kjos 						  size_t offsets_size,
1270c972a05STodd Kjos 						  size_t extra_buffers_size,
128261e7818SMartijn Coenen 						  int is_async,
129261e7818SMartijn Coenen 						  int pid);
1300c972a05STodd Kjos extern void binder_alloc_init(struct binder_alloc *alloc);
131533dfb25STetsuo Handa extern int binder_alloc_shrinker_init(void);
132*adb9743dSQi Zheng extern void binder_alloc_shrinker_exit(void);
1330c972a05STodd Kjos extern void binder_alloc_vma_close(struct binder_alloc *alloc);
1340c972a05STodd Kjos extern struct binder_buffer *
13553d311cfSTodd Kjos binder_alloc_prepare_to_free(struct binder_alloc *alloc,
1360c972a05STodd Kjos 			     uintptr_t user_ptr);
1370c972a05STodd Kjos extern void binder_alloc_free_buf(struct binder_alloc *alloc,
1380c972a05STodd Kjos 				  struct binder_buffer *buffer);
1390c972a05STodd Kjos extern int binder_alloc_mmap_handler(struct binder_alloc *alloc,
1400c972a05STodd Kjos 				     struct vm_area_struct *vma);
1410c972a05STodd Kjos extern void binder_alloc_deferred_release(struct binder_alloc *alloc);
1420c972a05STodd Kjos extern int binder_alloc_get_allocated_count(struct binder_alloc *alloc);
1430c972a05STodd Kjos extern void binder_alloc_print_allocated(struct seq_file *m,
1440c972a05STodd Kjos 					 struct binder_alloc *alloc);
1458ef4665aSSherry Yang void binder_alloc_print_pages(struct seq_file *m,
1468ef4665aSSherry Yang 			      struct binder_alloc *alloc);
1470c972a05STodd Kjos 
1480c972a05STodd Kjos /**
1490c972a05STodd Kjos  * binder_alloc_get_free_async_space() - get free space available for async
1500c972a05STodd Kjos  * @alloc:	binder_alloc for this proc
1510c972a05STodd Kjos  *
1520c972a05STodd Kjos  * Return:	the bytes remaining in the address-space for async transactions
1530c972a05STodd Kjos  */
1540c972a05STodd Kjos static inline size_t
binder_alloc_get_free_async_space(struct binder_alloc * alloc)1550c972a05STodd Kjos binder_alloc_get_free_async_space(struct binder_alloc *alloc)
1560c972a05STodd Kjos {
1570c972a05STodd Kjos 	size_t free_async_space;
1580c972a05STodd Kjos 
1590c972a05STodd Kjos 	mutex_lock(&alloc->mutex);
1600c972a05STodd Kjos 	free_async_space = alloc->free_async_space;
1610c972a05STodd Kjos 	mutex_unlock(&alloc->mutex);
1620c972a05STodd Kjos 	return free_async_space;
1630c972a05STodd Kjos }
1640c972a05STodd Kjos 
1651a7c3d9bSTodd Kjos unsigned long
1661a7c3d9bSTodd Kjos binder_alloc_copy_user_to_buffer(struct binder_alloc *alloc,
1671a7c3d9bSTodd Kjos 				 struct binder_buffer *buffer,
1681a7c3d9bSTodd Kjos 				 binder_size_t buffer_offset,
1691a7c3d9bSTodd Kjos 				 const void __user *from,
1701a7c3d9bSTodd Kjos 				 size_t bytes);
1711a7c3d9bSTodd Kjos 
172bb4a2e48STodd Kjos int binder_alloc_copy_to_buffer(struct binder_alloc *alloc,
1738ced0c62STodd Kjos 				struct binder_buffer *buffer,
1748ced0c62STodd Kjos 				binder_size_t buffer_offset,
1758ced0c62STodd Kjos 				void *src,
1768ced0c62STodd Kjos 				size_t bytes);
1778ced0c62STodd Kjos 
178bb4a2e48STodd Kjos int binder_alloc_copy_from_buffer(struct binder_alloc *alloc,
1798ced0c62STodd Kjos 				  void *dest,
1808ced0c62STodd Kjos 				  struct binder_buffer *buffer,
1818ced0c62STodd Kjos 				  binder_size_t buffer_offset,
1828ced0c62STodd Kjos 				  size_t bytes);
1838ced0c62STodd Kjos 
1840c972a05STodd Kjos #endif /* _LINUX_BINDER_ALLOC_H */
1850c972a05STodd Kjos 
186