From: Luc Verhaegen Date: Fri, 11 Mar 2011 14:02:52 +0000 (+0100) Subject: gpu: pvr: pdumpfs: add debugfs entries for the current frame X-Git-Url: http://git.openpandora.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=99064a20d8967518cf3d1a370cfe62c4952037f3;p=sgx.git gpu: pvr: pdumpfs: add debugfs entries for the current frame We keep another pointer to the current_frame around, so that the data in our debugfs files is predictable. Signed-off-by: Luc Verhaegen Signed-off-by: Imre Deak --- diff --git a/pvr/pvr_pdumpfs.c b/pvr/pvr_pdumpfs.c index 60cb726..931319d 100644 --- a/pvr/pvr_pdumpfs.c +++ b/pvr/pvr_pdumpfs.c @@ -63,6 +63,9 @@ static struct pdumpfs_frame *frame_init; static struct pdumpfs_frame *frame_stream; static struct pdumpfs_frame *frame_current; +static struct pdumpfs_frame *frame_current_debugfs; +static int frame_current_open_count; + static struct pdumpfs_frame * frame_create(void) { @@ -93,11 +96,21 @@ frame_destroy(struct pdumpfs_frame *frame) static void frame_destroy_all(void) { + /* detach from possible clones */ + if (frame_current_debugfs && + ((frame_current_debugfs == frame_init) || + (frame_current_debugfs == frame_current) || + frame_current_debugfs->next)) + frame_current_debugfs = NULL; + frame_current = NULL; frame_destroy(frame_init); frame_init = NULL; + frame_destroy(frame_current_debugfs); + frame_current_debugfs = NULL; + while (frame_stream) { struct pdumpfs_frame *frame = frame_stream; @@ -117,7 +130,13 @@ frame_cull(void) frame_stream = frame->next; frame->next = NULL; - frame_destroy(frame); + /* + * we cannot have frames vanish in the middle of reading + * them through debugfs + */ + if (frame != frame_current_debugfs) + frame_destroy(frame); + frame_count--; } } @@ -602,6 +621,85 @@ static const struct file_operations pdumpfs_init_fops = { .read = pdumpfs_init_read, }; +/* + * We need to make sure that our frame doesn't vanish while we are still + * reading it: so reference this frame again. + */ +static int +pdumpfs_current_open(struct inode *inode, struct file *filp) +{ + mutex_lock(pdumpfs_mutex); + + if (!frame_current_open_count) + frame_current_debugfs = frame_current; + + frame_current_open_count++; + + mutex_unlock(pdumpfs_mutex); + return 0; +} + +static int +pdumpfs_current_release(struct inode *inode, struct file *filp) +{ + mutex_lock(pdumpfs_mutex); + + frame_current_open_count--; + + if (!frame_current_open_count) { + if ((frame_current_debugfs != frame_init) && + (frame_current_debugfs != frame_current) && + !frame_current_debugfs->next) + frame_destroy(frame_current_debugfs); + frame_current_debugfs = NULL; + } + + mutex_unlock(pdumpfs_mutex); + return 0; +} + +static loff_t +pdumpfs_current_llseek(struct file *filp, loff_t offset, int whence) +{ + loff_t f_pos; + + mutex_lock(pdumpfs_mutex); + + f_pos = pdumpfs_llseek_helper(filp, offset, whence, + frame_current_debugfs->offset); + + mutex_unlock(pdumpfs_mutex); + + return f_pos; +} + +static ssize_t +pdumpfs_current_read(struct file *filp, char __user *buf, size_t size, + loff_t *f_pos) +{ + mutex_lock(pdumpfs_mutex); + + if (frame_current_debugfs->offset) + size = pdumpfs_frame_read_single(frame_current_debugfs, + buf, size, *f_pos); + else + size = 0; + + mutex_unlock(pdumpfs_mutex); + + if (size > 0) + *f_pos += size; + return size; +} + +static const struct file_operations pdumpfs_current_fops = { + .owner = THIS_MODULE, + .llseek = pdumpfs_current_llseek, + .read = pdumpfs_current_read, + .open = pdumpfs_current_open, + .release = pdumpfs_current_release, +}; + static struct dentry *pdumpfs_dir; static void @@ -641,6 +739,8 @@ pdumpfs_fs_init(void) pdumpfs_file_create("init_frame", S_IRUSR, &pdumpfs_init_fops); + pdumpfs_file_create("current_frame", S_IRUSR, + &pdumpfs_current_fops); return 0; }