nvadsp: adspff: fix issues with kthread impl

- Implement file list rather than fixed length array
- Fix issues related to file mode handling
- Change file not found validation with respect to commit c136844cd414
  ("nvadsp: adspff: use kthread to schedule file io")

Bug 2538512

Change-Id: I1cd8fa065887effa6073d963df62f6e1bb877a1d
Signed-off-by: Niranjan Dighe <ndighe@nvidia.com>
Reviewed-on: https://git-master.nvidia.com/r/2102696
(cherry picked from commit ea7d4ea78a22b7d8675966f2b2f85343c488d059)
Reviewed-on: https://git-master.nvidia.com/r/2150780
Tested-by: Hariharan Sivaraman <hariharans@nvidia.com>
Reviewed-by: Automatic_Commit_Validation_User
GVS: Gerrit_Virtual_Submit
Reviewed-by: Nitin Pai <npai@nvidia.com>
Reviewed-by: mobile promotions <svcmobile_promotions@nvidia.com>
Tested-by: mobile promotions <svcmobile_promotions@nvidia.com>
This commit is contained in:
Niranjan Dighe
2019-04-22 19:59:17 +05:30
committed by Laxman Dewangan
parent b82520e6d3
commit 8916271137
2 changed files with 38 additions and 20 deletions

View File

@@ -26,6 +26,7 @@
#include <linux/semaphore.h> #include <linux/semaphore.h>
#include <linux/debugfs.h> #include <linux/debugfs.h>
#include <linux/platform_device.h> #include <linux/platform_device.h>
#include <linux/list.h>
#include <linux/tegra_nvadsp.h> #include <linux/tegra_nvadsp.h>
@@ -33,7 +34,7 @@
#include "dev.h" #include "dev.h"
#define ADSPFF_MAX_OPEN_FILES (4) #define ADSPFF_MAX_OPEN_FILES (32)
struct file_struct { struct file_struct {
struct file *fp; struct file *fp;
@@ -41,11 +42,12 @@ struct file_struct {
unsigned int flags; unsigned int flags;
unsigned long long wr_offset; unsigned long long wr_offset;
unsigned long long rd_offset; unsigned long long rd_offset;
struct list_head list;
}; };
static struct file_struct adspff_open_files[ADSPFF_MAX_OPEN_FILES]; static struct list_head file_list;
static spinlock_t adspff_lock; static spinlock_t adspff_lock;
static int open_count;
/****************************************************************************** /******************************************************************************
* Kernel file functions * Kernel file functions
@@ -162,31 +164,40 @@ void set_flags(union adspff_message_t *m, unsigned int *flags)
/* /*
* checks if file is already opened * checks if file is already opened
* if yes, then returns the struct file_struct for the file * if yes, then returns the struct file_struct for the file
* if no, thgen returns first available struct file_struct * if no, then allocates a file_struct and adds to the list
* if ADSPFF_MAX_OPEN_FILES alreadu open, returns NULL * and returns the pointer to the newly allocated file_struct
* if ADSPFF_MAX_OPEN_FILES already open, returns NULL
*/ */
static struct file_struct *check_file_opened(const char *path) static struct file_struct *check_file_opened(const char *path)
{ {
struct file_struct *file; struct file_struct *file = NULL;
int idx; struct list_head *pos;
/* assuming files opened by ADSP will /* assuming files opened by ADSP will
* never be actually closed in kernel * never be actually closed in kernel
*/ */
for (idx = 0; idx < ADSPFF_MAX_OPEN_FILES; idx++) { list_for_each(pos, &file_list) {
file = &adspff_open_files[idx]; file = list_entry(pos, struct file_struct, list);
if (!file->fp) if (!file->fp)
break; break;
if (!strncmp(path, file->file_name, if (!strncmp(path, file->file_name,
ADSPFF_MAX_FILENAME_SIZE)) { ADSPFF_MAX_FILENAME_SIZE)) {
break; break;
} }
file = NULL;
} }
if (idx == ADSPFF_MAX_OPEN_FILES) { if (file != NULL)
return file;
if (open_count == ADSPFF_MAX_OPEN_FILES) {
pr_err("adspff: %d files already opened\n", pr_err("adspff: %d files already opened\n",
ADSPFF_MAX_OPEN_FILES); ADSPFF_MAX_OPEN_FILES);
file = NULL; file = NULL;
} else {
file = kzalloc(sizeof(*file), GFP_KERNEL);
open_count++;
list_add_tail(&file->list, &file_list);
} }
return file; return file;
} }
@@ -242,8 +253,7 @@ void adspff_fopen(void)
file->flags = flags; file->flags = flags;
} }
if (!(file->fp)) { if (file && !file->fp) {
kfree(file);
file = NULL; file = NULL;
pr_err("File not found - %s\n", pr_err("File not found - %s\n",
(const char *) message->msg.payload.fopen_msg.fname); (const char *) message->msg.payload.fopen_msg.fname);
@@ -256,6 +266,12 @@ void adspff_fopen(void)
(msgq_message_t *)msg_recv); (msgq_message_t *)msg_recv);
if (ret < 0) { if (ret < 0) {
pr_err("fopen Enqueue failed %d.", ret); pr_err("fopen Enqueue failed %d.", ret);
if (file) {
file_close(file->fp);
file->fp = NULL;
}
kfree(message); kfree(message);
kfree(msg_recv); kfree(msg_recv);
return; return;
@@ -269,7 +285,7 @@ void adspff_fopen(void)
static inline unsigned int is_read_file(struct file_struct *file) static inline unsigned int is_read_file(struct file_struct *file)
{ {
return file->flags & (O_RDONLY | O_RDWR); return ((!file->flags) || (file->flags & O_RDWR));
} }
static inline unsigned int is_write_file(struct file_struct *file) static inline unsigned int is_write_file(struct file_struct *file)
@@ -585,17 +601,20 @@ static int adspff_msg_handler(uint32_t msg, void *data)
static int adspff_set(void *data, u64 val) static int adspff_set(void *data, u64 val)
{ {
int i;
struct file_struct *file; struct file_struct *file;
struct list_head *pos, *n;
if (val != 1) if (val != 1)
return 0; return 0;
for (i = 0; i < ADSPFF_MAX_OPEN_FILES; i++) { list_for_each_safe(pos, n, &file_list) {
file = &adspff_open_files[i]; file = list_entry(pos, struct file_struct, list);
list_del(pos);
if (file->fp) if (file->fp)
file_close(file->fp); file_close(file->fp);
kfree(file);
} }
memset(adspff_open_files, 0, sizeof(adspff_open_files));
open_count = 0;
return 0; return 0;
} }
@@ -650,13 +669,12 @@ int adspff_init(struct platform_device *pdev)
spin_lock_init(&adspff_lock); spin_lock_init(&adspff_lock);
memset(&adspff_open_files, 0, sizeof(adspff_open_files));
ret = adspff_debugfs_init(drv); ret = adspff_debugfs_init(drv);
if (ret) if (ret)
pr_warn("adspff: failed to create debugfs entry\n"); pr_warn("adspff: failed to create debugfs entry\n");
INIT_LIST_HEAD(&adspff_kthread_msgq_head); INIT_LIST_HEAD(&adspff_kthread_msgq_head);
INIT_LIST_HEAD(&file_list);
adspff_kthread = kthread_create(adspff_kthread_fn, adspff_kthread = kthread_create(adspff_kthread_fn,
NULL, "adspp_kthread"); NULL, "adspp_kthread");

View File

@@ -57,7 +57,7 @@ enum adspff_mbx_cmd {
/* supported message payloads */ /* supported message payloads */
struct fopen_msg_t { struct fopen_msg_t {
uint8_t fname[ADSPFF_MAX_FILENAME_SIZE]; uint8_t fname[ADSPFF_MAX_FILENAME_SIZE];
uint8_t modes[2]; uint8_t modes[3];
}; };
struct fwrite_msg_t { struct fwrite_msg_t {