diff options
author | Konsta Holtta <kholtta@nvidia.com> | 2014-10-02 08:25:53 -0400 |
---|---|---|
committer | Dan Willemsen <dwillemsen@nvidia.com> | 2015-03-18 15:11:49 -0400 |
commit | a870ff1d294126a3b46db4e0fdc14276035a2840 (patch) | |
tree | b4bb2e094ff77d57636ba887ecd3e14f8fc04689 | |
parent | 23d15214ae7d1e98b33552cd4cd2346cfea5725f (diff) |
gpu: nvgpu: Remove get and put client routines
gk20a_get_client() and gk20a_put_client() routines are effectively dead
code. The GPU has been using pm_runtime for reference counting whether
the device should be turned on or off, and gk20a_get_client() and
gk20a_put_client() have had no positive effect on the behaviour.
In worst case these functions trigger some issues as they may trigger
code paths that should not be run. There is also a race between get/put
and busy/idle.
This patch removes the functions and reworks as_gk20a.c to correctly use
gk20a_busy()/gk20a_idle() where put/get was required.
Additionally, finalize_poweron() is moved to gk20a_busy(), similarly as
it was with gk20a_get_client(). If pm_runtime is not in use, the device
is only powered on and never off. Currently this affects vgpu power
management since it does not use pm_runtime yet.
Bug 1562096
Change-Id: I3162655f83457e9caccd9264eed36b5d51e60c52
Signed-off-by: Arto Merilainen <amerilainen@nvidia.com>
Signed-off-by: Konsta Holtta <kholtta@nvidia.com>
Reviewed-on: http://git-master/r/414998
Reviewed-by: Automatic_Commit_Validation_User
Reviewed-by: Seshendra Gadagottu <sgadagottu@nvidia.com>
Tested-by: Seshendra Gadagottu <sgadagottu@nvidia.com>
GVS: Gerrit_Virtual_Submit
Reviewed-by: Terje Bergstrom <tbergstrom@nvidia.com>
-rw-r--r-- | drivers/gpu/nvgpu/gk20a/as_gk20a.c | 22 | ||||
-rw-r--r-- | drivers/gpu/nvgpu/gk20a/channel_gk20a.c | 10 | ||||
-rw-r--r-- | drivers/gpu/nvgpu/gk20a/ctrl_gk20a.c | 18 | ||||
-rw-r--r-- | drivers/gpu/nvgpu/gk20a/gk20a.c | 74 | ||||
-rw-r--r-- | drivers/gpu/nvgpu/gk20a/gk20a.h | 2 |
5 files changed, 16 insertions, 110 deletions
diff --git a/drivers/gpu/nvgpu/gk20a/as_gk20a.c b/drivers/gpu/nvgpu/gk20a/as_gk20a.c index 74d83a7d..27608cec 100644 --- a/drivers/gpu/nvgpu/gk20a/as_gk20a.c +++ b/drivers/gpu/nvgpu/gk20a/as_gk20a.c | |||
@@ -56,14 +56,19 @@ int gk20a_as_alloc_share(struct gk20a_as *as, | |||
56 | as_share->ref_cnt.counter = 1; | 56 | as_share->ref_cnt.counter = 1; |
57 | 57 | ||
58 | /* this will set as_share->vm. */ | 58 | /* this will set as_share->vm. */ |
59 | err = gk20a_busy(g->dev); | ||
60 | if (err) | ||
61 | goto failed; | ||
59 | err = g->ops.mm.vm_alloc_share(as_share, flags); | 62 | err = g->ops.mm.vm_alloc_share(as_share, flags); |
63 | gk20a_idle(g->dev); | ||
64 | |||
60 | if (err) | 65 | if (err) |
61 | goto failed; | 66 | goto failed; |
62 | 67 | ||
63 | *out = as_share; | 68 | *out = as_share; |
64 | return 0; | 69 | return 0; |
65 | 70 | ||
66 | failed: | 71 | failed: |
67 | kfree(as_share); | 72 | kfree(as_share); |
68 | return err; | 73 | return err; |
69 | } | 74 | } |
@@ -180,16 +185,9 @@ int gk20a_as_dev_open(struct inode *inode, struct file *filp) | |||
180 | 185 | ||
181 | g = container_of(inode->i_cdev, struct gk20a, as.cdev); | 186 | g = container_of(inode->i_cdev, struct gk20a, as.cdev); |
182 | 187 | ||
183 | err = gk20a_get_client(g); | ||
184 | if (err) { | ||
185 | gk20a_dbg_fn("fail to get channel!"); | ||
186 | return err; | ||
187 | } | ||
188 | |||
189 | err = gk20a_as_alloc_share(&g->as, 0, &as_share); | 188 | err = gk20a_as_alloc_share(&g->as, 0, &as_share); |
190 | if (err) { | 189 | if (err) { |
191 | gk20a_dbg_fn("failed to alloc share"); | 190 | gk20a_dbg_fn("failed to alloc share"); |
192 | gk20a_put_client(g); | ||
193 | return err; | 191 | return err; |
194 | } | 192 | } |
195 | 193 | ||
@@ -200,16 +198,10 @@ int gk20a_as_dev_open(struct inode *inode, struct file *filp) | |||
200 | int gk20a_as_dev_release(struct inode *inode, struct file *filp) | 198 | int gk20a_as_dev_release(struct inode *inode, struct file *filp) |
201 | { | 199 | { |
202 | struct gk20a_as_share *as_share = filp->private_data; | 200 | struct gk20a_as_share *as_share = filp->private_data; |
203 | int ret; | ||
204 | struct gk20a *g = gk20a_from_as(as_share->as); | ||
205 | 201 | ||
206 | gk20a_dbg_fn(""); | 202 | gk20a_dbg_fn(""); |
207 | 203 | ||
208 | ret = gk20a_as_release_share(as_share); | 204 | return gk20a_as_release_share(as_share); |
209 | |||
210 | gk20a_put_client(g); | ||
211 | |||
212 | return ret; | ||
213 | } | 205 | } |
214 | 206 | ||
215 | long gk20a_as_dev_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) | 207 | long gk20a_as_dev_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) |
diff --git a/drivers/gpu/nvgpu/gk20a/channel_gk20a.c b/drivers/gpu/nvgpu/gk20a/channel_gk20a.c index bcc05079..eaea5a77 100644 --- a/drivers/gpu/nvgpu/gk20a/channel_gk20a.c +++ b/drivers/gpu/nvgpu/gk20a/channel_gk20a.c | |||
@@ -726,7 +726,6 @@ int gk20a_channel_release(struct inode *inode, struct file *filp) | |||
726 | gk20a_free_channel(ch, true); | 726 | gk20a_free_channel(ch, true); |
727 | gk20a_idle(ch->g->dev); | 727 | gk20a_idle(ch->g->dev); |
728 | 728 | ||
729 | gk20a_put_client(g); | ||
730 | filp->private_data = NULL; | 729 | filp->private_data = NULL; |
731 | return 0; | 730 | return 0; |
732 | } | 731 | } |
@@ -788,23 +787,14 @@ static int __gk20a_channel_open(struct gk20a *g, struct file *filp) | |||
788 | 787 | ||
789 | trace_gk20a_channel_open(dev_name(&g->dev->dev)); | 788 | trace_gk20a_channel_open(dev_name(&g->dev->dev)); |
790 | 789 | ||
791 | err = gk20a_get_client(g); | ||
792 | if (err) { | ||
793 | gk20a_err(dev_from_gk20a(g), | ||
794 | "failed to get client ref"); | ||
795 | return err; | ||
796 | } | ||
797 | |||
798 | err = gk20a_busy(g->dev); | 790 | err = gk20a_busy(g->dev); |
799 | if (err) { | 791 | if (err) { |
800 | gk20a_put_client(g); | ||
801 | gk20a_err(dev_from_gk20a(g), "failed to power on, %d", err); | 792 | gk20a_err(dev_from_gk20a(g), "failed to power on, %d", err); |
802 | return err; | 793 | return err; |
803 | } | 794 | } |
804 | ch = gk20a_open_new_channel(g); | 795 | ch = gk20a_open_new_channel(g); |
805 | gk20a_idle(g->dev); | 796 | gk20a_idle(g->dev); |
806 | if (!ch) { | 797 | if (!ch) { |
807 | gk20a_put_client(g); | ||
808 | gk20a_err(dev_from_gk20a(g), | 798 | gk20a_err(dev_from_gk20a(g), |
809 | "failed to get f"); | 799 | "failed to get f"); |
810 | return -ENOMEM; | 800 | return -ENOMEM; |
diff --git a/drivers/gpu/nvgpu/gk20a/ctrl_gk20a.c b/drivers/gpu/nvgpu/gk20a/ctrl_gk20a.c index 6969a3a7..fbc93fc3 100644 --- a/drivers/gpu/nvgpu/gk20a/ctrl_gk20a.c +++ b/drivers/gpu/nvgpu/gk20a/ctrl_gk20a.c | |||
@@ -25,7 +25,6 @@ | |||
25 | 25 | ||
26 | int gk20a_ctrl_dev_open(struct inode *inode, struct file *filp) | 26 | int gk20a_ctrl_dev_open(struct inode *inode, struct file *filp) |
27 | { | 27 | { |
28 | int err; | ||
29 | struct gk20a *g; | 28 | struct gk20a *g; |
30 | 29 | ||
31 | gk20a_dbg_fn(""); | 30 | gk20a_dbg_fn(""); |
@@ -35,22 +34,13 @@ int gk20a_ctrl_dev_open(struct inode *inode, struct file *filp) | |||
35 | 34 | ||
36 | filp->private_data = g->dev; | 35 | filp->private_data = g->dev; |
37 | 36 | ||
38 | err = gk20a_get_client(g); | ||
39 | if (err) { | ||
40 | gk20a_dbg_fn("fail to get channel!"); | ||
41 | return err; | ||
42 | } | ||
43 | |||
44 | return 0; | 37 | return 0; |
45 | } | 38 | } |
46 | 39 | ||
47 | int gk20a_ctrl_dev_release(struct inode *inode, struct file *filp) | 40 | int gk20a_ctrl_dev_release(struct inode *inode, struct file *filp) |
48 | { | 41 | { |
49 | struct platform_device *dev = filp->private_data; | ||
50 | |||
51 | gk20a_dbg_fn(""); | 42 | gk20a_dbg_fn(""); |
52 | 43 | ||
53 | gk20a_put_client(get_gk20a(dev)); | ||
54 | return 0; | 44 | return 0; |
55 | } | 45 | } |
56 | 46 | ||
@@ -177,21 +167,15 @@ static int gk20a_ctrl_alloc_as( | |||
177 | } | 167 | } |
178 | fd_install(fd, file); | 168 | fd_install(fd, file); |
179 | 169 | ||
180 | err = gk20a_get_client(g); | ||
181 | if (err) | ||
182 | goto clean_up; | ||
183 | |||
184 | err = gk20a_as_alloc_share(&g->as, args->big_page_size, &as_share); | 170 | err = gk20a_as_alloc_share(&g->as, args->big_page_size, &as_share); |
185 | if (err) | 171 | if (err) |
186 | goto clean_up_client; | 172 | goto clean_up; |
187 | 173 | ||
188 | file->private_data = as_share; | 174 | file->private_data = as_share; |
189 | 175 | ||
190 | args->as_fd = fd; | 176 | args->as_fd = fd; |
191 | return 0; | 177 | return 0; |
192 | 178 | ||
193 | clean_up_client: | ||
194 | gk20a_put_client(g); | ||
195 | clean_up: | 179 | clean_up: |
196 | put_unused_fd(fd); | 180 | put_unused_fd(fd); |
197 | return err; | 181 | return err; |
diff --git a/drivers/gpu/nvgpu/gk20a/gk20a.c b/drivers/gpu/nvgpu/gk20a/gk20a.c index a09a0631..98dce955 100644 --- a/drivers/gpu/nvgpu/gk20a/gk20a.c +++ b/drivers/gpu/nvgpu/gk20a/gk20a.c | |||
@@ -734,72 +734,6 @@ static int gk20a_init_support(struct platform_device *dev) | |||
734 | return err; | 734 | return err; |
735 | } | 735 | } |
736 | 736 | ||
737 | static int gk20a_init_client(struct platform_device *dev) | ||
738 | { | ||
739 | struct gk20a *g = get_gk20a(dev); | ||
740 | struct gk20a_platform *platform = gk20a_get_platform(dev); | ||
741 | int err; | ||
742 | |||
743 | gk20a_dbg_fn(""); | ||
744 | |||
745 | if (platform->virtual_dev) { | ||
746 | err = vgpu_pm_finalize_poweron(&dev->dev); | ||
747 | if (err) | ||
748 | return err; | ||
749 | } | ||
750 | |||
751 | #ifndef CONFIG_PM_RUNTIME | ||
752 | gk20a_pm_finalize_poweron(&dev->dev); | ||
753 | #endif | ||
754 | |||
755 | err = gk20a_init_mm_setup_sw(g); | ||
756 | if (err) | ||
757 | return err; | ||
758 | |||
759 | if (IS_ENABLED(CONFIG_GK20A_DEVFREQ)) | ||
760 | gk20a_scale_hw_init(dev); | ||
761 | return 0; | ||
762 | } | ||
763 | |||
764 | static void gk20a_deinit_client(struct platform_device *dev) | ||
765 | { | ||
766 | struct gk20a_platform *platform = gk20a_get_platform(dev); | ||
767 | |||
768 | gk20a_dbg_fn(""); | ||
769 | |||
770 | if (platform->virtual_dev) { | ||
771 | vgpu_pm_prepare_poweroff(&dev->dev); | ||
772 | return; | ||
773 | } | ||
774 | |||
775 | #ifndef CONFIG_PM_RUNTIME | ||
776 | gk20a_pm_prepare_poweroff(&dev->dev); | ||
777 | #endif | ||
778 | } | ||
779 | |||
780 | int gk20a_get_client(struct gk20a *g) | ||
781 | { | ||
782 | int err = 0; | ||
783 | |||
784 | mutex_lock(&g->client_lock); | ||
785 | if (g->client_refcount == 0) | ||
786 | err = gk20a_init_client(g->dev); | ||
787 | if (!err) | ||
788 | g->client_refcount++; | ||
789 | mutex_unlock(&g->client_lock); | ||
790 | return err; | ||
791 | } | ||
792 | |||
793 | void gk20a_put_client(struct gk20a *g) | ||
794 | { | ||
795 | mutex_lock(&g->client_lock); | ||
796 | if (g->client_refcount == 1) | ||
797 | gk20a_deinit_client(g->dev); | ||
798 | g->client_refcount--; | ||
799 | mutex_unlock(&g->client_lock); | ||
800 | WARN_ON(g->client_refcount < 0); | ||
801 | } | ||
802 | |||
803 | static int gk20a_pm_prepare_poweroff(struct device *dev) | 737 | static int gk20a_pm_prepare_poweroff(struct device *dev) |
804 | { | 738 | { |
805 | struct platform_device *pdev = to_platform_device(dev); | 739 | struct platform_device *pdev = to_platform_device(dev); |
@@ -1662,6 +1596,14 @@ int gk20a_busy(struct platform_device *pdev) | |||
1662 | if (platform->idle) | 1596 | if (platform->idle) |
1663 | platform->idle(pdev); | 1597 | platform->idle(pdev); |
1664 | } | 1598 | } |
1599 | #else | ||
1600 | if (!g->power_on) { | ||
1601 | ret = platform->virtual_dev ? | ||
1602 | vgpu_pm_finalize_poweron(&dev->dev) | ||
1603 | : gk20a_pm_finalize_poweron(&dev->dev); | ||
1604 | if (ret) | ||
1605 | goto fail; | ||
1606 | } | ||
1665 | #endif | 1607 | #endif |
1666 | gk20a_scale_notify_busy(pdev); | 1608 | gk20a_scale_notify_busy(pdev); |
1667 | 1609 | ||
diff --git a/drivers/gpu/nvgpu/gk20a/gk20a.h b/drivers/gpu/nvgpu/gk20a/gk20a.h index 04a4cf66..20afd2bd 100644 --- a/drivers/gpu/nvgpu/gk20a/gk20a.h +++ b/drivers/gpu/nvgpu/gk20a/gk20a.h | |||
@@ -710,8 +710,6 @@ void gk20a_idle(struct platform_device *pdev); | |||
710 | void gk20a_disable(struct gk20a *g, u32 units); | 710 | void gk20a_disable(struct gk20a *g, u32 units); |
711 | void gk20a_enable(struct gk20a *g, u32 units); | 711 | void gk20a_enable(struct gk20a *g, u32 units); |
712 | void gk20a_reset(struct gk20a *g, u32 units); | 712 | void gk20a_reset(struct gk20a *g, u32 units); |
713 | int gk20a_get_client(struct gk20a *g); | ||
714 | void gk20a_put_client(struct gk20a *g); | ||
715 | int __gk20a_do_idle(struct platform_device *pdev); | 713 | int __gk20a_do_idle(struct platform_device *pdev); |
716 | int __gk20a_do_unidle(struct platform_device *pdev); | 714 | int __gk20a_do_unidle(struct platform_device *pdev); |
717 | 715 | ||