#include <linux/uaccess.h>
 #include <linux/debugfs.h>
 #include <linux/module.h>
+#include <linux/vmalloc.h>
 
 #include "qedf.h"
 #include "qedf_dbg.h"
 qedf_dbg_fp_int_cmd_read(struct file *filp, char __user *buffer, size_t count,
                         loff_t *ppos)
 {
+       ssize_t ret;
        size_t cnt = 0;
+       char *cbuf;
        int id;
        struct qedf_fastpath *fp = NULL;
        struct qedf_dbg_ctx *qedf_dbg =
 
        QEDF_INFO(qedf_dbg, QEDF_LOG_DEBUGFS, "entered\n");
 
-       cnt = sprintf(buffer, "\nFastpath I/O completions\n\n");
+       cbuf = vmalloc(QEDF_DEBUGFS_LOG_LEN);
+       if (!cbuf)
+               return 0;
+
+       cnt += scnprintf(cbuf + cnt, QEDF_DEBUGFS_LOG_LEN - cnt, "\nFastpath I/O completions\n\n");
 
        for (id = 0; id < qedf->num_queues; id++) {
                fp = &(qedf->fp_array[id]);
                if (fp->sb_id == QEDF_SB_ID_NULL)
                        continue;
-               cnt += sprintf((buffer + cnt), "#%d: %lu\n", id,
-                              fp->completions);
+               cnt += scnprintf(cbuf + cnt, QEDF_DEBUGFS_LOG_LEN - cnt,
+                                "#%d: %lu\n", id, fp->completions);
        }
 
-       cnt = min_t(int, count, cnt - *ppos);
-       *ppos += cnt;
-       return cnt;
+       ret = simple_read_from_buffer(buffer, count, ppos, cbuf, cnt);
+
+       vfree(cbuf);
+
+       return ret;
 }
 
 static ssize_t