Loading drivers/gpu/msm/kgsl_drawobj.c +27 −16 Original line number Original line Diff line number Diff line /* Copyright (c) 2016-2017, The Linux Foundation. All rights reserved. /* Copyright (c) 2016-2017,2019, The Linux Foundation. All rights reserved. * * * This program is free software; you can redistribute it and/or modify * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and * it under the terms of the GNU General Public License version 2 and Loading Loading @@ -173,8 +173,11 @@ static void syncobj_timer(unsigned long data) /* /* * a generic function to retire a pending sync event and (possibly) * a generic function to retire a pending sync event and (possibly) * kick the dispatcher * kick the dispatcher * Returns false if the event was already marked for cancellation in another * thread. This function should return true if this thread is responsible for * freeing up the memory, and the event will not be cancelled. */ */ static void drawobj_sync_expire(struct kgsl_device *device, static bool drawobj_sync_expire(struct kgsl_device *device, struct kgsl_drawobj_sync_event *event) struct kgsl_drawobj_sync_event *event) { { struct kgsl_drawobj_sync *syncobj = event->syncobj; struct kgsl_drawobj_sync *syncobj = event->syncobj; Loading @@ -183,7 +186,7 @@ static void drawobj_sync_expire(struct kgsl_device *device, * leave without doing anything useful * leave without doing anything useful */ */ if (!test_and_clear_bit(event->id, &syncobj->pending)) if (!test_and_clear_bit(event->id, &syncobj->pending)) return; return false; /* /* * If no more pending events, delete the timer and schedule the command * If no more pending events, delete the timer and schedule the command Loading @@ -196,6 +199,7 @@ static void drawobj_sync_expire(struct kgsl_device *device, device->ftbl->drawctxt_sched(device, device->ftbl->drawctxt_sched(device, event->syncobj->base.context); event->syncobj->base.context); } } return true; } } /* /* Loading @@ -210,8 +214,13 @@ static void drawobj_sync_func(struct kgsl_device *device, trace_syncpoint_timestamp_expire(event->syncobj, trace_syncpoint_timestamp_expire(event->syncobj, event->context, event->timestamp); event->context, event->timestamp); drawobj_sync_expire(device, event); /* * Put down the context ref count only if * this thread successfully clears the pending bit mask. */ if (drawobj_sync_expire(device, event)) kgsl_context_put(event->context); kgsl_context_put(event->context); drawobj_put(&event->syncobj->base); drawobj_put(&event->syncobj->base); } } Loading Loading @@ -241,19 +250,12 @@ static void drawobj_destroy_sparse(struct kgsl_drawobj *drawobj) static void drawobj_destroy_sync(struct kgsl_drawobj *drawobj) static void drawobj_destroy_sync(struct kgsl_drawobj *drawobj) { { struct kgsl_drawobj_sync *syncobj = SYNCOBJ(drawobj); struct kgsl_drawobj_sync *syncobj = SYNCOBJ(drawobj); unsigned long pending, flags; unsigned long flags; unsigned int i; unsigned int i; /* Zap the canary timer */ /* Zap the canary timer */ del_timer_sync(&syncobj->timer); del_timer_sync(&syncobj->timer); /* * Copy off the pending list and clear all pending events - this will * render any subsequent asynchronous callback harmless */ bitmap_copy(&pending, &syncobj->pending, KGSL_MAX_SYNCPOINTS); bitmap_zero(&syncobj->pending, KGSL_MAX_SYNCPOINTS); /* /* * Clear all pending events - this will render any subsequent async * Clear all pending events - this will render any subsequent async * callbacks harmless * callbacks harmless Loading @@ -261,8 +263,12 @@ static void drawobj_destroy_sync(struct kgsl_drawobj *drawobj) for (i = 0; i < syncobj->numsyncs; i++) { for (i = 0; i < syncobj->numsyncs; i++) { struct kgsl_drawobj_sync_event *event = &syncobj->synclist[i]; struct kgsl_drawobj_sync_event *event = &syncobj->synclist[i]; /* Don't do anything if the event has already expired */ /* if (!test_bit(i, &pending)) * Don't do anything if the event has already expired. * If this thread clears the pending bit mask then it is * responsible for doing context put. */ if (!test_and_clear_bit(i, &syncobj->pending)) continue; continue; switch (event->type) { switch (event->type) { Loading @@ -270,6 +276,11 @@ static void drawobj_destroy_sync(struct kgsl_drawobj *drawobj) kgsl_cancel_event(drawobj->device, kgsl_cancel_event(drawobj->device, &event->context->events, event->timestamp, &event->context->events, event->timestamp, drawobj_sync_func, event); drawobj_sync_func, event); /* * Do context put here to make sure the context is alive * till this thread cancels kgsl event. */ kgsl_context_put(event->context); break; break; case KGSL_CMD_SYNCPOINT_TYPE_FENCE: case KGSL_CMD_SYNCPOINT_TYPE_FENCE: spin_lock_irqsave(&event->handle_lock, flags); spin_lock_irqsave(&event->handle_lock, flags); Loading @@ -291,7 +302,7 @@ static void drawobj_destroy_sync(struct kgsl_drawobj *drawobj) * If we cancelled an event, there's a good chance that the context is * If we cancelled an event, there's a good chance that the context is * on a dispatcher queue, so schedule to get it removed. * on a dispatcher queue, so schedule to get it removed. */ */ if (!bitmap_empty(&pending, KGSL_MAX_SYNCPOINTS) && if (!bitmap_empty(&syncobj->pending, KGSL_MAX_SYNCPOINTS) && drawobj->device->ftbl->drawctxt_sched) drawobj->device->ftbl->drawctxt_sched) drawobj->device->ftbl->drawctxt_sched(drawobj->device, drawobj->device->ftbl->drawctxt_sched(drawobj->device, drawobj->context); drawobj->context); Loading Loading
drivers/gpu/msm/kgsl_drawobj.c +27 −16 Original line number Original line Diff line number Diff line /* Copyright (c) 2016-2017, The Linux Foundation. All rights reserved. /* Copyright (c) 2016-2017,2019, The Linux Foundation. All rights reserved. * * * This program is free software; you can redistribute it and/or modify * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and * it under the terms of the GNU General Public License version 2 and Loading Loading @@ -173,8 +173,11 @@ static void syncobj_timer(unsigned long data) /* /* * a generic function to retire a pending sync event and (possibly) * a generic function to retire a pending sync event and (possibly) * kick the dispatcher * kick the dispatcher * Returns false if the event was already marked for cancellation in another * thread. This function should return true if this thread is responsible for * freeing up the memory, and the event will not be cancelled. */ */ static void drawobj_sync_expire(struct kgsl_device *device, static bool drawobj_sync_expire(struct kgsl_device *device, struct kgsl_drawobj_sync_event *event) struct kgsl_drawobj_sync_event *event) { { struct kgsl_drawobj_sync *syncobj = event->syncobj; struct kgsl_drawobj_sync *syncobj = event->syncobj; Loading @@ -183,7 +186,7 @@ static void drawobj_sync_expire(struct kgsl_device *device, * leave without doing anything useful * leave without doing anything useful */ */ if (!test_and_clear_bit(event->id, &syncobj->pending)) if (!test_and_clear_bit(event->id, &syncobj->pending)) return; return false; /* /* * If no more pending events, delete the timer and schedule the command * If no more pending events, delete the timer and schedule the command Loading @@ -196,6 +199,7 @@ static void drawobj_sync_expire(struct kgsl_device *device, device->ftbl->drawctxt_sched(device, device->ftbl->drawctxt_sched(device, event->syncobj->base.context); event->syncobj->base.context); } } return true; } } /* /* Loading @@ -210,8 +214,13 @@ static void drawobj_sync_func(struct kgsl_device *device, trace_syncpoint_timestamp_expire(event->syncobj, trace_syncpoint_timestamp_expire(event->syncobj, event->context, event->timestamp); event->context, event->timestamp); drawobj_sync_expire(device, event); /* * Put down the context ref count only if * this thread successfully clears the pending bit mask. */ if (drawobj_sync_expire(device, event)) kgsl_context_put(event->context); kgsl_context_put(event->context); drawobj_put(&event->syncobj->base); drawobj_put(&event->syncobj->base); } } Loading Loading @@ -241,19 +250,12 @@ static void drawobj_destroy_sparse(struct kgsl_drawobj *drawobj) static void drawobj_destroy_sync(struct kgsl_drawobj *drawobj) static void drawobj_destroy_sync(struct kgsl_drawobj *drawobj) { { struct kgsl_drawobj_sync *syncobj = SYNCOBJ(drawobj); struct kgsl_drawobj_sync *syncobj = SYNCOBJ(drawobj); unsigned long pending, flags; unsigned long flags; unsigned int i; unsigned int i; /* Zap the canary timer */ /* Zap the canary timer */ del_timer_sync(&syncobj->timer); del_timer_sync(&syncobj->timer); /* * Copy off the pending list and clear all pending events - this will * render any subsequent asynchronous callback harmless */ bitmap_copy(&pending, &syncobj->pending, KGSL_MAX_SYNCPOINTS); bitmap_zero(&syncobj->pending, KGSL_MAX_SYNCPOINTS); /* /* * Clear all pending events - this will render any subsequent async * Clear all pending events - this will render any subsequent async * callbacks harmless * callbacks harmless Loading @@ -261,8 +263,12 @@ static void drawobj_destroy_sync(struct kgsl_drawobj *drawobj) for (i = 0; i < syncobj->numsyncs; i++) { for (i = 0; i < syncobj->numsyncs; i++) { struct kgsl_drawobj_sync_event *event = &syncobj->synclist[i]; struct kgsl_drawobj_sync_event *event = &syncobj->synclist[i]; /* Don't do anything if the event has already expired */ /* if (!test_bit(i, &pending)) * Don't do anything if the event has already expired. * If this thread clears the pending bit mask then it is * responsible for doing context put. */ if (!test_and_clear_bit(i, &syncobj->pending)) continue; continue; switch (event->type) { switch (event->type) { Loading @@ -270,6 +276,11 @@ static void drawobj_destroy_sync(struct kgsl_drawobj *drawobj) kgsl_cancel_event(drawobj->device, kgsl_cancel_event(drawobj->device, &event->context->events, event->timestamp, &event->context->events, event->timestamp, drawobj_sync_func, event); drawobj_sync_func, event); /* * Do context put here to make sure the context is alive * till this thread cancels kgsl event. */ kgsl_context_put(event->context); break; break; case KGSL_CMD_SYNCPOINT_TYPE_FENCE: case KGSL_CMD_SYNCPOINT_TYPE_FENCE: spin_lock_irqsave(&event->handle_lock, flags); spin_lock_irqsave(&event->handle_lock, flags); Loading @@ -291,7 +302,7 @@ static void drawobj_destroy_sync(struct kgsl_drawobj *drawobj) * If we cancelled an event, there's a good chance that the context is * If we cancelled an event, there's a good chance that the context is * on a dispatcher queue, so schedule to get it removed. * on a dispatcher queue, so schedule to get it removed. */ */ if (!bitmap_empty(&pending, KGSL_MAX_SYNCPOINTS) && if (!bitmap_empty(&syncobj->pending, KGSL_MAX_SYNCPOINTS) && drawobj->device->ftbl->drawctxt_sched) drawobj->device->ftbl->drawctxt_sched) drawobj->device->ftbl->drawctxt_sched(drawobj->device, drawobj->device->ftbl->drawctxt_sched(drawobj->device, drawobj->context); drawobj->context); Loading