139225Sgibbs/* SPDX-License-Identifier: GPL-2.0-only */ 239225Sgibbs/* 339225Sgibbs * Copyright (C) 2017 Google, Inc. 439225Sgibbs */ 5122362Simp 6122362Simp#ifndef _LINUX_BINDER_ALLOC_H 739225Sgibbs#define _LINUX_BINDER_ALLOC_H 8122362Simp 9122362Simp#include <linux/rbtree.h> 10122362Simp#include <linux/list.h> 11122362Simp#include <linux/mm.h> 12122362Simp#include <linux/spinlock.h> 13122362Simp#include <linux/vmalloc.h> 14122362Simp#include <linux/slab.h> 15122362Simp#include <linux/list_lru.h> 16122362Simp#include <uapi/linux/android/binder.h> 17122362Simp 18122362Simpextern struct list_lru binder_freelist; 19122362Simpstruct binder_transaction; 20122362Simp 21122362Simp/** 22122362Simp * struct binder_buffer - buffer used for binder transactions 23122362Simp * @entry: entry alloc->buffers 24122362Simp * @rb_node: node for allocated_buffers/free_buffers rb trees 25122362Simp * @free: %true if buffer is free 26122362Simp * @clear_on_free: %true if buffer must be zeroed after use 27122362Simp * @allow_user_free: %true if user is allowed to free buffer 28122362Simp * @async_transaction: %true if buffer is in use for an async txn 29122362Simp * @oneway_spam_suspect: %true if total async allocate size just exceed 30122362Simp * spamming detect threshold 3139225Sgibbs * @debug_id: unique ID for debugging 3239225Sgibbs * @transaction: pointer to associated struct binder_transaction 3339225Sgibbs * @target_node: struct binder_node associated with this buffer 3439225Sgibbs * @data_size: size of @transaction data 3539225Sgibbs * @offsets_size: size of array of offsets 3639225Sgibbs * @extra_buffers_size: size of space for other objects (like sg lists) 3739225Sgibbs * @user_data: user pointer to base of buffer space 3839225Sgibbs * @pid: pid to attribute the buffer to (caller) 3939225Sgibbs * 4039225Sgibbs * Bookkeeping structure for binder transaction buffers 4139225Sgibbs */ 4239225Sgibbsstruct binder_buffer { 4339225Sgibbs struct list_head entry; /* free and allocated entries by address */ 4439225Sgibbs struct rb_node rb_node; /* free entry by size or allocated entry */ 4539225Sgibbs /* by address */ 4639225Sgibbs unsigned free:1; 4739225Sgibbs unsigned clear_on_free:1; 4839225Sgibbs unsigned allow_user_free:1; 4939225Sgibbs unsigned async_transaction:1; 5039225Sgibbs unsigned oneway_spam_suspect:1; 5139225Sgibbs unsigned debug_id:27; 5239225Sgibbs struct binder_transaction *transaction; 5339225Sgibbs struct binder_node *target_node; 5439225Sgibbs size_t data_size; 5539225Sgibbs size_t offsets_size; 56119418Sobrien size_t extra_buffers_size; 57119418Sobrien unsigned long user_data; 58119418Sobrien int pid; 5939225Sgibbs}; 6039225Sgibbs 6142887Simp/** 62117126Sscottl * struct binder_lru_page - page object used for binder shrinker 63117126Sscottl * @page_ptr: pointer to physical page in mmap'd space 6439225Sgibbs * @lru: entry in binder_freelist 6539225Sgibbs * @alloc: binder_alloc for a proc 6639225Sgibbs */ 6751738Simpstruct binder_lru_page { 6851738Simp struct list_head lru; 6951738Simp struct page *page_ptr; 7051738Simp struct binder_alloc *alloc; 7139225Sgibbs}; 7251738Simp 7351738Simp/** 7439225Sgibbs * struct binder_alloc - per-binder proc state for binder allocator 7539225Sgibbs * @lock: protects binder_alloc fields 7639225Sgibbs * @vma: vm_area_struct passed to mmap_handler 7739225Sgibbs * (invariant after mmap) 7851738Simp * @mm: copy of task->mm (invariant after open) 7958544Simp * @buffer: base of per-proc address space mapped via mmap 8058544Simp * @buffers: list of all buffers for this proc 8158544Simp * @free_buffers: rb tree of buffers available for allocation 8258544Simp * sorted by size 8358544Simp * @allocated_buffers: rb tree of allocated buffers sorted by address 8451738Simp * @free_async_space: VA space available for async buffers. This is 8539225Sgibbs * initialized at mmap time to 1/2 the full VA space 8639225Sgibbs * @pages: array of binder_lru_page 8739225Sgibbs * @buffer_size: size of address space specified via mmap 8839225Sgibbs * @pid: pid for associated binder_proc (invariant after init) 8939225Sgibbs * @pages_high: high watermark of offset in @pages 9039225Sgibbs * @oneway_spam_detected: %true if oneway spam detection fired, clear that 9139225Sgibbs * flag once the async buffer has returned to a healthy state 9239225Sgibbs * 9339225Sgibbs * Bookkeeping structure for per-proc address space management for binder 9451738Simp * buffers. It is normally initialized during binder_init() and binder_mmap() 9539225Sgibbs * calls. The address space is used for both user-visible buffers and for 9639225Sgibbs * struct binder_buffer objects used to track the user buffers 9739225Sgibbs */ 9839225Sgibbsstruct binder_alloc { 99122361Simp spinlock_t lock; 10039225Sgibbs struct vm_area_struct *vma; 10141048Sgibbs struct mm_struct *mm; 10251738Simp unsigned long buffer; 10351738Simp struct list_head buffers; 10451738Simp struct rb_root free_buffers; 10551738Simp struct rb_root allocated_buffers; 10651738Simp size_t free_async_space; 10751738Simp struct binder_lru_page *pages; 10839225Sgibbs size_t buffer_size; 10951738Simp int pid; 11051738Simp size_t pages_high; 11151738Simp bool oneway_spam_detected; 11251738Simp}; 11352174Sdfr 11452174Sdfr#ifdef CONFIG_ANDROID_BINDER_IPC_SELFTEST 11551738Simpvoid binder_selftest_alloc(struct binder_alloc *alloc); 11651738Simp#else 11751738Simpstatic inline void binder_selftest_alloc(struct binder_alloc *alloc) {} 11839225Sgibbs#endif 11939225Sgibbsenum lru_status binder_alloc_free_page(struct list_head *item, 12039225Sgibbs struct list_lru_one *lru, 12139225Sgibbs spinlock_t *lock, void *cb_arg); 12251738Simpstruct binder_buffer *binder_alloc_new_buf(struct binder_alloc *alloc, 12339225Sgibbs size_t data_size, 12441048Sgibbs size_t offsets_size, 12551738Simp size_t extra_buffers_size, 12641048Sgibbs int is_async); 12739225Sgibbsvoid binder_alloc_init(struct binder_alloc *alloc); 12839225Sgibbsint binder_alloc_shrinker_init(void); 12939225Sgibbsvoid binder_alloc_shrinker_exit(void); 13039225Sgibbsvoid binder_alloc_vma_close(struct binder_alloc *alloc); 13139225Sgibbsstruct binder_buffer * 13239225Sgibbsbinder_alloc_prepare_to_free(struct binder_alloc *alloc, 13341048Sgibbs unsigned long user_ptr); 13439225Sgibbsvoid binder_alloc_free_buf(struct binder_alloc *alloc, 13552174Sdfr struct binder_buffer *buffer); 13652174Sdfrint binder_alloc_mmap_handler(struct binder_alloc *alloc, 13751738Simp struct vm_area_struct *vma); 13851738Simpvoid binder_alloc_deferred_release(struct binder_alloc *alloc); 13951738Simpint binder_alloc_get_allocated_count(struct binder_alloc *alloc); 14051738Simpvoid binder_alloc_print_allocated(struct seq_file *m, 14151738Simp struct binder_alloc *alloc); 14251738Simpvoid binder_alloc_print_pages(struct seq_file *m, 14351738Simp struct binder_alloc *alloc); 14440160Simp 14540160Simp/** 14639225Sgibbs * binder_alloc_get_free_async_space() - get free space available for async 147122361Simp * @alloc: binder_alloc for this proc 14851765Simp * 14939225Sgibbs * Return: the bytes remaining in the address-space for async transactions 15039225Sgibbs */ 15139225Sgibbsstatic inline size_t 15239225Sgibbsbinder_alloc_get_free_async_space(struct binder_alloc *alloc) 15351738Simp{ 15451738Simp size_t free_async_space; 15539225Sgibbs 15639225Sgibbs spin_lock(&alloc->lock); 15739225Sgibbs free_async_space = alloc->free_async_space; 15839225Sgibbs spin_unlock(&alloc->lock); 15939225Sgibbs return free_async_space; 16039225Sgibbs} 16139225Sgibbs 16241048Sgibbsunsigned long 163122340Simpbinder_alloc_copy_user_to_buffer(struct binder_alloc *alloc, 16451738Simp struct binder_buffer *buffer, 16551738Simp binder_size_t buffer_offset, 16639225Sgibbs const void __user *from, 16739225Sgibbs size_t bytes); 16851738Simp 16951738Simpint binder_alloc_copy_to_buffer(struct binder_alloc *alloc, 17039225Sgibbs struct binder_buffer *buffer, 17151738Simp binder_size_t buffer_offset, 17251738Simp void *src, 17339225Sgibbs size_t bytes); 17439225Sgibbs 17539225Sgibbsint binder_alloc_copy_from_buffer(struct binder_alloc *alloc, 17651738Simp void *dest, 17751738Simp struct binder_buffer *buffer, 17839225Sgibbs binder_size_t buffer_offset, 17939225Sgibbs size_t bytes); 18051738Simp 18139225Sgibbs#endif /* _LINUX_BINDER_ALLOC_H */ 18239225Sgibbs 18351738Simp