€•O:Œsphinx.addnodes”Œdocument”“”)”}”(Œ rawsource”Œ”Œchildren”]”(Œ translations”Œ LanguagesNode”“”)”}”(hhh]”(hŒ pending_xref”“”)”}”(hhh]”Œdocutils.nodes”ŒText”“”ŒChinese (Simplified)”…””}”Œparent”hsbaŒ attributes”}”(Œids”]”Œclasses”]”Œnames”]”Œdupnames”]”Œbackrefs”]”Œ refdomain”Œstd”Œreftype”Œdoc”Œ reftarget”Œ$/translations/zh_CN/dev-tools/sparse”Œmodname”NŒ classname”NŒ refexplicit”ˆuŒtagname”hhh ubh)”}”(hhh]”hŒChinese (Traditional)”…””}”hh2sbah}”(h]”h ]”h"]”h$]”h&]”Œ refdomain”h)Œreftype”h+Œ reftarget”Œ$/translations/zh_TW/dev-tools/sparse”Œmodname”NŒ classname”NŒ refexplicit”ˆuh1hhh ubh)”}”(hhh]”hŒItalian”…””}”hhFsbah}”(h]”h ]”h"]”h$]”h&]”Œ refdomain”h)Œreftype”h+Œ reftarget”Œ$/translations/it_IT/dev-tools/sparse”Œmodname”NŒ classname”NŒ refexplicit”ˆuh1hhh ubh)”}”(hhh]”hŒJapanese”…””}”hhZsbah}”(h]”h ]”h"]”h$]”h&]”Œ refdomain”h)Œreftype”h+Œ reftarget”Œ$/translations/ja_JP/dev-tools/sparse”Œmodname”NŒ classname”NŒ refexplicit”ˆuh1hhh ubh)”}”(hhh]”hŒKorean”…””}”hhnsbah}”(h]”h ]”h"]”h$]”h&]”Œ refdomain”h)Œreftype”h+Œ reftarget”Œ$/translations/ko_KR/dev-tools/sparse”Œmodname”NŒ classname”NŒ refexplicit”ˆuh1hhh ubh)”}”(hhh]”hŒSpanish”…””}”hh‚sbah}”(h]”h ]”h"]”h$]”h&]”Œ refdomain”h)Œreftype”h+Œ reftarget”Œ$/translations/sp_SP/dev-tools/sparse”Œmodname”NŒ classname”NŒ refexplicit”ˆuh1hhh ubeh}”(h]”h ]”h"]”h$]”h&]”Œcurrent_language”ŒEnglish”uh1h hhŒ _document”hŒsource”NŒline”NubhŒcomment”“”)”}”(hŒCopyright 2004 Linus Torvalds”h]”hŒCopyright 2004 Linus Torvalds”…””}”hh£sbah}”(h]”h ]”h"]”h$]”h&]”Œ xml:space”Œpreserve”uh1h¡hhhžhhŸŒ>/var/lib/git/docbuild/linux/Documentation/dev-tools/sparse.rst”h Kubh¢)”}”(hŒ*Copyright 2004 Pavel Machek ”h]”hŒ*Copyright 2004 Pavel Machek ”…””}”hh´sbah}”(h]”h ]”h"]”h$]”h&]”h±h²uh1h¡hhhžhhŸh³h Kubh¢)”}”(hŒ0Copyright 2006 Bob Copeland ”h]”hŒ0Copyright 2006 Bob Copeland ”…””}”hhÂsbah}”(h]”h ]”h"]”h$]”h&]”h±h²uh1h¡hhhžhhŸh³h KubhŒsection”“”)”}”(hhh]”(hŒtitle”“”)”}”(hŒSparse”h]”hŒSparse”…””}”(hh×hžhhŸNh Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hÕhhÒhžhhŸh³h KubhŒ paragraph”“”)”}”(hXsSparse is a semantic checker for C programs; it can be used to find a number of potential problems with kernel code. See https://lwn.net/Articles/689907/ for an overview of sparse; this document contains some kernel-specific sparse information. More information on sparse, mainly about its internals, can be found in its official pages at https://sparse.docs.kernel.org.”h]”(hŒzSparse is a semantic checker for C programs; it can be used to find a number of potential problems with kernel code. See ”…””}”(hhçhžhhŸNh NubhŒ reference”“”)”}”(hŒ https://lwn.net/Articles/689907/”h]”hŒ https://lwn.net/Articles/689907/”…””}”(hhñhžhhŸNh Nubah}”(h]”h ]”h"]”h$]”h&]”Œrefuri”hóuh1hïhhçubhŒº for an overview of sparse; this document contains some kernel-specific sparse information. More information on sparse, mainly about its internals, can be found in its official pages at ”…””}”(hhçhžhhŸNh Nubhð)”}”(hŒhttps://sparse.docs.kernel.org”h]”hŒhttps://sparse.docs.kernel.org”…””}”(hjhžhhŸNh Nubah}”(h]”h ]”h"]”h$]”h&]”Œrefuri”juh1hïhhçubhŒ.”…””}”(hhçhžhhŸNh Nubeh}”(h]”h ]”h"]”h$]”h&]”uh1håhŸh³h KhhÒhžhubhÑ)”}”(hhh]”(hÖ)”}”(hŒUsing sparse for typechecking”h]”hŒUsing sparse for typechecking”…””}”(hj hžhhŸNh Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hÕhjhžhhŸh³h Kubhæ)”}”(hŒH"__bitwise" is a type attribute, so you have to do something like this::”h]”hŒK“__bitwise†is a type attribute, so you have to do something like this:”…””}”(hj.hžhhŸNh Nubah}”(h]”h ]”h"]”h$]”h&]”uh1håhŸh³h KhjhžhubhŒ literal_block”“”)”}”(hŒ•typedef int __bitwise pm_request_t; enum pm_request { PM_SUSPEND = (__force pm_request_t) 1, PM_RESUME = (__force pm_request_t) 2 };”h]”hŒ•typedef int __bitwise pm_request_t; enum pm_request { PM_SUSPEND = (__force pm_request_t) 1, PM_RESUME = (__force pm_request_t) 2 };”…””}”hj>sbah}”(h]”h ]”h"]”h$]”h&]”h±h²uh1j<hŸh³h Khjhžhubhæ)”}”(hX1which makes PM_SUSPEND and PM_RESUME "bitwise" integers (the "__force" is there because sparse will complain about casting to/from a bitwise type, but in this case we really _do_ want to force the conversion). And because the enum values are all the same type, now "enum pm_request" will be that type too.”h]”hX=which makes PM_SUSPEND and PM_RESUME “bitwise†integers (the “__force†is there because sparse will complain about casting to/from a bitwise type, but in this case we really _do_ want to force the conversion). And because the enum values are all the same type, now “enum pm_request†will be that type too.”…””}”(hjLhžhhŸNh Nubah}”(h]”h ]”h"]”h$]”h&]”uh1håhŸh³h Khjhžhubhæ)”}”(hŒrAnd with gcc, all the "__bitwise"/"__force stuff" goes away, and it all ends up looking just like integers to gcc.”h]”hŒzAnd with gcc, all the “__bitwiseâ€/â€__force stuff†goes away, and it all ends up looking just like integers to gcc.”…””}”(hjZhžhhŸNh Nubah}”(h]”h ]”h"]”h$]”h&]”uh1håhŸh³h K"hjhžhubhæ)”}”(hŒwQuite frankly, you don't need the enum there. The above all really just boils down to one special "int __bitwise" type.”h]”hŒ}Quite frankly, you don’t need the enum there. The above all really just boils down to one special “int __bitwise†type.”…””}”(hjhhžhhŸNh Nubah}”(h]”h ]”h"]”h$]”h&]”uh1håhŸh³h K%hjhžhubhæ)”}”(hŒ"So the simpler way is to just do::”h]”hŒ!So the simpler way is to just do:”…””}”(hjvhžhhŸNh Nubah}”(h]”h ]”h"]”h$]”h&]”uh1håhŸh³h K(hjhžhubj=)”}”(hŒtypedef int __bitwise pm_request_t; #define PM_SUSPEND ((__force pm_request_t) 1) #define PM_RESUME ((__force pm_request_t) 2)”h]”hŒtypedef int __bitwise pm_request_t; #define PM_SUSPEND ((__force pm_request_t) 1) #define PM_RESUME ((__force pm_request_t) 2)”…””}”hj„sbah}”(h]”h ]”h"]”h$]”h&]”h±h²uh1j<hŸh³h K*hjhžhubhæ)”}”(hŒGand you now have all the infrastructure needed for strict typechecking.”h]”hŒGand you now have all the infrastructure needed for strict typechecking.”…””}”(hj’hžhhŸNh Nubah}”(h]”h ]”h"]”h$]”h&]”uh1håhŸh³h K/hjhžhubhæ)”}”(hXgOne small note: the constant integer "0" is special. You can use a constant zero as a bitwise integer type without sparse ever complaining. This is because "bitwise" (as the name implies) was designed for making sure that bitwise types don't get mixed up (little-endian vs big-endian vs cpu-endian vs whatever), and there the constant "0" really _is_ special.”h]”hXuOne small note: the constant integer “0†is special. You can use a constant zero as a bitwise integer type without sparse ever complaining. This is because “bitwise†(as the name implies) was designed for making sure that bitwise types don’t get mixed up (little-endian vs big-endian vs cpu-endian vs whatever), and there the constant “0†really _is_ special.”…””}”(hj hžhhŸNh Nubah}”(h]”h ]”h"]”h$]”h&]”uh1håhŸh³h K1hjhžhubeh}”(h]”Œusing-sparse-for-typechecking”ah ]”h"]”Œusing sparse for typechecking”ah$]”h&]”uh1hÐhhÒhžhhŸh³h KubhÑ)”}”(hhh]”(hÖ)”}”(hŒUsing sparse for lock checking”h]”hŒUsing sparse for lock checking”…””}”(hj¹hžhhŸNh Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hÕhj¶hžhhŸh³h K9ubhæ)”}”(hŒûThe following macros are undefined for gcc and defined during a sparse run to use the "context" tracking feature of sparse, applied to locking. These annotations tell sparse when a lock is held, with regard to the annotated function's entry and exit.”h]”hXThe following macros are undefined for gcc and defined during a sparse run to use the “context†tracking feature of sparse, applied to locking. These annotations tell sparse when a lock is held, with regard to the annotated function’s entry and exit.”…””}”(hjÇhžhhŸNh Nubah}”(h]”h ]”h"]”h$]”h&]”uh1håhŸh³h K;hj¶hžhubhæ)”}”(hŒD__must_hold - The specified lock is held on function entry and exit.”h]”hŒD__must_hold - The specified lock is held on function entry and exit.”…””}”(hjÕhžhhŸNh Nubah}”(h]”h ]”h"]”h$]”h&]”uh1håhŸh³h K@hj¶hžhubhæ)”}”(hŒH__acquires - The specified lock is held on function exit, but not entry.”h]”hŒH__acquires - The specified lock is held on function exit, but not entry.”…””}”(hjãhžhhŸNh Nubah}”(h]”h ]”h"]”h$]”h&]”uh1håhŸh³h KBhj¶hžhubhæ)”}”(hŒH__releases - The specified lock is held on function entry, but not exit.”h]”hŒH__releases - The specified lock is held on function entry, but not exit.”…””}”(hjñhžhhŸNh Nubah}”(h]”h ]”h"]”h$]”h&]”uh1håhŸh³h KDhj¶hžhubhæ)”}”(hŒüIf the function enters and exits without the lock held, acquiring and releasing the lock inside the function in a balanced way, no annotation is needed. The three annotations above are for cases where sparse would otherwise report a context imbalance.”h]”hŒüIf the function enters and exits without the lock held, acquiring and releasing the lock inside the function in a balanced way, no annotation is needed. The three annotations above are for cases where sparse would otherwise report a context imbalance.”…””}”(hjÿhžhhŸNh Nubah}”(h]”h ]”h"]”h$]”h&]”uh1håhŸh³h KFhj¶hžhubeh}”(h]”Œusing-sparse-for-lock-checking”ah ]”h"]”Œusing sparse for lock checking”ah$]”h&]”uh1hÐhhÒhžhhŸh³h K9ubhÑ)”}”(hhh]”(hÖ)”}”(hŒGetting sparse”h]”hŒGetting sparse”…””}”(hjhžhhŸNh Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hÕhjhžhhŸh³h KLubhæ)”}”(hŒqYou can get tarballs of the latest released versions from: https://www.kernel.org/pub/software/devel/sparse/dist/”h]”(hŒ;You can get tarballs of the latest released versions from: ”…””}”(hj&hžhhŸNh Nubhð)”}”(hŒ6https://www.kernel.org/pub/software/devel/sparse/dist/”h]”hŒ6https://www.kernel.org/pub/software/devel/sparse/dist/”…””}”(hj.hžhhŸNh Nubah}”(h]”h ]”h"]”h$]”h&]”Œrefuri”j0uh1hïhj&ubeh}”(h]”h ]”h"]”h$]”h&]”uh1håhŸh³h KNhjhžhubhæ)”}”(hŒeAlternatively, you can get snapshots of the latest development version of sparse using git to clone::”h]”hŒdAlternatively, you can get snapshots of the latest development version of sparse using git to clone:”…””}”(hjChžhhŸNh Nubah}”(h]”h ]”h"]”h$]”h&]”uh1håhŸh³h KQhjhžhubj=)”}”(hŒ4git://git.kernel.org/pub/scm/devel/sparse/sparse.git”h]”hŒ4git://git.kernel.org/pub/scm/devel/sparse/sparse.git”…””}”hjQsbah}”(h]”h ]”h"]”h$]”h&]”h±h²uh1j<hŸh³h KThjhžhubhæ)”}”(hŒOnce you have it, just do::”h]”hŒOnce you have it, just do:”…””}”(hj_hžhhŸNh Nubah}”(h]”h ]”h"]”h$]”h&]”uh1håhŸh³h KVhjhžhubj=)”}”(hŒmake make install”h]”hŒmake make install”…””}”hjmsbah}”(h]”h ]”h"]”h$]”h&]”h±h²uh1j<hŸh³h KXhjhžhubhæ)”}”(hŒFas a regular user, and it will install sparse in your ~/bin directory.”h]”hŒFas a regular user, and it will install sparse in your ~/bin directory.”…””}”(hj{hžhhŸNh Nubah}”(h]”h ]”h"]”h$]”h&]”uh1håhŸh³h K[hjhžhubeh}”(h]”Œgetting-sparse”ah ]”h"]”Œgetting sparse”ah$]”h&]”uh1hÐhhÒhžhhŸh³h KLubhÑ)”}”(hhh]”(hÖ)”}”(hŒ Using sparse”h]”hŒ Using sparse”…””}”(hj”hžhhŸNh Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hÕhj‘hžhhŸh³h K^ubhæ)”}”(hŒþDo a kernel make with "make C=1" to run sparse on all the C files that get recompiled, or use "make C=2" to run sparse on the files whether they need to be recompiled or not. The latter is a fast way to check the whole tree if you have already built it.”h]”hXDo a kernel make with “make C=1†to run sparse on all the C files that get recompiled, or use “make C=2†to run sparse on the files whether they need to be recompiled or not. The latter is a fast way to check the whole tree if you have already built it.”…””}”(hj¢hžhhŸNh Nubah}”(h]”h ]”h"]”h$]”h&]”uh1håhŸh³h K`hj‘hžhubhæ)”}”(hŒ‚The optional make variable CF can be used to pass arguments to sparse. The build system passes -Wbitwise to sparse automatically.”h]”hŒ‚The optional make variable CF can be used to pass arguments to sparse. The build system passes -Wbitwise to sparse automatically.”…””}”(hj°hžhhŸNh Nubah}”(h]”h ]”h"]”h$]”h&]”uh1håhŸh³h Kehj‘hžhubhæ)”}”(hŒ=Note that sparse defines the __CHECKER__ preprocessor symbol.”h]”hŒ=Note that sparse defines the __CHECKER__ preprocessor symbol.”…””}”(hj¾hžhhŸNh Nubah}”(h]”h ]”h"]”h$]”h&]”uh1håhŸh³h Khhj‘hžhubeh}”(h]”Œ using-sparse”ah ]”h"]”Œ using sparse”ah$]”h&]”uh1hÐhhÒhžhhŸh³h K^ubeh}”(h]”Œsparse”ah ]”h"]”Œsparse”ah$]”h&]”uh1hÐhhhžhhŸh³h Kubeh}”(h]”h ]”h"]”h$]”h&]”Œsource”h³uh1hŒcurrent_source”NŒ current_line”NŒsettings”Œdocutils.frontend”ŒValues”“”)”}”(hÕNŒ generator”NŒ datestamp”NŒ source_link”NŒ source_url”NŒ toc_backlinks”Œentry”Œfootnote_backlinks”KŒ sectnum_xform”KŒstrip_comments”NŒstrip_elements_with_classes”NŒ strip_classes”NŒ report_level”KŒ halt_level”KŒexit_status_level”KŒdebug”NŒwarning_stream”NŒ traceback”ˆŒinput_encoding”Œ utf-8-sig”Œinput_encoding_error_handler”Œstrict”Œoutput_encoding”Œutf-8”Œoutput_encoding_error_handler”jÿŒerror_encoding”Œutf-8”Œerror_encoding_error_handler”Œbackslashreplace”Œ language_code”Œen”Œrecord_dependencies”NŒconfig”NŒ id_prefix”hŒauto_id_prefix”Œid”Œ dump_settings”NŒdump_internals”NŒdump_transforms”NŒdump_pseudo_xml”NŒexpose_internals”NŒstrict_visitor”NŒ_disable_config”NŒ_source”h³Œ _destination”NŒ _config_files”]”Œ7/var/lib/git/docbuild/linux/Documentation/docutils.conf”aŒfile_insertion_enabled”ˆŒ raw_enabled”KŒline_length_limit”M'Œpep_references”NŒ pep_base_url”Œhttps://peps.python.org/”Œpep_file_url_template”Œpep-%04d”Œrfc_references”NŒ rfc_base_url”Œ&https://datatracker.ietf.org/doc/html/”Œ tab_width”KŒtrim_footnote_reference_space”‰Œsyntax_highlight”Œlong”Œ smart_quotes”ˆŒsmartquotes_locales”]”Œcharacter_level_inline_markup”‰Œdoctitle_xform”‰Œ docinfo_xform”KŒsectsubtitle_xform”‰Œ image_loading”Œlink”Œembed_stylesheet”‰Œcloak_email_addresses”ˆŒsection_self_link”‰Œenv”NubŒreporter”NŒindirect_targets”]”Œsubstitution_defs”}”Œsubstitution_names”}”Œrefnames”}”Œrefids”}”Œnameids”}”(jÙjÖj³j°jjjŽj‹jÑjÎuŒ nametypes”}”(jÙ‰j³‰j‰jމjщuh}”(jÖhÒj°jjj¶j‹jjÎj‘uŒ footnote_refs”}”Œ citation_refs”}”Œ autofootnotes”]”Œautofootnote_refs”]”Œsymbol_footnotes”]”Œsymbol_footnote_refs”]”Œ footnotes”]”Œ citations”]”Œautofootnote_start”KŒsymbol_footnote_start”KŒ id_counter”Œ collections”ŒCounter”“”}”…”R”Œparse_messages”]”Œtransform_messages”]”Œ transformer”NŒ include_log”]”Œ decoration”Nhžhub.