mirror of
git://nv-tegra.nvidia.com/linux-nv-oot.git
synced 2025-12-22 17:25:35 +03:00
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:
committed by
Laxman Dewangan
parent
b82520e6d3
commit
8916271137
@@ -26,6 +26,7 @@
|
||||
#include <linux/semaphore.h>
|
||||
#include <linux/debugfs.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/list.h>
|
||||
|
||||
#include <linux/tegra_nvadsp.h>
|
||||
|
||||
@@ -33,7 +34,7 @@
|
||||
#include "dev.h"
|
||||
|
||||
|
||||
#define ADSPFF_MAX_OPEN_FILES (4)
|
||||
#define ADSPFF_MAX_OPEN_FILES (32)
|
||||
|
||||
struct file_struct {
|
||||
struct file *fp;
|
||||
@@ -41,11 +42,12 @@ struct file_struct {
|
||||
unsigned int flags;
|
||||
unsigned long long wr_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 int open_count;
|
||||
|
||||
/******************************************************************************
|
||||
* Kernel file functions
|
||||
@@ -162,31 +164,40 @@ void set_flags(union adspff_message_t *m, unsigned int *flags)
|
||||
/*
|
||||
* checks if file is already opened
|
||||
* if yes, then returns the struct file_struct for the file
|
||||
* if no, thgen returns first available struct file_struct
|
||||
* if ADSPFF_MAX_OPEN_FILES alreadu open, returns NULL
|
||||
* if no, then allocates a file_struct and adds to the list
|
||||
* 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)
|
||||
{
|
||||
struct file_struct *file;
|
||||
int idx;
|
||||
struct file_struct *file = NULL;
|
||||
struct list_head *pos;
|
||||
|
||||
/* assuming files opened by ADSP will
|
||||
* never be actually closed in kernel
|
||||
*/
|
||||
for (idx = 0; idx < ADSPFF_MAX_OPEN_FILES; idx++) {
|
||||
file = &adspff_open_files[idx];
|
||||
list_for_each(pos, &file_list) {
|
||||
file = list_entry(pos, struct file_struct, list);
|
||||
if (!file->fp)
|
||||
break;
|
||||
if (!strncmp(path, file->file_name,
|
||||
ADSPFF_MAX_FILENAME_SIZE)) {
|
||||
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",
|
||||
ADSPFF_MAX_OPEN_FILES);
|
||||
file = NULL;
|
||||
} else {
|
||||
file = kzalloc(sizeof(*file), GFP_KERNEL);
|
||||
open_count++;
|
||||
list_add_tail(&file->list, &file_list);
|
||||
}
|
||||
return file;
|
||||
}
|
||||
@@ -242,8 +253,7 @@ void adspff_fopen(void)
|
||||
file->flags = flags;
|
||||
}
|
||||
|
||||
if (!(file->fp)) {
|
||||
kfree(file);
|
||||
if (file && !file->fp) {
|
||||
file = NULL;
|
||||
pr_err("File not found - %s\n",
|
||||
(const char *) message->msg.payload.fopen_msg.fname);
|
||||
@@ -256,6 +266,12 @@ void adspff_fopen(void)
|
||||
(msgq_message_t *)msg_recv);
|
||||
if (ret < 0) {
|
||||
pr_err("fopen Enqueue failed %d.", ret);
|
||||
|
||||
if (file) {
|
||||
file_close(file->fp);
|
||||
file->fp = NULL;
|
||||
}
|
||||
|
||||
kfree(message);
|
||||
kfree(msg_recv);
|
||||
return;
|
||||
@@ -269,7 +285,7 @@ void adspff_fopen(void)
|
||||
|
||||
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)
|
||||
@@ -585,17 +601,20 @@ static int adspff_msg_handler(uint32_t msg, void *data)
|
||||
|
||||
static int adspff_set(void *data, u64 val)
|
||||
{
|
||||
int i;
|
||||
struct file_struct *file;
|
||||
struct list_head *pos, *n;
|
||||
|
||||
if (val != 1)
|
||||
return 0;
|
||||
for (i = 0; i < ADSPFF_MAX_OPEN_FILES; i++) {
|
||||
file = &adspff_open_files[i];
|
||||
list_for_each_safe(pos, n, &file_list) {
|
||||
file = list_entry(pos, struct file_struct, list);
|
||||
list_del(pos);
|
||||
if (file->fp)
|
||||
file_close(file->fp);
|
||||
kfree(file);
|
||||
}
|
||||
memset(adspff_open_files, 0, sizeof(adspff_open_files));
|
||||
|
||||
open_count = 0;
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -650,13 +669,12 @@ int adspff_init(struct platform_device *pdev)
|
||||
|
||||
spin_lock_init(&adspff_lock);
|
||||
|
||||
memset(&adspff_open_files, 0, sizeof(adspff_open_files));
|
||||
|
||||
ret = adspff_debugfs_init(drv);
|
||||
if (ret)
|
||||
pr_warn("adspff: failed to create debugfs entry\n");
|
||||
|
||||
INIT_LIST_HEAD(&adspff_kthread_msgq_head);
|
||||
INIT_LIST_HEAD(&file_list);
|
||||
|
||||
adspff_kthread = kthread_create(adspff_kthread_fn,
|
||||
NULL, "adspp_kthread");
|
||||
|
||||
@@ -57,7 +57,7 @@ enum adspff_mbx_cmd {
|
||||
/* supported message payloads */
|
||||
struct fopen_msg_t {
|
||||
uint8_t fname[ADSPFF_MAX_FILENAME_SIZE];
|
||||
uint8_t modes[2];
|
||||
uint8_t modes[3];
|
||||
};
|
||||
|
||||
struct fwrite_msg_t {
|
||||
|
||||
Reference in New Issue
Block a user