* bug#55737: [PATCH] 28.1; Values of `read-process-output-max' above 64k not taken into account on GNU/Linux
@ 2022-05-31 11:09 Frédéric Giquel via Bug reports for GNU Emacs, the Swiss army knife of text editors
2022-05-31 12:00 ` Eli Zaretskii
0 siblings, 1 reply; 4+ messages in thread
From: Frédéric Giquel via Bug reports for GNU Emacs, the Swiss army knife of text editors @ 2022-05-31 11:09 UTC (permalink / raw)
To: 55737
[-- Attachment #1: Type: text/plain, Size: 5618 bytes --]
Hi,
While trying to understand the reason for slow completion with lsp-mode
in some situations, I noticed that the language server response is
split into 64k chunks despite setting `read-process-output-max' to 1M
(as recommended by lsp-mode maintainers).
The problem is not lsp-mode specific and can be reproduced without
additionnal packages by using the two scripts attached to this email:
- "write-server.py" is the server: it waits for a number
(requested_size) on its input and write a string of "requested_size"
bytes on its output. The file must be executable and located in the
PATH.
- "real-pipe-size.el" launch "write-server.py" and communicate with the
process using different values for `read-process-output-max'. It prints
the maximum chunk size used for each value.
On my system, I got the following output executing 'emacs -Q --script
~/Projets/emacs-pipe/real-pipe-size.el':
Real pipe size (with read-process-output-max = 4096): 4096
Real pipe size (with read-process-output-max = 32768): 32768
Real pipe size (with read-process-output-max = 65536): 65536
Real pipe size (with read-process-output-max = 65537): 65536
Real pipe size (with read-process-output-max = 204800): 65536
Real pipe size (with read-process-output-max = 1048576): 65536
Real pipe size (with read-process-output-max = 2097152): 65536
This 64k limit is GNU/Linux specific and is explained in "Pipe
capacity" section of pipe(7) manpage and can be changed calling
`fcntl'. So I added a call to `fcntl' for `F_SETPIPE_SZ' in
`create_process' function just after other uses of `fcntl' (I'm not
really sure if it's the right place). The patch is attached to this
email.
With the patch, the limit is now the value of `/proc/sys/fs/pipe-max-
size' (which default to 1M and can be change by users with the
CAP_SYS_RESOURCE capability). Output of 'emacs -Q --script
~/Projets/emacs-pipe/real-pipe-size.el' is now:
Real pipe size (with read-process-output-max = 4096): 4096
Real pipe size (with read-process-output-max = 32768): 32768
Real pipe size (with read-process-output-max = 65536): 65536
Real pipe size (with read-process-output-max = 65537): 65537
Real pipe size (with read-process-output-max = 204800): 204800
Real pipe size (with read-process-output-max = 1048576): 1048576
Real pipe size (with read-process-output-max = 2097152): 65536
And my initial problem of slow completion with lsp-mode is fixed.
P.S. I signed the FSF copyright assignment agreement for Emacs last
year.
In GNU Emacs 28.1 (build 1, x86_64-pc-linux-gnu, GTK+ Version 3.24.33,
cairo version 1.16.0)
of 2022-05-30 built on guiriden
Repository revision: 5a223c7f2ef4c31abbd46367b6ea83cd19d30aa7
Repository branch: heads/emacs-28.1
Windowing system distributor 'The X.Org Foundation', version
11.0.12201000
System Description: Debian GNU/Linux bookworm/sid
Configured features:
ACL CAIRO DBUS FREETYPE GIF GLIB GMP GNUTLS GPM GSETTINGS HARFBUZZ JPEG
JSON LCMS2 LIBOTF LIBSELINUX LIBSYSTEMD LIBXML2 M17N_FLT MODULES NOTIFY
INOTIFY PDUMPER PNG RSVG SECCOMP SOUND THREADS TIFF TOOLKIT_SCROLL_BARS
X11 XDBE XIM XPM GTK3 ZLIB
Important settings:
value of $LANG: fr_FR.UTF-8
value of $XMODIFIERS: @im=ibus
locale-coding-system: utf-8-unix
Major mode: Lisp Interaction
Minor modes in effect:
tooltip-mode: t
global-eldoc-mode: t
eldoc-mode: t
show-paren-mode: t
electric-indent-mode: t
mouse-wheel-mode: t
tool-bar-mode: t
menu-bar-mode: t
file-name-shadow-mode: t
global-font-lock-mode: t
font-lock-mode: t
blink-cursor-mode: t
auto-composition-mode: t
auto-encryption-mode: t
auto-compression-mode: t
line-number-mode: t
indent-tabs-mode: t
transient-mark-mode: t
Load-path shadows:
None found.
Features:
(shadow sort mail-extr emacsbug message rmc puny dired dired-loaddefs
rfc822 mml mml-sec epa derived epg rfc6068 epg-config gnus-util rmail
rmail-loaddefs auth-source cl-seq eieio eieio-core cl-macs
eieio-loaddefs password-cache json map text-property-search time-date
subr-x seq byte-opt gv bytecomp byte-compile cconv mm-decode mm-bodies
mm-encode mail-parse rfc2231 mailabbrev gmm-utils mailheader cl-
loaddefs
cl-lib sendmail rfc2047 rfc2045 ietf-drums mm-util mail-prsvr mail-
utils
iso-transl tooltip eldoc paren electric uniquify ediff-hook vc-hooks
lisp-float-type elisp-mode mwheel term/x-win x-win term/common-win x-
dnd
tool-bar dnd fontset image regexp-opt fringe tabulated-list replace
newcomment text-mode lisp-mode prog-mode register page tab-bar menu-bar
rfn-eshadow isearch easymenu timer select scroll-bar mouse jit-lock
font-lock syntax font-core term/tty-colors frame minibuffer cl-generic
cham georgian utf-8-lang misc-lang vietnamese tibetan thai tai-viet lao
korean japanese eucjp-ms cp51932 hebrew greek romanian slovak czech
european ethiopic indian cyrillic chinese composite emoji-zwj
charscript
charprop case-table epa-hook jka-cmpr-hook help simple abbrev obarray
cl-preloaded nadvice button loaddefs faces cus-face macroexp files
window text-properties overlay sha1 md5 base64 format env code-pages
mule custom widget hashtable-print-readable backquote threads dbusbind
inotify lcms2 dynamic-setting system-font-setting font-render-setting
cairo move-toolbar gtk x-toolkit x multi-tty make-network-process
emacs)
Memory information:
((conses 16 50603 6602)
(symbols 48 6632 1)
(strings 32 18327 1513)
(string-bytes 1 607344)
(vectors 16 13715)
(vector-slots 8 184638 11282)
(floats 8 21 47)
(intervals 56 195 0)
(buffers 992 10))
[-- Attachment #2: write-server.py --]
[-- Type: text/x-python3, Size: 175 bytes --]
#! /usr/bin/env python3
import sys
while True:
requested_size = int(sys.stdin.readline())
write_size = sys.stdout.write("A" * requested_size)
sys.stdout.flush()
[-- Attachment #3: real-pipe-size.el --]
[-- Type: text/x-emacs-lisp, Size: 1388 bytes --]
(defvar show-details nil)
;; Values to use for `read-process-output-max'
(defvar read-process-output-max-list
`(
4096 ;; default value
,(* 32 1024) ;; 32k
,(* 64 1024) ;; 64k
,(+ 1 (* 64 1024)) ;; 64k + 1
,(* 200 1024) ;; 200k
,(* 1024 1024) ;; 1M
,(* 2 1024 1024) ;; 2M
))
(defun filter-set-max-chunk-size (proc string)
(when show-details
(message "... chunk size: %s" (length string)))
(setq max-chunk-size (max (length string) max-chunk-size)))
(defun calculate-real-pipe-size (requested-pipe-size)
(let* ((read-process-output-max requested-pipe-size)
(max-chunk-size 0)
(proc (make-process
:name "calculate-pipe-size"
:buffer nil
:command '("write-server.py")
:connection-type 'pipe
:filter 'filter-set-max-chunk-size)))
(when show-details
(message "== Calculating real pipe size with read-process-output-max = %s ==" read-process-output-max))
(process-send-string "calculate-pipe-size" (concat (number-to-string requested-pipe-size) "\n"))
(accept-process-output proc)
(delete-process proc)
max-chunk-size))
(dolist (pipe-size read-process-output-max-list)
(message "Real pipe size (with read-process-output-max = %s): %s" pipe-size (calculate-real-pipe-size pipe-size)))
[-- Attachment #4: pipe-size.patch --]
[-- Type: text/x-patch, Size: 1125 bytes --]
diff --git a/src/process.c b/src/process.c
index 8b587aaa4e..703352e59e 100644
--- a/src/process.c
+++ b/src/process.c
@@ -2155,6 +2155,10 @@ create_process (Lisp_Object process, char **new_argv, Lisp_Object current_dir)
fcntl (inchannel, F_SETFL, O_NONBLOCK);
fcntl (outchannel, F_SETFL, O_NONBLOCK);
+#if defined(GNU_LINUX) && defined(F_SETPIPE_SZ)
+ fcntl (inchannel, F_SETPIPE_SZ, read_process_output_max);
+#endif
+
/* Record this as an active process, with its channels. */
eassert (0 <= inchannel && inchannel < FD_SETSIZE);
chan_process[inchannel] = process;
@@ -8571,7 +8575,10 @@ syms_of_process (void)
DEFVAR_INT ("read-process-output-max", read_process_output_max,
doc: /* Maximum number of bytes to read from subprocess in a single chunk.
Enlarge the value only if the subprocess generates very large (megabytes)
-amounts of data in one go. */);
+amounts of data in one go.
+
+On GNU/Linux system, the value should not exceed
+`/proc/sys/fs/pipe-max-size'. See pipe(7) manpage for details. */);
read_process_output_max = 4096;
DEFSYM (Qinternal_default_interrupt_process,
^ permalink raw reply related [flat|nested] 4+ messages in thread
* bug#55737: [PATCH] 28.1; Values of `read-process-output-max' above 64k not taken into account on GNU/Linux
2022-05-31 11:09 bug#55737: [PATCH] 28.1; Values of `read-process-output-max' above 64k not taken into account on GNU/Linux Frédéric Giquel via Bug reports for GNU Emacs, the Swiss army knife of text editors
@ 2022-05-31 12:00 ` Eli Zaretskii
2022-06-01 6:09 ` Frédéric Giquel via Bug reports for GNU Emacs, the Swiss army knife of text editors
0 siblings, 1 reply; 4+ messages in thread
From: Eli Zaretskii @ 2022-05-31 12:00 UTC (permalink / raw)
To: Frédéric Giquel; +Cc: 55737
> Date: Tue, 31 May 2022 13:09:38 +0200
> From: Frédéric Giquel via "Bug reports for GNU Emacs,
> the Swiss army knife of text editors" <bug-gnu-emacs@gnu.org>
>
> +#if defined(GNU_LINUX) && defined(F_SETPIPE_SZ)
> + fcntl (inchannel, F_SETPIPE_SZ, read_process_output_max);
> +#endif
Shouldn't this be done only for pipe connections to the subprocess?
Thanks.
^ permalink raw reply [flat|nested] 4+ messages in thread
* bug#55737: [PATCH] 28.1; Values of `read-process-output-max' above 64k not taken into account on GNU/Linux
2022-05-31 12:00 ` Eli Zaretskii
@ 2022-06-01 6:09 ` Frédéric Giquel via Bug reports for GNU Emacs, the Swiss army knife of text editors
2022-06-02 9:39 ` Lars Ingebrigtsen
0 siblings, 1 reply; 4+ messages in thread
From: Frédéric Giquel via Bug reports for GNU Emacs, the Swiss army knife of text editors @ 2022-06-01 6:09 UTC (permalink / raw)
To: Eli Zaretskii; +Cc: 55737
[-- Attachment #1: Type: text/plain, Size: 544 bytes --]
Le mardi 31 mai 2022 à 15:00 +0300, Eli Zaretskii a écrit :
> > Date: Tue, 31 May 2022 13:09:38 +0200
> > From: Frédéric Giquel via "Bug reports for GNU Emacs,
> > the Swiss army knife of text editors" <bug-gnu-emacs@gnu.org>
> >
> > +#if defined(GNU_LINUX) && defined(F_SETPIPE_SZ)
> > + fcntl (inchannel, F_SETPIPE_SZ, read_process_output_max);
> > +#endif
>
> Shouldn't this be done only for pipe connections to the subprocess?
You're right. Setting pipe size is useless for pty connection.
Here is the new patch.
[-- Attachment #2: pipe-size-v2.patch --]
[-- Type: text/x-patch, Size: 1081 bytes --]
diff --git a/src/process.c b/src/process.c
index 8b587aaa4e..eae7b26eb3 100644
--- a/src/process.c
+++ b/src/process.c
@@ -2132,6 +2132,10 @@ create_process (Lisp_Object process, char **new_argv, Lisp_Object current_dir)
inchannel = p->open_fd[READ_FROM_SUBPROCESS];
forkout = p->open_fd[SUBPROCESS_STDOUT];
+#if defined(GNU_LINUX) && defined(F_SETPIPE_SZ)
+ fcntl (inchannel, F_SETPIPE_SZ, read_process_output_max);
+#endif
+
if (!NILP (p->stderrproc))
{
struct Lisp_Process *pp = XPROCESS (p->stderrproc);
@@ -8571,7 +8575,10 @@ syms_of_process (void)
DEFVAR_INT ("read-process-output-max", read_process_output_max,
doc: /* Maximum number of bytes to read from subprocess in a single chunk.
Enlarge the value only if the subprocess generates very large (megabytes)
-amounts of data in one go. */);
+amounts of data in one go.
+
+On GNU/Linux system, the value should not exceed
+`/proc/sys/fs/pipe-max-size'. See pipe(7) manpage for details. */);
read_process_output_max = 4096;
DEFSYM (Qinternal_default_interrupt_process,
^ permalink raw reply related [flat|nested] 4+ messages in thread
* bug#55737: [PATCH] 28.1; Values of `read-process-output-max' above 64k not taken into account on GNU/Linux
2022-06-01 6:09 ` Frédéric Giquel via Bug reports for GNU Emacs, the Swiss army knife of text editors
@ 2022-06-02 9:39 ` Lars Ingebrigtsen
0 siblings, 0 replies; 4+ messages in thread
From: Lars Ingebrigtsen @ 2022-06-02 9:39 UTC (permalink / raw)
To: Frédéric Giquel; +Cc: 55737, Eli Zaretskii
Frédéric Giquel <frederic.giquel@laposte.net> writes:
> You're right. Setting pipe size is useless for pty connection.
> Here is the new patch.
Thanks; pushed to Emacs 29.
--
(domestic pets only, the antidote for overdose, milk.)
bloggy blog: http://lars.ingebrigtsen.no
^ permalink raw reply [flat|nested] 4+ messages in thread
end of thread, other threads:[~2022-06-02 9:39 UTC | newest]
Thread overview: 4+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2022-05-31 11:09 bug#55737: [PATCH] 28.1; Values of `read-process-output-max' above 64k not taken into account on GNU/Linux Frédéric Giquel via Bug reports for GNU Emacs, the Swiss army knife of text editors
2022-05-31 12:00 ` Eli Zaretskii
2022-06-01 6:09 ` Frédéric Giquel via Bug reports for GNU Emacs, the Swiss army knife of text editors
2022-06-02 9:39 ` Lars Ingebrigtsen
Code repositories for project(s) associated with this public inbox
https://git.savannah.gnu.org/cgit/emacs.git
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).