This patch removes the large buffer from the stack of the read file
operation and replaces it with a kmalloced buffer.
Signed-off-by: Richard Cochran <richardcochran@gmail.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
#include <linux/posix-clock.h>
#include <linux/poll.h>
#include <linux/sched.h>
#include <linux/posix-clock.h>
#include <linux/poll.h>
#include <linux/sched.h>
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,
uint rdflags, char __user *buf, size_t cnt)
{
struct ptp_clock *ptp = container_of(pc, struct ptp_clock, clock);
struct timestamp_event_queue *queue = &ptp->tsevq;
ssize_t ptp_read(struct posix_clock *pc,
uint rdflags, char __user *buf, size_t cnt)
{
struct ptp_clock *ptp = container_of(pc, struct ptp_clock, clock);
struct timestamp_event_queue *queue = &ptp->tsevq;
- struct ptp_extts_event event[PTP_BUF_TIMESTAMPS];
+ struct ptp_extts_event *event;
unsigned long flags;
size_t qcnt, i;
unsigned long flags;
size_t qcnt, i;
if (cnt % sizeof(struct ptp_extts_event) != 0)
return -EINVAL;
if (cnt % sizeof(struct ptp_extts_event) != 0)
return -EINVAL;
- if (cnt > sizeof(event))
- cnt = sizeof(event);
+ if (cnt > EXTTS_BUFSIZE)
+ cnt = EXTTS_BUFSIZE;
cnt = cnt / sizeof(struct ptp_extts_event);
cnt = cnt / sizeof(struct ptp_extts_event);
+ event = kmalloc(EXTTS_BUFSIZE, GFP_KERNEL);
+ if (!event) {
+ mutex_unlock(&ptp->tsevq_mux);
+ return -ENOMEM;
+ }
+
spin_lock_irqsave(&queue->lock, flags);
qcnt = queue_cnt(queue);
spin_lock_irqsave(&queue->lock, flags);
qcnt = queue_cnt(queue);
mutex_unlock(&ptp->tsevq_mux);
mutex_unlock(&ptp->tsevq_mux);
if (copy_to_user(buf, event, cnt))
if (copy_to_user(buf, event, cnt))
+ kfree(event);
+ return result;