From: Albert Cano Date: Mon, 24 Sep 2018 08:40:02 +0000 (+0100) Subject: [9610] wlbt: Changed hip4_sampler serialization. X-Git-Url: https://git.stricted.de/?a=commitdiff_plain;h=a35ee6f46429b9e7b4d7ee940313462971cac116;p=GitHub%2FLineageOS%2Fandroid_kernel_motorola_exynos9610.git [9610] wlbt: Changed hip4_sampler serialization. Changed hip4_sampler serialization after hitting a kernel panic when the spinlock logic gets out of sync. We still don't know the reason behind the kernel crash and it would require more research as the issue occurs around spinlock arm64 logic. Removed the per device node spinlcok and substituted by a global spinlock. This patch also includes an optimization in the tput update function. If the new tput value (rx/tx) has no changed from previous sample, do not generate a new one. Change-Id: I216097037f024e21fa8f4e598874e683ca436d54 SCSC-Bug-Id: SSB-43554 Signed-off-by: Albert Cano --- diff --git a/drivers/net/wireless/scsc/hip4_sampler.c b/drivers/net/wireless/scsc/hip4_sampler.c index 1311272bbf67..89e24474fe70 100755 --- a/drivers/net/wireless/scsc/hip4_sampler.c +++ b/drivers/net/wireless/scsc/hip4_sampler.c @@ -44,6 +44,10 @@ struct hip4_record { static atomic_t in_read; +/* Create a global spinlock for all the instances */ +/* It is less efficent, but we simplify the implementation */ +static spinlock_t g_spinlock; + static bool hip4_sampler_enable = true; module_param(hip4_sampler_enable, bool, S_IRUGO | S_IWUSR); MODULE_PARM_DESC(hip4_sampler_enable, "Enable hip4_sampler_enable. Run-time option - (default: Y)"); @@ -177,8 +181,6 @@ struct hip4_sampler_dev { wait_queue_head_t read_wait; /* Device in error */ enum hip4_dg_errors error; - /* Device node spinlock for IRQ */ - spinlock_t spinlock; /* Device node mutex for fops */ struct mutex mutex; /* Record number */ @@ -271,11 +273,10 @@ void hip4_sampler_update_record(u32 minor, u8 param1, u8 param2, u8 param3, u8 p if (minor >= SCSC_HIP4_INTERFACES) return; + spin_lock_irqsave(&g_spinlock, flags); hip4_dev = &hip4_sampler.devs[minor]; - - spin_lock_irqsave(&hip4_dev->spinlock, flags); __hip4_sampler_update_record(hip4_dev, minor, param1, param2, param3, param4, param5); - spin_unlock_irqrestore(&hip4_dev->spinlock, flags); + spin_unlock_irqrestore(&g_spinlock, flags); } static void hip4_sampler_store_param(void) @@ -359,6 +360,9 @@ static void hip4_sampler_dynamic_switcher(u32 bps) } } +static u32 g_tput_rx; +static u32 g_tput_tx; + void hip4_sampler_tput_monitor(void *client_ctx, u32 state, u32 tput_tx, u32 tput_rx) { struct hip4_sampler_dev *hip4_sampler_dev = (struct hip4_sampler_dev *)client_ctx; @@ -366,6 +370,12 @@ void hip4_sampler_tput_monitor(void *client_ctx, u32 state, u32 tput_tx, u32 tpu if (!hip4_sampler_enable) return; + if ((g_tput_tx == tput_tx) && (g_tput_rx == tput_rx)) + return; + + g_tput_rx == tput_tx; + g_tput_rx == tput_rx; + if (hip4_sampler_dynamic) { /* Call the dynamic switcher with the computed bps * The algorithm will decide to not change, decrease @@ -531,9 +541,9 @@ int hip4_collect(struct scsc_log_collector_client *collect_client, size_t size) buf = vmalloc(num_samples * sizeof(struct hip4_record)); if (!buf) continue; - spin_lock_irqsave(&hip4_dev->spinlock, flags); + spin_lock_irqsave(&g_spinlock, flags); ret = kfifo_out(&hip4_dev->fifo, buf, num_samples); - spin_unlock_irqrestore(&hip4_dev->spinlock, flags); + spin_unlock_irqrestore(&g_spinlock, flags); if (!ret) goto error; SLSI_DBG1_NODEV(SLSI_HIP, "num_samples %d ret %d size of hip4_record %zu\n", num_samples, ret, sizeof(struct hip4_record)); @@ -601,14 +611,12 @@ static int hip4_sampler_open(struct inode *inode, struct file *filp) filp->private_data = hip4_dev; - spin_lock(&hip4_dev->spinlock); /* Clear any remaining error */ hip4_dev->error = NO_ERROR; hip4_dev->record_num = 0; hip4_dev->kfifo_max = 0; hip4_dev->filp = filp; - spin_unlock(&hip4_dev->spinlock); SLSI_INFO_NODEV("%s: Sampling....\n", DRV_NAME); end: @@ -727,11 +735,9 @@ static int hip4_sampler_release(struct inode *inode, struct file *filp) return -EIO; } - spin_lock(&hip4_dev->spinlock); filp->private_data = NULL; hip4_dev->filp = NULL; kfifo_free(&hip4_dev->fifo); - spin_unlock(&hip4_dev->spinlock); mutex_unlock(&hip4_dev->mutex); SLSI_INFO_NODEV("%s: Sampling... end. Kfifo_max = %d\n", DRV_NAME, hip4_dev->kfifo_max); @@ -821,7 +827,6 @@ void hip4_sampler_create(struct slsi_dev *sdev, struct scsc_mx *mx) hip4_sampler.devs[minor].mx = mx; mutex_init(&hip4_sampler.devs[minor].mutex); - spin_lock_init(&hip4_sampler.devs[minor].spinlock); hip4_sampler.devs[minor].kfifo_max = 0; hip4_sampler.devs[minor].type = STREAMING; hip4_sampler.devs[minor].minor = minor; @@ -881,7 +886,6 @@ void hip4_sampler_create(struct slsi_dev *sdev, struct scsc_mx *mx) hip4_sampler.devs[minor].mx = mx; mutex_init(&hip4_sampler.devs[minor].mutex); - spin_lock_init(&hip4_sampler.devs[minor].spinlock); hip4_sampler.devs[minor].kfifo_max = 0; hip4_sampler.devs[minor].type = OFFLINE; @@ -918,10 +922,8 @@ void hip4_sampler_destroy(struct slsi_dev *sdev, struct scsc_mx *mx) * the service (device node) is open */ if (hip4_sampler.devs[i].filp) { - spin_lock(&hip4_sampler.devs[i].spinlock); hip4_sampler.devs[i].filp = NULL; kfifo_free(&hip4_sampler.devs[i].fifo); - spin_unlock(&hip4_dev->spinlock); } if (hip4_sampler.devs[i].type == OFFLINE) kfifo_free(&hip4_sampler.devs[i].fifo);