Skip to content

Commit 74caba7

Browse files
jognesspmladek
authored andcommitted
printk: move dictionary keys to dev_printk_info
Dictionaries are only used for SUBSYSTEM and DEVICE properties. The current implementation stores the property names each time they are used. This requires more space than otherwise necessary. Also, because the dictionary entries are currently considered optional, it cannot be relied upon that they are always available, even if the writer wanted to store them. These issues will increase should new dictionary properties be introduced. Rather than storing the subsystem and device properties in the dict ring, introduce a struct dev_printk_info with separate fields to store only the property values. Embed this struct within the struct printk_info to provide guaranteed availability. Signed-off-by: John Ogness <john.ogness@linutronix.de> Reviewed-by: Petr Mladek <pmladek@suse.com> Signed-off-by: Petr Mladek <pmladek@suse.com> Link: https://lore.kernel.org/r/87mu1jl6ne.fsf@jogness.linutronix.de
1 parent cfe2790 commit 74caba7

9 files changed

Lines changed: 164 additions & 160 deletions

File tree

Documentation/admin-guide/kdump/gdbmacros.txt

Lines changed: 33 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -172,13 +172,13 @@ end
172172

173173
define dump_record
174174
set var $desc = $arg0
175-
if ($argc > 1)
176-
set var $prev_flags = $arg1
175+
set var $info = $arg1
176+
if ($argc > 2)
177+
set var $prev_flags = $arg2
177178
else
178179
set var $prev_flags = 0
179180
end
180181

181-
set var $info = &$desc->info
182182
set var $prefix = 1
183183
set var $newline = 1
184184

@@ -237,44 +237,36 @@ define dump_record
237237

238238
# handle dictionary data
239239

240-
set var $begin = $desc->dict_blk_lpos.begin % (1U << prb->dict_data_ring.size_bits)
241-
set var $next = $desc->dict_blk_lpos.next % (1U << prb->dict_data_ring.size_bits)
242-
243-
# handle data-less record
244-
if ($begin & 1)
245-
set var $dict_len = 0
246-
set var $dict = ""
247-
else
248-
# handle wrapping data block
249-
if ($begin > $next)
250-
set var $begin = 0
251-
end
252-
253-
# skip over descriptor id
254-
set var $begin = $begin + sizeof(long)
255-
256-
# handle truncated message
257-
if ($next - $begin < $info->dict_len)
258-
set var $dict_len = $next - $begin
259-
else
260-
set var $dict_len = $info->dict_len
240+
set var $dict = &$info->dev_info.subsystem[0]
241+
set var $dict_len = sizeof($info->dev_info.subsystem)
242+
if ($dict[0] != '\0')
243+
printf " SUBSYSTEM="
244+
set var $idx = 0
245+
while ($idx < $dict_len)
246+
set var $c = $dict[$idx]
247+
if ($c == '\0')
248+
loop_break
249+
else
250+
if ($c < ' ' || $c >= 127 || $c == '\\')
251+
printf "\\x%02x", $c
252+
else
253+
printf "%c", $c
254+
end
255+
end
256+
set var $idx = $idx + 1
261257
end
262-
263-
set var $dict = &prb->dict_data_ring.data[$begin]
258+
printf "\n"
264259
end
265260

266-
if ($dict_len > 0)
261+
set var $dict = &$info->dev_info.device[0]
262+
set var $dict_len = sizeof($info->dev_info.device)
263+
if ($dict[0] != '\0')
264+
printf " DEVICE="
267265
set var $idx = 0
268-
set var $line = 1
269266
while ($idx < $dict_len)
270-
if ($line)
271-
printf " "
272-
set var $line = 0
273-
end
274267
set var $c = $dict[$idx]
275268
if ($c == '\0')
276-
printf "\n"
277-
set var $line = 1
269+
loop_break
278270
else
279271
if ($c < ' ' || $c >= 127 || $c == '\\')
280272
printf "\\x%02x", $c
@@ -288,10 +280,10 @@ define dump_record
288280
end
289281
end
290282
document dump_record
291-
Dump a single record. The first parameter is the descriptor
292-
sequence number, the second is optional and specifies the
293-
previous record's flags, used for properly formatting
294-
continued lines.
283+
Dump a single record. The first parameter is the descriptor,
284+
the second parameter is the info, the third parameter is
285+
optional and specifies the previous record's flags, used for
286+
properly formatting continued lines.
295287
end
296288

297289
define dmesg
@@ -311,12 +303,13 @@ define dmesg
311303

312304
while (1)
313305
set var $desc = &prb->desc_ring.descs[$id % $desc_count]
306+
set var $info = &prb->desc_ring.infos[$id % $desc_count]
314307

315308
# skip non-committed record
316309
set var $state = 3 & ($desc->state_var.counter >> $desc_flags_shift)
317310
if ($state == $desc_committed || $state == $desc_finalized)
318-
dump_record $desc $prev_flags
319-
set var $prev_flags = $desc->info.flags
311+
dump_record $desc $info $prev_flags
312+
set var $prev_flags = $info->flags
320313
end
321314

322315
set var $id = ($id + 1) & $id_mask

drivers/base/core.c

Lines changed: 16 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -3815,22 +3815,21 @@ void device_shutdown(void)
38153815
*/
38163816

38173817
#ifdef CONFIG_PRINTK
3818-
static int
3819-
create_syslog_header(const struct device *dev, char *hdr, size_t hdrlen)
3818+
static void
3819+
set_dev_info(const struct device *dev, struct dev_printk_info *dev_info)
38203820
{
38213821
const char *subsys;
3822-
size_t pos = 0;
3822+
3823+
memset(dev_info, 0, sizeof(*dev_info));
38233824

38243825
if (dev->class)
38253826
subsys = dev->class->name;
38263827
else if (dev->bus)
38273828
subsys = dev->bus->name;
38283829
else
3829-
return 0;
3830+
return;
38303831

3831-
pos += snprintf(hdr + pos, hdrlen - pos, "SUBSYSTEM=%s", subsys);
3832-
if (pos >= hdrlen)
3833-
goto overflow;
3832+
strscpy(dev_info->subsystem, subsys, sizeof(dev_info->subsystem));
38343833

38353834
/*
38363835
* Add device identifier DEVICE=:
@@ -3846,41 +3845,28 @@ create_syslog_header(const struct device *dev, char *hdr, size_t hdrlen)
38463845
c = 'b';
38473846
else
38483847
c = 'c';
3849-
pos++;
3850-
pos += snprintf(hdr + pos, hdrlen - pos,
3851-
"DEVICE=%c%u:%u",
3852-
c, MAJOR(dev->devt), MINOR(dev->devt));
3848+
3849+
snprintf(dev_info->device, sizeof(dev_info->device),
3850+
"%c%u:%u", c, MAJOR(dev->devt), MINOR(dev->devt));
38533851
} else if (strcmp(subsys, "net") == 0) {
38543852
struct net_device *net = to_net_dev(dev);
38553853

3856-
pos++;
3857-
pos += snprintf(hdr + pos, hdrlen - pos,
3858-
"DEVICE=n%u", net->ifindex);
3854+
snprintf(dev_info->device, sizeof(dev_info->device),
3855+
"n%u", net->ifindex);
38593856
} else {
3860-
pos++;
3861-
pos += snprintf(hdr + pos, hdrlen - pos,
3862-
"DEVICE=+%s:%s", subsys, dev_name(dev));
3857+
snprintf(dev_info->device, sizeof(dev_info->device),
3858+
"+%s:%s", subsys, dev_name(dev));
38633859
}
3864-
3865-
if (pos >= hdrlen)
3866-
goto overflow;
3867-
3868-
return pos;
3869-
3870-
overflow:
3871-
dev_WARN(dev, "device/subsystem name too long");
3872-
return 0;
38733860
}
38743861

38753862
int dev_vprintk_emit(int level, const struct device *dev,
38763863
const char *fmt, va_list args)
38773864
{
3878-
char hdr[128];
3879-
size_t hdrlen;
3865+
struct dev_printk_info dev_info;
38803866

3881-
hdrlen = create_syslog_header(dev, hdr, sizeof(hdr));
3867+
set_dev_info(dev, &dev_info);
38823868

3883-
return vprintk_emit(0, level, hdrlen ? hdr : NULL, hdrlen, fmt, args);
3869+
return vprintk_emit(0, level, &dev_info, fmt, args);
38843870
}
38853871
EXPORT_SYMBOL(dev_vprintk_emit);
38863872

include/linux/dev_printk.h

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,14 @@
2121

2222
struct device;
2323

24+
#define PRINTK_INFO_SUBSYSTEM_LEN 16
25+
#define PRINTK_INFO_DEVICE_LEN 48
26+
27+
struct dev_printk_info {
28+
char subsystem[PRINTK_INFO_SUBSYSTEM_LEN];
29+
char device[PRINTK_INFO_DEVICE_LEN];
30+
};
31+
2432
#ifdef CONFIG_PRINTK
2533

2634
__printf(3, 0) __cold

include/linux/printk.h

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -158,10 +158,12 @@ static inline void printk_nmi_direct_enter(void) { }
158158
static inline void printk_nmi_direct_exit(void) { }
159159
#endif /* PRINTK_NMI */
160160

161+
struct dev_printk_info;
162+
161163
#ifdef CONFIG_PRINTK
162-
asmlinkage __printf(5, 0)
164+
asmlinkage __printf(4, 0)
163165
int vprintk_emit(int facility, int level,
164-
const char *dict, size_t dictlen,
166+
const struct dev_printk_info *dev_info,
165167
const char *fmt, va_list args);
166168

167169
asmlinkage __printf(1, 0)

kernel/printk/internal.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,9 +14,9 @@
1414

1515
extern raw_spinlock_t logbuf_lock;
1616

17-
__printf(5, 0)
17+
__printf(4, 0)
1818
int vprintk_store(int facility, int level,
19-
const char *dict, size_t dictlen,
19+
const struct dev_printk_info *dev_info,
2020
const char *fmt, va_list args);
2121

2222
__printf(1, 0) int vprintk_default(const char *fmt, va_list args);

0 commit comments

Comments
 (0)