Commit 81444a79 authored by Ingo Molnar's avatar Ingo Molnar

Merge branch 'tracing/fastboot' into cpus4096

parents a64d31ba da485e0c
...@@ -127,6 +127,8 @@ of ftrace. Here is a list of some of the key files: ...@@ -127,6 +127,8 @@ of ftrace. Here is a list of some of the key files:
be traced. If a function exists in both set_ftrace_filter be traced. If a function exists in both set_ftrace_filter
and set_ftrace_notrace, the function will _not_ be traced. and set_ftrace_notrace, the function will _not_ be traced.
set_ftrace_pid: Have the function tracer only trace a single thread.
available_filter_functions: This lists the functions that ftrace available_filter_functions: This lists the functions that ftrace
has processed and can trace. These are the function has processed and can trace. These are the function
names that you can pass to "set_ftrace_filter" or names that you can pass to "set_ftrace_filter" or
...@@ -1073,6 +1075,83 @@ For simple one time traces, the above is sufficent. For anything else, ...@@ -1073,6 +1075,83 @@ For simple one time traces, the above is sufficent. For anything else,
a search through /proc/mounts may be needed to find where the debugfs a search through /proc/mounts may be needed to find where the debugfs
file-system is mounted. file-system is mounted.
Single thread tracing
---------------------
By writing into /debug/tracing/set_ftrace_pid you can trace a
single thread. For example:
# cat /debug/tracing/set_ftrace_pid
no pid
# echo 3111 > /debug/tracing/set_ftrace_pid
# cat /debug/tracing/set_ftrace_pid
3111
# echo function > /debug/tracing/current_tracer
# cat /debug/tracing/trace | head
# tracer: function
#
# TASK-PID CPU# TIMESTAMP FUNCTION
# | | | | |
yum-updatesd-3111 [003] 1637.254676: finish_task_switch <-thread_return
yum-updatesd-3111 [003] 1637.254681: hrtimer_cancel <-schedule_hrtimeout_range
yum-updatesd-3111 [003] 1637.254682: hrtimer_try_to_cancel <-hrtimer_cancel
yum-updatesd-3111 [003] 1637.254683: lock_hrtimer_base <-hrtimer_try_to_cancel
yum-updatesd-3111 [003] 1637.254685: fget_light <-do_sys_poll
yum-updatesd-3111 [003] 1637.254686: pipe_poll <-do_sys_poll
# echo -1 > /debug/tracing/set_ftrace_pid
# cat /debug/tracing/trace |head
# tracer: function
#
# TASK-PID CPU# TIMESTAMP FUNCTION
# | | | | |
##### CPU 3 buffer started ####
yum-updatesd-3111 [003] 1701.957688: free_poll_entry <-poll_freewait
yum-updatesd-3111 [003] 1701.957689: remove_wait_queue <-free_poll_entry
yum-updatesd-3111 [003] 1701.957691: fput <-free_poll_entry
yum-updatesd-3111 [003] 1701.957692: audit_syscall_exit <-sysret_audit
yum-updatesd-3111 [003] 1701.957693: path_put <-audit_syscall_exit
If you want to trace a function when executing, you could use
something like this simple program:
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
int main (int argc, char **argv)
{
if (argc < 1)
exit(-1);
if (fork() > 0) {
int fd, ffd;
char line[64];
int s;
ffd = open("/debug/tracing/current_tracer", O_WRONLY);
if (ffd < 0)
exit(-1);
write(ffd, "nop", 3);
fd = open("/debug/tracing/set_ftrace_pid", O_WRONLY);
s = sprintf(line, "%d\n", getpid());
write(fd, line, s);
write(ffd, "function", 8);
close(fd);
close(ffd);
execvp(argv[1], argv+1);
}
return 0;
}
dynamic ftrace dynamic ftrace
-------------- --------------
...@@ -1172,7 +1251,11 @@ These are the only wild cards which are supported. ...@@ -1172,7 +1251,11 @@ These are the only wild cards which are supported.
<match>*<match> will not work. <match>*<match> will not work.
# echo hrtimer_* > /debug/tracing/set_ftrace_filter Note: It is better to use quotes to enclose the wild cards, otherwise
the shell may expand the parameters into names of files in the local
directory.
# echo 'hrtimer_*' > /debug/tracing/set_ftrace_filter
Produces: Produces:
...@@ -1227,7 +1310,7 @@ Again, now we want to append. ...@@ -1227,7 +1310,7 @@ Again, now we want to append.
# echo sys_nanosleep > /debug/tracing/set_ftrace_filter # echo sys_nanosleep > /debug/tracing/set_ftrace_filter
# cat /debug/tracing/set_ftrace_filter # cat /debug/tracing/set_ftrace_filter
sys_nanosleep sys_nanosleep
# echo hrtimer_* >> /debug/tracing/set_ftrace_filter # echo 'hrtimer_*' >> /debug/tracing/set_ftrace_filter
# cat /debug/tracing/set_ftrace_filter # cat /debug/tracing/set_ftrace_filter
hrtimer_run_queues hrtimer_run_queues
hrtimer_run_pending hrtimer_run_pending
......
...@@ -51,11 +51,16 @@ to call) for the specific marker through marker_probe_register() and can be ...@@ -51,11 +51,16 @@ to call) for the specific marker through marker_probe_register() and can be
activated by calling marker_arm(). Marker deactivation can be done by calling activated by calling marker_arm(). Marker deactivation can be done by calling
marker_disarm() as many times as marker_arm() has been called. Removing a probe marker_disarm() as many times as marker_arm() has been called. Removing a probe
is done through marker_probe_unregister(); it will disarm the probe. is done through marker_probe_unregister(); it will disarm the probe.
marker_synchronize_unregister() must be called before the end of the module exit
function to make sure there is no caller left using the probe. This, and the marker_synchronize_unregister() must be called between probe unregistration and
fact that preemption is disabled around the probe call, make sure that probe the first occurrence of
removal and module unload are safe. See the "Probe example" section below for a - the end of module exit function,
sample probe module. to make sure there is no caller left using the probe;
- the free of any resource used by the probes,
to make sure the probes wont be accessing invalid data.
This, and the fact that preemption is disabled around the probe call, make sure
that probe removal and module unload are safe. See the "Probe example" section
below for a sample probe module.
The marker mechanism supports inserting multiple instances of the same marker. The marker mechanism supports inserting multiple instances of the same marker.
Markers can be put in inline functions, inlined static functions, and Markers can be put in inline functions, inlined static functions, and
......
...@@ -45,7 +45,7 @@ In include/trace/subsys.h : ...@@ -45,7 +45,7 @@ In include/trace/subsys.h :
#include <linux/tracepoint.h> #include <linux/tracepoint.h>
DECLARE_TRACE(subsys_eventname, DECLARE_TRACE(subsys_eventname,
TPPTOTO(int firstarg, struct task_struct *p), TPPROTO(int firstarg, struct task_struct *p),
TPARGS(firstarg, p)); TPARGS(firstarg, p));
In subsys/file.c (where the tracing statement must be added) : In subsys/file.c (where the tracing statement must be added) :
...@@ -66,7 +66,7 @@ Where : ...@@ -66,7 +66,7 @@ Where :
- subsys is the name of your subsystem. - subsys is the name of your subsystem.
- eventname is the name of the event to trace. - eventname is the name of the event to trace.
- TPPTOTO(int firstarg, struct task_struct *p) is the prototype of the - TPPROTO(int firstarg, struct task_struct *p) is the prototype of the
function called by this tracepoint. function called by this tracepoint.
- TPARGS(firstarg, p) are the parameters names, same as found in the - TPARGS(firstarg, p) are the parameters names, same as found in the
......
...@@ -779,6 +779,7 @@ ATM ...@@ -779,6 +779,7 @@ ATM
P: Chas Williams P: Chas Williams
M: chas@cmf.nrl.navy.mil M: chas@cmf.nrl.navy.mil
L: linux-atm-general@lists.sourceforge.net (subscribers-only) L: linux-atm-general@lists.sourceforge.net (subscribers-only)
L: netdev@vger.kernel.org
W: http://linux-atm.sourceforge.net W: http://linux-atm.sourceforge.net
S: Maintained S: Maintained
...@@ -4235,7 +4236,7 @@ M: dedekind@infradead.org ...@@ -4235,7 +4236,7 @@ M: dedekind@infradead.org
P: Adrian Hunter P: Adrian Hunter
M: ext-adrian.hunter@nokia.com M: ext-adrian.hunter@nokia.com
L: linux-mtd@lists.infradead.org L: linux-mtd@lists.infradead.org
T: git git://git.infradead.org/~dedekind/ubifs-2.6.git T: git git://git.infradead.org/ubifs-2.6.git
W: http://www.linux-mtd.infradead.org/doc/ubifs.html W: http://www.linux-mtd.infradead.org/doc/ubifs.html
S: Maintained S: Maintained
...@@ -4289,7 +4290,7 @@ P: Artem Bityutskiy ...@@ -4289,7 +4290,7 @@ P: Artem Bityutskiy
M: dedekind@infradead.org M: dedekind@infradead.org
W: http://www.linux-mtd.infradead.org/ W: http://www.linux-mtd.infradead.org/
L: linux-mtd@lists.infradead.org L: linux-mtd@lists.infradead.org
T: git git://git.infradead.org/~dedekind/ubi-2.6.git T: git git://git.infradead.org/ubi-2.6.git
S: Maintained S: Maintained
USB ACM DRIVER USB ACM DRIVER
......
...@@ -58,7 +58,7 @@ endif ...@@ -58,7 +58,7 @@ endif
kvm-objs := $(common-objs) kvm-ia64.o kvm_fw.o kvm-objs := $(common-objs) kvm-ia64.o kvm_fw.o
obj-$(CONFIG_KVM) += kvm.o obj-$(CONFIG_KVM) += kvm.o
EXTRA_CFLAGS_vcpu.o += -mfixed-range=f2-f5,f12-f127 CFLAGS_vcpu.o += -mfixed-range=f2-f5,f12-f127
kvm-intel-objs = vmm.o vmm_ivt.o trampoline.o vcpu.o optvfault.o mmio.o \ kvm-intel-objs = vmm.o vmm_ivt.o trampoline.o vcpu.o optvfault.o mmio.o \
vtlb.o process.o vtlb.o process.o
#Add link memcpy and memset to avoid possible structure assignment error #Add link memcpy and memset to avoid possible structure assignment error
......
...@@ -107,10 +107,10 @@ END(kvm_vps_resume_normal) ...@@ -107,10 +107,10 @@ END(kvm_vps_resume_normal)
GLOBAL_ENTRY(kvm_vps_resume_handler) GLOBAL_ENTRY(kvm_vps_resume_handler)
movl r30 = PAL_VPS_RESUME_HANDLER movl r30 = PAL_VPS_RESUME_HANDLER
;; ;;
ld8 r27=[r25] ld8 r26=[r25]
shr r17=r17,IA64_ISR_IR_BIT shr r17=r17,IA64_ISR_IR_BIT
;; ;;
dep r27=r17,r27,63,1 // bit 63 of r27 indicate whether enable CFLE dep r26=r17,r26,63,1 // bit 63 of r26 indicate whether enable CFLE
mov pr=r23,-2 mov pr=r23,-2
br.sptk.many kvm_vps_entry br.sptk.many kvm_vps_entry
END(kvm_vps_resume_handler) END(kvm_vps_resume_handler)
...@@ -894,12 +894,15 @@ ENTRY(kvm_resume_to_guest) ...@@ -894,12 +894,15 @@ ENTRY(kvm_resume_to_guest)
;; ;;
ld8 r19=[r19] ld8 r19=[r19]
mov b0=r29 mov b0=r29
cmp.ne p6,p7 = r0,r0 mov r27=cr.isr
;; ;;
tbit.z p6,p7 = r19,IA64_PSR_IC_BIT // p1=vpsr.ic tbit.z p6,p7 = r19,IA64_PSR_IC_BIT // p7=vpsr.ic
shr r27=r27,IA64_ISR_IR_BIT
;; ;;
(p6) ld8 r26=[r25] (p6) ld8 r26=[r25]
(p7) mov b0=r28 (p7) mov b0=r28
;;
(p6) dep r26=r27,r26,63,1
mov pr=r31,-2 mov pr=r31,-2
br.sptk.many b0 // call pal service br.sptk.many b0 // call pal service
;; ;;
......
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
/* MN10300 Kernel module helper routines /* MN10300 Kernel module helper routines
* *
* Copyright (C) 2007 Red Hat, Inc. All Rights Reserved. * Copyright (C) 2007, 2008 Red Hat, Inc. All Rights Reserved.
* Written by Mark Salter (msalter@redhat.com) * Written by Mark Salter (msalter@redhat.com)
* - Derived from arch/i386/kernel/module.c * - Derived from arch/i386/kernel/module.c
* *
...@@ -64,21 +64,6 @@ int module_frob_arch_sections(Elf_Ehdr *hdr, ...@@ -64,21 +64,6 @@ int module_frob_arch_sections(Elf_Ehdr *hdr,
return 0; return 0;
} }
static uint32_t reloc_get16(uint8_t *p)
{
return p[0] | (p[1] << 8);
}
static uint32_t reloc_get24(uint8_t *p)
{
return reloc_get16(p) | (p[2] << 16);
}
static uint32_t reloc_get32(uint8_t *p)
{
return reloc_get16(p) | (reloc_get16(p+2) << 16);
}
static void reloc_put16(uint8_t *p, uint32_t val) static void reloc_put16(uint8_t *p, uint32_t val)
{ {
p[0] = val & 0xff; p[0] = val & 0xff;
...@@ -144,25 +129,19 @@ int apply_relocate_add(Elf32_Shdr *sechdrs, ...@@ -144,25 +129,19 @@ int apply_relocate_add(Elf32_Shdr *sechdrs,
relocation = sym->st_value + rel[i].r_addend; relocation = sym->st_value + rel[i].r_addend;
switch (ELF32_R_TYPE(rel[i].r_info)) { switch (ELF32_R_TYPE(rel[i].r_info)) {
/* for the first four relocation types, we add the /* for the first four relocation types, we simply
* adjustment into the value at the location given */ * store the adjustment at the location given */
case R_MN10300_32: case R_MN10300_32:
value = reloc_get32(location); reloc_put32(location, relocation);
value += relocation;
reloc_put32(location, value);
break; break;
case R_MN10300_24: case R_MN10300_24:
value = reloc_get24(location); reloc_put24(location, relocation);
value += relocation;
reloc_put24(location, value);
break; break;
case R_MN10300_16: case R_MN10300_16:
value = reloc_get16(location); reloc_put16(location, relocation);
value += relocation;
reloc_put16(location, value);
break; break;
case R_MN10300_8: case R_MN10300_8:
*location += relocation; *location = relocation;
break; break;
/* for the next three relocation types, we write the /* for the next three relocation types, we write the
......
...@@ -91,6 +91,14 @@ rtc@68 { ...@@ -91,6 +91,14 @@ rtc@68 {
interrupts = <18 0x8>; interrupts = <18 0x8>;
interrupt-parent = <&ipic>; interrupt-parent = <&ipic>;
}; };
mcu_pio: mcu@a {
#gpio-cells = <2>;
compatible = "fsl,mc9s08qg8-mpc8349emitx",
"fsl,mcu-mpc8349emitx";
reg = <0x0a>;
gpio-controller;
};
}; };
spi@7000 { spi@7000 {
...@@ -139,14 +147,6 @@ dma-channel@180 { ...@@ -139,14 +147,6 @@ dma-channel@180 {
interrupt-parent = <&ipic>; interrupt-parent = <&ipic>;
interrupts = <71 8>; interrupts = <71 8>;
}; };
mcu_pio: mcu@a {
#gpio-cells = <2>;
compatible = "fsl,mc9s08qg8-mpc8349emitx",
"fsl,mcu-mpc8349emitx";
reg = <0x0a>;
gpio-controller;
};
}; };
usb@22000 { usb@22000 {
......
...@@ -104,4 +104,6 @@ static inline void kvmppc_set_pid(struct kvm_vcpu *vcpu, u32 new_pid) ...@@ -104,4 +104,6 @@ static inline void kvmppc_set_pid(struct kvm_vcpu *vcpu, u32 new_pid)
} }
} }
extern void kvmppc_core_destroy_mmu(struct kvm_vcpu *vcpu);
#endif /* __POWERPC_KVM_PPC_H__ */ #endif /* __POWERPC_KVM_PPC_H__ */
...@@ -17,6 +17,7 @@ ifdef CONFIG_FUNCTION_TRACER ...@@ -17,6 +17,7 @@ ifdef CONFIG_FUNCTION_TRACER
CFLAGS_REMOVE_cputable.o = -pg -mno-sched-epilog CFLAGS_REMOVE_cputable.o = -pg -mno-sched-epilog
CFLAGS_REMOVE_prom_init.o = -pg -mno-sched-epilog CFLAGS_REMOVE_prom_init.o = -pg -mno-sched-epilog
CFLAGS_REMOVE_btext.o = -pg -mno-sched-epilog CFLAGS_REMOVE_btext.o = -pg -mno-sched-epilog
CFLAGS_REMOVE_prom.o = -pg -mno-sched-epilog
ifdef CONFIG_DYNAMIC_FTRACE ifdef CONFIG_DYNAMIC_FTRACE
# dynamic ftrace setup. # dynamic ftrace setup.
......
...@@ -75,6 +75,7 @@ static int dma_direct_map_sg(struct device *dev, struct scatterlist *sgl, ...@@ -75,6 +75,7 @@ static int dma_direct_map_sg(struct device *dev, struct scatterlist *sgl,
for_each_sg(sgl, sg, nents, i) { for_each_sg(sgl, sg, nents, i) {
sg->dma_address = sg_phys(sg) + get_dma_direct_offset(dev); sg->dma_address = sg_phys(sg) + get_dma_direct_offset(dev);
sg->dma_length = sg->length; sg->dma_length = sg->length;
__dma_sync_page(sg_page(sg), sg->offset, sg->length, direction);
} }
return nents; return nents;
......
This diff is collapsed.
...@@ -894,18 +894,6 @@ _GLOBAL(enter_prom) ...@@ -894,18 +894,6 @@ _GLOBAL(enter_prom)
#ifdef CONFIG_DYNAMIC_FTRACE #ifdef CONFIG_DYNAMIC_FTRACE
_GLOBAL(mcount) _GLOBAL(mcount)
_GLOBAL(_mcount) _GLOBAL(_mcount)
/* Taken from output of objdump from lib64/glibc */
mflr r3
stdu r1, -112(r1)
std r3, 128(r1)
subi r3, r3, MCOUNT_INSN_SIZE
.globl mcount_call
mcount_call:
bl ftrace_stub
nop
ld r0, 128(r1)
mtlr r0
addi r1, r1, 112
blr blr
_GLOBAL(ftrace_caller) _GLOBAL(ftrace_caller)
......
This diff is collapsed.
...@@ -124,6 +124,14 @@ static void kvmppc_44x_shadow_release(struct kvm_vcpu *vcpu, ...@@ -124,6 +124,14 @@ static void kvmppc_44x_shadow_release(struct kvm_vcpu *vcpu,
} }
} }
void kvmppc_core_destroy_mmu(struct kvm_vcpu *vcpu)
{
int i;
for (i = 0; i <= tlb_44x_hwater; i++)
kvmppc_44x_shadow_release(vcpu, i);
}
void kvmppc_tlbe_set_modified(struct kvm_vcpu *vcpu, unsigned int i) void kvmppc_tlbe_set_modified(struct kvm_vcpu *vcpu, unsigned int i)
{ {
vcpu->arch.shadow_tlb_mod[i] = 1; vcpu->arch.shadow_tlb_mod[i] = 1;
......
...@@ -238,6 +238,7 @@ int kvm_arch_vcpu_init(struct kvm_vcpu *vcpu) ...@@ -238,6 +238,7 @@ int kvm_arch_vcpu_init(struct kvm_vcpu *vcpu)
void kvm_arch_vcpu_uninit(struct kvm_vcpu *vcpu) void kvm_arch_vcpu_uninit(struct kvm_vcpu *vcpu)
{ {
kvmppc_core_destroy_mmu(vcpu);
} }
/* Note: clearing MSR[DE] just means that the debug interrupt will not be /* Note: clearing MSR[DE] just means that the debug interrupt will not be
......
This diff is collapsed.
...@@ -600,7 +600,7 @@ static int irq_choose_cpu(unsigned int virt_irq) ...@@ -600,7 +600,7 @@ static int irq_choose_cpu(unsigned int virt_irq)
cpuid = first_cpu(tmp); cpuid = first_cpu(tmp);
} }
return cpuid; return get_hard_smp_processor_id(cpuid);
} }
#else #else
static int irq_choose_cpu(unsigned int virt_irq) static int irq_choose_cpu(unsigned int virt_irq)
......
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment