gpu: pvr: pdumpfs: add frame struct and initial frame handling code
authorLuc Verhaegen <libv@codethink.co.uk>
Fri, 11 Mar 2011 14:02:48 +0000 (15:02 +0100)
committerGrazvydas Ignotas <notasas@gmail.com>
Sun, 20 May 2012 18:43:04 +0000 (21:43 +0300)
Now we are tracking frames correctly, but we are not accepting any data
yet. frame_current is the last of frame_stream, and the frame that we
would be writing to.

New frames are created when userspace flags the start of a new frame
with PDumpSetFrameKM. This is also where we deliberately change the
pdump content by adding two comments. One for flagging the end of the
previous frame, one for the start of the new frame.

We keep at most frame_count_max frames around, older frames will be
removed by frame_cull() which gets called when a new frame gets
created.

Signed-off-by: Luc Verhaegen <libv@codethink.co.uk>
Signed-off-by: Imre Deak <imre.deak@nokia.com>
pvr/bridged_pvr_bridge.c
pvr/pvr_pdump.c
pvr/pvr_pdump.h
pvr/pvr_pdumpfs.c
pvr/pvr_pdumpfs.h

index 1028b76..d470bcd 100644 (file)
@@ -1073,9 +1073,8 @@ static int PDumpSetFrameBW(u32 ui32BridgeID,
                struct PVRSRV_PER_PROCESS_DATA *psPerProc)
 {
        PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, PVRSRV_BRIDGE_PDUMP_SETFRAME);
-       PVR_UNREFERENCED_PARAMETER(psPerProc);
 
-       PDumpSetFrameKM(psPDumpSetFrameIN->ui32Frame);
+       PDumpSetFrameKM(psPerProc->ui32PID, psPDumpSetFrameIN->ui32Frame);
 
        psRetOUT->eError = PVRSRV_OK;
 
index c9aa021..6966d01 100644 (file)
@@ -135,12 +135,14 @@ void PDumpCommentWithFlags(u32 ui32Flags, char *pszFormat, ...)
        PDumpCommentKM(gpszComment, ui32Flags);
 }
 
-void PDumpSetFrameKM(u32 ui32Frame)
+void PDumpSetFrameKM(u32 ui32PID, u32 ui32Frame)
 {
        if (PDumpSuspended())
                return;
 
-       pdumpfs_frame_set(ui32Frame);
+       PDumpComment("Ending current Frame\r\n");
+       pdumpfs_frame_set(ui32PID, ui32Frame);
+       PDumpComment("PID %d: Starting Frame %d\r\n", ui32PID, ui32Frame);
 }
 
 IMG_BOOL PDumpIsCaptureFrameKM(void)
index 895e698..6fbf4f4 100644 (file)
@@ -64,7 +64,7 @@ enum PVRSRV_ERROR PDumpPageTableKM(void *pvLinAddr, u32 ui32Bytes,
                                   void *hUniqueTag1, void *hUniqueTag2);
 void PDumpInit(void);
 void PDumpDeInit(void);
-void PDumpSetFrameKM(u32 ui32Frame);
+void PDumpSetFrameKM(u32 ui32PID, u32 ui32Frame);
 void PDumpCommentKM(char *pszComment, u32 ui32Flags);
 void PDumpRegWithFlagsKM(u32 ui32RegAddr, u32 ui32RegValue,
                         u32 ui32Flags);
index c5400f8..b642ac1 100644 (file)
@@ -43,14 +43,99 @@ static enum pdumpfs_mode pdumpfs_mode =
 #endif
        ;
 
-static u32 pdumpfs_frame_number;
+struct pdumpfs_frame {
+       struct pdumpfs_frame *next;
+
+       u32 pid;
+       u32 number;
+};
+
+static u32 frame_count_max = 16;
+static u32 frame_count;
+
+static struct pdumpfs_frame *frame_stream;
+static struct pdumpfs_frame *frame_current;
+
+static struct pdumpfs_frame *
+frame_create(void)
+{
+       struct pdumpfs_frame *frame =
+               kmalloc(sizeof(struct pdumpfs_frame), GFP_KERNEL);
+       if (!frame)
+               return NULL;
+
+       memset(frame, 0, sizeof(struct pdumpfs_frame));
+
+       return frame;
+}
+
+static void
+frame_destroy(struct pdumpfs_frame *frame)
+{
+       if (!frame)
+               return;
+
+       kfree(frame);
+}
+
+static void
+frame_destroy_all(void)
+{
+       frame_current = NULL;
+
+       while (frame_stream) {
+               struct pdumpfs_frame *frame = frame_stream;
+
+               frame_stream = frame->next;
+
+               frame_destroy(frame);
+               frame_count--;
+       }
+}
+
+static void
+frame_cull(void)
+{
+       while (frame_count > frame_count_max) {
+               struct pdumpfs_frame *frame = frame_stream;
+
+               frame_stream = frame->next;
+               frame->next = NULL;
+
+               frame_destroy(frame);
+               frame_count--;
+       }
+}
+
+static int
+frame_new(u32 pid, u32 number)
+{
+       struct pdumpfs_frame *frame = frame_create();
+
+       if (!frame) {
+               pr_err("%s: Failed to create frame.\n", __func__);
+               return -ENOMEM;
+       }
+
+       frame->pid = pid;
+       frame->number = number;
+
+       if (frame_current)
+               frame_current->next = frame;
+       frame_current = frame;
+       frame_count++;
+
+       frame_cull();
+
+       return 0;
+}
 
 void
-pdumpfs_frame_set(u32 frame)
+pdumpfs_frame_set(u32 pid, u32 frame)
 {
        mutex_lock(pdumpfs_mutex);
 
-       pdumpfs_frame_number = frame;
+       frame_new(pid, frame);
 
        mutex_unlock(pdumpfs_mutex);
 }
@@ -289,8 +374,14 @@ pdumpfs_fs_destroy(void)
 int
 pdumpfs_init(void)
 {
+       int ret;
+
        mutex_init(pdumpfs_mutex);
 
+       ret = frame_new(0, 0);
+       if (ret < 0)
+               return ret;
+
        pdumpfs_fs_init();
 
        return 0;
@@ -300,4 +391,6 @@ void
 pdumpfs_cleanup(void)
 {
        pdumpfs_fs_destroy();
+
+       frame_destroy_all();
 }
index 714f2db..76afd43 100644 (file)
@@ -19,7 +19,7 @@
 #ifndef _PVR_PDUMPFS_H_
 #define _PVR_PDUMPFS_H_
 
-void pdumpfs_frame_set(u32 frame);
+void pdumpfs_frame_set(u32 pid, u32 frame);
 bool pdumpfs_capture_enabled(void);
 bool pdumpfs_flags_check(u32 flags);
 enum PVRSRV_ERROR pdumpfs_write_data(void *buffer, size_t size, bool from_user);