提交 c7ec0bad 编写于 作者: R Richard Cochran 提交者: David S. Miller

ptp: reduce stack usage when reading external time stamps

This patch removes the large buffer from the stack of the read file
operation and replaces it with a kmalloced buffer.
Signed-off-by: NRichard Cochran <richardcochran@gmail.com>
Signed-off-by: NDavid S. Miller <davem@davemloft.net>
上级 cfd1979e
...@@ -21,6 +21,7 @@ ...@@ -21,6 +21,7 @@
#include <linux/posix-clock.h> #include <linux/posix-clock.h>
#include <linux/poll.h> #include <linux/poll.h>
#include <linux/sched.h> #include <linux/sched.h>
#include <linux/slab.h>
#include "ptp_private.h" #include "ptp_private.h"
...@@ -136,20 +137,23 @@ unsigned int ptp_poll(struct posix_clock *pc, struct file *fp, poll_table *wait) ...@@ -136,20 +137,23 @@ unsigned int ptp_poll(struct posix_clock *pc, struct file *fp, poll_table *wait)
return queue_cnt(&ptp->tsevq) ? POLLIN : 0; return queue_cnt(&ptp->tsevq) ? POLLIN : 0;
} }
#define EXTTS_BUFSIZE (PTP_BUF_TIMESTAMPS * sizeof(struct ptp_extts_event))
ssize_t ptp_read(struct posix_clock *pc, ssize_t ptp_read(struct posix_clock *pc,
uint rdflags, char __user *buf, size_t cnt) uint rdflags, char __user *buf, size_t cnt)
{ {
struct ptp_clock *ptp = container_of(pc, struct ptp_clock, clock); struct ptp_clock *ptp = container_of(pc, struct ptp_clock, clock);
struct timestamp_event_queue *queue = &ptp->tsevq; struct timestamp_event_queue *queue = &ptp->tsevq;
struct ptp_extts_event event[PTP_BUF_TIMESTAMPS]; struct ptp_extts_event *event;
unsigned long flags; unsigned long flags;
size_t qcnt, i; size_t qcnt, i;
int result;
if (cnt % sizeof(struct ptp_extts_event) != 0) if (cnt % sizeof(struct ptp_extts_event) != 0)
return -EINVAL; return -EINVAL;
if (cnt > sizeof(event)) if (cnt > EXTTS_BUFSIZE)
cnt = sizeof(event); cnt = EXTTS_BUFSIZE;
cnt = cnt / sizeof(struct ptp_extts_event); cnt = cnt / sizeof(struct ptp_extts_event);
...@@ -167,6 +171,12 @@ ssize_t ptp_read(struct posix_clock *pc, ...@@ -167,6 +171,12 @@ ssize_t ptp_read(struct posix_clock *pc,
return -ENODEV; return -ENODEV;
} }
event = kmalloc(EXTTS_BUFSIZE, GFP_KERNEL);
if (!event) {
mutex_unlock(&ptp->tsevq_mux);
return -ENOMEM;
}
spin_lock_irqsave(&queue->lock, flags); spin_lock_irqsave(&queue->lock, flags);
qcnt = queue_cnt(queue); qcnt = queue_cnt(queue);
...@@ -185,8 +195,10 @@ ssize_t ptp_read(struct posix_clock *pc, ...@@ -185,8 +195,10 @@ ssize_t ptp_read(struct posix_clock *pc,
mutex_unlock(&ptp->tsevq_mux); mutex_unlock(&ptp->tsevq_mux);
result = cnt;
if (copy_to_user(buf, event, cnt)) if (copy_to_user(buf, event, cnt))
return -EFAULT; result = -EFAULT;
return cnt; kfree(event);
return result;
} }
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册