Print this page
DLPX-25998 TCP congestion control is inadequate
Reviewed at: http://reviews.delphix.com/r/34808/
| Split |
Close |
| Expand all |
| Collapse all |
--- old/usr/src/uts/sparc/Makefile.sparc
+++ new/usr/src/uts/sparc/Makefile.sparc
1 1 #
2 2 # CDDL HEADER START
3 3 #
4 4 # The contents of this file are subject to the terms of the
5 5 # Common Development and Distribution License (the "License").
6 6 # You may not use this file except in compliance with the License.
7 7 #
8 8 # You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 9 # or http://www.opensolaris.org/os/licensing.
10 10 # See the License for the specific language governing permissions
11 11 # and limitations under the License.
12 12 #
13 13 # When distributing Covered Code, include this CDDL HEADER in each
14 14 # file and include the License file at usr/src/OPENSOLARIS.LICENSE.
|
↓ open down ↓ |
14 lines elided |
↑ open up ↑ |
15 15 # If applicable, add the following below this CDDL HEADER, with the
16 16 # fields enclosed by brackets "[]" replaced with your own identifying
17 17 # information: Portions Copyright [yyyy] [name of copyright owner]
18 18 #
19 19 # CDDL HEADER END
20 20 #
21 21
22 22 #
23 23 # Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
24 24 # Copyright (c) 2013 Andrew Stormont. All rights reserved.
25 +# Copyright (c) 2015, 2017 by Delphix. All rights reserved.
25 26 # Copyright (c) 2015, Joyent, Inc. All rights reserved.
26 27 # Copyright 2016 Gary Mills
27 28 # Copyright 2016 Nexenta Systems, Inc.
28 29 #
29 30
30 31 #
31 32 # This makefile contains the common definitions for all sparc
32 33 # implementation architecture independent modules.
33 34 #
34 35
35 36 #
36 37 # Define supported builds
37 38 #
38 39 DEF_BUILDS = $(DEF_BUILDS64)
39 40 ALL_BUILDS = $(ALL_BUILDS64)
40 41
41 42 #
42 43 # Everybody needs to know how to build modstubs.o and to locate unix.o.
43 44 # Note that unix.o must currently be selected from among the possible
44 45 # "implementation architectures". Note further, that unix.o is only
45 46 # used as an optional error check for undefines so (theoretically)
46 47 # any "implementation architectures" could be used. We choose sun4u
47 48 # because it is the reference port.
48 49 #
49 50 UNIX_DIR = $(UTSBASE)/sun4u/unix
50 51 GENLIB_DIR = $(UTSBASE)/sun4u/genunix
51 52 IPDRV_DIR = $(UTSBASE)/sparc/ip
52 53 MODSTUBS_DIR = $(UNIX_DIR)
53 54 DSF_DIR = $(UNIX_DIR)
54 55 LINTS_DIR = $(OBJS_DIR)
55 56 LINT_LIB_DIR = $(UTSBASE)/sparc/lint-libs/$(OBJS_DIR)
56 57
57 58 UNIX_O = $(UNIX_DIR)/$(OBJS_DIR)/unix.o
58 59 MODSTUBS_O = $(MODSTUBS_DIR)/$(OBJS_DIR)/modstubs.o
59 60 GENLIB = $(UTSBASE)/sun4u/lint-libs/$(OBJS_DIR)/libgenunix.so
60 61
61 62 LINT_LIB_32 = $(UTSBASE)/sun4u/lint-libs/$(OBJS_DIR)/llib-lunix.ln
62 63 GEN_LINT_LIB_32 = $(UTSBASE)/sun4u/lint-libs/$(OBJS_DIR)/llib-lgenunix.ln
63 64
64 65 LINT_LIB_64 = $(UTSBASE)/sun4u/lint-libs/$(OBJS_DIR)/llib-lunix.ln
65 66 GEN_LINT_LIB_64 = $(UTSBASE)/sun4u/lint-libs/$(OBJS_DIR)/llib-lgenunix.ln
66 67
67 68 LINT_LIB = $(LINT_LIB_$(CLASS))
68 69 GEN_LINT_LIB = $(GEN_LINT_LIB_$(CLASS))
69 70
70 71 LINT32_DIRS = $(LINT32_BUILDS:%=$(UTSBASE)/sparc/lint-libs/%)
71 72 LINT32_FILES = $(LINT32_DIRS:%=%/llib-l$(MODULE).ln)
72 73
73 74 LINT64_DIRS = $(LINT64_BUILDS:%=$(UTSBASE)/sparc/lint-libs/%)
74 75 LINT64_FILES = $(LINT64_DIRS:%=%/llib-l$(MODULE).ln)
75 76
76 77 #
77 78 # Include the makefiles which define build rule templates, the
78 79 # collection of files per module, and a few specific flags. Note
79 80 # that order is significant, just as with an include path. The
80 81 # first build rule template which matches the files name will be
81 82 # used. By including these in order from most machine dependent
82 83 # to most machine independent, we allow a machine dependent file
83 84 # to be used in preference over a machine independent version
84 85 # (Such as a machine specific optimization, which preserves the
85 86 # interfaces.)
86 87 #
87 88 include $(UTSBASE)/sparc/Makefile.files
88 89 include $(UTSBASE)/sparc/v9/Makefile.files
89 90 include $(UTSBASE)/sun/Makefile.files
90 91 include $(UTSBASE)/common/Makefile.files
91 92
92 93 #
93 94 # ----- TRANSITIONAL SECTION --------------------------------------------------
94 95 #
95 96
96 97 #
97 98 # Not everything which *should* be a module is a module yet. The
98 99 # following is a list of such objects which are currently part of
99 100 # genunix but which might someday become kmods. This must be
100 101 # defined before we include Makefile.uts, or else genunix's build
101 102 # won't be as parallel as we might like.
102 103 #
103 104 NOT_YET_KMODS = $(OLDPTY_OBJS) $(PTY_OBJS) $(VCONS_CONF_OBJS) $(MOD_OBJS)
104 105
105 106 #
106 107 # ----- END OF TRANSITIONAL SECTION -------------------------------------------
107 108 #
108 109 # Include machine independent rules. Note that this does not imply
109 110 # that the resulting module from rules in Makefile.uts is machine
110 111 # independent. Only that the build rules are machine independent.
111 112 #
112 113 include $(UTSBASE)/Makefile.uts
113 114
114 115 #
115 116 # machine specific optimization, override default in Makefile.master
116 117 #
117 118 XARCH_32 = -xarch=v8
118 119 XARCH_64 = -m64
119 120 XARCH = $(XARCH_$(CLASS))
120 121
121 122 COPTIMIZE_32 = -xO3
122 123 COPTIMIZE_64 = -xO3
123 124 COPTIMIZE = $(COPTIMIZE_$(CLASS))
124 125
125 126 CCMODE = -Xa
126 127
127 128 CFLAGS_32 = -xcg92
128 129 CFLAGS_64 = -xchip=ultra $(CCABS32) $(CCREGSYM)
129 130 CFLAGS = $(CFLAGS_$(CLASS))
130 131
131 132 CFLAGS += $(XARCH)
132 133 CFLAGS += $(COPTIMIZE)
133 134 CFLAGS += $(EXTRA_CFLAGS)
134 135 CFLAGS += $(XAOPT)
135 136 CFLAGS += $(INLINES) -D_ASM_INLINES
136 137 CFLAGS += $(CCMODE)
137 138 CFLAGS += $(SPACEFLAG)
138 139 CFLAGS += $(CERRWARN)
139 140 CFLAGS += $(CTF_FLAGS_$(CLASS))
140 141 CFLAGS += $(CSTD)
141 142 CFLAGS += $(CCUNBOUND)
142 143 CFLAGS += $(CCSTATICSYM)
143 144 CFLAGS += $(CC32BITCALLERS)
144 145 CFLAGS += $(CCNOAUTOINLINE)
145 146 CFLAGS += $(IROPTFLAG)
146 147 CFLAGS += $(CGLOBALSTATIC)
147 148 CFLAGS += -xregs=no%float
148 149 CFLAGS += -xstrconst
149 150 CFLAGS += $(CSOURCEDEBUGFLAGS)
150 151 CFLAGS += $(CUSERFLAGS)
151 152
152 153 ASFLAGS += $(XARCH)
153 154
154 155 LINT_DEFS_32 =
155 156 LINT_DEFS_64 = -m64
156 157 LINT_DEFS += $(LINT_DEFS_$(CLASS))
157 158
158 159 #
159 160 # The following must be defined for all implementations:
160 161 #
161 162 # MODSTUBS: Module stubs source file.
162 163 #
163 164 MODSTUBS = $(UTSBASE)/sparc/ml/modstubs.s
164 165
165 166 #
166 167 # Define the actual specific platforms - obviously none.
167 168 #
168 169 MACHINE_DEFS =
169 170
170 171 #
171 172 # Debugging level
172 173 #
173 174 # Special knowledge of which special debugging options effect which
174 175 # file is used to optimize the build if these flags are changed.
175 176 #
176 177 # XXX: The above could possibly be done for more flags and files, but
177 178 # is left as an experiment to the interested reader. Be forewarned,
178 179 # that excessive use could lead to maintenance difficulties.
179 180 #
180 181 DEBUG_DEFS_OBJ32 =
181 182 DEBUG_DEFS_DBG32 = -DDEBUG
182 183 DEBUG_DEFS_OBJ64 =
183 184 DEBUG_DEFS_DBG64 = -DDEBUG
184 185 DEBUG_DEFS = $(DEBUG_DEFS_$(BUILD_TYPE))
185 186
186 187 DEBUG_COND_OBJ32 = $(POUND_SIGN)
187 188 DEBUG_COND_DBG32 =
188 189 DEBUG_COND_OBJ64 = $(POUND_SIGN)
189 190 DEBUG_COND_DBG64 =
190 191 IF_DEBUG_OBJ = $(DEBUG_COND_$(BUILD_TYPE))$(OBJS_DIR)/
191 192
192 193 $(IF_DEBUG_OBJ)syscall.o := DEBUG_DEFS += -DSYSCALLTRACE
193 194 $(IF_DEBUG_OBJ)clock.o := DEBUG_DEFS += -DKSLICE=1
|
↓ open down ↓ |
159 lines elided |
↑ open up ↑ |
194 195
195 196 # Comment these out if you don't want dispatcher lock statistics.
196 197
197 198 # $(IF_DEBUG_OBJ)disp_lock.o := DEBUG_DEFS += -DDISP_LOCK_STATS
198 199
199 200 #
200 201 # Collect the preprocessor definitions to be associated with *all*
201 202 # files.
202 203 #
203 204 ALL_DEFS = $(MACHINE_DEFS) $(DEBUG_DEFS) $(OPTION_DEFS)
205 +
204 206 #
207 +# TCP congestion control modules (/kernel/cc)
205 208 #
209 +CC_KMODS += cc_newreno cc_cubic cc_sunreno
210 +
211 +#
212 +#
206 213 # The kernels modules which are "implementation architecture"
207 214 # specific for this machine are enumerated below. Note that most
208 215 # of these modules must exist (in one form or another) for each
209 216 # architecture.
210 217 #
211 218 # Common Drivers (usually pseudo drivers) (/kernel/drv):
212 219 #
213 220 DRV_KMODS += aggr arp audio bl blkdev bofi clone cn conskbd consms cpuid
214 221 DRV_KMODS += crypto cryptoadm devinfo dump
215 222 DRV_KMODS += dtrace fasttrap fbt lockstat profile sdt systrace dcpc
216 223 DRV_KMODS += fssnap icmp icmp6 ip ip6 ipnet ipsecah
217 224 DRV_KMODS += ipsecesp iptun iwscn keysock kmdb kstat ksyms llc1
218 225 DRV_KMODS += lofi
219 226 DRV_KMODS += log logindmux kssl mm nca physmem pm poll pool
220 227 DRV_KMODS += pseudo ptc ptm pts ptsl ramdisk random rsm rts sad
221 228 DRV_KMODS += simnet softmac sppp sppptun sy sysevent sysmsg
222 229 DRV_KMODS += spdsock
223 230 DRV_KMODS += tcp tcp6 timerfd tl tnf ttymux udp udp6 wc winlock zcons zfd
224 231 DRV_KMODS += ippctl
225 232 DRV_KMODS += dld
226 233 DRV_KMODS += ipd
227 234 DRV_KMODS += ipf
228 235 DRV_KMODS += rpcib
229 236 DRV_KMODS += dlpistub
230 237 DRV_KMODS += vnic
231 238 DRV_KMODS += xge
232 239 DRV_KMODS += rds
233 240 DRV_KMODS += rdsv3
234 241 DRV_KMODS += chxge
235 242 DRV_KMODS += smbsrv
236 243 DRV_KMODS += vscan
237 244 DRV_KMODS += nsmb
238 245 DRV_KMODS += fm
239 246 DRV_KMODS += nulldriver
240 247 DRV_KMODS += bridge trill
241 248 DRV_KMODS += bpf
242 249 DRV_KMODS += dca
243 250 DRV_KMODS += inotify
244 251 DRV_KMODS += eventfd
245 252 DRV_KMODS += signalfd
246 253 DRV_KMODS += timerfd
247 254
248 255 #
249 256 # Hardware Drivers in common space
250 257 #
251 258
252 259 DRV_KMODS += afe
253 260 DRV_KMODS += audio1575
254 261 DRV_KMODS += audioens
255 262 DRV_KMODS += audiols
256 263 DRV_KMODS += audiop16x
257 264 DRV_KMODS += audiopci
258 265 DRV_KMODS += audiots
259 266 DRV_KMODS += bnxe
260 267 DRV_KMODS += e1000g
261 268 DRV_KMODS += efe
262 269 DRV_KMODS += hxge
263 270 DRV_KMODS += mxfe
264 271 DRV_KMODS += rge
265 272 DRV_KMODS += rtls
266 273 DRV_KMODS += sfe
267 274 DRV_KMODS += aac
268 275 DRV_KMODS += igb
269 276 DRV_KMODS += ixgbe
270 277 DRV_KMODS += vr
271 278 DRV_KMODS += mr_sas
272 279 DRV_KMODS += yge
273 280
274 281 #
275 282 # Machine Specific Driver Modules (/kernel/drv):
276 283 #
277 284 DRV_KMODS += audiocs
278 285 DRV_KMODS += bge dmfe eri fas hme qfe
279 286 DRV_KMODS += openeepr options sd ses st
280 287 DRV_KMODS += ssd
281 288 DRV_KMODS += ecpp
282 289 DRV_KMODS += hid hubd ehci ohci uhci usb_mid usb_ia scsa2usb usbprn ugen
283 290 DRV_KMODS += usbser usbsacm usbsksp usbsprl
284 291 DRV_KMODS += usb_as usb_ac
285 292 DRV_KMODS += usbskel
286 293 DRV_KMODS += usbvc
287 294 DRV_KMODS += usbftdi
288 295 DRV_KMODS += usbecm
289 296 DRV_KMODS += hci1394 av1394 scsa1394 dcam1394
290 297 DRV_KMODS += sbp2
291 298 DRV_KMODS += ib ibp eibnx eoib rdsib sdp iser daplt hermon tavor sol_ucma sol_uverbs
292 299 DRV_KMODS += sol_umad
293 300 DRV_KMODS += pci_pci pcieb pcieb_bcm
294 301 DRV_KMODS += i8042 kb8042 mouse8042
295 302 DRV_KMODS += fcode
296 303 DRV_KMODS += mpt_sas
297 304 DRV_KMODS += socal
298 305 DRV_KMODS += sgen
299 306 DRV_KMODS += myri10ge
300 307 DRV_KMODS += smp
301 308 DRV_KMODS += dad
302 309 DRV_KMODS += scsi_vhci
303 310 DRV_KMODS += fcp
304 311 DRV_KMODS += fcip
305 312 DRV_KMODS += fcsm
306 313 DRV_KMODS += fp
307 314 DRV_KMODS += qlc
308 315 DRV_KMODS += qlge
309 316 DRV_KMODS += stmf
310 317 DRV_KMODS += stmf_sbd
311 318 DRV_KMODS += fct
312 319 DRV_KMODS += fcoe
313 320 DRV_KMODS += fcoet
314 321 DRV_KMODS += fcoei
315 322 DRV_KMODS += qlt
316 323 DRV_KMODS += iscsit
317 324 DRV_KMODS += pppt
318 325 DRV_KMODS += ncall nsctl sdbc nskern sv
319 326 DRV_KMODS += ii rdc rdcsrv rdcstub
320 327 DRV_KMODS += iscsi
321 328 DRV_KMODS += emlxs
322 329 DRV_KMODS += oce
323 330 DRV_KMODS += srpt
324 331 DRV_KMODS += pmcs
325 332 DRV_KMODS += pmcs8001fw
326 333
327 334 #
328 335 # I/O framework test drivers
329 336 #
330 337 DRV_KMODS += pshot
331 338 DRV_KMODS += gen_drv
332 339 DRV_KMODS += tvhci tphci tclient
333 340 DRV_KMODS += emul64
334 341
335 342 #
336 343 # PCMCIA specific module(s)
337 344 #
338 345 DRV_KMODS += pcs
339 346 MISC_KMODS += busra cardbus dada pcmcia
340 347 DRV_KMODS += pcic
341 348
342 349 #
343 350 # Exec Class Modules (/kernel/exec):
344 351 #
345 352 EXEC_KMODS += aoutexec elfexec intpexec shbinexec javaexec
346 353
347 354 #
348 355 # Scheduling Class Modules (/kernel/sched):
349 356 #
350 357 SCHED_KMODS += RT TS RT_DPTBL TS_DPTBL IA FSS FX FX_DPTBL SDC
351 358
352 359 #
353 360 # File System Modules (/kernel/fs):
354 361 #
355 362 FS_KMODS += dev devfs fdfs fifofs hsfs lofs namefs nfs pcfs tmpfs zfs
356 363 FS_KMODS += zut specfs udfs ufs autofs procfs sockfs mntfs
357 364 FS_KMODS += ctfs objfs sharefs dcfs smbfs bootfs
358 365
359 366 #
360 367 # Streams Modules (/kernel/strmod):
361 368 #
362 369 STRMOD_KMODS += bufmod connld dedump ldterm ms pckt pfmod
363 370 STRMOD_KMODS += pipemod ptem redirmod rpcmod rlmod telmod timod
364 371 STRMOD_KMODS += spppasyn spppcomp
365 372 STRMOD_KMODS += tirdwr ttcompat
366 373 STRMOD_KMODS += usbkbm usbms usbwcm usb_ah
367 374 STRMOD_KMODS += drcompat
368 375 STRMOD_KMODS += cryptmod
369 376 STRMOD_KMODS += vuid3ps2
370 377
371 378 #
372 379 # 'System' Modules (/kernel/sys):
373 380 #
374 381 SYS_KMODS += c2audit
375 382 SYS_KMODS += exacctsys
376 383 SYS_KMODS += inst_sync kaio msgsys semsys shmsys sysacct pipe
377 384 SYS_KMODS += doorfs pset acctctl portfs
378 385
379 386 #
380 387 # 'User' Modules (/kernel/misc):
381 388 #
382 389 MISC_KMODS += ac97
383 390 MISC_KMODS += bignum
384 391 MISC_KMODS += consconfig gld ipc nfs_dlboot nfssrv scsi
385 392 MISC_KMODS += strplumb swapgeneric tlimod
386 393 MISC_KMODS += rpcsec rpcsec_gss kgssapi kmech_dummy
387 394 MISC_KMODS += kmech_krb5
388 395 MISC_KMODS += fssnap_if
389 396 MISC_KMODS += hidparser kbtrans usba usba10 usbs49_fw
390 397 MISC_KMODS += s1394
391 398 MISC_KMODS += hpcsvc pcihp
392 399 MISC_KMODS += rsmops
393 400 MISC_KMODS += kcf
394 401 MISC_KMODS += ksocket
395 402 MISC_KMODS += ibcm
396 403 MISC_KMODS += ibdm
397 404 MISC_KMODS += ibdma
398 405 MISC_KMODS += ibmf
399 406 MISC_KMODS += ibtl
400 407 MISC_KMODS += sol_ofs
401 408 MISC_KMODS += idm
402 409 MISC_KMODS += idmap
403 410 MISC_KMODS += hook
404 411 MISC_KMODS += neti
405 412 MISC_KMODS += ctf
406 413 MISC_KMODS += mac dls
407 414 MISC_KMODS += cmlb
408 415 MISC_KMODS += tem
409 416 MISC_KMODS += pcicfg fcodem fcpci
410 417 MISC_KMODS += scsi_vhci_f_sym scsi_vhci_f_tpgs scsi_vhci_f_asym_sun
411 418 MISC_KMODS += scsi_vhci_f_sym_hds
412 419 MISC_KMODS += scsi_vhci_f_tape scsi_vhci_f_tpgs_tape
413 420 MISC_KMODS += fctl
414 421 MISC_KMODS += emlxs_fw
415 422 MISC_KMODS += qlc_fw_2200
416 423 MISC_KMODS += qlc_fw_2300
417 424 MISC_KMODS += qlc_fw_2400
418 425 MISC_KMODS += qlc_fw_2500
419 426 MISC_KMODS += qlc_fw_6322
420 427 MISC_KMODS += qlc_fw_8100
421 428 MISC_KMODS += spuni
422 429 MISC_KMODS += mii
423 430
424 431 MISC_KMODS += klmmod klmops
425 432
426 433 #
427 434 # Software Cryptographic Providers (/kernel/crypto):
428 435 #
429 436 CRYPTO_KMODS += aes
430 437 CRYPTO_KMODS += arcfour
431 438 CRYPTO_KMODS += blowfish
432 439 CRYPTO_KMODS += des
433 440 CRYPTO_KMODS += ecc
434 441 CRYPTO_KMODS += edonr
435 442 CRYPTO_KMODS += md4
436 443 CRYPTO_KMODS += md5
437 444 CRYPTO_KMODS += rsa
438 445 CRYPTO_KMODS += sha1
439 446 CRYPTO_KMODS += sha2
440 447 CRYPTO_KMODS += skein
441 448 CRYPTO_KMODS += swrand
442 449
443 450 #
444 451 # IP Policy Modules (/kernel/ipp):
445 452 #
446 453 IPP_KMODS += dlcosmk
447 454 IPP_KMODS += flowacct
448 455 IPP_KMODS += ipgpc
449 456 IPP_KMODS += dscpmk
450 457 IPP_KMODS += tokenmt
451 458 IPP_KMODS += tswtclmt
452 459
453 460 #
454 461 # 'Dacf' modules (/kernel/dacf)
455 462 DACF_KMODS += consconfig_dacf
456 463
457 464 #
458 465 # SVVS Testing Modules (/kernel/strmod):
459 466 #
460 467 # These are streams and driver modules which are not to be
461 468 # delivered with a released system. However, during development
462 469 # it is convenient to build and install the SVVS kernel modules.
463 470 #
464 471 SVVS_KMODS += lmodb lmode lmodr lmodt svvslo tidg tivc tmux
465 472
466 473 #
467 474 # Modules eXcluded from the product:
468 475 #
469 476 XMODS +=
470 477
471 478 #
472 479 # 'Dacf' Modules (/kernel/dacf):
473 480 #
474 481 DACF_KMODS += net_dacf
475 482
476 483 #
477 484 # MAC-Type Plugin Modules (/kernel/mac)
478 485 #
479 486 MAC_KMODS += mac_6to4
480 487 MAC_KMODS += mac_ether
481 488 MAC_KMODS += mac_ipv4
482 489 MAC_KMODS += mac_ipv6
483 490 MAC_KMODS += mac_wifi
484 491 MAC_KMODS += mac_ib
485 492
486 493 #
487 494 # socketmod (kernel/socketmod)
488 495 #
489 496 SOCKET_KMODS += sockpfp
490 497 SOCKET_KMODS += socksctp
491 498 SOCKET_KMODS += socksdp
492 499 SOCKET_KMODS += sockrds
493 500 SOCKET_KMODS += ksslf
494 501 SOCKET_KMODS += datafilt
495 502
496 503 #
497 504 # kiconv modules (/kernel/kiconv):
498 505 #
499 506 KICONV_KMODS += kiconv_emea kiconv_ja kiconv_ko kiconv_sc kiconv_tc
500 507
501 508 #
502 509 # Ensure that the variable member of the cpu_t (cpu_m) is defined
503 510 # for the lint builds so as not to cause lint errors during the
504 511 # global cross check.
505 512 #
506 513 $(LINTFLAGSUPPRESS)LINTFLAGS += -D_MACHDEP -I$(UTSBASE)/sun4 \
507 514 -I$(UTSBASE)/sun4u -I$(UTSBASE)/sfmmu
|
↓ open down ↓ |
292 lines elided |
↑ open up ↑ |
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX