Re: Re: [RFC PATCH 07/10] scsi/trace: Use scsi_show_result trace point instead of printk
Hi Christoph, Sorry for the late reply. (2014/08/29 9:50), Christoph Hellwig wrote: I'm not sure this is the correct way. Currently we have quite some code duplication in scsi_trace.c and constants.c, correct. So I definitely would like to see them both merged. But constants.c is influenced by CONFIG_SCSI_CONSTANTS, whereas scsi_trace isn't, and the functions in constants.c are used throughout the scsi stack. So I'd rather see to have scsi_trace to be updated to use the functions from constants.c, and remove the duplicate code in scsi_trace. The tracepoints need to use the magic print_flags & co helpers so that output works properly if using the binary tracebuffer and user space tools that decoded it (e.g. trace-cmd or perf), so using a kernel function for decoding is not an option. Ah, I see. The "format" files in SCSI traceevents output decoders, so we don't need to implement own decoders in userland. I think the current problem is duplicated decoders, so we'll consolidate those. If we use decoders in constants.c, the decoders are not output in format file, so user tools cannot decode the binary. On the other hand, if we use decoders in scsi_trace.c, the output format of command names is changed and there are unsupported command names. We would use decoders in scsi_trace.c and add new command names to decoders in scsi_trace.c, I think. How do you think about this? Hannes? As another topic, we found that we cannot decode SCSI traceevents by using current decoder in format files. For example, format file of scsi_dispatch_cmd_timeout outputs prot_op as follows: __print_symbolic(REC->prot_op, { SCSI_PROT_NORMAL, "SCSI_PROT_NORMAL" }, { SCSI_PROT_READ_INSERT, "SCSI_PROT_READ_INSERT" }, { SCSI_PROT_WRITE_STRIP, "SCSI_PROT_WRITE_STRIP" }, { SCSI_PROT_READ_STRIP, "SCSI_PROT_READ_STRIP" }, { SCSI_PROT_WRITE_INSERT, "SCSI_PROT_WRITE_INSERT" }, { SCSI_PROT_READ_PASS, "SCSI_PROT_READ_PASS" }, { SCSI_PROT_WRITE_PASS, "SCSI_PROT_WRITE_PASS" }) Decoding will fail to do macro expansion here, so we need to fix this. (We don't use enum for traceevents.) Thanks, Yoshihiro YUNOMAE But we can make these tracepoints dependent on CONFIG_SCSI_CONSTANTS to still allow building lighter kernels if we really care about it. -- To unsubscribe from this list: send the line "unsubscribe linux-scsi" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html -- Yoshihiro YUNOMAE Software Platform Research Dept. Linux Technology Center Hitachi, Ltd., Yokohama Research Laboratory E-mail: yoshihiro.yunomae...@hitachi.com -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
Re: Re: [PATCH 1/3] scsi/trace: Use macros for getting driver byte, host byte, msg byte, and status byte
(2014/09/02 0:15), Christoph Hellwig wrote: On Mon, Sep 01, 2014 at 12:33:28PM +, Yoshihiro YUNOMAE wrote: For getting driver byte, host byte, msg byte, and status byte, macros are implemented in scsi/scsi.h, so we use it. As mentioned about three times in various previous scsi logging discussions this is entirely wrong and breaks decoding binary trace buffers. No, this patch uses just macros, so this does not change decoders. However, other patches change decoders in format files, so we need to consider about these decoders more, as you say. We'll discuss on https://lkml.org/lkml/2014/8/28/657. Thanks, Yoshihiro YUNOMAE -- Yoshihiro YUNOMAE Software Platform Research Dept. Linux Technology Center Hitachi, Ltd., Yokohama Research Laboratory E-mail: yoshihiro.yunomae...@hitachi.com -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[PATCH 3/3] scsi/trace: Delete a duplicated decoder of SCSI command
There is a decoder of SCSI command in constants.c, so this patch deletes it in SCSI traveevents. A decoder in traceevents uses macros, so the command name is output as "XXX_YYY_ZZZ". On the other hand, a decoder in constants uses strings, so the command name is output as "Xxx Yyy Zzz" including space. We use a decoder in constants, so this patch adds double quotes for the name. Note: - If CONFIG_SCSI_CONSTANTS is disabled, command names are not shown. - Add command names for 0x07 and 0x2b. Signed-off-by: Yoshihiro YUNOMAE Cc: Hannes Reinecke Cc: Doug Gilbert Cc: Martin K. Petersen Cc: Christoph Hellwig Cc: "James E.J. Bottomley" Cc: Robert Elliott Cc: Ewan D. Milne Cc: Hidehiro Kawai Cc: Masami Hiramatsu --- drivers/scsi/constants.c| 13 +++- include/scsi/scsi.h |1 include/trace/events/scsi.h | 130 +-- 3 files changed, 37 insertions(+), 107 deletions(-) diff --git a/drivers/scsi/constants.c b/drivers/scsi/constants.c index 8c1f7ac..50e08c8 100644 --- a/drivers/scsi/constants.c +++ b/drivers/scsi/constants.c @@ -36,7 +36,7 @@ static const char * cdb_byte0_names[] = { /* 00-03 */ "Test Unit Ready", "Rezero Unit/Rewind", NULL, "Request Sense", /* 04-07 */ "Format Unit/Medium", "Read Block Limits", NULL, - "Reassign Blocks", + "Reassign Blocks/Initialize Element Status", /* 08-0d */ "Read(6)", NULL, "Write(6)", "Seek(6)", NULL, NULL, /* 0e-12 */ NULL, "Read Reverse", "Write Filemarks", "Space", "Inquiry", /* 13-16 */ "Verify(6)", "Recover Buffered Data", "Mode Select(6)", @@ -47,8 +47,8 @@ static const char * cdb_byte0_names[] = { /* 20-22 */ NULL, NULL, NULL, /* 23-28 */ "Read Format Capacities", "Set Window", "Read Capacity(10)", NULL, NULL, "Read(10)", -/* 29-2d */ "Read Generation", "Write(10)", "Seek(10)", "Erase(10)", -"Read updated block", +/* 29-2d */ "Read Generation", "Write(10)", "Seek(10)/Position To Element", + "Erase(10)", "Read updated block", /* 2e-31 */ "Write Verify(10)", "Verify(10)", "Search High", "Search Equal", /* 32-34 */ "Search Low", "Set Limits", "Prefetch/Read Position", /* 35-37 */ "Synchronize Cache(10)", "Lock/Unlock Cache(10)", @@ -103,6 +103,11 @@ static const char * cdb_byte0_names[] = { "Volume set (out), Send DVD structure", }; +inline const char *show_opcode_name(int cdb0) +{ + return cdb_byte0_names[cdb0]; +} + struct value_name_pair { int value; const char * name; @@ -365,7 +370,7 @@ static void print_opcode_name(struct scsi_device *sdev, const char *prefix, if (cdb0 < 0xc0) { cdb_classifier = NULL; #ifdef CONFIG_SCSI_CONSTANTS - cdb_name = cdb_byte0_names[cdb0]; + cdb_name = show_opcode_name(cdb0); if (!cdb_name) cdb_classifier = " (reserved)"; #endif diff --git a/include/scsi/scsi.h b/include/scsi/scsi.h index 6d6b3ef..59fedff 100644 --- a/include/scsi/scsi.h +++ b/include/scsi/scsi.h @@ -587,6 +587,7 @@ static inline __u32 scsi_to_u32(__u8 *ptr) } #ifdef CONFIG_SCSI_CONSTANTS +inline const char *show_opcode_name(int cdb0); inline const char *show_hostbyte_name(int hb); inline const char *show_driverbyte_name(int db); #endif diff --git a/include/trace/events/scsi.h b/include/trace/events/scsi.h index 67be592..5695ad7 100644 --- a/include/trace/events/scsi.h +++ b/include/trace/events/scsi.h @@ -9,102 +9,6 @@ #include #include -#define scsi_opcode_name(opcode) { opcode, #opcode } -#define show_opcode_name(val) \ - __print_symbolic(val, \ - scsi_opcode_name(TEST_UNIT_READY), \ - scsi_opcode_name(REZERO_UNIT), \ - scsi_opcode_name(REQUEST_SENSE),\ - scsi_opcode_name(FORMAT_UNIT), \ - scsi_opcode_name(READ_BLOCK_LIMITS),\ - scsi_opcode_name(REASSIGN_BLOCKS), \ - scsi_opcode_name(INITIALIZE_ELEMENT_STATUS),\ - scsi_opcode_name(READ_6), \ - scsi_opcode_name(WRITE_6), \ - scsi_opcode_name(SEEK_6), \ - scsi_opcode_name(READ_REVERSE), \ - scsi_opcode_name(WRITE_FILEMARKS), \ - scsi_opcode_name(SPACE),
[PATCH 1/3] scsi/trace: Use macros for getting driver byte, host byte, msg byte, and status byte
For getting driver byte, host byte, msg byte, and status byte, macros are implemented in scsi/scsi.h, so we use it. Signed-off-by: Yoshihiro YUNOMAE Reviewed-by: Ewan D. Milne Reviewed-by: Hannes Reinecke Cc: Hannes Reinecke Cc: Doug Gilbert Cc: Martin K. Petersen Cc: Christoph Hellwig Cc: "James E.J. Bottomley" Cc: Robert Elliott Cc: Ewan D. Milne Cc: Hidehiro Kawai Cc: Masami Hiramatsu --- include/trace/events/scsi.h |8 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/include/trace/events/scsi.h b/include/trace/events/scsi.h index db6c935..8aecdc2 100644 --- a/include/trace/events/scsi.h +++ b/include/trace/events/scsi.h @@ -328,10 +328,10 @@ DECLARE_EVENT_CLASS(scsi_cmd_done_timeout_template, show_opcode_name(__entry->opcode), __parse_cdb(__get_dynamic_array(cmnd), __entry->cmd_len), __print_hex(__get_dynamic_array(cmnd), __entry->cmd_len), - show_driverbyte_name(((__entry->result) >> 24) & 0xff), - show_hostbyte_name(((__entry->result) >> 16) & 0xff), - show_msgbyte_name(((__entry->result) >> 8) & 0xff), - show_statusbyte_name(__entry->result & 0xff)) + show_driverbyte_name(driver_byte(__entry->result)), + show_hostbyte_name(host_byte(__entry->result)), + show_msgbyte_name(msg_byte(__entry->result)), + show_statusbyte_name(status_byte(__entry->result))) ); DEFINE_EVENT(scsi_cmd_done_timeout_template, scsi_dispatch_cmd_done, -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[ PATCH -logging 0/3] scsi/trace: Delete duplicated decoders
Hi All, This patchset deletes duplicated decoders in scsi_trace.c. Almost decoders are implemented in constants.c, so we should use them. This patchset deletes following decoders in scsi_trace.c: - hostbyte in patch [2/3] - driverbyte in patch [2/3] - SCSI command in patch [3/3] This patchset is based on Hannes' logging branch: http://git.kernel.org/cgit/linux/kernel/git/hare/scsi-devel.git/log/?h=logging Thanks, Yoshihiro YUNOMAE --- Yoshihiro YUNOMAE (3): scsi/trace: Use macros for getting driver byte, host byte, msg byte, and status byte scsi/trace: Delete duplicated decoders of hostbyte and driverbyte scsi/trace: Delete a duplicated decoder of SCSI command drivers/scsi/constants.c| 34 +--- include/scsi/scsi.h |6 + include/trace/events/scsi.h | 179 ++- 3 files changed, 68 insertions(+), 151 deletions(-) -- Yoshihiro YUNOMAE Software Platform Research Dept. Linux Technology Center Hitachi, Ltd., Yokohama Research Laboratory E-mail: yoshihiro.yunomae...@hitachi.com -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[PATCH 2/3] scsi/trace: Delete duplicated decoders of hostbyte and driverbyte
There are decoders of hostbyte and driverbyte in constants.c, so this patch deletes those in SCSI traveevents. Note: If CONFIG_SCSI_CONSTANTS is disabled, hostbyte, driverbyte, msgbyte, and statusbyte are output as raw format from this patch. Signed-off-by: Yoshihiro YUNOMAE Cc: Hannes Reinecke Cc: Doug Gilbert Cc: Martin K. Petersen Cc: Christoph Hellwig Cc: "James E.J. Bottomley" Cc: Robert Elliott Cc: Ewan D. Milne Cc: Hidehiro Kawai Cc: Masami Hiramatsu --- drivers/scsi/constants.c| 21 ++- include/scsi/scsi.h |5 + include/trace/events/scsi.h | 47 +-- 3 files changed, 30 insertions(+), 43 deletions(-) diff --git a/drivers/scsi/constants.c b/drivers/scsi/constants.c index c6a7a4a..8c1f7ac 100644 --- a/drivers/scsi/constants.c +++ b/drivers/scsi/constants.c @@ -1505,21 +1505,22 @@ static const char * const driverbyte_table[]={ "DRIVER_INVALID", "DRIVER_TIMEOUT", "DRIVER_HARD", "DRIVER_SENSE"}; #define NUM_DRIVERBYTE_STRS ARRAY_SIZE(driverbyte_table) -void scsi_show_result(struct scsi_device *sdev, const char *name, int result) +inline const char *show_hostbyte_name(int hb) { - int hb = host_byte(result); - int db = driver_byte(result); - const char *hb_string; - const char *db_string; - - hb_string = (hb < NUM_HOSTBYTE_STRS) ? hostbyte_table[hb] : "invalid"; - db_string = (db < NUM_DRIVERBYTE_STRS) ? - driverbyte_table[db] : "invalid"; + return (hb < NUM_HOSTBYTE_STRS) ? hostbyte_table[hb] : "invalid"; +} +inline const char *show_driverbyte_name(int db) +{ + return (db < NUM_DRIVERBYTE_STRS) ? driverbyte_table[db] : "invalid"; +} +void scsi_show_result(struct scsi_device *sdev, const char *name, int result) +{ sdev_printk(KERN_INFO, sdev, "[%s] Result: hostbyte=%s driverbyte=%s\n", - name, hb_string, db_string); + name, show_hostbyte_name(host_byte(result)), + show_driverbyte_name(driver_byte(result))); } #else diff --git a/include/scsi/scsi.h b/include/scsi/scsi.h index 54ebf54..6d6b3ef 100644 --- a/include/scsi/scsi.h +++ b/include/scsi/scsi.h @@ -586,4 +586,9 @@ static inline __u32 scsi_to_u32(__u8 *ptr) return (ptr[0]<<24) + (ptr[1]<<16) + (ptr[2]<<8) + ptr[3]; } +#ifdef CONFIG_SCSI_CONSTANTS +inline const char *show_hostbyte_name(int hb); +inline const char *show_driverbyte_name(int db); +#endif + #endif /* _SCSI_SCSI_H */ diff --git a/include/trace/events/scsi.h b/include/trace/events/scsi.h index 8aecdc2..67be592 100644 --- a/include/trace/events/scsi.h +++ b/include/trace/events/scsi.h @@ -105,39 +105,6 @@ scsi_opcode_name(ATA_16), \ scsi_opcode_name(ATA_12)) -#define scsi_hostbyte_name(result) { result, #result } -#define show_hostbyte_name(val)\ - __print_symbolic(val, \ - scsi_hostbyte_name(DID_OK), \ - scsi_hostbyte_name(DID_NO_CONNECT), \ - scsi_hostbyte_name(DID_BUS_BUSY), \ - scsi_hostbyte_name(DID_TIME_OUT), \ - scsi_hostbyte_name(DID_BAD_TARGET), \ - scsi_hostbyte_name(DID_ABORT), \ - scsi_hostbyte_name(DID_PARITY), \ - scsi_hostbyte_name(DID_ERROR), \ - scsi_hostbyte_name(DID_RESET), \ - scsi_hostbyte_name(DID_BAD_INTR), \ - scsi_hostbyte_name(DID_PASSTHROUGH),\ - scsi_hostbyte_name(DID_SOFT_ERROR), \ - scsi_hostbyte_name(DID_IMM_RETRY), \ - scsi_hostbyte_name(DID_REQUEUE),\ - scsi_hostbyte_name(DID_TRANSPORT_DISRUPTED),\ - scsi_hostbyte_name(DID_TRANSPORT_FAILFAST)) - -#define scsi_driverbyte_name(result) { result, #result } -#define show_driverbyte_name(val) \ - __print_symbolic(val, \ - scsi_driverbyte_name(DRIVER_OK),\ - scsi_driverbyte_name(DRIVER_BUSY), \ - scsi_driverbyte_name(DRIVER_SOFT), \ - scsi_driverbyte_name(DRIVER_MEDIA), \ - scsi_driverbyte_name(DRIVER_ERROR), \ - scsi_driverbyte_name(DRIVER_INVALID), \ - scsi_driverbyte_name(DRIVER_TIMEOUT), \ - scsi_driverbyte_name(DRIVER_HARD), \ -
Re: [RFC PATCH 10/10] scsi/trace: Use scsi_print_command trace point instead of printk
Hi Hannes, Sorry for the late reply. (2014/08/28 21:15), Hannes Reinecke wrote: On 08/28/2014 08:19 AM, Yoshihiro YUNOMAE wrote: Hi Hannes, I tried to remove duplicated decoder of SCSI command, but the output format of it in constants.c is different from it in traceevents. I have two questions for it. (Ex1) traceevents: TEST_UNIT_READY constants: Test Unit Ready => Which of "XXX_YYY_ZZZ" and "Xxx Yyy Zzz" should the kernel output strings? This difference comes from difference of implementation. The decoder in traceevents are using macro. So, it cannot define separated words. On the other hand, the decoder in constants are using constant string array table. So, it can define separated words. I would go with the wording in constants.c, but set in double quotes like "Test Unit Ready" to avoid parsing errors later on. OK, we use constants' format and add double quotes for each sense code. (Ex2) traceevents: (nothing) constants: Set limits(12) => Should we merge those decoder? Yes, I would prefer this. Again, we should be setting the strings in double quotes irrespective if there are spaces in the resulting string or not. Sure. I understand we use the decoder of constants, but we need to solve these problems. Would you give me your comments? As mentioned previously, my aim is to convert the logging system in several steps: a) convert all lone 'printk' statements into dev_printk() variants and ensure everything is printed in one statement to avoid linebreaks in the resulting logging message. This will eliminate the immediate problem we're having, namely that debugging is near to impossible under high load. The patchset is nearing completion, and I will be posting it later this week. b) Convert scsi_trace to use the functions from constants.c to avoid code duplication and update scsi_trace to log sense codes. c) Remove all logging functions in the hot path (ie SCSI_LOG_MLQUEUE and SCSI_LOG_MLCOMPLETE) and replace them with trace events. b) is what you're working on, right? Right. For 'c)' the problem is that we should retain the existing functionality with scsi_logging_level here, at least initially. So we cannot just replace it, as this would leave SCSI_LOG_ML a dummy without any real functionality. I tried to change printk messages to new tracevents, but I'll stop it until we solve the problem. I'll submit the patch set removing duplicated decoder first. Thanks, Yoshihiro YUNOMAE -- Yoshihiro YUNOMAE Software Platform Research Dept. Linux Technology Center Hitachi, Ltd., Yokohama Research Laboratory E-mail: yoshihiro.yunomae...@hitachi.com -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
Re: Re: Re: [RFC PATCH 10/10] scsi/trace: Use scsi_print_command trace point instead of printk
Hi Hannes, I tried to remove duplicated decoder of SCSI command, but the output format of it in constants.c is different from it in traceevents. I have two questions for it. (Ex1) traceevents: TEST_UNIT_READY constants: Test Unit Ready => Which of "XXX_YYY_ZZZ" and "Xxx Yyy Zzz" should the kernel output strings? This difference comes from difference of implementation. The decoder in traceevents are using macro. So, it cannot define separated words. On the other hand, the decoder in constants are using constant string array table. So, it can define separated words. (Ex2) traceevents: (nothing) constants: Set limits(12) => Should we merge those decoder? I understand we use the decoder of constants, but we need to solve these problems. Would you give me your comments? Thanks, Yoshihiro YUNOMAE (2014/08/28 10:40), Yoshihiro YUNOMAE wrote: (2014/08/27 23:16), Hannes Reinecke wrote: On 08/08/2014 01:50 PM, Yoshihiro YUNOMAE wrote: Previous printk messages of SCSI command can be mixed into other printk messages because multiple printk messages are output for it. To avoid the problem, patch 4e64bb8d6 in Hannes' branch(*1) introduced a local buffer. But using local buffers can induce stack overflow, so we want to solve the problem without local buffer if possible. trace_seq_printf can add log messages without local buffer, so we use it. Note: We don't need constans.c any more. (*1) http://git.kernel.org/cgit/linux/kernel/git/hare/scsi-devel.git/log/?h=logging - Result examples (printk) sd 2:0:0:0: [sda] CDB: Read(10) scsi_print_command: host_no=2 channel=0 id=0 lun=0 [sda] CDB (Read(10)) Signed-off-by: Yoshihiro YUNOMAE Cc: Hannes Reinecke Cc: Doug Gilbert Cc: Martin K. Petersen Cc: Christoph Hellwig Cc: "James E.J. Bottomley" Cc: Hidehiro Kawai Cc: Masami Hiramatsu --- drivers/scsi/Makefile |2 drivers/scsi/constants.c| 425 --- drivers/scsi/scsi_trace.c | 408 + include/scsi/scsi.h |8 + include/trace/events/scsi.h | 45 + 5 files changed, 461 insertions(+), 427 deletions(-) delete mode 100644 drivers/scsi/constants.c diff --git a/drivers/scsi/Makefile b/drivers/scsi/Makefile index 5f0d299..c56f692 100644 --- a/drivers/scsi/Makefile +++ b/drivers/scsi/Makefile @@ -158,7 +158,7 @@ obj-$(CONFIG_SCSI_OSD_INITIATOR) += osd/ # This goes last, so that "real" scsi devices probe earlier obj-$(CONFIG_SCSI_DEBUG)+= scsi_debug.o -scsi_mod-y+= scsi.o hosts.o scsi_ioctl.o constants.o \ +scsi_mod-y+= scsi.o hosts.o scsi_ioctl.o \ scsicam.o scsi_error.o scsi_lib.o scsi_mod-$(CONFIG_SCSI_DMA)+= scsi_lib_dma.o scsi_mod-y+= scsi_scan.o scsi_sysfs.o scsi_devinfo.o diff --git a/drivers/scsi/constants.c b/drivers/scsi/constants.c deleted file mode 100644 index ce9ceb8..000 --- a/drivers/scsi/constants.c +++ /dev/null @@ -1,425 +0,0 @@ -/* - * ASCII values for a number of symbolic constants, printing functions, - * etc. - * Additions for SCSI 2 and Linux 2.2.x by D. Gilbert (990422) - * Additions for SCSI 3+ (SPC-3 T10/1416-D Rev 07 3 May 2002) - * by D. Gilbert and aeb (20020609) - * Updated to SPC-4 T10/1713-D Rev 36g, D. Gilbert 20130701 - */ - -#include -#include -#include -#include - -#include -#include - -/* Commands with service actions that change the command name */ -#define SERVICE_ACTION_IN_12 0xab -#define SERVICE_ACTION_OUT_12 0xa9 -#define SERVICE_ACTION_BIDIRECTIONAL 0x9d -#define SERVICE_ACTION_IN_16 0x9e -#define SERVICE_ACTION_OUT_16 0x9f -#define THIRD_PARTY_COPY_OUT 0x83 -#define THIRD_PARTY_COPY_IN 0x84 - - - -#ifdef CONFIG_SCSI_CONSTANTS -static const char * cdb_byte0_names[] = { -/* 00-03 */ "Test Unit Ready", "Rezero Unit/Rewind", NULL, "Request Sense", -/* 04-07 */ "Format Unit/Medium", "Read Block Limits", NULL, -"Reassign Blocks", -/* 08-0d */ "Read(6)", NULL, "Write(6)", "Seek(6)", NULL, NULL, -/* 0e-12 */ NULL, "Read Reverse", "Write Filemarks", "Space", "Inquiry", -/* 13-16 */ "Verify(6)", "Recover Buffered Data", "Mode Select(6)", -"Reserve(6)", -/* 17-1a */ "Release(6)", "Copy", "Erase", "Mode Sense(6)", -/* 1b-1d */ "Start/Stop Unit", "Receive Diagnostic", "Send Diagnostic", -/* 1e-1f */ "Prevent/Allow Medium Removal", NULL, -/* 20-22 */ NULL, NULL, NULL, -/* 23-28 */ "Read Format Capacities", "Set Window", -"Read Capacity(10)", NULL, NULL, "Read(10)", -/* 29-2d */ "Read Generation", "Write(10)", "Seek(10)", "Erase(10)", -"Read updated block
Re: Re: [RFC PATCH 10/10] scsi/trace: Use scsi_print_command trace point instead of printk
(2014/08/27 23:16), Hannes Reinecke wrote: On 08/08/2014 01:50 PM, Yoshihiro YUNOMAE wrote: Previous printk messages of SCSI command can be mixed into other printk messages because multiple printk messages are output for it. To avoid the problem, patch 4e64bb8d6 in Hannes' branch(*1) introduced a local buffer. But using local buffers can induce stack overflow, so we want to solve the problem without local buffer if possible. trace_seq_printf can add log messages without local buffer, so we use it. Note: We don't need constans.c any more. (*1) http://git.kernel.org/cgit/linux/kernel/git/hare/scsi-devel.git/log/?h=logging - Result examples (printk) sd 2:0:0:0: [sda] CDB: Read(10) scsi_print_command: host_no=2 channel=0 id=0 lun=0 [sda] CDB (Read(10)) Signed-off-by: Yoshihiro YUNOMAE Cc: Hannes Reinecke Cc: Doug Gilbert Cc: Martin K. Petersen Cc: Christoph Hellwig Cc: "James E.J. Bottomley" Cc: Hidehiro Kawai Cc: Masami Hiramatsu --- drivers/scsi/Makefile |2 drivers/scsi/constants.c| 425 --- drivers/scsi/scsi_trace.c | 408 + include/scsi/scsi.h |8 + include/trace/events/scsi.h | 45 + 5 files changed, 461 insertions(+), 427 deletions(-) delete mode 100644 drivers/scsi/constants.c diff --git a/drivers/scsi/Makefile b/drivers/scsi/Makefile index 5f0d299..c56f692 100644 --- a/drivers/scsi/Makefile +++ b/drivers/scsi/Makefile @@ -158,7 +158,7 @@ obj-$(CONFIG_SCSI_OSD_INITIATOR) += osd/ # This goes last, so that "real" scsi devices probe earlier obj-$(CONFIG_SCSI_DEBUG)+= scsi_debug.o -scsi_mod-y+= scsi.o hosts.o scsi_ioctl.o constants.o \ +scsi_mod-y+= scsi.o hosts.o scsi_ioctl.o \ scsicam.o scsi_error.o scsi_lib.o scsi_mod-$(CONFIG_SCSI_DMA)+= scsi_lib_dma.o scsi_mod-y+= scsi_scan.o scsi_sysfs.o scsi_devinfo.o diff --git a/drivers/scsi/constants.c b/drivers/scsi/constants.c deleted file mode 100644 index ce9ceb8..000 --- a/drivers/scsi/constants.c +++ /dev/null @@ -1,425 +0,0 @@ -/* - * ASCII values for a number of symbolic constants, printing functions, - * etc. - * Additions for SCSI 2 and Linux 2.2.x by D. Gilbert (990422) - * Additions for SCSI 3+ (SPC-3 T10/1416-D Rev 07 3 May 2002) - * by D. Gilbert and aeb (20020609) - * Updated to SPC-4 T10/1713-D Rev 36g, D. Gilbert 20130701 - */ - -#include -#include -#include -#include - -#include -#include - -/* Commands with service actions that change the command name */ -#define SERVICE_ACTION_IN_12 0xab -#define SERVICE_ACTION_OUT_12 0xa9 -#define SERVICE_ACTION_BIDIRECTIONAL 0x9d -#define SERVICE_ACTION_IN_16 0x9e -#define SERVICE_ACTION_OUT_16 0x9f -#define THIRD_PARTY_COPY_OUT 0x83 -#define THIRD_PARTY_COPY_IN 0x84 - - - -#ifdef CONFIG_SCSI_CONSTANTS -static const char * cdb_byte0_names[] = { -/* 00-03 */ "Test Unit Ready", "Rezero Unit/Rewind", NULL, "Request Sense", -/* 04-07 */ "Format Unit/Medium", "Read Block Limits", NULL, -"Reassign Blocks", -/* 08-0d */ "Read(6)", NULL, "Write(6)", "Seek(6)", NULL, NULL, -/* 0e-12 */ NULL, "Read Reverse", "Write Filemarks", "Space", "Inquiry", -/* 13-16 */ "Verify(6)", "Recover Buffered Data", "Mode Select(6)", -"Reserve(6)", -/* 17-1a */ "Release(6)", "Copy", "Erase", "Mode Sense(6)", -/* 1b-1d */ "Start/Stop Unit", "Receive Diagnostic", "Send Diagnostic", -/* 1e-1f */ "Prevent/Allow Medium Removal", NULL, -/* 20-22 */ NULL, NULL, NULL, -/* 23-28 */ "Read Format Capacities", "Set Window", -"Read Capacity(10)", NULL, NULL, "Read(10)", -/* 29-2d */ "Read Generation", "Write(10)", "Seek(10)", "Erase(10)", -"Read updated block", -/* 2e-31 */ "Write Verify(10)", "Verify(10)", "Search High", "Search Equal", -/* 32-34 */ "Search Low", "Set Limits", "Prefetch/Read Position", -/* 35-37 */ "Synchronize Cache(10)", "Lock/Unlock Cache(10)", -"Read Defect Data(10)", -/* 38-3c */ "Medium Scan", "Compare", "Copy Verify", "Write Buffer", -"Read Buffer", -/* 3d-3f */ "Update Block", "Read Long(10)", "Write Long(10)", -/* 40-41 */ "Change Definition", "Write Same(10)", -/* 42-48 */ "Unmap/Read sub-channel", "Read TOC/PMA/ATIP", -"Read density support", "Play audio(10)", "Get configuration", -"Play audio msf", &
Re: Re: [RFC PATCH 09/10] scsi/trace: Add additional sense code and additional sense code qualifier to scsi_print_sense trace point
(2014/08/27 23:16), Hannes Reinecke wrote: On 08/08/2014 01:50 PM, Yoshihiro YUNOMAE wrote: There are no mean that additional sense code and additional sense code qualifier are output as different messages of sense key, so those information are added. Note: scsi_show_extd_sense() is changed from export symbol to non-export symbol. - Result examples (printk) sd 2:0:0:0: [sda] Add. Sense: Unrecovered read error (ftrace, merged into scsi_print_sense traceevent) scsi_print_sense: host_no=2 channel=0 id=0 lun=0 [sda] Sense Key (Medium Error [current]) Add. Sense (Unrecovered read error) Signed-off-by: Yoshihiro YUNOMAE Cc: Hannes Reinecke Cc: Doug Gilbert Cc: Martin K. Petersen Cc: Christoph Hellwig Cc: "James E.J. Bottomley" Cc: Hidehiro Kawai Cc: Masami Hiramatsu --- drivers/scsi/constants.c| 932 --- drivers/scsi/scsi_trace.c | 920 ++ include/scsi/scsi_dbg.h |2 include/trace/events/scsi.h | 10 4 files changed, 928 insertions(+), 936 deletions(-) diff --git a/drivers/scsi/constants.c b/drivers/scsi/constants.c index 85b75c8..ce9ceb8 100644 --- a/drivers/scsi/constants.c +++ b/drivers/scsi/constants.c @@ -14,12 +14,6 @@ #include #include -#include -#include -#include -#include - -#include /* Commands with service actions that change the command name */ #define SERVICE_ACTION_IN_12 0xab @@ -429,929 +423,3 @@ void scsi_print_command(struct scsi_cmnd *cmd) print_opcode_name(cmd->device, devname, cmd->cmnd, cmd->cmd_len); } EXPORT_SYMBOL(scsi_print_command); - -#ifdef CONFIG_SCSI_CONSTANTS - -struct error_info { -unsigned short code12;/* 0x0302 looks better than 0x03,0x02 */ -const char * text; -}; - -/* - * The canonical list of T10 Additional Sense Codes is available at: - * http://www.t10.org/lists/asc-num.txt [most recent: 20130605] - */ - -static const struct error_info additional[] = -{ -{0x, "No additional sense information"}, -{0x0001, "Filemark detected"}, -{0x0002, "End-of-partition/medium detected"}, -{0x0003, "Setmark detected"}, -{0x0004, "Beginning-of-partition/medium detected"}, -{0x0005, "End-of-data detected"}, -{0x0006, "I/O process terminated"}, -{0x0007, "Programmable early warning detected"}, -{0x0011, "Audio play operation in progress"}, -{0x0012, "Audio play operation paused"}, -{0x0013, "Audio play operation successfully completed"}, -{0x0014, "Audio play operation stopped due to error"}, -{0x0015, "No current audio status to return"}, -{0x0016, "Operation in progress"}, -{0x0017, "Cleaning requested"}, -{0x0018, "Erase operation in progress"}, -{0x0019, "Locate operation in progress"}, -{0x001A, "Rewind operation in progress"}, -{0x001B, "Set capacity operation in progress"}, -{0x001C, "Verify operation in progress"}, -{0x001D, "ATA pass through information available"}, -{0x001E, "Conflicting SA creation request"}, -{0x001F, "Logical unit transitioning to another power condition"}, -{0x0020, "Extended copy information available"}, - -{0x0100, "No index/sector signal"}, - -{0x0200, "No seek complete"}, - -{0x0300, "Peripheral device write fault"}, -{0x0301, "No write current"}, -{0x0302, "Excessive write errors"}, - -{0x0400, "Logical unit not ready, cause not reportable"}, -{0x0401, "Logical unit is in process of becoming ready"}, -{0x0402, "Logical unit not ready, initializing command required"}, -{0x0403, "Logical unit not ready, manual intervention required"}, -{0x0404, "Logical unit not ready, format in progress"}, -{0x0405, "Logical unit not ready, rebuild in progress"}, -{0x0406, "Logical unit not ready, recalculation in progress"}, -{0x0407, "Logical unit not ready, operation in progress"}, -{0x0408, "Logical unit not ready, long write in progress"}, -{0x0409, "Logical unit not ready, self-test in progress"}, -{0x040A, "Logical unit not accessible, asymmetric access state " - "transition"}, -{0x040B, "Logical unit not accessible, target port in standby state"}, -{0x040C, "Logical unit not accessible, target port in unavailable " - "state"}, -{0x040D, "Logical unit not ready, structure check required"}, -{0x0410, "Logical unit not ready, auxiliary memory not accessible"}, -{0x0411, "Logical unit not ready, notify (enable spinup) required"}, -
Re: Re: [RFC PATCH 08/10] scsi/trace: Use scsi_print_sense trace point instead of printk
(2014/08/27 23:15), Hannes Reinecke wrote: On 08/08/2014 01:50 PM, Yoshihiro YUNOMAE wrote: Previous sense messages can be mixed into other sense messages, because continuous printk (KERN_CONT) was used. To avoid the problem, patch d87f3a6f51 introduced a local buffer in Hannes's baranch (*1). But using local buffers can induce stack overflow, so we want to solve the problem without local buffer if possible. trace_seq_printf can add log messages without local buffer, so we use it. (*1) http://git.kernel.org/cgit/linux/kernel/git/hare/scsi-devel.git/log/?h=logging - Result examples (printk) sd 2:0:0:0: [sda] Sense Key : Medium Error [current] (ftrace) scsi_print_sense: host_no=2 channel=0 id=0 lun=0 [sda] Sense Key (Medium Error [current]) Signed-off-by: Yoshihiro YUNOMAE Cc: Hannes Reinecke Cc: Doug Gilbert Cc: Martin K. Petersen Cc: Christoph Hellwig Cc: "James E.J. Bottomley" Cc: Hidehiro Kawai Cc: Masami Hiramatsu --- drivers/scsi/constants.c| 145 ++- drivers/scsi/scsi_trace.c | 140 -- include/scsi/scsi_eh.h |7 ++ include/trace/events/scsi.h | 48 ++ 4 files changed, 195 insertions(+), 145 deletions(-) diff --git a/drivers/scsi/constants.c b/drivers/scsi/constants.c index f7b7f32..85b75c8 100644 --- a/drivers/scsi/constants.c +++ b/drivers/scsi/constants.c @@ -19,7 +19,7 @@ #include #include - +#include /* Commands with service actions that change the command name */ #define SERVICE_ACTION_IN_12 0xab @@ -1267,58 +1267,8 @@ static const struct error_info2 additional2[] = {0x70, 0x00, 0xff, "Decompression exception short algorithm id of %x"}, {0, 0, 0, NULL} }; - -/* description of the sense key values */ -static const char * const snstext[] = { -"No Sense",/* 0: There is no sense information */ -"Recovered Error", /* 1: The last command completed successfully - but used error correction */ -"Not Ready",/* 2: The addressed target is not ready */ -"Medium Error",/* 3: Data error detected on the medium */ -"Hardware Error", /* 4: Controller or device failure */ -"Illegal Request", /* 5: Error in request */ -"Unit Attention", /* 6: Removable medium was changed, or - the target has been reset, or ... */ -"Data Protect",/* 7: Access to the data is blocked */ -"Blank Check",/* 8: Reached unexpected written or unwritten - region of the medium */ -"Vendor Specific(9)", -"Copy Aborted",/* A: COPY or COMPARE was aborted */ -"Aborted Command", /* B: The target aborted the command */ -"Equal",/* C: A SEARCH DATA command found data equal, - reserved in SPC-4 rev 36 */ -"Volume Overflow", /* D: Medium full with still data to be written */ -"Miscompare",/* E: Source data and data on the medium - do not agree */ -"Completed",/* F: command completed sense data reported, - may occur for successful command */ -}; -#else -static const char * const snstext[] = { -"0x0", "0x1", "0x2", "0x3", "0x4", "0x5", "0x6", "0x7", -"0x8", "0x9", "0xa", "0xb", "0xc", "0xd", "0xe", "0xf", -}; #endif -/* Get sense key string or NULL if not available */ -const char * -scsi_sense_key_string(unsigned char key) { -return snstext[key & 0xf]; -} -EXPORT_SYMBOL(scsi_sense_key_string); - -const char * -scsi_sense_type_string(struct scsi_sense_hdr *sshdr) -{ -return scsi_sense_is_deferred(sshdr) ? "[deferred]" : "[current]"; -} - -const char * -scsi_sense_format_string(struct scsi_sense_hdr *sshdr) -{ -return sshdr->response_code >= 0x72 ? "[descriptor]" : ""; -} - /* * Get additional sense code string or NULL if not available. * This string may contain a "%x" and should be printed with ascq as arg. @@ -1375,105 +1325,22 @@ void scsi_print_sense_hdr(struct scsi_device *sdev, const char *name, struct scsi_sense_hdr *sshdr) { -sdev_printk(KERN_INFO, sdev, "[%s] Sense Key : %s %s%s\n", name, -scsi_sense_key_string(sshdr->sense_key), -scsi_sense_type_string(sshdr), -scsi_sense_format_string(sshdr)); +trace_scsi_print_sense(sdev, name, sshdr, NULL, 0, 0); scsi_show_extd_sense(sdev, name, sshdr->asc, sshdr->ascq); } EXPORT_SYMBOL(scsi_print_sense_hdr); -static void -scsi_dump_sense_buffer(struct scsi_device *sdev, const char
Re: Re: [RFC PATCH 07/10] scsi/trace: Use scsi_show_result trace point instead of printk
(2014/08/27 23:12), Hannes Reinecke wrote: On 08/08/2014 01:50 PM, Yoshihiro YUNOMAE wrote: Current SCSI trace has hostbyte table and driverbyte table, so we don't need to have the same table in scsi/constants.c. - Result examples (printk) sd 2:0:0:0: [sda] Result: hostbyte=DID_OK driverbyte=DRIVER_SENSE (ftrace) scsi_show_result: host_no=2 channel=0 id=0 lun=0 [sda] result=(driver=DRIVER_SENSE host=DID_OK) Signed-off-by: Yoshihiro YUNOMAE Cc: Hannes Reinecke Cc: Doug Gilbert Cc: Martin K. Petersen Cc: Christoph Hellwig Cc: "James E.J. Bottomley" Cc: Hidehiro Kawai Cc: Masami Hiramatsu --- drivers/scsi/constants.c| 52 --- drivers/scsi/scsi_trace.c | 16 + include/trace/events/scsi.h | 38 +++ 3 files changed, 53 insertions(+), 53 deletions(-) diff --git a/drivers/scsi/constants.c b/drivers/scsi/constants.c index 6fad6b4..f7b7f32 100644 --- a/drivers/scsi/constants.c +++ b/drivers/scsi/constants.c @@ -1488,55 +1488,3 @@ void scsi_print_sense(struct scsi_cmnd *cmd) SCSI_SENSE_BUFFERSIZE); } EXPORT_SYMBOL(scsi_print_sense); - -#ifdef CONFIG_SCSI_CONSTANTS - -static const char * const hostbyte_table[]={ -"DID_OK", "DID_NO_CONNECT", "DID_BUS_BUSY", "DID_TIME_OUT", "DID_BAD_TARGET", -"DID_ABORT", "DID_PARITY", "DID_ERROR", "DID_RESET", "DID_BAD_INTR", -"DID_PASSTHROUGH", "DID_SOFT_ERROR", "DID_IMM_RETRY", "DID_REQUEUE", -"DID_TRANSPORT_DISRUPTED", "DID_TRANSPORT_FAILFAST", "DID_TARGET_FAILURE", -"DID_NEXUS_FAILURE" }; -#define NUM_HOSTBYTE_STRS ARRAY_SIZE(hostbyte_table) - -static const char * const driverbyte_table[]={ -"DRIVER_OK", "DRIVER_BUSY", "DRIVER_SOFT", "DRIVER_MEDIA", "DRIVER_ERROR", -"DRIVER_INVALID", "DRIVER_TIMEOUT", "DRIVER_HARD", "DRIVER_SENSE"}; -#define NUM_DRIVERBYTE_STRS ARRAY_SIZE(driverbyte_table) - -void scsi_show_result(struct scsi_device *sdev, const char *name, int result) -{ -int hb = host_byte(result); -int db = driver_byte(result); -const char *hb_string; -const char *db_string; - -hb_string = (hb < NUM_HOSTBYTE_STRS) ? hostbyte_table[hb] : "invalid"; -db_string = (db < NUM_DRIVERBYTE_STRS) ? -driverbyte_table[db] : "invalid"; - - -sdev_printk(KERN_INFO, sdev, -"[%s] Result: hostbyte=%s driverbyte=%s\n", -name, hb_string, db_string); -} - -#else - -void scsi_show_result(struct scsi_device *sdev, const char *name, int result) -{ -sdev_printk(KERN_INFO, sdev, -"[%s] Result: hostbyte=0x%02x driverbyte=0x%02x\n", -name, host_byte(result), driver_byte(result)); -} - -#endif -EXPORT_SYMBOL(scsi_show_result); - -void scsi_print_result(struct scsi_cmnd *cmd) -{ -const char *devname = cmd->request->rq_disk ? -cmd->request->rq_disk->disk_name : "scsi"; -scsi_show_result(cmd->device, devname, cmd->result); -} -EXPORT_SYMBOL(scsi_print_result); diff --git a/drivers/scsi/scsi_trace.c b/drivers/scsi/scsi_trace.c index 2bea4f0..6ffbc40 100644 --- a/drivers/scsi/scsi_trace.c +++ b/drivers/scsi/scsi_trace.c @@ -19,6 +19,8 @@ #include #include +#include + #define SERVICE_ACTION16(cdb) (cdb[1] & 0x1f) #define SERVICE_ACTION32(cdb) ((cdb[8] << 8) | cdb[9]) @@ -286,3 +288,17 @@ scsi_trace_parse_cdb(struct trace_seq *p, unsigned char *cdb, int len) return scsi_trace_misc(p, cdb, len); } } + +void scsi_show_result(struct scsi_device *sdev, const char *name, int result) +{ +trace_scsi_show_result(sdev, name, result); +} +EXPORT_SYMBOL(scsi_show_result); + +void scsi_print_result(struct scsi_cmnd *cmd) +{ +const char *devname = cmd->request->rq_disk ? +cmd->request->rq_disk->disk_name : "scsi"; +scsi_show_result(cmd->device, devname, cmd->result); +} +EXPORT_SYMBOL(scsi_print_result); diff --git a/include/trace/events/scsi.h b/include/trace/events/scsi.h index 8aecdc2..0675195 100644 --- a/include/trace/events/scsi.h +++ b/include/trace/events/scsi.h @@ -123,7 +123,11 @@ scsi_hostbyte_name(DID_IMM_RETRY),\ scsi_hostbyte_name(DID_REQUEUE),\ scsi_hostbyte_name(DID_TRANSPORT_DISRUPTED),\ -scsi_hostbyte_name(DID_TRANSPORT_FAILFAST)) +scsi_hostbyte_name(DID_TRANSPORT_FAILFAST),\ +scsi_hostbyte_name(DID_TARGET_FAILURE),\ +scsi_hostbyte_name(DID_NEXUS_FAILURE),\ +scsi_hostbyte_name(DID_ALLOC_FAILURE),\ +scsi_hostbyte_name(DID_MEDIUM_ERROR)) #define scsi_driverbyte_name(result){ result, #result }
Re: Re: [RFC PATCH 04/10] scsi/constants: Cleanup printk message in scsi_dump_sense_buffer()
(2014/08/16 0:08), Ewan Milne wrote: On Fri, 2014-08-08 at 11:50 +, Yoshihiro YUNOMAE wrote: Unrecognized sense data should be output after linebuf is filled because "[%s] Unrecognized sense data (in hex): %s" message is output many times in loop. Signed-off-by: Yoshihiro YUNOMAE Cc: Hannes Reinecke Cc: Doug Gilbert Cc: Martin K. Petersen Cc: Christoph Hellwig Cc: "James E.J. Bottomley" Cc: Hidehiro Kawai Cc: Masami Hiramatsu --- drivers/scsi/constants.c | 13 + 1 file changed, 5 insertions(+), 8 deletions(-) diff --git a/drivers/scsi/constants.c b/drivers/scsi/constants.c index 5956d4d..6fad6b4 100644 --- a/drivers/scsi/constants.c +++ b/drivers/scsi/constants.c @@ -1385,16 +1385,13 @@ EXPORT_SYMBOL(scsi_print_sense_hdr); static void scsi_dump_sense_buffer(struct scsi_device *sdev, const char *prefix, - const unsigned char *sense_buffer, int sense_len, - struct scsi_sense_hdr *sshdr) + const unsigned char *sense_buffer, int sense_len) { char linebuf[128]; int i, linelen, remaining; if (sense_len < 32) sense_len = 32; - sdev_printk(KERN_INFO, sdev, - "[%s] Unrecognized sense data (in hex):", prefix); remaining = sense_len; for (i = 0; i < sense_len; i += 16) { @@ -1403,9 +1400,10 @@ scsi_dump_sense_buffer(struct scsi_device *sdev, const char *prefix, hex_dump_to_buffer(sense_buffer + i, linelen, 16, 1, linebuf, sizeof(linebuf), false); - sdev_printk(KERN_INFO, sdev, "[%s] Sense: %s\n", - prefix, linebuf); } + sdev_printk(KERN_INFO, sdev, + "[%s] Unrecognized sense data (in hex): %s", + prefix, linebuf); } See my earlier comment regarding PATCH 03/10. This doesn't look right -- In Hannes' tree what the code is doing is printing out a separate line for each 16 bytes of the sense data. Your change will cause only the last (partial?) 16 bytes to be printed. That's true. We should not apply this as well. The removal of the unused sshdr argument is fine, though. Thanks! Yoshihiro YUNOMAE -Ewan static void @@ -1467,8 +1465,7 @@ void __scsi_print_sense(struct scsi_device *sdev, const char *name, if (!scsi_normalize_sense(sense_buffer, sense_len, &sshdr)) { /* this may be SCSI-1 sense data */ - scsi_dump_sense_buffer(sdev, name, sense_buffer, - sense_len, &sshdr); + scsi_dump_sense_buffer(sdev, name, sense_buffer, sense_len); return; } -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/ -- Yoshihiro YUNOMAE Software Platform Research Dept. Linux Technology Center Hitachi, Ltd., Yokohama Research Laboratory E-mail: yoshihiro.yunomae...@hitachi.com -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
Re: [RFC PATCH 03/10] scsi/constants: Cleanup printk message in __scsi_print_command()
Hi Ewan, Thank you for your review. (2014/08/16 0:05), Ewan Milne wrote: On Fri, 2014-08-08 at 11:50 +, Yoshihiro YUNOMAE wrote: All bytes in CDB should be output after linebuf is filled because "[%s] CDB: %s\n" message is output many times in loop. Signed-off-by: Yoshihiro YUNOMAE Cc: Hannes Reinecke Cc: Doug Gilbert Cc: Martin K. Petersen Cc: Christoph Hellwig Cc: "James E.J. Bottomley" Cc: Hidehiro Kawai Cc: Masami Hiramatsu --- drivers/scsi/constants.c |3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/drivers/scsi/constants.c b/drivers/scsi/constants.c index 9c38b8d..5956d4d 100644 --- a/drivers/scsi/constants.c +++ b/drivers/scsi/constants.c @@ -413,9 +413,8 @@ void __scsi_print_command(struct scsi_device *sdev, const char *prefix, hex_dump_to_buffer(cdb + i, linelen, 16, 1, linebuf, sizeof(linebuf), false); - sdev_printk(KERN_INFO, sdev, "[%s] CDB: %s\n", - prefix, linebuf); } + sdev_printk(KERN_INFO, sdev, "[%s] CDB: %s\n", prefix, linebuf); } EXPORT_SYMBOL(__scsi_print_command); This doesn't look right -- In Hannes' tree what the code is doing is printing out a separate line for each 16 bytes of the CDB. You change will cause only the last (partial?) 16 bytes to be printed. Ah, that's true. We should not apply this patch. Thanks, Yoshihiro YUNOMAE -- Yoshihiro YUNOMAE Software Platform Research Dept. Linux Technology Center Hitachi, Ltd., Yokohama Research Laboratory E-mail: yoshihiro.yunomae...@hitachi.com -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
Re: [RFC PATCH 01/10] scsi/constants: Cleanup printk message in __scsi_print_sense()
Hi Elliot, Thank you for your comment. (2014/08/12 23:51), Elliott, Robert (Server Storage) wrote: -Original Message- From: linux-scsi-ow...@vger.kernel.org [mailto:linux-scsi- ow...@vger.kernel.org] On Behalf Of Yoshihiro YUNOMAE Sent: Friday, 08 August, 2014 6:50 AM ... Subject: [RFC PATCH 01/10] scsi/constants: Cleanup printk message in __scsi_print_sense() A device name is output like "sda: Sense Key : Medium Error [current]" in __scsi_print_sense(), but it should be "[sda] Sense Key : Medium Error [current]" because other printk messages output a device name like "[sda] foo." ... diff --git a/drivers/scsi/constants.c b/drivers/scsi/constants.c index c6a7a4a..a0e8159 100644 --- a/drivers/scsi/constants.c +++ b/drivers/scsi/constants.c @@ -1470,7 +1470,7 @@ void __scsi_print_sense(struct scsi_device *sdev, const char *name, return; } - sdev_printk(KERN_INFO, sdev, "%s: Sense Key : %s %s%s\n", name, + sdev_printk(KERN_INFO, sdev, "[%s] Sense Key : %s %s%s\n", name, scsi_sense_key_string(sshdr.sense_key), scsi_sense_type_string(&sshdr), scsi_sense_format_string(&sshdr)); The callers of __scsi_print_sense do not always pass in a name like "sda". In fact, sd.c doesn't even call that function; its sd_print_sense_hdr calls sd_printk (which prints name as "[%s]") and scsi_show_sense_hdr. OK, I understood. Current Linux kernel also outputs ":" in __scsi_print_sense(), so we should not change this. Thanks, Yoshihiro YUNOMOAE -- Yoshihiro YUNOMAE Software Platform Research Dept. Linux Technology Center Hitachi, Ltd., Yokohama Research Laboratory E-mail: yoshihiro.yunomae...@hitachi.com -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
Re: Re: [RFC PATCH -logging 00/10] scsi/constants: Output continuous error messages on trace
Hi Douglas, Thank you for your comment. (2014/08/08 22:07), Douglas Gilbert wrote: On 14-08-08 01:50 PM, Yoshihiro YUNOMAE wrote: Hi All, This patch set introduces new traceevents in order to output continuous error messages. Current SCSI printk messages in upstream kernel can be divided by and mixed with other messages. Even if each error message has its device id, sometimes we can easily be lost in mixed logs because the message's device id is separated from it's body. To avoid it, I'd like to use traceevents to store error messages into the ftrace or perf buuffer, because traceevents are atomically commited to the buffer. In this patch set, all printk messages are removed based on a local discussion with Hannes, but I think printk messages should be kept because all users don't enable traceevents and rsyslog can store as files. However, if printk of logging branch is kept, the messages are duplicate and it can induce stack overflow by using local buffer(*1). (*1) https://lkml.org/lkml/2014/5/20/742 So, my suggestion is follows: 1) printk Keeps current implemntation of upstream kernel. The messages are divided and can be mixed, but all users can check the error messages without any settings. 2) traceevents To get the complete messages, we can use ftrace or perf (or something on them). Users can always understand correct messages, but they need to set up the tracers. This patch set is based on Hannes' logging branch: http://git.kernel.org/cgit/linux/kernel/git/hare/scsi-devel.git/log/?h=logging [1/10] ~ [6/10]: just cleanup for logging branch [7/10] ~ [10/10]: introduce new traceevents Any comments are welcome! In sg3_utils there are now string yielding equivalents to the sense buffer "print" functions. They take a form like this: char * get_sense_str(const unsigned char * sense_buffer, int sb_len, int blen, char * b); So this just does the hard work of decoding the sense buffer (or saying it is invalid) the result of which it places in buffer 'b'. And 'b' is returned (so this function can be in the arguments of a driver's printing function). Adding such string functions would give other parts of the SCSI subsystem the capability of tailoring their own messages that include sense data information. Existing sense buffer "print" function could be kept and implemented using the newer "_str" variants. Would that be worth the trouble? I have already sent the idea using local buffer on this February, but it was rejected by James (*1). By using stack region for local buffer, stack overflow can occur. So, I implemented this feature to atomically output an error message with device information. (*1) https://lkml.org/lkml/2014/5/20/742 Thanks, Yoshihiro YUNOMAE -- Yoshihiro YUNOMAE Software Platform Research Dept. Linux Technology Center Hitachi, Ltd., Yokohama Research Laboratory E-mail: yoshihiro.yunomae...@hitachi.com -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[RFC PATCH 09/10] scsi/trace: Add additional sense code and additional sense code qualifier to scsi_print_sense trace point
There are no mean that additional sense code and additional sense code qualifier are output as different messages of sense key, so those information are added. Note: scsi_show_extd_sense() is changed from export symbol to non-export symbol. - Result examples (printk) sd 2:0:0:0: [sda] Add. Sense: Unrecovered read error (ftrace, merged into scsi_print_sense traceevent) scsi_print_sense: host_no=2 channel=0 id=0 lun=0 [sda] Sense Key (Medium Error [current]) Add. Sense (Unrecovered read error) Signed-off-by: Yoshihiro YUNOMAE Cc: Hannes Reinecke Cc: Doug Gilbert Cc: Martin K. Petersen Cc: Christoph Hellwig Cc: "James E.J. Bottomley" Cc: Hidehiro Kawai Cc: Masami Hiramatsu --- drivers/scsi/constants.c| 932 --- drivers/scsi/scsi_trace.c | 920 ++ include/scsi/scsi_dbg.h |2 include/trace/events/scsi.h | 10 4 files changed, 928 insertions(+), 936 deletions(-) diff --git a/drivers/scsi/constants.c b/drivers/scsi/constants.c index 85b75c8..ce9ceb8 100644 --- a/drivers/scsi/constants.c +++ b/drivers/scsi/constants.c @@ -14,12 +14,6 @@ #include #include -#include -#include -#include -#include - -#include /* Commands with service actions that change the command name */ #define SERVICE_ACTION_IN_12 0xab @@ -429,929 +423,3 @@ void scsi_print_command(struct scsi_cmnd *cmd) print_opcode_name(cmd->device, devname, cmd->cmnd, cmd->cmd_len); } EXPORT_SYMBOL(scsi_print_command); - -#ifdef CONFIG_SCSI_CONSTANTS - -struct error_info { - unsigned short code12; /* 0x0302 looks better than 0x03,0x02 */ - const char * text; -}; - -/* - * The canonical list of T10 Additional Sense Codes is available at: - * http://www.t10.org/lists/asc-num.txt [most recent: 20130605] - */ - -static const struct error_info additional[] = -{ - {0x, "No additional sense information"}, - {0x0001, "Filemark detected"}, - {0x0002, "End-of-partition/medium detected"}, - {0x0003, "Setmark detected"}, - {0x0004, "Beginning-of-partition/medium detected"}, - {0x0005, "End-of-data detected"}, - {0x0006, "I/O process terminated"}, - {0x0007, "Programmable early warning detected"}, - {0x0011, "Audio play operation in progress"}, - {0x0012, "Audio play operation paused"}, - {0x0013, "Audio play operation successfully completed"}, - {0x0014, "Audio play operation stopped due to error"}, - {0x0015, "No current audio status to return"}, - {0x0016, "Operation in progress"}, - {0x0017, "Cleaning requested"}, - {0x0018, "Erase operation in progress"}, - {0x0019, "Locate operation in progress"}, - {0x001A, "Rewind operation in progress"}, - {0x001B, "Set capacity operation in progress"}, - {0x001C, "Verify operation in progress"}, - {0x001D, "ATA pass through information available"}, - {0x001E, "Conflicting SA creation request"}, - {0x001F, "Logical unit transitioning to another power condition"}, - {0x0020, "Extended copy information available"}, - - {0x0100, "No index/sector signal"}, - - {0x0200, "No seek complete"}, - - {0x0300, "Peripheral device write fault"}, - {0x0301, "No write current"}, - {0x0302, "Excessive write errors"}, - - {0x0400, "Logical unit not ready, cause not reportable"}, - {0x0401, "Logical unit is in process of becoming ready"}, - {0x0402, "Logical unit not ready, initializing command required"}, - {0x0403, "Logical unit not ready, manual intervention required"}, - {0x0404, "Logical unit not ready, format in progress"}, - {0x0405, "Logical unit not ready, rebuild in progress"}, - {0x0406, "Logical unit not ready, recalculation in progress"}, - {0x0407, "Logical unit not ready, operation in progress"}, - {0x0408, "Logical unit not ready, long write in progress"}, - {0x0409, "Logical unit not ready, self-test in progress"}, - {0x040A, "Logical unit not accessible, asymmetric access state " -"transition"}, - {0x040B, "Logical unit not accessible, target port in standby state"}, - {0x040C, "Logical unit not accessible, target port in unavailable " -"state"}, - {0x040D, "Logical unit not ready, structure check required"}, - {0x0410, "Logical unit not ready, auxiliary memory not accessible"}, - {0x0411, "Logical unit not ready,
[RFC PATCH 04/10] scsi/constants: Cleanup printk message in scsi_dump_sense_buffer()
Unrecognized sense data should be output after linebuf is filled because "[%s] Unrecognized sense data (in hex): %s" message is output many times in loop. Signed-off-by: Yoshihiro YUNOMAE Cc: Hannes Reinecke Cc: Doug Gilbert Cc: Martin K. Petersen Cc: Christoph Hellwig Cc: "James E.J. Bottomley" Cc: Hidehiro Kawai Cc: Masami Hiramatsu --- drivers/scsi/constants.c | 13 + 1 file changed, 5 insertions(+), 8 deletions(-) diff --git a/drivers/scsi/constants.c b/drivers/scsi/constants.c index 5956d4d..6fad6b4 100644 --- a/drivers/scsi/constants.c +++ b/drivers/scsi/constants.c @@ -1385,16 +1385,13 @@ EXPORT_SYMBOL(scsi_print_sense_hdr); static void scsi_dump_sense_buffer(struct scsi_device *sdev, const char *prefix, - const unsigned char *sense_buffer, int sense_len, - struct scsi_sense_hdr *sshdr) + const unsigned char *sense_buffer, int sense_len) { char linebuf[128]; int i, linelen, remaining; if (sense_len < 32) sense_len = 32; - sdev_printk(KERN_INFO, sdev, - "[%s] Unrecognized sense data (in hex):", prefix); remaining = sense_len; for (i = 0; i < sense_len; i += 16) { @@ -1403,9 +1400,10 @@ scsi_dump_sense_buffer(struct scsi_device *sdev, const char *prefix, hex_dump_to_buffer(sense_buffer + i, linelen, 16, 1, linebuf, sizeof(linebuf), false); - sdev_printk(KERN_INFO, sdev, "[%s] Sense: %s\n", - prefix, linebuf); } + sdev_printk(KERN_INFO, sdev, + "[%s] Unrecognized sense data (in hex): %s", + prefix, linebuf); } static void @@ -1467,8 +1465,7 @@ void __scsi_print_sense(struct scsi_device *sdev, const char *name, if (!scsi_normalize_sense(sense_buffer, sense_len, &sshdr)) { /* this may be SCSI-1 sense data */ - scsi_dump_sense_buffer(sdev, name, sense_buffer, - sense_len, &sshdr); + scsi_dump_sense_buffer(sdev, name, sense_buffer, sense_len); return; } -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[RFC PATCH 03/10] scsi/constants: Cleanup printk message in __scsi_print_command()
All bytes in CDB should be output after linebuf is filled because "[%s] CDB: %s\n" message is output many times in loop. Signed-off-by: Yoshihiro YUNOMAE Cc: Hannes Reinecke Cc: Doug Gilbert Cc: Martin K. Petersen Cc: Christoph Hellwig Cc: "James E.J. Bottomley" Cc: Hidehiro Kawai Cc: Masami Hiramatsu --- drivers/scsi/constants.c |3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/drivers/scsi/constants.c b/drivers/scsi/constants.c index 9c38b8d..5956d4d 100644 --- a/drivers/scsi/constants.c +++ b/drivers/scsi/constants.c @@ -413,9 +413,8 @@ void __scsi_print_command(struct scsi_device *sdev, const char *prefix, hex_dump_to_buffer(cdb + i, linelen, 16, 1, linebuf, sizeof(linebuf), false); - sdev_printk(KERN_INFO, sdev, "[%s] CDB: %s\n", - prefix, linebuf); } + sdev_printk(KERN_INFO, sdev, "[%s] CDB: %s\n", prefix, linebuf); } EXPORT_SYMBOL(__scsi_print_command); -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[RFC PATCH 05/10] scsi/trace: Use macros for getting driver byte, host byte, msg byte, and status byte
For getting driver byte, host byte, msg byte, and status byte, macros are implemented in scsi/scsi.h, so we use it. Signed-off-by: Yoshihiro YUNOMAE Cc: Hannes Reinecke Cc: Doug Gilbert Cc: Martin K. Petersen Cc: Christoph Hellwig Cc: "James E.J. Bottomley" Cc: Hidehiro Kawai Cc: Masami Hiramatsu --- include/trace/events/scsi.h |8 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/include/trace/events/scsi.h b/include/trace/events/scsi.h index db6c935..8aecdc2 100644 --- a/include/trace/events/scsi.h +++ b/include/trace/events/scsi.h @@ -328,10 +328,10 @@ DECLARE_EVENT_CLASS(scsi_cmd_done_timeout_template, show_opcode_name(__entry->opcode), __parse_cdb(__get_dynamic_array(cmnd), __entry->cmd_len), __print_hex(__get_dynamic_array(cmnd), __entry->cmd_len), - show_driverbyte_name(((__entry->result) >> 24) & 0xff), - show_hostbyte_name(((__entry->result) >> 16) & 0xff), - show_msgbyte_name(((__entry->result) >> 8) & 0xff), - show_statusbyte_name(__entry->result & 0xff)) + show_driverbyte_name(driver_byte(__entry->result)), + show_hostbyte_name(host_byte(__entry->result)), + show_msgbyte_name(msg_byte(__entry->result)), + show_statusbyte_name(status_byte(__entry->result))) ); DEFINE_EVENT(scsi_cmd_done_timeout_template, scsi_dispatch_cmd_done, -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[RFC PATCH 02/10] scsi/constants: Cleanup printk message in scsi_decode_sense_extras()
If sense_flags and fixed_valid are zero, the kernel does not need to output a printk message. So, if those conditions are met, it just returns. Signed-off-by: Yoshihiro YUNOMAE Cc: Hannes Reinecke Cc: Doug Gilbert Cc: Martin K. Petersen Cc: Christoph Hellwig Cc: "James E.J. Bottomley" Cc: Hidehiro Kawai Cc: Masami Hiramatsu --- drivers/scsi/constants.c |3 +++ 1 file changed, 3 insertions(+) diff --git a/drivers/scsi/constants.c b/drivers/scsi/constants.c index a0e8159..9c38b8d 100644 --- a/drivers/scsi/constants.c +++ b/drivers/scsi/constants.c @@ -1438,6 +1438,9 @@ scsi_decode_sense_extras(struct scsi_device *sdev, const char *name, sense_flags |= ucp[3] & 0xe0; } + if (!sense_flags && !fixed_valid) + return; + res = 0; memset(buff, 0, sizeof(buff)); blen = sizeof(buff) - 1; -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[RFC PATCH 10/10] scsi/trace: Use scsi_print_command trace point instead of printk
Previous printk messages of SCSI command can be mixed into other printk messages because multiple printk messages are output for it. To avoid the problem, patch 4e64bb8d6 in Hannes' branch(*1) introduced a local buffer. But using local buffers can induce stack overflow, so we want to solve the problem without local buffer if possible. trace_seq_printf can add log messages without local buffer, so we use it. Note: We don't need constans.c any more. (*1) http://git.kernel.org/cgit/linux/kernel/git/hare/scsi-devel.git/log/?h=logging - Result examples (printk) sd 2:0:0:0: [sda] CDB: Read(10) scsi_print_command: host_no=2 channel=0 id=0 lun=0 [sda] CDB (Read(10)) Signed-off-by: Yoshihiro YUNOMAE Cc: Hannes Reinecke Cc: Doug Gilbert Cc: Martin K. Petersen Cc: Christoph Hellwig Cc: "James E.J. Bottomley" Cc: Hidehiro Kawai Cc: Masami Hiramatsu --- drivers/scsi/Makefile |2 drivers/scsi/constants.c| 425 --- drivers/scsi/scsi_trace.c | 408 + include/scsi/scsi.h |8 + include/trace/events/scsi.h | 45 + 5 files changed, 461 insertions(+), 427 deletions(-) delete mode 100644 drivers/scsi/constants.c diff --git a/drivers/scsi/Makefile b/drivers/scsi/Makefile index 5f0d299..c56f692 100644 --- a/drivers/scsi/Makefile +++ b/drivers/scsi/Makefile @@ -158,7 +158,7 @@ obj-$(CONFIG_SCSI_OSD_INITIATOR) += osd/ # This goes last, so that "real" scsi devices probe earlier obj-$(CONFIG_SCSI_DEBUG) += scsi_debug.o -scsi_mod-y += scsi.o hosts.o scsi_ioctl.o constants.o \ +scsi_mod-y += scsi.o hosts.o scsi_ioctl.o \ scsicam.o scsi_error.o scsi_lib.o scsi_mod-$(CONFIG_SCSI_DMA)+= scsi_lib_dma.o scsi_mod-y += scsi_scan.o scsi_sysfs.o scsi_devinfo.o diff --git a/drivers/scsi/constants.c b/drivers/scsi/constants.c deleted file mode 100644 index ce9ceb8..000 --- a/drivers/scsi/constants.c +++ /dev/null @@ -1,425 +0,0 @@ -/* - * ASCII values for a number of symbolic constants, printing functions, - * etc. - * Additions for SCSI 2 and Linux 2.2.x by D. Gilbert (990422) - * Additions for SCSI 3+ (SPC-3 T10/1416-D Rev 07 3 May 2002) - * by D. Gilbert and aeb (20020609) - * Updated to SPC-4 T10/1713-D Rev 36g, D. Gilbert 20130701 - */ - -#include -#include -#include -#include - -#include -#include - -/* Commands with service actions that change the command name */ -#define SERVICE_ACTION_IN_12 0xab -#define SERVICE_ACTION_OUT_12 0xa9 -#define SERVICE_ACTION_BIDIRECTIONAL 0x9d -#define SERVICE_ACTION_IN_16 0x9e -#define SERVICE_ACTION_OUT_16 0x9f -#define THIRD_PARTY_COPY_OUT 0x83 -#define THIRD_PARTY_COPY_IN 0x84 - - - -#ifdef CONFIG_SCSI_CONSTANTS -static const char * cdb_byte0_names[] = { -/* 00-03 */ "Test Unit Ready", "Rezero Unit/Rewind", NULL, "Request Sense", -/* 04-07 */ "Format Unit/Medium", "Read Block Limits", NULL, - "Reassign Blocks", -/* 08-0d */ "Read(6)", NULL, "Write(6)", "Seek(6)", NULL, NULL, -/* 0e-12 */ NULL, "Read Reverse", "Write Filemarks", "Space", "Inquiry", -/* 13-16 */ "Verify(6)", "Recover Buffered Data", "Mode Select(6)", - "Reserve(6)", -/* 17-1a */ "Release(6)", "Copy", "Erase", "Mode Sense(6)", -/* 1b-1d */ "Start/Stop Unit", "Receive Diagnostic", "Send Diagnostic", -/* 1e-1f */ "Prevent/Allow Medium Removal", NULL, -/* 20-22 */ NULL, NULL, NULL, -/* 23-28 */ "Read Format Capacities", "Set Window", - "Read Capacity(10)", NULL, NULL, "Read(10)", -/* 29-2d */ "Read Generation", "Write(10)", "Seek(10)", "Erase(10)", -"Read updated block", -/* 2e-31 */ "Write Verify(10)", "Verify(10)", "Search High", "Search Equal", -/* 32-34 */ "Search Low", "Set Limits", "Prefetch/Read Position", -/* 35-37 */ "Synchronize Cache(10)", "Lock/Unlock Cache(10)", - "Read Defect Data(10)", -/* 38-3c */ "Medium Scan", "Compare", "Copy Verify", "Write Buffer", - "Read Buffer", -/* 3d-3f */ "Update Block", "Read Long(10)", "Write Long(10)", -/* 40-41 */ "Change Definition", "Write Same(10)", -/* 42-48 */ "Unmap/Read sub-channel", "Read TOC/PMA/ATIP", - "Read density support", "Play audio(10)", "Get configuration", - "Play audio msf", "Sanitize/Play audio track/index",
[RFC PATCH 08/10] scsi/trace: Use scsi_print_sense trace point instead of printk
Previous sense messages can be mixed into other sense messages, because continuous printk (KERN_CONT) was used. To avoid the problem, patch d87f3a6f51 introduced a local buffer in Hannes's baranch (*1). But using local buffers can induce stack overflow, so we want to solve the problem without local buffer if possible. trace_seq_printf can add log messages without local buffer, so we use it. (*1) http://git.kernel.org/cgit/linux/kernel/git/hare/scsi-devel.git/log/?h=logging - Result examples (printk) sd 2:0:0:0: [sda] Sense Key : Medium Error [current] (ftrace) scsi_print_sense: host_no=2 channel=0 id=0 lun=0 [sda] Sense Key (Medium Error [current]) Signed-off-by: Yoshihiro YUNOMAE Cc: Hannes Reinecke Cc: Doug Gilbert Cc: Martin K. Petersen Cc: Christoph Hellwig Cc: "James E.J. Bottomley" Cc: Hidehiro Kawai Cc: Masami Hiramatsu --- drivers/scsi/constants.c| 145 ++- drivers/scsi/scsi_trace.c | 140 -- include/scsi/scsi_eh.h |7 ++ include/trace/events/scsi.h | 48 ++ 4 files changed, 195 insertions(+), 145 deletions(-) diff --git a/drivers/scsi/constants.c b/drivers/scsi/constants.c index f7b7f32..85b75c8 100644 --- a/drivers/scsi/constants.c +++ b/drivers/scsi/constants.c @@ -19,7 +19,7 @@ #include #include - +#include /* Commands with service actions that change the command name */ #define SERVICE_ACTION_IN_12 0xab @@ -1267,58 +1267,8 @@ static const struct error_info2 additional2[] = {0x70, 0x00, 0xff, "Decompression exception short algorithm id of %x"}, {0, 0, 0, NULL} }; - -/* description of the sense key values */ -static const char * const snstext[] = { - "No Sense", /* 0: There is no sense information */ - "Recovered Error", /* 1: The last command completed successfully - but used error correction */ - "Not Ready",/* 2: The addressed target is not ready */ - "Medium Error", /* 3: Data error detected on the medium */ - "Hardware Error", /* 4: Controller or device failure */ - "Illegal Request", /* 5: Error in request */ - "Unit Attention", /* 6: Removable medium was changed, or - the target has been reset, or ... */ - "Data Protect", /* 7: Access to the data is blocked */ - "Blank Check", /* 8: Reached unexpected written or unwritten - region of the medium */ - "Vendor Specific(9)", - "Copy Aborted", /* A: COPY or COMPARE was aborted */ - "Aborted Command", /* B: The target aborted the command */ - "Equal",/* C: A SEARCH DATA command found data equal, - reserved in SPC-4 rev 36 */ - "Volume Overflow", /* D: Medium full with still data to be written */ - "Miscompare", /* E: Source data and data on the medium - do not agree */ - "Completed",/* F: command completed sense data reported, - may occur for successful command */ -}; -#else -static const char * const snstext[] = { - "0x0", "0x1", "0x2", "0x3", "0x4", "0x5", "0x6", "0x7", - "0x8", "0x9", "0xa", "0xb", "0xc", "0xd", "0xe", "0xf", -}; #endif -/* Get sense key string or NULL if not available */ -const char * -scsi_sense_key_string(unsigned char key) { - return snstext[key & 0xf]; -} -EXPORT_SYMBOL(scsi_sense_key_string); - -const char * -scsi_sense_type_string(struct scsi_sense_hdr *sshdr) -{ - return scsi_sense_is_deferred(sshdr) ? "[deferred]" : "[current]"; -} - -const char * -scsi_sense_format_string(struct scsi_sense_hdr *sshdr) -{ - return sshdr->response_code >= 0x72 ? "[descriptor]" : ""; -} - /* * Get additional sense code string or NULL if not available. * This string may contain a "%x" and should be printed with ascq as arg. @@ -1375,105 +1325,22 @@ void scsi_print_sense_hdr(struct scsi_device *sdev, const char *name, struct scsi_sense_hdr *sshdr) { - sdev_printk(KERN_INFO, sdev, "[%s] Sense Key : %s %s%s\n", name, - scsi_sense_key_string(sshdr->sense_key), - scsi_sense_type_string(sshdr), - scsi_sense_format_string(sshdr)); + trace_scsi_print_sense(sdev, name, sshdr, NULL, 0, 0); scsi_show_extd_sense(sdev, name, sshdr->asc, sshdr->ascq); } EXPORT_SYMBOL(scsi_p
[RFC PATCH 01/10] scsi/constants: Cleanup printk message in __scsi_print_sense()
A device name is output like "sda: Sense Key : Medium Error [current]" in __scsi_print_sense(), but it should be "[sda] Sense Key : Medium Error [current]" because other printk messages output a device name like "[sda] foo." Signed-off-by: Yoshihiro YUNOMAE Cc: Hannes Reinecke Cc: Doug Gilbert Cc: Martin K. Petersen Cc: Christoph Hellwig Cc: "James E.J. Bottomley" Cc: Hidehiro Kawai Cc: Masami Hiramatsu --- drivers/scsi/constants.c |2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/scsi/constants.c b/drivers/scsi/constants.c index c6a7a4a..a0e8159 100644 --- a/drivers/scsi/constants.c +++ b/drivers/scsi/constants.c @@ -1470,7 +1470,7 @@ void __scsi_print_sense(struct scsi_device *sdev, const char *name, return; } - sdev_printk(KERN_INFO, sdev, "%s: Sense Key : %s %s%s\n", name, + sdev_printk(KERN_INFO, sdev, "[%s] Sense Key : %s %s%s\n", name, scsi_sense_key_string(sshdr.sense_key), scsi_sense_type_string(&sshdr), scsi_sense_format_string(&sshdr)); -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[RFC PATCH 06/10] scsi/sd: Delete extra scsi_show_extd_sense() in sd_print_sense_hdr()
sd_print_sense_hdr() calls scsi_show_extd_sense(), but scsi_print_sense_hdr() also calls scsi_show_extd_sense(). We can get same result, so we delete it. Note: Calling scsi_show_extd_sense() is introduced in fdd8b297. Signed-off-by: Yoshihiro YUNOMAE Cc: Hannes Reinecke Cc: Doug Gilbert Cc: Martin K. Petersen Cc: Christoph Hellwig Cc: "James E.J. Bottomley" Cc: Hidehiro Kawai Cc: Masami Hiramatsu --- drivers/scsi/sd.c |2 -- 1 file changed, 2 deletions(-) diff --git a/drivers/scsi/sd.c b/drivers/scsi/sd.c index 8d7204a..22dd214 100644 --- a/drivers/scsi/sd.c +++ b/drivers/scsi/sd.c @@ -3286,8 +3286,6 @@ static void sd_print_sense_hdr(struct scsi_disk *sdkp, struct scsi_sense_hdr *sshdr) { scsi_print_sense_hdr(sdkp->device, sdkp->disk->disk_name, sshdr); - scsi_show_extd_sense(sdkp->device, sdkp->disk->disk_name, -sshdr->asc, sshdr->ascq); } static void sd_print_result(struct scsi_disk *sdkp, int result) -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[RFC PATCH 07/10] scsi/trace: Use scsi_show_result trace point instead of printk
Current SCSI trace has hostbyte table and driverbyte table, so we don't need to have the same table in scsi/constants.c. - Result examples (printk) sd 2:0:0:0: [sda] Result: hostbyte=DID_OK driverbyte=DRIVER_SENSE (ftrace) scsi_show_result: host_no=2 channel=0 id=0 lun=0 [sda] result=(driver=DRIVER_SENSE host=DID_OK) Signed-off-by: Yoshihiro YUNOMAE Cc: Hannes Reinecke Cc: Doug Gilbert Cc: Martin K. Petersen Cc: Christoph Hellwig Cc: "James E.J. Bottomley" Cc: Hidehiro Kawai Cc: Masami Hiramatsu --- drivers/scsi/constants.c| 52 --- drivers/scsi/scsi_trace.c | 16 + include/trace/events/scsi.h | 38 +++ 3 files changed, 53 insertions(+), 53 deletions(-) diff --git a/drivers/scsi/constants.c b/drivers/scsi/constants.c index 6fad6b4..f7b7f32 100644 --- a/drivers/scsi/constants.c +++ b/drivers/scsi/constants.c @@ -1488,55 +1488,3 @@ void scsi_print_sense(struct scsi_cmnd *cmd) SCSI_SENSE_BUFFERSIZE); } EXPORT_SYMBOL(scsi_print_sense); - -#ifdef CONFIG_SCSI_CONSTANTS - -static const char * const hostbyte_table[]={ -"DID_OK", "DID_NO_CONNECT", "DID_BUS_BUSY", "DID_TIME_OUT", "DID_BAD_TARGET", -"DID_ABORT", "DID_PARITY", "DID_ERROR", "DID_RESET", "DID_BAD_INTR", -"DID_PASSTHROUGH", "DID_SOFT_ERROR", "DID_IMM_RETRY", "DID_REQUEUE", -"DID_TRANSPORT_DISRUPTED", "DID_TRANSPORT_FAILFAST", "DID_TARGET_FAILURE", -"DID_NEXUS_FAILURE" }; -#define NUM_HOSTBYTE_STRS ARRAY_SIZE(hostbyte_table) - -static const char * const driverbyte_table[]={ -"DRIVER_OK", "DRIVER_BUSY", "DRIVER_SOFT", "DRIVER_MEDIA", "DRIVER_ERROR", -"DRIVER_INVALID", "DRIVER_TIMEOUT", "DRIVER_HARD", "DRIVER_SENSE"}; -#define NUM_DRIVERBYTE_STRS ARRAY_SIZE(driverbyte_table) - -void scsi_show_result(struct scsi_device *sdev, const char *name, int result) -{ - int hb = host_byte(result); - int db = driver_byte(result); - const char *hb_string; - const char *db_string; - - hb_string = (hb < NUM_HOSTBYTE_STRS) ? hostbyte_table[hb] : "invalid"; - db_string = (db < NUM_DRIVERBYTE_STRS) ? - driverbyte_table[db] : "invalid"; - - - sdev_printk(KERN_INFO, sdev, - "[%s] Result: hostbyte=%s driverbyte=%s\n", - name, hb_string, db_string); -} - -#else - -void scsi_show_result(struct scsi_device *sdev, const char *name, int result) -{ - sdev_printk(KERN_INFO, sdev, - "[%s] Result: hostbyte=0x%02x driverbyte=0x%02x\n", - name, host_byte(result), driver_byte(result)); -} - -#endif -EXPORT_SYMBOL(scsi_show_result); - -void scsi_print_result(struct scsi_cmnd *cmd) -{ - const char *devname = cmd->request->rq_disk ? - cmd->request->rq_disk->disk_name : "scsi"; - scsi_show_result(cmd->device, devname, cmd->result); -} -EXPORT_SYMBOL(scsi_print_result); diff --git a/drivers/scsi/scsi_trace.c b/drivers/scsi/scsi_trace.c index 2bea4f0..6ffbc40 100644 --- a/drivers/scsi/scsi_trace.c +++ b/drivers/scsi/scsi_trace.c @@ -19,6 +19,8 @@ #include #include +#include + #define SERVICE_ACTION16(cdb) (cdb[1] & 0x1f) #define SERVICE_ACTION32(cdb) ((cdb[8] << 8) | cdb[9]) @@ -286,3 +288,17 @@ scsi_trace_parse_cdb(struct trace_seq *p, unsigned char *cdb, int len) return scsi_trace_misc(p, cdb, len); } } + +void scsi_show_result(struct scsi_device *sdev, const char *name, int result) +{ + trace_scsi_show_result(sdev, name, result); +} +EXPORT_SYMBOL(scsi_show_result); + +void scsi_print_result(struct scsi_cmnd *cmd) +{ + const char *devname = cmd->request->rq_disk ? + cmd->request->rq_disk->disk_name : "scsi"; + scsi_show_result(cmd->device, devname, cmd->result); +} +EXPORT_SYMBOL(scsi_print_result); diff --git a/include/trace/events/scsi.h b/include/trace/events/scsi.h index 8aecdc2..0675195 100644 --- a/include/trace/events/scsi.h +++ b/include/trace/events/scsi.h @@ -123,7 +123,11 @@ scsi_hostbyte_name(DID_IMM_RETRY), \ scsi_hostbyte_name(DID_REQUEUE),\ scsi_hostbyte_name(DID_TRANSPORT_DISRUPTED),\ - scsi_hostbyte_name(DID_TRANSPORT_FAILFAST)) + scsi_hostbyte_name(DID_TRANSPORT_FAILFAST), \ + scsi_hostbyte_name(DID_TARGET_FAILURE), \ + scsi_hostbyte_name(DID_NEXUS_FAILURE), \ + scsi_hostbyte_name(DID_ALLOC_FAILURE), \ + scsi_hostbyte_nam
[RFC PATCH -logging 00/10] scsi/constants: Output continuous error messages on trace
Hi All, This patch set introduces new traceevents in order to output continuous error messages. Current SCSI printk messages in upstream kernel can be divided by and mixed with other messages. Even if each error message has its device id, sometimes we can easily be lost in mixed logs because the message's device id is separated from it's body. To avoid it, I'd like to use traceevents to store error messages into the ftrace or perf buuffer, because traceevents are atomically commited to the buffer. In this patch set, all printk messages are removed based on a local discussion with Hannes, but I think printk messages should be kept because all users don't enable traceevents and rsyslog can store as files. However, if printk of logging branch is kept, the messages are duplicate and it can induce stack overflow by using local buffer(*1). (*1) https://lkml.org/lkml/2014/5/20/742 So, my suggestion is follows: 1) printk Keeps current implemntation of upstream kernel. The messages are divided and can be mixed, but all users can check the error messages without any settings. 2) traceevents To get the complete messages, we can use ftrace or perf (or something on them). Users can always understand correct messages, but they need to set up the tracers. This patch set is based on Hannes' logging branch: http://git.kernel.org/cgit/linux/kernel/git/hare/scsi-devel.git/log/?h=logging [1/10] ~ [6/10]: just cleanup for logging branch [7/10] ~ [10/10]: introduce new traceevents Any comments are welcome! Thanks, Yoshihiro YUNOMAE --- Yoshihiro YUNOMAE (10): scsi/constants: Cleanup printk message in __scsi_print_sense() scsi/constants: Cleanup printk message in scsi_decode_sense_extras() scsi/constants: Cleanup printk message in __scsi_print_command() scsi/constants: Cleanup printk message in scsi_dump_sense_buffer() scsi/trace: Use macros for getting driver byte, host byte, msg byte, and status byte scsi/sd: Delete extra scsi_show_extd_sense() in sd_print_sense_hdr() scsi/trace: Use scsi_show_result trace point instead of printk scsi/trace: Use scsi_print_sense trace point instead of printk scsi/trace: Add additional sense code and additional sense code qualifier to scsi_print_sense trace point scsi/trace: Use scsi_print_command trace point instead of printk drivers/scsi/Makefile |2 drivers/scsi/constants.c| 1543 --- drivers/scsi/scsi_trace.c | 1484 + drivers/scsi/sd.c |2 include/scsi/scsi.h |8 include/scsi/scsi_dbg.h |2 include/scsi/scsi_eh.h |7 include/trace/events/scsi.h | 145 8 files changed, 1633 insertions(+), 1560 deletions(-) delete mode 100644 drivers/scsi/constants.c -- Yoshihiro YUNOMAE Software Platform Research Dept. Linux Technology Center Hitachi, Ltd., Yokohama Research Laboratory E-mail: yoshihiro.yunomae...@hitachi.com -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
Re: Re: [PATCH V4 1/5] trace-cmd/listen: Apply the trace-msg protocol for communication between a server and clients
Hi Steven, Thank you for your review. (2014/07/23 0:04), Steven Rostedt wrote: Sorry for taking so long to reply, I've been hacking on the kernel a bit and that takes precedence over user tools :-/ On Fri, 11 Jul 2014 00:58:26 + Yoshihiro YUNOMAE wrote: Apply trace-msg protocol for communication between a server and clients. Currently, trace-listen(server) and trace-record -N(client) operate as follows: listen to socket fd connect to socket fd accept the client send "tracecmd" +> receive "tracecmd" check "tracecmd" send cpus receive cpus <+ print "cpus=XXX" send pagesize | receive pagesize <+ print "pagesize=XXX" send option | receive option <--+ understand option send port_array +> receive port_array understand port_array send meta data receive meta data <---+ record meta data (snip) read block --- start sending trace data on child processes --- --- When client finishes sending trace data --- close(socket fd) read size = 0 close(socket fd) All messages are unstructured character strings, so server(client) using the protocol must parse the unstructured messages. Since it is hard to add complex contents in the protocol, structured binary message trace-msg is introduced as the communication protocol. By applying this patch, server and client operate as follows: listen to socket fd connect to socket fd accept the client send "tracecmd" +> receive "tracecmd" check "tracecmd" send "V2\0\00" as the v2 protocol Lets change this to "-1V2\0\00" The -1 will cause an old server to exit as it will not accept a -1 for CPU count. Then you can check if the return of the next read is -1, as the client would have disconnected. Sure. The reason I ask this, is because once you send a valid CPU count (and unfortunately, 0 happens to be valid :-p, the server side creates a file. When you close it, that file stays around as zero length. By sending -1, the old server will error out and never create a file. Yes, I also thought this should be fixed. I'll submit fixed patch. Thank you, Yoshihiro YUNOMAE -- Yoshihiro YUNOMAE Software Platform Research Dept. Linux Technology Center Hitachi, Ltd., Yokohama Research Laboratory E-mail: yoshihiro.yunomae...@hitachi.com -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[PATCH] serial/core: Fix too big allocation for attribute member
Current code allocates too much data for tty_groups member of uart_port struct, so fix it. Signed-off-by: Yoshihiro YUNOMAE CC: Greg Kroah-Hartman CC: Dan Carpenter --- drivers/tty/serial/serial_core.c |2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/tty/serial/serial_core.c b/drivers/tty/serial/serial_core.c index 4af764c..8ded213 100644 --- a/drivers/tty/serial/serial_core.c +++ b/drivers/tty/serial/serial_core.c @@ -2617,7 +2617,7 @@ int uart_add_one_port(struct uart_driver *drv, struct uart_port *uport) if (uport->attr_group) num_groups++; - uport->tty_groups = kcalloc(num_groups, sizeof(**uport->tty_groups), + uport->tty_groups = kcalloc(num_groups, sizeof(*uport->tty_groups), GFP_KERNEL); if (!uport->tty_groups) { ret = -ENOMEM; -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[PATCH V9 1/2] Serial: allow port drivers to have a default attribute group
From: Greg Kroah-Hartman Some serial drivers (like 8250), want to add sysfs files. We need to do so in a race-free way, so allow any port to be able to specify an attribute group that should be added at device creation time. Signed-off-by: Greg Kroah-Hartman Signed-off-by: Yoshihiro YUNOMAE --- drivers/tty/serial/serial_core.c | 24 +--- include/linux/serial_core.h |2 ++ 2 files changed, 19 insertions(+), 7 deletions(-) diff --git a/drivers/tty/serial/serial_core.c b/drivers/tty/serial/serial_core.c index fbf6c5a..4af764c 100644 --- a/drivers/tty/serial/serial_core.c +++ b/drivers/tty/serial/serial_core.c @@ -2563,12 +2563,6 @@ static const struct attribute_group tty_dev_attr_group = { .attrs = tty_dev_attrs, }; -static const struct attribute_group *tty_dev_attr_groups[] = { - &tty_dev_attr_group, - NULL - }; - - /** * uart_add_one_port - attach a driver-defined port structure * @drv: pointer to the uart low level driver structure for this port @@ -2585,6 +2579,7 @@ int uart_add_one_port(struct uart_driver *drv, struct uart_port *uport) struct tty_port *port; int ret = 0; struct device *tty_dev; + int num_groups; BUG_ON(in_interrupt()); @@ -2618,12 +2613,26 @@ int uart_add_one_port(struct uart_driver *drv, struct uart_port *uport) uart_configure_port(drv, state, uport); + num_groups = 2; + if (uport->attr_group) + num_groups++; + + uport->tty_groups = kcalloc(num_groups, sizeof(**uport->tty_groups), + GFP_KERNEL); + if (!uport->tty_groups) { + ret = -ENOMEM; + goto out; + } + uport->tty_groups[0] = &tty_dev_attr_group; + if (uport->attr_group) + uport->tty_groups[1] = uport->attr_group; + /* * Register the port whether it's detected or not. This allows * setserial to be used to alter this port's parameters. */ tty_dev = tty_port_register_device_attr(port, drv->tty_driver, - uport->line, uport->dev, port, tty_dev_attr_groups); + uport->line, uport->dev, port, uport->tty_groups); if (likely(!IS_ERR(tty_dev))) { device_set_wakeup_capable(tty_dev, 1); } else { @@ -2702,6 +2711,7 @@ int uart_remove_one_port(struct uart_driver *drv, struct uart_port *uport) */ if (uport->type != PORT_UNKNOWN) uport->ops->release_port(uport); + kfree(uport->tty_groups); /* * Indicate that there isn't a port here anymore. diff --git a/include/linux/serial_core.h b/include/linux/serial_core.h index 5bbb809..cf3a1e7 100644 --- a/include/linux/serial_core.h +++ b/include/linux/serial_core.h @@ -199,6 +199,8 @@ struct uart_port { unsigned char suspended; unsigned char irq_wake; unsigned char unused[2]; + struct attribute_group *attr_group;/* port specific attributes */ + const struct attribute_group **tty_groups; /* all attributes (serial core use only) */ void*private_data; /* generic platform data pointer */ }; -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[PATCH V9 2/2] serial/uart/8250: Add tunable RX interrupt trigger I/F of FIFO buffers
Add tunable RX interrupt trigger I/F of FIFO buffers. Serial devices are used as not only message communication devices but control or sending communication devices. For the latter uses, normally small data will be exchanged, so user applications want to receive data unit as soon as possible for real-time tendency. If we have a sensor which sends a 1 byte data each time and must control a device based on the sensor feedback, the RX interrupt should be triggered for each data. According to HW specification of serial UART devices, RX interrupt trigger can be changed, but the trigger is hard-coded. For example, RX interrupt trigger in 16550A can be set to 1, 4, 8, or 14 bytes for HW, but current driver sets the trigger to only 8bytes. This patch makes some devices change RX interrupt trigger from userland. - Read current setting # cat /sys/class/tty/ttyS0/rx_trig_bytes 8 - Write user setting # echo 1 > /sys/class/tty/ttyS0/rx_trig_bytes # cat /sys/class/tty/ttyS0/rx_trig_bytes 1 - 16550A and Tegra (1, 4, 8, or 14 bytes) - 16650V2 (8, 16, 24, or 28 bytes) - 16654 (8, 16, 56, or 60 bytes) - 16750 (1, 16, 32, or 56 bytes) Changes in V9: - Use attr_group instead of dev_spec_attr_group of uart_port structure Changes in V8: - Divide this patch from V7's patch based on Greg's comment Changes in V7: - Add Documentation - Change I/F name from rx_int_trig to rx_trig_bytes because the name rx_int_trig is hard to understand how users specify the value Changes in V6: - Move FCR_RX_TRIG_* definition in 8250.h to include/uapi/linux/serial_reg.h, rename those to UART_FCR_R_TRIG_*, and use UART_FCR_TRIGGER_MASK to UART_FCR_R_TRIG_BITS() - Change following function names: convert_fcr2val() => fcr_get_rxtrig_bytes() convert_val2rxtrig() => bytes_to_fcr_rxtrig() - Fix typo in serial8250_do_set_termios() - Delete the verbose error message pr_info() in bytes_to_fcr_rxtrig() - Rename *rx_int_trig/rx_trig* to *rxtrig* for several functions or variables (but UI remains rx_int_trig) - Change the meaningless variable name 'val' to 'bytes' following functions: fcr_get_rxtrig_bytes(), bytes_to_fcr_rxtrig(), do_set_rxtrig(), do_serial8250_set_rxtrig(), and serial8250_set_attr_rxtrig() - Use up->fcr in order to get rxtrig_bytes instead of rx_trig_raw in fcr_get_rxtrig_bytes() - Use conf_type->rxtrig_bytes[0] instead of switch statement for support check in register_dev_spec_attr_grp() - Delete the checking whether a user changed FCR or not when minimum buffer is needed in serial8250_do_set_termios() Changes in V5.1: - Fix FCR_RX_TRIG_MAX_STATE definition Changes in V5: - Support Tegra, 16650V2, 16654, and 16750 - Store default FCR value to up->fcr when the port is first created - Add rx_trig_byte[] in uart_config[] for each device and use rx_trig_byte[] in convert_fcr2val() and convert_val2rxtrig() Changes in V4: - Introduce fifo_bug flag in uart_8250_port structure This is enabled only when parity is enabled and UART_BUG_PARITY is enabled for up->bugs. If this flag is enabled, user cannot set RX trigger. - Return -EOPNOTSUPP when it does not support device at convert_fcr2val() and at convert_val2rxtrig() - Set the nearest lower RX trigger when users input a meaningless value at convert_val2rxtrig() - Check whether p->fcr is existing at serial8250_clear_and_reinit_fifos() - Set fcr = up->fcr in the begging of serial8250_do_set_termios() Changes in V3: - Change I/F from ioctl(2) to sysfs(rx_int_trig) Changed in V2: - Use _IOW for TIOCSFIFORTRIG definition - Pass the interrupt trigger value itself Signed-off-by: Yoshihiro YUNOMAE --- Documentation/ABI/testing/sysfs-tty | 16 +++ drivers/tty/serial/8250/8250.h |2 drivers/tty/serial/8250/8250_core.c | 173 --- include/linux/serial_8250.h |2 include/uapi/linux/serial_reg.h |5 + 5 files changed, 183 insertions(+), 15 deletions(-) diff --git a/Documentation/ABI/testing/sysfs-tty b/Documentation/ABI/testing/sysfs-tty index ad22fb0..9eb3c2b 100644 --- a/Documentation/ABI/testing/sysfs-tty +++ b/Documentation/ABI/testing/sysfs-tty @@ -138,3 +138,19 @@ Description: These sysfs values expose the TIOCGSERIAL interface via sysfs rather than via ioctls. + +What: /sys/class/tty/ttyS0/rx_trig_bytes +Date: May 2014 +Contact: Yoshihiro YUNOMAE +Description: +Shows current RX interrupt trigger bytes or sets the +user specified value to change it for the FIFO buffer. +Users can show or set this value regardless of opening the +serial device file or not. + +The RX trigger can be set one of four kinds of values for UART +serials. When users input a meaning less value to this I/F, +the RX trigger is changed t
[ PATCH V9 0/2] serial/uart/8250: Introduce tunable RX trigger I/F
Hi Greg, This patch set introduces tunable RX interrupt trigger I/F for 8250 serials. I used Greg's patch(*1) as 1st patch in this version, and applied 2nd patch of previous version. Would you review this patch set? Thanks! Note: I cleaned up Greg's patch as follows: - Delete extra line break - Use kcalloc instead of kmalloc - sizeof(struct attribute_group *) => sizeof(**uport->tty_groups) *1: https://lkml.org/lkml/2014/7/12/177 Changes in V9: [2/2] - Use attr_group instead of dev_spec_attr_group of uart_port structure Changes in V8: - Split V7's patch up into 2 patches Changes in V7: - Add Documentation - Change I/F name from rx_int_trig to rx_trig_bytes because the name rx_int_trig is hard to understand how users specify the value Changes in V6: - Move FCR_RX_TRIG_* definition in 8250.h to include/uapi/linux/serial_reg.h, rename those to UART_FCR_R_TRIG_*, and use UART_FCR_TRIGGER_MASK to UART_FCR_R_TRIG_BITS() - Change following function names: convert_fcr2val() => fcr_get_rxtrig_bytes() convert_val2rxtrig() => bytes_to_fcr_rxtrig() - Fix typo in serial8250_do_set_termios() - Delete the verbose error message pr_info() in bytes_to_fcr_rxtrig() - Rename *rx_int_trig/rx_trig* to *rxtrig* for several functions or variables (but UI remains rx_int_trig) - Change the meaningless variable name 'val' to 'bytes' following functions: fcr_get_rxtrig_bytes(), bytes_to_fcr_rxtrig(), do_set_rxtrig(), do_serial8250_set_rxtrig(), and serial8250_set_attr_rxtrig() - Use up->fcr in order to get rxtrig_bytes instead of rx_trig_raw in fcr_get_rxtrig_bytes() - Use conf_type->rxtrig_bytes[0] instead of switch statement for support check in register_dev_spec_attr_grp() - Delete the checking whether a user changed FCR or not when minimum buffer is needed in serial8250_do_set_termios() Changes in V5.1: - Fix FCR_RX_TRIG_MAX_STATE definition Changes in V5: - Support Tegra, 16650V2, 16654, and 16750 - Store default FCR value to up->fcr when the port is first created - Add rx_trig_byte[] in uart_config[] for each device and use rx_trig_byte[] in convert_fcr2val() and convert_val2rxtrig() Changes in V4: - Introduce fifo_bug flag in uart_8250_port structure This is enabled only when parity is enabled and UART_BUG_PARITY is enabled for up->bugs. If this flag is enabled, user cannot set RX trigger. - Return -EOPNOTSUPP when it does not support device at convert_fcr2val() and at convert_val2rxtrig() - Set the nearest lower RX trigger when users input a meaningless value at convert_val2rxtrig() - Check whether p->fcr is existing at serial8250_clear_and_reinit_fifos() - Set fcr = up->fcr in the begging of serial8250_do_set_termios() Changes in V3: - Change I/F from ioctl(2) to sysfs(rx_int_trig) Changed in V2: - Use _IOW for TIOCSFIFORTRIG definition - Pass the interrupt trigger value itself --- Greg Kroah-Hartman (1): Serial: allow port drivers to have a default attribute group Yoshihiro YUNOMAE (1): serial/uart/8250: Add tunable RX interrupt trigger I/F of FIFO buffers Documentation/ABI/testing/sysfs-tty | 16 +++ drivers/tty/serial/8250/8250.h |2 drivers/tty/serial/8250/8250_core.c | 173 --- drivers/tty/serial/serial_core.c| 24 +++-- include/linux/serial_8250.h |2 include/linux/serial_core.h |2 include/uapi/linux/serial_reg.h | 5 + 7 files changed, 202 insertions(+), 22 deletions(-) -- Yoshihiro YUNOMAE Software Platform Research Dept. Linux Technology Center Hitachi, Ltd., Yokohama Research Laboratory E-mail: yoshihiro.yunomae...@hitachi.com -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
Re: Re: [PATCH V8 2/2] serial/uart/8250: Add tunable RX interrupt trigger I/F of FIFO buffers
(2014/07/13 6:22), Greg KH wrote: On Thu, Jul 10, 2014 at 04:16:37PM -0700, Greg Kroah-Hartman wrote: On Thu, Jul 10, 2014 at 03:31:57PM +0100, One Thousand Gnomes wrote: I really don't like the way that the tty core has been changed to handle multiple attribute groups, as I feel tty drivers shouldn't be creating "special" sysfs files, depending on what driver is bound to them. The intent isn't that it is "special" but that it can be propogated to others as and when they wish to provide it. Usually we have handled this using tools like 'stty' and ioctls, right? Surely there is an ioctl to control the interrupt level, right? Hasn't this been covered before somehow? No, and the direction when this started was to use sysfs as we have also been moving all the other attributes towards sysfs and has been since 2012. TTY devices do have lots of strange attributes and right now many of them are only programmable by using device tree and rebooting. Ok. Hm, there has to be a better way to do the group sysfs file handling... Let me work on this tomorrow and see what I can come up with. We should be able to use the is_visable() attribute to create/notcreate the attribute where needed... Ok, how about this patch instead of your first one? It creates a new port attribute, attr_group, which you should be able to set in the 8250 driver if you device needs it. Then the serial core will handle the dynamic group creation, without relying on a "magic" number of groups. Very close to your patch, but now it's dynamic, and no fixed array, and no crazy casting in the tty_port_register_device_attr() call. Thank you very much for your patch. I'll use it as 1st patch in next version. I have not tested this, only test built the code. OK, I'll test it. If it works for you, can you redo your second patch, and then send both of these back to me so that I can apply them? Sure. Thank you, Yoshihiro YUNOMAE -- Yoshihiro YUNOMAE Software Platform Research Dept. Linux Technology Center Hitachi, Ltd., Yokohama Research Laboratory E-mail: yoshihiro.yunomae...@hitachi.com -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[PATCH V4 2/5] trace-cmd/msg: Use poll(2) to wait for a message
Use poll(2) to wait for a message. If a client/server cannot send a message for any reasons, the current server/client will wait in a blocking read operation. So, we use poll(2) for avoiding remaining in a blocking state. Changes in V4: Change the argument of tracecmd_msg_recv_wait() Fix some typos Signed-off-by: Yoshihiro YUNOMAE --- trace-msg.c | 42 -- 1 file changed, 36 insertions(+), 6 deletions(-) diff --git a/trace-msg.c b/trace-msg.c index 08fa2a6..db48365 100644 --- a/trace-msg.c +++ b/trace-msg.c @@ -395,6 +395,27 @@ error: return -ENOMSG; } +#define MSG_WAIT_MSEC 5000 + +/* + * A return value of 0 indicates time-out + */ +static int tracecmd_msg_recv_wait(int fd, struct tracecmd_msg *msg) +{ + struct pollfd pfd; + int ret; + + pfd.fd = fd; + pfd.events = POLLIN; + ret = poll(&pfd, 1, MSG_WAIT_MSEC); + if (ret < 0) + return -errno; + else if (ret == 0) + return -ETIMEDOUT; + + return tracecmd_msg_recv(fd, msg); +} + static void *tracecmd_msg_buf_access(struct tracecmd_msg *msg, int offset) { return (void *)msg + offset; @@ -405,9 +426,12 @@ static int tracecmd_msg_wait_for_msg(int fd, struct tracecmd_msg *msg) u32 cmd; int ret; - ret = tracecmd_msg_recv(fd, msg); - if (ret < 0) + ret = tracecmd_msg_recv_wait(fd, msg); + if (ret < 0) { + if (ret == -ETIMEDOUT) + warning("Connection timed out\n"); return ret; + } cmd = ntohl(msg->cmd); if (cmd == MSG_CLOSE) @@ -487,9 +511,12 @@ int tracecmd_msg_initial_setting(int fd, int *cpus, int *pagesize) u32 cmd; msg = (struct tracecmd_msg *)buf; - ret = tracecmd_msg_recv(fd, msg); - if (ret < 0) + ret = tracecmd_msg_recv_wait(fd, msg); + if (ret < 0) { + if (ret == -ETIMEDOUT) + warning("Connection timed out\n"); return ret; + } cmd = ntohl(msg->cmd); if (cmd != MSG_TINIT) { @@ -627,9 +654,12 @@ int tracecmd_msg_collect_metadata(int ifd, int ofd) msg = (struct tracecmd_msg *)buf; do { - ret = tracecmd_msg_recv(ifd, msg); + ret = tracecmd_msg_recv_wait(ifd, msg); if (ret < 0) { - warning("reading client"); + if (ret == -ETIMEDOUT) + warning("Connection timed out\n"); + else + warning("reading client"); return ret; } -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[PATCHV4 0/5] trace-cmd: Support the feature which guests send trace data via virtio
Hi Steven, This is a v4 patch set to support the feature which guests send trace data via virtio. (Previous patch set is here: https://lkml.org/lkml/2013/12/16/688) Any features in this V4 patch series are not changed from previous version. I fixed some typos, rebased for current version, and added usage in this version. Would you review this patch series? 1. Run virt-server on a host # trace-cmd virt-server --dom guest1 -c 2 2. Set up of virtio-serial pipe of guest1 on the host Add the following tags to domain XML files. # virsh edit guest1 3. Boot the guest # virsh start guest1 4. Run the guest1's client(see trace-cmd-record(1) with the *--virt* option) # trace-cmd record -e sched* --virt If you want to boot another guest sends trace-data via virtio-serial, you will manually make the guest domain directory and trace data I/Fs. - Make guest domain directory on the host # mkdir -p /tmp/trace-cmd/virt/ # chmod 710 /tmp/trace-cmd/virt/ # chgrp qemu /tmp/trace-cmd/virt/ - Make FIFO on the host # mkfifo /tmp/trace-cmd/virt//trace-path-cpu{0,1,...,X}.{in,out} I measured CPU usage outputted by top command on a guest when client sends trace data. Client means "record -N"(NW) or "record --virt"(virtio-serial). NW virtio-serial(splice) client(fedora19)~2.9[%] ~1.7[%] Changes in V4: [1/5] Fix some typos, cleanup, and rebase for current trace-cmd-v2.4 Change the argument of tracecmd_msg_recv() [2/5] Fix some typos Change the argument of tracecmd_msg_recv_wait() [3/5] Fix some typos and cleanup [4/5] Introduce parse_args_virt() and add usage of virt-server in trace-usage.c [5/5] Rebase for current trace-cmd-v2.4 and add usage of --virt for record in trace-usage.c Divide tracecmd_msg_connect_to_server() into two functions (tracecmd_msg_connect_to_server() and tracecmd_msg_send_init_data_virt(fd)) Changes in V3: [2/6] Change the license of trace-msg.c to LGPL v2.1 [4/6] Change _nw/_NW to _net/_NET [5/6] Change _nw/_NW to _net/_NET [6/6] Add this patch based on Steven's review (https://lkml.org/lkml/2013/10/14/618) Changes in V2: [1/5] Add a comment in open_udp() [2/5] Regacy protocol support in order to keep backward compatibility Thank you, --- Yoshihiro YUNOMAE (5): trace-cmd/listen: Apply the trace-msg protocol for communication between a server and clients trace-cmd/msg: Use poll(2) to wait for a message trace-cmd/virt-server: Add virt-server mode for a virtualization environment trace-cmd/virt-server: Add --dom option which makes a domain directory to virt-server trace-cmd/record: Add --virt option for record mode Documentation/trace-cmd-record.1.txt | 11 Documentation/trace-cmd-virt-server.1.txt | 113 Makefile |2 trace-cmd.c |3 trace-cmd.h | 15 trace-listen.c| 717 +++- trace-msg.c | 873 + trace-msg.h | 31 + trace-output.c|4 trace-record.c| 146 - trace-recorder.c | 50 +- trace-usage.c | 18 + 12 files changed, 1818 insertions(+), 165 deletions(-) create mode 100644 Documentation/trace-cmd-virt-server.1.txt create mode 100644 trace-msg.c create mode 100644 trace-msg.h -- Yoshihiro YUNOMAE Software Platform Research Dept. Linux Technology Center Hitachi, Ltd., Yokohama Research Laboratory E-mail: yoshihiro.yunomae...@hitachi.com -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[PATCH V4 5/5] trace-cmd/record: Add --virt option for record mode
Add --virt option for record mode for a virtualization environment. If we use this option on a guest, we can send trace data in low-overhead. This is because guests can send trace data to a host without copying the data by using splice(2). The format is: trace-cmd record --virt -e sched* The client using virtio-serial does not wait for the connection message "tracecmd" from the server. The client sends the connection message MSG_TCONNECT first. This feature can use from kernel-3.6 which supports splice_read for ftrace and splice_write for virtio-serial. Changes in V4: Rebase for current trace-cmd-v2.4 Add usage of --virt for record in trace-usage.c Divide tracecmd_msg_connect_to_server() into two functions (tracecmd_msg_connect_to_server() and tracecmd_msg_send_init_data_virt(fd)) Changes in V3: Change _nw/_NW to _net/_NET Signed-off-by: Yoshihiro YUNOMAE --- Documentation/trace-cmd-record.1.txt | 11 - trace-cmd.h |4 +- trace-msg.c | 79 +++--- trace-msg.h |4 ++ trace-record.c | 71 --- trace-usage.c|3 + 6 files changed, 158 insertions(+), 14 deletions(-) diff --git a/Documentation/trace-cmd-record.1.txt b/Documentation/trace-cmd-record.1.txt index 9e63eb4..c0de074 100644 --- a/Documentation/trace-cmd-record.1.txt +++ b/Documentation/trace-cmd-record.1.txt @@ -258,6 +258,15 @@ OPTIONS timestamp to gettimeofday which will allow wall time output from the timestamps reading the created 'trace.dat' file. +*--virt*:: +This option is usded on a guest in a virtualization environment. If a host +is running "trace-cmd virt-server", this option is used to have the data +sent to the host with virtio-serial like *-N* option. (see also +trace-cmd-virt-server(1)) + +Note: This option is not supported with latency tracer plugins: + wakeup, wakeup_rt, irqsoff, preemptoff and preemptirqsoff + EXAMPLES @@ -320,7 +329,7 @@ SEE ALSO trace-cmd(1), trace-cmd-report(1), trace-cmd-start(1), trace-cmd-stop(1), trace-cmd-extract(1), trace-cmd-reset(1), trace-cmd-split(1), -trace-cmd-list(1), trace-cmd-listen(1) +trace-cmd-list(1), trace-cmd-listen(1), trace-cmd-virt-server(1) AUTHOR -- diff --git a/trace-cmd.h b/trace-cmd.h index c4e5beb..1c1b0c3 100644 --- a/trace-cmd.h +++ b/trace-cmd.h @@ -250,7 +250,9 @@ void tracecmd_stat_cpu(struct trace_seq *s, int cpu); long tracecmd_flush_recording(struct tracecmd_recorder *recorder); /* for clients */ -int tracecmd_msg_send_init_data(int fd); +int tracecmd_msg_connect_to_server(int fd); +int tracecmd_msg_send_init_data_net(int fd); +int tracecmd_msg_send_init_data_virt(int fd); int tracecmd_msg_metadata_send(int fd, char *buf, int size); int tracecmd_msg_finish_sending_metadata(int fd); void tracecmd_msg_send_close_msg(void); diff --git a/trace-msg.c b/trace-msg.c index 0d606dc..7ca31d6 100644 --- a/trace-msg.c +++ b/trace-msg.c @@ -30,6 +30,7 @@ #include #include #include +#include #include #include @@ -72,6 +73,7 @@ int cpu_count; static int psfd; unsigned int page_size; int *client_ports; +int *virt_sfds; bool send_metadata; /* for server */ @@ -272,12 +274,20 @@ static int make_rinit(struct tracecmd_msg *msg) return 0; } +static int make_error_msg(u32 len, struct tracecmd_msg *msg) +{ + bufcpy(msg, TRACECMD_MSG_HDR_LEN, errmsg, len); + return 0; +} + static u32 tracecmd_msg_get_body_length(u32 cmd) { struct tracecmd_msg *msg; u32 len = 0; switch (cmd) { + case MSG_ERROR: + return ntohl(errmsg->size); case MSG_RCONNECT: return sizeof(msg->data.rconnect.str.size) + CONNECTION_MSGSIZE; case MSG_TINIT: @@ -305,6 +315,7 @@ static u32 tracecmd_msg_get_body_length(u32 cmd) + sizeof(msg->data.rinit.port_array); case MSG_SENDMETA: return TRACECMD_MSG_MAX_LEN - TRACECMD_MSG_HDR_LEN; + case MSG_TCONNECT: case MSG_CLOSE: case MSG_FINMETA: break; @@ -313,15 +324,18 @@ static u32 tracecmd_msg_get_body_length(u32 cmd) return 0; } -static int tracecmd_msg_make_body(u32 cmd, struct tracecmd_msg *msg) +static int tracecmd_msg_make_body(u32 cmd, u32 len, struct tracecmd_msg *msg) { switch (cmd) { + case MSG_ERROR: + return make_error_msg(len, msg); case MSG_RCONNECT: return make_rconnect(CONNECTION_MSG, CONNECTION_MSGSIZE, msg); case MSG_TINIT: return make_tinit(msg); case MSG_RINIT: return make_rinit(msg); + case MSG_TCONNECT: case MSG_CLOSE: case MSG_SE
[PATCH V4 1/5] trace-cmd/listen: Apply the trace-msg protocol for communication between a server and clients
Apply trace-msg protocol for communication between a server and clients. Currently, trace-listen(server) and trace-record -N(client) operate as follows: listen to socket fd connect to socket fd accept the client send "tracecmd" +> receive "tracecmd" check "tracecmd" send cpus receive cpus <+ print "cpus=XXX" send pagesize | receive pagesize <+ print "pagesize=XXX" send option | receive option <--+ understand option send port_array +> receive port_array understand port_array send meta data receive meta data <---+ record meta data (snip) read block --- start sending trace data on child processes --- --- When client finishes sending trace data --- close(socket fd) read size = 0 close(socket fd) All messages are unstructured character strings, so server(client) using the protocol must parse the unstructured messages. Since it is hard to add complex contents in the protocol, structured binary message trace-msg is introduced as the communication protocol. By applying this patch, server and client operate as follows: listen to socket fd connect to socket fd accept the client send "tracecmd" +> receive "tracecmd" check "tracecmd" send "V2\0\00" as the v2 protocol receive "V2" <+ check "V2" read "\00" send "V2" +---> receive "V2" check "V2" send cpus,pagesize,option(MSG_TINIT) receive MSG_TINIT <---+ print "cpus=XXX" print "pagesize=XXX" understand option send port_array +--MSG_RINIT-> receive MSG_RINIT understand port_array send meta data(MSG_SENDMETA) receive MSG_SENDMETA <+ record meta data (snip) send a message to finish sending meta data | (MSG_FINMETA) receive MSG_FINMETA <-+ read block --- start sending trace data on child processes --- --- When client finishes sending trace data --- send MSG_CLOSE receive MSG_CLOSE <---+ close(socket fd)close(socket fd) By introducing the v2 protocol, after the client checks "tracecmd", the client will send "V2\0\00\0". This complex message is used when the new client tries to connect to the old server. The new client wants to check whether the reply message from the server is "V2" or not. However, the old server does not respond to the client before receiving cpu numbers, page size, and options. Each message is separated with "\0" in the old server, so the client send "V2" as cpu numbers, "" as page size, and "0" as no options. On the other hands, the old server will understand the messages as cpus=0, pagesize=, and options=0, and then the server will send the message "\0" as port numbers. Then, the message which the client receives is not "V2" but "\0", so the client will reconnect to the old server as the v1 protocol. [1] Backward compatability checks We need to test backward compatability of this patch for old trace-cmds(client/server). So, this patch was tested for [2] command checks in following 3 types: new old old new new new [2] Command checks - server (common) # trace-cmd listen -p 12345 1) record - client # trace-cmd record -e sched -N :12345 ^C 2) record + multiple buffers - client # trace-cmd record -B foo -e sched -N :12345 ^C 3) extract - client # ./trace-cmd start -e sched # sleep 5 # ./trace-cmd extract -N :12345 4) extract + snapshot - client # ./trace-cmd start -e sched # sleep 5 # ./trace-cmd snapshot -s # ./trace-cmd extract -N :12345 -s Changes in V4: Fix some typos, cleanups and rebase for current trace-cmd-v2.4 Change t
[PATCH V4 4/5] trace-cmd/virt-server: Add --dom option which makes a domain directory to virt-server
Add --dom option which makes a domain directory to virt-server. When a user already knows domain name of a guest before running virt-server, trace-cmd should automatically set up I/Fs of the guest. By adding --dom option, trace-cmd creates a domain directory with 0710 and qemu group. This patch adds additional options for --dom as follows: -m This option changes the permission of domain directory. If you don't use this option, the default permission is 0710. -g This option changes group of domain directory. If you don't use this option, the default group is qemu. -c This option creates trace data I/Fs(trace-path-cpu*.{in,out}) for each CPU of 'domain'. If you don't use this option, those files are not created. Here, an example you use this option is written as follows: - trace-cmd creates a guest1 directory with trace data I/Fs of 2 CPUs. # trace-cmd virt-server --dom guest1 -c 2 - trace-cmd creates guest2 and guest3 directories # trace-cmd virt-server --dom guest2 -c 3 --dom guest3 -c 1 Changes in V4: Introduce parse_args_virt() Add usage of virt-server in trace-usage.c Signed-off-by: Yoshihiro YUNOMAE --- Documentation/trace-cmd-virt-server.1.txt | 56 --- trace-listen.c| 151 ++--- trace-usage.c |5 + 3 files changed, 178 insertions(+), 34 deletions(-) diff --git a/Documentation/trace-cmd-virt-server.1.txt b/Documentation/trace-cmd-virt-server.1.txt index 4168a04..fbd0ad6 100644 --- a/Documentation/trace-cmd-virt-server.1.txt +++ b/Documentation/trace-cmd-virt-server.1.txt @@ -34,40 +34,64 @@ OPTIONS *-l* 'filename':: This option writes the output messages to a log file instead of standard output. +*--dom* 'domain':: +This option makes a directory for the 'domain'. You can use additional options +*-m*, *-g*, *-c* after this option for the 'domain'. If you don't use these +additional options, the directory is made as 0710 and qemu group and +trace data I/Fs(trace-path-cpu*.{in,out}) are not created. + +*-m* 'permission':: +This option changes the permission of 'domain' directory. If you don't use +this option, the default permission is 0710. + +*-g* 'group':: +This option changes group of 'domain' directory. If you don't use this option, +the default group is qemu. + +*-c* 'cpu':: +This option creates trace data I/Fs(trace-path-cpu*.{in,out}) for each CPU +of 'domain'. If you don't use this option, those files are not created. + SET UP -- Here, an example is written as follows: 1. Run virt-server on a host - # trace-cmd virt-server - -2. Make guest domain directory - # mkdir -p /tmp/trace-cmd/virt/ - # chmod 710 /tmp/trace-cmd/virt/ - # chgrp qemu /tmp/trace-cmd/virt/ - -3. Make FIFO on the host - # mkfifo /tmp/trace-cmd/virt//trace-path-cpu{0,1,...,X}.{in,out} + # trace-cmd virt-server --dom guest1 -c 2 -4. Set up of virtio-serial pipe of a guest on the host +2. Set up of virtio-serial pipe of guest1 on the host Add the following tags to domain XML files. - # virsh edit + # virsh edit guest1 - + - ... (cpu1, cpu2, ...) + + + + -5. Boot the guest - # virsh start +3. Boot the guest + # virsh start guest1 -6. Run the guest's client(see trace-cmd-record(1) with the *--virt* option) +4. Run the guest1's client(see trace-cmd-record(1) with the *--virt* option) # trace-cmd record -e sched* --virt +If you want to boot another guest sends trace-data via virtio-serial, +you will manually make the guest domain directory and trace data I/Fs. + +- Make guest domain directory on the host + # mkdir -p /tmp/trace-cmd/virt/ + # chmod 710 /tmp/trace-cmd/virt/ + # chgrp qemu /tmp/trace-cmd/virt/ + +- Make FIFO on the host + # mkfifo /tmp/trace-cmd/virt//trace-path-cpu{0,1,...,X}.{in,out} + SEE ALSO trace-cmd(1), trace-cmd-record(1), trace-cmd-report(1), trace-cmd-start(1), diff --git a/trace-listen.c b/trace-listen.c index 01b7ebf..e424c2a 100644 --- a/trace-listen.c +++ b/trace-listen.c @@ -54,11 +54,21 @@ static int backlog = 5; static int proto_ver; +struct domain_dir { + struct domain_dir *next; + char *name; + char *group; + mode_t perms; + int cpu; +}; + enum { NET = 1, VIRT= 2, }; +struct domain_dir *dom_dir_list; + #define TEMP_FILE_STR_NET "%s.%s:%s.cpu%d", output_file, host, port, cpu #define TEMP_FILE_STR_VIRT "%s.%s:%d.cpu%d", output_file, domain, virtpid, cpu static char *get_temp_file(const char *host, const char *port, @@ -382,7 +392,9 @@ static int open_udp(const char *node, const char *port, int *pid, #define TRACE_CM
[PATCH V4 3/5] trace-cmd/virt-server: Add virt-server mode for a virtualization environment
Add the virt-server mode for a virtualization environment based on the listen mode for networking. This mode works like client/server mode over TCP/UDP, but it uses virtio-serial channel instead of IP network. Using networking for collecting trace data of guests is generally high overhead caused by processing of the network stack. We use virtio-serial for collecting trace data of guests. virtio-serial is a simple communication path between the guest and the host. Moreover, since virtio-serial and ftrace can use splice(2), memory copying is not occurred on the guests. Therefore, total overhead for collecting trace data of the guests will be reduced. The implementation of clients will be shown in another patch. virt-server uses two kinds of virtio-serial I/Fs: (1) agent-ctl-path(UNIX domain socket) => control path of an agent trace-cmd each guest (2) trace-path-cpuX(named pipe) => trace data path each vcpu Those I/Fs must be defined as below paths: (1) /tmp/trace-cmd/virt/agent-ctl-path (2) /tmp/trace-cmd/virt//trace-path-cpuX If we run virt-server, agent-ctl-path I/F is automatically created because virt-server operates as a server mode of UNIX domain socket. However, trace-path-cpuX is not automatically created because we need to separate trace data for each guests. When the client uses virtio-serial, the client must notify the server of the connection. This is because a virtio-serial I/F on the guest is a just character device. In other words, the server cannot understand whether the client exists or not even if the client opens the I/F. So, the server using virtio-serial waits for the connection message MSG_TCONNECT from the client. The server and the client operate as follows: wait for MSG_TCONNECT open virtio-serial I/F send MSG_TCONNECT receive MSG_TCONNECT <+ send MSG_RCONNECT +---> receive MSG_RCONNECT check "tracecmd-V2" send cpus,pagesize,option(MSG_TINIT) receive MSG_TINIT <---+ print "cpus=XXX" print "pagesize=XXX" understand option send port_array +--MSG_RINIT-> receive MSG_RINIT understand port_array send meta data(MSG_SENDMETA) receive MSG_SENDMETA <+ record meta data (snip) send a message to finish sending meta data | (MSG_FINMETA) receive MSG_FINMETA <-+ read block --- start sending trace data on child processes --- --- When client finishes sending trace data --- send MSG_CLOSE receive MSG_CLOSE <---+ close(socket fd)close(socket fd) 1. Run virt-server on a host before booting guests # trace-cmd virt-server 2. Make guest domain directory # mkdir -p /tmp/trace-cmd/virt/ # chmod 710 /tmp/trace-cmd/virt/ # chgrp qemu /tmp/trace-cmd/virt/ 3. Make FIFO on the host # mkfifo /tmp/trace-cmd/virt//trace-path-cpu{0,1,...,X}.{in,out} 4. Set up of virtio-serial pipe of a guest on the host Add the following tags to domain XML files. # virsh edit ... (cpu1, cpu2, ...) 5. Boot the guest # virsh start 6. Check I/F of virtio-serial on the guest # ls /dev/virtio-ports ... agent-ctl-path ... trace-path-cpu0 ... Next, the user will run trace-cmd with record --virt options or other options for virtualization on the guest. This patch adds only minimum features of virt-server as follows: - virt-server subcommand - Create I/F directory(/tmp/trace-cmd/virt/) - Use named pipe I/Fs of virtio-serial for trace data paths - Use UNIX domain socket for connecting clients on guests - Use splice(2) for collecting trace data of guests - Use libvirt when we boot guests Changes in V4: Fix some typos and cleanup Changes in V3: Change _nw/_NW to _net/_NET Signed-off-by: Yoshihiro YUNOMAE --- Documentation/trace-cmd-virt-server.1.txt | 89 ++ trace-cmd.c |3 trace-cmd.h |2 trace-listen.c| 467 - trace-msg.c | 106 ++- trace-recorder.c | 50 ++- trace-usage.c | 10 + 7 files changed, 624 insertions(+), 103 deletions(-) create mode 100644 Documentation/trace-cmd-virt-server.1.txt diff --git a/Documentation/trace-cmd-virt-server.1.txt b/Documentation/trace-cmd-virt-server.1.txt new file mode 100644 index 000..4168a04 --- /dev/null +++ b/Documentation/trace-cmd-virt-server.1.txt @@ -0,0 +1,89 @@ +TRACE-CMD-VIRT-SER
[ PATCH 0/2] [BUGFIX] trace-cmd: Fix two small bugs
Hi Steven, I found two small bugs for current trace-cmd, so I fixed those. 1st patch fixes the problem which listen server reader processes abort silently. 2nd patch fixes the problem which trace-cmd cannot record trace data of multiple buffers in old kernels. Thank you, --- Yoshihiro YUNOMAE (2): trace-cmd: [BUGFIX] Initialize handle->options list in tracecmd_attach_cpu_data_fd() trace-cmd: [BUGFIX] Don't die if an instance does not have 'current_tracer' file trace-output.c |1 + trace-record.c | 12 +++- 2 files changed, 12 insertions(+), 1 deletion(-) -- Yoshihiro YUNOMAE Software Platform Research Dept. Linux Technology Center Hitachi, Ltd., Yokohama Research Laboratory E-mail: yoshihiro.yunomae...@hitachi.com -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[PATCH 1/2] trace-cmd: [BUGFIX] Initialize handle->options list in tracecmd_attach_cpu_data_fd()
This patch initializes handle->options list in tracecmd_attach_cpu_data_fd(). When recorder sends trace data via network, server recording process is killed by SIGSEGV from the patch 71484a0854f7. This is because add_options() uses handle->options list from the patch, but tracecmd_attach_cpu_data_fd() calling add_options() does not initialize the list in spite of allocation of new handle. As the result, the server recording process will be killed because handle->options is cleared to zero in tracecmd_attach_cpu_data_fd(). 1. Execute network(listen) server # trace-cmd listen -p 12345 2. Execute network client # trace-cmd record -e sched* -N :12345 3. Stop the record on client ^C Here, network server should output a line "CPUX data recorded at offset=", but current network server aborts silently. Moreover the client's per-cpu files are separated. (Normally those files are merged into one trace file.) 4. Confirm error on network server # dmesg | tail -1 [18551.537113] trace-cmd[23073]: segfault at ffe8 ip 00432fd1 sp 7fa4caa0 error 5 in trace-cmd[40+47000] After we would introduce this patch, the server will be fully able to output the client's tracing data and we will not get this error. Signed-off-by: Yoshihiro YUNOMAE Cc: Steven Rostedt --- trace-output.c |1 + 1 file changed, 1 insertion(+) diff --git a/trace-output.c b/trace-output.c index ed81466..b033baa 100644 --- a/trace-output.c +++ b/trace-output.c @@ -1202,6 +1202,7 @@ int tracecmd_attach_cpu_data_fd(int fd, int cpus, char * const *cpu_data_files) handle->pevent = tracecmd_get_pevent(ihandle); pevent_ref(pevent); handle->page_size = tracecmd_page_size(ihandle); + list_head_init(&handle->options); if (tracecmd_append_cpu_data(handle, cpus, cpu_data_files) >= 0) ret = 0; -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[PATCH 2/2] trace-cmd: [BUGFIX] Don't die if an instance does not have 'current_tracer' file
Current trace-cmd requires 'current_tracer' file for an instance, and if the file is nothing, trace-cmd dies. However, current_tracer file was introduced from 607e2ea167e patch in Linux kernel 3.14-rc3, so current trace-cmd cannot use multiple buffers for old kernels. This patch avoids to die if current_tracer file is nothing in an instance and the plugin name is "nop". This is because old kernels always trace as nop mode in an instance. 1) # ./trace-cmd record -B foo -e sched Before introducing this patch, following error message is output in an old kernel: trace-cmd: Permission denied writing to '/sys/kernel/debug/tracing/instances/foo/current_tracer' trace-cmd dies in disable_trace() calling set_plugin("nop"). After introducing this patch, trace-cmd works fine in both old kernels and current kernel. 2) # ./trace-cmd record -B foo -e sched -p nop It also works fine after introducing this patch in both old kernels and current kernel. 3) # ./trace-cmd record -B foo -e sched -p function For old kernels, it dies because an user should not set plugin tracer. For current kernel, it works fine. Note that this patch was tested for kernel 3.11.9-200 and 3.15.0-rc2+. Signed-off-by: Yoshihiro YUNOMAE Cc: Steven Rostedt --- trace-record.c | 12 +++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/trace-record.c b/trace-record.c index d3dd0c5..1912175 100644 --- a/trace-record.c +++ b/trace-record.c @@ -890,8 +890,18 @@ set_plugin_instance(struct buffer_instance *instance, const char *name) path = get_instance_file(instance, "current_tracer"); fp = fopen(path, "w"); - if (!fp) + if (!fp) { + /* +* Legacy kernels do not have current_tracer file, and they +* always use nop. So, it doesn't need to try to change the +* plugin for those if name is "nop". +*/ + if (!strncmp(name, "nop", 3)) { + tracecmd_put_tracing_file(path); + return; + } die("writing to '%s'", path); + } tracecmd_put_tracing_file(path); fwrite(name, 1, strlen(name), fp); -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[RESEND PATCH V8 0/2] serial/uart/8250: Introduce tunable RX trigger I/F
Hi Greg, This patch set introduces tunable RX interrupt trigger I/F for 8250 serials. I just split V7's patch up into 2 patches, and all functions are not changed from previous version. V6 patch was reviewed by Stephen Warren and acked, but I removed the 'Reviewed-by' for this patch set just in case. Would you review this patch set? Thanks! Changes in V8: - Split V7's patch up into 2 patches Changes in V7: - Add Documentation - Change I/F name from rx_int_trig to rx_trig_bytes because the name rx_int_trig is hard to understand how users specify the value Changes in V6: - Move FCR_RX_TRIG_* definition in 8250.h to include/uapi/linux/serial_reg.h, rename those to UART_FCR_R_TRIG_*, and use UART_FCR_TRIGGER_MASK to UART_FCR_R_TRIG_BITS() - Change following function names: convert_fcr2val() => fcr_get_rxtrig_bytes() convert_val2rxtrig() => bytes_to_fcr_rxtrig() - Fix typo in serial8250_do_set_termios() - Delete the verbose error message pr_info() in bytes_to_fcr_rxtrig() - Rename *rx_int_trig/rx_trig* to *rxtrig* for several functions or variables (but UI remains rx_int_trig) - Change the meaningless variable name 'val' to 'bytes' following functions: fcr_get_rxtrig_bytes(), bytes_to_fcr_rxtrig(), do_set_rxtrig(), do_serial8250_set_rxtrig(), and serial8250_set_attr_rxtrig() - Use up->fcr in order to get rxtrig_bytes instead of rx_trig_raw in fcr_get_rxtrig_bytes() - Use conf_type->rxtrig_bytes[0] instead of switch statement for support check in register_dev_spec_attr_grp() - Delete the checking whether a user changed FCR or not when minimum buffer is needed in serial8250_do_set_termios() Changes in V5.1: - Fix FCR_RX_TRIG_MAX_STATE definition Changes in V5: - Support Tegra, 16650V2, 16654, and 16750 - Store default FCR value to up->fcr when the port is first created - Add rx_trig_byte[] in uart_config[] for each device and use rx_trig_byte[] in convert_fcr2val() and convert_val2rxtrig() Changes in V4: - Introduce fifo_bug flag in uart_8250_port structure This is enabled only when parity is enabled and UART_BUG_PARITY is enabled for up->bugs. If this flag is enabled, user cannot set RX trigger. - Return -EOPNOTSUPP when it does not support device at convert_fcr2val() and at convert_val2rxtrig() - Set the nearest lower RX trigger when users input a meaningless value at convert_val2rxtrig() - Check whether p->fcr is existing at serial8250_clear_and_reinit_fifos() - Set fcr = up->fcr in the begging of serial8250_do_set_termios() Changes in V3: - Change I/F from ioctl(2) to sysfs(rx_int_trig) Changed in V2: - Use _IOW for TIOCSFIFORTRIG definition - Pass the interrupt trigger value itself --- Yoshihiro YUNOMAE (2): serial/uart: Introduce device specific attribute group to uart_port structure serial/uart/8250: Add tunable RX interrupt trigger I/F of FIFO buffers Documentation/ABI/testing/sysfs-tty | 16 +++ drivers/tty/serial/8250/8250.h |2 drivers/tty/serial/8250/8250_core.c | 173 --- drivers/tty/serial/serial_core.c| 18 ++-- include/linux/serial_8250.h |2 include/linux/serial_core.h |4 + include/uapi/linux/serial_reg.h | 5 + 7 files changed, 198 insertions(+), 22 deletions(-) -- Yoshihiro YUNOMAE Software Platform Research Dept. Linux Technology Center Hitachi, Ltd., Yokohama Research Laboratory E-mail: yoshihiro.yunomae...@hitachi.com -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[RESEND PATCH V8 2/2] serial/uart/8250: Add tunable RX interrupt trigger I/F of FIFO buffers
Add tunable RX interrupt trigger I/F of FIFO buffers. Serial devices are used as not only message communication devices but control or sending communication devices. For the latter uses, normally small data will be exchanged, so user applications want to receive data unit as soon as possible for real-time tendency. If we have a sensor which sends a 1 byte data each time and must control a device based on the sensor feedback, the RX interrupt should be triggered for each data. According to HW specification of serial UART devices, RX interrupt trigger can be changed, but the trigger is hard-coded. For example, RX interrupt trigger in 16550A can be set to 1, 4, 8, or 14 bytes for HW, but current driver sets the trigger to only 8bytes. This patch makes some devices change RX interrupt trigger from userland. - Read current setting # cat /sys/class/tty/ttyS0/rx_trig_bytes 8 - Write user setting # echo 1 > /sys/class/tty/ttyS0/rx_trig_bytes # cat /sys/class/tty/ttyS0/rx_trig_bytes 1 - 16550A and Tegra (1, 4, 8, or 14 bytes) - 16650V2 (8, 16, 24, or 28 bytes) - 16654 (8, 16, 56, or 60 bytes) - 16750 (1, 16, 32, or 56 bytes) Changes in V8: - Divide this patch from V7's patch based on Greg's comment Changes in V7: - Add Documentation - Change I/F name from rx_int_trig to rx_trig_bytes because the name rx_int_trig is hard to understand how users specify the value Changes in V6: - Move FCR_RX_TRIG_* definition in 8250.h to include/uapi/linux/serial_reg.h, rename those to UART_FCR_R_TRIG_*, and use UART_FCR_TRIGGER_MASK to UART_FCR_R_TRIG_BITS() - Change following function names: convert_fcr2val() => fcr_get_rxtrig_bytes() convert_val2rxtrig() => bytes_to_fcr_rxtrig() - Fix typo in serial8250_do_set_termios() - Delete the verbose error message pr_info() in bytes_to_fcr_rxtrig() - Rename *rx_int_trig/rx_trig* to *rxtrig* for several functions or variables (but UI remains rx_int_trig) - Change the meaningless variable name 'val' to 'bytes' following functions: fcr_get_rxtrig_bytes(), bytes_to_fcr_rxtrig(), do_set_rxtrig(), do_serial8250_set_rxtrig(), and serial8250_set_attr_rxtrig() - Use up->fcr in order to get rxtrig_bytes instead of rx_trig_raw in fcr_get_rxtrig_bytes() - Use conf_type->rxtrig_bytes[0] instead of switch statement for support check in register_dev_spec_attr_grp() - Delete the checking whether a user changed FCR or not when minimum buffer is needed in serial8250_do_set_termios() Changes in V5.1: - Fix FCR_RX_TRIG_MAX_STATE definition Changes in V5: - Support Tegra, 16650V2, 16654, and 16750 - Store default FCR value to up->fcr when the port is first created - Add rx_trig_byte[] in uart_config[] for each device and use rx_trig_byte[] in convert_fcr2val() and convert_val2rxtrig() Changes in V4: - Introduce fifo_bug flag in uart_8250_port structure This is enabled only when parity is enabled and UART_BUG_PARITY is enabled for up->bugs. If this flag is enabled, user cannot set RX trigger. - Return -EOPNOTSUPP when it does not support device at convert_fcr2val() and at convert_val2rxtrig() - Set the nearest lower RX trigger when users input a meaningless value at convert_val2rxtrig() - Check whether p->fcr is existing at serial8250_clear_and_reinit_fifos() - Set fcr = up->fcr in the begging of serial8250_do_set_termios() Changes in V3: - Change I/F from ioctl(2) to sysfs(rx_int_trig) Changed in V2: - Use _IOW for TIOCSFIFORTRIG definition - Pass the interrupt trigger value itself Signed-off-by: Yoshihiro YUNOMAE --- Documentation/ABI/testing/sysfs-tty | 16 +++ drivers/tty/serial/8250/8250.h |2 drivers/tty/serial/8250/8250_core.c | 173 --- include/linux/serial_8250.h |2 include/uapi/linux/serial_reg.h |5 + 5 files changed, 183 insertions(+), 15 deletions(-) diff --git a/Documentation/ABI/testing/sysfs-tty b/Documentation/ABI/testing/sysfs-tty index ad22fb0..9eb3c2b 100644 --- a/Documentation/ABI/testing/sysfs-tty +++ b/Documentation/ABI/testing/sysfs-tty @@ -138,3 +138,19 @@ Description: These sysfs values expose the TIOCGSERIAL interface via sysfs rather than via ioctls. + +What: /sys/class/tty/ttyS0/rx_trig_bytes +Date: May 2014 +Contact: Yoshihiro YUNOMAE +Description: +Shows current RX interrupt trigger bytes or sets the +user specified value to change it for the FIFO buffer. +Users can show or set this value regardless of opening the +serial device file or not. + +The RX trigger can be set one of four kinds of values for UART +serials. When users input a meaning less value to this I/F, +the RX trigger is changed to the nearest lower value for the +device specification. For example, when use
[RESEND PATCH V8 1/2] serial/uart: Introduce device specific attribute group to uart_port structure
Current serial device driver has the common sysfs I/F for all serial devices, but it does not have device specific sysfs I/F. To make device specific sysfs I/F, this patch introduces device specific attribute group to uart_port structure. Changes in V8: - Divide this patch from V7's patch based on Greg's comment Signed-off-by: Yoshihiro YUNOMAE --- drivers/tty/serial/serial_core.c | 18 +++--- include/linux/serial_core.h |4 2 files changed, 15 insertions(+), 7 deletions(-) diff --git a/drivers/tty/serial/serial_core.c b/drivers/tty/serial/serial_core.c index fbf6c5a..ed6ec1c 100644 --- a/drivers/tty/serial/serial_core.c +++ b/drivers/tty/serial/serial_core.c @@ -2559,15 +2559,16 @@ static struct attribute *tty_dev_attrs[] = { NULL, }; -static const struct attribute_group tty_dev_attr_group = { +static struct attribute_group tty_dev_attr_group = { .attrs = tty_dev_attrs, }; -static const struct attribute_group *tty_dev_attr_groups[] = { - &tty_dev_attr_group, - NULL - }; - +static void make_uport_attr_grps(struct uart_port *uport) +{ + uport->attr_grps[0] = &tty_dev_attr_group; + if (uport->dev_spec_attr_group) + uport->attr_grps[1] = uport->dev_spec_attr_group; +} /** * uart_add_one_port - attach a driver-defined port structure @@ -2618,12 +2619,15 @@ int uart_add_one_port(struct uart_driver *drv, struct uart_port *uport) uart_configure_port(drv, state, uport); + make_uport_attr_grps(uport); + /* * Register the port whether it's detected or not. This allows * setserial to be used to alter this port's parameters. */ tty_dev = tty_port_register_device_attr(port, drv->tty_driver, - uport->line, uport->dev, port, tty_dev_attr_groups); + uport->line, uport->dev, port, + (const struct attribute_group **)uport->attr_grps); if (likely(!IS_ERR(tty_dev))) { device_set_wakeup_capable(tty_dev, 1); } else { diff --git a/include/linux/serial_core.h b/include/linux/serial_core.h index 5bbb809..3b20c17 100644 --- a/include/linux/serial_core.h +++ b/include/linux/serial_core.h @@ -113,6 +113,8 @@ struct uart_icount { typedef unsigned int __bitwise__ upf_t; +#define MAX_ATTR_GRPS 3 + struct uart_port { spinlock_t lock; /* port lock */ unsigned long iobase; /* in/out[bwl] */ @@ -195,6 +197,8 @@ struct uart_port { unsigned intline; /* port index */ resource_size_t mapbase;/* for ioremap */ struct device *dev; /* parent device */ + struct attribute_group *dev_spec_attr_group; /* specific attribute */ + struct attribute_group *attr_grps[MAX_ATTR_GRPS];/* all attr. groups */ unsigned char hub6; /* this should be in the 8250 driver */ unsigned char suspended; unsigned char irq_wake; -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
Re: [tracing] 939c7a4f04f: -46.4% cpuidle.C3-IVT.time
Hi Jet, Thank you for your report. I have some questions for your test. 1. Did you enable ftrace? This patch added a feature for ftrace. If you disabled ftrace in this test, my patch will not affect the system. Moreover, in my patch, arrays for saved_cmdlines were just changed from using static global variables to using kmalloc() on default setting. So, even if you enabled ftrace, this patch will not induce a big problem, I think. 2. How did you test it and what does the result mean? Please tell me the workload, how to calculate the score, system settings, etc... Thanks, Yoshihiro YUNOMAE (2014/06/18 12:15), Jet Chen wrote: Hi Yoshihiro, FYI, we noticed the below changes on commit 939c7a4f04fcd2162109744e8bf88194948a6e65 ("tracing: Introduce saved_cmdlines_size file") test case: brickland3/aim7/3000-brk_test beba4bb096201ce 939c7a4f04fcd2162109744e8 --- - 352643 ~40% -46.4% 189136 ~15% TOTAL cpuidle.C3-IVT.time 750 ~ 2% -13.3%650 ~ 2% TOTAL vmstat.procs.b 362016 ~ 3% -6.0% 340296 ~ 3% TOTAL proc-vmstat.pgmigrate_success 362016 ~ 3% -6.0% 340296 ~ 3% TOTAL proc-vmstat.numa_pages_migrated 1642328 ~ 3% +13.3%1860721 ~ 2% TOTAL softirqs.RCU 2278829 ~ 2% -14.0%1959647 ~ 2% TOTAL time.voluntary_context_switches 207 ~ 0% -10.4%185 ~ 0% TOTAL time.user_time ~ 0% +8.5%~ 0% TOTAL turbostat.RAM_W 4418246 ~ 3% -6.4%4136447 ~ 1% TOTAL time.minor_page_faults ~ 0% +3.4%~ 0% TOTAL turbostat.Cor_W ~ 0% +3.0%~ 0% TOTAL turbostat.Pkg_W 11354889 ~ 0% +2.0% 11579897 ~ 0% TOTAL time.involuntary_context_switches Legend: ~XX%- stddev percent [+-]XX% - change percent time.voluntary_context_switches 2.4e+06 ++---*+ *.. *.... .. | 2.3e+06 ++ .*.. *.. .. * | | *..*.. .*.. .. * *.. + *.. *..* |*.* . .*..*.. + .. | 2.2e+06 ++ *..*. * * | | | 2.1e+06 ++| | | 2e+06 O+ O O O | | O O O O| |O O O O O | 1.9e+06 ++ O O O O| |O O O | 1.8e+06 +++ turbostat.Pkg_W +++ O+ O O O OO| | O O O O O O O O O O O O | ++ O O | ++| ++| ++| | | ++| ++| ++*.. .*.. | *+.*... .. *...*.*...*..*..*...*..*.. ..*.. *...*..*..*...*..* | * *. .. | ++* | +++ turbostat.Cor_W +++ O+ O O O O O OO O O | | O O O O O O O
Re: [PATCH ftrace/core] tracing: Remove return value in event_trace_self_tests() when top_trace_array() returns NULL
Hi Steven, Thank you for applying my patches. I received build warning report from kbuild test bot, so I fixed it. Would you apply this patch? Thank you, Yoshihiro YUNOMAE (2014/06/06 15:28), Yoshihiro YUNOMAE wrote: Remove return value in event_trace_self_tests() when top_trace_array() returns NULL because event_trace_self_tests() is void type. Signed-off-by: Yoshihiro YUNOMAE Cc: Steven Rostedt Cc: Ingo Molnar Cc: linux-kernel@vger.kernel.org --- kernel/trace/trace_events.c |2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/kernel/trace/trace_events.c b/kernel/trace/trace_events.c index 1349870..f99e0b3 100644 --- a/kernel/trace/trace_events.c +++ b/kernel/trace/trace_events.c @@ -2547,7 +2547,7 @@ static __init void event_trace_self_tests(void) tr = top_trace_array(); if (!tr) - return -ENODEV; + return; pr_info("Running tests on trace events:\n"); -- Yoshihiro YUNOMAE Software Platform Research Dept. Linux Technology Center Hitachi, Ltd., Yokohama Research Laboratory E-mail: yoshihiro.yunomae...@hitachi.com -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[PATCH ftrace/core] tracing: Remove return value in event_trace_self_tests() when top_trace_array() returns NULL
Remove return value in event_trace_self_tests() when top_trace_array() returns NULL because event_trace_self_tests() is void type. Signed-off-by: Yoshihiro YUNOMAE Cc: Steven Rostedt Cc: Ingo Molnar Cc: linux-kernel@vger.kernel.org --- kernel/trace/trace_events.c |2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/kernel/trace/trace_events.c b/kernel/trace/trace_events.c index 1349870..f99e0b3 100644 --- a/kernel/trace/trace_events.c +++ b/kernel/trace/trace_events.c @@ -2547,7 +2547,7 @@ static __init void event_trace_self_tests(void) tr = top_trace_array(); if (!tr) - return -ENODEV; + return; pr_info("Running tests on trace events:\n"); -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[PATCH ftrace/core 0/3] ftrace: Fix three small bugs
Hi Steven, I found three small bugs for current ftrace/core, so I fixed those. Would you apply these patches? Thanks! --- Yoshihiro YUNOMAE (3): trace/event: Return error if ftrace_trace_arrays is empty list trace/kprobes: Avoid self tests if tracing is disabled on boot up trace: Fix memory leak when new instance creation failed kernel/trace/trace.c| 23 ++- kernel/trace/trace.h|3 +++ kernel/trace/trace_events.c | 13 + kernel/trace/trace_kprobe.c |3 +++ 4 files changed, 33 insertions(+), 9 deletions(-) -- Yoshihiro YUNOMAE Software Platform Research Dept. Linux Technology Center Hitachi, Ltd., Yokohama Research Laboratory E-mail: yoshihiro.yunomae...@hitachi.com -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[PATCH ftrace/core 3/3] trace: Fix memory leak when new instance creation failed
Current new_instance_create() implements just two fail paths for four allocation operations. So, it can induce memory leak if new instance creation failed. This patch fixes it by defining all fail paths and freeing allocated memories appropriately. Signed-off-by: Yoshihiro YUNOMAE Cc: Steven Rostedt Cc: Ingo Molnar Cc: linux-kernel@vger.kernel.org --- kernel/trace/trace.c | 23 ++- 1 file changed, 14 insertions(+), 9 deletions(-) diff --git a/kernel/trace/trace.c b/kernel/trace/trace.c index 473eb68..bbd86d2 100644 --- a/kernel/trace/trace.c +++ b/kernel/trace/trace.c @@ -6277,7 +6277,7 @@ static int new_instance_create(const char *name) goto out_free_tr; if (!alloc_cpumask_var(&tr->tracing_cpumask, GFP_KERNEL)) - goto out_free_tr; + goto out_free_tr_name; cpumask_copy(tr->tracing_cpumask, cpu_all_mask); @@ -6291,16 +6291,16 @@ static int new_instance_create(const char *name) INIT_LIST_HEAD(&tr->events); if (allocate_trace_buffers(tr, trace_buf_size) < 0) - goto out_free_tr; + goto out_free_cpumask_var; tr->dir = debugfs_create_dir(name, trace_instance_dir); if (!tr->dir) - goto out_free_tr; + goto out_free_trace_buffers; ret = event_trace_add_tracer(tr->dir, tr); if (ret) { debugfs_remove_recursive(tr->dir); - goto out_free_tr; + goto out_free_trace_buffers; } init_tracer_debugfs(tr, tr->dir); @@ -6311,18 +6311,23 @@ static int new_instance_create(const char *name) return 0; - out_free_tr: - if (tr->trace_buffer.buffer) - ring_buffer_free(tr->trace_buffer.buffer); + out_free_trace_buffers: + ring_buffer_free(tr->trace_buffer.buffer); + free_percpu(tr->trace_buffer.data); +#ifdef CONFIG_TRACER_MAX_TRACE + ring_buffer_free(tr->max_buffer.buffer); + free_percpu(tr->max_buffer.data); +#endif + out_free_cpumask_var: free_cpumask_var(tr->tracing_cpumask); + out_free_tr_name: kfree(tr->name); + out_free_tr: kfree(tr); - out_unlock: mutex_unlock(&trace_types_lock); return ret; - } static int instance_delete(const char *name) -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[PATCH ftrace/core 1/3] trace/event: Return error if ftrace_trace_arrays is empty list
ftrace_trace_arrays links global_trace.list. However, global_trace is not added to ftrace_trace_arrays if trace_alloc_buffers() failed. As the result, ftrace_trace_arrays becomes empty list. If ftrace_trace_arrays is empty list, current top_trace_array() returns invalid pointer. As the result, the kernel can induce memory corruption or panic. Current implementation does not check whether ftrace_trace_arrays is empty list or not. So, in this patch, if ftrace_trace_arrays is empty list, top_trace_array() returns NULL. Moreover, this patch makes all functions calling top_trace_array() handle it appropriately. Signed-off-by: Yoshihiro YUNOMAE Cc: Steven Rostedt Cc: Ingo Molnar Cc: linux-kernel@vger.kernel.org --- kernel/trace/trace.h|3 +++ kernel/trace/trace_events.c | 13 + 2 files changed, 16 insertions(+) diff --git a/kernel/trace/trace.h b/kernel/trace/trace.h index 217207a..9e82551 100644 --- a/kernel/trace/trace.h +++ b/kernel/trace/trace.h @@ -252,6 +252,9 @@ static inline struct trace_array *top_trace_array(void) { struct trace_array *tr; + if (list_empty(ftrace_trace_arrays.prev)) + return NULL; + tr = list_entry(ftrace_trace_arrays.prev, typeof(*tr), list); WARN_ON(!(tr->flags & TRACE_ARRAY_FL_GLOBAL)); diff --git a/kernel/trace/trace_events.c b/kernel/trace/trace_events.c index 3ddfd8f..1349870 100644 --- a/kernel/trace/trace_events.c +++ b/kernel/trace/trace_events.c @@ -574,6 +574,9 @@ int trace_set_clr_event(const char *system, const char *event, int set) { struct trace_array *tr = top_trace_array(); + if (!tr) + return -ENODEV; + return __ftrace_set_clr_event(tr, NULL, system, event, set); } EXPORT_SYMBOL_GPL(trace_set_clr_event); @@ -2065,6 +2068,9 @@ event_enable_func(struct ftrace_hash *hash, bool enable; int ret; + if (!tr) + return -ENODEV; + /* hash funcs only work with set_ftrace_filter */ if (!enabled || !param) return -EINVAL; @@ -2396,6 +2402,9 @@ static __init int event_trace_enable(void) char *token; int ret; + if (!tr) + return -ENODEV; + for_each_event(iter, __start_ftrace_events, __stop_ftrace_events) { call = *iter; @@ -2442,6 +2451,8 @@ static __init int event_trace_init(void) int ret; tr = top_trace_array(); + if (!tr) + return -ENODEV; d_tracer = tracing_init_dentry(); if (!d_tracer) @@ -2535,6 +2546,8 @@ static __init void event_trace_self_tests(void) int ret; tr = top_trace_array(); + if (!tr) + return -ENODEV; pr_info("Running tests on trace events:\n"); -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[PATCH ftrace/core 2/3] trace/kprobes: Avoid self tests if tracing is disabled on boot up
If tracing is disabled on boot up, the kernel should not execute self tests. In this patch, the kernel checks whether tracing is disabled or not before executing self tests. Signed-off-by: Yoshihiro YUNOMAE Cc: Steven Rostedt Cc: Ingo Molnar Cc: Masami Hiramatsu Cc: linux-kernel@vger.kernel.org --- kernel/trace/trace_kprobe.c |3 +++ 1 file changed, 3 insertions(+) diff --git a/kernel/trace/trace_kprobe.c b/kernel/trace/trace_kprobe.c index 903ae28..ef2fba1 100644 --- a/kernel/trace/trace_kprobe.c +++ b/kernel/trace/trace_kprobe.c @@ -1377,6 +1377,9 @@ static __init int kprobe_trace_self_tests_init(void) struct trace_kprobe *tk; struct ftrace_event_file *file; + if (tracing_is_disabled()) + return -ENODEV; + target = kprobe_trace_selftest_target; pr_info("Testing kprobe tracing: "); -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[PATCH ftrace/core V5] ftrace: Introduce saved_cmdlines_size file
Introduce saved_cmdlines_size file for changing the number of pid-comm list. saved_cmdlines can store 128 command names using SAVED_CMDLINES now, but 'no-existing processes' names are often lost in saved_cmdlines when we read trace data. So, by introducing saved_cmdlines_size file, the rule storing 128 command names is changed to the command numbers defined users. When we write a value to saved_cmdlines_size, the number of the value will be stored in pid-comm list: # echo 1024 > /sys/kernel/debug/tracing/saved_cmdlines_size Here, 1024 command names are stored. The default number is 128 and the maximum number is PID_MAX_DEFAULT (=32768 if CONFIG_BASE_SMALL is not set). So, if we want to avoid to lose command names, we need to set 32768 to saved_cmdlines_size. We can read the maximum number of the list: # cat /sys/kernel/debug/tracing/saved_cmdlines_size 128 Changes in V5: - Change sizeof(unsigned) to sizeof(*s->map_cmdline_to_pid) in allocate_cmdlines_buffer() Changes in V4: - Remove trace_init_cmdlines_buffer() - Remove extra gotos in allocate_cmdlines_buffer(), trace_create_savedcmd(), and tracing_resize_saved_cmdlines. - Use seq_release instead of tracing_saved_cmdlines_close - Move trace_create_savedcmd() before allocate_trace_buffers because freeing of saved_cmdlines is easier than that of global_trace buffers. Changes in V3: - Change 'nr_saved_cmdlines' to 'saved_cmdlines_size' - Delete two helper functions(trace_init_savedcmd() and trace_create_and_init_saved_cmd()) - Rebase this patch for current ftrace/core tree - Remove reader member in saved_cmdlines_buffer structure because the racing problem does not occur even if we don't use the member in this patch - Fix several typos Changes in V2: - Fix a racing problem of savedcmd between saved_cmdlines I/F and nr_saved_cmdlines I/F. If one reads saved_cmdlines and writes a value to nr_saved_cmdlines at the same time, then the write returns -EBUSY. [terminal 1] Read saved_cmdlines # while true; do cat saved_cmdlines > /dev/null; done; [terminal 2] Write 1024 to nr_saved_cmdlines # while true; do echo 1024 > nr_saved_cmdlines; done; -bash: echo: write error: Device or resource busy -bash: echo: write error: Device or resource busy -bash: echo: write error: Device or resource busy Signed-off-by: Yoshihiro YUNOMAE Cc: Steven Rostedt Cc: Frederic Weisbecker Cc: Ingo Molnar Cc: linux-kernel@vger.kernel.org --- kernel/trace/trace.c | 178 +++--- 1 file changed, 154 insertions(+), 24 deletions(-) diff --git a/kernel/trace/trace.c b/kernel/trace/trace.c index 135af32..e29edee 100644 --- a/kernel/trace/trace.c +++ b/kernel/trace/trace.c @@ -1285,22 +1285,71 @@ void tracing_reset_all_online_cpus(void) } } -#define SAVED_CMDLINES 128 +#define SAVED_CMDLINES_DEFAULT 128 #define NO_CMDLINE_MAP UINT_MAX -static unsigned map_pid_to_cmdline[PID_MAX_DEFAULT+1]; -static unsigned map_cmdline_to_pid[SAVED_CMDLINES]; -static char saved_cmdlines[SAVED_CMDLINES][TASK_COMM_LEN]; -static int cmdline_idx; static arch_spinlock_t trace_cmdline_lock = __ARCH_SPIN_LOCK_UNLOCKED; +struct saved_cmdlines_buffer { + unsigned map_pid_to_cmdline[PID_MAX_DEFAULT+1]; + unsigned *map_cmdline_to_pid; + unsigned cmdline_num; + int cmdline_idx; + char *saved_cmdlines; +}; +static struct saved_cmdlines_buffer *savedcmd; /* temporary disable recording */ static atomic_t trace_record_cmdline_disabled __read_mostly; -static void trace_init_cmdlines(void) +static inline char *get_saved_cmdlines(int idx) +{ + return &savedcmd->saved_cmdlines[idx * TASK_COMM_LEN]; +} + +static inline void set_cmdline(int idx, const char *cmdline) { - memset(&map_pid_to_cmdline, NO_CMDLINE_MAP, sizeof(map_pid_to_cmdline)); - memset(&map_cmdline_to_pid, NO_CMDLINE_MAP, sizeof(map_cmdline_to_pid)); - cmdline_idx = 0; + memcpy(get_saved_cmdlines(idx), cmdline, TASK_COMM_LEN); +} + +static int allocate_cmdlines_buffer(unsigned int val, + struct saved_cmdlines_buffer *s) +{ + s->map_cmdline_to_pid = kmalloc(val * sizeof(*s->map_cmdline_to_pid), + GFP_KERNEL); + if (!s->map_cmdline_to_pid) + return -ENOMEM; + + s->saved_cmdlines = kmalloc(val * TASK_COMM_LEN, GFP_KERNEL); + if (!s->saved_cmdlines) { + kfree(s->map_cmdline_to_pid); + return -ENOMEM; + } + + s->cmdline_idx = 0; + s->cmdline_num = val; + memset(&s->map_pid_to_cmdline, NO_CMDLINE_MAP, + sizeof(s->map_pid_to_cmdline)); + memset(s->map_cmdline_to_pid, NO_CMDLINE_MAP, + val * sizeof(*s->map_cmdline_to_pid)); + + return 0; +} + +static int trace_create_savedcmd(void) +{ +
[V4 PATCH ftrace/core] ftrace: Introduce saved_cmdlines_size file
Introduce saved_cmdlines_size file for changing the number of pid-comm list. saved_cmdlines can store 128 command names using SAVED_CMDLINES now, but 'no-existing processes' names are often lost in saved_cmdlines when we read trace data. So, by introducing saved_cmdlines_size file, the rule storing 128 command names is changed to the command numbers defined users. When we write a value to saved_cmdlines_size, the number of the value will be stored in pid-comm list: # echo 1024 > /sys/kernel/debug/tracing/saved_cmdlines_size Here, 1024 command names are stored. The default number is 128 and the maximum number is PID_MAX_DEFAULT (=32768 if CONFIG_BASE_SMALL is not set). So, if we want to avoid to lose command names, we need to set 32768 to saved_cmdlines_size. We can read the maximum number of the list: # cat /sys/kernel/debug/tracing/saved_cmdlines_size 128 Changes in V2: - Fix a racing problem of savedcmd between saved_cmdlines I/F and nr_saved_cmdlines I/F. If one reads saved_cmdlines and writes a value to nr_saved_cmdlines at the same time, then the write returns -EBUSY. [terminal 1] Read saved_cmdlines # while true; do cat saved_cmdlines > /dev/null; done; [terminal 2] Write 1024 to nr_saved_cmdlines # while true; do echo 1024 > nr_saved_cmdlines; done; -bash: echo: write error: Device or resource busy -bash: echo: write error: Device or resource busy -bash: echo: write error: Device or resource busy Changes in V3: - Change 'nr_saved_cmdlines' to 'saved_cmdlines_size' - Delete two helper functions(trace_init_savedcmd() and trace_create_and_init_saved_cmd()) - Rebase this patch for current ftrace/core tree - Remove reader member in saved_cmdlines_buffer structure because the racing problem does not occur even if we don't use the member in this patch - Fix several typos Changes in V4: - Remove trace_init_cmdlines_buffer() - Remove extra gotos in allocate_cmdlines_buffer(), trace_create_savedcmd(), and tracing_resize_saved_cmdlines. - Use seq_release instead of tracing_saved_cmdlines_close - Move trace_create_savedcmd() before allocate_trace_buffers because freeing of saved_cmdlines is easier than that of global_trace buffers. Signed-off-by: Yoshihiro YUNOMAE Cc: Steven Rostedt Cc: Frederic Weisbecker Cc: Ingo Molnar Cc: linux-kernel@vger.kernel.org --- kernel/trace/trace.c | 177 +++--- 1 file changed, 153 insertions(+), 24 deletions(-) diff --git a/kernel/trace/trace.c b/kernel/trace/trace.c index 135af32..ed9185c 100644 --- a/kernel/trace/trace.c +++ b/kernel/trace/trace.c @@ -1285,22 +1285,70 @@ void tracing_reset_all_online_cpus(void) } } -#define SAVED_CMDLINES 128 +#define SAVED_CMDLINES_DEFAULT 128 #define NO_CMDLINE_MAP UINT_MAX -static unsigned map_pid_to_cmdline[PID_MAX_DEFAULT+1]; -static unsigned map_cmdline_to_pid[SAVED_CMDLINES]; -static char saved_cmdlines[SAVED_CMDLINES][TASK_COMM_LEN]; -static int cmdline_idx; static arch_spinlock_t trace_cmdline_lock = __ARCH_SPIN_LOCK_UNLOCKED; +struct saved_cmdlines_buffer { + unsigned map_pid_to_cmdline[PID_MAX_DEFAULT+1]; + unsigned *map_cmdline_to_pid; + unsigned cmdline_num; + int cmdline_idx; + char *saved_cmdlines; +}; +static struct saved_cmdlines_buffer *savedcmd; /* temporary disable recording */ static atomic_t trace_record_cmdline_disabled __read_mostly; -static void trace_init_cmdlines(void) +static inline char *get_saved_cmdlines(int idx) +{ + return &savedcmd->saved_cmdlines[idx * TASK_COMM_LEN]; +} + +static inline void set_cmdline(int idx, const char *cmdline) { - memset(&map_pid_to_cmdline, NO_CMDLINE_MAP, sizeof(map_pid_to_cmdline)); - memset(&map_cmdline_to_pid, NO_CMDLINE_MAP, sizeof(map_cmdline_to_pid)); - cmdline_idx = 0; + memcpy(get_saved_cmdlines(idx), cmdline, TASK_COMM_LEN); +} + +static int allocate_cmdlines_buffer(unsigned int val, + struct saved_cmdlines_buffer *s) +{ + s->map_cmdline_to_pid = kmalloc(val * sizeof(unsigned), GFP_KERNEL); + if (!s->map_cmdline_to_pid) + return -ENOMEM; + + s->saved_cmdlines = kmalloc(val * TASK_COMM_LEN, GFP_KERNEL); + if (!s->saved_cmdlines) { + kfree(s->map_cmdline_to_pid); + return -ENOMEM; + } + + s->cmdline_idx = 0; + s->cmdline_num = val; + memset(&s->map_pid_to_cmdline, NO_CMDLINE_MAP, + sizeof(s->map_pid_to_cmdline)); + memset(s->map_cmdline_to_pid, NO_CMDLINE_MAP, + val * sizeof(*s->map_cmdline_to_pid)); + + return 0; +} + +static int trace_create_savedcmd(void) +{ + int ret; + + savedcmd = kmalloc(sizeof(struct saved_cmdlines_buffer), GFP_KERNEL); + if (!savedcmd) + return -ENOMEM;
Re: Re: [PATCH ftrace/core 2/2] ftrace: Introduce saved_cmdlines_size file
Hi Steven, Thank you for your review. (2014/06/04 9:30), Steven Rostedt wrote: On Tue, 03 Jun 2014 13:28:05 +0900 Yoshihiro YUNOMAE wrote: --- kernel/trace/trace.c | 203 -- 1 file changed, 180 insertions(+), 23 deletions(-) diff --git a/kernel/trace/trace.c b/kernel/trace/trace.c index 135af32..473eb68 100644 --- a/kernel/trace/trace.c +++ b/kernel/trace/trace.c @@ -1285,22 +1285,82 @@ void tracing_reset_all_online_cpus(void) } } -#define SAVED_CMDLINES 128 +#define SAVED_CMDLINES_DEFAULT 128 #define NO_CMDLINE_MAP UINT_MAX -static unsigned map_pid_to_cmdline[PID_MAX_DEFAULT+1]; -static unsigned map_cmdline_to_pid[SAVED_CMDLINES]; -static char saved_cmdlines[SAVED_CMDLINES][TASK_COMM_LEN]; -static int cmdline_idx; static arch_spinlock_t trace_cmdline_lock = __ARCH_SPIN_LOCK_UNLOCKED; +struct saved_cmdlines_buffer { + unsigned map_pid_to_cmdline[PID_MAX_DEFAULT+1]; + unsigned *map_cmdline_to_pid; + unsigned cmdline_num; + int cmdline_idx; + char *saved_cmdlines; +}; +static struct saved_cmdlines_buffer *savedcmd; /* temporary disable recording */ static atomic_t trace_record_cmdline_disabled __read_mostly; -static void trace_init_cmdlines(void) +static inline char *get_saved_cmdlines(int idx) +{ + return &savedcmd->saved_cmdlines[idx * TASK_COMM_LEN]; +} + +static inline void set_cmdline(int idx, const char *cmdline) +{ + memcpy(get_saved_cmdlines(idx), cmdline, TASK_COMM_LEN); +} + +static int allocate_cmdlines_buffer(unsigned int val, + struct saved_cmdlines_buffer *s) { - memset(&map_pid_to_cmdline, NO_CMDLINE_MAP, sizeof(map_pid_to_cmdline)); - memset(&map_cmdline_to_pid, NO_CMDLINE_MAP, sizeof(map_cmdline_to_pid)); - cmdline_idx = 0; + s->map_cmdline_to_pid = kmalloc(val * sizeof(unsigned), GFP_KERNEL); + if (!s->map_cmdline_to_pid) + goto out; + + s->saved_cmdlines = kmalloc(val * TASK_COMM_LEN, GFP_KERNEL); + if (!s->saved_cmdlines) + goto out_free_map_cmdline_to_pid; + + return 0; + +out_free_map_cmdline_to_pid: + kfree(s->map_cmdline_to_pid); +out: + return -ENOMEM; +} + +static void trace_init_cmdlines_buffer(unsigned int val, + struct saved_cmdlines_buffer *s) +{ + s->cmdline_idx = 0; + s->cmdline_num = val; + memset(&s->map_pid_to_cmdline, NO_CMDLINE_MAP, + sizeof(s->map_pid_to_cmdline)); + memset(s->map_cmdline_to_pid, NO_CMDLINE_MAP, + val * sizeof(*s->map_cmdline_to_pid)); +} Please combine the above two functions. Get rid of trace_init_cmdlines_buffer(). That is, move the contents of trace_init_cmdlines_buffer() into allocate_cmdline_buffer() just before the return 0. There's no reason that we need to have two functions, one to allocate and one to initialize it. The allocation can also initialize it. OK, I'll move the initialization into allocate_cmdline_buffer(). + +static int trace_create_savedcmd(void) +{ + int ret; + + savedcmd = kmalloc(sizeof(struct saved_cmdlines_buffer), GFP_KERNEL); + if (!savedcmd) + goto out; if (!savedcmd) return -ENOMEM; + + ret = allocate_cmdlines_buffer(SAVED_CMDLINES_DEFAULT, savedcmd); + if (ret < 0) + goto out_free; if (ret < 0) { kfree(savedcmd); savedcmd = NULL; return -ENOMEM; } This function is small enough that we don't need to use gotos to make it clean. OK. I'll remove gotos. + + trace_init_cmdlines_buffer(SAVED_CMDLINES_DEFAULT, savedcmd); + + return 0; + +out_free: + kfree(savedcmd); + savedcmd = NULL; +out: + return -ENOMEM; } int is_tracing_stopped(void) @@ -1457,9 +1517,9 @@ static int trace_save_cmdline(struct task_struct *tsk) if (!arch_spin_trylock(&trace_cmdline_lock)) return 0; - idx = map_pid_to_cmdline[tsk->pid]; + idx = savedcmd->map_pid_to_cmdline[tsk->pid]; if (idx == NO_CMDLINE_MAP) { - idx = (cmdline_idx + 1) % SAVED_CMDLINES; + idx = (savedcmd->cmdline_idx + 1) % savedcmd->cmdline_num; /* * Check whether the cmdline buffer at idx has a pid @@ -1467,17 +1527,17 @@ static int trace_save_cmdline(struct task_struct *tsk) * need to clear the map_pid_to_cmdline. Otherwise we * would read the new comm for the old pid. */ - pid = map_cmdline_to_pid[idx]; + pid = savedcmd->map_cmdline_to_pid[idx]; if (pid != NO_CMDLINE_MAP) - map_pid_to_cmdline[pid] = NO_CMDLINE_MAP; + sav
[PATCH ftrace/core 0/2] ftrace: Introduce the new file "saved_cmdlines_size"
Hi Steven, This patch set introduces the new file "saved_cmdlines_size" for increasing the number of saved cmdlines. Current saved_cmdlines can store just 128 command names and PIDs, but process names are often lost like <...> when we read trace data. If the process exists, we can get the name by using ps command. However, if the process already has not existed, we cannot get the name. To solve this issue, we introduce the new file "saved_cmdlines_size" to expand the max number of saved command line names. This file is very simple. If we write a number to nr_saved_cmdlines, the number of command name will be stored. And, if we read the file, we can get current maximum number of command name. The default number is 128 which is current default number, so this patch does not change the usage of memory for saved_cmdlines when we boot kernel. I found a bug for current ftrace, so I fixed the bug before introducing saved_cmdlines_size file (2nd patch). Note that the 2nd patch depends on the 1st patch. Thanks! Changes in V2: [2/2] - Fix a racing problem of savedcmd between saved_cmdlines I/F and nr_saved_cmdlines I/F. If one reads saved_cmdlines and writes a value to nr_saved_cmdlines at the same time, then the write returns -EBUSY. [terminal 1] Read saved_cmdlines # while true; do cat saved_cmdlines > /dev/null; done; [terminal 2] Write 1024 to nr_saved_cmdlines # while true; do echo 1024 > nr_saved_cmdlines; done; -bash: echo: write error: Device or resource busy -bash: echo: write error: Device or resource busy -bash: echo: write error: Device or resource busy Changes in V3: [1/2] - Introduce this patch [2/2] - Change 'nr_saved_cmdlines' to 'saved_cmdlines_size' - Delete two helper functions(trace_init_savedcmd() and trace_creare_and_init_saved_cmd()) - Rebase this patch for current ftrace/core tree - Remove reader member in saved_cmdlines_buffer structure because the racing problem does not occur even if we don't the member in this patch - Fix several typos --- Yoshihiro YUNOMAE (2): [BUGFIX] ftrace: Avoid panic when allocation of max_buffer is failed ftrace: Introduce saved_cmdlines_size file kernel/trace/trace.c | 205 -- 1 file changed, 179 insertions(+), 26 deletions(-) -- Yoshihiro YUNOMAE Software Platform Research Dept. Linux Technology Center Hitachi, Ltd., Yokohama Research Laboratory E-mail: yoshihiro.yunomae...@hitachi.com -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[PATCH ftrace/core 1/2] [BUGFIX] ftrace: Avoid panic when allocation of max_buffer is failed
When allocation of max_buffer is failed, the kernel frees tr->trace_buffer.data per CPU and return -ENOMEM in allocate_trace_buffers(). However, tracer_alloc_buffers() calling allocate_trace_buffers() also frees the data per CPU for -ENOMEM by allocate_trace_buffers(). Therefore, the allocation failure induces double free. For the out_free_mask path in tracer_alloc_buffers(), global_trace.trace_buffer.data and global_trace.max_buffer.data are not allocated yet, so free_percpu of those are not needed. Signed-off-by: Yoshihiro YUNOMAE Cc: Steven Rostedt Cc: Frederic Weisbecker Cc: Ingo Molnar Cc: linux-kernel@vger.kernel.org --- kernel/trace/trace.c |4 1 file changed, 4 deletions(-) diff --git a/kernel/trace/trace.c b/kernel/trace/trace.c index 626dbfd..135af32 100644 --- a/kernel/trace/trace.c +++ b/kernel/trace/trace.c @@ -6671,10 +6671,6 @@ __init static int tracer_alloc_buffers(void) out_free_temp_buffer: ring_buffer_free(temp_buffer); out_free_cpumask: - free_percpu(global_trace.trace_buffer.data); -#ifdef CONFIG_TRACER_MAX_TRACE - free_percpu(global_trace.max_buffer.data); -#endif free_cpumask_var(global_trace.tracing_cpumask); out_free_buffer_mask: free_cpumask_var(tracing_buffer_mask); -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[PATCH ftrace/core 2/2] ftrace: Introduce saved_cmdlines_size file
Introduce saved_cmdlines_size file for changing the number of pid-comm list. saved_cmdlines can store 128 command names using SAVED_CMDLINES now, but 'no-existing processes' names are often lost in saved_cmdlines when we read trace data. So, by introducing saved_cmdlines_size file, the rule storing 128 command names is changed to the command numbers defined users. When we write a value to saved_cmdlines_size, the number of the value will be stored in pid-comm list: # echo 1024 > /sys/kernel/debug/tracing/saved_cmdlines_size Here, 1024 command names are stored. The default number is 128 and the maximum number is PID_MAX_DEFAULT (=32768 if CONFIG_BASE_SMALL is not set). So, if we want to avoid to lose command names, we need to set 32768 to saved_cmdlines_size. We can read the maximum number of the list: # cat /sys/kernel/debug/tracing/saved_cmdlines_size 128 Changes in V2: - Fix a racing problem of savedcmd between saved_cmdlines I/F and nr_saved_cmdlines I/F. If one reads saved_cmdlines and writes a value to nr_saved_cmdlines at the same time, then the write returns -EBUSY. [terminal 1] Read saved_cmdlines # while true; do cat saved_cmdlines > /dev/null; done; [terminal 2] Write 1024 to nr_saved_cmdlines # while true; do echo 1024 > nr_saved_cmdlines; done; -bash: echo: write error: Device or resource busy -bash: echo: write error: Device or resource busy -bash: echo: write error: Device or resource busy Changes in V3: - Change 'nr_saved_cmdlines' to 'saved_cmdlines_size' - Delete two helper functions(trace_init_savedcmd() and trace_create_and_init_saved_cmd()) - Rebase this patch for current ftrace/core tree - Remove reader member in saved_cmdlines_buffer structure because the racing problem does not occur even if we don't use the member in this patch - Fix several typos Signed-off-by: Yoshihiro YUNOMAE Cc: Steven Rostedt Cc: Frederic Weisbecker Cc: Ingo Molnar Cc: linux-kernel@vger.kernel.org --- kernel/trace/trace.c | 203 -- 1 file changed, 180 insertions(+), 23 deletions(-) diff --git a/kernel/trace/trace.c b/kernel/trace/trace.c index 135af32..473eb68 100644 --- a/kernel/trace/trace.c +++ b/kernel/trace/trace.c @@ -1285,22 +1285,82 @@ void tracing_reset_all_online_cpus(void) } } -#define SAVED_CMDLINES 128 +#define SAVED_CMDLINES_DEFAULT 128 #define NO_CMDLINE_MAP UINT_MAX -static unsigned map_pid_to_cmdline[PID_MAX_DEFAULT+1]; -static unsigned map_cmdline_to_pid[SAVED_CMDLINES]; -static char saved_cmdlines[SAVED_CMDLINES][TASK_COMM_LEN]; -static int cmdline_idx; static arch_spinlock_t trace_cmdline_lock = __ARCH_SPIN_LOCK_UNLOCKED; +struct saved_cmdlines_buffer { + unsigned map_pid_to_cmdline[PID_MAX_DEFAULT+1]; + unsigned *map_cmdline_to_pid; + unsigned cmdline_num; + int cmdline_idx; + char *saved_cmdlines; +}; +static struct saved_cmdlines_buffer *savedcmd; /* temporary disable recording */ static atomic_t trace_record_cmdline_disabled __read_mostly; -static void trace_init_cmdlines(void) +static inline char *get_saved_cmdlines(int idx) +{ + return &savedcmd->saved_cmdlines[idx * TASK_COMM_LEN]; +} + +static inline void set_cmdline(int idx, const char *cmdline) +{ + memcpy(get_saved_cmdlines(idx), cmdline, TASK_COMM_LEN); +} + +static int allocate_cmdlines_buffer(unsigned int val, + struct saved_cmdlines_buffer *s) { - memset(&map_pid_to_cmdline, NO_CMDLINE_MAP, sizeof(map_pid_to_cmdline)); - memset(&map_cmdline_to_pid, NO_CMDLINE_MAP, sizeof(map_cmdline_to_pid)); - cmdline_idx = 0; + s->map_cmdline_to_pid = kmalloc(val * sizeof(unsigned), GFP_KERNEL); + if (!s->map_cmdline_to_pid) + goto out; + + s->saved_cmdlines = kmalloc(val * TASK_COMM_LEN, GFP_KERNEL); + if (!s->saved_cmdlines) + goto out_free_map_cmdline_to_pid; + + return 0; + +out_free_map_cmdline_to_pid: + kfree(s->map_cmdline_to_pid); +out: + return -ENOMEM; +} + +static void trace_init_cmdlines_buffer(unsigned int val, + struct saved_cmdlines_buffer *s) +{ + s->cmdline_idx = 0; + s->cmdline_num = val; + memset(&s->map_pid_to_cmdline, NO_CMDLINE_MAP, + sizeof(s->map_pid_to_cmdline)); + memset(s->map_cmdline_to_pid, NO_CMDLINE_MAP, + val * sizeof(*s->map_cmdline_to_pid)); +} + +static int trace_create_savedcmd(void) +{ + int ret; + + savedcmd = kmalloc(sizeof(struct saved_cmdlines_buffer), GFP_KERNEL); + if (!savedcmd) + goto out; + + ret = allocate_cmdlines_buffer(SAVED_CMDLINES_DEFAULT, savedcmd); + if (ret < 0) + goto out_free; + + trace_init_cmdlines_buffer(SAVED_CMDLINES_DEFAULT,
Re: Re: [PATCH V2 2/2] ftrace: Introduce nr_saved_cmdlines I/F
Hi Steven, Thank you for your review and fixing my patch. (2014/05/31 2:08), Steven Rostedt wrote: On Fri, 30 May 2014 10:02:23 -0400 Steven Rostedt wrote: This last part conflicts with my current 3.16 queue. You can see how it does in my for-next repo. But I'll be pushing my latest with the updates I mentioned above soon and will let you know where to get them. I just pushed my updates to my repo, which includes your first patch plus a fix. This may still rebase, I only solidify my "for-next" branch. But if you rewrite your patch against this branch with my updates, then I can take it and test it for 3.16. Still have one week left, but the earlier the better. OK, I understood. I'll fix my 2nd patch based on your review, and I'll resend the patch as soon as possible. Thank you, Yoshihiro YUNOMAE -- Yoshihiro YUNOMAE Software Platform Research Dept. Linux Technology Center Hitachi, Ltd., Yokohama Research Laboratory E-mail: yoshihiro.yunomae...@hitachi.com -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[PATCH V8 0/2] serial/uart/8250: Introduce tunable RX trigger I/F
Hi Greg, This patch set introduces tunable RX interrupt trigger I/F for 8250 serials. I just split V7's patch up into 2 patches, and all functions are not changed from previous version. V6 patch was reviewed by Stephen Warren and acked, but I removed the 'Reviewed-by' for this patch set just in case. Thanks! Changed in V2: - Use _IOW for TIOCSFIFORTRIG definition - Pass the interrupt trigger value itself Changes in V3: - Change I/F from ioctl(2) to sysfs(rx_int_trig) Changes in V4: - Introduce fifo_bug flag in uart_8250_port structure This is enabled only when parity is enabled and UART_BUG_PARITY is enabled for up->bugs. If this flag is enabled, user cannot set RX trigger. - Return -EOPNOTSUPP when it does not support device at convert_fcr2val() and at convert_val2rxtrig() - Set the nearest lower RX trigger when users input a meaningless value at convert_val2rxtrig() - Check whether p->fcr is existing at serial8250_clear_and_reinit_fifos() - Set fcr = up->fcr in the begging of serial8250_do_set_termios() Changes in V5: - Support Tegra, 16650V2, 16654, and 16750 - Store default FCR value to up->fcr when the port is first created - Add rx_trig_byte[] in uart_config[] for each device and use rx_trig_byte[] in convert_fcr2val() and convert_val2rxtrig() Changes in V5.1: - Fix FCR_RX_TRIG_MAX_STATE definition Changes in V6: - Move FCR_RX_TRIG_* definition in 8250.h to include/uapi/linux/serial_reg.h, rename those to UART_FCR_R_TRIG_*, and use UART_FCR_TRIGGER_MASK to UART_FCR_R_TRIG_BITS() - Change following function names: convert_fcr2val() => fcr_get_rxtrig_bytes() convert_val2rxtrig() => bytes_to_fcr_rxtrig() - Fix typo in serial8250_do_set_termios() - Delete the verbose error message pr_info() in bytes_to_fcr_rxtrig() - Rename *rx_int_trig/rx_trig* to *rxtrig* for several functions or variables (but UI remains rx_int_trig) - Change the meaningless variable name 'val' to 'bytes' following functions: fcr_get_rxtrig_bytes(), bytes_to_fcr_rxtrig(), do_set_rxtrig(), do_serial8250_set_rxtrig(), and serial8250_set_attr_rxtrig() - Use up->fcr in order to get rxtrig_bytes instead of rx_trig_raw in fcr_get_rxtrig_bytes() - Use conf_type->rxtrig_bytes[0] instead of switch statement for support check in register_dev_spec_attr_grp() - Delete the checking whether a user changed FCR or not when minimum buffer is needed in serial8250_do_set_termios() Changes in V7: - Add Documentation - Change I/F name from rx_int_trig to rx_trig_bytes because the name rx_int_trig is hard to understand how users specify the value Changes in V8: - Split V7's patch up into 2 patches --- Yoshihiro YUNOMAE (2): serial/uart: Introduce device specific attribute group to uart_port structure serial/uart/8250: Add tunable RX interrupt trigger I/F of FIFO buffers Documentation/ABI/testing/sysfs-tty | 16 +++ drivers/tty/serial/8250/8250.h |2 drivers/tty/serial/8250/8250_core.c | 173 --- drivers/tty/serial/serial_core.c| 18 ++-- include/linux/serial_8250.h |2 include/linux/serial_core.h |4 + include/uapi/linux/serial_reg.h | 5 + 7 files changed, 198 insertions(+), 22 deletions(-) -- Yoshihiro YUNOMAE Software Platform Research Dept. Linux Technology Center Hitachi, Ltd., Yokohama Research Laboratory E-mail: yoshihiro.yunomae...@hitachi.com -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[PATCH V8 1/2] serial/uart: Introduce device specific attribute group to uart_port structure
Current serial device driver has the common sysfs I/F for all serial devices, but it does not have device specific sysfs I/F. To make device specific sysfs I/F, this patch introduces device specific attribute group to uart_port structure. Changes in V8: - Divide this patch from V7's patch based on Greg's comment Signed-off-by: Yoshihiro YUNOMAE --- drivers/tty/serial/serial_core.c | 18 +++--- include/linux/serial_core.h |4 2 files changed, 15 insertions(+), 7 deletions(-) diff --git a/drivers/tty/serial/serial_core.c b/drivers/tty/serial/serial_core.c index b68550d..524cb49 100644 --- a/drivers/tty/serial/serial_core.c +++ b/drivers/tty/serial/serial_core.c @@ -2552,15 +2552,16 @@ static struct attribute *tty_dev_attrs[] = { NULL, }; -static const struct attribute_group tty_dev_attr_group = { +static struct attribute_group tty_dev_attr_group = { .attrs = tty_dev_attrs, }; -static const struct attribute_group *tty_dev_attr_groups[] = { - &tty_dev_attr_group, - NULL - }; - +static void make_uport_attr_grps(struct uart_port *uport) +{ + uport->attr_grps[0] = &tty_dev_attr_group; + if (uport->dev_spec_attr_group) + uport->attr_grps[1] = uport->dev_spec_attr_group; +} /** * uart_add_one_port - attach a driver-defined port structure @@ -2611,12 +2612,15 @@ int uart_add_one_port(struct uart_driver *drv, struct uart_port *uport) uart_configure_port(drv, state, uport); + make_uport_attr_grps(uport); + /* * Register the port whether it's detected or not. This allows * setserial to be used to alter this port's parameters. */ tty_dev = tty_port_register_device_attr(port, drv->tty_driver, - uport->line, uport->dev, port, tty_dev_attr_groups); + uport->line, uport->dev, port, + (const struct attribute_group **)uport->attr_grps); if (likely(!IS_ERR(tty_dev))) { device_set_wakeup_capable(tty_dev, 1); } else { diff --git a/include/linux/serial_core.h b/include/linux/serial_core.h index f729be9..7e3122f 100644 --- a/include/linux/serial_core.h +++ b/include/linux/serial_core.h @@ -113,6 +113,8 @@ struct uart_icount { typedef unsigned int __bitwise__ upf_t; +#define MAX_ATTR_GRPS 3 + struct uart_port { spinlock_t lock; /* port lock */ unsigned long iobase; /* in/out[bwl] */ @@ -195,6 +197,8 @@ struct uart_port { unsigned intline; /* port index */ resource_size_t mapbase;/* for ioremap */ struct device *dev; /* parent device */ + struct attribute_group *dev_spec_attr_group; /* specific attribute */ + struct attribute_group *attr_grps[MAX_ATTR_GRPS];/* all attr. groups */ unsigned char hub6; /* this should be in the 8250 driver */ unsigned char suspended; unsigned char irq_wake; -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[PATCH V8 2/2] serial/uart/8250: Add tunable RX interrupt trigger I/F of FIFO buffers
Add tunable RX interrupt trigger I/F of FIFO buffers. Serial devices are used as not only message communication devices but control or sending communication devices. For the latter uses, normally small data will be exchanged, so user applications want to receive data unit as soon as possible for real-time tendency. If we have a sensor which sends a 1 byte data each time and must control a device based on the sensor feedback, the RX interrupt should be triggered for each data. According to HW specification of serial UART devices, RX interrupt trigger can be changed, but the trigger is hard-coded. For example, RX interrupt trigger in 16550A can be set to 1, 4, 8, or 14 bytes for HW, but current driver sets the trigger to only 8bytes. This patch makes some devices change RX interrupt trigger from userland. - Read current setting # cat /sys/class/tty/ttyS0/rx_trig_bytes 8 - Write user setting # echo 1 > /sys/class/tty/ttyS0/rx_trig_bytes # cat /sys/class/tty/ttyS0/rx_trig_bytes 1 - 16550A and Tegra (1, 4, 8, or 14 bytes) - 16650V2 (8, 16, 24, or 28 bytes) - 16654 (8, 16, 56, or 60 bytes) - 16750 (1, 16, 32, or 56 bytes) Changed in V2: - Use _IOW for TIOCSFIFORTRIG definition - Pass the interrupt trigger value itself Changes in V3: - Change I/F from ioctl(2) to sysfs(rx_int_trig) Changes in V4: - Introduce fifo_bug flag in uart_8250_port structure This is enabled only when parity is enabled and UART_BUG_PARITY is enabled for up->bugs. If this flag is enabled, user cannot set RX trigger. - Return -EOPNOTSUPP when it does not support device at convert_fcr2val() and at convert_val2rxtrig() - Set the nearest lower RX trigger when users input a meaningless value at convert_val2rxtrig() - Check whether p->fcr is existing at serial8250_clear_and_reinit_fifos() - Set fcr = up->fcr in the begging of serial8250_do_set_termios() Changes in V5: - Support Tegra, 16650V2, 16654, and 16750 - Store default FCR value to up->fcr when the port is first created - Add rx_trig_byte[] in uart_config[] for each device and use rx_trig_byte[] in convert_fcr2val() and convert_val2rxtrig() Changes in V5.1: - Fix FCR_RX_TRIG_MAX_STATE definition Changes in V6: - Move FCR_RX_TRIG_* definition in 8250.h to include/uapi/linux/serial_reg.h, rename those to UART_FCR_R_TRIG_*, and use UART_FCR_TRIGGER_MASK to UART_FCR_R_TRIG_BITS() - Change following function names: convert_fcr2val() => fcr_get_rxtrig_bytes() convert_val2rxtrig() => bytes_to_fcr_rxtrig() - Fix typo in serial8250_do_set_termios() - Delete the verbose error message pr_info() in bytes_to_fcr_rxtrig() - Rename *rx_int_trig/rx_trig* to *rxtrig* for several functions or variables (but UI remains rx_int_trig) - Change the meaningless variable name 'val' to 'bytes' following functions: fcr_get_rxtrig_bytes(), bytes_to_fcr_rxtrig(), do_set_rxtrig(), do_serial8250_set_rxtrig(), and serial8250_set_attr_rxtrig() - Use up->fcr in order to get rxtrig_bytes instead of rx_trig_raw in fcr_get_rxtrig_bytes() - Use conf_type->rxtrig_bytes[0] instead of switch statement for support check in register_dev_spec_attr_grp() - Delete the checking whether a user changed FCR or not when minimum buffer is needed in serial8250_do_set_termios() Changes in V7: - Add Documentation - Change I/F name from rx_int_trig to rx_trig_bytes because the name rx_int_trig is hard to understand how users specify the value Changes in V8: - Divide this patch from V7's patch based on Greg's comment Signed-off-by: Yoshihiro YUNOMAE --- Documentation/ABI/testing/sysfs-tty | 16 +++ drivers/tty/serial/8250/8250.h |2 drivers/tty/serial/8250/8250_core.c | 173 --- include/linux/serial_8250.h |2 include/uapi/linux/serial_reg.h |5 + 5 files changed, 183 insertions(+), 15 deletions(-) diff --git a/Documentation/ABI/testing/sysfs-tty b/Documentation/ABI/testing/sysfs-tty index ad22fb0..9eb3c2b 100644 --- a/Documentation/ABI/testing/sysfs-tty +++ b/Documentation/ABI/testing/sysfs-tty @@ -138,3 +138,19 @@ Description: These sysfs values expose the TIOCGSERIAL interface via sysfs rather than via ioctls. + +What: /sys/class/tty/ttyS0/rx_trig_bytes +Date: May 2014 +Contact: Yoshihiro YUNOMAE +Description: +Shows current RX interrupt trigger bytes or sets the +user specified value to change it for the FIFO buffer. +Users can show or set this value regardless of opening the +serial device file or not. + +The RX trigger can be set one of four kinds of values for UART +serials. When users input a meaning less value to this I/F, +the RX trigger is changed to the nearest lower value for the +device specification. For example, when use
Re: Re: [PATCH V7] serial/uart/8250: Add tunable RX interrupt trigger I/F of FIFO buffers
Hi Greg, Thank you for your review. (2014/05/29 5:13), Greg Kroah-Hartman wrote: On Tue, May 27, 2014 at 02:09:21PM +0900, Yoshihiro YUNOMAE wrote: Add tunable RX interrupt trigger I/F of FIFO buffers. Serial devices are used as not only message communication devices but control or sending communication devices. For the latter uses, normally small data will be exchanged, so user applications want to receive data unit as soon as possible for real-time tendency. If we have a sensor which sends a 1 byte data each time and must control a device based on the sensor feedback, the RX interrupt should be triggered for each data. According to HW specification of serial UART devices, RX interrupt trigger can be changed, but the trigger is hard-coded. For example, RX interrupt trigger in 16550A can be set to 1, 4, 8, or 14 bytes for HW, but current driver sets the trigger to only 8bytes. This patch makes some devices change RX interrupt trigger from userland. I'd prefer it if you could split the attr_grps logic out into a separate patch, the first one in a 2 patch series. I don't think it is quite correct what you are doing here, but given the other changes going on at the same time, it's hard to pick it apart. OK, I understood. If this patch will be separated as you say, other people will be able to understand easily when attr_grps will have been introduced. So, can you split this up into 2 patches and resend please? Sure. I'll do it soon. Thank you, Yoshihiro YUNOMAE -- Yoshihiro YUNOMAE Software Platform Research Dept. Linux Technology Center Hitachi, Ltd., Yokohama Research Laboratory E-mail: yoshihiro.yunomae...@hitachi.com -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[PATCH V7] serial/uart/8250: Add tunable RX interrupt trigger I/F of FIFO buffers
Add tunable RX interrupt trigger I/F of FIFO buffers. Serial devices are used as not only message communication devices but control or sending communication devices. For the latter uses, normally small data will be exchanged, so user applications want to receive data unit as soon as possible for real-time tendency. If we have a sensor which sends a 1 byte data each time and must control a device based on the sensor feedback, the RX interrupt should be triggered for each data. According to HW specification of serial UART devices, RX interrupt trigger can be changed, but the trigger is hard-coded. For example, RX interrupt trigger in 16550A can be set to 1, 4, 8, or 14 bytes for HW, but current driver sets the trigger to only 8bytes. This patch makes some devices change RX interrupt trigger from userland. - Read current setting # cat /sys/class/tty/ttyS0/rx_trig_bytes 8 - Write user setting # echo 1 > /sys/class/tty/ttyS0/rx_trig_bytes # cat /sys/class/tty/ttyS0/rx_trig_bytes 1 - 16550A and Tegra (1, 4, 8, or 14 bytes) - 16650V2 (8, 16, 24, or 28 bytes) - 16654 (8, 16, 56, or 60 bytes) - 16750 (1, 16, 32, or 56 bytes) Changed in V2: - Use _IOW for TIOCSFIFORTRIG definition - Pass the interrupt trigger value itself Changes in V3: - Change I/F from ioctl(2) to sysfs(rx_int_trig) Changes in V4: - Introduce fifo_bug flag in uart_8250_port structure This is enabled only when parity is enabled and UART_BUG_PARITY is enabled for up->bugs. If this flag is enabled, user cannot set RX trigger. - Return -EOPNOTSUPP when it does not support device at convert_fcr2val() and at convert_val2rxtrig() - Set the nearest lower RX trigger when users input a meaningless value at convert_val2rxtrig() - Check whether p->fcr is existing at serial8250_clear_and_reinit_fifos() - Set fcr = up->fcr in the begging of serial8250_do_set_termios() Changes in V5: - Support Tegra, 16650V2, 16654, and 16750 - Store default FCR value to up->fcr when the port is first created - Add rx_trig_byte[] in uart_config[] for each device and use rx_trig_byte[] in convert_fcr2val() and convert_val2rxtrig() Changes in V5.1: - Fix FCR_RX_TRIG_MAX_STATE definition Changes in V6: - Move FCR_RX_TRIG_* definition in 8250.h to include/uapi/linux/serial_reg.h, rename those to UART_FCR_R_TRIG_*, and use UART_FCR_TRIGGER_MASK to UART_FCR_R_TRIG_BITS() - Change following function names: convert_fcr2val() => fcr_get_rxtrig_bytes() convert_val2rxtrig() => bytes_to_fcr_rxtrig() - Fix typo in serial8250_do_set_termios() - Delete the verbose error message pr_info() in bytes_to_fcr_rxtrig() - Rename *rx_int_trig/rx_trig* to *rxtrig* for several functions or variables (but UI remains rx_int_trig) - Change the meaningless variable name 'val' to 'bytes' following functions: fcr_get_rxtrig_bytes(), bytes_to_fcr_rxtrig(), do_set_rxtrig(), do_serial8250_set_rxtrig(), and serial8250_set_attr_rxtrig() - Use up->fcr in order to get rxtrig_bytes instead of rx_trig_raw in fcr_get_rxtrig_bytes() - Use conf_type->rxtrig_bytes[0] instead of switch statement for support check in register_dev_spec_attr_grp() - Delete the checking whether a user changed FCR or not when minimum buffer is needed in serial8250_do_set_termios() Changes in V7: - Add Documentation - Change I/F name from rx_int_trig to rx_trig_bytes because the name rx_int_trig is hard to understand how users specify the value Signed-off-by: Yoshihiro YUNOMAE Reviewed-by: Stephen Warren Cc: Greg Kroah-Hartman Cc: Jiri Slaby Cc: Heikki Krogerus Cc: Jingoo Han Cc: Aaron Sierra Cc: linux-ser...@vger.kernel.org Cc: linux-kernel@vger.kernel.org --- Documentation/ABI/testing/sysfs-tty | 16 +++ drivers/tty/serial/8250/8250.h |2 drivers/tty/serial/8250/8250_core.c | 173 --- drivers/tty/serial/serial_core.c| 18 ++-- include/linux/serial_8250.h |2 include/linux/serial_core.h |4 + include/uapi/linux/serial_reg.h |5 + 7 files changed, 198 insertions(+), 22 deletions(-) diff --git a/Documentation/ABI/testing/sysfs-tty b/Documentation/ABI/testing/sysfs-tty index ad22fb0..9eb3c2b 100644 --- a/Documentation/ABI/testing/sysfs-tty +++ b/Documentation/ABI/testing/sysfs-tty @@ -138,3 +138,19 @@ Description: These sysfs values expose the TIOCGSERIAL interface via sysfs rather than via ioctls. + +What: /sys/class/tty/ttyS0/rx_trig_bytes +Date: May 2014 +Contact: Yoshihiro YUNOMAE +Description: +Shows current RX interrupt trigger bytes or sets the +user specified value to change it for the FIFO buffer. +Users can show or set this value regardless of opening the +serial device file or not. + +The RX trigger can be set one of four kinds of values for UART +se
Re: Re: [PATCH RESEND] scsi: Output error messages using structured printk in single line
Hi Hannes, (2014/05/21 15:30), Hannes Reinecke wrote: On 05/21/2014 05:18 AM, Elliott, Robert (Server Storage) wrote: -Original Message- From: linux-scsi-ow...@vger.kernel.org [mailto:linux-scsi- ow...@vger.kernel.org] On Behalf Of James Bottomley Sent: Tuesday, May 20, 2014 9:22 PM To: Yoshihiro YUNOMAE Cc: Hannes Reinecke; Prarit Bhargava; linux-s...@vger.kernel.org; Kay Sievers; linux-kernel@vger.kernel.org; Hidehiro Kawai; yrl.pp- manager...@hitachi.com; Masami Hiramatsu Subject: Re: [PATCH RESEND] scsi: Output error messages using structured printk in single line On Thu, 2014-02-27 at 13:17 +0900, Yoshihiro YUNOMAE wrote: +/* Maximum size of a local buffer for structured printk */ +#define SCSI_LOG_LINE_MAX 512 + +/* Local buffer for structured printk */ +struct scsi_log_line { +int offset; +char buf[SCSI_LOG_LINE_MAX]; +}; This piece isn't going to fly; it's an on stack allocation of 0.5kb; that's too much for small stack kernels. Just changing this to a kalloc is going be problematic too because we're in the io paths and the allocation may fail. So I appreciate the problem, but I don't think the solution works. Could we just tag the messages and use grep to put them back together? James When the system gets busy, I've seen CDB bytes strung out with each byte getting its own timestamp, with messages from different devices and threads interleaved together, so like the idea of printing each line with a single printk() call. Most lines aren't anywhere near 512 bytes long. Can this be coded to let the calling function define an appropriate buffer size for whatever it is printing, with sizeof() used to bounds check? As mentioned several times, I'm working on a patchset to update scsi logging. The original patchset tried to convert any logging message into a single statement, which wouldn't be broken up even under heavy load. While this works reasonably well for most things, printing out decoded sense with just one line (and not end up in massive switch() statements) is near impossible. Plus you'll end up having to use a static buffer at one point, which again increases the stack size. The alternative approach as discussed at LSF is to move scsi_logging over to tracing. There is already some coding for scsi tracing, but Oh, I didn't attend the meeting, so I didn't know it. Did you completely change the development from fixing scsi_logging to using tracing? in most cases it just duplicates existing logging statements. So if we were to replace the entire scsi_logging infrastructure with scsi tracing most of the issues (like chopped-up CDBs) would be gone. Plus we would have a far better control about _what_ is being printed. And yes, I do have some patches for that :-) I would like to develop the feature together because this is an important problem. Would you upload the patches to your tree? And, would you share current status and issues with us? Thank you, Yoshihiro YUNOMAE -- Yoshihiro YUNOMAE Software Platform Research Dept. Linux Technology Center Hitachi, Ltd., Yokohama Research Laboratory E-mail: yoshihiro.yunomae...@hitachi.com -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
Re: [PATCH V2 0/2] ftrace: Introduce the new I/F "nr_saved_cmdlines"
Hi Steven, Would you review this patch set? Thanks, Yoshihiro YUNOMAE (2014/02/20 17:44), Yoshihiro YUNOMAE wrote: Hi, This patch set introduces the new I/F "nr_saved_cmdlines" for increasing the number of saved cmdlines. Current saved_cmdlines can store just 128 command names and PIDs, but process names are often lost like <...> when we read trace data. If the process exists, we can get the name by using ps command. However, if the process already has not existed, we cannot get the name. To solve this issue, we introduce the new I/F "nr_saved_cmdlines" to expand the max number of saved command line names. This I/F is very simple. If we write a number to nr_saved_cmdlines, the number of command name will be stored. And, if we read the I/F, we can get current maximum number of command name. The default number is 128 which is current default number, so this patch does not change the usage of memory for saved_cmdlines when we boot kernel. Thanks! Changes in V2: - Fix a racing problem of savedcmd between saved_cmdlines I/F and nr_saved_cmdlines I/F. If one reads saved_cmdlines and writes a value to nr_saved_cmdlines at the same time, then the write returns -EBUSY. [2/2] --- Yoshihiro YUNOMAE (2): ftrace: Make saved_cmdlines use seq_read ftrace: Introduce nr_saved_cmdlines I/F kernel/trace/trace.c | 316 +- 1 file changed, 261 insertions(+), 55 deletions(-) -- Yoshihiro YUNOMAE Software Platform Research Dept. Linux Technology Center Hitachi, Ltd., Yokohama Research Laboratory E-mail: yoshihiro.yunomae...@hitachi.com -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
Re: Re: [RFC PATCH 1/2] printk: Add context information to the header of /dev/kmsg
Hi, (2014/05/20 12:36), valdis.kletni...@vt.edu wrote: On Mon, 19 May 2014 19:28:38 +0900, Yoshihiro YUNOMAE said: The header information is changed as follows: /; Has this been tested with popular userspace that reads /dev/kmsg, to make sure that it actually plays nice with a 5th field being added? Yes, I know I checked it for systemd-journald and rsyslog on the source code level, those tools don't handle new flag and field before ';' in the header of /dev/kmsg. Those tools use only log level, sequence#, and timestamp. So, even if we add these new flag and field for each message, those tools will be able to work. But, we'll fix this issue by other method if we found it in any subsystems except for the SCSI layer. (In the SCSI layer, we'll tackle this issue by using tracing feature.) Thank you, Yoshihiro YUNOMAE -- Yoshihiro YUNOMAE Software Platform Research Dept. Linux Technology Center Hitachi, Ltd., Yokohama Research Laboratory E-mail: yoshihiro.yunomae...@hitachi.com -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
Re: Re: [RFC PATCH 1/2] printk: Add context information to the header of /dev/kmsg
Hi Kay, Thank you for your reply. (2014/05/19 20:35), Kay Sievers wrote: On Mon, May 19, 2014 at 7:28 PM, Yoshihiro YUNOMAE wrote: Add context information to the header of /dev/kmsg. Two printk messages connected with KERN_CONT can be divided in multiple lines by a different process context message. If the different context message seems like the 1st divided message, it is difficult to understand which the 2nd divided message belongs to. This problem can also occur for the situation where multiple message lines without KERN_CONT are broken into by similar messages. For example, SCSI disk error messages can be show as follows: [110781.736171] sd 2:0:0:0: [sdb] [110781.736170] sd 3:0:0:0: [sdc] Unhandled sense code [110781.736172] sd 3:0:0:0: [sdc] [110781.736175] Result: hostbyte=DID_OK driverbyte=DRIVER_SENSE [110781.736177] sd 3:0:0:0: [sdc] [110781.736178] Sense Key : Medium Error [current] [110781.736187] Sense Key : Recovered Error [110781.736189] [current] [...] This patch adds PID and interrupt context flag to the header of /dev/kmsg as the context information in order to understand relation of output messages. If PID values of two messages and the interrupt context flags are same, it means that those messages are same context, so those message have some relation. If not so, it means that those messages are different context, so users do not need to take care about the relation of the messages. [...] --- a/kernel/printk/printk.c +++ b/kernel/printk/printk.c @@ -197,6 +197,8 @@ enum log_flags { struct printk_log { u64 ts_nsec;/* timestamp in nanoseconds */ + pid_t pid; /* identify PID */ + u32 irq_count; /* identify irq_count */ I don't think it is worth to blow-up this heavily used struct up even more, just because SCSI cannot log in simple single calls. How about fixing SCSI to log to a local buffer if it cannot safely print one line at once. I'm not convinced, that turning the /dev/kmsg format into an "annotation language', and requiring a rather complex state machine to re-construct the "broken" logging makes too much sense here. If tools rely on properly formatted logging messages, the logging should be fixed at the source while it is logged, not be reconstructed later. It is not not my call, but I don't this makes much sense. Continuation lines are "best effort" not a facility that is or ever was reliable in the past. I think the proper fix is how the log is created, not how it is exported. As we discussed about this issue in LinuxCon Japan, mixed messages will be fixed in each subsystem. In the SCSI layer, tracing feature will be used. (http://www.spinics.net/lists/linux-scsi/msg74428.html) If we found the same issue in other subsystem, we would like to add new generic printk API to avoid mixed messages. Thank you, Yoshihiro YUNOMAE -- Yoshihiro YUNOMAE Software Platform Research Dept. Linux Technology Center Hitachi, Ltd., Yokohama Research Laboratory E-mail: yoshihiro.yunomae...@hitachi.com -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[RFC PATCH 2/2] printk: Simplify fragmented line information of the header of /dev/kmsg
Simplify fragmented line information of the 4th flag of the header of /dev/kmsg. One of the hint of the printk() linebreak is the header information of /dev/kmsg. 4th flag in the header adds 'c' or '+' when a message is divided. Users can roughly understand where the printk message was divided, but they cannot understand exactly which messages are divided or how those messages should be connected. According to a comment in printk.c, 'c' is marked for the first fragment of a line. However, 'c' is not always marked as the first fragment of the line in current kernel. The kernel outputs the 'c' flag when current message flags has LOG_CONT and previous message flag does not have LOG_CONT. So, LOG_CONT flag is needed to add 'c'. However, when the previous message A is being stored in cont buffer and the current message B is not added to cont buffer, LOG_CONT flag is added not to the message A but to the message B. In this situation, 'c' flag is added to the message B even though the message A is actually the first fragmented line. As the result, it seems that the message A is not divided because the message A is output with '-' (no fragment). In addition, all following fragments are flagged with '+' according to Documentation/ABI/testing/dev-kmsg. In kernel, when current message and the previous message has LOG_CONT flag, '+' flag is added to the current message. However, if those messages are output in different context and those messages have LOG_CONT flag, '+' flag is added to the current message but it is sometimes meaningless. For example, when previous message with LOG_CONT is output by process C and current message (1st continuous message) with LOG_CONT is output by process D, adding '+' flag to the current message of process D is incorrect. This occurs when both return values of both messages without '\n' are false in cont_add(). This patch simplifies the fragmented line flag policy. 1) Add 'f' flag if the kernel flushes a fragment message 2) Delete 'c' and '+' When fragmentation occurs, the current message flushes the previous message with LOG_CONT. When the kernel outputs the messages to /dev/kmsg, it just checks whether messages have LOG_CONT flag or not. If the messages have LOG_CONT flag, it adds 'f' flag in the header of /dev/kmsg. Then, users can understand which message was divided by 'f' flag and how these messages should be connected by checking the fragmented flag and the context information. - Environment Execute 3 kernel threads A, B, and C. Each thread outputs following messages: /* for {A, B, C} */ pr_info("{A, B, C}1"); printk("{A, B, C}2"); printk("{A, B, C}3\n"); - Current result of /dev/kmsg 6,225186,93838029,-,2288/-;B1<== No fragment? 6,225187,93838091,c,2289/-;C1 4,225188,93838092,+,2289/-;C2 4,225189,93838092,+,2289/-;C3 6,225190,93842059,c,2289/-;C1 4,225191,93842409,+,2289/-;C2C3 4,225192,93842713,-,2288/-;B2<== No fragment? 6,225193,93842944,c,2287/-;A1 4,225194,93842944,+,2287/-;A2 4,225195,93842945,+,2287/-;A3 4,225196,93846199,-,2288/-;B3<== No fragment? In this example, fragmented flags of the B thread are incorrect because B1, B2, and B3 are actually divided, but there are no flags. So, users cannot understand which messages are divided or how those messages should be connected in current implementation. - Apply this patch This patch introduces 'f' flag policy and deletes 'c' and '+' flags. If a message is forcibly flushed in the middle, just add 'f'. Moreover, if a message includes '\n' meaning the end of the messages, add no fragment flag ('-'). So, if users find 'f' flag for a message, they can connect the message to next 'f' flag (forcibly flushed) or '-' (the end of the messages) in same context. 6,8219,543073110,f,538/-;B1<== This message is fragmented. 6,8220,543073113,f,539/-;C1 4,8221,543073115,f,539/-;C2 4,8222,543073116,-,539/-;C3 4,8223,543073117,f,538/-;B2<== Stil fragmented 6,8224,543073120,f,537/-;A1 4,8225,543073120,-,538/-;B3<== This is the end of the messages. 4,8226,543073123,-,537/-;A2A3 A message merging tool can convert these messages as follows: 6,8219,543073110,-,538/-;B1B2B3 6,8220,543073113,-,539/-;C1C2C3 6,8224,543073120,-,537/-;A1A2A3 Signed-off-by: Yoshihiro YUNOMAE Signed-off-by: Hidehiro Kawai Cc: Randy Dunlap Cc: Kay Sievers Cc: Andrew Morton Cc: Joe Perches Cc: Petr Mladek Cc: Arun KS Cc: Kees Cook --- Documentation/ABI/testing/dev-
[RFC PATCH 1/2] printk: Add context information to the header of /dev/kmsg
Add context information to the header of /dev/kmsg. Two printk messages connected with KERN_CONT can be divided in multiple lines by a different process context message. If the different context message seems like the 1st divided message, it is difficult to understand which the 2nd divided message belongs to. This problem can also occur for the situation where multiple message lines without KERN_CONT are broken into by similar messages. For example, SCSI disk error messages can be show as follows: [110781.736171] sd 2:0:0:0: [sdb] [110781.736170] sd 3:0:0:0: [sdc] Unhandled sense code [110781.736172] sd 3:0:0:0: [sdc] [110781.736175] Result: hostbyte=DID_OK driverbyte=DRIVER_SENSE [110781.736177] sd 3:0:0:0: [sdc] [110781.736178] Sense Key : Medium Error [current] [110781.736187] Sense Key : Recovered Error [110781.736189] [current] This patch adds PID and interrupt context flag to the header of /dev/kmsg as the context information in order to understand relation of output messages. If PID values of two messages and the interrupt context flags are same, it means that those messages are same context, so those message have some relation. If not so, it means that those messages are different context, so users do not need to take care about the relation of the messages. The header information is changed as follows: /; | | +---+ context info. Interrupt context indicates as follows: n: NMI context h: Hard IRQ context s: Soft IRQ context -: No interrupt context - Output same 3 printk messages in two kernel threads. Run two kernel threads in same time in order to make the messages compete. pr_info("A1"); printk("A2"); printk("A3\n"); - Current implementation (without context information) 6,3321,31629088,-;A1<== Who output this message? 6,3322,31629091,c;A1 | 4,3323,31629094,+;A2<+ 4,3324,31629095,+;A3 | Which? 4,3325,31629097,c;A2<+ 4,3326,31629099,+;A3 A1, A2, and A3 messages of two threads are clearly fragmented in this result, but we cannot understand who output the 1st line message and which messages were output by whom. So, the relation of divided messages is unclear from this test. - Applying this patch (with context information) 6,2308,36687114,-,622/-;A1<== Output by PID=622 6,2309,36687118,c,621/-;A1 | 4,2310,36687121,+,621/-;A2 | Relate 4,2311,36687123,+,621/-;A3 | 4,2312,36687124,c,622/-;A2<+ (1) 4,2313,36687126,+,622/-;A3<+ (2) We can understand the relation of divided messages. For example, the 1st line indicates PID=622 and no interrupt context. The same context is the lines of (1) and (2). So, users can understand these three messages are output by the same thread. Note: According to Documentation/ABI/testing/dev-kmsg, we can add comma separated values before ';' as the header information of /dev/kmsg. So, this change does not affect ABI. Signed-off-by: Yoshihiro YUNOMAE Signed-off-by: Hidehiro Kawai Cc: Randy Dunlap Cc: Kay Sievers Cc: Andrew Morton Cc: Joe Perches Cc: Petr Mladek Cc: Arun KS Cc: Kees Cook --- Documentation/ABI/testing/dev-kmsg | 21 -- kernel/printk/printk.c | 77 2 files changed, 76 insertions(+), 22 deletions(-) diff --git a/Documentation/ABI/testing/dev-kmsg b/Documentation/ABI/testing/dev-kmsg index bb820be..d8128ac 100644 --- a/Documentation/ABI/testing/dev-kmsg +++ b/Documentation/ABI/testing/dev-kmsg @@ -77,11 +77,11 @@ Description:The /dev/kmsg character device node provides userspace access userspace. Example: - 7,160,424069,-;pci_root PNP0A03:00: host bridge window [io 0x-0x0cf7] (ignored) + 7,160,424069,-,1/-;pci_root PNP0A03:00: host bridge window [io 0x-0x0cf7] (ignored) SUBSYSTEM=acpi DEVICE=+acpi:PNP0A03:00 - 6,339,5140900,-;NET: Registered protocol family 10 - 30,340,5690716,-;udevd[80]: starting version 181 + 6,339,5140900,-,1/-;NET: Registered protocol family 10 + 30,340,5690716,-,80/-;udevd[80]: starting version 181 The DEVICE= key uniquely identifies devices the following way: b12:8- block dev_t @@ -89,7 +89,7 @@ Description: The /dev/kmsg character device node provides userspace access n8 - netdev ifindex +sound:card0 - subsystem:devname - The flags field carries
[RFC PATCH 0/2] printk: Add context information to kernel messages from /dev/kmsg
adds fragment flags by guess work, but a user tool can connect fragmented lines exactly by utilizing context information. So, current fragment flag is not appropriate after applying this patch, and we introduced new fragment flag 'f' instead of 'c' and '+'. To understand how to connect fragmented messages by changing the header of /dev/kmsg, we assume that each two kernel threads executes the following 3 printk(): pr_info("A1"); printk("A2"); printk("A3\n"); In current implementation, these threads can output as follows: 6,3321,31629088,-;A1<== Who output this message? 6,3322,31629091,c;A1 | 4,3323,31629094,+;A2<+ 4,3324,31629095,+;A3 | Which? 4,3325,31629097,c;A2<+ 4,3326,31629099,+;A3 A1, A2, and A3 messages of two threads are clearly fragmented in this result, but we cannot understand who output the 1st line message and which messages were output by whom. So, the relation of divided messages is unclear from this test. Moreover, although the 4th fields of the header indicate fragment flags, the flag in the 1st line shows not 'c' (fragment) but '-' (no fragment). By applying this patch set, we can get a following result from /dev/kmsg: 6,7868,2070756113,f,1185/-;A1 6,7869,2070756116,f,1186/-;A1 4,7870,2070756118,f,1186/-;A2 4,7871,2070756119,-,1186/-;A3 4,7872,2070756120,f,1185/-;A2 4,7873,2070756122,-,1185/-;A3 1st line indicates fragmented line, PID=1185, and no interrupt context. 2nd line indicates fragmented line, PID=1186, and no interrupt context. So, 1st line will connect to 6th line and 7th line by fragment flags and PID. On the other hand, 2nd line will connect to 3rd line and 4th line. A message merging tool can convert these messages as follows: 6,7868,2070756113,-,1185/-;A1A2A3 /* thread1 */ 6,7869,2070756116,-,1186/-;A1A2A3 /* thread2 */ Thanks! --- Yoshihiro YUNOMAE (2): printk: Add context information to the header of /dev/kmsg printk: Simplify fragmented line information of the header of /dev/kmsg Documentation/ABI/testing/dev-kmsg | 34 ++++ kernel/printk/printk.c | 104 +--- 2 files changed, 95 insertions(+), 43 deletions(-) -- Yoshihiro YUNOMAE Software Platform Research Dept. Linux Technology Center Hitachi, Ltd., Yokohama Research Laboratory E-mail: yoshihiro.yunomae...@hitachi.com -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
Re: Re: Re: [PATCH V6] serial/uart/8250: Add tunable RX interrupt trigger I/F of FIFO buffers
Hi Greg, Sorry for the late reply. (2014/04/26 1:01), Greg Kroah-Hartman wrote: On Fri, Apr 25, 2014 at 05:53:02PM +0900, Yoshihiro YUNOMAE wrote: Hi Greg, Thank you for your review. (2014/04/25 8:11), Greg Kroah-Hartman wrote: On Thu, Apr 17, 2014 at 03:06:44PM +0900, Yoshihiro YUNOMAE wrote: [snip] +static DEVICE_ATTR(rx_int_trig, S_IRUSR | S_IWUSR | S_IRGRP, + serial8250_get_attr_rx_int_trig, + serial8250_set_attr_rx_int_trig); + As you are adding a new sysfs attribute, you have to add a Documentation/ABI/ entry as well. I added this attribute to /sys/dev/char/* What? No. That's not ok, why would it be? See, Documentation would have pointed that problem out very obviously :) , so the documentation may be sysfs-dev. However, any other attributes are not written at all. Should I add this description to it or is there another file? It shouldn't be on a char device, that's not acceptable. My reply that I added this attribute to /sys/dev/char/* was inappropriate. Actually, I added it to a serial device(ttyS0) in /sys/devices/ tree. /sys/dev/char/* stores symlinks of devices in /sys/devices/ tree. I think the documentation where I should add the description is Documentation/ABI/testing/sysfs-tty. (/sys/class/* also stores symlinks of devices in /sys/devices/ tree.) +static struct attribute *serial8250_dev_attrs[] = { + &dev_attr_rx_int_trig.attr, + NULL, + }; + +static struct attribute_group serial8250_dev_attr_group = { + .attrs = serial8250_dev_attrs, + }; What's wrong with the macro to create a group? I'll explain about this below. + +static void register_dev_spec_attr_grp(struct uart_8250_port *up) +{ + const struct serial8250_config *conf_type = &uart_config[up->port.type]; + + if (conf_type->rxtrig_bytes[0]) + up->port.dev_spec_attr_group = &serial8250_dev_attr_group; +} + static void serial8250_config_port(struct uart_port *port, int flags) { struct uart_8250_port *up = @@ -2708,6 +2848,9 @@ static void serial8250_config_port(struct uart_port *port, int flags) if ((port->type == PORT_XR17V35X) || (port->type == PORT_XR17D15X)) port->handle_irq = exar_handle_irq; + + register_dev_spec_attr_grp(up); + up->fcr = uart_config[up->port.type].fcr; } static int diff --git a/drivers/tty/serial/serial_core.c b/drivers/tty/serial/serial_core.c index 2cf5649..41ac44b 100644 --- a/drivers/tty/serial/serial_core.c +++ b/drivers/tty/serial/serial_core.c @@ -2548,15 +2548,16 @@ static struct attribute *tty_dev_attrs[] = { NULL, }; -static const struct attribute_group tty_dev_attr_group = { +static struct attribute_group tty_dev_attr_group = { .attrs = tty_dev_attrs, }; -static const struct attribute_group *tty_dev_attr_groups[] = { - &tty_dev_attr_group, - NULL - }; - +static void make_uport_attr_grps(struct uart_port *uport) +{ + uport->attr_grps[0] = &tty_dev_attr_group; + if (uport->dev_spec_attr_group) + uport->attr_grps[1] = uport->dev_spec_attr_group; +} /** *uart_add_one_port - attach a driver-defined port structure @@ -2607,12 +2608,15 @@ int uart_add_one_port(struct uart_driver *drv, struct uart_port *uport) uart_configure_port(drv, state, uport); + make_uport_attr_grps(uport); + /* * Register the port whether it's detected or not. This allows * setserial to be used to alter this port's parameters. */ tty_dev = tty_port_register_device_attr(port, drv->tty_driver, - uport->line, uport->dev, port, tty_dev_attr_groups); + uport->line, uport->dev, port, + (const struct attribute_group **)uport->attr_grps); If you have to cast that hard, something is wrong here, why are you doing that? The attribute group in serial layer was defined as constant because serial layer has only common sysfs I/F. However, I want to change sysfs I/F for specific devices. So, I deleted 'const' from the definition of the attribute group in serial layer in order to make the attribute group be changeable. On the other hand, to pass the attribute group to tty layer, the group must be const because the 5th variable of tty_port_register_device_attr() is an attribute group with 'const', so I implemented like this. Although I investigated again, tty_port_register_device_attr() is used only here, and tty_register_device_attr() called by the function is called from 2 locations (the one of them passes NULL in the 5th variable). Therefore, we can delete 'const' for those functions, I think. How do you think about this? I think you need to not be messing with the devices in /sys/dev/char/ at all... And why d
Re: Re: [PATCH V6] serial/uart/8250: Add tunable RX interrupt trigger I/F of FIFO buffers
Hi Greg, Thank you for your review. (2014/04/25 8:11), Greg Kroah-Hartman wrote: On Thu, Apr 17, 2014 at 03:06:44PM +0900, Yoshihiro YUNOMAE wrote: [snip] +static DEVICE_ATTR(rx_int_trig, S_IRUSR | S_IWUSR | S_IRGRP, + serial8250_get_attr_rx_int_trig, + serial8250_set_attr_rx_int_trig); + As you are adding a new sysfs attribute, you have to add a Documentation/ABI/ entry as well. I added this attribute to /sys/dev/char/*, so the documentation may be sysfs-dev. However, any other attributes are not written at all. Should I add this description to it or is there another file? +static struct attribute *serial8250_dev_attrs[] = { + &dev_attr_rx_int_trig.attr, + NULL, + }; + +static struct attribute_group serial8250_dev_attr_group = { + .attrs = serial8250_dev_attrs, + }; What's wrong with the macro to create a group? I'll explain about this below. + +static void register_dev_spec_attr_grp(struct uart_8250_port *up) +{ + const struct serial8250_config *conf_type = &uart_config[up->port.type]; + + if (conf_type->rxtrig_bytes[0]) + up->port.dev_spec_attr_group = &serial8250_dev_attr_group; +} + static void serial8250_config_port(struct uart_port *port, int flags) { struct uart_8250_port *up = @@ -2708,6 +2848,9 @@ static void serial8250_config_port(struct uart_port *port, int flags) if ((port->type == PORT_XR17V35X) || (port->type == PORT_XR17D15X)) port->handle_irq = exar_handle_irq; + + register_dev_spec_attr_grp(up); + up->fcr = uart_config[up->port.type].fcr; } static int diff --git a/drivers/tty/serial/serial_core.c b/drivers/tty/serial/serial_core.c index 2cf5649..41ac44b 100644 --- a/drivers/tty/serial/serial_core.c +++ b/drivers/tty/serial/serial_core.c @@ -2548,15 +2548,16 @@ static struct attribute *tty_dev_attrs[] = { NULL, }; -static const struct attribute_group tty_dev_attr_group = { +static struct attribute_group tty_dev_attr_group = { .attrs = tty_dev_attrs, }; -static const struct attribute_group *tty_dev_attr_groups[] = { - &tty_dev_attr_group, - NULL - }; - +static void make_uport_attr_grps(struct uart_port *uport) +{ + uport->attr_grps[0] = &tty_dev_attr_group; + if (uport->dev_spec_attr_group) + uport->attr_grps[1] = uport->dev_spec_attr_group; +} /** *uart_add_one_port - attach a driver-defined port structure @@ -2607,12 +2608,15 @@ int uart_add_one_port(struct uart_driver *drv, struct uart_port *uport) uart_configure_port(drv, state, uport); + make_uport_attr_grps(uport); + /* * Register the port whether it's detected or not. This allows * setserial to be used to alter this port's parameters. */ tty_dev = tty_port_register_device_attr(port, drv->tty_driver, - uport->line, uport->dev, port, tty_dev_attr_groups); + uport->line, uport->dev, port, + (const struct attribute_group **)uport->attr_grps); If you have to cast that hard, something is wrong here, why are you doing that? The attribute group in serial layer was defined as constant because serial layer has only common sysfs I/F. However, I want to change sysfs I/F for specific devices. So, I deleted 'const' from the definition of the attribute group in serial layer in order to make the attribute group be changeable. On the other hand, to pass the attribute group to tty layer, the group must be const because the 5th variable of tty_port_register_device_attr() is an attribute group with 'const', so I implemented like this. Although I investigated again, tty_port_register_device_attr() is used only here, and tty_register_device_attr() called by the function is called from 2 locations (the one of them passes NULL in the 5th variable). Therefore, we can delete 'const' for those functions, I think. How do you think about this? Thank you, Yoshihiro YUNOMAE -- Yoshihiro YUNOMAE Software Platform Research Dept. Linux Technology Center Hitachi, Ltd., Yokohama Research Laboratory E-mail: yoshihiro.yunomae...@hitachi.com -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[PATCH V6] serial/uart/8250: Add tunable RX interrupt trigger I/F of FIFO buffers
Add tunable RX interrupt trigger I/F of FIFO buffers. Serial devices are used as not only message communication devices but control or sending communication devices. For the latter uses, normally small data will be exchanged, so user applications want to receive data unit as soon as possible for real-time tendency. If we have a sensor which sends a 1 byte data each time and must control a device based on the sensor feedback, the RX interrupt should be triggered for each data. According to HW specification of serial UART devices, RX interrupt trigger can be changed, but the trigger is hard-coded. For example, RX interrupt trigger in 16550A can be set to 1, 4, 8, or 14 bytes for HW, but current driver sets the trigger to only 8bytes. This patch makes some devices change RX interrupt trigger from userland. - Read current setting # cat /sys/dev/char/4\:64/rx_int_trig 8 - Write user setting # echo 1 > /sys/dev/char/4\:64/rx_int_trig # cat /sys/dev/char/4\:64/rx_int_trig 1 - 16550A and Tegra (1, 4, 8, or 14 bytes) - 16650V2 (8, 16, 24, or 28 bytes) - 16654 (8, 16, 56, or 60 bytes) - 16750 (1, 16, 32, or 56 bytes) Changed in V2: - Use _IOW for TIOCSFIFORTRIG definition - Pass the interrupt trigger value itself Changes in V3: - Change I/F from ioctl(2) to sysfs(rx_int_trig) Changes in V4: - Introduce fifo_bug flag in uart_8250_port structure This is enabled only when parity is enabled and UART_BUG_PARITY is enabled for up->bugs. If this flag is enabled, user cannot set RX trigger. - Return -EOPNOTSUPP when it does not support device at convert_fcr2val() and at convert_val2rxtrig() - Set the nearest lower RX trigger when users input a meaningless value at convert_val2rxtrig() - Check whether p->fcr is existing at serial8250_clear_and_reinit_fifos() - Set fcr = up->fcr in the begging of serial8250_do_set_termios() Changes in V5: - Support Tegra, 16650V2, 16654, and 16750 - Store default FCR value to up->fcr when the port is first created - Add rx_trig_byte[] in uart_config[] for each device and use rx_trig_byte[] in convert_fcr2val() and convert_val2rxtrig() Changes in V5.1: - Fix FCR_RX_TRIG_MAX_STATE definition Changes in V6: - Move FCR_RX_TRIG_* definition in 8250.h to include/uapi/linux/serial_reg.h, rename those to UART_FCR_R_TRIG_*, and use UART_FCR_TRIGGER_MASK to UART_FCR_R_TRIG_BITS() - Change following function names: convert_fcr2val() => fcr_get_rxtrig_bytes() convert_val2rxtrig() => bytes_to_fcr_rxtrig() - Fix typo in serial8250_do_set_termios() - Delete the verbose error message pr_info() in bytes_to_fcr_rxtrig() - Rename *rx_int_trig/rx_trig* to *rxtrig* for several functions or variables (but UI remains rx_int_trig) - Change the meaningless variable name 'val' to 'bytes' following functions: fcr_get_rxtrig_bytes(), bytes_to_fcr_rxtrig(), do_set_rxtrig(), do_serial8250_set_rxtrig(), and serial8250_set_attr_rxtrig() - Use up->fcr in order to get rxtrig_bytes instead of rx_trig_raw in fcr_get_rxtrig_bytes() - Use conf_type->rxtrig_bytes[0] instead of switch statement for support check in register_dev_spec_attr_grp() - Delete the checking whether a user changed FCR or not when minimum buffer is needed in serial8250_do_set_termios() Signed-off-by: Yoshihiro YUNOMAE Cc: Greg Kroah-Hartman Cc: Jiri Slaby Cc: Heikki Krogerus Cc: Jingoo Han Cc: Aaron Sierra Cc: Stephen Warren Cc: linux-ser...@vger.kernel.org Cc: linux-kernel@vger.kernel.org --- drivers/tty/serial/8250/8250.h |2 drivers/tty/serial/8250/8250_core.c | 173 --- drivers/tty/serial/serial_core.c| 18 ++-- include/linux/serial_8250.h |2 include/linux/serial_core.h |4 + include/uapi/linux/serial_reg.h |5 + 6 files changed, 182 insertions(+), 22 deletions(-) diff --git a/drivers/tty/serial/8250/8250.h b/drivers/tty/serial/8250/8250.h index 1ebf853..1b08c91 100644 --- a/drivers/tty/serial/8250/8250.h +++ b/drivers/tty/serial/8250/8250.h @@ -12,6 +12,7 @@ */ #include +#include #include struct uart_8250_dma { @@ -60,6 +61,7 @@ struct serial8250_config { unsigned short fifo_size; unsigned short tx_loadsz; unsigned char fcr; + unsigned char rxtrig_bytes[UART_FCR_R_TRIG_MAX_STATE]; unsigned intflags; }; diff --git a/drivers/tty/serial/8250/8250_core.c b/drivers/tty/serial/8250/8250_core.c index 81f909c..fd1b3ec 100644 --- a/drivers/tty/serial/8250/8250_core.c +++ b/drivers/tty/serial/8250/8250_core.c @@ -31,7 +31,6 @@ #include #include #include -#include #include #include #include @@ -161,6 +160,7 @@ static const struct serial8250_config uart_config[] = { .fifo_size = 16, .tx_loadsz = 16, .fcr= UART_FCR_ENABLE_FIFO | UART_FCR_R_TRIG_10, + .rxtrig_bytes = {1, 4, 8, 14},
Re: Re: [PATCH V5.1] serial/uart/8250: Add tunable RX interrupt trigger I/F of FIFO buffers
Hi Stephen, Thank you for your reply. (2014/04/17 2:04), Stephen Warren wrote: On 04/15/2014 08:08 PM, Yoshihiro YUNOMAE wrote: diff --git a/drivers/tty/serial/8250/8250_core.c b/drivers/tty/serial/8250/8250_core.c @@ -2275,10 +2276,9 @@ serial8250_do_set_termios(struct uart_port *port, struct ktermios *termios, if (up->capabilities & UART_CAP_FIFO && port->fifosize > 1) { -fcr = uart_config[port->type].fcr; -if ((baud < 2400 && !up->dma) || fifo_bug) { -fcr &= ~UART_FCR_TRIGGER_MASK; -fcr |= UART_FCR_TRIGGER_1; +/* NOTE: If fifo_bug is not set, a uaser can set RX_trigger. */ +if ((baud < 2400 && !up->dma && +(up->fcr == uart_config[port->type].fcr)) || up->fifo_bug) { +up->fcr &= ~UART_FCR_TRIGGER_MASK; +up->fcr |= UART_FCR_TRIGGER_1; } } Does the "(up->fcr == uart_config[port->type].fcr)" term prevent the user from changing the trigger level multiple times? Perhaps this is intended? No, this means that if a user changed FCR value before setting termios, use the changed value because the user think changed value is always set. But, I thought this is not straightforward and it cannot help when the user want to use default FCR value. Could I add FCR changed flag(user_changed_fcr) in uart_8250_port structure and check the flag here? Or shouldn't the driver check the user changing? Oh, I wasn't aware that the user could change FCR directly. To be honest, I'm not sure of the best way to resolve that kind of conflict... OK. For simplicity, I don't implement the checking. Even if FCR is changed here, users can change it any time, so this is not so big problem, I think. Thanks, Yoshihiro YUNOMAE -- Yoshihiro YUNOMAE Software Platform Research Dept. Linux Technology Center Hitachi, Ltd., Yokohama Research Laboratory E-mail: yoshihiro.yunomae...@hitachi.com -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
Re: Re: [PATCH V5.1] serial/uart/8250: Add tunable RX interrupt trigger I/F of FIFO buffers
Hi Stephen, Thank you for your review. (2014/04/16 2:39), Stephen Warren wrote: On 04/15/2014 02:06 AM, Yoshihiro YUNOMAE wrote: /* I found a bug in V5, so I resend this as V5.1. Please do not review V5. */ Add tunable RX interrupt trigger I/F of FIFO buffers. Serial devices are used as not only message communication devices but control or sending communication devices. For the latter uses, normally small data will be exchanged, so user applications want to receive data unit as soon as possible for real-time tendency. If we have a sensor which sends a 1 byte data each time and must control a device based on the sensor feedback, the RX interrupt should be triggered for each data. According to HW specification of serial UART devices, RX interrupt trigger can be changed, but the trigger is hard-coded. For example, RX interrupt trigger in 16550A can be set to 1, 4, 8, or 14 bytes for HW, but current driver sets the trigger to only 8bytes. diff --git a/drivers/tty/serial/8250/8250.h b/drivers/tty/serial/8250/8250.h +#define FCR_RX_TRIG_OFFSET 6 Isn't "SHIFT" the usual term rather than "OFFSET". Why not add this OK, I'll rename this. define into include/uapi/linux/serial_reg.h, along with all the other UART_FCR_TRIGGER_* defines? I thought these definition will not be used in userland. I'll move these in serial_reg.h. +#define FCR_RX_TRIG_BITS(x)(((x) >> FCR_RX_TRIG_OFFSET) & 0x3) Perhaps use UART_FCR_TRIGGER_MASK rather than a hard-coded "3" (and then you'd have to mask before shifting). OK, I'll define FCR_RX_TRIG_BITS as follows: #define UART_FCR_R_TRIG_SHIFT6 #define UART_FCR_R_TRIG_BITS(x) \ (((x) & UART_FCR_TRIGGER_MASK) >> UART_FCR_R_TRIG_SHIFT) diff --git a/drivers/tty/serial/8250/8250_core.c b/drivers/tty/serial/8250/8250_core.c @@ -2275,10 +2276,9 @@ serial8250_do_set_termios(struct uart_port *port, struct ktermios *termios, if (up->capabilities & UART_CAP_FIFO && port->fifosize > 1) { - fcr = uart_config[port->type].fcr; - if ((baud < 2400 && !up->dma) || fifo_bug) { - fcr &= ~UART_FCR_TRIGGER_MASK; - fcr |= UART_FCR_TRIGGER_1; + /* NOTE: If fifo_bug is not set, a uaser can set RX_trigger. */ + if ((baud < 2400 && !up->dma && + (up->fcr == uart_config[port->type].fcr)) || up->fifo_bug) { + up->fcr &= ~UART_FCR_TRIGGER_MASK; + up->fcr |= UART_FCR_TRIGGER_1; } } Does the "(up->fcr == uart_config[port->type].fcr)" term prevent the user from changing the trigger level multiple times? Perhaps this is intended? No, this means that if a user changed FCR value before setting termios, use the changed value because the user think changed value is always set. But, I thought this is not straightforward and it cannot help when the user want to use default FCR value. Could I add FCR changed flag(user_changed_fcr) in uart_8250_port structure and check the flag here? Or shouldn't the driver check the user changing? +static int convert_fcr2val(struct uart_8250_port *up) "val" is rather generic here, and doesn't describe what the function is doing. What about fcr_get_rxtrig_bytes()? Sure. +{ + const struct serial8250_config *conf_type = &uart_config[up->port.type]; + unsigned char rx_trig_raw = up->fcr & UART_FCR_TRIGGER_MASK; + unsigned char val; + + val = conf_type->rx_trig_byte[FCR_RX_TRIG_BITS(rx_trig_raw)]; Given that FCR_RX_TRIG_BITS() does all the required shifting/masking, why not just: val = conf_type->rx_trig_byte[FCR_RX_TRIG_BITS(up->fcr)]; That's true. I'll fix it. +static int convert_val2rxtrig(struct uart_8250_port *up, unsigned char val) Perhaps name this bytes_to_fcr_txtrig()? OK, I'll rename it to bytes_to_fcr_rxtrig(). +static void register_dev_spec_attr_grp(struct uart_8250_port *up) +{ + switch (up->port.type) { + case PORT_16550A: + case PORT_16650V2: + case PORT_16654: + case PORT_16750: + case PORT_TEGRA: Why not replace that with: const struct serial8250_config *conf_type = &uart_config[up->port.type]; if (conf_type->rx_trig_byte[0]) { (or something like that anyway) That means this switch statement doesn't need to be updated when new UART types are modified to set up the rx_trig_byte field. Nice idea! I'll use your idea. Thanks, Yoshihiro YUNOMAE -- Yoshihiro YUNOMAE Software Platform Research Dept. Linux Technology Center Hitachi, Ltd., Yokohama Research Laboratory E-mail: yoshihiro.yunomae...@hitachi.com -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
Re: Re: [PATCH V5.1] serial/uart/8250: Add tunable RX interrupt trigger I/F of FIFO buffers
Hi Alan, Thank you for your review. (2014/04/15 19:10), One Thousand Gnomes wrote: +static int convert_val2rxtrig(struct uart_8250_port *up, unsigned char val) +{ + const struct serial8250_config *conf_type = &uart_config[up->port.type]; + int i; + + if (!conf_type->rx_trig_byte[FCR_RX_TRIG_BITS(UART_FCR_R_TRIG_00)]) { + pr_info("Not support RX-trigger setting for this serial %s\n", + conf_type->name); + return -EOPNOTSUPP; We don't want the pr_info here - otherwise users can flood the logs. The err code is sufficient. OK, I'll delete this pr_info(). + for (i = 1; i < FCR_RX_TRIG_MAX_STATE; i++) { + if (val < conf_type->rx_trig_byte[i]) + /* Use the nearest lower value */ + return (--i) << FCR_RX_TRIG_OFFSET; Odd case here - your 16654 entry has a minimum of 8 so if I pass 1 then it'll return -1 ? I guess for that case the best we can do is to set 8. No, in that case, this function returns 0. Note that the "i" starts from 1, so the minimal value is 0. Actually convert_val2rxtrig() returns the index of rx_trig_byte, and when val == 1, it returns 0 and caller gets rx_trig_byte[0] == 8. Other trivial thing to tweak - you have "uaser" in spot instead of "user". Oops, I'll fix it. Thanks, Yoshihiro YUNOMAE With those two fixed it looks good to me. Alan -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/ -- Yoshihiro YUNOMAE Software Platform Research Dept. Linux Technology Center Hitachi, Ltd., Yokohama Research Laboratory E-mail: yoshihiro.yunomae...@hitachi.com -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[PATCH V5.1] serial/uart/8250: Add tunable RX interrupt trigger I/F of FIFO buffers
/* I found a bug in V5, so I resend this as V5.1. Please do not review V5. */ Add tunable RX interrupt trigger I/F of FIFO buffers. Serial devices are used as not only message communication devices but control or sending communication devices. For the latter uses, normally small data will be exchanged, so user applications want to receive data unit as soon as possible for real-time tendency. If we have a sensor which sends a 1 byte data each time and must control a device based on the sensor feedback, the RX interrupt should be triggered for each data. According to HW specification of serial UART devices, RX interrupt trigger can be changed, but the trigger is hard-coded. For example, RX interrupt trigger in 16550A can be set to 1, 4, 8, or 14 bytes for HW, but current driver sets the trigger to only 8bytes. This patch makes some devices change RX interrupt trigger from userland. - Read current setting # cat /sys/dev/char/4\:64/rx_int_trig 8 - Write user setting # echo 1 > /sys/dev/char/4\:64/rx_int_trig # cat /sys/dev/char/4\:64/rx_int_trig 1 - 16550A and Tegra (1, 4, 8, or 14 bytes) - 16650V2 (8, 16, 24, or 28 bytes) - 16654 (8, 16, 56, or 60 bytes) - 16750 (1, 16, 32, or 56 bytes) Changed in V2: - Use _IOW for TIOCSFIFORTRIG definition - Pass the interrupt trigger value itself Changes in V3: - Change I/F from ioctl(2) to sysfs(rx_int_trig) Changes in V4: - Introduce fifo_bug flag in uart_8250_port structure This is enabled only when parity is enabled and UART_BUG_PARITY is enabled for up->bugs. If this flag is enabled, user cannot set RX trigger. - Return -EOPNOTSUPP when it does not support device at convert_fcr2val() and at convert_val2rxtrig() - Set the nearest lower RX trigger when users input a meaningless value at convert_val2rxtrig() - Check whether p->fcr is existing at serial8250_clear_and_reinit_fifos() - Set fcr = up->fcr in the begging of serial8250_do_set_termios() Changes in V5: - Support Tegra, 16650V2, 16654, and 16750 - Store default FCR value to up->fcr when the port is first created - Add rx_trig_byte[] in uart_config[] for each device and use rx_trig_byte[] in convert_fcr2val() and convert_val2rxtrig() Changes in V5.1: - Fix FCR_RX_TRIG_MAX_STATE definition Signed-off-by: Yoshihiro YUNOMAE Cc: Greg Kroah-Hartman Cc: Jiri Slaby Cc: Heikki Krogerus Cc: Jingoo Han Cc: Aaron Sierra Cc: Stephen Warren Cc: linux-ser...@vger.kernel.org Cc: linux-kernel@vger.kernel.org --- drivers/tty/serial/8250/8250.h |6 + drivers/tty/serial/8250/8250_core.c | 184 --- drivers/tty/serial/serial_core.c| 18 ++- include/linux/serial_8250.h |2 include/linux/serial_core.h |4 + 5 files changed, 192 insertions(+), 22 deletions(-) diff --git a/drivers/tty/serial/8250/8250.h b/drivers/tty/serial/8250/8250.h index 1ebf853..0025694 100644 --- a/drivers/tty/serial/8250/8250.h +++ b/drivers/tty/serial/8250/8250.h @@ -12,6 +12,7 @@ */ #include +#include #include struct uart_8250_dma { @@ -55,11 +56,16 @@ struct old_serial_port { unsigned long irqflags; }; +#define FCR_RX_TRIG_OFFSET 6 +#define FCR_RX_TRIG_BITS(x)(((x) >> FCR_RX_TRIG_OFFSET) & 0x3) +#define FCR_RX_TRIG_MAX_STATE 4 + struct serial8250_config { const char *name; unsigned short fifo_size; unsigned short tx_loadsz; unsigned char fcr; + unsigned char rx_trig_byte[FCR_RX_TRIG_MAX_STATE]; unsigned intflags; }; diff --git a/drivers/tty/serial/8250/8250_core.c b/drivers/tty/serial/8250/8250_core.c index 81f909c..9987845 100644 --- a/drivers/tty/serial/8250/8250_core.c +++ b/drivers/tty/serial/8250/8250_core.c @@ -31,7 +31,6 @@ #include #include #include -#include #include #include #include @@ -161,6 +160,7 @@ static const struct serial8250_config uart_config[] = { .fifo_size = 16, .tx_loadsz = 16, .fcr= UART_FCR_ENABLE_FIFO | UART_FCR_R_TRIG_10, + .rx_trig_byte = {1, 4, 8, 14}, .flags = UART_CAP_FIFO, }, [PORT_CIRRUS] = { @@ -180,6 +180,7 @@ static const struct serial8250_config uart_config[] = { .tx_loadsz = 16, .fcr= UART_FCR_ENABLE_FIFO | UART_FCR_R_TRIG_01 | UART_FCR_T_TRIG_00, + .rx_trig_byte = {8, 16, 24, 28}, .flags = UART_CAP_FIFO | UART_CAP_EFR | UART_CAP_SLEEP, }, [PORT_16750] = { @@ -188,6 +189,7 @@ static const struct serial8250_config uart_config[] = { .tx_loadsz = 64, .fcr= UART_FCR_ENABLE_FIFO | UART_FCR_R_TRIG_10 | UART_FCR7_64BYTE, + .rx_trig_byte = {1, 16, 32, 56}, .flags = UART_CAP_FIFO | UART
[PATCH V5] serial/uart/8250: Add tunable RX interrupt trigger I/F of FIFO buffers
Add tunable RX interrupt trigger I/F of FIFO buffers. Serial devices are used as not only message communication devices but control or sending communication devices. For the latter uses, normally small data will be exchanged, so user applications want to receive data unit as soon as possible for real-time tendency. If we have a sensor which sends a 1 byte data each time and must control a device based on the sensor feedback, the RX interrupt should be triggered for each data. According to HW specification of serial UART devices, RX interrupt trigger can be changed, but the trigger is hard-coded. For example, RX interrupt trigger in 16550A can be set to 1, 4, 8, or 14 bytes for HW, but current driver sets the trigger to only 8bytes. This patch makes some devices change RX interrupt trigger from userland. - Read current setting # cat /sys/dev/char/4\:64/rx_int_trig 8 - Write user setting # echo 1 > /sys/dev/char/4\:64/rx_int_trig # cat /sys/dev/char/4\:64/rx_int_trig 1 - 16550A and Tegra (1, 4, 8, or 14 bytes) - 16650V2 (8, 16, 24, or 28 bytes) - 16654 (8, 16, 56, or 60 bytes) - 16750 (1, 16, 32, or 56 bytes) Changed in V2: - Use _IOW for TIOCSFIFORTRIG definition - Pass the interrupt trigger value itself Changes in V3: - Change I/F from ioctl(2) to sysfs(rx_int_trig) Changes in V4: - Introduce fifo_bug flag in uart_8250_port structure This is enabled only when parity is enabled and UART_BUG_PARITY is enabled for up->bugs. If this flag is enabled, user cannot set RX trigger. - Return -EOPNOTSUPP when it does not support device at convert_fcr2val() and at convert_val2rxtrig() - Set the nearest lower RX trigger when users input a meaningless value at convert_val2rxtrig() - Check whether p->fcr is existing at serial8250_clear_and_reinit_fifos() - Set fcr = up->fcr in the begging of serial8250_do_set_termios() Changes in V5: - Support Tegra, 16650V2, 16654, and 16750 - Store default FCR value to up->fcr when the port is first created - Add rx_trig_byte[] in uart_config[] for each device and use rx_trig_byte[] in convert_fcr2val() and convert_val2rxtrig() Signed-off-by: Yoshihiro YUNOMAE Cc: Greg Kroah-Hartman Cc: Jiri Slaby Cc: Heikki Krogerus Cc: Jingoo Han Cc: Aaron Sierra Cc: Stephen Warren Cc: linux-ser...@vger.kernel.org Cc: linux-kernel@vger.kernel.org --- drivers/tty/serial/8250/8250.h |7 + drivers/tty/serial/8250/8250_core.c | 184 --- drivers/tty/serial/serial_core.c| 18 ++- include/linux/serial_8250.h |2 include/linux/serial_core.h |4 + 5 files changed, 193 insertions(+), 22 deletions(-) diff --git a/drivers/tty/serial/8250/8250.h b/drivers/tty/serial/8250/8250.h index 1ebf853..ab5d812 100644 --- a/drivers/tty/serial/8250/8250.h +++ b/drivers/tty/serial/8250/8250.h @@ -12,6 +12,7 @@ */ #include +#include #include struct uart_8250_dma { @@ -55,11 +56,17 @@ struct old_serial_port { unsigned long irqflags; }; +#define FCR_RX_TRIG_OFFSET 6 +#define FCR_RX_TRIG_BITS(x)(((x) >> FCR_RX_TRIG_OFFSET) & 0x3) +#define FCR_RX_TRIG_MAX_STATE \ +((FCR_RX_TRIG_BITS(UART_FCR_R_TRIG_11))-(FCR_RX_TRIG_BITS(UART_FCR_R_TRIG_00))) + struct serial8250_config { const char *name; unsigned short fifo_size; unsigned short tx_loadsz; unsigned char fcr; + unsigned char rx_trig_byte[FCR_RX_TRIG_MAX_STATE]; unsigned intflags; }; diff --git a/drivers/tty/serial/8250/8250_core.c b/drivers/tty/serial/8250/8250_core.c index 81f909c..9987845 100644 --- a/drivers/tty/serial/8250/8250_core.c +++ b/drivers/tty/serial/8250/8250_core.c @@ -31,7 +31,6 @@ #include #include #include -#include #include #include #include @@ -161,6 +160,7 @@ static const struct serial8250_config uart_config[] = { .fifo_size = 16, .tx_loadsz = 16, .fcr= UART_FCR_ENABLE_FIFO | UART_FCR_R_TRIG_10, + .rx_trig_byte = {1, 4, 8, 14}, .flags = UART_CAP_FIFO, }, [PORT_CIRRUS] = { @@ -180,6 +180,7 @@ static const struct serial8250_config uart_config[] = { .tx_loadsz = 16, .fcr= UART_FCR_ENABLE_FIFO | UART_FCR_R_TRIG_01 | UART_FCR_T_TRIG_00, + .rx_trig_byte = {8, 16, 24, 28}, .flags = UART_CAP_FIFO | UART_CAP_EFR | UART_CAP_SLEEP, }, [PORT_16750] = { @@ -188,6 +189,7 @@ static const struct serial8250_config uart_config[] = { .tx_loadsz = 64, .fcr= UART_FCR_ENABLE_FIFO | UART_FCR_R_TRIG_10 | UART_FCR7_64BYTE, + .rx_trig_byte = {1, 16, 32, 56}, .flags = UART_CAP_FIFO | UART_CAP_SLEEP | UART_CAP_AFE, }, [PORT_START
Re: Re: [PATCH V4] serial/uart/8250: Add tunable RX interrupt trigger I/F of FIFO buffers
Hi Stephen, Thank you for your reply. (2014/03/20 4:51), Stephen Warren wrote: On 03/19/2014 04:15 AM, Yoshihiro YUNOMAE wrote: Add tunable RX interrupt trigger I/F of FIFO buffers. Serial devices are used as not only message communication devices but control or sending communication devices. For the latter uses, normally small data will be exchanged, so user applications want to receive data unit as soon as possible for real-time tendency. If we have a sensor which sends a 1 byte data each time and must control a device based on the sensor feedback, the RX interrupt should be triggered for each data. According to HW specification of serial UART devices, RX interrupt trigger can be changed, but the trigger is hard-coded. For example, RX interrupt trigger in 16550A can be set to 1, 4, 8, or 14 bytes for HW, but current driver sets the trigger to only 8bytes. diff --git a/drivers/tty/serial/8250/8250_core.c b/drivers/tty/serial/8250/8250_core.c index 69932b7..fc17fb2 100644 --- a/drivers/tty/serial/8250/8250_core.c +++ b/drivers/tty/serial/8250/8250_core.c @@ -531,11 +531,10 @@ static void serial8250_clear_fifos(struct uart_8250_port *p) void serial8250_clear_and_reinit_fifos(struct uart_8250_port *p) { - unsigned char fcr; - serial8250_clear_fifos(p); - fcr = uart_config[p->port.type].fcr; - serial_out(p, UART_FCR, fcr); + if (!p->fcr) + p->fcr = uart_config[p->port.type].fcr; Rather than sprinkling this initialization all over the place, can't the fcr value be set up one time, when the port is first created? It's nice idea. If we can store default value of fcr to up->fcr when the port is first created, we don't need to check whether p->fcr exists or not. Maybe by adding the operation after register_dev_spec_attr_grp() in my patch, we can avoid the check. +static int convert_fcr2val(struct uart_8250_port *up, unsigned char fcr) +{ + unsigned char trig_raw = fcr & UART_FCR_TRIGGER_MASK; + + switch (up->port.type) { + case PORT_16550A: + if (trig_raw == UART_FCR_R_TRIG_00) + return 1; + else if (trig_raw == UART_FCR_R_TRIG_01) + return 4; + else if (trig_raw == UART_FCR_R_TRIG_10) + return 8; + else if (trig_raw == UART_FCR_R_TRIG_11) + return 14; + break; + } + return -EOPNOTSUPP; +} Rather than implementing this translation inside this one function (well, and convert_val2rxtrig() too), perhaps it would make sense to put the values into uart_config[] and just look them up here. That would better isolate the type-specific data into one place. Sure. I'll apply following implementation: [PORT_16550A] = { .name = "16550A", .fifo_size = 16, .tx_loadsz = 16, .fcr= UART_FCR_ENABLE_FIFO | UART_FCR_R_TRIG_10, + .rx_trig_byte = {1, 4, 8, 14}, .flags = UART_CAP_FIFO, }; The comment right before UART_FCR_R_TRIG_00 in include/uapi/linux/serial_reg.h might help when filling in any extra fields in uart_config[]. OK, I'll add following rx_trig_byte to PORT_16650V2, PORT_16654, PORT_16750, and PORT_TEGRA in uart_config[]. /* * Note: The FIFO trigger levels are chip specific: * RX:76 = 00 01 10 11 TX:54 = 00 01 10 11 * PC16550D: 1 4 8 14 xx xx xx xx * TI16C550A:1 4 8 14 xx xx xx xx * TI16C550C:1 4 8 14 xx xx xx xx * ST16C550: 1 4 8 14 xx xx xx xx * ST16C650: 8 16 24 28 16 8 24 30 PORT_16650V2 * NS16C552: 1 4 8 14 xx xx xx xx * ST16C654: 8 16 56 60 8 16 32 56 PORT_16654 * TI16C750: 1 16 32 56 xx xx xx xx PORT_16750 * TI16C752: 8 16 56 60 8 16 32 56 * Tegra:1 4 8 14 16 8 4 1 PORT_TEGRA */ Thanks, Yoshihiro YUNOMAE -- Yoshihiro YUNOMAE Software Platform Research Dept. Linux Technology Center Hitachi, Ltd., Yokohama Research Laboratory E-mail: yoshihiro.yunomae...@hitachi.com -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[PATCH V4] serial/uart/8250: Add tunable RX interrupt trigger I/F of FIFO buffers
Add tunable RX interrupt trigger I/F of FIFO buffers. Serial devices are used as not only message communication devices but control or sending communication devices. For the latter uses, normally small data will be exchanged, so user applications want to receive data unit as soon as possible for real-time tendency. If we have a sensor which sends a 1 byte data each time and must control a device based on the sensor feedback, the RX interrupt should be triggered for each data. According to HW specification of serial UART devices, RX interrupt trigger can be changed, but the trigger is hard-coded. For example, RX interrupt trigger in 16550A can be set to 1, 4, 8, or 14 bytes for HW, but current driver sets the trigger to only 8bytes. This patch makes a 16550A device change RX interrupt trigger from userland. - Read current setting # cat /sys/dev/char/4\:64/rx_int_trig 8 - Write user setting # echo 1 > /sys/dev/char/4\:64/rx_int_trig # cat /sys/dev/char/4\:64/rx_int_trig 1 - 16550A (1, 4, 8, or 14 bytes) Changed in V2: - Use _IOW for TIOCSFIFORTRIG definition - Pass the interrupt trigger value itself Changes in V3: - Change I/F from ioctl(2) to sysfs(rx_int_trig) Changes in V4: - Introduce fifo_bug flag in uart_8250_port structure This is enabled only when parity is enabled and UART_BUG_PARITY is enabled for up->bugs. If this flag is enabled, user cannot set RX trigger. - Return -EOPNOTSUPP when it does not support device at convert_fcr2val() and at convert_val2rxtrig() - Set the nearest lower RX trigger when users input a meaningless value at convert_val2rxtrig() - Check whether p->fcr is existing at serial8250_clear_and_reinit_fifos() - Set fcr = up->fcr in the begging of serial8250_do_set_termios() Signed-off-by: Yoshihiro YUNOMAE Cc: Greg Kroah-Hartman Cc: Jiri Slaby Cc: Heikki Krogerus Cc: Jingoo Han Cc: Aaron Sierra Cc: Stephen Warren Cc: linux-ser...@vger.kernel.org Cc: linux-kernel@vger.kernel.org --- drivers/tty/serial/8250/8250_core.c | 196 +-- drivers/tty/serial/serial_core.c| 18 ++- include/linux/serial_8250.h |2 include/linux/serial_core.h |4 + 4 files changed, 201 insertions(+), 19 deletions(-) diff --git a/drivers/tty/serial/8250/8250_core.c b/drivers/tty/serial/8250/8250_core.c index 69932b7..fc17fb2 100644 --- a/drivers/tty/serial/8250/8250_core.c +++ b/drivers/tty/serial/8250/8250_core.c @@ -531,11 +531,10 @@ static void serial8250_clear_fifos(struct uart_8250_port *p) void serial8250_clear_and_reinit_fifos(struct uart_8250_port *p) { - unsigned char fcr; - serial8250_clear_fifos(p); - fcr = uart_config[p->port.type].fcr; - serial_out(p, UART_FCR, fcr); + if (!p->fcr) + p->fcr = uart_config[p->port.type].fcr; + serial_out(p, UART_FCR, p->fcr); } EXPORT_SYMBOL_GPL(serial8250_clear_and_reinit_fifos); @@ -2271,10 +2270,9 @@ serial8250_do_set_termios(struct uart_port *port, struct ktermios *termios, { struct uart_8250_port *up = container_of(port, struct uart_8250_port, port); - unsigned char cval, fcr = 0; + unsigned char cval, fcr = up->fcr; unsigned long flags; unsigned int baud, quot; - int fifo_bug = 0; switch (termios->c_cflag & CSIZE) { case CS5: @@ -2297,7 +2295,7 @@ serial8250_do_set_termios(struct uart_port *port, struct ktermios *termios, if (termios->c_cflag & PARENB) { cval |= UART_LCR_PARITY; if (up->bugs & UART_BUG_PARITY) - fifo_bug = 1; + up->fifo_bug = true; } if (!(termios->c_cflag & PARODD)) cval |= UART_LCR_EPAR; @@ -2321,12 +2319,20 @@ serial8250_do_set_termios(struct uart_port *port, struct ktermios *termios, quot++; if (up->capabilities & UART_CAP_FIFO && port->fifosize > 1) { - fcr = uart_config[port->type].fcr; - if ((baud < 2400 && !up->dma) || fifo_bug) { + /* +* If fcr exists, a user has opened this port, changed RX +* trigger, or read RX trigger before. If so, we don't change +* fcr. +*/ + if (!fcr) + fcr = uart_config[port->type].fcr; + /* NOTE: If fifo_bug is not set, a uaser can set RX_trigger. */ + if ((baud < 2400 && !up->dma && !up->fcr) || up->fifo_bug) { fcr &= ~UART_FCR_TRIGGER_MASK; fcr |= UART_FCR_TRIGGER_1; } } + up->fcr = fcr; /* * MCR-based auto flow control. When AFE is enabled, RTS will be @@ -2455,15 +2461,15 @@ serial8250_do_set_termios(struct uart
Re: Re: [PATCH V3] serial/uart/8250: Add tunable RX interrupt trigger I/F of FIFO buffers
Hi Alan, Thank you for your reply. (2014/03/14 21:04), One Thousand Gnomes wrote: @@ -2325,10 +2323,19 @@ serial8250_do_set_termios(struct uart_port *port, struct ktermios *termios, if ((baud < 2400 && !up->dma) || fifo_bug) { fcr &= ~UART_FCR_TRIGGER_MASK; fcr |= UART_FCR_TRIGGER_1; + /* Don't use user setting RX trigger */ + up->fcr = 0; This breaks set fcr via sysfs set baud rate below 2400 set baud rate higher If baud < 2400 and the user has set a value then probably we should honour OK, I'll add !up->fcr in this flow as follows: /* NOTE: If fifo_bug is not set, a user can set RX trigger. */ if ((baud < 2400 && !up->dma && !up->fcr) || fifo_bug) { fcr &= ~UART_TRIGGER_MASK; fcr |= UART_FCR_TRIGGER_1; up->fcr = 0; } it. If fifo_bug is set then we should never honour it (and should perhaps eventually error it in the sysfs set). When fifo_bug is set to "1", we need to check not only whether (up->bugs & UART_BUG_PARITY) but whether parity is enabled. We can check whether parity is enable only in this function currently, so I think we need to store fifo_bug's value into up->fifo_bug and refer it in the sysfs set(do_set_rx_int_trig()) as follows: @do_set_rx_int_trig() if (!(up->capabilities & UART_CAP_FIFO) || uport->fifosize <= 1 || (up->fifo_bug & UART_BUG_PARITY)) return -EINVAL; +static unsigned char convert_fcr2val(struct uart_8250_port *up, +unsigned char fcr) +{ + unsigned char val = 0, trig_raw = fcr & UART_FCR_TRIGGER_MASK; + + switch (up->port.type) { + case PORT_16550A: + if (trig_raw == UART_FCR_R_TRIG_00) + val = 1; + else if (trig_raw == UART_FCR_R_TRIG_01) + val = 4; + else if (trig_raw == UART_FCR_R_TRIG_10) + val = 8; + else if (trig_raw == UART_FCR_R_TRIG_11) + val = 14; + break; Surely the default case should be returning 1 not 0 ? In the default case, it returns "0" meaning error because "1" has other meaning (1 byte RX trigger). But, "0" is not instinctive value for the error, so it should return -EOPNOTSUPP here. +static int convert_val2rxtrig(struct uart_8250_port *up, unsigned char val) +{ + switch (up->port.type) { + case PORT_16550A: + if (val == 1) + return UART_FCR_R_TRIG_00; + else if (val == 4) + return UART_FCR_R_TRIG_01; + else if (val == 8) + return UART_FCR_R_TRIG_10; + else if (val == 14) + return UART_FCR_R_TRIG_11; What happens if you specify a meaningless value. Doing exact matching means that you have to know the hardware exactly. How about if (val < 4) return UART_FCR_R_TRIG_00; else if (val < 8) return UART_FCR_R_TRIG_01; else if (val < 14) return UART_FCR_R_TRIG_10; else return UART_FCR_R_TRIG_11; so you get the nearest lower value that the hardware can provide ? It is a good idea. I was concerned about the same thing which users must know the HW exactly. I'll implement it as you say. + break; + default: + pr_info("Not support RX-trigger setting for this serial %u\n", + up->port.type); That lets users spew into the logs. I think actually you just want default: return -EOPNOTSUPP; OK, I'll use this. Thank you, Yoshihiro YUNOMAE -- Yoshihiro YUNOMAE Software Platform Research Dept. Linux Technology Center Hitachi, Ltd., Yokohama Research Laboratory E-mail: yoshihiro.yunomae...@hitachi.com -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
Re: Re: [PATCH V3] serial/uart/8250: Add tunable RX interrupt trigger I/F of FIFO buffers
Hi Heikki, Thank you for your reply. (2014/03/14 23:16), Heikki Krogerus wrote: Hi, On Fri, Mar 14, 2014 at 11:21:54AM +0900, Yoshihiro YUNOMAE wrote: void serial8250_clear_and_reinit_fifos(struct uart_8250_port *p) { - unsigned char fcr; - serial8250_clear_fifos(p); - fcr = uart_config[p->port.type].fcr; - serial_out(p, UART_FCR, fcr); + p->fcr = uart_config[p->port.type].fcr; + serial_out(p, UART_FCR, p->fcr); You should allow also the probe drivers to set this.. if (!p->fcr) p->fcr = uart_config[p->port.type].fcr; Oh, I'll fix it. } EXPORT_SYMBOL_GPL(serial8250_clear_and_reinit_fifos); @@ -2325,10 +2323,19 @@ serial8250_do_set_termios(struct uart_port *port, struct ktermios *termios, if ((baud < 2400 && !up->dma) || fifo_bug) { fcr &= ~UART_FCR_TRIGGER_MASK; fcr |= UART_FCR_TRIGGER_1; + /* Don't use user setting RX trigger */ + up->fcr = 0; I don't know about this but.. } } /* +* If up->fcr exists, a user has opened this port, changed RX trigger, +* or read RX trigger before. So, we don't need to change up->fcr here. +*/ + if (!up->fcr) + up->fcr = fcr; Why not just set fcr = up->fcr in the beginning of the function? Ah, we don't need to set up->fcr = 0 in the previous flow when we implement as follows: unsigned char fcr = up->fcr; ... ... /* * If fcr exists, a user has opened this port, changed RX * trigger, or read RX trigger before. If so, we do not change * fcr. */ if (!fcr) fcr = uart_config[port_type].fcr; if ((baud < 2400 && !up->dma) || fifo_bug) { fcr &= ~UART_FCR_TRIGGER_MASK; fcr |= UART_FCR_TRIGGER_1; } up->fcr = fcr; +static int do_set_rx_int_trig(struct tty_port *port, unsigned char val) +{ + struct uart_state *state = container_of(port, struct uart_state, port); + struct uart_port *uport = state->uart_port; + struct uart_8250_port *up = + container_of(uport, struct uart_8250_port, port); + unsigned char fcr; + int rx_trig; + + if (!(up->capabilities & UART_CAP_FIFO) || uport->fifosize <= 1) + return -EINVAL; + + rx_trig = convert_val2rxtrig(up, val); + if (rx_trig < 0) + return rx_trig; + + serial8250_clear_fifos(up); + if (!up->fcr) + /* termios is not set yet */ + fcr = uart_config[up->port.type].fcr; + else + fcr = up->fcr; + fcr &= ~UART_FCR_TRIGGER_MASK; + fcr |= (unsigned char)rx_trig; + up->fcr = fcr; + serial_out(up, UART_FCR, up->fcr); + return 0; +} Where are you setting UART_FCR_ENABLE_FIFO bit? Am I missing something? In these implementation, the driver sets up->fcr as uart_config[up->port.type].fcr first and changes only RX trigger. So, we don't need to set the bit in a direct way. Thank you, Yoshihiro YUNOMAE -- Yoshihiro YUNOMAE Software Platform Research Dept. Linux Technology Center Hitachi, Ltd., Yokohama Research Laboratory E-mail: yoshihiro.yunomae...@hitachi.com -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[PATCH V3] serial/uart/8250: Add tunable RX interrupt trigger I/F of FIFO buffers
Add tunable RX interrupt trigger I/F of FIFO buffers. Serial devices are used as not only message communication devices but control or sending communication devices. For the latter uses, normally small data will be exchanged, so user applications want to receive data unit as soon as possible for real-time tendency. If we have a sensor which sends a 1 byte data each time and must control a device based on the sensor feedback, the RX interrupt should be triggered for each data. According to HW specification of serial UART devices, RX interrupt trigger can be changed, but the trigger is hard-coded. For example, RX interrupt trigger in 16550A can be set to 1, 4, 8, or 14 bytes for HW, but current driver sets the trigger to only 8bytes. This patch makes a 16550A device change RX interrupt trigger from userland. - Read current setting # cat /sys/dev/char/4\:64/rx_int_trig 8 - Write user setting # echo 1 > /sys/dev/char/4\:64/rx_int_trig # cat /sys/dev/char/4\:64/rx_int_trig 1 - 16550A (1, 4, 8, or 14 bytes) Changed in V2: - Use _IOW for TIOCSFIFORTRIG definition - Pass the interrupt trigger value itself Changes in V3: - Change I/F from ioctl(2) to sysfs(rx_int_trig) Signed-off-by: Yoshihiro YUNOMAE Cc: Greg Kroah-Hartman Cc: Jiri Slaby Cc: Heikki Krogerus Cc: Jingoo Han Cc: Aaron Sierra Cc: Stephen Warren Cc: linux-ser...@vger.kernel.org Cc: linux-kernel@vger.kernel.org --- drivers/tty/serial/8250/8250_core.c | 189 ++- drivers/tty/serial/serial_core.c| 18 ++- include/linux/serial_8250.h |1 include/linux/serial_core.h |4 + 4 files changed, 198 insertions(+), 14 deletions(-) diff --git a/drivers/tty/serial/8250/8250_core.c b/drivers/tty/serial/8250/8250_core.c index 69932b7..c945ceb 100644 --- a/drivers/tty/serial/8250/8250_core.c +++ b/drivers/tty/serial/8250/8250_core.c @@ -531,11 +531,9 @@ static void serial8250_clear_fifos(struct uart_8250_port *p) void serial8250_clear_and_reinit_fifos(struct uart_8250_port *p) { - unsigned char fcr; - serial8250_clear_fifos(p); - fcr = uart_config[p->port.type].fcr; - serial_out(p, UART_FCR, fcr); + p->fcr = uart_config[p->port.type].fcr; + serial_out(p, UART_FCR, p->fcr); } EXPORT_SYMBOL_GPL(serial8250_clear_and_reinit_fifos); @@ -2325,10 +2323,19 @@ serial8250_do_set_termios(struct uart_port *port, struct ktermios *termios, if ((baud < 2400 && !up->dma) || fifo_bug) { fcr &= ~UART_FCR_TRIGGER_MASK; fcr |= UART_FCR_TRIGGER_1; + /* Don't use user setting RX trigger */ + up->fcr = 0; } } /* +* If up->fcr exists, a user has opened this port, changed RX trigger, +* or read RX trigger before. So, we don't need to change up->fcr here. +*/ + if (!up->fcr) + up->fcr = fcr; + + /* * MCR-based auto flow control. When AFE is enabled, RTS will be * deasserted when the receive FIFO contains more characters than * the trigger, or the MCR RTS bit is cleared. In the case where @@ -2455,15 +2462,15 @@ serial8250_do_set_termios(struct uart_port *port, struct ktermios *termios, * is written without DLAB set, this mode will be disabled. */ if (port->type == PORT_16750) - serial_port_out(port, UART_FCR, fcr); + serial_port_out(port, UART_FCR, up->fcr); serial_port_out(port, UART_LCR, cval); /* reset DLAB */ up->lcr = cval; /* Save LCR */ if (port->type != PORT_16750) { /* emulated UARTs (Lucent Venus 167x) need two steps */ - if (fcr & UART_FCR_ENABLE_FIFO) + if (up->fcr & UART_FCR_ENABLE_FIFO) serial_port_out(port, UART_FCR, UART_FCR_ENABLE_FIFO); - serial_port_out(port, UART_FCR, fcr); /* set fcr */ + serial_port_out(port, UART_FCR, up->fcr); /* set fcr */ } serial8250_set_mctrl(port, port->mctrl); spin_unlock_irqrestore(&port->lock, flags); @@ -2656,6 +2663,172 @@ static int serial8250_request_port(struct uart_port *port) return ret; } +static unsigned char convert_fcr2val(struct uart_8250_port *up, +unsigned char fcr) +{ + unsigned char val = 0, trig_raw = fcr & UART_FCR_TRIGGER_MASK; + + switch (up->port.type) { + case PORT_16550A: + if (trig_raw == UART_FCR_R_TRIG_00) + val = 1; + else if (trig_raw == UART_FCR_R_TRIG_01) + val = 4; + else if (trig_raw == UART_FCR_R_TRIG_10) + val = 8; +
Re: [PATCH RESEND] scsi: Output error messages using structured printk in single line
Hi Hannes, Although I sent you a message 6 days ago to ask your work which is similar to my patch, I resend my patch because I'm considering this problem should be fixed as soon as possible. Thank you, Yoshihiro YUNOMAE (2014/02/27 13:17), Yoshihiro YUNOMAE wrote: Output error messages using structured printk in single line. In SCSI drivers, some error messages which should be output in single line are divided in multiple lines. When user tools handle the error messages, those divided messages will create some inconveniences. The reason why this problem is induced is structured printk for error messages. Structured printk can add device information for printk, and it is used in scmd_printk() and sd_printk(). The printk aims at output in atomic, so we cannot use those functions for connecting multiple messages like KERN_CONT. However, some error messages is implemented as follows: structured_printk("DEVICE INFORMATION:"); printk(KERN_CONT, "DETAIL INFORMATION\n"); This implementation will be expected to output like "DEVICE INFORMATION: DETAIL INFORMATION", but actually, this will be output as follows: DEVICE INFORMATION: DETAIL INFORMATION For instance, in a following pseudo SCSI error test, the device information and the detail information are divided: -- Pseudo SCSI error test for current kernel # modprobe scsi_debug # cd /sys/bus/pseudo/drivers/scsi_debug # echo 2 > opts # dd if=/dev/sdb of=/dev/null 2> /dev/null -- Result for current kernel # dmesg [ 17.842110] sd 2:0:0:0: [sdb] Attached SCSI disk [ 18.859098] sd 2:0:0:0: [sdb] Unhandled sense code [ 18.859103] sd 2:0:0:0: [sdb] [ 18.859106] Result: hostbyte=DID_OK driverbyte=DRIVER_SENSE [ 18.859108] sd 2:0:0:0: [sdb] [ 18.859110] Sense Key : Medium Error [current] [ 18.859114] Info fld=0x1234 [ 18.859116] sd 2:0:0:0: [sdb] [ 18.859119] Add. Sense: Unrecovered read error [ 18.859122] sd 2:0:0:0: [sdb] CDB: [ 18.859124] Read(10): 28 00 00 00 11 e0 00 01 00 00 In a SCSI device driver, sd_print_result() is implemented as follows: sd_print_result() { sd_printk(KERN_INFO, sdkp, " "); scsi_show_result(result); } Here, first sd_printk() outputs "sd 2:0:0:0: [sdb] ", then scsi_show_sense_hdr() outputs "Result: hostbyte=DID_OK driverbyte=DRIVER_SENSE". sd_printk() does not include "\n", but it forcibly starts a new line. Therefore, when the driver outputs error messages, those messages are divided. This patch makes those multiple line messages output in single line as follows: # dmesg [ 17.145085] sdb: unknown partition table [ 17.149096] sd 2:0:0:0: [sdb] Attached SCSI disk [ 18.166090] sd 2:0:0:0: [sdb] Unhandled sense code [ 18.166095] sd 2:0:0:0: [sdb] Result: hostbyte=DID_OK driverbyte=DRIVER_SENSE [ 18.166099] sd 2:0:0:0: [sdb] Sense Key : Medium Error [current] [ 18.166104] Info fld=0x1234 [ 18.166106] sd 2:0:0:0: [sdb] Add. Sense: Unrecovered read error [ 18.166111] sd 2:0:0:0: [sdb] CDB: Read(10): 28 00 00 00 11 e0 00 01 00 00 Signed-off-by: Yoshihiro YUNOMAE Cc: James E.J. Bottomley Cc: Hannes Reinecke Cc: Kay Sievers Cc: linux-kernel@vger.kernel.org Cc: linux-s...@vger.kernel.org --- drivers/scsi/constants.c | 206 -- drivers/scsi/scsi.c | 28 -- drivers/scsi/sd.c| 19 +++- include/scsi/scsi_dbg.h | 23 - 4 files changed, 176 insertions(+), 100 deletions(-) diff --git a/drivers/scsi/constants.c b/drivers/scsi/constants.c index d35a5d6..cb93435 100644 --- a/drivers/scsi/constants.c +++ b/drivers/scsi/constants.c @@ -256,8 +256,26 @@ static const char * get_sa_name(const struct value_name_pair * arr, return (k < arr_sz) ? arr->name : NULL; } +/* Store a SCSI logging event to buf. */ +__printf(2, 3) +void scsi_log_add(struct scsi_log_line *log, const char *fmt, ...) +{ + va_list args; + int len; + + va_start(args, fmt); + len = vscnprintf(log->buf + log->offset, +SCSI_LOG_LINE_MAX - log->offset, fmt, args); + WARN_ONCE(!len, "Cannot store the message '%s' in a local log buffer\n", + fmt); + log->offset += len; + va_end(args); +} +EXPORT_SYMBOL(scsi_log_add); + /* attempt to guess cdb length if cdb_len==0 . No trailing linefeed. */ -static void print_opcode_name(unsigned char * cdbp, int cdb_len) +static void print_opcode_name(unsigned char *cdbp, int cdb_len, + struct scsi_log_line *log) { int sa, len, cdb0; int fin_name = 0; @@ -268,20 +286,22 @@ static void print_opcode_name(unsigned char * cdbp, int cdb_len) case VARIABLE_LENGTH_CMD: len = scsi_varlen_cdb_length(cdbp); if (len < 10) { - printk("short variabl
[PATCH RESEND] scsi: Output error messages using structured printk in single line
Output error messages using structured printk in single line. In SCSI drivers, some error messages which should be output in single line are divided in multiple lines. When user tools handle the error messages, those divided messages will create some inconveniences. The reason why this problem is induced is structured printk for error messages. Structured printk can add device information for printk, and it is used in scmd_printk() and sd_printk(). The printk aims at output in atomic, so we cannot use those functions for connecting multiple messages like KERN_CONT. However, some error messages is implemented as follows: structured_printk("DEVICE INFORMATION:"); printk(KERN_CONT, "DETAIL INFORMATION\n"); This implementation will be expected to output like "DEVICE INFORMATION: DETAIL INFORMATION", but actually, this will be output as follows: DEVICE INFORMATION: DETAIL INFORMATION For instance, in a following pseudo SCSI error test, the device information and the detail information are divided: -- Pseudo SCSI error test for current kernel # modprobe scsi_debug # cd /sys/bus/pseudo/drivers/scsi_debug # echo 2 > opts # dd if=/dev/sdb of=/dev/null 2> /dev/null -- Result for current kernel # dmesg [ 17.842110] sd 2:0:0:0: [sdb] Attached SCSI disk [ 18.859098] sd 2:0:0:0: [sdb] Unhandled sense code [ 18.859103] sd 2:0:0:0: [sdb] [ 18.859106] Result: hostbyte=DID_OK driverbyte=DRIVER_SENSE [ 18.859108] sd 2:0:0:0: [sdb] [ 18.859110] Sense Key : Medium Error [current] [ 18.859114] Info fld=0x1234 [ 18.859116] sd 2:0:0:0: [sdb] [ 18.859119] Add. Sense: Unrecovered read error [ 18.859122] sd 2:0:0:0: [sdb] CDB: [ 18.859124] Read(10): 28 00 00 00 11 e0 00 01 00 00 In a SCSI device driver, sd_print_result() is implemented as follows: sd_print_result() { sd_printk(KERN_INFO, sdkp, " "); scsi_show_result(result); } Here, first sd_printk() outputs "sd 2:0:0:0: [sdb] ", then scsi_show_sense_hdr() outputs "Result: hostbyte=DID_OK driverbyte=DRIVER_SENSE". sd_printk() does not include "\n", but it forcibly starts a new line. Therefore, when the driver outputs error messages, those messages are divided. This patch makes those multiple line messages output in single line as follows: # dmesg [ 17.145085] sdb: unknown partition table [ 17.149096] sd 2:0:0:0: [sdb] Attached SCSI disk [ 18.166090] sd 2:0:0:0: [sdb] Unhandled sense code [ 18.166095] sd 2:0:0:0: [sdb] Result: hostbyte=DID_OK driverbyte=DRIVER_SENSE [ 18.166099] sd 2:0:0:0: [sdb] Sense Key : Medium Error [current] [ 18.166104] Info fld=0x1234 [ 18.166106] sd 2:0:0:0: [sdb] Add. Sense: Unrecovered read error [ 18.166111] sd 2:0:0:0: [sdb] CDB: Read(10): 28 00 00 00 11 e0 00 01 00 00 Signed-off-by: Yoshihiro YUNOMAE Cc: James E.J. Bottomley Cc: Hannes Reinecke Cc: Kay Sievers Cc: linux-kernel@vger.kernel.org Cc: linux-s...@vger.kernel.org --- drivers/scsi/constants.c | 206 -- drivers/scsi/scsi.c | 28 -- drivers/scsi/sd.c| 19 +++- include/scsi/scsi_dbg.h | 23 - 4 files changed, 176 insertions(+), 100 deletions(-) diff --git a/drivers/scsi/constants.c b/drivers/scsi/constants.c index d35a5d6..cb93435 100644 --- a/drivers/scsi/constants.c +++ b/drivers/scsi/constants.c @@ -256,8 +256,26 @@ static const char * get_sa_name(const struct value_name_pair * arr, return (k < arr_sz) ? arr->name : NULL; } +/* Store a SCSI logging event to buf. */ +__printf(2, 3) +void scsi_log_add(struct scsi_log_line *log, const char *fmt, ...) +{ + va_list args; + int len; + + va_start(args, fmt); + len = vscnprintf(log->buf + log->offset, +SCSI_LOG_LINE_MAX - log->offset, fmt, args); + WARN_ONCE(!len, "Cannot store the message '%s' in a local log buffer\n", + fmt); + log->offset += len; + va_end(args); +} +EXPORT_SYMBOL(scsi_log_add); + /* attempt to guess cdb length if cdb_len==0 . No trailing linefeed. */ -static void print_opcode_name(unsigned char * cdbp, int cdb_len) +static void print_opcode_name(unsigned char *cdbp, int cdb_len, + struct scsi_log_line *log) { int sa, len, cdb0; int fin_name = 0; @@ -268,20 +286,22 @@ static void print_opcode_name(unsigned char * cdbp, int cdb_len) case VARIABLE_LENGTH_CMD: len = scsi_varlen_cdb_length(cdbp); if (len < 10) { - printk("short variable length command, " - "len=%d ext_len=%d", len, cdb_len); + scsi_log_add(log, +"short variable length command, len=%d ext_len=%d", +len, cdb_len);
Re: [PATCH] st: use dev_printk() to avoid linebreaks in kernel messages.
Hi Hannes, We want to handle the error message in userland for HA clusters, so the error messages should be output in single(atomic) line. However, current upstream kernel outputs SCSI error messages in multiple lines, so current implementation is inconvenient. Even if human reads the error messages, the split messages are difficult to read. Therefore, the split error messages should be fixed. In order to solve this problem, recently I submitted the patch fixing SCSI error message split[1] to LKML. However, when I read the discussion of you and Maurizio, I noticed that you already have fixed in your branch. When will you send your branch to linux-kernel ML or linux-scsi ML? [1] https://lkml.org/lkml/2014/1/15/926 [2] http://marc.info/?t=13928007191&r=1&w=2 Thank you, Yoshihiro YUNOMAE -- Yoshihiro YUNOMAE Software Platform Research Dept. Linux Technology Center Hitachi, Ltd., Yokohama Research Laboratory E-mail: yoshihiro.yunomae...@hitachi.com -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[PATCH V2 2/2] ftrace: Introduce nr_saved_cmdlines I/F
Introduce nr_saved_cmdlines I/F for changing the number of pid-comm list. saved_cmdlines can store 128 command names using SAVED_CMDLINES now, but 'no-existing processes' names are often lost in saved_cmdlines when we read trace data. So, by introducing nr_saved_cmdlines I/F, the rule storing 128 command names is changed to the command numbers defined users. When we write a value to nr_saved_cmdlines, the number of the value will be stored in pid-comm list: # echo 1024 > /sys/kernel/debug/tracing/nr_saved_cmdlines Here, 1024 command names are stored. The default number is 128 and the maximum number is PID_MAX_DEFAULT (=32768 if CONFIG_BASE_SMALL is not set). So, if we want to avoid to lose command names, we need to set 32768 to nr_saved_cmdlines. We can read the maximum number of the list: # cat /sys/kernel/debug/tracing/nr_saved_cmdlines 128 Changes in V2: - Fix a racing problem of savedcmd between saved_cmdlines I/F and nr_saved_cmdlines I/F. If one reads saved_cmdlines and writes a value to nr_saved_cmdlines at the same time, then the write returns -EBUSY. [terminal 1] Read saved_cmdlines # while true; do cat saved_cmdlines > /dev/null; done; [terminal 2] Write 1024 to nr_saved_cmdlines # while true; do echo 1024 > nr_saved_cmdlines; done; -bash: echo: write error: Device or resource busy -bash: echo: write error: Device or resource busy -bash: echo: write error: Device or resource busy Signed-off-by: Yoshihiro YUNOMAE Cc: Steven Rostedt Cc: Frederic Weisbecker Cc: Ingo Molnar Cc: linux-kernel@vger.kernel.org --- kernel/trace/trace.c | 233 +- 1 file changed, 210 insertions(+), 23 deletions(-) diff --git a/kernel/trace/trace.c b/kernel/trace/trace.c index b97648aa..0e838bd 100644 --- a/kernel/trace/trace.c +++ b/kernel/trace/trace.c @@ -1293,22 +1293,98 @@ void tracing_reset_all_online_cpus(void) } } -#define SAVED_CMDLINES 128 +#define SAVED_CMDLINES_DEFAULT 128 #define NO_CMDLINE_MAP UINT_MAX -static unsigned map_pid_to_cmdline[PID_MAX_DEFAULT+1]; -static unsigned map_cmdline_to_pid[SAVED_CMDLINES]; -static char saved_cmdlines[SAVED_CMDLINES][TASK_COMM_LEN]; -static int cmdline_idx; static arch_spinlock_t trace_cmdline_lock = __ARCH_SPIN_LOCK_UNLOCKED; +struct saved_cmdlines_buffer { + unsigned map_pid_to_cmdline[PID_MAX_DEFAULT+1]; + unsigned *map_cmdline_to_pid; + unsigned cmdline_num; + unsigned reader; + int cmdline_idx; + char *saved_cmdlines; +}; +static struct saved_cmdlines_buffer *savedcmd; /* temporary disable recording */ static atomic_t trace_record_cmdline_disabled __read_mostly; -static void trace_init_cmdlines(void) +static inline char *get_cmdline(int idx) +{ + return &savedcmd->saved_cmdlines[idx*TASK_COMM_LEN]; +} + +static inline void set_cmdline(int idx, char *cmdline) +{ + memcpy(get_cmdline(idx), cmdline, TASK_COMM_LEN); +} + +static int allocate_cmdlines_buffer(unsigned int val, + struct saved_cmdlines_buffer *s) +{ + s->map_cmdline_to_pid = kmalloc(val*sizeof(unsigned), GFP_KERNEL); + if (!s->map_cmdline_to_pid) + goto out; + + s->saved_cmdlines = kmalloc(val*TASK_COMM_LEN, GFP_KERNEL); + if (!s->saved_cmdlines) + goto out_free_map_cmdline_to_pid; + + return 0; + +out_free_map_cmdline_to_pid: + kfree(s->map_cmdline_to_pid); +out: + return -ENOMEM; +} + +static void trace_init_cmdlines_buffer(unsigned int val, + struct saved_cmdlines_buffer *s) +{ + s->cmdline_idx = 0; + s->cmdline_num = val; + s->reader = 0; + memset(&s->map_pid_to_cmdline, NO_CMDLINE_MAP, + sizeof(s->map_pid_to_cmdline)); + memset(s->map_cmdline_to_pid, NO_CMDLINE_MAP, val*sizeof(unsigned)); +} + +static int trace_create_savedcmd(void) +{ + int ret; + + savedcmd = kmalloc(sizeof(struct saved_cmdlines_buffer), GFP_KERNEL); + if (!savedcmd) + goto out; + + ret = allocate_cmdlines_buffer(SAVED_CMDLINES_DEFAULT, savedcmd); + if (ret < 0) + goto out_free; + + return 0; + +out_free: + kfree(savedcmd); +out: + return -ENOMEM; +} + +static void trace_init_savedcmd(void) +{ + trace_init_cmdlines_buffer(SAVED_CMDLINES_DEFAULT, savedcmd); +} + +static int trace_create_and_init_savedcmd(void) { - memset(&map_pid_to_cmdline, NO_CMDLINE_MAP, sizeof(map_pid_to_cmdline)); - memset(&map_cmdline_to_pid, NO_CMDLINE_MAP, sizeof(map_cmdline_to_pid)); - cmdline_idx = 0; + int ret; + + ret = trace_create_savedcmd(); + if (ret < 0) + return ret; + + trace_init_savedcmd(); + + return 0; } int is_tracing_stopped(void) @@ -1465,9 +1541,9 @@ static vo
[PATCH V2 0/2] ftrace: Introduce the new I/F "nr_saved_cmdlines"
Hi, This patch set introduces the new I/F "nr_saved_cmdlines" for increasing the number of saved cmdlines. Current saved_cmdlines can store just 128 command names and PIDs, but process names are often lost like <...> when we read trace data. If the process exists, we can get the name by using ps command. However, if the process already has not existed, we cannot get the name. To solve this issue, we introduce the new I/F "nr_saved_cmdlines" to expand the max number of saved command line names. This I/F is very simple. If we write a number to nr_saved_cmdlines, the number of command name will be stored. And, if we read the I/F, we can get current maximum number of command name. The default number is 128 which is current default number, so this patch does not change the usage of memory for saved_cmdlines when we boot kernel. Thanks! Changes in V2: - Fix a racing problem of savedcmd between saved_cmdlines I/F and nr_saved_cmdlines I/F. If one reads saved_cmdlines and writes a value to nr_saved_cmdlines at the same time, then the write returns -EBUSY. [2/2] --- Yoshihiro YUNOMAE (2): ftrace: Make saved_cmdlines use seq_read ftrace: Introduce nr_saved_cmdlines I/F kernel/trace/trace.c | 316 +- 1 file changed, 261 insertions(+), 55 deletions(-) -- Yoshihiro YUNOMAE Software Platform Research Dept. Linux Technology Center Hitachi, Ltd., Yokohama Research Laboratory E-mail: yoshihiro.yunomae...@hitachi.com -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[PATCH V2 1/2] ftrace: Make saved_cmdlines use seq_read
Current tracing_saved_cmdlines_read() implementation is naive; simply allocate a big buffer, construct output data on the buffer for each read operation, and then copy a portion of the buffer to the user space buffer. This can cause a couple of issues such as a slow memory allocation, high cpu usage, and a corruption of the output data. To address these issues, make saved_cmdlines use seq_read. Signed-off-by: Hidehiro Kawai Signed-off-by: Yoshihiro YUNOMAE Cc: Steven Rostedt Cc: Frederic Weisbecker Cc: Ingo Molnar Cc: linux-kernel@vger.kernel.org --- kernel/trace/trace.c | 89 ++ 1 file changed, 54 insertions(+), 35 deletions(-) diff --git a/kernel/trace/trace.c b/kernel/trace/trace.c index 815c878..b97648aa 100644 --- a/kernel/trace/trace.c +++ b/kernel/trace/trace.c @@ -3638,55 +3638,74 @@ static const struct file_operations tracing_readme_fops = { .llseek = generic_file_llseek, }; -static ssize_t -tracing_saved_cmdlines_read(struct file *file, char __user *ubuf, - size_t cnt, loff_t *ppos) +static void *saved_cmdlines_next(struct seq_file *m, void *v, loff_t *pos) { - char *buf_comm; - char *file_buf; - char *buf; - int len = 0; - int pid; - int i; + unsigned int *ptr = v; - file_buf = kmalloc(SAVED_CMDLINES*(16+TASK_COMM_LEN), GFP_KERNEL); - if (!file_buf) - return -ENOMEM; + if (*pos || m->count) + ptr++; - buf_comm = kmalloc(TASK_COMM_LEN, GFP_KERNEL); - if (!buf_comm) { - kfree(file_buf); - return -ENOMEM; - } + (*pos)++; + + for (; ptr < &map_cmdline_to_pid[SAVED_CMDLINES]; ptr++) { + if (*ptr == -1 || *ptr == NO_CMDLINE_MAP) + continue; - buf = file_buf; + return ptr; + } - for (i = 0; i < SAVED_CMDLINES; i++) { - int r; + return NULL; +} - pid = map_cmdline_to_pid[i]; - if (pid == -1 || pid == NO_CMDLINE_MAP) - continue; +static void *saved_cmdlines_start(struct seq_file *m, loff_t *pos) +{ + void *v; + loff_t l = 0; - trace_find_cmdline(pid, buf_comm); - r = sprintf(buf, "%d %s\n", pid, buf_comm); - buf += r; - len += r; + v = &map_cmdline_to_pid[0]; + while (l <= *pos) { + v = saved_cmdlines_next(m, v, &l); + if (!v) + return NULL; } - len = simple_read_from_buffer(ubuf, cnt, ppos, - file_buf, len); + return v; +} - kfree(file_buf); - kfree(buf_comm); +static void saved_cmdlines_stop(struct seq_file *m, void *v) +{ +} - return len; +static int saved_cmdlines_show(struct seq_file *m, void *v) +{ + char buf[TASK_COMM_LEN]; + unsigned int *pid = v; + + trace_find_cmdline(*pid, buf); + seq_printf(m, "%d %s\n", *pid, buf); + return 0; +} + +static const struct seq_operations tracing_saved_cmdlines_seq_ops = { + .start = saved_cmdlines_start, + .next = saved_cmdlines_next, + .stop = saved_cmdlines_stop, + .show = saved_cmdlines_show, +}; + +static int tracing_saved_cmdlines_open(struct inode *inode, struct file *filp) +{ + if (tracing_disabled) + return -ENODEV; + + return seq_open(filp, &tracing_saved_cmdlines_seq_ops); } static const struct file_operations tracing_saved_cmdlines_fops = { -.open = tracing_open_generic, -.read = tracing_saved_cmdlines_read, -.llseek= generic_file_llseek, + .open = tracing_saved_cmdlines_open, + .read = seq_read, + .llseek = seq_lseek, + .release= seq_release, }; static ssize_t -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
Re: [PATCH V2] serial/uart: Add tunable RX interrupt trigger I/F of FIFO buffers
Hi Alan, Thank you for your reply. (2014/02/18 0:12), One Thousand Gnomes wrote: According to HW specification of serial UART devices, RX interrupt trigger can be changed, but the trigger is hard-coded. For example, RX interrupt trigger in 16550A can be set to 1, 4, 8, or 14 bytes for HW, but current driver sets the trigger to only 8bytes. This patch makes a 16550A device change RX interrupt trigger from userland. We probably need to be much smarter about how we set this as lots of non 16550A type devices have a tunable trigger. We tune it dynamically based upon baud rate for many platforms, and we turn it on and off according to low latency settings. In other words we can't just have an ioctl poking values about in parallel and without any locking. You're right. If a user sets low_latency using ioctl() on an 8250 device, serial8250_clear_fifos() initializing FCR will be executed. So, my approach which does not get lock is inappropriate. For the API IMHO this really belongs in sysfs IMHO. That does mean we need to turn the existing sysfs API read/write by adding a few set methods not just get ones in drivers/tty/serial/ but it would be a lot cleaner and the uart_set_info path does the correct stopping and restarting as well as locking for the fifo size change. As you say, sysfs is more convenient than ioctl for users. Moreover, using uart_set_info() solves the competent problem. So, I'll implement this feature in sysfs. Thank you, Yoshihiro YUNOMAE -- Yoshihiro YUNOMAE Software Platform Research Dept. Linux Technology Center Hitachi, Ltd., Yokohama Research Laboratory E-mail: yoshihiro.yunomae...@hitachi.com -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
Re: Re: [PATCH -tip RESEND 2/2] ftrace: Introduce nr_saved_cmdlines I/F
Hi Namhyung, (2014/02/17 16:13), Namhyung Kim wrote: > Hi Yoshihiro, > > On Mon, 17 Feb 2014 13:57:13 +0900, Yoshihiro YUNOMAE wrote: >> Hi Namhyung, >> >> (2014/02/14 13:50), Namhyung Kim wrote: >>> Hi Yoshihiro, >>> >>> On Thu, 13 Feb 2014 10:28:58 +0900, Yoshihiro YUNOMAE wrote: >>>> Introduce nr_saved_cmdlines I/F for changing the number of pid-comm list. >>>> saved_cmdlines can store 128 command names using SAVED_CMDLINES now, but >>>> 'no-existing processes' names are often lost in saved_cmdlines when we >>>> read trace data. So, by introducing nr_saved_cmdlines I/F, the rule storing >>>> 128 command names is changed to the command numbers defined users. >>>> >>>> When we write a value to nr_saved_cmdlines, the number of the value will >>>> be stored in pid-comm list: >>>> >>>># echo 1024 > /sys/kernel/debug/tracing/nr_saved_cmdlines >>>> >>>> Here, 1024 command names are stored. The default number is 128 and the >>>> maximum >>>> number is PID_MAX_DEFAULT (=32768 if CONFIG_BASE_SMALL is not set). So, if >>>> we >>>> want to avoid to lose command names, we need to set 32768 to >>>> nr_saved_cmdlines. >>>> >>>> We can read the maximum number of the list: >>>> >>>># cat /sys/kernel/debug/tracing/nr_saved_cmdlines >>>>128 >>> >>> [SNIP] >>>> @@ -3685,7 +3760,8 @@ static void *saved_cmdlines_next(struct seq_file *m, >>>> void *v, loff_t *pos) >>>> >>>>(*pos)++; >>>> >>>> - for (; ptr < &map_cmdline_to_pid[SAVED_CMDLINES]; ptr++) { >>>> + for (; ptr < &savedcmd->map_cmdline_to_pid[savedcmd->cmdline_num]; >>>> + ptr++) { >>>>if (*ptr == -1 || *ptr == NO_CMDLINE_MAP) >>>>continue; >>>> >>>> @@ -3700,7 +3776,7 @@ static void *saved_cmdlines_start(struct seq_file >>>> *m, loff_t *pos) >>>>void *v; >>>>loff_t l = 0; >>>> >>>> - v = &map_cmdline_to_pid[0]; >>>> + v = &savedcmd->map_cmdline_to_pid[0]; >>>>while (l <= *pos) { >>>>v = saved_cmdlines_next(m, v, &l); >>>>if (!v) >>> >>> Are you accessing the savecmd without trace_cmdline_lock? >> >> It does not need to get trace_cmdline_lock here. >> The elements of map_pid_to_cmdline[] and saved_cmdlines[] are protected >> by trace_cmdline_lock in trace_find_cmdline(), but on the other hand >> map_cmdline_to_pid[] are not protected. There are no problems in >> particular. This is because map_cmdline_to_pid[] always refers to a >> valid process name or "<...>". > > I don't get it. What does protect the savedcmd from being changed > during reading "saved_cmdlines" file with changing "nr_saved_cmdlines"? Ah, that's true. As you say, this implementation can cause the competition problem. I'll fix it in V2. Thank you, Yoshihiro YUNOMAE -- Yoshihiro YUNOMAE Software Platform Research Dept. Linux Technology Center Hitachi, Ltd., Yokohama Research Laboratory E-mail: yoshihiro.yunomae...@hitachi.com -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
Re: Re: [PATCH -tip RESEND 2/2] ftrace: Introduce nr_saved_cmdlines I/F
Hi Namhyung, (2014/02/14 13:50), Namhyung Kim wrote: > Hi Yoshihiro, > > On Thu, 13 Feb 2014 10:28:58 +0900, Yoshihiro YUNOMAE wrote: >> Introduce nr_saved_cmdlines I/F for changing the number of pid-comm list. >> saved_cmdlines can store 128 command names using SAVED_CMDLINES now, but >> 'no-existing processes' names are often lost in saved_cmdlines when we >> read trace data. So, by introducing nr_saved_cmdlines I/F, the rule storing >> 128 command names is changed to the command numbers defined users. >> >> When we write a value to nr_saved_cmdlines, the number of the value will >> be stored in pid-comm list: >> >> # echo 1024 > /sys/kernel/debug/tracing/nr_saved_cmdlines >> >> Here, 1024 command names are stored. The default number is 128 and the >> maximum >> number is PID_MAX_DEFAULT (=32768 if CONFIG_BASE_SMALL is not set). So, if we >> want to avoid to lose command names, we need to set 32768 to >> nr_saved_cmdlines. >> >> We can read the maximum number of the list: >> >> # cat /sys/kernel/debug/tracing/nr_saved_cmdlines >> 128 > > [SNIP] >> @@ -3685,7 +3760,8 @@ static void *saved_cmdlines_next(struct seq_file *m, >> void *v, loff_t *pos) >> >> (*pos)++; >> >> -for (; ptr < &map_cmdline_to_pid[SAVED_CMDLINES]; ptr++) { >> +for (; ptr < &savedcmd->map_cmdline_to_pid[savedcmd->cmdline_num]; >> + ptr++) { >> if (*ptr == -1 || *ptr == NO_CMDLINE_MAP) >> continue; >> >> @@ -3700,7 +3776,7 @@ static void *saved_cmdlines_start(struct seq_file *m, >> loff_t *pos) >> void *v; >> loff_t l = 0; >> >> -v = &map_cmdline_to_pid[0]; >> +v = &savedcmd->map_cmdline_to_pid[0]; >> while (l <= *pos) { >> v = saved_cmdlines_next(m, v, &l); >> if (!v) > > Are you accessing the savecmd without trace_cmdline_lock? It does not need to get trace_cmdline_lock here. The elements of map_pid_to_cmdline[] and saved_cmdlines[] are protected by trace_cmdline_lock in trace_find_cmdline(), but on the other hand map_cmdline_to_pid[] are not protected. There are no problems in particular. This is because map_cmdline_to_pid[] always refers to a valid process name or "<...>". Note that we can always get process names by setting nr_saved_cmdlines to maximum number if we want to avoid to get "<...>". Thank you, Yoshihiro YUNOMAE -- Yoshihiro YUNOMAE Software Platform Research Dept. Linux Technology Center Hitachi, Ltd., Yokohama Research Laboratory E-mail: yoshihiro.yunomae...@hitachi.com -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[PATCH V2] serial/uart: Add tunable RX interrupt trigger I/F of FIFO buffers
Add tunable RX interrupt trigger I/F of FIFO buffers. Serial devices are used as not only message communication devices but control or sending communication devices. For the latter uses, normally small data will be exchanged, so user applications want to receive data unit as soon as possible for real-time tendency. If we have a sensor which sends a 1 byte data each time and must control a device based on the sensor feedback, the RX interrupt should be triggered for each data. According to HW specification of serial UART devices, RX interrupt trigger can be changed, but the trigger is hard-coded. For example, RX interrupt trigger in 16550A can be set to 1, 4, 8, or 14 bytes for HW, but current driver sets the trigger to only 8bytes. This patch makes a 16550A device change RX interrupt trigger from userland. unsigned char rx_trig_byte = 1; fd = open(TTY_PASS, O_RDWR | O_NONBLOCK); ioctl(fd, TIOCSFIFOTRIG, rx_trig_byte); read(fd, buf, size); - 16550A (1, 4, 8, or 14 bytes) Changed in V2: - Use _IOW for TIOCSFIFORTRIG definition - Pass the interrupt trigger value itself Signed-off-by: Yoshihiro YUNOMAE Cc: Greg Kroah-Hartman --- drivers/tty/serial/8250/8250_core.c | 58 +++ include/uapi/asm-generic/ioctls.h |1 + 2 files changed, 59 insertions(+) diff --git a/drivers/tty/serial/8250/8250_core.c b/drivers/tty/serial/8250/8250_core.c index 61ecd70..429f3a6 100644 --- a/drivers/tty/serial/8250/8250_core.c +++ b/drivers/tty/serial/8250/8250_core.c @@ -2699,6 +2699,63 @@ serial8250_verify_port(struct uart_port *port, struct serial_struct *ser) return 0; } +static int convert_val2rxtrig(struct uart_8250_port *up, unsigned char val) +{ + switch (up->port.type) { + case PORT_16550A: + if (val == 1) + return UART_FCR_R_TRIG_00; + else if (val == 4) + return UART_FCR_R_TRIG_01; + else if (val == 8) + return UART_FCR_R_TRIG_10; + else if (val == 14) + return UART_FCR_R_TRIG_11; + break; + default: + pr_info("Not support RX-trigger setting for this serial %u\n", + up->port.type); + } + return -EINVAL; +} + +static int set_fifo_rx_trigger(struct uart_8250_port *up, unsigned char val) +{ + unsigned char fcr; + int rx_trig; + + rx_trig = convert_val2rxtrig(up, val); + if (rx_trig < 0) + return rx_trig; + + fcr = uart_config[up->port.type].fcr; + serial8250_clear_fifos(up); + fcr &= ~UART_FCR_TRIGGER_MASK; + fcr |= (unsigned char)rx_trig; + serial_out(up, UART_FCR, fcr); + return 0; +} + +static int +serial8250_ioctl(struct uart_port *port, unsigned int cmd, unsigned long arg) +{ + struct uart_8250_port *up = + container_of(port, struct uart_8250_port, port); + int ret; + + if (!(up->capabilities & UART_CAP_FIFO) || port->fifosize <= 1) + return -EINVAL; + + switch (cmd) { + case TIOCSFIFORTRIG: + ret = set_fifo_rx_trigger(up, (unsigned char)arg); + break; + default: + ret = -ENOIOCTLCMD; + } + return ret; +} + static const char * serial8250_type(struct uart_port *port) { @@ -2728,6 +2785,7 @@ static struct uart_ops serial8250_pops = { .request_port = serial8250_request_port, .config_port= serial8250_config_port, .verify_port= serial8250_verify_port, + .ioctl = serial8250_ioctl, #ifdef CONFIG_CONSOLE_POLL .poll_get_char = serial8250_get_poll_char, .poll_put_char = serial8250_put_poll_char, diff --git a/include/uapi/asm-generic/ioctls.h b/include/uapi/asm-generic/ioctls.h index 143dacb..9504dca 100644 --- a/include/uapi/asm-generic/ioctls.h +++ b/include/uapi/asm-generic/ioctls.h @@ -77,6 +77,7 @@ #define TIOCGPKT _IOR('T', 0x38, int) /* Get packet mode state */ #define TIOCGPTLCK _IOR('T', 0x39, int) /* Get Pty lock state */ #define TIOCGEXCL _IOR('T', 0x40, int) /* Get exclusive mode state */ +#define TIOCSFIFORTRIG _IOW('T', 0x41, unsigned char) /* Set RX int. trigger */ #define FIONCLEX 0x5450 #define FIOCLEX0x5451 -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
Re: [PATCH] serial/uart: Add tunable RX interrupt trigger I/F of FIFO buffers
Hi Greg, Thank you for your reply. [snip] diff --git a/include/uapi/asm-generic/ioctls.h b/include/uapi/asm-generic/ioctls.h index 143dacb..d2e56a4 100644 --- a/include/uapi/asm-generic/ioctls.h +++ b/include/uapi/asm-generic/ioctls.h @@ -78,6 +78,8 @@ #define TIOCGPTLCK_IOR('T', 0x39, int) /* Get Pty lock state */ #define TIOCGEXCL _IOR('T', 0x40, int) /* Get exclusive mode state */ +#define TIOCSFIFORTRIG 0x5441 Please define this as a "proper" ioctl command by using the correct IO* macros. OK. I'll use _IOW as follows: #define TIOCSFIFORTRIG_IOW('T', 0x41, unsigned char) Also, why pass a pointer to a variable, and not just the value itself? Ah, it's no big reason. It will pass just the value itself in V2. And are you sure there's no other way to do this already? It's odd that no one else has ever hit this before... According to a manual of setserial command, we could set RX interrupt trigger only for the Hayes ESP serial driver. However, current kernel does not support Hayes ESP serial[1]. I couldn't find this feature for current 8250/16X50 drivers. [1] https://lkml.org/lkml/2009/12/11/500 Thanks, Yoshihiro YUNOMAE -- Yoshihiro YUNOMAE Software Platform Research Dept. Linux Technology Center Hitachi, Ltd., Yokohama Research Laboratory E-mail: yoshihiro.yunomae...@hitachi.com -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[PATCH -tip RESEND 1/2] ftrace: Make saved_cmdlines use seq_read
Current tracing_saved_cmdlines_read() implementation is naive; simply allocate a big buffer, construct output data on the buffer for each read operation, and then copy a portion of the buffer to the user space buffer. This can cause a couple of issues such as a slow memory allocation, high cpu usage, and a corruption of the output data. To address these issues, make saved_cmdlines use seq_read. Signed-off-by: Hidehiro Kawai Signed-off-by: Yoshihiro YUNOMAE Cc: Steven Rostedt Cc: Frederic Weisbecker Cc: Ingo Molnar Cc: linux-kernel@vger.kernel.org --- kernel/trace/trace.c | 89 ++ 1 file changed, 54 insertions(+), 35 deletions(-) diff --git a/kernel/trace/trace.c b/kernel/trace/trace.c index 6a9212d..f930f4d 100644 --- a/kernel/trace/trace.c +++ b/kernel/trace/trace.c @@ -3676,55 +3676,74 @@ static const struct file_operations tracing_readme_fops = { .llseek = generic_file_llseek, }; -static ssize_t -tracing_saved_cmdlines_read(struct file *file, char __user *ubuf, - size_t cnt, loff_t *ppos) +static void *saved_cmdlines_next(struct seq_file *m, void *v, loff_t *pos) { - char *buf_comm; - char *file_buf; - char *buf; - int len = 0; - int pid; - int i; + unsigned int *ptr = v; - file_buf = kmalloc(SAVED_CMDLINES*(16+TASK_COMM_LEN), GFP_KERNEL); - if (!file_buf) - return -ENOMEM; + if (*pos || m->count) + ptr++; - buf_comm = kmalloc(TASK_COMM_LEN, GFP_KERNEL); - if (!buf_comm) { - kfree(file_buf); - return -ENOMEM; - } + (*pos)++; + + for (; ptr < &map_cmdline_to_pid[SAVED_CMDLINES]; ptr++) { + if (*ptr == -1 || *ptr == NO_CMDLINE_MAP) + continue; - buf = file_buf; + return ptr; + } - for (i = 0; i < SAVED_CMDLINES; i++) { - int r; + return NULL; +} - pid = map_cmdline_to_pid[i]; - if (pid == -1 || pid == NO_CMDLINE_MAP) - continue; +static void *saved_cmdlines_start(struct seq_file *m, loff_t *pos) +{ + void *v; + loff_t l = 0; - trace_find_cmdline(pid, buf_comm); - r = sprintf(buf, "%d %s\n", pid, buf_comm); - buf += r; - len += r; + v = &map_cmdline_to_pid[0]; + while (l <= *pos) { + v = saved_cmdlines_next(m, v, &l); + if (!v) + return NULL; } - len = simple_read_from_buffer(ubuf, cnt, ppos, - file_buf, len); + return v; +} - kfree(file_buf); - kfree(buf_comm); +static void saved_cmdlines_stop(struct seq_file *m, void *v) +{ +} - return len; +static int saved_cmdlines_show(struct seq_file *m, void *v) +{ + char buf[TASK_COMM_LEN]; + unsigned int *pid = v; + + trace_find_cmdline(*pid, buf); + seq_printf(m, "%d %s\n", *pid, buf); + return 0; +} + +static const struct seq_operations tracing_saved_cmdlines_seq_ops = { + .start = saved_cmdlines_start, + .next = saved_cmdlines_next, + .stop = saved_cmdlines_stop, + .show = saved_cmdlines_show, +}; + +static int tracing_saved_cmdlines_open(struct inode *inode, struct file *filp) +{ + if (tracing_disabled) + return -ENODEV; + + return seq_open(filp, &tracing_saved_cmdlines_seq_ops); } static const struct file_operations tracing_saved_cmdlines_fops = { -.open = tracing_open_generic, -.read = tracing_saved_cmdlines_read, -.llseek= generic_file_llseek, + .open = tracing_saved_cmdlines_open, + .read = seq_read, + .llseek = seq_lseek, + .release= seq_release, }; static ssize_t -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[PATCH -tip RESEND 0/2] ftrace: Introduce the new I/F "nr_saved_cmdlines"
Hi Steven, This patch set introduces the new I/F "nr_saved_cmdlines" for increasing the number of saved cmdlines. Current saved_cmdlines can store just 128 command names and PIDs, but process names are often lost like <...> when we read trace data. If the process exists, we can get the name by using ps command. However, if the process already has not existed, we cannot get the name. To solve this issue, we introduce the new I/F "nr_saved_cmdlines" to expand the max number of saved command line names. This I/F is very simple. If we write a number to nr_saved_cmdlines, the number of command name will be stored. And, if we read the I/F, we can get current maximum number of command name. The default number is 128 which is current default number, so this patch does not change the usage of memory for saved_cmdlines when we boot kernel. Thanks! Note: This patch set was rebased for current tip ftrace-core kernel. --- Yoshihiro YUNOMAE (2): ftrace: Make saved_cmdlines use seq_read ftrace: Introduce nr_saved_cmdlines I/F kernel/trace/trace.c | 296 +- 1 file changed, 241 insertions(+), 55 deletions(-) -- Yoshihiro YUNOMAE Software Platform Research Dept. Linux Technology Center Hitachi, Ltd., Yokohama Research Laboratory E-mail: yoshihiro.yunomae...@hitachi.com -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[PATCH -tip RESEND 2/2] ftrace: Introduce nr_saved_cmdlines I/F
Introduce nr_saved_cmdlines I/F for changing the number of pid-comm list. saved_cmdlines can store 128 command names using SAVED_CMDLINES now, but 'no-existing processes' names are often lost in saved_cmdlines when we read trace data. So, by introducing nr_saved_cmdlines I/F, the rule storing 128 command names is changed to the command numbers defined users. When we write a value to nr_saved_cmdlines, the number of the value will be stored in pid-comm list: # echo 1024 > /sys/kernel/debug/tracing/nr_saved_cmdlines Here, 1024 command names are stored. The default number is 128 and the maximum number is PID_MAX_DEFAULT (=32768 if CONFIG_BASE_SMALL is not set). So, if we want to avoid to lose command names, we need to set 32768 to nr_saved_cmdlines. We can read the maximum number of the list: # cat /sys/kernel/debug/tracing/nr_saved_cmdlines 128 Signed-off-by: Yoshihiro YUNOMAE Cc: Steven Rostedt Cc: Frederic Weisbecker Cc: Ingo Molnar Cc: linux-kernel@vger.kernel.org --- kernel/trace/trace.c | 211 +- 1 file changed, 189 insertions(+), 22 deletions(-) diff --git a/kernel/trace/trace.c b/kernel/trace/trace.c index f930f4d..e7d292a 100644 --- a/kernel/trace/trace.c +++ b/kernel/trace/trace.c @@ -1294,22 +1294,96 @@ void tracing_reset_all_online_cpus(void) } } -#define SAVED_CMDLINES 128 +#define SAVED_CMDLINES_DEFAULT 128 #define NO_CMDLINE_MAP UINT_MAX -static unsigned map_pid_to_cmdline[PID_MAX_DEFAULT+1]; -static unsigned map_cmdline_to_pid[SAVED_CMDLINES]; -static char saved_cmdlines[SAVED_CMDLINES][TASK_COMM_LEN]; -static int cmdline_idx; static arch_spinlock_t trace_cmdline_lock = __ARCH_SPIN_LOCK_UNLOCKED; +struct saved_cmdlines_buffer { + unsigned map_pid_to_cmdline[PID_MAX_DEFAULT+1]; + unsigned *map_cmdline_to_pid; + unsigned cmdline_num; + int cmdline_idx; + char *saved_cmdlines; +}; +static struct saved_cmdlines_buffer *savedcmd; /* temporary disable recording */ static atomic_t trace_record_cmdline_disabled __read_mostly; -static void trace_init_cmdlines(void) +static inline char *get_cmdline(int idx) +{ + return &savedcmd->saved_cmdlines[idx*TASK_COMM_LEN]; +} + +static inline void set_cmdline(int idx, char *cmdline) +{ + memcpy(get_cmdline(idx), cmdline, TASK_COMM_LEN); +} + +static int allocate_cmdlines_buffer(unsigned int val, + struct saved_cmdlines_buffer *s) { - memset(&map_pid_to_cmdline, NO_CMDLINE_MAP, sizeof(map_pid_to_cmdline)); - memset(&map_cmdline_to_pid, NO_CMDLINE_MAP, sizeof(map_cmdline_to_pid)); - cmdline_idx = 0; + s->map_cmdline_to_pid = kmalloc(val*sizeof(unsigned), GFP_KERNEL); + if (!s->map_cmdline_to_pid) + goto out; + + s->saved_cmdlines = kmalloc(val*TASK_COMM_LEN, GFP_KERNEL); + if (!s->saved_cmdlines) + goto out_free_map_cmdline_to_pid; + + return 0; + +out_free_map_cmdline_to_pid: + kfree(s->map_cmdline_to_pid); +out: + return -ENOMEM; +} + +static void trace_init_cmdlines_buffer(unsigned int val, + struct saved_cmdlines_buffer *s) +{ + s->cmdline_idx = 0; + s->cmdline_num = val; + memset(&s->map_pid_to_cmdline, NO_CMDLINE_MAP, + sizeof(s->map_pid_to_cmdline)); + memset(s->map_cmdline_to_pid, NO_CMDLINE_MAP, val*sizeof(unsigned)); +} + +static int trace_create_savedcmd(void) +{ + int ret; + + savedcmd = kmalloc(sizeof(struct saved_cmdlines_buffer), GFP_KERNEL); + if (!savedcmd) + goto out; + + ret = allocate_cmdlines_buffer(SAVED_CMDLINES_DEFAULT, savedcmd); + if (ret < 0) + goto out_free; + + return 0; + +out_free: + kfree(savedcmd); +out: + return -ENOMEM; +} + +static void trace_init_savedcmd(void) +{ + trace_init_cmdlines_buffer(SAVED_CMDLINES_DEFAULT, savedcmd); +} + +static int trace_create_and_init_savedcmd(void) +{ + int ret; + + ret = trace_create_savedcmd(); + if (ret < 0) + return ret; + + trace_init_savedcmd(); + + return 0; } int is_tracing_stopped(void) @@ -1466,9 +1540,9 @@ static void trace_save_cmdline(struct task_struct *tsk) if (!arch_spin_trylock(&trace_cmdline_lock)) return; - idx = map_pid_to_cmdline[tsk->pid]; + idx = savedcmd->map_pid_to_cmdline[tsk->pid]; if (idx == NO_CMDLINE_MAP) { - idx = (cmdline_idx + 1) % SAVED_CMDLINES; + idx = (savedcmd->cmdline_idx + 1) % savedcmd->cmdline_num; /* * Check whether the cmdline buffer at idx has a pid @@ -1476,17 +1550,17 @@ static void trace_save_cmdline(struct task_struct *tsk) * need to clear the map_
[PATCH] serial/uart: Add tunable RX interrupt trigger I/F of FIFO buffers
Add tunable RX interrupt trigger I/F of FIFO buffers. Serial devices are used as not only message communication devices but control or sending communication devices. For the latter uses, normally small data will be exchanged, so user applications want to receive data unit as soon as possible for real-time tendency. If we have a sensor which sends a 1 byte data each time and must control a device based on the sensor feedback, the RX interrupt should be triggered for each data. According to HW specification of serial UART devices, RX interrupt trigger can be changed, but the trigger is hard-coded. For example, RX interrupt trigger in 16550A can be set to 1, 4, 8, or 14 bytes for HW, but current driver sets the trigger to only 8bytes. This patch makes a 16550A device change RX interrupt trigger from userland. unsigned char rx_trig_byte = 1; fd = open(TTY_PASS, O_RDWR | O_NONBLOCK); ioctl(fd, TIOCSFIFOTRIG, &rx_trig_byte); read(fd, buf, size); - 16550A (1, 4, 8, or 14 bytes) Signed-off-by: Yoshihiro YUNOMAE Cc: Greg Kroah-Hartman --- drivers/tty/serial/8250/8250_core.c | 63 +++ include/uapi/asm-generic/ioctls.h |2 + 2 files changed, 65 insertions(+) diff --git a/drivers/tty/serial/8250/8250_core.c b/drivers/tty/serial/8250/8250_core.c index 61ecd70..f51637a 100644 --- a/drivers/tty/serial/8250/8250_core.c +++ b/drivers/tty/serial/8250/8250_core.c @@ -2699,6 +2699,68 @@ serial8250_verify_port(struct uart_port *port, struct serial_struct *ser) return 0; } +static int convert_val2rxtrig(struct uart_8250_port *up, unsigned char val) +{ + switch (up->port.type) { + case PORT_16550A: + if (val == 1) + return UART_FCR_R_TRIG_00; + else if (val == 4) + return UART_FCR_R_TRIG_01; + else if (val == 8) + return UART_FCR_R_TRIG_10; + else if (val == 14) + return UART_FCR_R_TRIG_11; + break; + default: + pr_info("Not support RX-trigger setting for this serial %u\n", + up->port.type); + } + return -EINVAL; +} + +static int set_fifo_rx_trigger(struct uart_8250_port *up, + unsigned char __user *uval) +{ + unsigned char fcr, val; + int rx_trig; + + if (copy_from_user(&val, uval, sizeof(unsigned char))) + return -EFAULT; + + rx_trig = convert_val2rxtrig(up, val); + if (rx_trig < 0) + return rx_trig; + + fcr = uart_config[up->port.type].fcr; + serial8250_clear_fifos(up); + fcr &= ~UART_FCR_TRIGGER_MASK; + fcr |= (unsigned char)rx_trig; + serial_out(up, UART_FCR, fcr); + return 0; +} + +static int +serial8250_ioctl(struct uart_port *port, unsigned int cmd, unsigned long arg) +{ + struct uart_8250_port *up = + container_of(port, struct uart_8250_port, port); + void __user *uarg = (void __user *)arg; + int ret; + + if (!(up->capabilities & UART_CAP_FIFO) || port->fifosize <= 1) + return -EINVAL; + + switch (cmd) { + case TIOCSFIFORTRIG: + ret = set_fifo_rx_trigger(up, uarg); + break; + default: + ret = -ENOIOCTLCMD; + } + return ret; +} + static const char * serial8250_type(struct uart_port *port) { @@ -2728,6 +2790,7 @@ static struct uart_ops serial8250_pops = { .request_port = serial8250_request_port, .config_port= serial8250_config_port, .verify_port= serial8250_verify_port, + .ioctl = serial8250_ioctl, #ifdef CONFIG_CONSOLE_POLL .poll_get_char = serial8250_get_poll_char, .poll_put_char = serial8250_put_poll_char, diff --git a/include/uapi/asm-generic/ioctls.h b/include/uapi/asm-generic/ioctls.h index 143dacb..d2e56a4 100644 --- a/include/uapi/asm-generic/ioctls.h +++ b/include/uapi/asm-generic/ioctls.h @@ -78,6 +78,8 @@ #define TIOCGPTLCK _IOR('T', 0x39, int) /* Get Pty lock state */ #define TIOCGEXCL _IOR('T', 0x40, int) /* Get exclusive mode state */ +#define TIOCSFIFORTRIG 0x5441 + #define FIONCLEX 0x5450 #define FIOCLEX0x5451 #define FIOASYNC 0x5452 -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[PATCH] scsi: Output error messages using structured printk in single line
Output error messages using structured printk in single line. In SCSI drivers, some error messages which should be output in single line are divided in multiple lines. When user tools handle the error messages, those divided messages will create some inconveniences. The reason why this problem is induced is structured printk for error messages. Structured printk can add device information for printk, and it is used in scmd_printk() and sd_printk(). The printk aims at output in atomic, so we cannot use those functions for connecting multiple messages like KERN_CONT. However, some error messages is implemented as follows: structured_printk("DEVICE INFORMATION:"); printk(KERN_CONT, "DETAIL INFORMATION\n"); This implementation will be expected to output like "DEVICE INFORMATION: DETAIL INFORMATION", but actually, this will be output as follows: DEVICE INFORMATION: DETAIL INFORMATION For instance, in a following pseudo SCSI error test, the device information and the detail information are divided: -- Pseudo SCSI error test for current kernel # modprobe scsi_debug # cd /sys/bus/pseudo/drivers/scsi_debug # echo 2 > opts # dd if=/dev/sdb of=/dev/null 2> /dev/null -- Result for current kernel # dmesg [ 17.842110] sd 2:0:0:0: [sdb] Attached SCSI disk [ 18.859098] sd 2:0:0:0: [sdb] Unhandled sense code [ 18.859103] sd 2:0:0:0: [sdb] [ 18.859106] Result: hostbyte=DID_OK driverbyte=DRIVER_SENSE [ 18.859108] sd 2:0:0:0: [sdb] [ 18.859110] Sense Key : Medium Error [current] [ 18.859114] Info fld=0x1234 [ 18.859116] sd 2:0:0:0: [sdb] [ 18.859119] Add. Sense: Unrecovered read error [ 18.859122] sd 2:0:0:0: [sdb] CDB: [ 18.859124] Read(10): 28 00 00 00 11 e0 00 01 00 00 In a SCSI device driver, sd_print_result() is implemented as follows: sd_print_result() { sd_printk(KERN_INFO, sdkp, " "); scsi_show_result(result); } Here, first sd_printk() outputs "sd 2:0:0:0: [sdb] ", then scsi_show_sense_hdr() outputs "Result: hostbyte=DID_OK driverbyte=DRIVER_SENSE". sd_printk() does not include "\n", but it forcibly starts a new line. Therefore, when the driver outputs error messages, those messages are divided. This patch makes those multiple line messages output in single line as follows: # dmesg [ 17.145085] sdb: unknown partition table [ 17.149096] sd 2:0:0:0: [sdb] Attached SCSI disk [ 18.166090] sd 2:0:0:0: [sdb] Unhandled sense code [ 18.166095] sd 2:0:0:0: [sdb] Result: hostbyte=DID_OK driverbyte=DRIVER_SENSE [ 18.166099] sd 2:0:0:0: [sdb] Sense Key : Medium Error [current] [ 18.166104] Info fld=0x1234 [ 18.166106] sd 2:0:0:0: [sdb] Add. Sense: Unrecovered read error [ 18.166111] sd 2:0:0:0: [sdb] CDB: Read(10): 28 00 00 00 11 e0 00 01 00 00 Signed-off-by: Yoshihiro YUNOMAE Cc: "James E.J. Bottomley" Cc: Kay Sievers Cc: linux-kernel@vger.kernel.org --- drivers/scsi/constants.c | 206 -- drivers/scsi/scsi.c | 28 -- drivers/scsi/sd.c| 19 +++- include/scsi/scsi_dbg.h | 23 - 4 files changed, 176 insertions(+), 100 deletions(-) diff --git a/drivers/scsi/constants.c b/drivers/scsi/constants.c index d35a5d6..a9b51c7 100644 --- a/drivers/scsi/constants.c +++ b/drivers/scsi/constants.c @@ -256,8 +256,26 @@ static const char * get_sa_name(const struct value_name_pair * arr, return (k < arr_sz) ? arr->name : NULL; } +/* Store a SCSI logging event to buf. If buf is NULL, output the event. */ +__printf(2, 3) +void scsi_log_add(struct scsi_log_line *log, const char *fmt, ...) +{ + va_list args; + int len; + + va_start(args, fmt); + len = vscnprintf(log->buf + log->offset, +SCSI_LOG_LINE_MAX - log->offset, fmt, args); + WARN_ONCE(!len, "Cannot store the message '%s' in a local log buffer\n", + fmt); + log->offset += len; + va_end(args); +} +EXPORT_SYMBOL(scsi_log_add); + /* attempt to guess cdb length if cdb_len==0 . No trailing linefeed. */ -static void print_opcode_name(unsigned char * cdbp, int cdb_len) +static void print_opcode_name(unsigned char *cdbp, int cdb_len, + struct scsi_log_line *log) { int sa, len, cdb0; int fin_name = 0; @@ -268,20 +286,22 @@ static void print_opcode_name(unsigned char * cdbp, int cdb_len) case VARIABLE_LENGTH_CMD: len = scsi_varlen_cdb_length(cdbp); if (len < 10) { - printk("short variable length command, " - "len=%d ext_len=%d", len, cdb_len); + scsi_log_add(log, +"short variable length command, len=%d ext_len=%d", +len, cdb_len);