Linux Kernel: Hot and Cold page in linux kernel - memory

Can somebody explain exact difference between Hot and Cold pages in linux page-allocation process? use this
And, In any way is it related to page_order?
void __free_pages(struct page *page, unsigned int order)
{
if (put_page_testzero(page)) {
if (order == 0)
free_hot_cold_page(page, false);
else
__free_pages_ok(page, order);
}
}

Related

Using WINC1500 with a PIC32, scan not working properly

I'm currently working on a project using a PIC32 and the wifi module ATWINC1500. I won't be able to give all the code but I'm on a test function that I can share.
First, here is some settings and configuration I'm using:
Processor : PIC32MZ1024EFE064
IDE : MPLAB IDE 5.45
Harmony version : 2.06
Wifi Module : ATWINC1500
Real Time OS : FreeRTOS
What I'm trying to do is to connect the Wifi module to an existing Access Point using the Infrastructure mode. I'm able to get the number of access point around me but when I try to read information from those access points, information are empty, void or incorrect.
Here is my code:
bool WIFI_Test_Infrastructure(void)
{
//Example: https://www.microchip.com/forums/m906568.aspx
//Wait for WINC1500 to be initialized
if(isWdrvExtReady() == false)
return false;
//Start a scan or wait for result
IWPRIV_PARAM_SCAN scanner;
IWPRIV_GET_PARAM param_scan = {
.scan = scanner
};
iwpriv_get(SCANSTATUS_GET, &param_scan);
IWPRIV_SCAN_STATUS status = param_scan.scan.scanStatus;
IWPRIV_EXECUTE_PARAM dummy_param;
//Process StateMachine while scanning
if(status == IWPRIV_SCAN_IDLE)
{
vTaskDelay(1000 / portTICK_PERIOD_MS);
//Disconnect wifi from everything
WDRV_Disconnect();
vTaskDelay(1000 / portTICK_PERIOD_MS);
while(WDRV_ConnectionState_Get() != WDRV_CONNECTION_STATE_NOT_CONNECTED)
vTaskDelay(10 / portTICK_PERIOD_MS);
vTaskDelay(1000 / portTICK_PERIOD_MS);
WDRV_EXT_CmdScanStart();
return false;
}
else if(status == IWPRIV_SCAN_IN_PROGRESS)
{
return false;
}
else if(status == IWPRIV_SCAN_NO_AP_FOUND)
{
iwpriv_execute(SCAN_START, &dummy_param);
return false;
}
else if(status == IWPRIV_SCAN_SUCCESSFUL)
{
vTaskDelay(1000 / portTICK_PERIOD_MS);
//Read liste of wifi access point
uint16_t wifi_number_AP;
wifi_number_AP = m2m_wifi_get_num_ap_found();
WDRV_SCAN_RESULT scanResult;
tstrM2mWifiscanResult result;
int i;
for(i=0; i<wifi_number_AP; i++)
{
m2m_wifi_req_scan_result(i);
vTaskDelay(1000 / portTICK_PERIOD_MS);
winc1500_scan_result_read(&result); //ISSUE HAPPENED HERE
vTaskDelay(1000 / portTICK_PERIOD_MS);
memcpy((void *)scanResult.bssid, (void *)result.au8BSSID, sizeof(scanResult.bssid));
}
//SUCCESS
return true;
}
else
{
return false;
}
}
So what happened here:
First, you need to know that this function is called by a Thread Manager, that's why it returns false or true. I'm checking the state in which the scan is.
I'm able to reach the SCAN_SUCCESSFUL part and the number of access point detected is correct.
I labeled the line where the issue is happening. When I'm reading the result information of an access point, it is quite empty. Here is what I see in Debug Session (and it is the same result for all of access points):
I have been waiting for weeks before asking this. Hope someone can help or at least give me hints on things to check.
If I missed information, do not hesitate to ask me.
Thanks in advance!
Adrien
The solution was simply a story of stack. I have two other tasks: SYS and TCP/IP. I needed to increase the size of their stack because they were managing several functions about scanning. So there was an overriding somewhere.

Saxon-C CentOS8 Compile

I am trying to evaluate Saxon-C 1.2.1 HE on CentOS8 and installation seems to have gone ok. Trying out the samples by cd samples/cppTests && build64-linux.sh though leads to a myriad of compilation errors to the tune of the following:
../../Saxon.C.API/SaxonProcessor.h:599:32: error: division ‘sizeof (JNINativeMethod*) / sizeof (JNINativeMethod)’ does not compute the number of array elements [-Werror=sizeof-pointer-div]
gMethods, sizeof(gMethods) / sizeof(gMethods[0]));
Before I summarily and trustfully switched off -Werror=sizeof-pointer-div i checked the source code and what's going on there do seem dubious.
bool registerCPPFunction(char * libName, JNINativeMethod * gMethods=NULL){
if(libName != NULL) {
setConfigurationProperty("extc", libName);
}
if(gMethods == NULL && nativeMethodVect.size()==0) {
return false;
} else {
if(gMethods == NULL) {
//copy vector to gMethods
gMethods = new JNINativeMethod[nativeMethodVect.size()];
}
return registerNativeMethods(sxn_environ->env, "com/saxonica/functions/>
gMethods, sizeof(gMethods) / sizeof(gMethods[0]));
}
return false;
}
more specifically sizeof(gMethods) / sizeof(gMethods[0]) would not seem to calculate anything useful by any margin. The intention was probably rather to output some code that would arrive at the same value as nativeMethodVect.size() but seeing this project's source for the very first time i might be mistaking and the division is in fact intentional ?
I am inclined to guess the intention was in fact closer to b than to a in the following example:
#include <cstdio>
struct test
{
int x, y, z;
};
int main()
{
test *a = new test[32], b[32];
printf("%d %d\n", sizeof(a)/sizeof(a[0]), sizeof(b)/sizeof(b[0]));
return 0;
}
which output 0 32 which is expected as the sizeof(a) gives the size of a pointer not the size of an array's memory region.
That bit of code is to support the feature of user defined extension functions in XSLT stylesheets and XQuery queries. If a user is not using these features then they don't need that bit of code. In fact User defined extension functions is only available in Saxon-PE/C and Saxon-EE/C so it should not be in the Saxon-HE/C code base. I have created the following bug issue to investigate the error above and to https://saxonica.plan.io/issues/4477
I would think the workaround would be to either remove the code in question if the extension function feature is not used or remove the compile flag -Werror=sizeof-pointer-div.
The intent was code is as follows:
jobject JNICALL cppNativeCall(jstring funcName, jobjectArray arguments, jobjectArray argTypes){
//native call code here
}
JNINativeMethod cppMethods[] =
{
{
fname,
funcParameters,
(void *)&cppNativeCall
}
};
bool nativeFound = processor->registerNativeMethods(env, "NativeCall",
cppMethods, sizeof(cppMethods) / sizeof(cppMethods[0]));

How linux driver can delegate functions to another driver (shared hardware)

I'm writing a custom IR transmitter driver for lirc on an embedded board. The board has a i2c-to-gpio extender (FXL6408).
The problem is that only one GPIO pin is needed for my driver (and hence LIRC) and the other pins are needed for use by other applications. Something like this:
I've read LWM, LDD3, and tons of sites about i2c-slave, i2c adaptors, buses, pinctrl, gpio, stacking etc but its not clear how to do what I want:
my-driver needs to control a single pin on the GPIO extender while still allowing other applications to control the other 7 pins via /dev/i2c-0.
Following this SO suggestion was promising but i2c_new_dummy failed, returning NULL:
i2cAdaptor = i2c_get_adapter(ECP_I2CBUS); // 1 means i2c-1 bus
if (i2cAdaptor == NULL)
{
printk("ecp_gpio: Could not acquire i2c adaptor\n");
return -EBUSY;
}
i2cClient = i2c_new_dummy(i2cAdaptor, ECP_I2CDEV); // 0x43 - slave address on i2c bus
if (i2cClient == NULL)
{
printk("ecp_gpio: Could not acquire i2c client\n");
return -EBUSY;
}
if ( (rc = i2c_smbus_write_byte(i2cClient, 0xF0)) < 0)
{
printk("ecp_gpio: Error writing byte - error %d", rc);
return -EIO;
}
What is the correct way to hook up the plumbing to achieve what I want?
OS Info:
# uname -a
Linux ecp 4.4.127-1.el6.elrepo.i686 #1 SMP Sun Apr 8 09:44:43 EDT 2018 i686 i686 i386 GNU/Linux
After trying many different things, I found one that works. I don't know if it is "the right way" to do it, but it does work.
Instead of trying to create a dummy client, just call the i2c_xx functions directly. So the code looks like:
i2cAdaptor = i2c_get_adapter(ECP_I2CBUS); // 1 means i2c-1 bus etc
if (i2cAdaptor == NULL)
{
printk("ecp_gpio: Could not acquire i2c adaptor\n");
return -EBUSY;
}
union i2c_smbus_data data;
data.byte = 0xF0;
if ((rc = i2c_smbus_xfer(ecpHardware.i2cAdaptor, ECP_I2CDEV, 0, I2C_SMBUS_WRITE, 0x05, I2C_SMBUS_BYTE_DATA, &data)) < 0)
{
printk("ecp_gpio: i2c_smbus_xfer failed: %d\n", rc);
return -EIO;
}
data.byte = 0xE0;
if ((rc = i2c_smbus_xfer(ecpHardware.i2cAdaptor, ECP_I2CDEV, 0, I2C_SMBUS_WRITE, 0x05, I2C_SMBUS_BYTE_DATA, &data)) < 0)
{
printk("ecp_gpio: i2c_smbus_xfer failed: %d\n", rc);
return -EIO;
}

fgets segmentation fault reading from stdin

I'm currently trying to read a line from stdin using fgets() but i'm getting a segmentation fault (i'm not geting the segmentation fault anymore, please see edit)
int main(void)
{
char selection;
string firstName = NULL;
printf("[A]dd a new client \n");
printf("[D]isplay all clients \n");
printf("[I]ncome Average for all clients \n");
printf("[Q]uit \n");
selection = fgetc(stdin);
printf("\n");
switch (selection) {
case 'A':
printf("First name: ");
fgets(firstName, MAXNAMESIZE, stdin);
printf("\n");
...
}
}
This is the compiler's output:
[A]dd a new client
[D]isplay all clients
[I]ncome Average for all clients
[Q]uit
A
First name: Segmentation fault
Thank you!!
Edit:
i've changed the code like this:
int main(void)
{
char selection;
string firstName;
printf("[A]dd a new client \n");
printf("[D]isplay all clients \n");
printf("[I]ncome Average for all clients \n");
printf("[Q]uit \n");
selection = fgetc(stdin);
printf("\n");
switch (selection) {
case 'A':
if ((firstName = malloc(MAXNAMESIZE * sizeof(char))) == NULL)
return 1;
printf("First name: ");
fgets(firstName, MAXNAMESIZE, stdin);
printf("\n");
...
}
}
But now i'm not able to enter any name, the program just ends. This is the output:
~/workspace/ $ ./test
[A]dd a new client
[D]isplay all clients
[I]ncome Average for all clients
[Q]uit
A
First name:
~/workspace/ $
You need to malloc firstName before you can use it, hence make sure to #include <stdlib.h>.
Try string firstName = malloc(MAXNAMESIZE * sizeof(char));
Always check that the result of malloc is not NULL.
Moreover, at the end of your program or when you think it's more useful free(firstName) to prevent memory leaks.

Memory leak in a Tcl wrapper

I read all I could find about memory management in the Tcl API, but haven't been able to solve my problem so far. I wrote a Tcl extension to access an existing application. It works, except for a serious issue: memory leak.
I tried to reproduce the problem with minimal code, which you can find at the end of the post. The extension defines a new command, recordings, in namespace vtcl. The recordings command creates a list of 10000 elements, each element being a new command. Each command has data attached to it, which is the name of a recording. The name subcommand of each command returns the name of the recording.
I run the following Tcl code with tclsh to reproduce the problem:
load libvtcl.so
for {set ii 0} {$ii < 1000} {incr ii} {
set recs [vtcl::recordings]
foreach r $recs {rename $r ""}
}
The line foreach r $recs {rename $r ""} deletes all the commands at each iteration, which frees the memory of the piece of data attached to each command (I can see that in gdb). I can also see in gdb that the reference count of variable recs goes to 0 at each iteration so that the contents of the list is freed. Nonetheless, I see the memory of the process running tclsh going up at each iteration.
I have no more idea what else I could try. Help will be greatly appreciated.
#include <stdio.h>
#include <string.h>
#include <tcl.h>
static void DecrementRefCount(ClientData cd);
static int ListRecordingsCmd(ClientData cd, Tcl_Interp *interp, int objc,
Tcl_Obj *CONST objv[]);
static int RecordingCmd(ClientData cd, Tcl_Interp *interp, int objc,
Tcl_Obj *CONST objv[]);
static void
DecrementRefCount(ClientData cd)
{
Tcl_Obj *obj = (Tcl_Obj *) cd;
Tcl_DecrRefCount(obj);
return;
}
static int
ListRecordingsCmd(ClientData cd, Tcl_Interp *interp, int objc,
Tcl_Obj *CONST objv[])
{
char name_buf[20];
Tcl_Obj *rec_list = Tcl_NewListObj(0, NULL);
for (int ii = 0; ii < 10000; ii++)
{
static int obj_id = 0;
Tcl_Obj *cmd;
Tcl_Obj *rec_name;
cmd = Tcl_NewStringObj ("rec", -1);
Tcl_AppendObjToObj (cmd, Tcl_NewIntObj (obj_id++));
rec_name = Tcl_NewStringObj ("DM", -1);
snprintf(name_buf, sizeof(name_buf), "%04d", ii);
Tcl_AppendStringsToObj(rec_name, name_buf, (char *) NULL);
Tcl_IncrRefCount(rec_name);
Tcl_CreateObjCommand (interp, Tcl_GetString (cmd), RecordingCmd,
(ClientData) rec_name, DecrementRefCount);
Tcl_ListObjAppendElement (interp, rec_list, cmd);
}
Tcl_SetObjResult (interp, rec_list);
return TCL_OK;
}
static int
RecordingCmd(ClientData cd, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[])
{
Tcl_Obj *rec_name = (Tcl_Obj *)cd;
char *subcmd;
subcmd = Tcl_GetString (objv[1]);
if (strcmp (subcmd, "name") == 0)
{
Tcl_SetObjResult (interp, rec_name);
}
else
{
Tcl_Obj *result = Tcl_NewStringObj ("", 0);
Tcl_AppendStringsToObj (result,
"bad command \"",
Tcl_GetString (objv[1]),
"\"",
(char *) NULL);
Tcl_SetObjResult (interp, result);
return TCL_ERROR;
}
return TCL_OK;
}
int
Vtcl_Init(Tcl_Interp *interp)
{
#ifdef USE_TCL_STUBS
if (Tcl_InitStubs(interp, "8.5", 0) == NULL) {
return TCL_ERROR;
}
#endif
if (Tcl_PkgProvide(interp, "vtcl", "0.0.1") != TCL_OK)
return TCL_ERROR;
Tcl_CreateNamespace(interp, "vtcl", (ClientData) NULL,
(Tcl_NamespaceDeleteProc *) NULL);
Tcl_CreateObjCommand(interp, "::vtcl::recordings", ListRecordingsCmd,
(ClientData) NULL, (Tcl_CmdDeleteProc *) NULL);
return TCL_OK;
}
The management of the Tcl_Obj * reference counts looks absolutely correct, but I do wonder whether you're freeing all the other resources associated with a particular instance in your real code. It might also be something else entirely; your code is not the only thing in Tcl that allocates memory! Furthermore, the default memory allocator in Tcl does not actually return memory to the OS, but instead holds onto it until the process ends. Figuring out what is wrong can be tricky.
You can try doing a build of Tcl with the --enable-symbols=mem passed to configure. That makes Tcl build in an extra command, memory, which allows more extensive checking of memory management behaviour (it also does things like ensure that memory is never written to after it is freed). It's not enabled by default because it has a substantial performance hit, but it could well help you track down what's going on. (The memory info subcommand is where to get started.)
You could also try adding -DPURIFY to the CFLAGS when building; it completely disables the Tcl memory allocator (so memory checking tools like — commercial — Purify and — OSS — Electric Fence can get accurate information, instead of getting very confused by Tcl's high-performance thread-aware allocator) and may allow you to figure out what is going on.
I found where the leak is. In function ListRecordingsCmd, I replaced line
Tcl_AppendObjToObj (cmd, Tcl_NewIntObj (obj_id++));
with
Tcl_Obj *obj = Tcl_NewIntObj (obj_id++);
Tcl_AppendObjToObj (cmd, obj);
Tcl_DecrRefCount(obj);
The memory allocated to store the object id was not released. The memory used by the tclsh process is now stable.

Resources