video: tegra: host: rewrite nvhost_job_pin/unpin APIs
Mayuresh Kulkarni [Mon, 9 Apr 2012 06:51:24 +0000 (11:51 +0530)]
- remove usage of custom interface of nvmap to patch the relocs and
  and pin the gathers/relocs
- convert code that references nvmap_handle to nvmap_handle_ref
- add logic to pin and map only unique gathers and relocs
- rename nvhost_channel_gather to nvhost_job_gather, because it's
  used in nvhost_job code only

Bug 965206

Change-Id: Iaa7fbac9e4a7b08c0a7c1e184b8dd3566e1edfe2
Signed-off-by: Mayuresh Kulkarni <mkulkarni@nvidia.com>
Signed-off-by: Terje Bergstrom <tbergstrom@nvidia.com>
Reviewed-on: http://git-master/r/95299
Reviewed-by: Automatic_Commit_Validation_User
Reviewed-by: Juha Tukkinen <jtukkinen@nvidia.com>

14 files changed:
drivers/video/tegra/host/bus_client.c
drivers/video/tegra/host/chip_support.h
drivers/video/tegra/host/gr3d/gr3d_t20.c
drivers/video/tegra/host/gr3d/gr3d_t30.c
drivers/video/tegra/host/host1x/host1x_cdma.c
drivers/video/tegra/host/host1x/host1x_channel.c
drivers/video/tegra/host/host1x/host1x_debug.c
drivers/video/tegra/host/mpe/mpe.c
drivers/video/tegra/host/nvhost_cdma.c
drivers/video/tegra/host/nvhost_cdma.h
drivers/video/tegra/host/nvhost_channel.h
drivers/video/tegra/host/nvhost_job.c
drivers/video/tegra/host/nvhost_job.h
include/trace/events/nvhost.h

index fd632a6..822f8f3 100644 (file)
@@ -166,7 +166,7 @@ static int set_submit(struct nvhost_channel_userctx *ctx)
                return -EFAULT;
        }
 
-       ctx->job = nvhost_job_realloc(ctx->job,
+       ctx->job = nvhost_job_alloc(ctx->ch,
                        ctx->hwctx,
                        &ctx->hdr,
                        ctx->nvmap,
@@ -241,13 +241,17 @@ static ssize_t nvhost_channelwrite(struct file *filp, const char __user *buf,
                        consumed = sizeof(struct nvhost_reloc);
                        if (remaining < consumed)
                                break;
-                       if (copy_from_user(&job->pinarray[job->num_pins],
+                       if (copy_from_user(&job->pinarray[job->num_relocs],
                                        buf, consumed)) {
                                err = -EFAULT;
                                break;
                        }
-                       trace_nvhost_channel_write_reloc(chname);
-                       job->num_pins++;
+                       trace_nvhost_channel_write_reloc(chname,
+                               job->pinarray[job->num_relocs].patch_mem,
+                               job->pinarray[job->num_relocs].patch_offset,
+                               job->pinarray[job->num_relocs].pin_mem,
+                               job->pinarray[job->num_relocs].pin_offset);
+                       job->num_relocs++;
                        hdr->num_relocs--;
                } else if (hdr->num_waitchks) {
                        int numwaitchks =
@@ -269,7 +273,7 @@ static ssize_t nvhost_channelwrite(struct file *filp, const char __user *buf,
                        hdr->num_waitchks -= numwaitchks;
                } else if (priv->num_relocshifts) {
                        int next_shift =
-                               job->num_pins - priv->num_relocshifts;
+                               job->num_relocs - priv->num_relocshifts;
                        consumed = sizeof(struct nvhost_reloc_shift);
                        if (remaining < consumed)
                                break;
@@ -337,6 +341,9 @@ static int nvhost_ioctl_channel_flush(
        if (err)
                nvhost_job_unpin(ctx->job);
 
+       nvhost_job_put(ctx->job);
+       ctx->job = NULL;
+
        return err;
 }
 
index edc5f6a..173a360 100644 (file)
@@ -31,7 +31,7 @@ struct nvhost_syncpt;
 struct nvhost_waitchk;
 struct nvhost_userctx_timeout;
 struct nvhost_channel;
-struct nvmap_handle;
+struct nvmap_handle_ref;
 struct nvmap_client;
 struct nvhost_hwctx;
 struct nvhost_cdma;
@@ -77,7 +77,7 @@ struct nvhost_chip_support {
                void (*destroy)(struct push_buffer *);
                void (*push_to)(struct push_buffer *,
                                struct nvmap_client *,
-                               struct nvmap_handle *,
+                               struct nvmap_handle_ref *,
                                u32 op1, u32 op2);
                void (*pop_from)(struct push_buffer *,
                                 unsigned int slots);
index c0efac0..5645f5b 100644 (file)
@@ -138,7 +138,7 @@ static void save_push_v0(struct nvhost_hwctx *nctx, struct nvhost_cdma *cdma)
 
        nvhost_cdma_push_gather(cdma,
                        nvhost_get_host(nctx->channel->dev)->nvmap,
-                       p->save_buf->handle,
+                       p->save_buf,
                        0,
                        nvhost_opcode_gather(p->save_size),
                        p->save_phys);
index 93d98df..57f4c77 100644 (file)
@@ -145,7 +145,7 @@ static void save_push_v1(struct nvhost_hwctx *nctx, struct nvhost_cdma *cdma)
        /* gather the save buffer */
        nvhost_cdma_push_gather(cdma,
                        nvhost_get_host(nctx->channel->dev)->nvmap,
-                       p->save_buf->handle,
+                       p->save_buf,
                        0,
                        nvhost_opcode_gather(p->save_size),
                        p->save_phys);
index fcb1f05..4569c3d 100644 (file)
@@ -137,7 +137,7 @@ static void push_buffer_destroy(struct push_buffer *pb)
  */
 static void push_buffer_push_to(struct push_buffer *pb,
                struct nvmap_client *client,
-               struct nvmap_handle *handle, u32 op1, u32 op2)
+               struct nvmap_handle_ref *handle, u32 op1, u32 op2)
 {
        u32 cur = pb->cur;
        u32 *p = (u32 *)((u32)pb->mapped + cur);
index 8c4a7a5..0b4d07c 100644 (file)
@@ -143,7 +143,7 @@ static void submit_ctxrestore(struct nvhost_job *job)
        /* Send restore buffer to channel */
        nvhost_cdma_push_gather(&ch->cdma,
                host->nvmap,
-               nvmap_ref_to_handle(ctx->restore),
+               ctx->restore,
                0,
                nvhost_opcode_gather(ctx->restore_size),
                ctx->restore_phys);
@@ -188,7 +188,7 @@ void submit_gathers(struct nvhost_job *job)
                u32 op2 = job->gathers[i].mem;
                nvhost_cdma_push_gather(&job->ch->cdma,
                                job->nvmap,
-                               nvmap_id_to_handle(job->gathers[i].mem_id),
+                               job->gathers[i].ref,
                                job->gathers[i].offset,
                                op1, op2);
        }
index 76483d8..a5574a0 100644 (file)
@@ -169,32 +169,27 @@ static void show_channel_gather(struct output *o, u32 addr,
        struct push_buffer *pb = &cdma->push_buffer;
        u32 cur = addr - pb->phys;
        struct nvmap_client_handle *nvmap = &pb->nvmap[cur/8];
-       struct nvmap_handle_ref ref;
        u32 *map_addr, offset;
        phys_addr_t pin_addr;
        int state, count, i;
 
        if (!nvmap->handle || !nvmap->client
-                       || atomic_read(&nvmap->handle->ref) < 1) {
+                       || atomic_read(&nvmap->handle->handle->ref) < 1) {
                nvhost_debug_output(o, "[already deallocated]\n");
                return;
        }
 
-       /* Create a fake nvmap_handle_ref - nvmap requires it
-        * but accesses only the first field - nvmap_handle */
-       ref.handle = nvmap->handle;
-
-       map_addr = nvmap_mmap(&ref);
+       map_addr = nvmap_mmap(nvmap->handle);
        if (!map_addr) {
                nvhost_debug_output(o, "[could not mmap]\n");
                return;
        }
 
        /* Get base address from nvmap */
-       pin_addr = nvmap_pin(nvmap->client, &ref);
+       pin_addr = nvmap_pin(nvmap->client, nvmap->handle);
        if (IS_ERR_VALUE(pin_addr)) {
                nvhost_debug_output(o, "[couldn't pin]\n");
-               nvmap_munmap(&ref, map_addr);
+               nvmap_munmap(nvmap->handle, map_addr);
                return;
        }
 
@@ -215,8 +210,8 @@ static void show_channel_gather(struct output *o, u32 addr,
                                        *(map_addr + offset/4 + i),
                                        cdma);
        }
-       nvmap_unpin(nvmap->client, &ref);
-       nvmap_munmap(&ref, map_addr);
+       nvmap_unpin(nvmap->client, nvmap->handle);
+       nvmap_munmap(nvmap->handle, map_addr);
 #endif
 }
 
index d8c9da7..3fe2fcd 100644 (file)
@@ -502,7 +502,7 @@ static void ctxmpe_save_push(struct nvhost_hwctx *nctx,
        struct host1x_hwctx_handler *h = host1x_hwctx_handler(ctx);
        nvhost_cdma_push_gather(cdma,
                        nvhost_get_host(nctx->channel->dev)->nvmap,
-                       h->save_buf->handle,
+                       h->save_buf,
                        0,
                        nvhost_opcode_gather(h->save_size),
                        h->save_phys);
index a72e18f..b1f1383 100644 (file)
@@ -371,15 +371,13 @@ int nvhost_cdma_begin(struct nvhost_cdma *cdma, struct nvhost_job *job)
 }
 
 static void trace_write_gather(struct nvhost_cdma *cdma,
-               struct nvmap_handle *handle,
+               struct nvmap_handle_ref *ref,
                u32 offset, u32 words)
 {
-       struct nvmap_handle_ref ref;
        void *mem = NULL;
 
        if (nvhost_debug_trace_cmdbuf) {
-               ref.handle = handle;
-               mem = nvmap_mmap(&ref);
+               mem = nvmap_mmap(ref);
                if (IS_ERR_OR_NULL(mem))
                        mem = NULL;
        };
@@ -393,12 +391,12 @@ static void trace_write_gather(struct nvhost_cdma *cdma,
                for (i = 0; i < words; i += TRACE_MAX_LENGTH) {
                        trace_nvhost_cdma_push_gather(
                                cdma_to_channel(cdma)->dev->name,
-                               (u32)handle,
+                               (u32)ref->handle,
                                min(words - i, TRACE_MAX_LENGTH),
                                offset + i * sizeof(u32),
                                mem);
                }
-               nvmap_munmap(&ref, mem);
+               nvmap_munmap(ref, mem);
        }
 }
 
@@ -421,7 +419,7 @@ void nvhost_cdma_push(struct nvhost_cdma *cdma, u32 op1, u32 op2)
  */
 void nvhost_cdma_push_gather(struct nvhost_cdma *cdma,
                struct nvmap_client *client,
-               struct nvmap_handle *handle,
+               struct nvmap_handle_ref *handle,
                u32 offset, u32 op1, u32 op2)
 {
        u32 slots_free = cdma->slots_free;
index e6f5117..98393f0 100644 (file)
@@ -48,7 +48,7 @@ struct nvhost_job;
 
 struct nvmap_client_handle {
        struct nvmap_client *client;
-       struct nvmap_handle *handle;
+       struct nvmap_handle_ref *handle;
 };
 
 struct push_buffer {
@@ -113,7 +113,7 @@ int nvhost_cdma_begin(struct nvhost_cdma *cdma, struct nvhost_job *job);
 void   nvhost_cdma_push(struct nvhost_cdma *cdma, u32 op1, u32 op2);
 void   nvhost_cdma_push_gather(struct nvhost_cdma *cdma,
                struct nvmap_client *client,
-               struct nvmap_handle *handle, u32 offset, u32 op1, u32 op2);
+               struct nvmap_handle_ref *handle, u32 offset, u32 op1, u32 op2);
 void   nvhost_cdma_end(struct nvhost_cdma *cdma,
                struct nvhost_job *job);
 void   nvhost_cdma_update(struct nvhost_cdma *cdma);
index eac5173..a8f16f0 100644 (file)
@@ -36,13 +36,6 @@ struct nvhost_device;
 struct nvhost_channel;
 struct nvhost_hwctx;
 
-struct nvhost_channel_gather {
-       u32 words;
-       phys_addr_t mem;
-       u32 mem_id;
-       int offset;
-};
-
 struct nvhost_channel {
        int refcount;
        int chid;
index 71f2ab0..11d6596 100644 (file)
@@ -23,6 +23,7 @@
 #include <linux/err.h>
 #include <linux/vmalloc.h>
 #include <linux/nvmap.h>
+#include <trace/events/nvhost.h>
 #include "nvhost_channel.h"
 #include "nvhost_job.h"
 #include "nvhost_hwctx.h"
 
 static int job_size(struct nvhost_submit_hdr_ext *hdr)
 {
-       int num_pins = hdr ? (hdr->num_relocs + hdr->num_cmdbufs)*2 : 0;
+       int num_relocs = hdr ? hdr->num_relocs : 0;
        int num_waitchks = hdr ? hdr->num_waitchks : 0;
+       int num_cmdbufs = hdr ? hdr->num_cmdbufs : 0;
+       int num_unpins = num_cmdbufs + num_relocs;
 
        return sizeof(struct nvhost_job)
-                       + num_pins * sizeof(struct nvmap_pinarray_elem)
-                       + num_pins * sizeof(struct nvmap_handle *)
-                       + num_waitchks * sizeof(struct nvhost_waitchk);
-}
-
-static int gather_size(int num_cmdbufs)
-{
-       return num_cmdbufs * sizeof(struct nvhost_channel_gather);
-}
-
-static void free_gathers(struct nvhost_job *job)
-{
-       if (job->gathers) {
-               nvmap_munmap(job->gather_mem, job->gathers);
-               job->gathers = NULL;
-       }
-       if (job->gather_mem) {
-               nvmap_free(job->nvmap, job->gather_mem);
-               job->gather_mem = NULL;
-       }
-}
-
-static int alloc_gathers(struct nvhost_job *job,
-               int num_cmdbufs)
-{
-       int err = 0;
-
-       job->gather_mem = NULL;
-       job->gathers = NULL;
-       job->gather_mem_size = 0;
-
-       if (num_cmdbufs) {
-               /* Allocate memory */
-               job->gather_mem = nvmap_alloc(job->nvmap,
-                               gather_size(num_cmdbufs),
-                               32, NVMAP_HANDLE_CACHEABLE, 0);
-               if (IS_ERR_OR_NULL(job->gather_mem)) {
-                       err = job->gather_mem ? PTR_ERR(job->gather_mem) : -ENOMEM;
-                       job->gather_mem = NULL;
-                       goto error;
-               }
-               job->gather_mem_size = gather_size(num_cmdbufs);
-
-               /* Map memory to kernel */
-               job->gathers = nvmap_mmap(job->gather_mem);
-               if (IS_ERR_OR_NULL(job->gathers)) {
-                       err = job->gathers ? PTR_ERR(job->gathers) : -ENOMEM;
-                       job->gathers = NULL;
-                       goto error;
-               }
-       }
-
-       return 0;
-
-error:
-       free_gathers(job);
-       return err;
-}
-
-static int realloc_gathers(struct nvhost_job *oldjob,
-               struct nvhost_job *newjob,
-               int num_cmdbufs)
-{
-       int err = 0;
-
-       /* Check if we can reuse gather buffer */
-       if (oldjob->gather_mem_size < gather_size(num_cmdbufs)
-                       || oldjob->nvmap != newjob->nvmap) {
-               free_gathers(oldjob);
-               err = alloc_gathers(newjob, num_cmdbufs);
-       } else {
-               newjob->gather_mem = oldjob->gather_mem;
-               newjob->gathers = oldjob->gathers;
-               newjob->gather_mem_size = oldjob->gather_mem_size;
-
-               oldjob->gather_mem = NULL;
-               oldjob->gathers = NULL;
-               oldjob->gather_mem_size = 0;
-       }
-       return err;
+                       + num_relocs * sizeof(struct nvmap_pinarray_elem)
+                       + num_unpins * sizeof(struct nvmap_handle_ref *)
+                       + num_waitchks * sizeof(struct nvhost_waitchk)
+                       + num_cmdbufs * sizeof(struct nvhost_job_gather);
 }
 
 static void init_fields(struct nvhost_job *job,
                struct nvhost_submit_hdr_ext *hdr,
                int priority, int clientid)
 {
-       int num_pins = hdr ? (hdr->num_relocs + hdr->num_cmdbufs)*2 : 0;
+       int num_relocs = hdr ? hdr->num_relocs : 0;
        int num_waitchks = hdr ? hdr->num_waitchks : 0;
+       int num_cmdbufs = hdr ? hdr->num_cmdbufs : 0;
+       int num_unpins = num_cmdbufs + num_relocs;
        void *mem = job;
 
        /* First init state to zero */
-       job->num_gathers = 0;
-       job->num_pins = 0;
-       job->num_unpins = 0;
-       job->num_waitchk = 0;
-       job->waitchk_mask = 0;
-       job->syncpt_id = 0;
-       job->syncpt_incrs = 0;
-       job->syncpt_end = 0;
        job->priority = priority;
        job->clientid = clientid;
-       job->null_kickoff = false;
-       job->first_get = 0;
-       job->num_slots = 0;
 
        /* Redistribute memory to the structs */
        mem += sizeof(struct nvhost_job);
-       if (num_pins) {
-               job->pinarray = mem;
-               mem += num_pins * sizeof(struct nvmap_pinarray_elem);
-               job->unpins = mem;
-               mem += num_pins * sizeof(struct nvmap_handle *);
-       } else {
-               job->pinarray = NULL;
-               job->unpins = NULL;
-       }
-
+       job->pinarray = num_relocs ? mem : NULL;
+       mem += num_relocs * sizeof(struct nvmap_pinarray_elem);
+       job->unpins = num_unpins ? mem : NULL;
+       mem += num_unpins * sizeof(struct nvmap_handle_ref *);
        job->waitchk = num_waitchks ? mem : NULL;
+       mem += num_waitchks * sizeof(struct nvhost_waitchk);
+       job->gathers = num_cmdbufs ? mem : NULL;
 
        /* Copy information from header */
        if (hdr) {
@@ -172,8 +86,6 @@ struct nvhost_job *nvhost_job_alloc(struct nvhost_channel *ch,
                int clientid)
 {
        struct nvhost_job *job = NULL;
-       int num_cmdbufs = hdr ? hdr->num_cmdbufs : 0;
-       int err = 0;
 
        job = vzalloc(job_size(hdr));
        if (!job)
@@ -186,10 +98,6 @@ struct nvhost_job *nvhost_job_alloc(struct nvhost_channel *ch,
                hwctx->h->get(hwctx);
        job->nvmap = nvmap ? nvmap_client_get(nvmap) : NULL;
 
-       err = alloc_gathers(job, num_cmdbufs);
-       if (err)
-               goto error;
-
        init_fields(job, hdr, priority, clientid);
 
        return job;
@@ -200,46 +108,6 @@ error:
        return NULL;
 }
 
-struct nvhost_job *nvhost_job_realloc(
-               struct nvhost_job *oldjob,
-               struct nvhost_hwctx *hwctx,
-               struct nvhost_submit_hdr_ext *hdr,
-               struct nvmap_client *nvmap,
-               int priority, int clientid)
-{
-       struct nvhost_job *newjob = NULL;
-       int num_cmdbufs = hdr ? hdr->num_cmdbufs : 0;
-       int err = 0;
-
-       newjob = vzalloc(job_size(hdr));
-       if (!newjob)
-               goto error;
-       kref_init(&newjob->ref);
-       newjob->ch = oldjob->ch;
-       newjob->hwctx = hwctx;
-       if (hwctx)
-               newjob->hwctx->h->get(newjob->hwctx);
-       newjob->timeout = oldjob->timeout;
-       newjob->nvmap = nvmap ? nvmap_client_get(nvmap) : NULL;
-
-       err = realloc_gathers(oldjob, newjob, num_cmdbufs);
-       if (err)
-               goto error;
-
-       nvhost_job_put(oldjob);
-
-       init_fields(newjob, hdr, priority, clientid);
-
-       return newjob;
-
-error:
-       if (newjob)
-               nvhost_job_put(newjob);
-       if (oldjob)
-               nvhost_job_put(oldjob);
-       return NULL;
-}
-
 void nvhost_job_get(struct nvhost_job *job)
 {
        kref_get(&job->ref);
@@ -253,10 +121,6 @@ static void job_free(struct kref *ref)
                job->hwctxref->h->put(job->hwctxref);
        if (job->hwctx)
                job->hwctx->h->put(job->hwctx);
-       if (job->gathers)
-               nvmap_munmap(job->gather_mem, job->gathers);
-       if (job->gather_mem)
-               nvmap_free(job->nvmap, job->gather_mem);
        if (job->nvmap)
                nvmap_client_put(job->nvmap);
        vfree(job);
@@ -280,42 +144,119 @@ void nvhost_job_put(struct nvhost_job *job)
 void nvhost_job_add_gather(struct nvhost_job *job,
                u32 mem_id, u32 words, u32 offset)
 {
-       struct nvmap_pinarray_elem *pin;
-       struct nvhost_channel_gather *cur_gather =
+       struct nvhost_job_gather *cur_gather =
                        &job->gathers[job->num_gathers];
 
-       pin = &job->pinarray[job->num_pins++];
-       pin->patch_mem = (u32)nvmap_ref_to_handle(job->gather_mem);
-       pin->patch_offset = (void *)&(cur_gather->mem) - (void *)job->gathers;
-       pin->pin_mem = nvmap_convert_handle_u2k(mem_id);
-       pin->pin_offset = offset;
        cur_gather->words = words;
        cur_gather->mem_id = mem_id;
        cur_gather->offset = offset;
        job->num_gathers += 1;
 }
 
-int nvhost_job_pin(struct nvhost_job *job)
+static int do_relocs(struct nvhost_job *job, u32 patch_mem, void *patch_addr)
 {
-       int err = 0;
+       phys_addr_t pin_phys;
+       int i;
+       u32 mem_id = 0;
+       struct nvmap_handle_ref *pin_ref = NULL;
+
+       /* pin & patch the relocs for one gather */
+       for (i = 0; i < job->num_relocs; i++) {
+               struct nvmap_pinarray_elem *pin = &job->pinarray[i];
+
+               /* skip all other gathers */
+               if (patch_mem != pin->patch_mem)
+                       continue;
+
+               /* check if pin-mem is same as previous */
+               if (pin->pin_mem != mem_id) {
+                       pin_ref = nvmap_duplicate_handle_id(job->nvmap,
+                                       pin->pin_mem);
+                       if (IS_ERR(pin_ref))
+                               return PTR_ERR(pin_ref);
+
+                       pin_phys = nvmap_pin(job->nvmap, pin_ref);
+                       if (IS_ERR((void *)pin_phys)) {
+                               nvmap_free(job->nvmap, pin_ref);
+                               return pin_phys;
+                       }
+
+                       mem_id = pin->pin_mem;
+                       job->unpins[job->num_unpins++] = pin_ref;
+               }
+
+               __raw_writel((pin_phys + pin->pin_offset) >> pin->reloc_shift,
+                               (patch_addr + pin->patch_offset));
+
+               /* Different gathers might have same mem_id. This ensures we
+                * perform reloc only once per gather memid. */
+               pin->patch_mem = 0;
+       }
+
+       return 0;
+}
 
-       /* pin mem handles and patch physical addresses */
-       job->num_unpins = nvmap_pin_array(job->nvmap,
-                               nvmap_ref_to_handle(job->gather_mem),
-                               job->pinarray, job->num_pins,
-                               job->unpins);
-       if (job->num_unpins < 0)
-               err = job->num_unpins;
+int nvhost_job_pin(struct nvhost_job *job)
+{
+       int err = 0, i = 0;
+       phys_addr_t gather_phys = 0;
+       void *gather_addr = NULL;
+
+       /* pin gathers */
+       for (i = 0; i < job->num_gathers; i++) {
+               struct nvhost_job_gather *g = &job->gathers[i];
+
+               /* process each gather mem only once */
+               if (!g->ref) {
+                       g->ref = nvmap_duplicate_handle_id(job->nvmap,
+                                       job->gathers[i].mem_id);
+                       if (IS_ERR(g->ref)) {
+                               err = PTR_ERR(g->ref);
+                               g->ref = NULL;
+                               break;
+                       }
+
+                       gather_phys = nvmap_pin(job->nvmap, g->ref);
+                       if (IS_ERR((void *)gather_phys)) {
+                               nvmap_free(job->nvmap, g->ref);
+                               err = gather_phys;
+                               break;
+                       }
+
+                       /* store the gather ref into unpin array */
+                       job->unpins[job->num_unpins++] = g->ref;
+
+                       gather_addr = nvmap_mmap(g->ref);
+                       if (!gather_addr) {
+                               err = -ENOMEM;
+                               break;
+                       }
+
+                       err = do_relocs(job, g->mem_id, gather_addr);
+                       nvmap_munmap(g->ref, gather_addr);
+
+                       if (err)
+                               break;
+               }
+               g->mem = gather_phys + g->offset;
+       }
+       wmb();
 
        return err;
 }
 
 void nvhost_job_unpin(struct nvhost_job *job)
 {
-       nvmap_unpin_handles(job->nvmap, job->unpins,
-                       job->num_unpins);
+       int i;
+
+       for (i = 0; i < job->num_unpins; i++) {
+               nvmap_unpin(job->nvmap, job->unpins[i]);
+               nvmap_free(job->nvmap, job->unpins[i]);
+       }
+
        memset(job->unpins, BAD_MAGIC,
-                       job->num_unpins * sizeof(struct nvmap_handle *));
+                       job->num_unpins * sizeof(struct nvmap_handle_ref *));
+       job->num_unpins = 0;
 }
 
 /**
index ad9d1af..48555a2 100644 (file)
@@ -29,6 +29,14 @@ struct nvmap_client;
 struct nvhost_waitchk;
 struct nvmap_handle;
 
+struct nvhost_job_gather {
+       u32 words;
+       phys_addr_t mem;
+       u32 mem_id;
+       int offset;
+       struct nvmap_handle_ref *ref;
+};
+
 /*
  * Each submit is tracked as a nvhost_job.
  */
@@ -50,10 +58,8 @@ struct nvhost_job {
        struct nvmap_client *nvmap;
 
        /* Gathers and their memory */
-       struct nvmap_handle_ref *gather_mem;
-       struct nvhost_channel_gather *gathers;
+       struct nvhost_job_gather *gathers;
        int num_gathers;
-       int gather_mem_size;
 
        /* Wait checks to be processed at submit time */
        struct nvhost_waitchk *waitchk;
@@ -62,8 +68,8 @@ struct nvhost_job {
 
        /* Array of handles to be pinned & unpinned */
        struct nvmap_pinarray_elem *pinarray;
-       int num_pins;
-       struct nvmap_handle **unpins;
+       int num_relocs;
+       struct nvmap_handle_ref **unpins;
        int num_unpins;
 
        /* Sync point id, number of increments and end related to the submit */
@@ -99,17 +105,6 @@ struct nvhost_job *nvhost_job_alloc(struct nvhost_channel *ch,
                int priority, int clientid);
 
 /*
- * Allocate memory for a job. Just enough memory will be allocated to
- * accomodate the submit announced in submit header. Gather memory from
- * oldjob will be reused, and nvhost_job_put() will be called to it.
- */
-struct nvhost_job *nvhost_job_realloc(struct nvhost_job *oldjob,
-               struct nvhost_hwctx *hwctx,
-               struct nvhost_submit_hdr_ext *hdr,
-               struct nvmap_client *nvmap,
-               int priority, int clientid);
-
-/*
  * Add a gather to a job.
  */
 void nvhost_job_add_gather(struct nvhost_job *job,
index 4bb79e3..6358fed 100644 (file)
@@ -194,20 +194,30 @@ TRACE_EVENT(nvhost_cdma_push_gather,
 );
 
 TRACE_EVENT(nvhost_channel_write_reloc,
-       TP_PROTO(const char *name),
+       TP_PROTO(const char *name, u32 cmdbuf_mem, u32 cmdbuf_offset,
+               u32 target, u32 target_offset),
 
-       TP_ARGS(name),
+       TP_ARGS(name, cmdbuf_mem, cmdbuf_offset, target, target_offset),
 
        TP_STRUCT__entry(
                __field(const char *, name)
+               __field(u32, cmdbuf_mem)
+               __field(u32, cmdbuf_offset)
+               __field(u32, target)
+               __field(u32, target_offset)
        ),
 
        TP_fast_assign(
                __entry->name = name;
+               __entry->cmdbuf_mem = cmdbuf_mem;
+               __entry->cmdbuf_offset = cmdbuf_offset;
+               __entry->target = target;
+               __entry->target_offset = target_offset;
        ),
 
-       TP_printk("name=%s",
-         __entry->name)
+       TP_printk("name=%s, cmdbuf_mem=%08x, cmdbuf_offset=%04x, target=%08x, target_offset=%04x",
+         __entry->name, __entry->cmdbuf_mem, __entry->cmdbuf_offset,
+         __entry->target, __entry->target_offset)
 );
 
 TRACE_EVENT(nvhost_channel_write_waitchks,