From: Jiyu Yang Date: Thu, 31 Aug 2017 13:57:24 +0000 (+0800) Subject: gpu: update r8p0 patch [6/7] X-Git-Url: https://git.stricted.de/?a=commitdiff_plain;h=24f245d3e8c9125eee48704d34de3a54fdb8e96d;p=GitHub%2FLineageOS%2FG12%2Fandroid_hardware_amlogic_kernel-modules_mali-driver.git gpu: update r8p0 patch [6/7] PD#149525 Change-Id: Ia207984ef4b84dbf6dd3f251f824b04ed7dc8414 --- diff --git a/lib/mali450_ion/libGLES_mali_default_7a_32-o-r8p0.so b/lib/mali450_ion/libGLES_mali_default_7a_32-o-r8p0.so new file mode 120000 index 0000000..6853e0d --- /dev/null +++ b/lib/mali450_ion/libGLES_mali_default_7a_32-o-r8p0.so @@ -0,0 +1 @@ +libGLES_mali_default_8a_32-o-r8p0.so \ No newline at end of file diff --git a/lib/mali450_ion/libGLES_mali_default_8a_32-o-r7p0.so b/lib/mali450_ion/libGLES_mali_default_8a_32-o-r7p0.so new file mode 120000 index 0000000..079b4b0 --- /dev/null +++ b/lib/mali450_ion/libGLES_mali_default_8a_32-o-r7p0.so @@ -0,0 +1 @@ +libGLES_mali_default_8a_32-n-r7p0.so \ No newline at end of file diff --git a/lib/mali450_ion/libGLES_mali_default_8a_32-o-r8p0.so b/lib/mali450_ion/libGLES_mali_default_8a_32-o-r8p0.so index 6f520bb..3c6f30a 100644 Binary files a/lib/mali450_ion/libGLES_mali_default_8a_32-o-r8p0.so and b/lib/mali450_ion/libGLES_mali_default_8a_32-o-r8p0.so differ diff --git a/lib/mali450_ion/libGLES_mali_default_8a_64-o-r7p0.so b/lib/mali450_ion/libGLES_mali_default_8a_64-o-r7p0.so new file mode 120000 index 0000000..ae69604 --- /dev/null +++ b/lib/mali450_ion/libGLES_mali_default_8a_64-o-r7p0.so @@ -0,0 +1 @@ +libGLES_mali_default_8a_64-n-r7p0.so \ No newline at end of file diff --git a/lib/mali450_ion/libGLES_mali_default_8a_64-o-r8p0.so b/lib/mali450_ion/libGLES_mali_default_8a_64-o-r8p0.so index 553ff47..ede3f5b 100644 Binary files a/lib/mali450_ion/libGLES_mali_default_8a_64-o-r8p0.so and b/lib/mali450_ion/libGLES_mali_default_8a_64-o-r8p0.so differ diff --git a/mali/common/mali_kernel_core.c b/mali/common/mali_kernel_core.c index 43de848..bee4033 100755 --- a/mali/common/mali_kernel_core.c +++ b/mali/common/mali_kernel_core.c @@ -44,8 +44,12 @@ #include #include #if defined(CONFIG_MALI_DMA_BUF_FENCE) +#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 10, 0) +#include +#else #include #endif +#endif #define MALI_SHARED_MEMORY_DEFAULT_SIZE 0xffffffff @@ -752,7 +756,11 @@ _mali_osk_errcode_t mali_initialize_subsystems(void) mali_pp_job_initialize(); - mali_timeline_initialize(); + err = mali_timeline_initialize(); + if (_MALI_OSK_ERR_OK != err) { + mali_terminate_subsystems(); + return err; + } err = mali_session_initialize(); if (_MALI_OSK_ERR_OK != err) { @@ -1161,7 +1169,9 @@ _mali_osk_errcode_t _mali_ukk_open(void **context) /* Initialize the dma fence context.*/ #if defined(CONFIG_MALI_DMA_BUF_FENCE) -#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 17, 0) +#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 10, 0) + session->fence_context = dma_fence_context_alloc(1); +#elif LINUX_VERSION_CODE >= KERNEL_VERSION(3, 17, 0) session->fence_context = fence_context_alloc(1); _mali_osk_atomic_init(&session->fence_seqno, 0); #else diff --git a/mali/common/mali_pp_job.h b/mali/common/mali_pp_job.h index 53f9c7c..0ebd138 100755 --- a/mali/common/mali_pp_job.h +++ b/mali/common/mali_pp_job.h @@ -27,7 +27,6 @@ #endif #if defined(CONFIG_MALI_DMA_BUF_FENCE) #include "linux/mali_dma_fence.h" -#include #endif typedef enum pp_job_status { @@ -102,8 +101,12 @@ struct mali_pp_job { #if defined(CONFIG_MALI_DMA_BUF_FENCE) struct mali_dma_fence_context dma_fence_context; /**< The mali dma fence context to record dma fence waiters that this job wait for */ +#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 10, 0) + struct dma_fence *rendered_dma_fence; /**< the new dma fence link to this job */ +#else struct fence *rendered_dma_fence; /**< the new dma fence link to this job */ #endif +#endif }; void mali_pp_job_initialize(void); diff --git a/mali/common/mali_timeline.c b/mali/common/mali_timeline.c index 9dae115..22555dd 100755 --- a/mali/common/mali_timeline.c +++ b/mali/common/mali_timeline.c @@ -20,6 +20,12 @@ #define MALI_TIMELINE_SYSTEM_LOCKED(system) (mali_spinlock_reentrant_is_held((system)->spinlock, _mali_osk_get_tid())) +#if defined(CONFIG_SYNC) || defined(CONFIG_SYNC_FILE) +_mali_osk_wq_work_t *sync_fence_callback_work_t = NULL; +_mali_osk_spinlock_irq_t *sync_fence_callback_list_lock = NULL; +static _MALI_OSK_LIST_HEAD_STATIC_INIT(sync_fence_callback_queue); +#endif + /* * Following three elements are used to record how many * gp, physical pp or virtual pp jobs are delayed in the whole @@ -75,88 +81,19 @@ static void mali_timeline_sync_fence_callback(struct sync_fence *sync_fence, str static void mali_timeline_sync_fence_callback(struct mali_internal_sync_fence *sync_fence, struct mali_internal_sync_fence_waiter *sync_fence_waiter) #endif { - struct mali_timeline_system *system; - struct mali_timeline_waiter *waiter; struct mali_timeline_tracker *tracker; - mali_scheduler_mask schedule_mask = MALI_SCHEDULER_MASK_EMPTY; - u32 tid = _mali_osk_get_tid(); - mali_bool is_aborting = MALI_FALSE; -#if LINUX_VERSION_CODE < KERNEL_VERSION(3, 17, 0) - int fence_status = sync_fence->status; -#else - int fence_status = atomic_read(&sync_fence->status); -#endif - MALI_DEBUG_ASSERT_POINTER(sync_fence); + MALI_IGNORE(sync_fence); MALI_DEBUG_ASSERT_POINTER(sync_fence_waiter); tracker = _MALI_OSK_CONTAINER_OF(sync_fence_waiter, struct mali_timeline_tracker, sync_fence_waiter); MALI_DEBUG_ASSERT_POINTER(tracker); - system = tracker->system; - MALI_DEBUG_ASSERT_POINTER(system); - MALI_DEBUG_ASSERT_POINTER(system->session); - - mali_spinlock_reentrant_wait(system->spinlock, tid); + _mali_osk_spinlock_irq_lock(sync_fence_callback_list_lock); + _mali_osk_list_addtail(&tracker->sync_fence_signal_list, &sync_fence_callback_queue); + _mali_osk_spinlock_irq_unlock(sync_fence_callback_list_lock); - is_aborting = system->session->is_aborting; - if (!is_aborting && (0 > fence_status)) { - MALI_PRINT_ERROR(("Mali Timeline: sync fence fd %d signaled with error %d\n", tracker->fence.sync_fd, fence_status)); - tracker->activation_error |= MALI_TIMELINE_ACTIVATION_ERROR_SYNC_BIT; - } - - waiter = tracker->waiter_sync; - MALI_DEBUG_ASSERT_POINTER(waiter); - - tracker->sync_fence = NULL; - tracker->fence.sync_fd = -1; - - schedule_mask |= mali_timeline_system_release_waiter(system, waiter); - - /* If aborting, wake up sleepers that are waiting for sync fence callbacks to complete. */ - if (is_aborting) { - _mali_osk_wait_queue_wake_up(system->wait_queue); - } - - mali_spinlock_reentrant_signal(system->spinlock, tid); - - /* - * Older versions of Linux, before 3.5, doesn't support fput() in interrupt - * context. For those older kernels, allocate a list object and put the - * fence object on that and defer the call to sync_fence_put() to a workqueue. - */ -#if LINUX_VERSION_CODE < KERNEL_VERSION(3,5,0) - { - struct mali_deferred_fence_put_entry *obj; - - obj = kzalloc(sizeof(struct mali_deferred_fence_put_entry), GFP_ATOMIC); - if (obj) { - unsigned long flags; - mali_bool schedule = MALI_FALSE; - - obj->fence = sync_fence; - - spin_lock_irqsave(&mali_timeline_sync_fence_to_free_lock, flags); - if (hlist_empty(&mali_timeline_sync_fence_to_free_list)) - schedule = MALI_TRUE; - hlist_add_head(&obj->list, &mali_timeline_sync_fence_to_free_list); - spin_unlock_irqrestore(&mali_timeline_sync_fence_to_free_lock, flags); - - if (schedule) - schedule_delayed_work(&delayed_sync_fence_put, 0); - } - } -#else -#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 6, 0) - sync_fence_put(sync_fence); -#else - fput(sync_fence->file); -#endif -#endif /* LINUX_VERSION_CODE < KERNEL_VERSION(3,5,0) */ - - if (!is_aborting) { - mali_executor_schedule_from_mask(schedule_mask, MALI_TRUE); - } + _mali_osk_wq_schedule_work(sync_fence_callback_work_t); } #endif /* defined(CONFIG_SYNC) || defined(CONFIG_SYNC_FILE) */ @@ -939,8 +876,14 @@ static void mali_timeline_cancel_dma_fence_waiters(struct mali_timeline_system * * This function returns true if the callback is successfully removed, * or false if the fence has already been signaled. */ +#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 10, 0) + bool ret = dma_fence_remove_callback(pp_job->dma_fence_context.mali_dma_fence_waiters[j]->fence, + &pp_job->dma_fence_context.mali_dma_fence_waiters[j]->base); + +#else bool ret = fence_remove_callback(pp_job->dma_fence_context.mali_dma_fence_waiters[j]->fence, &pp_job->dma_fence_context.mali_dma_fence_waiters[j]->base); +#endif if (ret) { fence_is_signaled = MALI_FALSE; } @@ -1513,18 +1456,156 @@ mali_timeline_point mali_timeline_system_get_latest_point(struct mali_timeline_s return point; } -void mali_timeline_initialize(void) +#if defined(CONFIG_SYNC) || defined(CONFIG_SYNC_FILE) +static void mali_timeline_do_sync_fence_callback(void *arg) +{ + _MALI_OSK_LIST_HEAD_STATIC_INIT(list); + struct mali_timeline_tracker *tracker; + struct mali_timeline_tracker *tmp_tracker; + u32 tid = _mali_osk_get_tid(); + + MALI_IGNORE(arg); + + /* + * Quickly "unhook" the jobs pending to be deleted, so we can release + * the lock before we start deleting the job objects + * (without any locks held) + */ + _mali_osk_spinlock_irq_lock(sync_fence_callback_list_lock); + _mali_osk_list_move_list(&sync_fence_callback_queue, &list); + _mali_osk_spinlock_irq_unlock(sync_fence_callback_list_lock); + + _MALI_OSK_LIST_FOREACHENTRY(tracker, tmp_tracker, &list, + struct mali_timeline_tracker, sync_fence_signal_list) { + mali_scheduler_mask schedule_mask = MALI_SCHEDULER_MASK_EMPTY; + mali_bool is_aborting = MALI_FALSE; + int fence_status = 0; +#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 6, 0) + struct sync_fence *sync_fence = NULL; +#else + struct mali_internal_sync_fence *sync_fence = NULL; +#endif + struct mali_timeline_system *system = NULL; + struct mali_timeline_waiter *waiter = NULL; + + _mali_osk_list_delinit(&tracker->sync_fence_signal_list); + + sync_fence = tracker->sync_fence; + MALI_DEBUG_ASSERT_POINTER(sync_fence); + +#if LINUX_VERSION_CODE < KERNEL_VERSION(3, 17, 0) + fence_status = sync_fence->status; +#else + fence_status = atomic_read(&sync_fence->status); +#endif + + system = tracker->system; + MALI_DEBUG_ASSERT_POINTER(system); + MALI_DEBUG_ASSERT_POINTER(system->session); + + mali_spinlock_reentrant_wait(system->spinlock, tid); + + is_aborting = system->session->is_aborting; + if (!is_aborting && (0 > fence_status)) { + MALI_PRINT_ERROR(("Mali Timeline: sync fence fd %d signaled with error %d\n", tracker->fence.sync_fd, fence_status)); + tracker->activation_error |= MALI_TIMELINE_ACTIVATION_ERROR_SYNC_BIT; + } + + waiter = tracker->waiter_sync; + MALI_DEBUG_ASSERT_POINTER(waiter); + + tracker->sync_fence = NULL; + tracker->fence.sync_fd = -1; + + schedule_mask |= mali_timeline_system_release_waiter(system, waiter); + + /* If aborting, wake up sleepers that are waiting for sync fence callbacks to complete. */ + if (is_aborting) { + _mali_osk_wait_queue_wake_up(system->wait_queue); + } + + mali_spinlock_reentrant_signal(system->spinlock, tid); + + /* + * Older versions of Linux, before 3.5, doesn't support fput() in interrupt + * context. For those older kernels, allocate a list object and put the + * fence object on that and defer the call to sync_fence_put() to a workqueue. + */ +#if LINUX_VERSION_CODE < KERNEL_VERSION(3,5,0) + { + struct mali_deferred_fence_put_entry *obj; + + obj = kzalloc(sizeof(struct mali_deferred_fence_put_entry), GFP_ATOMIC); + if (obj) { + unsigned long flags; + mali_bool schedule = MALI_FALSE; + + obj->fence = sync_fence; + + spin_lock_irqsave(&mali_timeline_sync_fence_to_free_lock, flags); + if (hlist_empty(&mali_timeline_sync_fence_to_free_list)) + schedule = MALI_TRUE; + hlist_add_head(&obj->list, &mali_timeline_sync_fence_to_free_list); + spin_unlock_irqrestore(&mali_timeline_sync_fence_to_free_lock, flags); + + if (schedule) + schedule_delayed_work(&delayed_sync_fence_put, 0); + } + } +#else +#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 6, 0) + sync_fence_put(sync_fence); +#else + fput(sync_fence->file); +#endif +#endif /* LINUX_VERSION_CODE < KERNEL_VERSION(3,5,0) */ + + if (!is_aborting) { + mali_executor_schedule_from_mask(schedule_mask, MALI_TRUE); + } + } +} +#endif +_mali_osk_errcode_t mali_timeline_initialize(void) { _mali_osk_atomic_init(&gp_tracker_count, 0); _mali_osk_atomic_init(&phy_pp_tracker_count, 0); _mali_osk_atomic_init(&virt_pp_tracker_count, 0); + +#if defined(CONFIG_SYNC) || defined(CONFIG_SYNC_FILE) + sync_fence_callback_list_lock = _mali_osk_spinlock_irq_init(_MALI_OSK_LOCKFLAG_UNORDERED, _MALI_OSK_LOCK_ORDER_FIRST); + if (NULL == sync_fence_callback_list_lock) { + return _MALI_OSK_ERR_NOMEM; + } + + sync_fence_callback_work_t = _mali_osk_wq_create_work( + mali_timeline_do_sync_fence_callback, NULL); + + if (NULL == sync_fence_callback_work_t) { + return _MALI_OSK_ERR_FAULT; + } +#endif + return _MALI_OSK_ERR_OK; } + void mali_timeline_terminate(void) { _mali_osk_atomic_term(&gp_tracker_count); _mali_osk_atomic_term(&phy_pp_tracker_count); _mali_osk_atomic_term(&virt_pp_tracker_count); + +#if defined(CONFIG_SYNC) || defined(CONFIG_SYNC_FILE) + if (NULL != sync_fence_callback_list_lock) { + _mali_osk_spinlock_irq_term(sync_fence_callback_list_lock); + sync_fence_callback_list_lock = NULL; + } + + if (NULL != sync_fence_callback_work_t) { + _mali_osk_wq_delete_work(sync_fence_callback_work_t); + sync_fence_callback_work_t = NULL; + } +#endif } #if defined(MALI_TIMELINE_DEBUG_FUNCTIONS) @@ -1642,8 +1723,8 @@ void mali_timeline_debug_print_tracker(struct mali_timeline_tracker *tracker, _m tracker->fence.sync_fd, (unsigned int)(uintptr_t)(tracker->sync_fence), (unsigned int)(uintptr_t)(tracker->job)); else MALI_DEBUG_PRINT(2, ("TL: %s %u %c fd:%d fence:(0x%08X) job:(0x%08X)\n", - tracker_type, tracker->point, state_char, - tracker->fence.sync_fd, (unsigned int)(uintptr_t)(tracker->sync_fence), (unsigned int)(uintptr_t)(tracker->job))); + tracker_type, tracker->point, state_char, + tracker->fence.sync_fd, (unsigned int)(uintptr_t)(tracker->sync_fence), (unsigned int)(uintptr_t)(tracker->job))); } #else @@ -1657,11 +1738,11 @@ void mali_timeline_debug_print_tracker(struct mali_timeline_tracker *tracker, _m (unsigned int)(uintptr_t)(tracker->job)); else MALI_DEBUG_PRINT(2, ("TL: %s %u %c - ref_wait:%u [%s(%u),%s(%u),%s(%u)] job:(0x%08X)\n", - tracker_type, tracker->point, state_char, tracker->trigger_ref_count, - is_waiting_on_timeline(tracker, MALI_TIMELINE_GP) ? "WaitGP" : " ", tracker->fence.points[0], - is_waiting_on_timeline(tracker, MALI_TIMELINE_PP) ? "WaitPP" : " ", tracker->fence.points[1], - is_waiting_on_timeline(tracker, MALI_TIMELINE_SOFT) ? "WaitSOFT" : " ", tracker->fence.points[2], - (unsigned int)(uintptr_t)(tracker->job))); + tracker_type, tracker->point, state_char, tracker->trigger_ref_count, + is_waiting_on_timeline(tracker, MALI_TIMELINE_GP) ? "WaitGP" : " ", tracker->fence.points[0], + is_waiting_on_timeline(tracker, MALI_TIMELINE_PP) ? "WaitPP" : " ", tracker->fence.points[1], + is_waiting_on_timeline(tracker, MALI_TIMELINE_SOFT) ? "WaitSOFT" : " ", tracker->fence.points[2], + (unsigned int)(uintptr_t)(tracker->job))); } else { if (print_ctx) _mali_osk_ctxprintf(print_ctx, "TL: %s %u %c job:(0x%08X)\n", @@ -1717,11 +1798,11 @@ void mali_timeline_debug_direct_print_tracker(struct mali_timeline_tracker *trac #else if (0 != tracker->trigger_ref_count) { MALI_PRINT(("TL: %s %u %c - ref_wait:%u [%s(%u),%s(%u),%s(%u)] job:(0x%08X)\n", - tracker_type, tracker->point, state_char, tracker->trigger_ref_count, - is_waiting_on_timeline(tracker, MALI_TIMELINE_GP) ? "WaitGP" : " ", tracker->fence.points[0], - is_waiting_on_timeline(tracker, MALI_TIMELINE_PP) ? "WaitPP" : " ", tracker->fence.points[1], - is_waiting_on_timeline(tracker, MALI_TIMELINE_SOFT) ? "WaitSOFT" : " ", tracker->fence.points[2], - tracker->job)); + tracker_type, tracker->point, state_char, tracker->trigger_ref_count, + is_waiting_on_timeline(tracker, MALI_TIMELINE_GP) ? "WaitGP" : " ", tracker->fence.points[0], + is_waiting_on_timeline(tracker, MALI_TIMELINE_PP) ? "WaitPP" : " ", tracker->fence.points[1], + is_waiting_on_timeline(tracker, MALI_TIMELINE_SOFT) ? "WaitSOFT" : " ", tracker->fence.points[2], + tracker->fence.sync_fd, (unsigned int)(uintptr_t)(tracker->sync_fence), (unsigned int)(uintptr_t)(tracker->job))); } else { MALI_PRINT(("TL: %s %u %c job:(0x%08X)\n", tracker_type, tracker->point, state_char, @@ -1767,7 +1848,7 @@ void mali_timeline_debug_print_system(struct mali_timeline_system *system, _mali timeline_id_to_string((enum mali_timeline_id)i)); else MALI_DEBUG_PRINT(2, ("TL: Timeline %s: oldest (%u) next(%u)\n", - timeline_id_to_string((enum mali_timeline_id)i), timeline->point_oldest, timeline->point_next)); + timeline_id_to_string((enum mali_timeline_id)i), timeline->point_oldest, timeline->point_next)); mali_timeline_debug_print_timeline(timeline, print_ctx); num_printed++; diff --git a/mali/common/mali_timeline.h b/mali/common/mali_timeline.h index f0ecd06..3aeb75c 100755 --- a/mali/common/mali_timeline.h +++ b/mali/common/mali_timeline.h @@ -202,6 +202,8 @@ struct mali_timeline_tracker { struct mali_internal_sync_fence *sync_fence; /**< The sync fence this tracker is waiting on. */ #endif _mali_osk_list_t sync_fence_cancel_list; /**< List node used to cancel sync fence waiters. */ + _mali_osk_list_t sync_fence_signal_list; /** < List node used to singal sync fence callback function. */ + #endif /* defined(CONFIG_SYNC) || defined(CONFIG_SYNC_FILE) */ #if defined(CONFIG_MALI_DMA_BUF_FENCE) @@ -479,7 +481,7 @@ MALI_STATIC_INLINE mali_bool mali_timeline_tracker_activation_error( */ void mali_timeline_fence_copy_uk_fence(struct mali_timeline_fence *fence, _mali_uk_fence_t *uk_fence); -void mali_timeline_initialize(void); +_mali_osk_errcode_t mali_timeline_initialize(void); void mali_timeline_terminate(void); diff --git a/mali/linux/mali_dma_fence.c b/mali/linux/mali_dma_fence.c index df6e311..7db30b8 100644 --- a/mali/linux/mali_dma_fence.c +++ b/mali/linux/mali_dma_fence.c @@ -19,6 +19,34 @@ static DEFINE_SPINLOCK(mali_dma_fence_lock); +#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 10, 0) +static bool mali_dma_fence_enable_signaling(struct dma_fence *fence) +{ + MALI_IGNORE(fence); + return true; +} + +static const char *mali_dma_fence_get_driver_name(struct dma_fence *fence) +{ + MALI_IGNORE(fence); + return "mali"; +} + +static const char *mali_dma_fence_get_timeline_name(struct dma_fence *fence) +{ + MALI_IGNORE(fence); + return "mali_dma_fence"; +} + +static const struct dma_fence_ops mali_dma_fence_ops = { + .get_driver_name = mali_dma_fence_get_driver_name, + .get_timeline_name = mali_dma_fence_get_timeline_name, + .enable_signaling = mali_dma_fence_enable_signaling, + .signaled = NULL, + .wait = dma_fence_default_wait, + .release = NULL +}; +#else static bool mali_dma_fence_enable_signaling(struct fence *fence) { MALI_IGNORE(fence); @@ -45,6 +73,7 @@ static const struct fence_ops mali_dma_fence_ops = { .wait = fence_default_wait, .release = NULL }; +#endif static void mali_dma_fence_context_cleanup(struct mali_dma_fence_context *dma_fence_context) { @@ -54,9 +83,16 @@ static void mali_dma_fence_context_cleanup(struct mali_dma_fence_context *dma_fe for (i = 0; i < dma_fence_context->num_dma_fence_waiter; i++) { if (dma_fence_context->mali_dma_fence_waiters[i]) { +#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 10, 0) + dma_fence_remove_callback(dma_fence_context->mali_dma_fence_waiters[i]->fence, + &dma_fence_context->mali_dma_fence_waiters[i]->base); + dma_fence_put(dma_fence_context->mali_dma_fence_waiters[i]->fence); + +#else fence_remove_callback(dma_fence_context->mali_dma_fence_waiters[i]->fence, &dma_fence_context->mali_dma_fence_waiters[i]->base); fence_put(dma_fence_context->mali_dma_fence_waiters[i]->fence); +#endif kfree(dma_fence_context->mali_dma_fence_waiters[i]); dma_fence_context->mali_dma_fence_waiters[i] = NULL; } @@ -80,7 +116,11 @@ static void mali_dma_fence_context_work_func(struct work_struct *work_handle) dma_fence_context->cb_func(dma_fence_context->pp_job_ptr); } +#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 10, 0) +static void mali_dma_fence_callback(struct dma_fence *fence, struct dma_fence_cb *cb) +#else static void mali_dma_fence_callback(struct fence *fence, struct fence_cb *cb) +#endif { struct mali_dma_fence_waiter *dma_fence_waiter = NULL; struct mali_dma_fence_context *dma_fence_context = NULL; @@ -99,7 +139,11 @@ static void mali_dma_fence_callback(struct fence *fence, struct fence_cb *cb) schedule_work(&dma_fence_context->work_handle); } +#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 10, 0) +static _mali_osk_errcode_t mali_dma_fence_add_callback(struct mali_dma_fence_context *dma_fence_context, struct dma_fence *fence) +#else static _mali_osk_errcode_t mali_dma_fence_add_callback(struct mali_dma_fence_context *dma_fence_context, struct fence *fence) +#endif { int ret = 0; struct mali_dma_fence_waiter *dma_fence_waiter; @@ -127,16 +171,27 @@ static _mali_osk_errcode_t mali_dma_fence_add_callback(struct mali_dma_fence_con return _MALI_OSK_ERR_NOMEM; } +#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 10, 0) + dma_fence_get(fence); +#else fence_get(fence); - +#endif dma_fence_waiter->fence = fence; dma_fence_waiter->parent = dma_fence_context; atomic_inc(&dma_fence_context->count); - +#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 10, 0) + ret = dma_fence_add_callback(fence, &dma_fence_waiter->base, + mali_dma_fence_callback); +#else ret = fence_add_callback(fence, &dma_fence_waiter->base, mali_dma_fence_callback); +#endif if (0 > ret) { +#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 10, 0) + dma_fence_put(fence); +#else fence_put(fence); +#endif kfree(dma_fence_waiter); atomic_dec(&dma_fence_context->count); if (-ENOENT == ret) { @@ -155,32 +210,52 @@ static _mali_osk_errcode_t mali_dma_fence_add_callback(struct mali_dma_fence_con } + #if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 10, 0) + struct dma_fence *mali_dma_fence_new(u32 context, u32 seqno) + #else struct fence *mali_dma_fence_new(u32 context, u32 seqno) +#endif { +#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 10, 0) + struct dma_fence *fence = NULL; + fence = kzalloc(sizeof(struct dma_fence), GFP_KERNEL); +#else struct fence *fence = NULL; - - fence = kzalloc(sizeof(*fence), GFP_KERNEL); - + fence = kzalloc(sizeof(struct fence), GFP_KERNEL); +#endif if (NULL == fence) { MALI_DEBUG_PRINT(1, ("Mali dma fence: failed to create dma fence.\n")); return fence; } - +#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 10, 0) + dma_fence_init(fence, + &mali_dma_fence_ops, + &mali_dma_fence_lock, + context, seqno); +#else fence_init(fence, &mali_dma_fence_ops, &mali_dma_fence_lock, context, seqno); - +#endif return fence; } +#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 10, 0) +void mali_dma_fence_signal_and_put(struct dma_fence **fence) +#else void mali_dma_fence_signal_and_put(struct fence **fence) +#endif { MALI_DEBUG_ASSERT_POINTER(fence); MALI_DEBUG_ASSERT_POINTER(*fence); - +#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 10, 0) + dma_fence_signal(*fence); + dma_fence_put(*fence); +#else fence_signal(*fence); fence_put(*fence); +#endif *fence = NULL; } @@ -202,10 +277,14 @@ _mali_osk_errcode_t mali_dma_fence_context_add_waiters(struct mali_dma_fence_con struct reservation_object *dma_reservation_object) { _mali_osk_errcode_t ret = _MALI_OSK_ERR_OK; - struct fence *exclusive_fence = NULL; u32 shared_count = 0, i; +#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 10, 0) + struct dma_fence *exclusive_fence = NULL; + struct dma_fence **shared_fences = NULL; +#else + struct fence *exclusive_fence = NULL; struct fence **shared_fences = NULL; - +#endif MALI_DEBUG_ASSERT_POINTER(dma_fence_context); MALI_DEBUG_ASSERT_POINTER(dma_reservation_object); @@ -239,11 +318,19 @@ _mali_osk_errcode_t mali_dma_fence_context_add_waiters(struct mali_dma_fence_con ended: if (exclusive_fence) +#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 10, 0) + dma_fence_put(exclusive_fence); +#else fence_put(exclusive_fence); +#endif if (shared_fences) { for (i = 0; i < shared_count; i++) { +#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 10, 0) + dma_fence_put(shared_fences[i]); +#else fence_put(shared_fences[i]); +#endif } kfree(shared_fences); } diff --git a/mali/linux/mali_dma_fence.h b/mali/linux/mali_dma_fence.h index 35534e2..112fdd1 100644 --- a/mali/linux/mali_dma_fence.h +++ b/mali/linux/mali_dma_fence.h @@ -18,7 +18,11 @@ #define _MALI_DMA_FENCE_H_ #if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 17, 0) +#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 10, 0) +#include +#else #include +#endif #include #endif @@ -28,9 +32,14 @@ struct mali_dma_fence_context; typedef void (*mali_dma_fence_context_callback_func_t)(void *pp_job_ptr); struct mali_dma_fence_waiter { +#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 10, 0) + struct dma_fence *fence; + struct dma_fence_cb base; +#else struct fence_cb base; - struct mali_dma_fence_context *parent; struct fence *fence; +#endif + struct mali_dma_fence_context *parent; }; struct mali_dma_fence_context { @@ -47,13 +56,19 @@ struct mali_dma_fence_context { * @param seqno A linearly increasing sequence number for this context * @return the new dma fence if success, or NULL on failure. */ + #if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 10, 0) + struct dma_fence *mali_dma_fence_new(u32 context, u32 seqno); + #else struct fence *mali_dma_fence_new(u32 context, u32 seqno); - +#endif /* Signal and put dma fence * @param fence The dma fence to signal and put */ +#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 10, 0) +void mali_dma_fence_signal_and_put(struct dma_fence **fence); +#else void mali_dma_fence_signal_and_put(struct fence **fence); - +#endif /** * Initialize a mali dma fence context for pp job. * @param dma_fence_context The mali dma fence context to initialize. diff --git a/mali/linux/mali_internal_sync.c b/mali/linux/mali_internal_sync.c index 506b421..ee62def 100644 --- a/mali/linux/mali_internal_sync.c +++ b/mali/linux/mali_internal_sync.c @@ -66,10 +66,18 @@ struct mali_internal_sync_info_data { */ #define MALI_INTERNAL_SYNC_IOC_FENCE_INFO _IOWR('>', 2, struct mali_internal_sync_info_data) +#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 10, 0) +static const struct dma_fence_ops fence_ops; +#else static const struct fence_ops fence_ops; +#endif static const struct file_operations sync_fence_fops; +#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 10, 0) +static struct mali_internal_sync_point *mali_internal_fence_to_sync_pt(struct dma_fence *fence) +#else static struct mali_internal_sync_point *mali_internal_fence_to_sync_pt(struct fence *fence) +#endif { MALI_DEBUG_ASSERT_POINTER(fence); return container_of(fence, struct mali_internal_sync_point, base); @@ -123,7 +131,11 @@ err: return NULL; } +#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 10, 0) +static void mali_internal_fence_check_cb_func(struct dma_fence *fence, struct dma_fence_cb *cb) +#else static void mali_internal_fence_check_cb_func(struct fence *fence, struct fence_cb *cb) +#endif { struct mali_internal_sync_fence_cb *check; struct mali_internal_sync_fence *sync_fence; @@ -138,7 +150,11 @@ static void mali_internal_fence_check_cb_func(struct fence *fence, struct fence_ wake_up_all(&sync_fence->wq); } +#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 10, 0) +static void mali_internal_sync_fence_add_fence(struct mali_internal_sync_fence *sync_fence, struct dma_fence *sync_pt) +#else static void mali_internal_sync_fence_add_fence(struct mali_internal_sync_fence *sync_fence, struct fence *sync_pt) +#endif { int fence_num = 0; MALI_DEBUG_ASSERT_POINTER(sync_fence); @@ -148,12 +164,19 @@ static void mali_internal_sync_fence_add_fence(struct mali_internal_sync_fence * sync_fence->cbs[fence_num].base = sync_pt; sync_fence->cbs[fence_num].sync_fence = sync_fence; - +#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 10, 0) + if (!dma_fence_add_callback(sync_pt, &sync_fence->cbs[fence_num].cb, mali_internal_fence_check_cb_func)) { + dma_fence_get(sync_pt); + atomic_inc(&sync_fence->num_fences); + atomic_inc(&sync_fence->status); + } +#else if (!fence_add_callback(sync_pt, &sync_fence->cbs[fence_num].cb, mali_internal_fence_check_cb_func)) { fence_get(sync_pt); atomic_inc(&sync_fence->num_fences); atomic_inc(&sync_fence->status); } +#endif } static int mali_internal_sync_fence_wake_up_wq(wait_queue_t *curr, unsigned mode, @@ -190,7 +213,11 @@ struct mali_internal_sync_timeline *mali_internal_sync_timeline_create(const str } kref_init(&sync_timeline->kref_count); sync_timeline->ops = ops; +#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 10, 0) + sync_timeline->fence_context = dma_fence_context_alloc(1); +#else sync_timeline->fence_context = fence_context_alloc(1); +#endif strlcpy(sync_timeline->name, name, sizeof(sync_timeline->name)); INIT_LIST_HEAD(&sync_timeline->sync_pt_list_head); @@ -227,7 +254,11 @@ void mali_internal_sync_timeline_signal(struct mali_internal_sync_timeline *sync list_for_each_entry_safe(sync_pt, next, &sync_timeline->sync_pt_list_head, sync_pt_list) { +#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 10, 0) + if (dma_fence_is_signaled_locked(&sync_pt->base)) +#else if (fence_is_signaled_locked(&sync_pt->base)) +#endif list_del_init(&sync_pt->sync_pt_list); } @@ -253,8 +284,13 @@ struct mali_internal_sync_point *mali_internal_sync_point_create(struct mali_int } spin_lock_irqsave(&sync_timeline->sync_pt_list_lock, flags); kref_get(&sync_timeline->kref_count); +#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 10, 0) + dma_fence_init(&sync_pt->base, &fence_ops, &sync_timeline->sync_pt_list_lock, + sync_timeline->fence_context, ++sync_timeline->value); +#else fence_init(&sync_pt->base, &fence_ops, &sync_timeline->sync_pt_list_lock, sync_timeline->fence_context, ++sync_timeline->value); +#endif INIT_LIST_HEAD(&sync_pt->sync_pt_list); spin_unlock_irqrestore(&sync_timeline->sync_pt_list_lock, flags); @@ -283,8 +319,13 @@ struct mali_internal_sync_fence *mali_internal_sync_fence_create(struct mali_int sync_fence->cbs[0].base = &sync_pt->base; sync_fence->cbs[0].sync_fence = sync_fence; +#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 10, 0) + if (dma_fence_add_callback(&sync_pt->base, &sync_fence->cbs[0].cb, + mali_internal_fence_check_cb_func)) +#else if (fence_add_callback(&sync_pt->base, &sync_fence->cbs[0].cb, - mali_internal_fence_check_cb_func)) + mali_internal_fence_check_cb_func)) +#endif atomic_dec(&sync_fence->status); return sync_fence; @@ -322,9 +363,13 @@ struct mali_internal_sync_fence *mali_internal_sync_fence_merge( } for (i = j = 0; i < num_fence1 && j < num_fence2; ) { +#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 10, 0) + struct dma_fence *fence1 = sync_fence1->cbs[i].base; + struct dma_fence *fence2 = sync_fence2->cbs[j].base; +#else struct fence *fence1 = sync_fence1->cbs[i].base; struct fence *fence2 = sync_fence2->cbs[j].base; - +#endif if (fence1->context < fence2->context) { mali_internal_sync_fence_add_fence(new_sync_fence, fence1); @@ -476,7 +521,11 @@ static int mali_internal_sync_fence_wait(struct mali_internal_sync_fence *sync_f return ret; } +#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 10, 0) +static const char *mali_internal_fence_get_driver_name(struct dma_fence *fence) +#else static const char *mali_internal_fence_get_driver_name(struct fence *fence) +#endif { struct mali_internal_sync_point *sync_pt; struct mali_internal_sync_timeline *parent; @@ -489,7 +538,11 @@ static const char *mali_internal_fence_get_driver_name(struct fence *fence) return parent->ops->driver_name; } +#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 10, 0) +static const char *mali_internal_fence_get_timeline_name(struct dma_fence *fence) +#else static const char *mali_internal_fence_get_timeline_name(struct fence *fence) +#endif { struct mali_internal_sync_point *sync_pt; struct mali_internal_sync_timeline *parent; @@ -502,7 +555,11 @@ static const char *mali_internal_fence_get_timeline_name(struct fence *fence) return parent->name; } +#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 10, 0) +static void mali_internal_fence_release(struct dma_fence *fence) +#else static void mali_internal_fence_release(struct fence *fence) +#endif { unsigned long flags; struct mali_internal_sync_point *sync_pt; @@ -523,10 +580,18 @@ static void mali_internal_fence_release(struct fence *fence) parent->ops->free_pt(sync_pt); kref_put(&parent->kref_count, mali_internal_sync_timeline_free); +#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 10, 0) + dma_fence_free(&sync_pt->base); +#else fence_free(&sync_pt->base); +#endif } +#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 10, 0) +static bool mali_internal_fence_signaled(struct dma_fence *fence) +#else static bool mali_internal_fence_signaled(struct fence *fence) +#endif { int ret; struct mali_internal_sync_point *sync_pt; @@ -539,11 +604,19 @@ static bool mali_internal_fence_signaled(struct fence *fence) ret = parent->ops->has_signaled(sync_pt); if (0 > ret) +#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 10, 0) + fence->error = ret; +#else fence->status = ret; +#endif return ret; } +#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 10, 0) +static bool mali_internal_fence_enable_signaling(struct dma_fence *fence) +#else static bool mali_internal_fence_enable_signaling(struct fence *fence) +#endif { struct mali_internal_sync_point *sync_pt; struct mali_internal_sync_timeline *parent; @@ -560,8 +633,11 @@ static bool mali_internal_fence_enable_signaling(struct fence *fence) return true; } -static void mali_internal_fence_value_str(struct fence *fence, - char *str, int size) +#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 10, 0) +static void mali_internal_fence_value_str(struct dma_fence *fence, char *str, int size) +#else +static void mali_internal_fence_value_str(struct fence *fence, char *str, int size) +#endif { struct mali_internal_sync_point *sync_pt; struct mali_internal_sync_timeline *parent; @@ -576,12 +652,20 @@ static void mali_internal_fence_value_str(struct fence *fence, parent->ops->print_sync_pt(sync_pt); } +#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 10, 0) +static const struct dma_fence_ops fence_ops = { +#else static const struct fence_ops fence_ops = { +#endif .get_driver_name = mali_internal_fence_get_driver_name, .get_timeline_name = mali_internal_fence_get_timeline_name, .enable_signaling = mali_internal_fence_enable_signaling, .signaled = mali_internal_fence_signaled, +#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 10, 0) + .wait = dma_fence_default_wait, +#else .wait = fence_default_wait, +#endif .release = mali_internal_fence_release, .fence_value_str = mali_internal_fence_value_str, }; @@ -597,8 +681,13 @@ static void mali_internal_sync_fence_free(struct kref *kref_count) num_fences = atomic_read(&sync_fence->num_fences); for (i = 0; i = KERNEL_VERSION(4, 10, 0) + dma_fence_remove_callback(sync_fence->cbs[i].base, &sync_fence->cbs[i].cb); + dma_fence_put(sync_fence->cbs[i].base); +#else fence_remove_callback(sync_fence->cbs[i].base, &sync_fence->cbs[i].cb); fence_put(sync_fence->cbs[i].base); +#endif } kfree(sync_fence); @@ -741,8 +830,11 @@ static long mali_internal_sync_fence_ioctl_fence_info(struct mali_internal_sync_ for (i = 0; i < num_fences; ++i) { struct mali_internal_sync_pt_info *sync_pt_info = NULL; +#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 10, 0) + struct dma_fence *base = sync_fence->cbs[i].base; +#else struct fence *base = sync_fence->cbs[i].base; - +#endif if ((size - len) < sizeof(struct mali_internal_sync_pt_info)) { MALI_PRINT_ERROR(("Mali internal sync:Failed to fence size check when sync fence ioctl fence data info.\n")); err = -ENOMEM; @@ -755,8 +847,13 @@ static long mali_internal_sync_fence_ioctl_fence_info(struct mali_internal_sync_ strlcpy(sync_pt_info->obj_name, base->ops->get_timeline_name(base), sizeof(sync_pt_info->obj_name)); strlcpy(sync_pt_info->driver_name, base->ops->get_driver_name(base), sizeof(sync_pt_info->driver_name)); +#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 10, 0) + if (dma_fence_is_signaled(base)) + sync_pt_info->status = base->error >= 0 ? 1 : base->error; +#else if (fence_is_signaled(base)) sync_pt_info->status = base->status >= 0 ? 1 : base->status; +#endif else sync_pt_info->status = 0; diff --git a/mali/linux/mali_internal_sync.h b/mali/linux/mali_internal_sync.h index 787e8a3..723378b 100644 --- a/mali/linux/mali_internal_sync.h +++ b/mali/linux/mali_internal_sync.h @@ -23,8 +23,11 @@ #include #include #include +#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 10, 0) +#include +#else #include - +#endif struct mali_internal_sync_timeline; struct mali_internal_sync_point; struct mali_internal_sync_fence; @@ -49,13 +52,22 @@ struct mali_internal_sync_timeline { }; struct mali_internal_sync_point { +#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 10, 0) + struct dma_fence base; +#else struct fence base; +#endif struct list_head sync_pt_list; }; struct mali_internal_sync_fence_cb { +#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 10, 0) + struct dma_fence_cb cb; + struct dma_fence *base; +#else struct fence_cb cb; struct fence *base; +#endif struct mali_internal_sync_fence *sync_fence; }; diff --git a/mali/linux/mali_kernel_sysfs.c b/mali/linux/mali_kernel_sysfs.c index 9e00977..bf0cc88 100755 --- a/mali/linux/mali_kernel_sysfs.c +++ b/mali/linux/mali_kernel_sysfs.c @@ -26,7 +26,12 @@ #include #include +#include +#if LINUX_VERSION_CODE >= KERNEL_VERSION(4,12,0) +#include +#else #include +#endif #include #include #include "mali_kernel_sysfs.h" diff --git a/mali/linux/mali_memory.c b/mali/linux/mali_memory.c index 31e341e..78fdd05 100755 --- a/mali/linux/mali_memory.c +++ b/mali/linux/mali_memory.c @@ -50,37 +50,47 @@ static void mali_mem_vma_open(struct vm_area_struct *vma) } static void mali_mem_vma_close(struct vm_area_struct *vma) { - - struct file *filp = NULL; - struct mali_session_data *session = NULL; - /* If need to share the allocation, unref ref_count here */ mali_mem_allocation *alloc = (mali_mem_allocation *)vma->vm_private_data; - filp = vma->vm_file; - MALI_DEBUG_ASSERT(filp); - session = (struct mali_session_data *)filp->private_data; - MALI_DEBUG_ASSERT(session); + if (NULL != alloc) { + struct file *filp = NULL; + struct mali_session_data *session = NULL; - mali_session_memory_lock(session); - vma->vm_private_data = NULL; - mali_session_memory_unlock(session); + filp = vma->vm_file; + MALI_DEBUG_ASSERT(filp); + session = (struct mali_session_data *)filp->private_data; + MALI_DEBUG_ASSERT(session); - mali_allocation_unref(&alloc); + mali_session_memory_lock(session); + vma->vm_private_data = NULL; + mali_session_memory_unlock(session); + + mali_allocation_unref(&alloc); + } } +#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 11, 0) +static int mali_mem_vma_fault(struct vm_fault *vmf) +#else static int mali_mem_vma_fault(struct vm_area_struct *vma, struct vm_fault *vmf) +#endif { struct file *filp = NULL; struct mali_session_data *session = NULL; mali_mem_allocation *alloc = NULL; - mali_mem_backend *mem_bkend = NULL; int ret; int prefetch_num = MALI_VM_NUM_FAULT_PREFETCH; +#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 11, 0) + struct vm_area_struct *vma = vmf->vma; +#endif +#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 10, 0) + unsigned long address = (unsigned long)vmf->address; +#else unsigned long address = (unsigned long)vmf->virtual_address; - +#endif filp = vma->vm_file; MALI_DEBUG_ASSERT(filp); session = (struct mali_session_data *)filp->private_data; @@ -241,6 +251,11 @@ int mali_mmap(struct file *filp, struct vm_area_struct *vma) } mutex_unlock(&mali_idr_mutex); + if ((vma->vm_start + mem_bkend->size) > vma->vm_end) { + MALI_PRINT_ERROR(("mali_mmap: out of memory mapping map_size %d, physical_size %d\n", vma->vm_end - vma->vm_start, mem_bkend->size)); + return -EFAULT; + } + if (!(MALI_MEM_SWAP == mali_alloc->type || (MALI_MEM_COW == mali_alloc->type && (mem_bkend->flags & MALI_MEM_BACKEND_FLAG_SWAP_COWED)))) { /* Set some bits which indicate that, the memory is IO memory, meaning diff --git a/mali/linux/mali_memory_dma_buf.c b/mali/linux/mali_memory_dma_buf.c index 2c9f23d..59107fa 100755 --- a/mali/linux/mali_memory_dma_buf.c +++ b/mali/linux/mali_memory_dma_buf.c @@ -9,7 +9,12 @@ */ #include /* file system operations */ -#include /* user space access */ +#include +#if LINUX_VERSION_CODE >= KERNEL_VERSION(4,12,0) +#include +#else +#include +#endif #include #include #include @@ -40,7 +45,7 @@ static int mali_dma_buf_map(mali_mem_backend *mem_backend) struct mali_page_directory *pagedir; _mali_osk_errcode_t err; struct scatterlist *sg; - u32 virt, flags; + u32 virt, flags, unmap_dma_size; int i; MALI_DEBUG_ASSERT_POINTER(mem_backend); @@ -50,7 +55,8 @@ static int mali_dma_buf_map(mali_mem_backend *mem_backend) mem = mem_backend->dma_buf.attachment; MALI_DEBUG_ASSERT_POINTER(mem); - + MALI_DEBUG_ASSERT_POINTER(mem->buf); + unmap_dma_size = mem->buf->size; session = alloc->session; MALI_DEBUG_ASSERT_POINTER(session); MALI_DEBUG_ASSERT(mem->session == session); @@ -94,6 +100,7 @@ static int mali_dma_buf_map(mali_mem_backend *mem_backend) u32 size = sg_dma_len(sg); dma_addr_t phys = sg_dma_address(sg); + unmap_dma_size -= size; /* sg must be page aligned. */ MALI_DEBUG_ASSERT(0 == size % MALI_MMU_PAGE_SIZE); MALI_DEBUG_ASSERT(0 == (phys & ~(uintptr_t)0xFFFFFFFF)); @@ -113,6 +120,12 @@ static int mali_dma_buf_map(mali_mem_backend *mem_backend) mem->is_mapped = MALI_TRUE; + if (0 != unmap_dma_size) { + MALI_DEBUG_PRINT_ERROR(("The dma buf size isn't equal to the total scatterlists' dma length.\n")); + mali_session_memory_unlock(session); + return -EFAULT; + } + /* Wake up any thread waiting for buffer to become mapped */ wake_up_all(&mem->wait_queue); diff --git a/mali/linux/mali_memory_manager.c b/mali/linux/mali_memory_manager.c index ec12e89..bf7797a 100755 --- a/mali/linux/mali_memory_manager.c +++ b/mali/linux/mali_memory_manager.c @@ -419,6 +419,17 @@ _mali_osk_errcode_t _mali_ukk_mem_allocate(_mali_uk_alloc_mem_s *args) MALI_DEBUG_PRINT(4, (" _mali_ukk_mem_allocate, vaddr=0x%x, size =0x%x! \n", args->gpu_vaddr, args->psize)); + if (args->vsize < args->psize) { + MALI_PRINT_ERROR(("_mali_ukk_mem_allocate: vsize %d shouldn't be less than psize %d\n", args->vsize, args->psize)); + return _MALI_OSK_ERR_INVALID_ARGS; + } else if ((args->vsize % _MALI_OSK_MALI_PAGE_SIZE) || (args->psize % _MALI_OSK_MALI_PAGE_SIZE)) { + MALI_PRINT_ERROR(("_mali_ukk_mem_allocate: not supported non page aligned size-->pszie %d, vsize %d\n", args->psize, args->vsize)); + return _MALI_OSK_ERR_INVALID_ARGS; + } else if ((args->vsize != args->psize) && ((args->flags & _MALI_MEMORY_ALLOCATE_SWAPPABLE) || (args->flags & _MALI_MEMORY_ALLOCATE_SECURE))) { + MALI_PRINT_ERROR(("_mali_ukk_mem_allocate: not supported mem resizeable for mem flag %d\n", args->flags)); + return _MALI_OSK_ERR_INVALID_ARGS; + } + /* Check if the address is allocated */ mali_vma_node = mali_vma_offset_search(&session->allocation_mgr, args->gpu_vaddr, 0); @@ -623,13 +634,18 @@ _mali_osk_errcode_t _mali_ukk_mem_free(_mali_uk_free_mem_s *args) MALI_DEBUG_PRINT(1, ("_mali_ukk_mem_free: invalid addr: 0x%x\n", vaddr)); return _MALI_OSK_ERR_INVALID_ARGS; } - MALI_DEBUG_ASSERT(NULL != mali_vma_node); + mali_alloc = container_of(mali_vma_node, struct mali_mem_allocation, mali_vma_node); - if (mali_alloc) + if (mali_alloc) { + if ((MALI_MEM_UMP == mali_alloc->type) || (MALI_MEM_DMA_BUF == mali_alloc->type) + || (MALI_MEM_EXTERNAL == mali_alloc->type)) { + MALI_PRINT_ERROR(("_mali_ukk_mem_free: not supported for memory type %d\n", mali_alloc->type)); + return _MALI_OSK_ERR_UNSUPPORTED; + } /* check ref_count */ args->free_pages_nr = mali_allocation_unref(&mali_alloc); - + } return _MALI_OSK_ERR_OK; } @@ -781,9 +797,17 @@ _mali_osk_errcode_t _mali_ukk_mem_unbind(_mali_uk_unbind_mem_s *args) return _MALI_OSK_ERR_INVALID_ARGS; } - if (NULL != mali_allocation) + if (NULL != mali_allocation) { + + if ((MALI_MEM_UMP != mali_allocation->type) && (MALI_MEM_DMA_BUF != mali_allocation->type) + && (MALI_MEM_EXTERNAL != mali_allocation->type)) { + MALI_PRINT_ERROR(("_mali_ukk_mem_unbind not supported for memory type %d\n", mali_allocation->type)); + return _MALI_OSK_ERR_UNSUPPORTED; + } + /* check ref_count */ mali_allocation_unref(&mali_allocation); + } return _MALI_OSK_ERR_OK; } @@ -936,7 +960,10 @@ _mali_osk_errcode_t _mali_ukk_mem_cow_modify_range(_mali_uk_cow_modify_range_s * return ret; } - MALI_DEBUG_ASSERT(MALI_MEM_COW == mem_backend->type); + if (MALI_MEM_COW != mem_backend->type) { + MALI_PRINT_ERROR(("_mali_ukk_mem_cow_modify_range: not supported for memory type %d !\n", mem_backend->type)); + return _MALI_OSK_ERR_FAULT; + } ret = mali_memory_cow_modify_range(mem_backend, args->range_start, args->size); args->change_pages_nr = mem_backend->cow_mem.change_pages_nr; diff --git a/mali/linux/mali_memory_util.c b/mali/linux/mali_memory_util.c index 4fbb757..5114388 100755 --- a/mali/linux/mali_memory_util.c +++ b/mali/linux/mali_memory_util.c @@ -115,6 +115,9 @@ static u32 _mali_free_allocation_mem(mali_mem_allocation *mali_alloc) break; } + if ((NULL != mali_alloc->cpu_mapping.vma) && (mali_alloc == (mali_alloc->cpu_mapping.vma)->vm_private_data)) + (mali_alloc->cpu_mapping.vma)->vm_private_data = NULL; + /*Remove backend memory idex */ mutex_lock(&mali_idr_mutex); idr_remove(&mali_backend_idr, mali_alloc->backend_handle); diff --git a/mali/linux/mali_osk_mali.c b/mali/linux/mali_osk_mali.c index 272d196..f47b343 100755 --- a/mali/linux/mali_osk_mali.c +++ b/mali/linux/mali_osk_mali.c @@ -13,7 +13,12 @@ * Implementation of the OS abstraction layer which is specific for the Mali kernel device driver */ #include +#include +#if LINUX_VERSION_CODE >= KERNEL_VERSION(4,12,0) +#include +#else #include +#endif #include #include #include diff --git a/mali/linux/mali_osk_misc.c b/mali/linux/mali_osk_misc.c index 7dda283..2a6ae91 100755 --- a/mali/linux/mali_osk_misc.c +++ b/mali/linux/mali_osk_misc.c @@ -13,7 +13,12 @@ * Implementation of the OS abstraction layer for the kernel device driver */ #include +#include +#if LINUX_VERSION_CODE >= KERNEL_VERSION(4,12,0) +#include +#else #include +#endif #include #include #include diff --git a/mali/linux/mali_osk_specific.h b/mali/linux/mali_osk_specific.h index adcca29..0826b08 100755 --- a/mali/linux/mali_osk_specific.h +++ b/mali/linux/mali_osk_specific.h @@ -17,7 +17,12 @@ #ifndef __MALI_OSK_SPECIFIC_H__ #define __MALI_OSK_SPECIFIC_H__ +#include +#if LINUX_VERSION_CODE >= KERNEL_VERSION(4,12,0) +#include +#else #include +#endif #include #include #include diff --git a/mali/linux/mali_sync.c b/mali/linux/mali_sync.c index 0d17a0d..48e3d65 100755 --- a/mali/linux/mali_sync.c +++ b/mali/linux/mali_sync.c @@ -605,7 +605,11 @@ struct mali_internal_sync_fence *mali_sync_flag_create_fence(struct mali_sync_fl sync_fence = mali_internal_sync_fence_create(sync_pt); if (NULL == sync_fence) { MALI_PRINT_ERROR(("Mali sync: sync_fence creation failed\n")); +#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 10, 0) + dma_fence_put(&sync_pt->base); +#else fence_put(&sync_pt->base); +#endif return NULL; } diff --git a/mali/linux/mali_ukk_core.c b/mali/linux/mali_ukk_core.c index a6c43b7..62e31c9 100755 --- a/mali/linux/mali_ukk_core.c +++ b/mali/linux/mali_ukk_core.c @@ -9,7 +9,12 @@ */ #include /* file system operations */ #include /* memort allocation functions */ -#include /* user space access */ +#include +#if LINUX_VERSION_CODE >= KERNEL_VERSION(4,12,0) +#include +#else +#include +#endif #include "mali_ukk.h" #include "mali_osk.h" diff --git a/mali/linux/mali_ukk_gp.c b/mali/linux/mali_ukk_gp.c index d7c5d2f..6909e52 100755 --- a/mali/linux/mali_ukk_gp.c +++ b/mali/linux/mali_ukk_gp.c @@ -8,7 +8,12 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include /* file system operations */ -#include /* user space access */ +#include +#if LINUX_VERSION_CODE >= KERNEL_VERSION(4,12,0) +#include +#else +#include +#endif #include "mali_ukk.h" #include "mali_osk.h" diff --git a/mali/linux/mali_ukk_mem.c b/mali/linux/mali_ukk_mem.c index 3dfe345..ea21147 100755 --- a/mali/linux/mali_ukk_mem.c +++ b/mali/linux/mali_ukk_mem.c @@ -8,7 +8,12 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include /* file system operations */ -#include /* user space access */ +#include +#if LINUX_VERSION_CODE >= KERNEL_VERSION(4,12,0) +#include +#else +#include +#endif #include "mali_ukk.h" #include "mali_osk.h" diff --git a/mali/linux/mali_ukk_pp.c b/mali/linux/mali_ukk_pp.c index 2c59bc7..17ac889 100755 --- a/mali/linux/mali_ukk_pp.c +++ b/mali/linux/mali_ukk_pp.c @@ -8,7 +8,13 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include /* file system operations */ -#include /* user space access */ +#include + +#if LINUX_VERSION_CODE >= KERNEL_VERSION(4,12,0) +#include +#else +#include +#endif #include "mali_ukk.h" #include "mali_osk.h" diff --git a/mali/linux/mali_ukk_profiling.c b/mali/linux/mali_ukk_profiling.c index 35f916d..1c82611 100755 --- a/mali/linux/mali_ukk_profiling.c +++ b/mali/linux/mali_ukk_profiling.c @@ -8,7 +8,13 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include /* file system operations */ -#include /* user space access */ +#include + +#if LINUX_VERSION_CODE >= KERNEL_VERSION(4,12,0) +#include +#else +#include +#endif #include #include "mali_ukk.h" diff --git a/mali/linux/mali_ukk_soft_job.c b/mali/linux/mali_ukk_soft_job.c index beeb753..5d700ea 100755 --- a/mali/linux/mali_ukk_soft_job.c +++ b/mali/linux/mali_ukk_soft_job.c @@ -8,7 +8,13 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include /* file system operations */ -#include /* user space access */ +#include + +#if LINUX_VERSION_CODE >= KERNEL_VERSION(4,12,0) +#include +#else +#include +#endif #include "mali_ukk.h" #include "mali_osk.h" diff --git a/mali/linux/mali_ukk_timeline.c b/mali/linux/mali_ukk_timeline.c index 76775b5..8670d04 100755 --- a/mali/linux/mali_ukk_timeline.c +++ b/mali/linux/mali_ukk_timeline.c @@ -8,7 +8,13 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include /* file system operations */ -#include /* user space access */ +#include + +#if LINUX_VERSION_CODE >= KERNEL_VERSION(4,12,0) +#include +#else +#include +#endif #include "mali_ukk.h" #include "mali_osk.h" diff --git a/mali/linux/mali_ukk_vsync.c b/mali/linux/mali_ukk_vsync.c index 5b54fb9..e3f1d32 100755 --- a/mali/linux/mali_ukk_vsync.c +++ b/mali/linux/mali_ukk_vsync.c @@ -8,7 +8,13 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include /* file system operations */ -#include /* user space access */ +#include + +#if LINUX_VERSION_CODE >= KERNEL_VERSION(4,12,0) +#include +#else +#include +#endif #include "mali_ukk.h" #include "mali_osk.h"