diff options
author | Richard Cochran <richardcochran@gmail.com> | 2012-11-25 20:44:35 -0500 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2012-11-26 17:22:14 -0500 |
commit | c3484c275db5abe88e01a7e1a80932112c9bbf69 (patch) | |
tree | 0113d9e291e5fcf3d3ba7bd70d7c8ccf9b885e30 /drivers/ptp | |
parent | c7ec0badcc54508d3ab052bb425cc677521a89be (diff) |
ptp: reduce stack usage when measuring the system time offset
This patch removes the large buffer from the stack of the system
offset ioctl and replaces it with a kmalloced buffer.
Signed-off-by: Richard Cochran <richardcochran@gmail.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers/ptp')
-rw-r--r-- | drivers/ptp/ptp_chardev.c | 21 |
1 files changed, 14 insertions, 7 deletions
diff --git a/drivers/ptp/ptp_chardev.c b/drivers/ptp/ptp_chardev.c index 9d7542efb175..34a0c607318e 100644 --- a/drivers/ptp/ptp_chardev.c +++ b/drivers/ptp/ptp_chardev.c | |||
@@ -34,7 +34,7 @@ long ptp_ioctl(struct posix_clock *pc, unsigned int cmd, unsigned long arg) | |||
34 | { | 34 | { |
35 | struct ptp_clock_caps caps; | 35 | struct ptp_clock_caps caps; |
36 | struct ptp_clock_request req; | 36 | struct ptp_clock_request req; |
37 | struct ptp_sys_offset sysoff; | 37 | struct ptp_sys_offset *sysoff = NULL; |
38 | struct ptp_clock *ptp = container_of(pc, struct ptp_clock, clock); | 38 | struct ptp_clock *ptp = container_of(pc, struct ptp_clock, clock); |
39 | struct ptp_clock_info *ops = ptp->info; | 39 | struct ptp_clock_info *ops = ptp->info; |
40 | struct ptp_clock_time *pct; | 40 | struct ptp_clock_time *pct; |
@@ -94,17 +94,22 @@ long ptp_ioctl(struct posix_clock *pc, unsigned int cmd, unsigned long arg) | |||
94 | break; | 94 | break; |
95 | 95 | ||
96 | case PTP_SYS_OFFSET: | 96 | case PTP_SYS_OFFSET: |
97 | if (copy_from_user(&sysoff, (void __user *)arg, | 97 | sysoff = kmalloc(sizeof(*sysoff), GFP_KERNEL); |
98 | sizeof(sysoff))) { | 98 | if (!sysoff) { |
99 | err = -ENOMEM; | ||
100 | break; | ||
101 | } | ||
102 | if (copy_from_user(sysoff, (void __user *)arg, | ||
103 | sizeof(*sysoff))) { | ||
99 | err = -EFAULT; | 104 | err = -EFAULT; |
100 | break; | 105 | break; |
101 | } | 106 | } |
102 | if (sysoff.n_samples > PTP_MAX_SAMPLES) { | 107 | if (sysoff->n_samples > PTP_MAX_SAMPLES) { |
103 | err = -EINVAL; | 108 | err = -EINVAL; |
104 | break; | 109 | break; |
105 | } | 110 | } |
106 | pct = &sysoff.ts[0]; | 111 | pct = &sysoff->ts[0]; |
107 | for (i = 0; i < sysoff.n_samples; i++) { | 112 | for (i = 0; i < sysoff->n_samples; i++) { |
108 | getnstimeofday(&ts); | 113 | getnstimeofday(&ts); |
109 | pct->sec = ts.tv_sec; | 114 | pct->sec = ts.tv_sec; |
110 | pct->nsec = ts.tv_nsec; | 115 | pct->nsec = ts.tv_nsec; |
@@ -117,7 +122,7 @@ long ptp_ioctl(struct posix_clock *pc, unsigned int cmd, unsigned long arg) | |||
117 | getnstimeofday(&ts); | 122 | getnstimeofday(&ts); |
118 | pct->sec = ts.tv_sec; | 123 | pct->sec = ts.tv_sec; |
119 | pct->nsec = ts.tv_nsec; | 124 | pct->nsec = ts.tv_nsec; |
120 | if (copy_to_user((void __user *)arg, &sysoff, sizeof(sysoff))) | 125 | if (copy_to_user((void __user *)arg, sysoff, sizeof(*sysoff))) |
121 | err = -EFAULT; | 126 | err = -EFAULT; |
122 | break; | 127 | break; |
123 | 128 | ||
@@ -125,6 +130,8 @@ long ptp_ioctl(struct posix_clock *pc, unsigned int cmd, unsigned long arg) | |||
125 | err = -ENOTTY; | 130 | err = -ENOTTY; |
126 | break; | 131 | break; |
127 | } | 132 | } |
133 | |||
134 | kfree(sysoff); | ||
128 | return err; | 135 | return err; |
129 | } | 136 | } |
130 | 137 | ||